import type { ReactNode } from "react"; /** One block of the form; sections after the first are separated by a divider. */ export type FormDrawerSection = { /** Stable React key. */ id: string; /** Renders an h3 above the content; also names the section region. */ title?: string; /** Muted line under `title`; ignored without a title. */ description?: string; /** Body of the section, rendered below its title and description. */ content: ReactNode; }; /** Every user-facing string FormDrawer owns; pass the ones you localise. */ export type FormDrawerLabels = { /** Heading of the error summary. Defaults to "Please fix the following before saving". */ fixErrors: string; /** Defaults to "Discard changes?". */ discardTitle: string; /** Defaults to "You have unsaved changes. If you close now, they will be lost.". */ discardBody: string; /** Confirm button of the discard dialog. Defaults to "Discard". */ discard: string; /** Cancel button of the discard dialog, focused on open. Defaults to "Keep editing". */ keepEditing: string; }; /** Sectioned create/edit form in a Drawer: error summary, sticky footer, and a discard-changes confirm when closing while dirty. */ export interface FormDrawerProps { /** Controlled open state; the drawer stays closed until this is true. */ isOpen: boolean; /** Called once the user has really closed: clean close, or Discard confirmed. Never called while `isSubmitting`. */ onClose: () => void; /** Drawer heading; also the accessible name of the dialog and of the form. */ title: string; /** Muted line under the title. */ description?: string; /** Form blocks rendered top to bottom in array order. */ sections: FormDrawerSection[]; /** Validation messages shown as a summary above the form; the summary takes focus after a submit that leaves any. */ errors?: string[]; /** Closing (X, Esc, overlay, Cancel) asks for confirmation while true. */ isDirty: boolean; /** Fires on submit (button or Enter in a field); the browser's own validation is off, so validate in the handler. */ onSubmit: () => void; /** Spins the submit button, disables Cancel and blocks every close path. Set it synchronously in `onSubmit` so error focus waits for the result. */ isSubmitting?: boolean; /** Disables the primary button and swallows Enter and any other form submit, so `onSubmit` never fires; unlike `isSubmitting`, Cancel and every close path stay live. */ isSubmitDisabled?: boolean; /** Defaults to "Save". */ submitLabel?: string; /** Defaults to "Cancel". */ cancelLabel?: string; /** Rendered left of Cancel, e.g. a ghost "Save as draft" Button. */ secondaryAction?: ReactNode; /** Drawer width. Defaults to "md". */ size?: "sm" | "md" | "lg"; /** Overrides for the built-in strings. */ labels?: Partial; /** Set on the form; the error summary and submit button get `-errors` / `-submit` suffixes. Defaults to "form-drawer". */ "data-testid"?: string; }