***

title: "FormComponents"
generated: true
---------------

## DashboardCustomFormComponent

<GenerationInfo sourceFile="packages/dashboard/src/lib/framework/extension-api/types/form-components.ts" sourceLine="13" packageName="@vendure/dashboard" since="3.4.0" />

Allows you to define a custom input component for custom fields and configurable operation arguments
in the dashboard. Register the component here, then reference its `id` from the field or argument
`ui.component` config.

```ts title="Signature"
interface DashboardCustomFormComponent {
    id: string;
    component: DashboardFormComponent;
}
```

<div className="members-wrapper">

### id

\<MemberInfo kind="property" type={`string`}   />

A unique identifier for the custom form component. It is a good practice to namespace
these IDs to avoid naming collisions, for example `"my-plugin.markdown-editor"`.

### component

\<MemberInfo kind="property" type={`<a href='/current/core/reference/dashboard/extensions-api/form-components#dashboardformcomponent'>DashboardFormComponent</a>`}   />

The React component that will be rendered as the custom form input.

</div>
## DashboardCustomFormComponents

<GenerationInfo sourceFile="packages/dashboard/src/lib/framework/extension-api/types/form-components.ts" sourceLine="36" packageName="@vendure/dashboard" since="3.4.0" />

Interface for registering custom input components which can be selected by custom fields and
configurable operation arguments via their `ui.component` config.

```ts title="Signature"
interface DashboardCustomFormComponents {
    customFields?: DashboardCustomFormComponent[];
}
```

<div className="members-wrapper">

### customFields

\<MemberInfo kind="property" type={`<a href='/current/core/reference/dashboard/extensions-api/form-components#dashboardcustomformcomponent'>DashboardCustomFormComponent</a>[]`}   />

Custom input components for custom fields and configurable operation arguments.

</div>
## DashboardFormComponentProps

<GenerationInfo sourceFile="packages/dashboard/src/lib/framework/form-engine/form-engine-types.ts" sourceLine="92" packageName="@vendure/dashboard" since="3.4.0" />

Props that get passed to all form input components. They are based on the
controller props used by the underlying `react-hook-form`, i.e.:

```ts
export type ControllerRenderProps = {
    onChange: (event: any) => void;
    onBlur: () => void;
    value: any;
    disabled?: boolean;
    name: string;
    ref: RefCallBack;
};
```

in addition, they can optionally be passed a `fieldDef` prop if the
component is used in the context of a custom field or configurable operation arg.

The `fieldDef` arg, when present, has the following shape:

```ts
export type ConfigurableArgDef = {
    defaultValue: any
    description: string | null
    label: string | null
    list: boolean
    name: string
    required: boolean
    type: string
    ui: any
}
```

```ts title="Signature"
type DashboardFormComponentProps<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>> = ControllerRenderProps<TFieldValues, TName> & {
    fieldDef?: ConfigurableFieldDef;
}
```

## DashboardFormComponentMetadata

<GenerationInfo sourceFile="packages/dashboard/src/lib/framework/form-engine/form-engine-types.ts" sourceLine="122" packageName="@vendure/dashboard" since="3.4.0" />

Metadata which can be defined on a [DashboardFormComponent](/current/core/reference/dashboard/extensions-api/form-components#dashboardformcomponent) which
provides additional information about how the dashboard should render the
component.

The metadata is defined by adding the static property on the component:

*Example*

```ts
export const MyCustomInput: DashboardFormComponent = props => {
  // implementation omitted
}

MyCustomInput.metadata = { // [!code highlight]
  isListInput: true // [!code highlight]
} // [!code highlight]
```

```ts title="Signature"
type DashboardFormComponentMetadata = {
    isListInput?: boolean | 'dynamic';
    isFullWidth?: boolean;
}
```

<div className="members-wrapper">

### isListInput

\<MemberInfo kind="property" type={`boolean | 'dynamic'`}   />

Defines whether this form component is designed to handle list inputs.
If set to `'dynamic'`, it means the component has internal logic that can
handle both lists and single values.

### isFullWidth

\<MemberInfo kind="property" type={`boolean`}   />

When true, the dashboard will render this form component so it spans
the full width of the detail form grid.

</div>
## DashboardFormComponent

<GenerationInfo sourceFile="packages/dashboard/src/lib/framework/form-engine/form-engine-types.ts" sourceLine="166" packageName="@vendure/dashboard" since="3.4.0" />

This is the common type for all custom form components registered for:

* custom fields
* configurable operation args
* detail page fields

Here's a simple example:

```ts
import { DashboardFormComponent, Input } from '@vendure/dashboard';

const MyComponent: DashboardFormComponent = (props) => {
    return <Input value={props.value}
                  onChange={props.onChange}
                  onBlur={props.onBlur}
                  name={props.name}
                  disabled={props.disabled}
                  ref={props.ref}
                  />;
};
```

```ts title="Signature"
type DashboardFormComponent = React.ComponentType<DashboardFormComponentProps> & {
    metadata?: DashboardFormComponentMetadata;
}
```
