# Custom

## Overview

`CustomField` is a component that allows you to define custom form fields that can be used in your react application. You can use it to render any type of form field that you want, based on the `type` specified in the field configuration.

`CustomField` can be used either globally, by specifying it in the `fieldComponents` object passed to the `FormProvider` component, or locally, by specifying the `Field` prop in the field configuration when creating a form.

## Example

```tsx
import { Field, FieldConfig } from '@tutim/types';

export const CustomField: Field = ({ inputProps, fieldConfig }) => {
  const { value, onChange } = inputProps;
  const onClick = () => onChange(value + 2);
  return (
    <button type="button" onClick={onClick}>
      {fieldConfig.label}: {value}
    </button>
  );
};
```

## Interface

### Field

```jsx
import { Field } from "@tutim/types";
```

This is an interface representing a custom form field. It includes the following properties:

```typescript
type Field = (props: FieldProps) => JSX.Element;
```

* `props`: The properties [`YourCustomField`](/api-reference/fields/customfield.md) gets, return any JSX field

### FieldProps

```jsx
import { FieldProps } from "@tutim/types";
```

This is an interface representing field props. It includes the following properties:

```typescript
interface FieldProps {
  inputProps: InputProps;
  fieldConfig: FieldConfig;
  fieldState?: InputState;
}
```

* \`\`[`inputProps`](#inputprops): The control properties of the input, use it to control your field.
* \`\`[`fieldConfig`](#fieldconfig): The properties defined on `FieldConfig`, use it to customize your field (static).

### InputProps

```jsx
import { InputProps } from "@tutim/types";
```

This is an interface representing a form of field props. It includes the following properties:

```typescript
interface InputProps {
  value: any;
  onChange: (newValue: InputProps["value"]) => void;
}
```

* `value`: The current value of the field
* `onChange`: The update method. Use it to update `value`.

### FieldConfig

```jsx
import { FieldConfig } from "@tutim/types";
```

This is an interface representing the configuration for a single form field. It includes the following properties:

```typescript
interface FieldConfig {
  key: string;
  type: InputType;
  Field: Field;
  label?: string;
  isDisabled?: boolean;
  isRequired?: boolean;
  options?: Option[];
  defaultValue?: any;
}
```

* `key`: A unique identifier for the field.
* `type`: The type of input to use for the field, as specified by the `InputType` enumeration.
* \`\`[`Field`](#field): A Field Component, use in order to replace the default (global) field set for this `type`, can only be used with `InputType.Custom.`
* `label`: (optional) The label to display for the field.
* `isDisabled`: (optional) A boolean value indicating whether the field should be disabled.
* `isRequired`: (optional) A boolean value indicating whether the field is required.
* `options`: (optional) An array of `Option` objects for use with `InputType.Select` and `InputType.Radio` fields.
* `defaultValue`: (optional) The default value for the field.

### InputState

```jsx
import { InputState } from "@tutim/types";
```

This is an interface representing a form of field state props. It includes the following properties:

```typescript
export interface InputState {
  invalid?: boolean;
  error?: { message?: string };
}
```

* `invalid`: A boolean representing the validity of the field
* `error`: Error object with `message` , usually a [validation](/api-reference/field-config.md#validation) message

## More examples

### Basic example

To use `CustomField`, you will need to define the custom field component and specify the `type` that you want to use to reference it. You can do this by creating a new component that implements the `Field` interface from the `@tutim/types` library, and specifying the `type` in the field configuration when creating a form.

Here is an example of how to use `CustomField` to create a custom form field that renders a button that increments a number when clicked:

```tsx
import { Field, FieldConfig } from '@tutim/types';

export const CustomField: Field = ({ inputProps, fieldConfig }) => {
  const { value, onChange } = inputProps;
  const onClick = () => onChange(value + 2);
  return (
    <button type="button" onClick={onClick}>
      {fieldConfig.label}: {value}
    </button>
  );
};

export const customFieldConfig: FieldConfig = {
  key: 'clicker',
  label: 'Click Me',
  type: 'custom',
  defaultValue: 0,
  Field: CustomField,
};
```

You can then use the `customFieldConfig` object to create a form with a custom field that increments its value by 2 every time the button is clicked:

```jsx
import { TutimWizard } from '@tutim/fields';
import { customFieldConfig } from './CustomField';

