---
title: "Form Configuration"
framework: react
version: "2.1.2"
---

# Form Configuration

Custom widgets can use the built-in Studio form builder to edit their data and format settings.

#### Custom Widget

```tsx
"use client";

import React, {
  useCallback,
  useMemo,
  useRef,
  useState,
  StrictMode,
} from "react";
import { createRoot } from "react-dom/client";
import { AgStudio, AgStudioRef } from "ag-studio-react";
import {
  AgDataEngine,
  AgDataSourcesDefinition,
  AgDefaultRegistry,
  AgReportState,
  AgStudioApi,
  AgStudioApiReadyEvent,
  AgStudioMode,
  AgStudioProperties,
  AgWidgetFormParams,
  AgWidgetsConfig,
  createWidgets,
} from "ag-studio";
import { CustomDef, MyRegistry } from "./interfaces.tsx";
import CustomWidget from "./customWidget.tsx";

const StudioExample = () => {
  const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
  const studioStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);
  const [data, setData] = useState<AgDataSourcesDefinition | AgDataEngine>();
  const initialState = useMemo<AgReportState<MyRegistry>>(() => {
    return {
      pages: [
        {
          id: "page1",
          widgets: {
            "1": {
              type: "customWidget",
              dataMapping: {
                value: [
                  {
                    id: "medals.gold",
                    aggregation: "sum",
                  },
                ],
              },
            },
          },
          widgetLayout: {
            "1": {
              xTrack: 0,
              yTrack: 0,
              xSpan: 24,
              ySpan: 12,
            },
          },
          selection: {
            type: "widget",
            id: "1",
          },
        },
      ],
      selectedPageId: "page1",
      panels: {
        filters: {
          collapsed: true,
        },
        data: {
          collapsed: true,
        },
      },
    };
  }, []);
  const widgets = useMemo<
    | AgWidgetsConfig<MyRegistry>
    | ((
        widgets: AgWidgetsConfig<AgDefaultRegistry>,
      ) => AgWidgetsConfig<MyRegistry>)
  >(() => {
    return createWidgets<MyRegistry>({
      additionalTypes: [
        {
          id: "customWidget",
          icon: {
            url: "https://www.ag-grid.com/studio/images/brandmark.svg",
          },
          label: "Custom Widget",
          dataMapping: {
            value: {
              type: "field",
              supportedRoles: ["numeric"],
              requires: { cardinality: "one" },
              required: true,
            },
          },
          form: (params: AgWidgetFormParams<CustomDef>) => {
            const defaultForm = params.createDefaults({
              dataMappingItems: [
                {
                  key: "value",
                  label: "Value",
                },
              ],
            });
            defaultForm.items[0].items.push({
              type: "section",
              key: "customSection",
              label: "Special Config",
              items: [
                {
                  type: "number",
                  id: "format.style.valueFontSize",
                  label: "Value Font Size",
                  defaultValue: 48,
                },
              ],
            });
            return defaultForm;
          },
          comp: CustomWidget,
          defaultSize: {
            width: 400,
            height: 300,
          },
          minSize: {
            width: 200,
            height: 100,
          },
          ai: {
            description:
              "Custom widget used for displaying values in an interesting way.",
          },
        },
      ],
      menu: [
        {
          label: "Custom",
          widgetIds: ["customWidget"],
        },
      ],
    });
  }, []);

  const onApiReady = useCallback((params: AgStudioApiReadyEvent) => {
    fetch("https://www.ag-grid.com/studio/example-assets/olympic-winners.json")
      .then((resp) => resp.json())
      .then((data: any[]) => setData({ sources: [{ id: "medals", data }] }));
  }, []);

  return (
    <div style={containerStyle}>
      <div style={{ display: "flex", flexDirection: "column", height: "100%" }}>
        <AgStudio<MyRegistry>
          style={studioStyle}
          className="my-studio-container"
          data={data}
          initialState={initialState}
          widgets={widgets}
          mode={"edit"}
          onApiReady={onApiReady}
        />
      </div>
    </div>
  );
};

const root = createRoot(document.getElementById("root")!);
root.render(
  <StrictMode>
    <StudioExample />
  </StrictMode>,
);
```

