import type { FieldRules } from '../composables/useForm' import type { OptionPrimitive, SelectOption } from './components' import type { AccessControlled } from '../permissions' // --------------------------------------------------------------------------- // Field types // --------------------------------------------------------------------------- /** All supported field types that map to SDK components. */ export type FormFieldType = | 'text' | 'email' | 'password' | 'secret' | 'number' | 'tel' | 'url' | 'search' | 'textarea' | 'select' | 'multiselect' | 'checkbox' | 'toggle' | 'radio' | 'slider' | 'tags' | 'date' | 'time' | 'datetime' | 'file' | 'path' | 'formula' | 'sequence' | 'molecule' | 'concentration' | 'unit' // --------------------------------------------------------------------------- // Conditions (JSON-serializable) // --------------------------------------------------------------------------- export type FieldCondition = | { field: string; eq: unknown } | { field: string; neq: unknown } | { field: string; gt: number } | { field: string; lt: number } | { field: string; gte: number } | { field: string; lte: number } | { field: string; in: unknown[] } | { field: string; notIn: unknown[] } | { field: string; truthy: true } | { field: string; falsy: true } | { field: string; contains: string } | { and: FieldCondition[] } | { or: FieldCondition[] } | { not: FieldCondition } // --------------------------------------------------------------------------- // Validation (JSON-safe subset of FieldRules) // --------------------------------------------------------------------------- export interface FieldValidation { required?: boolean | string minLength?: number | { value: number; message: string } maxLength?: number | { value: number; message: string } min?: number | { value: number; message: string } max?: number | { value: number; message: string } /** Pattern as a string (converted to RegExp at runtime). */ pattern?: string | { value: string; message: string } email?: boolean | string } // --------------------------------------------------------------------------- // Field schema // --------------------------------------------------------------------------- export interface FormFieldSchema extends AccessControlled { name: string label: string type: FormFieldType defaultValue?: unknown placeholder?: string hint?: string icon?: string | string[] iconColor?: string iconBg?: string size?: 'sm' | 'md' | 'lg' disabled?: boolean readonly?: boolean validation?: FieldValidation condition?: FieldCondition /** Grid column span (1-3). Defaults to 1. */ colSpan?: number /** Extra props passed directly to the underlying component. */ props?: Record /** Element type for `tags` fields; `number` parses each entered tag back to a number. */ itemType?: 'string' | 'number' } export type FormOptionInput = SelectOption | OptionPrimitive // --------------------------------------------------------------------------- // Section schema // --------------------------------------------------------------------------- export interface FormSectionSchema { id: string title: string description?: string collapsible?: boolean defaultOpen?: boolean /** Number of grid columns (1-3). Defaults to 1. */ columns?: 1 | 2 | 3 fields: FormFieldSchema[] condition?: FieldCondition } // --------------------------------------------------------------------------- // Wizard step schema // --------------------------------------------------------------------------- export interface FormStepSchema { id: string label: string description?: string icon?: string optional?: boolean sections: FormSectionSchema[] } // --------------------------------------------------------------------------- // Top-level form schema // --------------------------------------------------------------------------- export type FormSchema = | { sections: FormSectionSchema[] steps?: never submitLabel?: string cancelLabel?: string showCancel?: boolean } | { sections?: never steps: FormStepSchema[] submitLabel?: string cancelLabel?: string showCancel?: boolean } // --------------------------------------------------------------------------- // Enhancements (TS-only, NOT JSON-serializable) // --------------------------------------------------------------------------- export interface FieldEnhancement = Record> { /** Custom validator appended to the field's rules. */ validate?: (value: unknown, data: T) => string | undefined | null /** Dynamic visibility (overrides schema condition if both present). */ visible?: (data: T) => boolean /** Dynamic options for select/multiselect/radio fields. */ options?: (data: T) => FormOptionInput[] /** Dynamic extra props merged into the component. */ props?: (data: T) => Record } export interface FormEnhancements = Record> { /** Per-field enhancements keyed by field name. */ fields?: Partial>> /** Called on successful submit. */ onSubmit?: (data: T) => Promise | void /** Transform data before submit (return transformed copy). */ transform?: (data: T) => T | Record /** Called when any field value changes. */ onFieldChange?: (field: keyof T, value: unknown, data: T) => void } // --------------------------------------------------------------------------- // useFormBuilder return type // --------------------------------------------------------------------------- export interface UseFormBuilderReturn> { /** Underlying useForm return. */ form: import('../composables/useForm').UseFormReturn /** Validation rules derived from schema + enhancements. */ rules: Partial> /** Whether a field is currently visible. */ isFieldVisible: (name: string) => boolean /** Whether a section is currently visible. */ isSectionVisible: (id: string) => boolean /** All flattened field schemas. */ fields: FormFieldSchema[] /** Resolve final component props for a field. */ getResolvedFieldProps: (field: FormFieldSchema) => Record /** Get options for a select/radio/multiselect field. */ getFieldOptions: (name: string) => FormOptionInput[] | undefined // Wizard-specific currentStep: import('vue').Ref isCurrentStepValid: import('vue').ComputedRef goNext: () => boolean goBack: () => void goToStep: (index: number) => void // Actions validate: () => boolean reset: (values?: Partial) => void submit: () => Promise /** Replace the active schema and rebuild field state for still-mounted forms. */ updateSchema: (schema: FormSchema, values?: Partial) => void }