import type { JSX } from "react"; import type { AttioRecord } from "../attio-record.js"; import type { DecoratedComboboxOption, DecoratedComboboxOptionsProvider, PlainComboboxOption, PlainComboboxOptionsProvider } from "../components/combobox.js"; import type { Fieldset } from "../components/fieldset.js"; import type { InputGroup } from "../components/input-group.js"; import type { FormAttioRecord } from "../forms/attio-record.js"; import type { PathTo, PathToArrayOf, ValueOf } from "../forms/path.js"; import type { FormString } from "../forms/string.js"; import type { FormValue } from "../forms/value.js"; import type { ObjectSlug } from "../object-slug.js"; export type FormSchema = Record; /** * Recursive type for validation errors that can be nested. * Each field can either be a string error message or a nested object of errors. */ export type ValidationErrors = Partial<{ [K in keyof T]: T[K] extends AttioRecord ? string : T[K] extends object ? ValidationErrors : string; }>; /** * A
component that must wrap all the fields and provide a submit handler. * * @example * ```tsx * { * console.log(values) * }}> * * * * * * * ``` */ type Form = (props: { /** The contents of the form, including layout and input components */ children: React.ReactNode; /** * The function to call when the form is submitted. * * `onSubmit` will NOT be called if there are validation errors. */ onSubmit: (values: ValueOf) => void | Promise; }) => JSX.Element; /** * A text input field. */ type TextInput = (props: { /** The type of the input field. Defaults to "text". */ type?: "text" | "email" | "password" | "tel" | "url"; /** The label of the input field */ label: string; /** The path to the value of the input field, e.g. `"name"` or `"address.street"` */ name: PathTo; /** The optional placeholder text of the input field */ placeholder?: string; /** Whether the input field is disabled */ disabled?: boolean; }) => JSX.Element; type TextArea = (props: { /** The label of the textarea */ label: string; /** The path to the value of the textarea, e.g. `"name"` or `"address.street"` */ name: PathTo; /** The optional placeholder text of the textarea */ placeholder?: string; /** Make the textarea resizable */ resizable?: boolean; /** Whether the textarea is disabled */ disabled?: boolean; }) => JSX.Element; /** * A number input field. */ type NumberInput = (props: { /** The label of the input field */ label: string; /** The path to the value of the input field, e.g. `"age"` or `"shipping.cost"` */ name: PathTo; /** The optional placeholder text of the input field */ placeholder?: string; /** Whether the input field is disabled */ disabled?: boolean; }) => JSX.Element; /** * A rich text input field. */ type RichTextInput = (props: { /** The label of the input field */ label: string; /** The path to the value of the input field, e.g. `"name"` or `"address.street"` */ name: PathTo; /** The optional placeholder text of the input field */ placeholder?: string; /** Whether the input field is disabled */ disabled?: boolean; }) => JSX.Element; /** * A radio group item. */ type RadioGroupItem = (props: { /** The value of the radio item */ value: string; /** The label of the radio item */ label: string; }) => JSX.Element; /** * A radio group input field. * * @experimental This component is experimental and should not be used yet. */ type RadioGroup = ((props: { /** The path to the value of the radio group field, e.g. "department" or "shipping.method" */ name: PathTo; /** Whether the radio group is disabled */ disabled?: boolean; /** The radio group items */ children: React.ReactNode; }) => JSX.Element) & { Item: RadioGroupItem; }; /** * A checkbox input field. */ type Checkbox = (props: { /** The label of the input field */ label: string; /** The path to the value of the input field, e.g. `"is_active"` or `"shipping.is_express"` */ name: PathTo; /** Whether the input field is disabled */ disabled?: boolean; }) => JSX.Element; /** * A toggle input field. */ type Toggle = (props: { /** The label of the input field */ label: string; /** The path to the value of the input field, e.g. `"is_active"` or `"shipping.is_express"` */ name: PathTo; /** Whether the input field is disabled */ disabled?: boolean; }) => JSX.Element; /** * A date time input field. */ type DateTimeInput = (props: { /** The label of the input field */ label: string; /** The path to the value of the input field, e.g. `"check_in_time"` or `"shipping.drop_off_time"` */ name: PathTo; /** Whether the input field is disabled */ disabled?: boolean; /** The optional placeholder text of the input field */ placeholder?: string; }) => JSX.Element; /** * A date (YYYY-MM-DD) input field. */ type PlainDateInput = (props: { /** The label of the input field */ label: string; /** The path to the value of the input field, e.g. `"dob"` or `"shipping.date"` */ name: PathTo; /** Whether the input field is disabled */ disabled?: boolean; /** The optional placeholder text of the input field */ placeholder?: string; }) => JSX.Element; /** * Base props for single-select combobox (value is a string). */ export interface BaseComboboxPropsSingle { /** The label of the combobox field */ label: string; /** The path to the value of the combobox field, e.g. `"mode"` or `"shipping.method"` */ name: PathTo; /** * The optional placeholder text for the search input * * @default "Search..." */ searchPlaceholder?: string; /** Whether the combobox field is disabled */ disabled?: boolean; } /** * Base props for multi-select combobox (value is an array of strings). */ export interface BaseComboboxPropsMulti { /** The label of the combobox field */ label: string; /** The path to the value of the combobox field, e.g. `"modes"` or `"shipping.methods"` */ name: PathToArrayOf>; /** * The optional placeholder text for the search input * * @default "Search..." */ searchPlaceholder?: string; /** Whether the combobox field is disabled */ disabled?: boolean; } /** * Base props common to all combobox variants. * Multi-select is automatically inferred from the path type: * - If the path points to a string, it's single-select * - If the path points to an array of strings, it's multi-select */ export type BaseComboboxProps = BaseComboboxPropsSingle | BaseComboboxPropsMulti; /** * Props for decorated combobox variant. */ export interface DecoratedComboboxProps { /** * If decorated, the combobox will be require decorated options. Defaults to true. */ decorated: true; /** * The options of the combobox field * * Either an array of options, or a provider that asynchronously fetches options. */ options: Array | DecoratedComboboxOptionsProvider; /** * The optional placeholder text or option of the combobox field **/ placeholder?: string | Omit; } /** * Props for plain combobox variant. */ export interface PlainComboboxProps { /** * If not decorated, the combobox will be plain. Defaults to false. */ decorated?: false; /** * The options of the combobox field * * Either an array of options, or a provider that asynchronously fetches options. */ options: Array | PlainComboboxOptionsProvider; /** * The optional placeholder text or option of the combobox field **/ placeholder?: string; } /** * A combobox input field. */ type Combobox = (props: BaseComboboxProps & (DecoratedComboboxProps | PlainComboboxProps)) => JSX.Element; type AttioRecordCombobox = (props: { /** The label of the Attio record combobox field */ label: string; /** * The path to the value of the Attio record combobox field, e.g. `"company"` or `"team.staffManager"`. * Can point to either a single attio-record or an array of attio-records. * If the path points to an array, the combobox will support multiselect. */ name: PathTo | PathToArrayOf>; /** The optional placeholder text for the Attio record combobox field */ placeholder?: string; /** * The optional placeholder text for the search input * * @default "Search..." */ searchPlaceholder?: string; /** * The slugs of Attio objects that can be selected. * * @default ["people", "companies", "deals", "workspaces", "users"] */ object?: ObjectSlug | Array; /** Whether the record combobox field is disabled */ disabled?: boolean; }) => JSX.Element; type AttioUserCombobox = (props: { /** * The path to the value of the Attio user combobox field, e.g. `"assignedTo"` or `"team.manager"`. * Can point to either a single string or an array of strings. * If the path points to an array, the combobox will support multiselect. */ name: PathTo | PathToArrayOf>; /** The label of the Attio user combobox field */ label: string; /** The optional placeholder text for the Attio user combobox field */ placeholder?: string; /** * The optional placeholder text for the search input * * @default "Search..." */ searchPlaceholder?: string; /** Whether the Attio user combobox field is disabled */ disabled?: boolean; }) => JSX.Element; /** * A component used to render a collection of inputs. */ type Collection = >(props: { /** The label of the collection field */ label: string; /** The path to the value of the collection field, e.g. `"items"` or `"shipping.items"` */ name: TPath; /** * A render prop that receives the path and index of one of the items and renders * the inputs for that item */ children: (args: { path: `${TPath}.${number}`; index: number; }) => React.ReactNode; }) => JSX.Element; /** * A component used to group inputs in a collection together */ type CollectionItem = (props: { /** The label of the collection item */ label: string; /** The inputs of the collection item */ children: React.ReactNode; }) => JSX.Element; /** * A submit button for the form. * * If the form is rendered inside a dialog, the submit button will be placed at the bottom of the dialog. */ type SubmitButton = (props: { /** The label of the submit button */ label: string; }) => JSX.Element; export interface WithStateProps { values?: TValues; submitting?: TSubmitting; errors?: TErrors; children: (state: { values: TValues extends true ? ValueOf : never; submitting: TSubmitting extends true ? boolean : never; errors: TErrors extends true ? Record : never; }) => JSX.Element; } /** * A component that provides the form state via a render prop. * * You may specifically request various parts of form state, such as * `values`, `submitting`, and `errors`. This component will rerender * whenever any of the values requested change. */ type WithState = { (props: WithStateProps): JSX.Element; (props: WithStateProps): JSX.Element; (props: WithStateProps): JSX.Element; (props: WithStateProps): JSX.Element; (props: WithStateProps): JSX.Element; (props: WithStateProps): JSX.Element; (props: WithStateProps): JSX.Element; (props: WithStateProps): JSX.Element; }; export interface FormApi { /** * Submits the form. * * This will validate the form and call the `onSubmit` handler. */ submit: () => void; /** * Changes the value of a field. */ change: >(path: TPath, value: ValueOf[TPath]) => void; /** * The
component to wrap the fields of this form and provide a submit handler. */ Form: Form; /** * A text input field. */ TextInput: TextInput; /** * A text area field. */ TextArea: TextArea; /** * A number input field. */ NumberInput: NumberInput; /** * A rich text input field. */ RichTextInput: RichTextInput; /** * A radio group input field. */ RadioGroup: RadioGroup; /** * A checkbox input field. */ Checkbox: Checkbox; /** * A component for grouping input fields. * * It will automatically wrap after the third child. */ InputGroup: typeof InputGroup; /** * A fieldset component that groups related form inputs together with a legend. * Can contain either a single RadioGroup or multiple Checkbox inputs, but not mixed. */ Fieldset: typeof Fieldset; /** * A toggle input field. */ Toggle: Toggle; /** * A date time input field. */ DateTimeInput: DateTimeInput; /** * A date (YYYY-MM-DD) input field. */ PlainDateInput: PlainDateInput; /** * A combobox input field. */ Combobox: Combobox; /** * A Attio user combobox input field. */ AttioUserCombobox: AttioUserCombobox; /** * A Attio record combobox input field. */ AttioRecordCombobox: AttioRecordCombobox; /** * A component used to render a collection of inputs. */ Collection: Collection; /** * A component used to group inputs in a collection together. */ CollectionItem: CollectionItem; /** * A submit button for the form. */ SubmitButton: SubmitButton; /** * A component that provides the form state via a render prop. */ WithState: WithState; } /** * Creates a form API for a given schema and initial values. * * @example * ```tsx * const api = useForm({ * name: Forms.string(), * age: Forms.number(), * isActive: Forms.boolean(), * isExpress: Forms.boolean(), * }, { * name: "John", * age: 30, * isActive: true, * isExpress: false, * }); * ``` */ export declare function useForm(schema: TSchema, initialValues: Partial>, /** * Optional function to validate the form. * * Errors should be returned as a record of field names to error messages. * The keys must match the keys of the form schema. * * Errors can be nested for complex objects. e.g. * ```ts * { * shipping: { * street: "Street is required" * } * } * ``` * * Errors given here will be overridden by errors generated by the form schema. */ validate?: (values: ValueOf) => ValidationErrors>): FormApi; export {}; //# sourceMappingURL=use-form.d.ts.map