[Live example: Custom Widget](https://www.ag-grid.com/studio/examples/custom-widgets-form/custom-widget/reactFunctionalTs/)

The example above adds a `Special Config` section to the setup tab, with an input to control the font size of the value in the custom widget.

The form is provided via the `form` property of the widget definition.

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `form` | `Function` |  | Form configuration using typed form builder. |

## Form Setup

The ID of each form item is a dot delimited path of the corresponding property within the widget config.

```
interface CustomWidgetStyle {
    valueFontSize?: number;
}

interface CustomWidgetDef {
    type: 'customWidget';
    dataMapping: {
        value: AgWidgetFieldReference[];
    };
    format?: AgWidgetDataFormat<CustomWidgetStyle>;
}
```

For the above definition, the corresponding input ID for the `valueFontSize` property would be `format.style.valueFontSize`.

## Form Helpers

The `form` callback provides some helper functions to create form elements for the default properties (e.g. data mapping, titles, etc.).

```
const widgetDefinition = {
    // ...
    form: (params) => {
        return params.createDefaults({
            dataMappingItems: [
                {
                    key: 'value',
                    label: 'Value',
                },
            ],
        });
    },
}
```

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `createDefaults` | `Function` |  | Create the default tab group with a setup and format tab. Setup tab contains: Widget section Data mapping section (if data mapping exists) Cross filter section Format tab contains: Titles section |
| `createWidgetSection` | `Function` |  | Creates a section containing the widget type selector. |
| `createDataMapping` | `Function` |  | Create the data mapping item. Either a section if multiple data mapping fields, or a single fieldset or field item. |
| `createCrossFilterSection` | `Function` |  | Creates a section containing the cross filter input. |
| `createTitleGroup` | `Function` |  | Creates the title group. |
| `createSubtitleGroup` | `Function` |  | Creates the subtitle group. |
| `createCaptionGroup` | `Function` |  | Creates the caption group. |
| `createTitleSection` | `Function` |  | Creates the title section containing the title, subtitle and caption group. |

## Form Grouping Items

The following form items allow for grouping/structuring the form items (e.g. they have children).

| Item | Interface | Description |
| --- | --- | --- |
| Tab Group | `AgWidgetFormTabGroup` / `AgFormTabGroup` | A group of tab items. E.g. the top-level Setup / Format tab group in the edit panel for the default widgets. |
| Tab | `AgWidgetFormTab` / `AgFormTab` | A child tab of a tab group item. E.g. the Setup tab in the edit panel for the default widgets. |
| Section | `AgWidgetFormSection` / `AgFormSection` | A top-level collection of items. E.g. the Titles section in the edit panel for the default widgets. |
| Group | `AgWidgetFormGroup` / `AgFormGroup` | A lower-level collection of items (with an optional toggle). E.g. the Title group in the edit panel for the default widgets. |

## Form Input Items

| Item | Interface | Description |
| --- | --- | --- |
| Select | `AgWidgetFormSelect` / `AgFormSelect` | A select input item. |
| Checkbox | `AgWidgetFormCheckbox` / `AgFormCheckbox` | A checkbox input item. |
| Toggle | `AgWidgetFormToggle` / `AgFormToggle` | A toggle input item. |
| Text Input | `AgWidgetFormTextField` / `AgFormTextField` | A text input item. |
| Text Area | `AgWidgetFormTextArea` / `AgFormTextArea` | A text area input item. |
| Number Input | `AgWidgetFormNumber` / `AgFormNumber` | A number input item. |
| Optional Number Input | `AgWidgetFormOptionalNumber` / `AgFormOptionalNumber` | A number input item that allows optional values. |
| Color Input | `AgWidgetFormColor` / `AgFormColor` | A color picker input item. |
| Widget Type Selector | `AgWidgetFormWidgetType` (widget form only) | A select input that allows changing the widget type. |
| Field Selection Input | `AgWidgetFormField` (widget form only) | An input for selecting a field (supporting drag and drop). |
| Fieldset Selection Input | `AgWidgetFormFieldSet` (widget form only) | An input for selecting multiple fields (supporting drag and drop). |
| Grouped Typography Input | `AgWidgetFormTypography` (widget form only) | A group of elements for configuring typography. |
