import { type FormEvent, type ReactNode } from "react"; import type { AnalyticsAction } from "./analytics-actions.js"; export type FormVariant = "dialog" | "sheet" | "page" | "inline"; export type FormDialogSize = "sm" | "md" | "lg"; type SubmitResult = void | boolean; /** Provides Radix title, description and close parts to a frame inside a Radix dialog. */ export declare function FormDialogChromeProvider({ children }: { children: ReactNode; }): import("react").JSX.Element; export interface FormFrameProps { /** Presentation. Default "dialog". */ variant?: FormVariant | undefined; /** Names the object and the outcome: "New variable set", "Replace value". */ title: ReactNode; /** One sentence under the title. */ description?: ReactNode | undefined; /** A 40px tile or icon before the title (dialog and sheet only). */ leading?: ReactNode | undefined; /** Right of the title, for example a status badge. */ headerAside?: ReactNode | undefined; /** The fields. Wrap them in `FieldStack` for the 24px rhythm. */ children?: ReactNode | undefined; /** Verb + object: "Create variable set". */ submitLabel: ReactNode; /** Shown with a spinner while submitting: "Creating…". */ pendingLabel?: ReactNode | undefined; /** Closed product-analytics label for the primary button (never derived from text). */ submitAnalyticsAction?: AnalyticsAction | null | undefined; /** Pass null to hide Cancel (for example on a one-time secret step). */ cancelLabel?: ReactNode | null | undefined; /** "destructive" fills the primary in danger, for confirmations. */ tone?: "default" | "destructive" | undefined; onSubmit?: ((event: FormEvent) => SubmitResult | Promise) | undefined; /** Called after a successful submit. */ onSubmitted?: (() => void) | undefined; onCancel?: (() => void) | undefined; /** Controlled submitting state. Defaults to tracking `onSubmit`'s promise. */ pending?: boolean | undefined; onPendingChange?: ((pending: boolean) => void) | undefined; /** A server error, rendered inside the form above the footer. */ error?: ReactNode | undefined; submitDisabled?: boolean | undefined; /** Why the primary is disabled, shown in the footer: who can fix it. */ disabledReason?: ReactNode | undefined; /** Quiet content at the start of the footer, for example "Runs with your connected accounts." */ footerStart?: ReactNode | undefined; /** Replaces the Cancel and primary buttons entirely; false hides the footer (a step that waits). */ footer?: ReactNode | false | undefined; /** Close button in the header (dialog and sheet). Default true. */ showClose?: boolean | undefined; /** Back link above the title (page only). */ back?: { label: ReactNode; href?: string | undefined; onClick?: (() => void) | undefined; } | undefined; /** What gets focus when an overlay opens: the first field (default) or Cancel. */ initialFocus?: "field" | "cancel" | undefined; /** The current values are loading (an edit form): fields show as placeholders. */ loading?: boolean | undefined; /** How many field placeholders to show while loading. Default 3. */ loadingFields?: number | undefined; className?: string | undefined; bodyClassName?: string | undefined; } /** First focusable field in a form body, for initial focus and after a failed submit. */ export declare function firstFormField(root: ParentNode | null, invalidOnly?: boolean): HTMLElement | null; export declare function FormFrame({ variant, title, description, leading, headerAside, children, submitLabel, pendingLabel, submitAnalyticsAction, cancelLabel, tone, onSubmit, onSubmitted, onCancel, pending: pendingProp, onPendingChange, error, submitDisabled, disabledReason, footerStart, footer, showClose, back, initialFocus, loading, loadingFields, className, bodyClassName, }: FormFrameProps): import("react").JSX.Element; export interface FormOverlayProps extends Omit { open: boolean; onOpenChange: (open: boolean) => void; /** Optional trigger element, rendered with Radix `asChild`. */ trigger?: ReactNode | undefined; /** * When false, only Cancel, Close or Escape close it. Use it on a step that * shows something once (a new API key). Outside clicks never discard typed * input either way. */ dismissible?: boolean | undefined; onCancel?: (() => void) | undefined; /** * Where focus goes after closing. Defaults to the trigger, or to whatever * had focus when it opened (a button, or the ⋯ that owned a menu item). */ onCloseAutoFocus?: ((event: Event) => void) | undefined; } /** Shared open/close rules for FormDialog and FormSheet. */ export declare function useFormOverlay({ open, onOpenChange, dismissible, pending, onSubmitted, onCancel, onPendingChange, onCloseAutoFocus, hasTrigger, }: Pick & { hasTrigger?: boolean; }): { contentRef: import("react").RefObject; rootProps: { open: boolean; onOpenChange: (next: boolean) => void; }; contentProps: { ref: import("react").RefObject; onInput: () => void; onOpenAutoFocus: (event: Event) => void; onPointerDownOutside: (event: Event) => void; onEscapeKeyDown: (event: Event) => void; onCloseAutoFocus: (event: Event) => void; }; frameProps: { onPendingChange: (next: boolean) => void; onSubmitted: () => void; onCancel: () => void; }; }; export declare function FormDialog({ open, onOpenChange, trigger, size, dismissible, onCloseAutoFocus, onSubmitted, onCancel, onPendingChange, className, ...frame }: FormOverlayProps & { size?: FormDialogSize; }): import("react").JSX.Element; /** A full-page create form, for example /schedules/new. The footer sticks to the bottom. */ export declare function FormPage(props: Omit): import("react").JSX.Element; /** A form panel in the page flow. Keep it for one or two fields next to what they change. */ export declare function FormInline(props: Omit): import("react").JSX.Element; export {};