import { ReactNode } from 'react'; import { RegisterOptions, UseFormReturn } from 'react-hook-form'; import { BoxProps } from '../Box'; import { MinimalCheckboxProps } from '../ConnectedForm'; import { CheckboxLabelUnion, TextAreaProps } from '../Form'; import { CheckboxPaddingProps } from '../Form/types'; import { ColumnProps } from '../Layout'; import { InfoTipSubComponentProps } from '../Tip/InfoTip/type-utils'; import { Text, TextProps } from '../Typography/Text'; export interface BaseFormInputProps { className?: string; required?: boolean; disabled?: boolean; error?: boolean; } export type BaseFormField = { defaultValue?: Value; customError?: string; disabled?: boolean; /** * Whether the label should be hidden visually and not take up space. */ hideLabel?: boolean; /** * HTML id to use instead of the name. */ id?: string; /** * InfoTip to display next to the field label. The InfoTip button is * automatically labelled by the field label. To override this behavior, * provide `ariaLabel` or `ariaLabelledby`. */ infotip?: InfoTipSubComponentProps; isSoloField?: boolean; name: string; onUpdate?: (value: Value) => void; size: ColumnProps['size']; rowspan?: ColumnProps['rowspan']; }; export type GridFormCheckboxField = BaseFormField & CheckboxPaddingProps & { description: string; label?: React.ReactNode; multiline?: boolean; validation?: RegisterOptions; type: 'checkbox'; }; export type NestedGridFormCheckboxOption = Omit & CheckboxLabelUnion & { options?: NestedGridFormCheckboxOption[]; }; export type GridFormNestedCheckboxField = BaseFormField & CheckboxPaddingProps & { label?: React.ReactNode; options: NestedGridFormCheckboxOption[]; validation?: RegisterOptions; type: 'nested-checkboxes'; }; export type GridFormCustomFieldProps = { className?: string; error?: string; field: GridFormCustomField | GridFormCustomGroupField; register: UseFormReturn['register']; setValue: (value: any) => void; }; export type GridFormCustomField = BaseFormField & { label?: React.ReactNode; render: (props: GridFormCustomFieldProps) => React.ReactNode; validation?: RegisterOptions; type: 'custom'; }; export type GridFormCustomGroupField = BaseFormField & { label?: React.ReactNode; render: (props: GridFormCustomFieldProps) => React.ReactNode; validation?: RegisterOptions; type: 'custom-group'; }; export type BasicInputType = 'color' | 'date' | 'datetime-local' | 'email' | 'month' | 'number' | 'password' | 'search' | 'tel' | 'text' | 'time' | 'url' | 'week'; export type GridFormTextField = BaseFormField & { label: React.ReactNode; placeholder?: string; validation?: RegisterOptions; type: BasicInputType; }; export type GridFormRadioOption = Pick, 'infotip'> & { label: ReactNode; value: string; }; export type GridFormRadioGroupField = BaseFormField & { label: ReactNode | string; options: GridFormRadioOption[]; validation?: RegisterOptions; type: 'radio-group'; ariaLabel?: string; }; export type GridFormSelectField = BaseFormField & { label: React.ReactNode; options: string[] | Record; validation?: RegisterOptions; type: 'select'; }; export type GridFormFileField = BaseFormField & { label: React.ReactNode; validation?: RegisterOptions; type: 'file'; }; export type GridFormTextAreaField = BaseFormField & Pick & { label: React.ReactNode; validation?: RegisterOptions; type: 'textarea'; }; type HiddenField = Omit, 'size' | 'rowspan'>; export type GridFormHiddenField = HiddenField & { type: 'hidden'; }; export type GridFormSweetContainerField = HiddenField & { label: string; type: 'sweet-container'; }; export type GridFormField = GridFormCheckboxField | GridFormCustomField | GridFormCustomGroupField | GridFormNestedCheckboxField | GridFormRadioGroupField | GridFormTextField | GridFormSelectField | GridFormFileField | GridFormTextAreaField | GridFormHiddenField | GridFormSweetContainerField; type UnionValuesStartingWith = keyof { [Key in Base as Extract]: true; }; type FilterNestedEnumByPrefix = { [Key in keyof Type]: UnionValuesStartingWith; }; type RestrictedTitleVariant = FilterNestedEnumByPrefix, 'title'>; export type GridFormRequiredTextProps = { /** * Style overrides for the required text -- required text should be spaced apart from or stylistically different from the element above it. */ requiredTextProps?: React.ComponentProps; }; export type GridFormSectionTitleBaseProps = RestrictedTitleVariant & { title: string; as?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'; layout?: 'center' | 'left'; titleWrapperProps?: BoxProps; }; export type GridFormSectionProps = GridFormSectionTitleBaseProps & { fields: GridFormField[]; }; export type GridFormFieldsProps = GridFormField | GridFormSectionProps; export {};