diff --git a/apps/react/app/App.tsx b/apps/react/app/App.tsx
index 032aff9e..82b3a802 100644
--- a/apps/react/app/App.tsx
+++ b/apps/react/app/App.tsx
@@ -3,7 +3,6 @@ import { document } from '@/utils/document'
import { workbook } from '@/utils/workbook'
import { recordHook } from '@flatfile/plugin-record-hook'
import {
- attachStyleSheet,
Document,
Sheet,
Space,
@@ -16,11 +15,21 @@ import {
import { useEffect, useState } from 'react'
import styles from './page.module.css'
-attachStyleSheet({ nonce: 'flatfile-abc123' }) // add custom nonce
-
+/**
+ * @description Is responsible for rendering a Flatfile application with several
+ * features such as useEffect, useListener, usePlugin and useEvent. It also defines
+ * four buttons to trigger different actions related to opening, closing, and updating
+ * the portal, as well as submitting workbooks and records.
+ *
+ * @returns {Component} a React component that renders a Portal and several listeners
+ * for event handling.
+ */
const App = () => {
const { open, openPortal, closePortal } = useFlatfile()
const [label, setLabel] = useState('Rock')
+ /**
+ * @description Either opens or closes a portal, depending on the value of `open`.
+ */
const toggleOpen = () => {
open ? closePortal({ reset: false }) : openPortal()
}
@@ -98,6 +107,21 @@ const App = () => {
}}
>
+ {/**
+ * @description Configures and generates high-quality documentation for given code.
+ * It accepts an object `workbook` with configuration properties, a `onSubmit` function
+ * that logs information when called, and an `onRecordHooks` array of functions that
+ * set property values on records before they are returned.
+ *
+ * @param {object} config - configuration options for a specific worksheet, allowing
+ * you to define properties such as the sheet name, slug, and record hooks.
+ *
+ * @param {object} onSubmit - 3rd sheet that will receive the submitted data after
+ * it has been processed and transformed.
+ *
+ * @param {array} onRecordHooks - 2 record hook functions that are executed when a
+ * record is inserted, updated, or deleted in the specified sheet.
+ */}
{
],
]}
>
+ {/**
+ * @description Configures a Google Sheets document with a specific name and default
+ * page, sets an onRecordHook function to update the "email" field with a custom
+ * value, and defines an onSubmit function to log a message when the sheet is submitted.
+ *
+ * @param {object} config - configuration for a specific worksheet, which includes
+ * the sheet name, slug, and an optional onRecordHook function to manipulate records
+ * before they are saved.
+ *
+ * @param {asynchronous function.} onRecordHook - callback function that is triggered
+ * when a new record is created or updated in the Sheet, which allows for custom
+ * modifications to be applied to the recorded data before it is saved.
+ *
+ * * `record`: The current record being processed in the hook, with properties
+ * matching the corresponding fields in the sheet's data source.
+ * * `sheet`: The active `Sheet` instance, used to access properties and methods for
+ * interacting with the Google Sheets API.
+ *
+ * @param {`async function`.} onSubmit - function that is executed when a record is
+ * submitted in the Sheet 3.
+ *
+ * * `onSubmit`: This is a function that will be called when a submit event occurs
+ * on the sheet.
+ * * `({ sheet })`: This is the event listener object that contains information about
+ * the submitted sheet. The `{ sheet }` property refers to the sheet that was submitted.
+ */}
{
console.log('onSubmit from Sheet 3', { sheet })
}}
/>
+ {/**
+ * @description Configures a new Google Sheets document with a specified slug, name,
+ * and onRecordHook function to manipulate the contents of the sheet before it is
+ * created. The `onSubmit` function logs information when the sheet is submitted.
+ *
+ * @param {object} config - configuration for a new spreadsheet, including the slug
+ * and name of the spreadsheet, as well as overwriting the email field with the value
+ * `'SHEET 4 RECORDHOOK'`.
+ *
+ * @param {Anonymous function.} onRecordHook - 4th sheet's record hook, which sets
+ * the email field of each record to 'SHEET 4 RECORDHOOK'.
+ *
+ * * `record`: A record object that contains information about the updated record.
+ * * `SHEET 4 RECORDHOOK`: The email address specified as part of the onRecordHook
+ * hook.
+ *
+ * @param {object} onSubmit - action performed when a user submits data through the
+ * sheet.
+ */}
`: This component is a wrapping container for Flatfile, which
+ * is a module that provides a simple way to store and retrieve data in a flat file.
+ * The `publishableKey` attribute within the `config` object is used to specify the
+ * publishable key for the Flatfile module.
+ * * `App`: This is the component that will be rendered inside the `FlatfileProvider`.
+ * It is likely that this component contains some of the logic and styling for the
+ * application being developed.
+ */
export default function Home() {
const PUBLISHABLE_KEY = process.env.NEXT_PUBLIC_FLATFILE_PUBLISHABLE_KEY
if (!PUBLISHABLE_KEY) return <>No Publishable Key Available>
@@ -11,7 +26,8 @@ export default function Home() {
diff --git a/packages/react/src/components/FlatfileProvider.tsx b/packages/react/src/components/FlatfileProvider.tsx
index ca4a88aa..137b9868 100644
--- a/packages/react/src/components/FlatfileProvider.tsx
+++ b/packages/react/src/components/FlatfileProvider.tsx
@@ -19,6 +19,8 @@ import { getSpace } from '../utils/getSpace'
import { EmbeddedIFrameWrapper } from './EmbeddedIFrameWrapper'
import FlatfileContext, { DEFAULT_CREATE_SPACE } from './FlatfileContext'
+import { attachStyleSheet } from '../utils/attachStyleSheet'
+
const configDefaults: IFrameTypes = {
preload: true,
resetOnClose: true,
@@ -31,6 +33,73 @@ interface ISessionSpace
upgradedAt: string
}
+/**
+ * @description Sets up Flatfile Provider for a Portal, handling authentication, sheet
+ * management, and space creation/updates. It provisions an iframe to load the Portal
+ * content and listens for postMessages from the created iFrame to handle space updates
+ * and closing.
+ *
+ * @param {React Element or JSX Expression} .children - children of the FlatfileProvider
+ * component, which are the components that will be rendered inside the iFrame.
+ *
+ * 1/ `children`: The input passed to the `` component is
+ * an array of React components.
+ * 2/ `FLATFILE_PROVIDER_CONFIG`: An object that contains various configuration
+ * options for Flatfile, such as the space URL, API URL, and environment ID. This
+ * object is used to update the space and documents inside the space.
+ * 3/ `handleCreateSpace`: A function that creates a new space when called. It takes
+ * no arguments.
+ * 4/ `handleReUseSpace`: A function that updates an existing space when called. It
+ * takes no arguments.
+ * 5/ `publishableKey`: An optional string that contains the publishable key for the
+ * Flatfile instance. If not provided, it will be fetched from the Flatfile server.
+ * 6/ `internalAccessToken`: An optional string that contains the internal access
+ * token for the Flatfile instance. If not provided, it will be fetched from the
+ * Flatfile server.
+ * 7/ `apiUrl`: The API URL for the Flatfile instance. This is used to make requests
+ * to the Flatfile server.
+ * 8/ `environmentId`: An optional string that contains the environment ID for the
+ * Flatfile instance. If not provided, it will be fetched from the Flatfile server.
+ * 9/ `open`: An optional boolean value that indicates whether the space is open or
+ * closed. This is used to control the visibility of the space.
+ * 10/ `setOpen`: A function that sets the open status of the space. It takes a
+ * boolean argument indicating whether the space should be open or closed.
+ * 11/ `sessionSpace`: An optional object that contains information about the current
+ * session space, including the ID and URL. If not provided, it will be fetched from
+ * the Flatfile server.
+ * 12/ `setSessionSpace`: A function that sets the session space information. It
+ * takes an object with `ID` and `URL` properties as arguments.
+ * 13/ `setListener`: A function that sets the listener function for updates to the
+ * space and documents. It takes a function as an argument.
+ * 14/ `listener`: An optional function that is called whenever there are updates
+ * to the space or documents. If not provided, it will be fetched from the Flatfile
+ * server.
+ * 15/ `defaultPage`: An optional React component that contains the default page for
+ * the Flatfile instance. If not provided, it will be fetched from the Flatfile server.
+ * 16/ `setDefaultPage`: A function that sets the default page for the Flatfile
+ * instance. It takes a React component as an argument.
+ *
+ * @param {string} .publishableKey - 10-digit publishable key associated with the
+ * Space, which is required to authenticate and interact with the Flatfile platform.
+ *
+ * @param {string} .accessToken - Flatfile access token used to authenticate and make
+ * API requests within the provider component.
+ *
+ * @param {string} .environmentId - environment ID that Flatfile should be deployed
+ * to. It is used to pass the necessary configuration to the Flatfile provider component
+ * to properly authenticate and interact with the Flatfile API.
+ *
+ * @param {string} .apiUrl - 3D visualization API endpoint used for fetching and
+ * updating the virtual 3D environment.
+ *
+ * @param {object} .config - Flatfile Provider configuration object, which is used
+ * to determine the behavior of the `FlatfileContext.Provider` component. It specifies
+ * various settings and options for the provider, such as the API URL, authentication
+ * token, and whether to create a new space or reuse an existing one.
+ *
+ * @returns {object} a Flatfile provider that renders a space and allows for the
+ * creation, updating, and deleting of sheets, workbooks, and documents.
+ */
export const FlatfileProvider: React.FC = ({
children,
publishableKey,
@@ -73,6 +142,26 @@ export const FlatfileProvider: React.FC = ({
}, [])
const [ready, setReady] = useState(false)
+ /**
+ * @description Automatically configure's Flatfile space using API key when provided
+ * with publishable key, otherwise it handles internal client side API usage and
+ * updates default page in Flatfile space.
+ *
+ * @returns {AccessToken} an access token for the newly created space, which is stored
+ * in the `window` object and used for internal client-side Flatfile API usage.
+ *
+ * * `createdSpace`: an object containing the newly created space, including its ID,
+ * name, and auto-configure status.
+ * * `apiUrl`: the URL of the Flatfile API server.
+ * * `publishableKey`: the publishable key for the Flatfile API.
+ * * `workbook`: the workbook associated with the createSpace call, or undefined if
+ * none was provided.
+ * * `document`: the document associated with the createSpace call, or undefined if
+ * none was provided.
+ * * `sessionSpace`: an object containing the current session space, including its
+ * ID and access token.
+ * * `internalAccessToken`: the internal access token for the current session space.
+ */
const handleCreateSpace = async () => {
if (!publishableKey) {
return
@@ -98,6 +187,10 @@ export const FlatfileProvider: React.FC = ({
setSessionSpace(createdSpace)
}
+ /**
+ * @description Verifies if an access token exists for a given space, and if so, sets
+ * it as the internal access token and saves it to the session space object.
+ */
const handleReUseSpace = async () => {
if (internalAccessToken && createSpace.space.id) {
const { data: reUsedSpace } = await getSpace({
@@ -114,6 +207,23 @@ export const FlatfileProvider: React.FC = ({
}
}
+ /**
+ * @description Updates a pre-existing Flutter file by adding a new sheet to the
+ * workbook if one does not already exist with the same slug as the new sheet.
+ *
+ * @param {Flatfile.SheetConfig} newSheet - Flatfile.SheetConfig object containing
+ * the configuration details of a new sheet to be created within an existing workbook.
+ *
+ * @returns {updated instance of `Flatfile.WorkbookConfig} a modified version of the
+ * `prevSpace` object, where a new sheet has been added to the workbook.
+ *
+ * * `prevSpace`: The previous workbook state.
+ * * `workbook`: The updated workbook state, which includes the new sheet added to
+ * the previous one. It is an object with the following properties:
+ * + `sheets`: An array of sheets, which now contains the newly added sheet as well
+ * as the existing ones.
+ * + `slug`: The unique identifier for each sheet, used for reference in the workbook.
+ */
const addSheet = (newSheet: Flatfile.SheetConfig) => {
setCreateSpace((prevSpace) => {
// Check if the sheet already exists
@@ -134,6 +244,19 @@ export const FlatfileProvider: React.FC = ({
})
}
+ /**
+ * @description Updates a specific sheet in a Flatfile workbook based on a given slug
+ * and partial updates. It mutates the workbook's sheets object by mapping over it
+ * and replacing the specified sheet with the updated one.
+ *
+ * @param {string} sheetSlug - unique identifier of the sheet for which the updates
+ * are being applied.
+ *
+ * @param {Partial} sheetUpdates - updates that should be applied
+ * to the sheet with the matching slug, which is provided as the `sheetSlug` input parameter.
+ *
+ * @returns {object} an updated `Flatfile.Workspace` object with a modified sheet.
+ */
const updateSheet = (
sheetSlug: string,
sheetUpdates: Partial
@@ -156,6 +279,15 @@ export const FlatfileProvider: React.FC = ({
})
}
+ /**
+ * @description Modifies a previously created workbook configuration based on new
+ * inputs provided by the `workbookUpdates` object. It prioritizes the sheets and
+ * actions passed in the updates, merging them with any existing sheets and actions
+ * in the previous workbook configuration.
+ *
+ * @param {Flatfile.CreateWorkbookConfig} workbookUpdates - updates to be applied to
+ * the workbook, including changes to the worksheet configuration, actions, and sheets.
+ */
const updateWorkbook = (workbookUpdates: Flatfile.CreateWorkbookConfig) => {
setCreateSpace((prevSpace) => ({
...prevSpace,
@@ -175,6 +307,15 @@ export const FlatfileProvider: React.FC = ({
}))
}
+ /**
+ * @description Updates a `Flatfile.DocumentConfig` object's `document` property by
+ * concatenating the original document and any update documents provided in the
+ * `documentUpdates` object.
+ *
+ * @param {Flatfile.DocumentConfig} documentUpdates - updates to be applied to the
+ * `document` field of the `Flatfile.DocumentConfig` object, which are then merged
+ * with the previous document configuration to produce the updated document configuration.
+ */
const updateDocument = (documentUpdates: Flatfile.DocumentConfig) => {
setCreateSpace((prevSpace) => ({
...prevSpace,
@@ -185,6 +326,13 @@ export const FlatfileProvider: React.FC = ({
}))
}
+ /**
+ * @description Updates a space configuration by combining the current space configuration
+ * with new space updates. The updated space configuration is then assigned to the
+ * `space` object within the context.
+ *
+ * @param {Flatfile.SpaceConfig} spaceUpdates - updates to be applied to the space configuration.
+ */
const updateSpace = (spaceUpdates: Flatfile.SpaceConfig) => {
setCreateSpace((prevSpace) => ({
...prevSpace,
@@ -192,6 +340,14 @@ export const FlatfileProvider: React.FC = ({
}))
}
+ /**
+ * @description Sets open to false, resets internal access token and session space,
+ * preloads a space URL, and updates an iframe's source tag based on configuration options.
+ *
+ * @param {ClosePortalOptions} .reset - FlatFile Provider configuration's `resetOnClose`
+ * property, which when set to `true`, triggers the reset of internal access token
+ * and space URL after the portal is closed.
+ */
const resetSpace = ({ reset }: ClosePortalOptions = {}) => {
setOpen(false)
@@ -214,6 +370,14 @@ export const FlatfileProvider: React.FC = ({
// Works but only after the iframe is visible
}
}
+ const styleSheetRef = useRef(false)
+
+ useEffect(() => {
+ if (!styleSheetRef.current) {
+ attachStyleSheet(config?.styleSheetOptions)
+ styleSheetRef.current = true
+ }
+ }, [config?.styleSheetOptions, styleSheetRef])
// Listen to the postMessage event from the created iFrame
useEffect(() => {
@@ -256,6 +420,11 @@ export const FlatfileProvider: React.FC = ({
// Triggers handleCreateSpace or handleReUseSpace when the openPortal() is clicked and ready is true
useEffect(() => {
if (ready && open) {
+ /**
+ * @description Determines whether to create a new space or update an existing one
+ * based on two inputs: `publishableKey` and `internalAccessToken`. It executes the
+ * appropriate action based on the input values.
+ */
const createOrUpdateSpace = async () => {
if (publishableKey && !internalAccessToken) {
await handleCreateSpace()
diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts
index f3472fb5..da704892 100644
--- a/packages/react/src/index.ts
+++ b/packages/react/src/index.ts
@@ -6,17 +6,8 @@ import type {
IUserInfo,
} from '@flatfile/embedded-utils'
-import stylesheet from './components/style.scss'
-import { styleInject } from './utils/styleInject'
export { makeTheme } from './utils/makeTheme'
export * from './components'
export * from './hooks'
export type { ISidebarConfig, ISpace, ISpaceInfo, IThemeConfig, IUserInfo }
-
-export function attachStyleSheet(options?: {
- insertAt?: 'top'
- nonce?: string
-}) {
- styleInject(stylesheet, options)
-}
diff --git a/packages/react/src/types/iFrameProps.ts b/packages/react/src/types/iFrameProps.ts
index 0902e8cd..2c41ad35 100644
--- a/packages/react/src/types/iFrameProps.ts
+++ b/packages/react/src/types/iFrameProps.ts
@@ -1,5 +1,5 @@
import { ISpace } from '@flatfile/embedded-utils'
-
+import { StyleSheetOptions } from '../utils/attachStyleSheet'
export type IFrameTypes = Partial<
Pick<
ISpace,
@@ -12,5 +12,9 @@ export type IFrameTypes = Partial<
| 'displayAsModal'
| 'closeSpace'
| 'spaceUrl'
- > & { preload?: boolean; resetOnClose?: boolean }
+ > & {
+ preload?: boolean
+ resetOnClose?: boolean
+ styleSheetOptions?: StyleSheetOptions
+ }
>
diff --git a/packages/react/src/utils/attachStyleSheet.ts b/packages/react/src/utils/attachStyleSheet.ts
new file mode 100644
index 00000000..c4953b3e
--- /dev/null
+++ b/packages/react/src/utils/attachStyleSheet.ts
@@ -0,0 +1,18 @@
+import { styleInject } from '../utils/styleInject'
+
+import stylesheet from '../components/style.scss'
+export type StyleSheetOptions = {
+ insertAt?: 'top'
+ nonce?: string
+}
+
+/**
+ * @description Attaches a CSS stylesheet to the HTML document through the `styleInject`
+ * method, providing an optional set of options for customization.
+ *
+ * @param {StyleSheetOptions} options - configuration object for customizing the
+ * behavior of the style injection process.
+ */
+export function attachStyleSheet(options?: StyleSheetOptions) {
+ styleInject(stylesheet, options)
+}