const FormWithCustomField = () => {
  return <TutimWizard onSubmit={console.log} config={{ fields: [customFieldConfig] }} />;
};
```

### Advanced example

You can use `CustomField` globally by specifying it in the `fieldComponents` object passed to the `FormProvider` component. This allows you to use your custom field in any form within your application, without having to specify the `Field` prop in the field configuration for each form.

To use `CustomField` globally, you will need to define the custom field component and add it to the `fieldComponents` object, using the `type` as the key and the field component as the value.

For example, you can use `CustomField` to create a custom form field that renders a button that increments a number when clicked, and use it in multiple forms by specifying it in the `fieldComponents` object passed to `FormProvider`:

```tsx
import { TutimWizard } from '@tutim/fields';
import { FormProvider } from '@tutim/headless';
import { Field, FieldComponents, InputType } from '@tutim/types';

export const CustomField: Field = ({ inputProps, fieldConfig }) => {
  const { value, onChange } = inputProps;
  const onClick = () => onChange(value + 2);
  return (
    <button type="button" onClick={onClick}>
      {fieldConfig.label}: {value}
    </button>
  );
};

const fieldComponents: FieldComponents = {
  [InputType.Text]: ({ inputProps }) => <input {...inputProps} />,
  'custom-field': (fieldProps) => <CustomField {...fieldProps} />,
  // add any type of input and reference it by 'type'
};

const App = (): JSX.Element => {
  return (
    <div className="App">
      <FormProvider fieldComponents={fieldComponents}>
        <TutimWizard
          onSubmit={console.log}
          config={{
            fields: [
              { key: 'textField', label: 'Text Field', type: 'text' },
              { key: 'customField', label: 'Custom Field', type: 'custom-field', defaultValue: 0 },
            ],
          }}
        />
      </FormProvider>
    </div>
  );
};

export default App;
```

In this example, the `CustomField` component is added to the `fieldComponents` object with the key `'custom-field'`. This means that any form field with an `type` of `'custom-field'` will use the `CustomField` component to render the field.

### Multiple custom fields

You can use multiple custom fields in your application by adding them to the `fieldComponents` object in the same way. For example, you can define a second custom field like this:

```tsx
import { Field, FieldConfig } from '@tutim/types';

export const CustomField2: Field = ({ inputProps, fieldConfig }) => {
  const { value, onChange } = inputProps;
  const onClick = () => onChange(value + 1);
  return (
    <button type="button" onClick={onClick}>
      {fieldConfig.label}: {value}
    </button>
  );
};

export const customFieldConfig2: FieldConfig = {
  key: 'clicker2',
  label: 'Click Me 2',
  type: 'custom-field-2',
  defaultValue: 0,
  Field: CustomField2,
};
```

You can then add the `CustomField2` component to the `fieldComponents` object, using the `type` `'custom-field-2'` as the key:

```tsx
import { TutimWizard } from '@tutim/fields';
import { FormProvider } from '@tutim/headless';
import { Field, FieldComponents, InputType } from '@tutim/types';
import { CustomField, customFieldConfig } from './CustomField';
import { CustomField2, customFieldConfig2 } from './CustomField2';

const fieldComponents: FieldComponents = {
  [InputType.Text]: ({ inputProps }) => <input {...inputProps} />,
  'custom-field': (fieldProps) => <CustomField {...fieldProps} />,
  'custom-field-2': (fieldProps) => <CustomField2 {...fieldProps} />,
  // add any other custom fields here, using the 'type' as the key
};

const App = (): JSX.Element => {
  return (
    <div className="App">
      <FormProvider fieldComponents={fieldComponents}>
        <TutimWizard
          onSubmit={console.log}
          config={{
            fields: [
              { key: 'textField', label: 'Text Field', type: 'text' },
              customFieldConfig, // use customFieldConfig to specify the 'type' and 'Field' props
              customFieldConfig2, // use customFieldConfig2 to specify the 'type' and 'Field' props
            ],
          }}
        />
      </FormProvider>
    </div>
  );
};

export default App;
```

In this example, the `CustomField` and `CustomField2` components are added to the `fieldComponents` object with the keys `'custom-field'` and `'custom-field-2'`, respectively. This means that any form field with an `type` of `'custom-field'` will use the `CustomField` component to render the field, and any form field with an `type` of `'custom-field-2'` will use the `CustomField2` component to render the field.

```
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.tutim.io/api-reference/fields/customfield.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
