My App

Hooks

Learn about the hooks provided by the Figma Forms Renderer for managing form state and behavior

The Figma Forms Renderer provides several custom React hooks to manage form state, navigation, validation, and data. These hooks allow you to easily interact with the form's functionality and state within your React components.

These hooks must be used within a <FormProvider> component to ensure they have access to the necessary context.

useFormData

Returns the static properties from the JsonForm object passed to the <FormProvider>.

PropertyTypeDescription
titlestringThe title of the form.
descriptionstringThe description of the form.
pagesJsonFormPage[]An array of form pages.

Examples

Use title and description to display the form header.

FormHeader.tsx
import { useFormData } from "@/components/formProvider";

export function FormHeader() {
  const { title, description } = useFormData();

  return (
    <header>
      <h1>{title}</h1>
      <p>{description}</p>
    </header>
  );
}

Use pages to create a sidebar listing all form pages.

FormSidebar.tsx
import { useFormData } from "@/components/formProvider";

export function FormSidebar() {
  const { pages } = useFormData();

  return (
    <aside>
      <ul>
        {pages.map((page) => (
          <li key={page.id}>{page.title}</li>
        ))}
      </ul>
    </aside>
  );
}

useFormNavigation

Returns the active page's JsonFormPage object and functions to navigate between form pages.

PropertyTypeDescription
currentPageJsonFormPageThe currently active form page.
pageIdxnumberThe index of the currently active page.
nextPage() => voidNavigate to the next form page.
prevPage() => voidNavigate to the previous form page.
goToPage(idx: number) => voidNavigate to a specific form page by index.

All navigation methods respect page validation and will not navigate to the next page if the current page has validation errors.

Examples

Use currentPage to display the active page's title and description. Use nextPage and prevPage for navigation buttons.

FormPage.tsx
import { useFormNavigation } from "@/components/formProvider";
import { FormRenderer } from "@/components/formRenderer";

export function FormPage() {
  const { currentPage, pageIdx, nextPage, prevPage } = useFormNavigation();

  return (
    <div>
      <h2>
        Page {pageIdx + 1}: {currentPage.title}
      </h2>
      <h3>{currentPage.description}</h3>
      <FormRenderer />
      <div>
        {pageIdx !== 0 && <button onClick={prevPage}>Previous</button>}
        <button onClick={nextPage}>Next</button>
      </div>
    </div>
  );
}

Use goToPage to create a sidebar for direct page navigation.

FormSidebar.tsx
import { useFormNavigation, useFormData } from "@/components/formProvider";

export function FormSidebar() {
  const { pages } = useFormData();
  const { goToPage } = useFormNavigation();

  return (
    <aside>
      <ul>
        {pages.map((page, index) => (
          <li key={page.id} onClick={() => goToPage(index)}>
            {page.title}
          </li>
        ))}
      </ul>
    </aside>
  );
}

useFormStatus

Returns the completion status of pages and the overall form.

PropertyTypeDescription
getStepStatus() => StepStatusReturns the total and completed step counts
getPageInfo(idx: number) => PageInfoReturns information about a specific page by index.

Examples

Use getStepStatus to display form progress.

FormProgress.tsx
import { useFormStatus } from "@/components/formProvider";

export function FormProgress() {
  const { getStepStatus } = useFormStatus();
  const { totalSteps, completedSteps } = getStepStatus();

  return (
    <div>
      Progress: {completedSteps} / {totalSteps} steps completed
    </div>
  );
}

Use getPageInfo to create a sidebar with page status indicators.

SidebarItem.tsx
import { useFormNavigation, useFormStatus } from "@/components/formProvider";

export function SidebarItem(props: { title: string; idx: number }) {
  const { title, idx } = props;
  const { goToPage } = useFormNavigation();
  const { getPageInfo } = useFormStatus();
  const { complete, disabled, isCurrent } = getPageInfo(idx);

  return (
    <li
      onClick={() => goToPage(idx)}
      style={{
        textDecoration: complete ? "line-through" : "none",
        fontWeight: isCurrent ? "bold" : "normal",
        color: disabled ? "gray" : "black",
        cursor: disabled ? "not-allowed" : "pointer",
      }}
    >
      {title}
    </li>
  );
}

useFormState

Manages and provides access to the form's state.

PropertyTypeDescription
formStateFormStateThe current state of the form.
setFormState(state: FormState) => voidFunction to update the form state.
handleCheckboxChange(groupId: string, itemId: string, elements: Checkbox[]) => voidHandle changes in checkbox groups.
handleRadioChange(groupId: string, itemId: string, elements: RadioButton[]) => voidHandle changes in radio button groups.

The formState object contains the current values of all form fields, where keys are field IDs and values are user inputs. See formProvider/types.ts for more details on the FormState type.

Form field components generally handle state updates using JsonForms' built-in handleChange method. However, nested fields require special handlers that also remove child field values when a parent field is unchecked or when a radio button selection changes.

Examples

Use formState to submit the form data.

FormSubmit.tsx
import { useFormState } from "@/components/formProvider";

export function FormSubmit() {
  const { formState } = useFormState();

  const handleSubmit = () => {
    // Simulate form submission
    console.log("Form submitted with state:", formState);
  };

  return <button onClick={handleSubmit}>Submit Form</button>;
}

Use setFormState to reset the form.

FormReset.tsx
import { useFormState } from "@/components/formProvider";

export function FormReset() {
  const { setFormState } = useFormState();

  const handleReset = () => {
    setFormState({});
  };

  return <button onClick={handleReset}>Reset Form</button>;
}

useFormValidation

Returns validation status and functions to validate the form.

PropertyTypeDescription
errorsErrorObject[]An array of AJV validation errors for the current page.
setErrors(errors: ErrorObject[]) => voidFunction to set validation errors.
validationModeValidationModeThe current validation mode of the form ("None" or "ValidateAndShow").

Example

Use errors to display validation errors for the current page.

ErrorsPanel.tsx
import { useFormValidation } from "@/components/formProvider";

export function ErrorsPanel() {
  const { errors, validationMode } = useFormValidation();

  if (validationMode !== "ValidateAndShow" || errors.length === 0) {
    return null;
  }

  return (
    <div>
      <h3>Validation Errors:</h3>
      <ul>
        {errors.map((error, index) => (
          <li key={index}>{error.message}</li>
        ))}
      </ul>
    </div>
  );
}

On this page