@payfit/unity-components
Version:
93 lines (92 loc) • 4.07 kB
TypeScript
import { StandardSchemaV1 } from '@standard-schema/spec';
import { ForwardedRef, ReactNode } from 'react';
import { FieldPath, FieldValues } from 'react-hook-form';
import { Schema } from '../../hooks/use-form.types.js';
import { LabelProps } from '../label/Label.js';
import { MultiSelectProps } from '../multi-select/MultiselectTypes.js';
interface FieldProps<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>> extends Pick<LabelProps, 'isRequired' | 'requiredVariant'> {
/** The name of the field, which should match the form schema. */
name: TName;
/** The label for the multi-select field. */
label: string;
/** Helper text to display below the multi-select field. */
helperText?: ReactNode;
/** Feedback text to display below the multi-select field. */
feedbackText?: ReactNode;
/** A contextual link to display below the multi-select field. */
contextualLink?: ReactNode;
}
type BaseMultiSelectProps<TItems = undefined> = Omit<MultiSelectProps<TItems>, 'value' | 'defaultValue' | 'onChange' | 'aria-labelledby' | 'aria-label'>;
export type MultiSelectFieldProps<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>, TItems = undefined> = FieldProps<TFieldValues, TName> & BaseMultiSelectProps<TItems>;
/**
* The `MultiSelectField` component renders a full field that allows selecting multiple items from a dropdown list, and integrates with the `Form` component automatically.
*
* The component uses a single generic parameter `TItems` that infers the item type from the `items` prop
* for the dynamic API, or defaults to `undefined` for the static API (using `children` directly).
* @example Static API
* ```tsx
* const schema = z.object({
* fruits: z.set(z.string()),
* })
*
* function MyForm() {
* const { Form } = useUnityForm(schema)
*
* return (
* <Form action={handleSubmit}>
* <MultiSelectField<typeof schema>
* name="fruits"
* label="Select fruits"
* >
* <MultiSelectOption value="apple">Apple</MultiSelectOption>
* <MultiSelectOption value="banana">Banana</MultiSelectOption>
* <MultiSelectOption value="orange">Orange</MultiSelectOption>
* </MultiSelectField>
* </Form>
* )
* }
* ```
* @example Dynamic API
* ```tsx
* interface Fruit { id: string; name: string }
* const fruits = new Set<Fruit>([...])
*
* const schema = z.object({
* fruits: z.set(z.string()),
* })
*
* function MyForm() {
* const { Form } = useUnityForm(schema)
*
* return (
* <Form action={handleSubmit}>
* <MultiSelectField<typeof schema, Set<Fruit>>
* name="fruits"
* label="Select fruits"
* items={fruits}
* getItemValue={fruit => fruit.id}
* >
* {fruit => (
* <MultiSelectOption value={fruit.id}>{fruit.name}</MultiSelectOption>
* )}
* </MultiSelectField>
* </Form>
* )
* }
* ```
* @note The schema type parameter is needed to ensure type safety with the form's schema. If you omit it, the `name` prop will not be type-safe.
* @remarks
* [API & Docs](https://unity-components.payfit.io/?path=/docs/forms-multiselectfield--docs) • [Design Guidelines](https://www.payfit.design/24f360409/p/928776-multiselect)
* @deprecated React Hook Form components are deprecated. Use the TanStack Form version instead.
* @see Storybook docs: https://unity-components.payfit.io/?path=/docs/forms-introduction-to-unity-forms--docs
*/
/**
* Component type for MultiSelectField with proper generic support
*/
type MultiSelectFieldComponent = <TSchema extends Schema = Schema, TItems = undefined>(props: MultiSelectFieldProps<StandardSchemaV1.InferOutput<TSchema>, FieldPath<StandardSchemaV1.InferOutput<TSchema>>, TItems> & {
ref?: ForwardedRef<HTMLButtonElement>;
}) => React.JSX.Element;
export declare const MultiSelectField: MultiSelectFieldComponent & {
displayName: string;
};
export {};