@petrarca/sonnet-forms 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/FormFieldWrapper.tsx","../src/formFieldUtils.ts","../src/FormInput.tsx","../src/FormTextarea.tsx","../src/FormNumberInput.tsx","../src/FormCheckbox.tsx","../src/FormSelect.tsx","../src/FormMultiSelect.tsx","../src/FormTagsInput.tsx","../src/FormQuantityInput.tsx","../src/FormActions.tsx","../src/ExtraPropertiesCard.tsx","../src/JsonSchemaFormRenderer.tsx","../src/widgets/types.ts","../src/widgets/TextInputWidget.tsx","../src/widgets/TextareaWidget.tsx","../src/widgets/NumberWidget.tsx","../src/widgets/CheckboxWidget.tsx","../src/widgets/SelectWidget.tsx","../src/widgets/TagsInputWidget.tsx","../src/widgets/JsonEditorWidget.tsx","../src/widgets/EntitySelectWidget.tsx","../src/widgets/ObjectWidget.tsx","../src/hooks/useNestedFormContext.ts","../src/NestedFormContext.tsx","../src/templates/DefaultObjectContainerTemplate.tsx","../src/widgets/ArrayWidget.tsx","../src/templates/DefaultArrayItemTemplate.tsx","../src/templates/gridUtils.ts","../src/templates/DefaultArrayHeaderTemplate.tsx","../src/widgets/QuantityWidget.tsx","../src/widgets/widgetResolver.ts","../src/widgets/index.ts","../src/templates/HorizontalArrayItemTemplate.tsx","../src/templates/index.ts","../src/FormFieldRenderer.tsx","../src/hooks/useFormEngine.ts","../src/hooks/orderProperties.ts","../src/hooks/useResolvedSchema.ts"],"sourcesContent":["/**\n * FormFieldWrapper - Shared label / description / error chrome for form fields.\n *\n * Eliminates duplication across FormInput, FormNumberInput, FormQuantityInput,\n * etc. Each field component renders its control as `children` and delegates\n * the surrounding chrome here.\n *\n * Supports two modes:\n * - Normal: label, children, description, error displayed vertically\n * - Compact: suppresses label, description, error text (for grid layouts)\n */\n\nimport React from \"react\";\nimport { cn } from \"@petrarca/sonnet-core\";\n\nexport interface FormFieldWrapperProps {\n /** Field id -- wired to the label's htmlFor */\n inputId: string;\n /** Visible label text (false = explicitly hidden) */\n label?: string | false;\n /** Helper text shown below the control */\n description?: string;\n /** Validation error message (takes precedence over description for aria-describedby) */\n error?: string;\n /** Shows a required asterisk next to the label */\n required?: boolean;\n /**\n * Compact mode -- suppresses label, description, and error text so the\n * cell height stays fixed in horizontal grid layouts. Error state is\n * still communicated via the control's own styling (e.g. red border).\n */\n compact?: boolean;\n /** Additional class name for the outer wrapper div */\n className?: string;\n /** The form control(s) */\n children: React.ReactNode;\n}\n\n/**\n * FormFieldWrapper renders label, children (the control), description, and\n * error in the standard vertical layout used by all form field components.\n */\nexport function FormFieldWrapper({\n inputId,\n label,\n description,\n error,\n required,\n compact,\n className,\n children,\n}: FormFieldWrapperProps) {\n const showChrome = !compact;\n\n return (\n <div className={cn(showChrome && \"space-y-2\", className)}>\n {showChrome && !!label && (\n <label\n htmlFor={inputId}\n className=\"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\"\n >\n {label}\n {required && <span className=\"ml-1 text-destructive\">*</span>}\n </label>\n )}\n {showChrome && description && (\n <p\n id={`${inputId}-description`}\n className=\"text-sm text-muted-foreground\"\n >\n {description}\n </p>\n )}\n {children}\n {showChrome && error && (\n <p\n id={`${inputId}-error`}\n className=\"text-sm font-medium text-destructive\"\n >\n {error}\n </p>\n )}\n </div>\n );\n}\n","/**\n * Shared utility functions for form field components.\n * Kept separate from FormFieldWrapper so the wrapper file exports only\n * components (required for React fast-refresh).\n */\n\n/**\n * Returns the correct aria-describedby id for a form control:\n * - error id when there is an error (screen readers announce errors immediately)\n * - description id when there is only a description\n * - undefined when neither is present\n */\nexport function getAriaDescribedBy(\n inputId: string,\n error: string | undefined,\n description: string | undefined,\n): string | undefined {\n if (error) return `${inputId}-error`;\n if (description) return `${inputId}-description`;\n return undefined;\n}\n\n/**\n * Compact-aware version of getAriaDescribedBy.\n * In compact mode, label/description/error text is not rendered, so\n * aria-describedby should be undefined.\n */\nexport function getAriaDescribedByCompact(\n inputId: string,\n error: string | undefined,\n description: string | undefined,\n compact: boolean | undefined,\n): string | undefined {\n if (compact) return undefined;\n return getAriaDescribedBy(inputId, error, description);\n}\n\n/**\n * In compact mode, when label text is hidden, expose it as aria-label\n * so screen readers still announce the field purpose.\n */\nexport function getCompactAriaLabel(\n label: string | false | undefined,\n compact: boolean | undefined,\n): string | undefined {\n if (compact && label) return String(label);\n return undefined;\n}\n\n/**\n * In compact mode, expose the error as a native tooltip so sighted users\n * can hover to see the validation message.\n */\nexport function getCompactTitle(\n error: string | undefined,\n compact: boolean | undefined,\n): string | undefined {\n if (compact && error) return error;\n return undefined;\n}\n\n/**\n * Resolve a `label?: string | false` prop into `string | undefined` for\n * FormFieldWrapper, which does not accept `false` directly.\n * `false` means \"explicitly hidden\"; `undefined` means \"not provided\".\n */\nexport function resolveFieldLabel(\n label: string | false | undefined,\n): string | undefined {\n if (label === false) return undefined;\n return label ?? undefined;\n}\n","/**\n * FormInput - Input wrapper with label, description, and error support\n *\n * Wraps shadcn Input with form field features to match Mantine TextInput API:\n * - Label with required indicator\n * - Description text\n * - Error message display\n * - Proper accessibility attributes\n */\n\nimport React, { useId } from \"react\";\nimport { Input } from \"@petrarca/sonnet-ui\";\nimport { cn } from \"@petrarca/sonnet-core\";\nimport { FormFieldWrapper } from \"./FormFieldWrapper\";\nimport {\n getAriaDescribedByCompact,\n getCompactAriaLabel,\n getCompactTitle,\n} from \"./formFieldUtils\";\n\nexport interface FormInputProps\n extends React.ComponentPropsWithoutRef<typeof Input> {\n /** Input label (false = hide label) */\n label?: string | false;\n /** Description text shown below label */\n description?: string;\n /** Error message to display */\n error?: string;\n /** Whether the field is required */\n required?: boolean;\n /** Additional class name for the wrapper */\n wrapperClassName?: string;\n /** Right section content (e.g., icons, buttons) */\n rightSection?: React.ReactNode;\n /** Width of the right section in pixels (for padding adjustment) */\n rightSectionWidth?: number;\n /**\n * Compact mode -- suppresses label, description, and error text so the\n * cell height stays fixed in horizontal grid layouts. Error state is\n * still communicated via a red border on the input.\n */\n compact?: boolean;\n}\n\n/**\n * FormInput component with label, description, and error handling\n */\nexport const FormInput = React.forwardRef<HTMLInputElement, FormInputProps>(\n (\n {\n label,\n description,\n error,\n required,\n wrapperClassName,\n className,\n id,\n rightSection,\n rightSectionWidth,\n compact,\n ...props\n },\n ref,\n ) => {\n const generatedId = useId();\n const inputId = id ?? generatedId;\n\n const paddingStyle = rightSectionWidth\n ? { paddingRight: `${rightSectionWidth}px` }\n : undefined;\n\n return (\n <FormFieldWrapper\n inputId={inputId}\n label={label === false ? undefined : label}\n description={description}\n error={error}\n required={required}\n compact={compact}\n className={wrapperClassName}\n >\n <div className=\"relative\">\n <Input\n id={inputId}\n ref={ref}\n required={required}\n style={paddingStyle}\n className={cn(\n error && \"border-destructive focus-visible:ring-destructive\",\n className,\n )}\n aria-invalid={error ? \"true\" : \"false\"}\n aria-describedby={getAriaDescribedByCompact(\n inputId,\n error,\n description,\n compact,\n )}\n aria-label={getCompactAriaLabel(label, compact)}\n title={getCompactTitle(error, compact)}\n {...props}\n />\n {rightSection && (\n <div className=\"absolute top-1/2 -translate-y-1/2 right-2 flex items-center gap-1\">\n {rightSection}\n </div>\n )}\n </div>\n </FormFieldWrapper>\n );\n },\n);\n\nFormInput.displayName = \"FormInput\";\n","/**\n * FormTextarea - Textarea wrapper with label, description, error, and autosize support\n *\n * Wraps shadcn Textarea with form field features to match Mantine Textarea API:\n * - Label with required indicator\n * - Description text\n * - Error message display\n * - Auto-resize functionality (via useEffect)\n * - Proper accessibility attributes\n */\n\nimport React, { useEffect, useId, useRef } from \"react\";\nimport { Textarea } from \"@petrarca/sonnet-ui\";\nimport { cn } from \"@petrarca/sonnet-core\";\nimport { FormFieldWrapper } from \"./FormFieldWrapper\";\nimport { getAriaDescribedBy } from \"./formFieldUtils\";\n\nexport interface FormTextareaProps\n extends React.ComponentPropsWithoutRef<typeof Textarea> {\n /** Textarea label (false = hide label) */\n label?: string | false;\n /** Description text shown below label */\n description?: string;\n /** Error message to display */\n error?: string;\n /** Whether the field is required */\n required?: boolean;\n /** Additional class name for the wrapper */\n wrapperClassName?: string;\n /** Enable auto-resize behavior (default: false) */\n autosize?: boolean;\n /** Minimum number of rows when autosize is enabled (default: 3) */\n minRows?: number;\n /** Right section content (e.g., action buttons) */\n rightSection?: React.ReactNode;\n /** Width of the right section in pixels (for padding adjustment) */\n rightSectionWidth?: number;\n}\n\n// -- Hooks ----------------------------------------------------------------\n\n/** Merge a forwarded ref with an internal ref. */\nfunction useMergedRef(\n forwardedRef: React.ForwardedRef<HTMLTextAreaElement>,\n internalRef: React.RefObject<HTMLTextAreaElement | null>,\n) {\n return (element: HTMLTextAreaElement | null) => {\n internalRef.current = element;\n if (typeof forwardedRef === \"function\") {\n forwardedRef(element);\n } else if (forwardedRef) {\n forwardedRef.current = element;\n }\n };\n}\n\n/** Auto-resize the textarea to fit its content. */\nfunction useAutoResize(\n ref: React.RefObject<HTMLTextAreaElement | null>,\n value: React.ComponentPropsWithoutRef<typeof Textarea>[\"value\"],\n autosize: boolean,\n minRows: number,\n) {\n useEffect(() => {\n if (!autosize || !ref.current) return;\n const textarea = ref.current;\n textarea.style.height = \"auto\";\n const newHeight = Math.max(textarea.scrollHeight, minRows * 24);\n textarea.style.height = `${newHeight}px`;\n }, [value, autosize, minRows, ref]);\n}\n\n// -- Helpers --------------------------------------------------------------\n\n/** Build the textarea className from state flags. */\nfunction textareaClassName(\n error: string | undefined,\n autosize: boolean,\n className: string | undefined,\n) {\n return cn(\n error && \"border-destructive focus-visible:ring-destructive\",\n autosize && \"resize-none overflow-hidden\",\n \"h-full\",\n className,\n );\n}\n\n// -- FormTextarea ---------------------------------------------------------\n\n/**\n * FormTextarea component with label, description, error, and autosize handling\n */\nexport const FormTextarea = React.forwardRef<\n HTMLTextAreaElement,\n FormTextareaProps\n>((allProps, ref) => {\n const {\n label,\n description,\n error,\n required,\n wrapperClassName,\n className,\n id,\n value,\n onChange,\n rightSection,\n rightSectionWidth,\n ...props\n } = allProps;\n const autosize = allProps.autosize ?? false;\n const minRows = allProps.minRows ?? 3;\n\n const generatedId = useId();\n const textareaId = id ?? generatedId;\n const internalRef = useRef<HTMLTextAreaElement | null>(null);\n const setRefs = useMergedRef(ref, internalRef);\n\n useAutoResize(internalRef, value, autosize, minRows);\n\n const paddingStyle = rightSectionWidth\n ? { paddingRight: `${rightSectionWidth}px` }\n : undefined;\n\n const effectiveRows = autosize ? minRows : props.rows;\n const resolvedLabel = label === false ? undefined : label;\n\n return (\n <FormFieldWrapper\n inputId={textareaId}\n label={resolvedLabel}\n description={description}\n error={error}\n required={required}\n className={cn(\"flex flex-col\", wrapperClassName)}\n >\n <div className=\"relative flex-1 min-h-0\">\n <Textarea\n id={textareaId}\n ref={setRefs}\n value={value}\n onChange={onChange}\n required={required}\n rows={effectiveRows}\n className={textareaClassName(error, autosize, className)}\n style={paddingStyle}\n aria-invalid={error ? \"true\" : \"false\"}\n aria-describedby={getAriaDescribedBy(textareaId, error, description)}\n {...props}\n />\n {rightSection && (\n <div className=\"absolute top-2 right-2 flex items-start gap-1\">\n {rightSection}\n </div>\n )}\n </div>\n </FormFieldWrapper>\n );\n});\n\nFormTextarea.displayName = \"FormTextarea\";\n","/**\n * FormNumberInput - Number input wrapper with label, description, error, and numeric constraints.\n */\n\nimport React, { useId } from \"react\";\nimport { Input } from \"@petrarca/sonnet-ui\";\nimport { cn } from \"@petrarca/sonnet-core\";\nimport { FormFieldWrapper } from \"./FormFieldWrapper\";\nimport { getAriaDescribedBy } from \"./formFieldUtils\";\n\nexport interface FormNumberInputProps {\n /** Input value */\n value?: number | string;\n /** Input label */\n label?: string;\n /** Description text shown below input */\n description?: string;\n /** Error message to display */\n error?: string;\n /** Placeholder text */\n placeholder?: string;\n /** Whether the field is required */\n required?: boolean;\n /** Whether the input is disabled */\n disabled?: boolean;\n /** Whether the input is read-only */\n readOnly?: boolean;\n /** Minimum value */\n min?: number;\n /** Maximum value */\n max?: number;\n /** Step increment/decrement value */\n step?: number;\n /** Allow decimal values (if false, only integers) */\n allowDecimal?: boolean;\n /** Change handler - receives number or undefined */\n onChange?: (value: number | undefined) => void;\n /** Blur handler */\n onBlur?: React.FocusEventHandler<HTMLInputElement>;\n /** Auto-focus on mount */\n autoFocus?: boolean;\n /** Additional class name for the wrapper */\n wrapperClassName?: string;\n /** Additional class name for the input */\n className?: string;\n /** Input ID */\n id?: string;\n /** Input name */\n name?: string;\n}\n\nexport const FormNumberInput = React.forwardRef<\n HTMLInputElement,\n FormNumberInputProps\n>(\n (\n {\n value,\n label,\n description,\n error,\n placeholder,\n required,\n disabled,\n readOnly,\n min,\n max,\n step,\n allowDecimal = true,\n onChange,\n onBlur,\n autoFocus,\n wrapperClassName,\n className,\n id,\n name,\n },\n ref,\n ) => {\n const generatedId = useId();\n const inputId = id ?? generatedId;\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n if (!onChange) return;\n const val = e.target.value;\n if (val === \"\" || val === undefined) {\n onChange(undefined);\n } else {\n const numVal = parseFloat(val);\n if (!isNaN(numVal)) onChange(numVal);\n }\n };\n\n const displayValue =\n value !== undefined && value !== null ? String(value) : \"\";\n\n return (\n <FormFieldWrapper\n inputId={inputId}\n label={label}\n description={description}\n error={error}\n required={required}\n className={wrapperClassName}\n >\n <Input\n id={inputId}\n name={name}\n ref={ref}\n type=\"number\"\n inputMode=\"numeric\"\n value={displayValue}\n onChange={handleChange}\n onBlur={onBlur}\n placeholder={placeholder}\n disabled={disabled}\n readOnly={readOnly}\n autoFocus={autoFocus}\n min={min}\n max={max}\n step={step ?? (allowDecimal ? \"any\" : 1)}\n className={cn(error && \"border-destructive\", className)}\n aria-invalid={error ? \"true\" : \"false\"}\n aria-describedby={getAriaDescribedBy(inputId, error, description)}\n aria-required={required}\n />\n </FormFieldWrapper>\n );\n },\n);\n\nFormNumberInput.displayName = \"FormNumberInput\";\n","/**\n * FormCheckbox - Checkbox wrapper with label, description, error, and indeterminate support\n *\n * Wraps shadcn Checkbox with form field features to match Mantine Checkbox API:\n * - Inline label (checkbox + label on same line)\n * - Description text\n * - Error message display\n * - Indeterminate state support (tri-state)\n * - Proper accessibility attributes\n */\n\nimport React, { useId } from \"react\";\nimport { Checkbox } from \"@petrarca/sonnet-ui\";\nimport { cn } from \"@petrarca/sonnet-core\";\nimport {\n getAriaDescribedByCompact,\n getCompactAriaLabel,\n getCompactTitle,\n} from \"./formFieldUtils\";\n\nexport interface FormCheckboxProps {\n /** Checkbox checked state (boolean or 'indeterminate') */\n checked?: boolean | \"indeterminate\";\n /** Checkbox label (displayed inline, false = hide label) */\n label?: string | false;\n /** Description text shown below checkbox */\n description?: string;\n /** Error message to display */\n error?: string;\n /** Whether the field is required */\n required?: boolean;\n /** Whether the checkbox is disabled */\n disabled?: boolean;\n /** Whether the checkbox is read-only */\n readOnly?: boolean;\n /** Change handler */\n onChange?: (checked: boolean | \"indeterminate\") => void;\n /** Blur handler */\n onBlur?: React.FocusEventHandler<HTMLButtonElement>;\n /** Auto-focus on mount */\n autoFocus?: boolean;\n /** Additional class name for the wrapper */\n wrapperClassName?: string;\n /** Additional class name for the checkbox */\n className?: string;\n /** Input ID */\n id?: string;\n /**\n * Compact mode -- suppresses label, description, and error text so the\n * cell height stays fixed in horizontal grid layouts. Error state is\n * still communicated via a red border on the checkbox.\n */\n compact?: boolean;\n}\n\n// -- Sub-components --------------------------------------------------------\n\ninterface CheckboxLabelProps {\n htmlFor: string;\n label: string | false | undefined;\n required: boolean | undefined;\n disabled: boolean | undefined;\n compact: boolean | undefined;\n}\n\nfunction CheckboxLabel({\n htmlFor,\n label,\n required,\n disabled,\n compact,\n}: CheckboxLabelProps) {\n if (compact || !label) return null;\n return (\n <label\n htmlFor={htmlFor}\n className={cn(\n \"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\",\n disabled && \"opacity-70 cursor-not-allowed\",\n )}\n >\n {label}\n {required && <span className=\"text-destructive ml-1\">*</span>}\n </label>\n );\n}\n\ninterface CheckboxChromeProps {\n inputId: string;\n description: string | undefined;\n error: string | undefined;\n compact: boolean | undefined;\n}\n\nfunction CheckboxChrome({\n inputId,\n description,\n error,\n compact,\n}: CheckboxChromeProps) {\n if (compact) return null;\n return (\n <>\n {description && (\n <p\n id={`${inputId}-description`}\n className=\"text-sm text-muted-foreground ml-6\"\n >\n {description}\n </p>\n )}\n {error && (\n <p id={`${inputId}-error`} className=\"text-sm text-destructive ml-6\">\n {error}\n </p>\n )}\n </>\n );\n}\n\n// -- FormCheckbox ----------------------------------------------------------\n\n/**\n * FormCheckbox component with label, description, error, and indeterminate handling\n */\nexport const FormCheckbox = React.forwardRef<\n HTMLButtonElement,\n FormCheckboxProps\n>(\n (\n {\n checked,\n label,\n description,\n error,\n required,\n disabled,\n readOnly,\n onChange,\n onBlur,\n autoFocus,\n wrapperClassName,\n className,\n id,\n compact,\n },\n ref,\n ) => {\n const generatedId = useId();\n const checkboxId = id ?? generatedId;\n\n const handleCheckedChange = (newChecked: boolean | \"indeterminate\") => {\n if (!readOnly && onChange) {\n onChange(newChecked);\n }\n };\n\n return (\n <div className={cn(!compact && \"space-y-2\", wrapperClassName)}>\n <div className=\"flex items-start space-x-2\">\n <Checkbox\n id={checkboxId}\n ref={ref}\n checked={checked}\n onCheckedChange={handleCheckedChange}\n onBlur={onBlur}\n disabled={disabled || readOnly}\n autoFocus={autoFocus}\n className={cn(error && \"border-destructive\", className)}\n aria-invalid={error ? \"true\" : \"false\"}\n aria-describedby={getAriaDescribedByCompact(\n checkboxId,\n error,\n description,\n compact,\n )}\n aria-label={getCompactAriaLabel(label, compact)}\n title={getCompactTitle(error, compact)}\n />\n <CheckboxLabel\n htmlFor={checkboxId}\n label={label}\n required={required}\n disabled={disabled}\n compact={compact}\n />\n </div>\n <CheckboxChrome\n inputId={checkboxId}\n description={description}\n error={error}\n compact={compact}\n />\n </div>\n );\n },\n);\n\nFormCheckbox.displayName = \"FormCheckbox\";\n","/**\n * FormSelect - Searchable single-select dropdown with form field wrapper\n *\n * Composable select component using Popover + Command for searchable,\n * keyboard-navigable dropdown. Follows Form wrapper pattern with\n * label, description, error support.\n */\n\nimport * as React from \"react\";\nimport { Check, ChevronsUpDown, X } from \"lucide-react\";\nimport { cn } from \"@petrarca/sonnet-core\";\nimport { Button } from \"@petrarca/sonnet-ui\";\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from \"@petrarca/sonnet-ui\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"@petrarca/sonnet-ui\";\nimport { FormFieldWrapper } from \"./FormFieldWrapper\";\nimport {\n getAriaDescribedByCompact,\n getCompactAriaLabel,\n getCompactTitle,\n} from \"./formFieldUtils\";\nimport type { SelectOption } from \"./widgets/types\";\n\nexport type { SelectOption };\n\nexport interface FormSelectProps {\n // Form wrapper props (consistent with FormInput/FormTextarea)\n label?: string | false;\n description?: string;\n error?: string;\n required?: boolean;\n wrapperClassName?: string;\n /**\n * Compact mode -- suppresses label, description, and error text so the\n * cell height stays fixed in horizontal grid layouts. Error state is\n * still communicated via a red border on the trigger button.\n */\n compact?: boolean;\n\n // Select-specific props\n options: SelectOption[];\n value?: string | null;\n onChange?: (value: string | null) => void;\n onBlur?: () => void;\n placeholder?: string;\n searchPlaceholder?: string;\n emptyMessage?: string;\n clearable?: boolean;\n disabled?: boolean;\n readOnly?: boolean;\n loading?: boolean;\n className?: string;\n id?: string;\n name?: string;\n autoFocus?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Sub-components\n// ---------------------------------------------------------------------------\n\ninterface TriggerButtonProps {\n selectId: string;\n open: boolean;\n selectedOption: SelectOption | undefined;\n placeholder: string;\n error: string | undefined;\n compact: boolean | undefined;\n label: string | false | undefined;\n description: string | undefined;\n clearable: boolean;\n value: string | null | undefined;\n isDisabled: boolean;\n autoFocus: boolean | undefined;\n className: string | undefined;\n onClear: (e: React.MouseEvent) => void;\n}\n\nfunction TriggerButton({\n selectId,\n open,\n selectedOption,\n placeholder,\n error,\n compact,\n label,\n description,\n clearable,\n value,\n isDisabled,\n autoFocus,\n className,\n onClear,\n}: TriggerButtonProps) {\n return (\n <Button\n id={selectId}\n variant=\"outline\"\n role=\"combobox\"\n aria-expanded={open}\n aria-invalid={error ? \"true\" : \"false\"}\n aria-describedby={getAriaDescribedByCompact(\n selectId,\n error,\n description,\n compact,\n )}\n aria-label={getCompactAriaLabel(label, compact)}\n title={getCompactTitle(error, compact)}\n className={cn(\n \"w-full justify-between\",\n !selectedOption && \"text-muted-foreground\",\n error && \"border-destructive\",\n className,\n )}\n disabled={isDisabled}\n autoFocus={autoFocus}\n >\n <span className=\"truncate\">\n {selectedOption ? selectedOption.label : placeholder}\n </span>\n <div className=\"flex items-center gap-1\">\n {clearable && value && !isDisabled && (\n <X\n className=\"h-4 w-4 opacity-50 hover:opacity-100\"\n onClick={onClear}\n />\n )}\n <ChevronsUpDown className=\"h-4 w-4 shrink-0 opacity-50\" />\n </div>\n </Button>\n );\n}\n\ninterface SelectDropdownProps {\n searchPlaceholder: string;\n searchQuery: string;\n onSearchChange: (value: string) => void;\n loading: boolean;\n emptyMessage: string;\n options: SelectOption[];\n value: string | null | undefined;\n onSelect: (value: string) => void;\n}\n\nfunction SelectDropdown({\n searchPlaceholder,\n searchQuery,\n onSearchChange,\n loading,\n emptyMessage,\n options,\n value,\n onSelect,\n}: SelectDropdownProps) {\n return (\n <Command shouldFilter={false}>\n <CommandInput\n placeholder={searchPlaceholder}\n value={searchQuery}\n onValueChange={onSearchChange}\n />\n <CommandList>\n <CommandEmpty>{loading ? \"Loading...\" : emptyMessage}</CommandEmpty>\n <CommandGroup>\n {options\n .filter((option) =>\n option.label.toLowerCase().includes(searchQuery.toLowerCase()),\n )\n .map((option) => (\n <CommandItem\n key={option.value}\n value={option.value}\n onSelect={onSelect}\n >\n <Check\n className={cn(\n \"mr-2 h-4 w-4\",\n value === option.value ? \"opacity-100\" : \"opacity-0\",\n )}\n />\n {option.label}\n </CommandItem>\n ))}\n </CommandGroup>\n </CommandList>\n </Command>\n );\n}\n\n// ---------------------------------------------------------------------------\n// FormSelect\n// ---------------------------------------------------------------------------\n\n// -- Hook: encapsulate popover state + event handlers --\n\nfunction useSelectState(\n value: string | null | undefined,\n onChange: ((value: string | null) => void) | undefined,\n onBlur: (() => void) | undefined,\n) {\n const [open, setOpen] = React.useState(false);\n const [searchQuery, setSearchQuery] = React.useState(\"\");\n\n const handleSelect = (selectedValue: string) => {\n onChange?.(selectedValue === value ? null : selectedValue);\n setOpen(false);\n setSearchQuery(\"\");\n };\n\n const handleClear = (e: React.MouseEvent) => {\n e.stopPropagation();\n onChange?.(null);\n };\n\n const handleOpenChange = (newOpen: boolean) => {\n setOpen(newOpen);\n if (newOpen) return;\n setSearchQuery(\"\");\n onBlur?.();\n };\n\n return {\n open,\n searchQuery,\n setSearchQuery,\n handleSelect,\n handleClear,\n handleOpenChange,\n };\n}\n\n/** Resolve optional props to concrete values outside the component to reduce branching. */\nfunction resolveSelectDefaults(props: FormSelectProps) {\n return {\n placeholder: props.placeholder ?? \"Select...\",\n searchPlaceholder: props.searchPlaceholder ?? \"Search...\",\n emptyMessage: props.emptyMessage ?? \"No results found\",\n clearable: props.clearable ?? true,\n disabled: props.disabled ?? false,\n readOnly: props.readOnly ?? false,\n loading: props.loading ?? false,\n };\n}\n\nexport function FormSelect(props: FormSelectProps) {\n const {\n label,\n description,\n error,\n required,\n wrapperClassName,\n compact,\n options,\n value,\n onChange,\n onBlur,\n className,\n id,\n autoFocus,\n } = props;\n const {\n placeholder,\n searchPlaceholder,\n emptyMessage,\n clearable,\n disabled,\n readOnly,\n loading,\n } = resolveSelectDefaults(props);\n\n const generatedId = React.useId();\n const selectId = id ?? generatedId;\n\n const {\n open,\n searchQuery,\n setSearchQuery,\n handleSelect,\n handleClear,\n handleOpenChange,\n } = useSelectState(value, onChange, onBlur);\n\n const selectedOption = options.find((opt) => opt.value === value);\n const isDisabled = disabled || readOnly || loading;\n\n return (\n <FormFieldWrapper\n inputId={selectId}\n label={label}\n description={description}\n error={error}\n required={required}\n compact={compact}\n className={wrapperClassName}\n >\n <Popover open={open} onOpenChange={handleOpenChange}>\n <PopoverTrigger asChild>\n <TriggerButton\n selectId={selectId}\n open={open}\n selectedOption={selectedOption}\n placeholder={placeholder}\n error={error}\n compact={compact}\n label={label}\n description={description}\n clearable={clearable}\n value={value}\n isDisabled={isDisabled}\n autoFocus={autoFocus}\n className={className}\n onClear={handleClear}\n />\n </PopoverTrigger>\n <PopoverContent\n className=\"w-[--radix-popover-trigger-width] p-0\"\n align=\"start\"\n >\n <SelectDropdown\n searchPlaceholder={searchPlaceholder}\n searchQuery={searchQuery}\n onSearchChange={setSearchQuery}\n loading={loading}\n emptyMessage={emptyMessage}\n options={options}\n value={value}\n onSelect={handleSelect}\n />\n </PopoverContent>\n </Popover>\n </FormFieldWrapper>\n );\n}\n","/**\n * FormMultiSelect - Searchable multi-select dropdown with badges\n *\n * Multi-select component using Popover + Command with badge display\n * for selected items. Follows Form wrapper pattern with label,\n * description, error support.\n */\n\nimport * as React from \"react\";\nimport { Check, ChevronsUpDown, X } from \"lucide-react\";\nimport { cn } from \"@petrarca/sonnet-core\";\nimport { Button } from \"@petrarca/sonnet-ui\";\nimport { Badge, badgeVariants } from \"@petrarca/sonnet-ui\";\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from \"@petrarca/sonnet-ui\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"@petrarca/sonnet-ui\";\nimport type { VariantProps } from \"class-variance-authority\";\nimport { FormFieldWrapper } from \"./FormFieldWrapper\";\nimport { resolveFieldLabel } from \"./formFieldUtils\";\nimport type { SelectOption } from \"./widgets/types\";\n\ntype BadgeColor = NonNullable<VariantProps<typeof badgeVariants>[\"badgeColor\"]>;\n\nexport type { SelectOption };\n\nexport interface FormMultiSelectProps {\n // Form wrapper props (consistent with FormInput/FormTextarea)\n label?: string | false;\n description?: string;\n error?: string;\n required?: boolean;\n wrapperClassName?: string;\n\n // Multi-select specific props\n options: SelectOption[];\n value?: string[];\n onChange?: (value: string[]) => void;\n onBlur?: () => void;\n placeholder?: string;\n searchPlaceholder?: string;\n emptyMessage?: string;\n clearable?: boolean;\n disabled?: boolean;\n readOnly?: boolean;\n loading?: boolean;\n className?: string;\n id?: string;\n name?: string;\n autoFocus?: boolean;\n maxDisplay?: number; // Max badges to display before showing \"+X more\"\n badgeColor?: BadgeColor;\n}\n\n// ---------------------------------------------------------------------------\n// Sub-components\n// ---------------------------------------------------------------------------\n\ninterface RemovableBadgeProps {\n option: SelectOption;\n isDisabled: boolean;\n badgeColor: BadgeColor | undefined;\n onRemove: (value: string, e: React.MouseEvent | React.KeyboardEvent) => void;\n}\n\nfunction RemovableBadge({\n option,\n isDisabled,\n badgeColor,\n onRemove,\n}: RemovableBadgeProps) {\n return (\n <Badge variant=\"secondary\" badgeColor={badgeColor} className=\"mr-1\">\n {option.label}\n {!isDisabled && (\n <button\n type=\"button\"\n className=\"ml-1 ring-offset-background rounded-full outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2\"\n onKeyDown={(e) => {\n if (e.key === \"Enter\") onRemove(option.value, e);\n }}\n onMouseDown={(e) => {\n e.preventDefault();\n e.stopPropagation();\n }}\n onClick={(e) => onRemove(option.value, e)}\n >\n <X className=\"h-3 w-3 text-muted-foreground hover:text-foreground\" />\n </button>\n )}\n </Badge>\n );\n}\n\ninterface SelectedBadgesProps {\n selectedOptions: SelectOption[];\n effectiveMaxDisplay: number;\n expanded: boolean;\n maxDisplay: number;\n isDisabled: boolean;\n badgeColor: BadgeColor | undefined;\n placeholder: string;\n onRemove: (value: string, e: React.MouseEvent | React.KeyboardEvent) => void;\n onExpand: (e: React.MouseEvent) => void;\n onCollapse: (e: React.MouseEvent) => void;\n}\n\nfunction SelectedBadges({\n selectedOptions,\n effectiveMaxDisplay,\n expanded,\n maxDisplay,\n isDisabled,\n badgeColor,\n placeholder,\n onRemove,\n onExpand,\n onCollapse,\n}: SelectedBadgesProps) {\n if (selectedOptions.length === 0) {\n return <span className=\"text-muted-foreground\">{placeholder}</span>;\n }\n\n const displayedBadges = selectedOptions.slice(0, effectiveMaxDisplay);\n const remainingCount = selectedOptions.length - effectiveMaxDisplay;\n const showCollapse =\n expanded && remainingCount <= 0 && selectedOptions.length > maxDisplay;\n\n return (\n <>\n {displayedBadges.map((option) => (\n <RemovableBadge\n key={option.value}\n option={option}\n isDisabled={isDisabled}\n badgeColor={badgeColor}\n onRemove={onRemove}\n />\n ))}\n {remainingCount > 0 && (\n <Badge\n variant=\"secondary\"\n badgeColor={badgeColor}\n className=\"mr-1 cursor-pointer hover:bg-secondary/80\"\n onClick={onExpand}\n >\n +{remainingCount} more\n </Badge>\n )}\n {showCollapse && (\n <Badge\n variant=\"secondary\"\n badgeColor={badgeColor}\n className=\"mr-1 cursor-pointer hover:bg-secondary/80\"\n onClick={onCollapse}\n >\n Show less\n </Badge>\n )}\n </>\n );\n}\n\ninterface MultiSelectDropdownProps {\n searchPlaceholder: string;\n searchQuery: string;\n onSearchChange: (value: string) => void;\n loading: boolean;\n emptyMessage: string;\n options: SelectOption[];\n value: string[];\n onSelect: (value: string) => void;\n}\n\nfunction MultiSelectDropdown({\n searchPlaceholder,\n searchQuery,\n onSearchChange,\n loading,\n emptyMessage,\n options,\n value,\n onSelect,\n}: MultiSelectDropdownProps) {\n return (\n <Command shouldFilter={false}>\n <CommandInput\n placeholder={searchPlaceholder}\n value={searchQuery}\n onValueChange={onSearchChange}\n />\n <CommandList>\n <CommandEmpty>{loading ? \"Loading...\" : emptyMessage}</CommandEmpty>\n <CommandGroup>\n {options\n .filter((option) =>\n option.label.toLowerCase().includes(searchQuery.toLowerCase()),\n )\n .map((option) => (\n <CommandItem\n key={option.value}\n value={option.value}\n onSelect={onSelect}\n >\n <Check\n className={cn(\n \"mr-2 h-4 w-4\",\n value.includes(option.value) ? \"opacity-100\" : \"opacity-0\",\n )}\n />\n {option.label}\n </CommandItem>\n ))}\n </CommandGroup>\n </CommandList>\n </Command>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Hook: encapsulate popover state + handlers\n// ---------------------------------------------------------------------------\n\nfunction useMultiSelectState(\n value: string[],\n onChange: ((value: string[]) => void) | undefined,\n onBlur: (() => void) | undefined,\n) {\n const [open, setOpen] = React.useState(false);\n const [searchQuery, setSearchQuery] = React.useState(\"\");\n const [expanded, setExpanded] = React.useState(false);\n\n const handleSelect = (selectedValue: string) => {\n const newValue = value.includes(selectedValue)\n ? value.filter((v) => v !== selectedValue)\n : [...value, selectedValue];\n onChange?.(newValue);\n };\n\n const handleRemove = (\n valueToRemove: string,\n e: React.MouseEvent | React.KeyboardEvent,\n ) => {\n e.stopPropagation();\n onChange?.(value.filter((v) => v !== valueToRemove));\n };\n\n const handleClearAll = (e: React.MouseEvent) => {\n e.stopPropagation();\n onChange?.([]);\n };\n\n const handleOpenChange = (newOpen: boolean) => {\n setOpen(newOpen);\n if (newOpen) return;\n setSearchQuery(\"\");\n setExpanded(false);\n onBlur?.();\n };\n\n const handleExpand = (e: React.MouseEvent) => {\n e.stopPropagation();\n setExpanded(true);\n };\n\n const handleCollapse = (e: React.MouseEvent) => {\n e.stopPropagation();\n setExpanded(false);\n };\n\n return {\n open,\n searchQuery,\n setSearchQuery,\n expanded,\n handleSelect,\n handleRemove,\n handleClearAll,\n handleOpenChange,\n handleExpand,\n handleCollapse,\n };\n}\n\n// ---------------------------------------------------------------------------\n// FormMultiSelect\n// ---------------------------------------------------------------------------\n\n/** Resolve optional props to concrete values outside the component to reduce branching. */\nfunction resolveMultiSelectDefaults(props: FormMultiSelectProps) {\n return {\n placeholder: props.placeholder ?? \"Select...\",\n searchPlaceholder: props.searchPlaceholder ?? \"Search...\",\n emptyMessage: props.emptyMessage ?? \"No results found\",\n clearable: props.clearable ?? true,\n disabled: props.disabled ?? false,\n readOnly: props.readOnly ?? false,\n loading: props.loading ?? false,\n maxDisplay: props.maxDisplay ?? Infinity,\n };\n}\n\n// -- Trigger button sub-component --\n\ninterface MultiSelectTriggerProps {\n id: string | undefined;\n open: boolean;\n error: string | undefined;\n className: string | undefined;\n isDisabled: boolean;\n autoFocus: boolean | undefined;\n clearable: boolean;\n hasValues: boolean;\n selectedOptions: SelectOption[];\n effectiveMaxDisplay: number;\n expanded: boolean;\n maxDisplay: number;\n badgeColor: BadgeColor | undefined;\n placeholder: string;\n onRemove: (value: string, e: React.MouseEvent | React.KeyboardEvent) => void;\n onExpand: (e: React.MouseEvent) => void;\n onCollapse: (e: React.MouseEvent) => void;\n onClearAll: (e: React.MouseEvent) => void;\n}\n\nfunction MultiSelectTrigger({\n id,\n open,\n error,\n className,\n isDisabled,\n autoFocus,\n clearable,\n hasValues,\n selectedOptions,\n effectiveMaxDisplay,\n expanded,\n maxDisplay,\n badgeColor,\n placeholder,\n onRemove,\n onExpand,\n onCollapse,\n onClearAll,\n}: MultiSelectTriggerProps) {\n return (\n <Button\n id={id}\n variant=\"outline\"\n role=\"combobox\"\n aria-expanded={open}\n className={cn(\n \"w-full justify-between min-h-10 h-auto\",\n error && \"border-destructive\",\n className,\n )}\n disabled={isDisabled}\n autoFocus={autoFocus}\n >\n <div className=\"flex flex-wrap gap-1 flex-1\">\n <SelectedBadges\n selectedOptions={selectedOptions}\n effectiveMaxDisplay={effectiveMaxDisplay}\n expanded={expanded}\n maxDisplay={maxDisplay}\n isDisabled={isDisabled}\n badgeColor={badgeColor}\n placeholder={placeholder}\n onRemove={onRemove}\n onExpand={onExpand}\n onCollapse={onCollapse}\n />\n </div>\n <div className=\"flex items-center gap-1 ml-2\">\n {clearable && hasValues && !isDisabled && (\n <X\n className=\"h-4 w-4 opacity-50 hover:opacity-100\"\n onClick={onClearAll}\n />\n )}\n <ChevronsUpDown className=\"h-4 w-4 shrink-0 opacity-50\" />\n </div>\n </Button>\n );\n}\n\nexport function FormMultiSelect(props: FormMultiSelectProps) {\n const {\n label,\n description,\n error,\n required,\n wrapperClassName,\n options,\n onChange,\n onBlur,\n className,\n id,\n name,\n autoFocus,\n badgeColor,\n } = props;\n const value = props.value ?? [];\n const generatedId = React.useId();\n const fieldId = id ?? generatedId;\n const {\n placeholder,\n searchPlaceholder,\n emptyMessage,\n clearable,\n disabled,\n readOnly,\n loading,\n maxDisplay,\n } = resolveMultiSelectDefaults(props);\n\n const selectedOptions = options.filter((opt) => value.includes(opt.value));\n const isDisabled = disabled || readOnly || loading;\n\n const {\n open,\n searchQuery,\n setSearchQuery,\n expanded,\n handleSelect,\n handleRemove,\n handleClearAll,\n handleOpenChange,\n handleExpand,\n handleCollapse,\n } = useMultiSelectState(value, onChange, onBlur);\n\n const effectiveMaxDisplay = expanded ? Infinity : maxDisplay;\n\n return (\n <FormFieldWrapper\n inputId={fieldId}\n label={resolveFieldLabel(label)}\n description={description}\n error={error}\n required={required}\n className={wrapperClassName}\n >\n <Popover open={open} onOpenChange={handleOpenChange}>\n <PopoverTrigger asChild>\n <MultiSelectTrigger\n id={fieldId}\n open={open}\n error={error}\n className={className}\n isDisabled={isDisabled}\n autoFocus={autoFocus}\n clearable={clearable}\n hasValues={value.length > 0}\n selectedOptions={selectedOptions}\n effectiveMaxDisplay={effectiveMaxDisplay}\n expanded={expanded}\n maxDisplay={maxDisplay}\n badgeColor={badgeColor}\n placeholder={placeholder}\n onRemove={handleRemove}\n onExpand={handleExpand}\n onCollapse={handleCollapse}\n onClearAll={handleClearAll}\n />\n </PopoverTrigger>\n <PopoverContent\n className=\"w-[--radix-popover-trigger-width] p-0\"\n align=\"start\"\n >\n <MultiSelectDropdown\n searchPlaceholder={searchPlaceholder}\n searchQuery={searchQuery}\n onSearchChange={setSearchQuery}\n loading={loading}\n emptyMessage={emptyMessage}\n options={options}\n value={value}\n onSelect={handleSelect}\n />\n </PopoverContent>\n </Popover>\n\n {/* Hidden inputs for form submission */}\n {name &&\n value.map((v) => <input key={v} type=\"hidden\" name={name} value={v} />)}\n </FormFieldWrapper>\n );\n}\n","/**\n * FormTagsInput - Input field for managing tags with badges\n *\n * Allows adding tags by pressing Enter or comma, removing tags via X button\n * or backspace. Displays tags as badges. Follows Form wrapper pattern with\n * label, description, error support.\n */\n\nimport * as React from \"react\";\nimport { X } from \"lucide-react\";\nimport { cn } from \"@petrarca/sonnet-core\";\nimport { Input } from \"@petrarca/sonnet-ui\";\nimport { Badge } from \"@petrarca/sonnet-ui\";\nimport { FormFieldWrapper } from \"./FormFieldWrapper\";\nimport { resolveFieldLabel } from \"./formFieldUtils\";\n\nexport interface FormTagsInputProps {\n // Form wrapper props (consistent with FormInput/FormTextarea)\n label?: string | false;\n description?: string;\n error?: string;\n required?: boolean;\n wrapperClassName?: string;\n\n // TagsInput specific props\n id?: string;\n name?: string;\n value: string[];\n onChange?: (tags: string[]) => void;\n placeholder?: string;\n disabled?: boolean;\n readOnly?: boolean;\n maxTags?: number;\n splitKeys?: string[]; // Keys that trigger tag creation (default: ['Enter', ','])\n allowDuplicates?: boolean;\n}\n\n// -- Sub-component --------------------------------------------------------\n\ninterface TagBadgeProps {\n tag: string;\n index: number;\n isDisabled: boolean;\n onRemove: (index: number) => void;\n}\n\nfunction TagBadge({ tag, index, isDisabled, onRemove }: TagBadgeProps) {\n return (\n <Badge variant=\"secondary\" className=\"gap-1\">\n {tag}\n {!isDisabled && (\n <button\n type=\"button\"\n className=\"ml-1 ring-offset-background rounded-full outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2\"\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n onRemove(index);\n }\n }}\n onMouseDown={(e) => {\n e.preventDefault();\n e.stopPropagation();\n }}\n onClick={(e) => {\n e.stopPropagation();\n onRemove(index);\n }}\n >\n <X className=\"h-3 w-3 text-muted-foreground hover:text-foreground\" />\n </button>\n )}\n </Badge>\n );\n}\n\n// -- Hook: tag management -------------------------------------------------\n\nfunction useTagManagement(\n value: string[],\n onChange: ((tags: string[]) => void) | undefined,\n allowDuplicates: boolean,\n maxTags: number | undefined,\n splitKeys: string[],\n) {\n const [inputValue, setInputValue] = React.useState(\"\");\n\n const addTag = React.useCallback(\n (tag: string) => {\n const trimmedTag = tag.trim();\n if (!trimmedTag) return;\n if (!allowDuplicates && value.includes(trimmedTag)) return;\n if (maxTags && value.length >= maxTags) return;\n onChange?.([...value, trimmedTag]);\n setInputValue(\"\");\n },\n [value, onChange, allowDuplicates, maxTags],\n );\n\n const removeTag = React.useCallback(\n (indexToRemove: number) => {\n onChange?.(value.filter((_, index) => index !== indexToRemove));\n },\n [value, onChange],\n );\n\n const handleKeyDown = React.useCallback(\n (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (splitKeys.includes(e.key)) {\n e.preventDefault();\n addTag(inputValue);\n return;\n }\n if (e.key === \"Backspace\" && !inputValue && value.length > 0) {\n e.preventDefault();\n removeTag(value.length - 1);\n }\n },\n [splitKeys, inputValue, value.length, addTag, removeTag],\n );\n\n const handleInputChange = React.useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = e.target.value;\n if (!splitKeys.includes(\",\") || !newValue.includes(\",\")) {\n setInputValue(newValue);\n return;\n }\n const parts = newValue.split(\",\");\n parts.slice(0, -1).forEach((tag) => addTag(tag));\n setInputValue(parts[parts.length - 1]);\n },\n [splitKeys, addTag],\n );\n\n return { inputValue, addTag, removeTag, handleKeyDown, handleInputChange };\n}\n\n// -- FormTagsInput --------------------------------------------------------\n\n/** Resolve optional props with defaults outside the component scope. */\nfunction resolveTagsDefaults(props: FormTagsInputProps) {\n return {\n required: props.required ?? false,\n placeholder: props.placeholder ?? \"Enter tag and press Enter\",\n splitKeys: props.splitKeys ?? [\"Enter\", \",\"],\n allowDuplicates: props.allowDuplicates ?? false,\n };\n}\n\nexport const FormTagsInput = React.forwardRef<\n HTMLInputElement,\n FormTagsInputProps\n>((props, ref) => {\n const {\n label,\n description,\n error,\n wrapperClassName,\n id,\n name,\n value = [],\n onChange,\n disabled,\n readOnly,\n maxTags,\n } = props;\n const { required, placeholder, splitKeys, allowDuplicates } =\n resolveTagsDefaults(props);\n\n const generatedId = React.useId();\n const fieldId = id ?? generatedId;\n const inputRef = React.useRef<HTMLInputElement>(null);\n React.useImperativeHandle(ref, () => inputRef.current!);\n\n const isDisabled = disabled || readOnly;\n const { inputValue, removeTag, handleKeyDown, handleInputChange } =\n useTagManagement(value, onChange, allowDuplicates, maxTags, splitKeys);\n\n const handleContainerClick = () => {\n inputRef.current?.focus();\n };\n\n return (\n <FormFieldWrapper\n inputId={fieldId}\n label={resolveFieldLabel(label)}\n description={description}\n error={error}\n required={required}\n className={wrapperClassName}\n >\n <div\n className={cn(\n \"flex min-h-10 w-full flex-wrap gap-1.5 rounded-md border border-input bg-background px-3 py-2 text-sm\",\n isDisabled && \"cursor-not-allowed opacity-50\",\n error && \"border-destructive\",\n )}\n onClick={handleContainerClick}\n >\n {value.map((tag, index) => (\n <TagBadge\n key={index}\n tag={tag}\n index={index}\n isDisabled={!!isDisabled}\n onRemove={removeTag}\n />\n ))}\n <Input\n ref={inputRef}\n id={fieldId}\n name={name}\n value={inputValue}\n onChange={handleInputChange}\n onKeyDown={handleKeyDown}\n placeholder={value.length === 0 ? placeholder : \"\"}\n disabled={!!isDisabled}\n className=\"flex-1 min-w-[120px] border-0 p-0 h-auto focus-visible:ring-0 focus-visible:ring-offset-0\"\n />\n </div>\n </FormFieldWrapper>\n );\n});\n\nFormTagsInput.displayName = \"FormTagsInput\";\n","/**\n * FormQuantityInput - Compound input for a numeric value paired with a unit selector.\n *\n * Renders as a single visual control using InputGroup: the numeric input fills\n * the left side; the unit selector (or static text) sits inside the right (or\n * left) edge of the same border as an inline addon.\n *\n * Value shape: { value: number | undefined, unit: string }\n *\n * Decimal handling: uses inputMode=\"decimal\" with type=\"text\" to support\n * international decimal separators (comma and period). Input is validated and\n * normalized on blur, not on every keystroke, to allow intermediate states\n * such as \"37.\" or \"-\".\n *\n * NOTE on precision: toFixed() uses IEEE 754 rounding. For values where exact\n * decimal representation matters (e.g. financial amounts), the caller should\n * round the emitted number independently before storing it.\n */\n\nimport React, { useCallback, useEffect, useId, useMemo, useState } from \"react\";\nimport { ChevronsUpDown } from \"lucide-react\";\nimport { cn } from \"@petrarca/sonnet-core\";\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupInput,\n} from \"@petrarca/sonnet-ui\";\nimport { FormFieldWrapper } from \"./FormFieldWrapper\";\nimport { getAriaDescribedBy } from \"./formFieldUtils\";\nimport type { SelectOption } from \"./widgets/types\";\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\n/** Compound quantity value: numeric value + unit code */\nexport interface QuantityValue {\n value: number | undefined;\n unit: string;\n}\n\n/** Where the unit label renders relative to the numeric input */\nexport type UnitPosition = \"prefix\" | \"suffix\";\n\n/** A unit option with optional per-unit validation constraints and position */\nexport interface UnitOption extends SelectOption {\n /** Minimum allowed value for this unit */\n min?: number;\n /** Maximum allowed value for this unit */\n max?: number;\n /** Where to render this unit relative to the value (default: \"suffix\") */\n position?: UnitPosition;\n}\n\nexport interface FormQuantityInputProps {\n /** Controlled compound value */\n value?: QuantityValue;\n /** Change handler -- receives the updated quantity */\n onChange?: (value: QuantityValue) => void;\n /** Blur handler */\n onBlur?: () => void;\n\n /** Available unit options. Single = static text, 2+ = dropdown, none = no addon. */\n units?: UnitOption[];\n /**\n * Default position for all units. Individual UnitOption.position overrides\n * this. Default: \"suffix\".\n */\n unitPosition?: UnitPosition;\n /**\n * Decimal places to format on blur (undefined = no formatting).\n * Uses toFixed() -- see IEEE 754 note in file header.\n */\n precision?: number;\n /** Arrow-key step increment */\n step?: number;\n /** Global minimum (overridden by per-unit min when present) */\n min?: number;\n /** Global maximum (overridden by per-unit max when present) */\n max?: number;\n\n /** Visible label */\n label?: string;\n /** Helper text shown below the control */\n description?: string;\n /** Validation error message */\n error?: string;\n /** Placeholder for the numeric input */\n placeholder?: string;\n /** Shows a required asterisk */\n required?: boolean;\n disabled?: boolean;\n readOnly?: boolean;\n autoFocus?: boolean;\n /** Additional class name for the outer wrapper */\n wrapperClassName?: string;\n /** Additional class name for the numeric input */\n className?: string;\n id?: string;\n name?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Pure helpers\n// ---------------------------------------------------------------------------\n\n// Allows in-progress numeric strings: optional leading minus, digits,\n// at most one decimal separator (comma or period).\nconst VALID_NUMERIC_INPUT = /^-?\\d*[.,]?\\d*$/;\n\n/** Sentinel values that represent incomplete but valid in-progress entries. */\nconst INCOMPLETE_SENTINELS = new Set([\"\", \".\", \"-\", \"-.\"]);\n\n/**\n * Round n to p decimal places using integer scaling.\n *\n * Avoids the IEEE 754 trap in toFixed() (e.g. (1.005).toFixed(2) === \"1.00\").\n * The Number.EPSILON nudge shifts values that land exactly halfway between two\n * representable floats (e.g. 1.005, 0.045) to the correct side before rounding.\n * Safe for all values within Number.MAX_SAFE_INTEGER / 10^p, which covers every\n * practical clinical and financial quantity this widget handles (see ADR-0010).\n */\nfunction roundToPrecision(n: number, p: number): number {\n const factor = Math.pow(10, p);\n return Math.round((n + Number.EPSILON) * factor) / factor;\n}\n\n/** Pure validation -- returns an error string or empty string. */\nfunction validateQuantity(\n numValue: number,\n lo: number | undefined,\n hi: number | undefined,\n unitLabel: string,\n): string {\n if (lo !== undefined && numValue < lo) {\n return `Value must be at least ${lo}${unitLabel ? ` ${unitLabel}` : \"\"}`;\n }\n if (hi !== undefined && numValue > hi) {\n return `Value must be at most ${hi}${unitLabel ? ` ${unitLabel}` : \"\"}`;\n }\n return \"\";\n}\n\n/** Round and format a parsed number. Returns { rounded, formatted }. */\nfunction roundAndFormat(\n numValue: number,\n precision: number | undefined,\n): { rounded: number; formatted: string } {\n const rounded =\n precision !== undefined ? roundToPrecision(numValue, precision) : numValue;\n const formatted =\n precision !== undefined ? rounded.toFixed(precision) : String(rounded);\n return { rounded, formatted };\n}\n\n// ---------------------------------------------------------------------------\n// UnitAddon sub-component (named for React DevTools visibility)\n// ---------------------------------------------------------------------------\n\ninterface UnitAddonProps {\n units: UnitOption[];\n currentUnit: string;\n addonAlign: \"inline-start\" | \"inline-end\";\n disabled?: boolean;\n readOnly?: boolean;\n onChange: (e: React.ChangeEvent<HTMLSelectElement>) => void;\n}\n\nfunction UnitAddon({\n units,\n currentUnit,\n addonAlign,\n disabled,\n readOnly,\n onChange,\n}: UnitAddonProps) {\n if (units.length === 0) return null;\n\n if (units.length === 1) {\n return (\n <InputGroupAddon align={addonAlign}>\n <span className=\"text-sm text-muted-foreground\">{units[0].label}</span>\n </InputGroupAddon>\n );\n }\n\n return (\n <InputGroupAddon align={addonAlign}>\n <div className=\"relative flex items-center\">\n <select\n value={currentUnit}\n onChange={onChange}\n disabled={disabled || readOnly}\n className=\"cursor-pointer appearance-none border-0 bg-transparent py-0 pr-5 pl-1 text-sm text-muted-foreground outline-none hover:text-foreground focus:text-foreground\"\n aria-label=\"Unit\"\n >\n {units.map((u) => (\n <option key={u.value} value={u.value}>\n {u.label}\n </option>\n ))}\n </select>\n <ChevronsUpDown className=\"pointer-events-none absolute right-0 h-3.5 w-3.5 text-muted-foreground/60\" />\n </div>\n </InputGroupAddon>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Hooks\n// ---------------------------------------------------------------------------\n\n/** Derive current unit, position, and effective min/max from props. */\nfunction useUnitState(\n value: QuantityValue | undefined,\n units: UnitOption[],\n unitPosition: UnitPosition,\n min: number | undefined,\n max: number | undefined,\n) {\n const currentUnit = useMemo(() => {\n const preferred = value?.unit;\n if (preferred && units.some((u) => u.value === preferred)) return preferred;\n return units[0]?.value ?? \"\";\n }, [value?.unit, units]);\n\n const unitMeta = useMemo(\n () => units.find((u) => u.value === currentUnit),\n [units, currentUnit],\n );\n\n const effectiveMin = unitMeta?.min ?? min;\n const effectiveMax = unitMeta?.max ?? max;\n const effectivePosition = unitMeta?.position ?? unitPosition;\n const addonAlign: \"inline-start\" | \"inline-end\" =\n effectivePosition === \"prefix\" ? \"inline-start\" : \"inline-end\";\n\n return { currentUnit, effectiveMin, effectiveMax, addonAlign };\n}\n\n/** Manage raw text input, validation, and handlers for numeric entry. */\nfunction useQuantityInput(\n value: QuantityValue | undefined,\n onChange: ((value: QuantityValue) => void) | undefined,\n onBlur: (() => void) | undefined,\n currentUnit: string,\n precision: number | undefined,\n effectiveMin: number | undefined,\n effectiveMax: number | undefined,\n externalError: string | undefined,\n) {\n const [rawInput, setRawInput] = useState<string>(\n value?.value !== undefined ? String(value.value) : \"\",\n );\n const [validationError, setValidationError] = useState<string>(\"\");\n\n // Sync rawInput when the controlled value changes from outside.\n useEffect(() => {\n const external = value?.value !== undefined ? String(value.value) : \"\";\n setRawInput((prev) => {\n const parsed = parseFloat(prev.replace(\",\", \".\"));\n if (!isNaN(parsed) && parsed === value?.value) return prev;\n return external;\n });\n }, [value?.value]);\n\n const error = externalError || validationError;\n\n const emit = useCallback(\n (numValue: number | undefined, unitValue: string) => {\n onChange?.({ value: numValue, unit: unitValue });\n },\n [onChange],\n );\n\n const handleInputChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const raw = e.target.value;\n if (raw !== \"\" && !VALID_NUMERIC_INPUT.test(raw)) return;\n setRawInput(raw);\n setValidationError(\"\");\n },\n [],\n );\n\n const handleInputBlur = useCallback(() => {\n const normalized = rawInput.replace(\",\", \".\");\n\n // Handle incomplete entries (empty, just a dot/minus/minus-dot).\n if (INCOMPLETE_SENTINELS.has(normalized)) {\n if (normalized !== \"\") setRawInput(\"\");\n emit(undefined, currentUnit);\n setValidationError(\"\");\n onBlur?.();\n return;\n }\n\n const numValue = parseFloat(normalized);\n if (isNaN(numValue)) {\n setRawInput(\"\");\n emit(undefined, currentUnit);\n onBlur?.();\n return;\n }\n\n const { rounded, formatted } = roundAndFormat(numValue, precision);\n setRawInput(formatted);\n setValidationError(\n validateQuantity(rounded, effectiveMin, effectiveMax, currentUnit),\n );\n emit(rounded, currentUnit);\n onBlur?.();\n }, [\n rawInput,\n currentUnit,\n precision,\n effectiveMin,\n effectiveMax,\n emit,\n onBlur,\n ]);\n\n return {\n rawInput,\n error,\n handleInputChange,\n handleInputBlur,\n emit,\n setValidationError,\n };\n}\n\n// ---------------------------------------------------------------------------\n// FormQuantityInput\n// ---------------------------------------------------------------------------\n\n/**\n * FormQuantityInput -- controlled compound numeric + unit input in a single\n * InputGroup border. See file header for behavioural notes.\n */\nexport const FormQuantityInput = React.forwardRef<\n HTMLInputElement,\n FormQuantityInputProps\n>((allProps, ref) => {\n const {\n value,\n onChange,\n onBlur,\n precision,\n step,\n min,\n max,\n label,\n description,\n placeholder,\n required,\n disabled,\n readOnly,\n autoFocus,\n wrapperClassName,\n className,\n name,\n } = allProps;\n const units = useMemo(() => allProps.units ?? [], [allProps.units]);\n const unitPosition = allProps.unitPosition ?? \"suffix\";\n const error = allProps.error;\n\n const generatedId = useId();\n const inputId = allProps.id ?? generatedId;\n\n const { currentUnit, effectiveMin, effectiveMax, addonAlign } = useUnitState(\n value,\n units,\n unitPosition,\n min,\n max,\n );\n\n const {\n rawInput,\n error: resolvedError,\n handleInputChange,\n handleInputBlur,\n emit,\n setValidationError,\n } = useQuantityInput(\n value,\n onChange,\n onBlur,\n currentUnit,\n precision,\n effectiveMin,\n effectiveMax,\n error,\n );\n\n // Unit change handler\n const handleUnitChange = useCallback(\n (e: React.ChangeEvent<HTMLSelectElement>) => {\n const unitValue = e.target.value;\n setValidationError(\"\");\n const normalized = rawInput.replace(\",\", \".\");\n const numValue = parseFloat(normalized);\n if (isNaN(numValue)) return;\n const um = units.find((u) => u.value === unitValue);\n const lo = um?.min ?? min;\n const hi = um?.max ?? max;\n setValidationError(validateQuantity(numValue, lo, hi, unitValue));\n emit(numValue, unitValue);\n },\n [rawInput, units, min, max, emit, setValidationError],\n );\n\n const unitAddon = useMemo(\n () => (\n <UnitAddon\n units={units}\n currentUnit={currentUnit}\n addonAlign={addonAlign}\n disabled={disabled}\n readOnly={readOnly}\n onChange={handleUnitChange}\n />\n ),\n [units, currentUnit, addonAlign, disabled, readOnly, handleUnitChange],\n );\n\n return (\n <FormFieldWrapper\n inputId={inputId}\n label={label}\n description={description}\n error={resolvedError}\n required={required}\n className={wrapperClassName}\n >\n <InputGroup\n data-disabled={disabled || undefined}\n className={cn(resolvedError && \"border-destructive\")}\n >\n <InputGroupInput\n id={inputId}\n name={name}\n ref={ref}\n type=\"text\"\n inputMode=\"decimal\"\n value={rawInput}\n onChange={handleInputChange}\n onBlur={handleInputBlur}\n placeholder={placeholder}\n disabled={disabled}\n readOnly={readOnly}\n autoFocus={autoFocus}\n step={step}\n className={className}\n aria-invalid={resolvedError ? \"true\" : \"false\"}\n aria-describedby={getAriaDescribedBy(\n inputId,\n resolvedError,\n description,\n )}\n aria-required={required}\n aria-valuemin={effectiveMin}\n aria-valuemax={effectiveMax}\n />\n {unitAddon}\n </InputGroup>\n </FormFieldWrapper>\n );\n});\n\nFormQuantityInput.displayName = \"FormQuantityInput\";\n","/**\n * FormActions - Save / Cancel button row for buffered forms\n *\n * Rendered only when the parent JsonSchemaFormRenderer is in buffered mode\n * (showActions=true). Keeps button logic out of the orchestrator.\n *\n * @module components/Forms/FormActions\n */\n\nimport { Button } from \"@petrarca/sonnet-ui\";\nimport { SimpleGroup } from \"@petrarca/sonnet-ui\";\n\nexport interface FormActionsProps {\n onSave: () => void;\n onCancel: () => void;\n disabled?: boolean;\n hasChanges: boolean;\n isValid: boolean;\n saveLabel?: string;\n cancelLabel?: string;\n showCancel?: boolean;\n}\n\nexport function FormActions({\n onSave,\n onCancel,\n disabled = false,\n hasChanges,\n isValid,\n saveLabel = \"Save\",\n cancelLabel = \"Cancel\",\n showCancel = true,\n}: FormActionsProps) {\n return (\n <SimpleGroup justify=\"flex-end\" mt=\"md\">\n {showCancel && (\n <Button variant=\"outline\" onClick={onCancel} disabled={disabled}>\n {cancelLabel}\n </Button>\n )}\n <Button onClick={onSave} disabled={disabled || !hasChanges || !isValid}>\n {saveLabel}\n </Button>\n </SimpleGroup>\n );\n}\n","import { useMemo } from \"react\";\nimport { ChevronDown, ChevronRight } from \"lucide-react\";\nimport { Card } from \"@petrarca/sonnet-ui\";\nimport { useDisclosure } from \"@petrarca/sonnet-core/hooks\";\nimport { JsonSchema } from \"@petrarca/sonnet-core/schema\";\nimport { Collapsible, CollapsibleContent } from \"@petrarca/sonnet-ui\";\n\ntype Props = {\n properties: Record<string, any>;\n schema: JsonSchema | null;\n};\n\n/**\n * Displays properties that are not defined in the JSON Schema.\n * Shown as a collapsible card, closed by default.\n *\n * This is a generic component that can be used anywhere a schema and properties\n * need to be compared to show additional/extra properties.\n */\nfunction ExtraPropertiesCard({ properties, schema }: Props) {\n const [opened, { toggle }] = useDisclosure(false);\n\n const extraProperties = useMemo(() => {\n if (!schema) return null;\n const schemaProps = schema.properties ?? {};\n const extra = Object.fromEntries(\n Object.entries(properties).filter(([k]) => !(k in schemaProps)),\n );\n return Object.keys(extra).length > 0 ? extra : null;\n }, [properties, schema]);\n\n if (!extraProperties) return null;\n\n return (\n <Card className=\"border p-3\">\n <p\n className={`flex items-center gap-1 text-sm font-medium cursor-pointer select-none ${opened ? \"mb-1\" : \"\"}`}\n onClick={toggle}\n >\n {opened ? (\n <ChevronDown className=\"h-3.5 w-3.5\" />\n ) : (\n <ChevronRight className=\"h-3.5 w-3.5\" />\n )}\n Extra Properties (not in schema)\n </p>\n <Collapsible open={opened}>\n <CollapsibleContent>\n <pre className=\"text-xs bg-muted p-2 rounded overflow-x-auto\">\n <code>{JSON.stringify(extraProperties, null, 2)}</code>\n </pre>\n </CollapsibleContent>\n </Collapsible>\n </Card>\n );\n}\n\nexport default ExtraPropertiesCard;\n","/**\n * JsonSchemaFormRenderer - Generic form renderer based on JSON Schema\n *\n * Thin orchestrator: composes useFormEngine, FormFieldRenderer, and FormActions.\n *\n * Supports three update modes:\n * 1. Real-time (default) — onChange on every field change\n * 2. Deferred (deferChanges=true) — onChange on blur for text fields\n * 3. Buffered (showActions=true) — Save/Cancel managed by form; onUpdate on Save\n *\n * When rendered inside a HorizontalArrayItemTemplate (via ObjectWidget in an\n * array row), the caller sets `displayContents=true` so this renderer's\n * wrapper uses `display: contents`, making each field div a direct grid cell\n * in the parent row grid.\n *\n * @module components/Forms/JsonSchemaFormRenderer\n */\n\nimport React, { useCallback, useMemo } from \"react\";\nimport { SimpleStack } from \"@petrarca/sonnet-ui\";\nimport {\n JsonSchema,\n UILayoutConfig,\n UILayoutRowConfig,\n} from \"@petrarca/sonnet-core/schema\";\nimport type { FormDiff } from \"@petrarca/sonnet-core/schema\";\nimport { isFieldRequired } from \"@petrarca/sonnet-core/schema\";\nimport { FORM_ITEM_ID_FIELD } from \"@petrarca/sonnet-core\";\nimport ExtraPropertiesCard from \"./ExtraPropertiesCard\";\nimport { DEFAULT_WIDGETS, WidgetRegistry, UISchema } from \"./widgets\";\nimport { TemplateRegistry, UISchemaOptions } from \"./widgets/types\";\nimport { DEFAULT_TEMPLATES } from \"./templates\";\nimport { FormFieldRenderer } from \"./FormFieldRenderer\";\nimport { FormActions } from \"./FormActions\";\nimport { useFormEngine } from \"./hooks/useFormEngine\";\nimport { NestedFormContext, NestedRenderer } from \"./NestedFormContext\";\n\n/**\n * Recursively remove FORM_ITEM_ID_FIELD from all array items in a data object.\n * This is the single boundary where _fid is stripped -- it never leaves the renderer.\n */\nfunction stripFids(data: Record<string, unknown>): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data)) {\n if (Array.isArray(value)) {\n result[key] = value.map((item: unknown) => {\n if (item !== null && typeof item === \"object\" && !Array.isArray(item)) {\n const rest = Object.fromEntries(\n Object.entries(item as Record<string, unknown>).filter(\n ([k]) => k !== FORM_ITEM_ID_FIELD,\n ),\n );\n return stripFids(rest);\n }\n return item;\n });\n } else if (value !== null && typeof value === \"object\") {\n result[key] = stripFids(value as Record<string, unknown>);\n } else {\n result[key] = value;\n }\n }\n return result;\n}\n\n/** Resolve boolean/flag default values for optional props. */\nfunction resolveFlagDefaults(props: JsonSchemaFormRendererProps) {\n return {\n disabled: props.disabled ?? false,\n readOnly: props.readOnly ?? false,\n showActions: props.showActions ?? false,\n deferChanges: props.deferChanges ?? false,\n deferStateUpdates: props.deferStateUpdates ?? false,\n showCancel: props.showCancel ?? true,\n showExtraProperties: props.showExtraProperties ?? true,\n displayContents: props.displayContents ?? false,\n };\n}\n\n/** Resolve non-boolean default values for optional props. */\nfunction resolveValueDefaults(props: JsonSchemaFormRendererProps) {\n return {\n saveLabel: props.saveLabel ?? \"Save\",\n cancelLabel: props.cancelLabel ?? \"Cancel\",\n widgets: props.widgets ?? DEFAULT_WIDGETS,\n uiSchema: props.uiSchema ?? ({} as { [fieldName: string]: UISchema }),\n };\n}\n\n/**\n * Wrap outbound callbacks to strip _fid before data crosses the renderer\n * boundary. Each callback is memoised individually.\n */\nfunction useWrappedCallbacks(\n onChange: JsonSchemaFormRendererProps[\"onChange\"],\n onBlur: JsonSchemaFormRendererProps[\"onBlur\"],\n onUpdate: JsonSchemaFormRendererProps[\"onUpdate\"],\n) {\n const wrappedOnChange = useCallback(\n (d: Record<string, any>) => onChange?.(stripFids(d)),\n [onChange],\n );\n\n const wrappedOnBlur = useCallback(\n (fieldName: string, d: Record<string, any>) =>\n onBlur?.(fieldName, stripFids(d)),\n [onBlur],\n );\n\n const wrappedOnUpdate = useCallback(\n (d: Record<string, any>, changed: Record<string, any>, diff: FormDiff) =>\n onUpdate?.(stripFids(d), stripFids(changed), diff),\n [onUpdate],\n );\n\n return {\n wrappedOnChange: onChange ? wrappedOnChange : undefined,\n wrappedOnBlur: onBlur ? wrappedOnBlur : undefined,\n wrappedOnUpdate: onUpdate ? wrappedOnUpdate : undefined,\n };\n}\n\n/** Index field elements by their React key for O(1) lookup. */\nfunction buildFieldMap(\n fields: React.ReactElement[],\n): Map<string, React.ReactElement> {\n const map = new Map<string, React.ReactElement>();\n for (const field of fields) {\n if (React.isValidElement(field) && field.key != null) {\n map.set(String(field.key), field);\n }\n }\n return map;\n}\n\n/** Build a single CSS grid row element from a row definition. */\nfunction buildRowElement(\n row: UILayoutRowConfig,\n fieldMap: Map<string, React.ReactElement>,\n defaultRowGap: number,\n): { element: React.ReactElement; placed: string[] } | null {\n const rowFields = row.fields\n .map((name) => fieldMap.get(name))\n .filter((el): el is React.ReactElement => el != null);\n if (rowFields.length === 0) return null;\n\n const gridColumns = row.columns ?? `repeat(${rowFields.length}, 1fr)`;\n const rowGap = row.gap ?? defaultRowGap;\n\n return {\n element: (\n <div\n key={`row:${row.fields.join(\",\")}`}\n style={{\n display: \"grid\",\n gridTemplateColumns: gridColumns,\n gap: `${rowGap}px`,\n }}\n >\n {rowFields}\n </div>\n ),\n placed: row.fields,\n };\n}\n\n/** Collect fields not present in the placed set, preserving source order. */\nfunction collectUnplacedFields(\n fields: React.ReactElement[],\n placed: Set<string>,\n): React.ReactElement[] {\n const result: React.ReactElement[] = [];\n for (const field of fields) {\n if (\n React.isValidElement(field) &&\n field.key != null &&\n !placed.has(String(field.key))\n ) {\n result.push(field);\n }\n }\n return result;\n}\n\n/**\n * Arrange field elements into CSS grid rows according to row definitions.\n * Fields not mentioned in any row are appended in source order.\n */\nfunction layoutFieldsInRows(\n fields: React.ReactElement[],\n rowDefs: UILayoutRowConfig[],\n defaultRowGap: number,\n): React.ReactElement[] {\n const fieldMap = buildFieldMap(fields);\n const placed = new Set<string>();\n const elements: React.ReactElement[] = [];\n\n for (const row of rowDefs) {\n const result = buildRowElement(row, fieldMap, defaultRowGap);\n if (result == null) continue;\n elements.push(result.element);\n for (const name of result.placed) placed.add(name);\n }\n\n return elements.concat(collectUnplacedFields(fields, placed));\n}\n\ninterface FormContainerProps {\n displayContents: boolean;\n showExtraProperties: boolean;\n showActions: boolean;\n formData: Record<string, any>;\n resolvedSchema: JsonSchema;\n handleSave: () => void;\n handleCancel: () => void;\n disabled: boolean;\n hasChanges: boolean;\n isValid: boolean;\n saveLabel: string;\n cancelLabel: string;\n showCancel: boolean;\n children: React.ReactNode;\n}\n\n/** Container that renders either display:contents or a SimpleStack with actions. */\nfunction FormContainer({\n displayContents,\n showExtraProperties,\n showActions,\n formData,\n resolvedSchema,\n handleSave,\n handleCancel,\n disabled,\n hasChanges,\n isValid,\n saveLabel,\n cancelLabel,\n showCancel,\n children,\n}: FormContainerProps): React.ReactElement {\n if (displayContents) {\n return <div style={{ display: \"contents\" }}>{children}</div>;\n }\n return (\n <SimpleStack gap={24}>\n {children}\n {showExtraProperties && (\n <ExtraPropertiesCard properties={formData} schema={resolvedSchema} />\n )}\n {showActions && (\n <FormActions\n onSave={handleSave}\n onCancel={handleCancel}\n disabled={disabled}\n hasChanges={hasChanges}\n isValid={isValid}\n saveLabel={saveLabel}\n cancelLabel={cancelLabel}\n showCancel={showCancel}\n />\n )}\n </SimpleStack>\n );\n}\n\nexport type JsonSchemaFormRendererProps = {\n /** JSON Schema defining the form fields */\n schema: JsonSchema;\n\n /** Current form data */\n data: Record<string, any>;\n\n /** Callback when any field changes (real-time updates) */\n onChange?: (data: Record<string, any>) => void;\n\n /** Callback when a field loses focus */\n onBlur?: (fieldName: string, data: Record<string, any>) => void;\n\n /** Optional callback for validation state changes */\n onValidationChange?: (errors: string[], isValid: boolean) => void;\n\n /**\n * Defer onChange to blur for text fields (default: false).\n * Checkboxes and selects always trigger immediately.\n */\n deferChanges?: boolean;\n\n /**\n * Defer internal state updates to blur for text fields (default: false).\n * Only applies when showActions=true. The Save button enables only after\n * leaving a modified text field.\n */\n deferStateUpdates?: boolean;\n\n /**\n * Callback when user saves changes -- only fired if data actually changed.\n *\n * - `data`: complete form data (all fields, _fid stripped)\n * - `changedFields`: only fields that differ from the original baseline,\n * useful for PATCH-style APIs with exclude_unset semantics (_fid stripped)\n * - `diff`: structured diff classifying each change as value/array add/remove/move/modify.\n * Array item changes carry `fid` tokens for correlation; these are form-internal\n * and are never sent to the server.\n */\n onUpdate?: (\n data: Record<string, any>,\n changedFields: Record<string, any>,\n diff: FormDiff,\n ) => void;\n\n /** Callback when user clicks Cancel */\n onCancel?: () => void;\n\n /** Disable all fields */\n disabled?: boolean;\n\n /** Read-only mode — fields are not editable */\n readOnly?: boolean;\n\n /** Show Save/Cancel action buttons */\n showActions?: boolean;\n\n /** Label for Save button (default: \"Save\") */\n saveLabel?: string;\n\n /** Label for Cancel button (default: \"Cancel\") */\n cancelLabel?: string;\n\n /** Show the Cancel button (default: true) */\n showCancel?: boolean;\n\n /** Show extra properties card (default: true) */\n showExtraProperties?: boolean;\n\n /** Widget registry for custom widgets (default: DEFAULT_WIDGETS) */\n widgets?: WidgetRegistry;\n\n /**\n * Template registry for custom layout templates (default: DEFAULT_TEMPLATES).\n *\n * Templates control structural rendering (array item rows, object containers).\n * Widgets control input rendering. Override specific templates by providing\n * a partial registry -- unspecified keys fall back to DEFAULT_TEMPLATES.\n */\n templates?: TemplateRegistry;\n\n /**\n * When true, renders with `display: contents` instead of a SimpleStack.\n *\n * Used by ObjectWidget when it is a direct child of a HorizontalArrayItemTemplate\n * row grid. `display: contents` makes this renderer's wrapper invisible to the\n * layout algorithm so each field div becomes a direct grid cell in the row.\n */\n displayContents?: boolean;\n\n /**\n * UISchema for customizing widget behavior and appearance.\n *\n * @example\n * ```typescript\n * uiSchema={{\n * 'x-ui-globalOptions': { label: false },\n * 'x-ui-order': ['email', 'name'],\n * name: { 'x-ui-widget': 'textarea' },\n * }}\n * ```\n */\n uiSchema?: { [fieldName: string]: UISchema };\n};\n\nexport function JsonSchemaFormRenderer(\n props: JsonSchemaFormRendererProps,\n): React.ReactElement {\n const {\n schema,\n data,\n onChange,\n onBlur,\n onValidationChange,\n onUpdate,\n onCancel,\n templates,\n } = props;\n\n const {\n disabled,\n readOnly,\n showActions,\n deferChanges,\n deferStateUpdates,\n showCancel,\n showExtraProperties,\n displayContents,\n } = resolveFlagDefaults(props);\n\n const { saveLabel, cancelLabel, widgets, uiSchema } =\n resolveValueDefaults(props);\n\n const { wrappedOnChange, wrappedOnBlur, wrappedOnUpdate } =\n useWrappedCallbacks(onChange, onBlur, onUpdate);\n\n const {\n formData,\n displayData,\n resolvedSchema,\n orderedProperties,\n hasChanges,\n isValid,\n handleFieldChange,\n handleFieldBlur,\n handleSave,\n handleCancel,\n } = useFormEngine({\n schema,\n data,\n uiSchema,\n onChange: wrappedOnChange,\n onBlur: wrappedOnBlur,\n onValidationChange,\n onUpdate: wrappedOnUpdate,\n onCancel,\n readOnly,\n showActions,\n deferChanges,\n deferStateUpdates,\n });\n\n const globalOptions: UISchemaOptions =\n (uiSchema[\"x-ui-globalOptions\"] as UISchemaOptions) || {};\n\n // Merge caller-supplied templates over the defaults. Callers only need\n // to provide the templates they want to override.\n const resolvedTemplates = useMemo(\n () => ({ ...DEFAULT_TEMPLATES, ...templates }),\n [templates],\n );\n\n // Provide renderer + templates to nested widgets via context so they can\n // render sub-forms and resolve layout templates without circular imports.\n // The `displayContents` prop is forwarded from the call site (ObjectWidget)\n // when this renderer is inside a horizontal array row grid.\n const nestedRenderer = useCallback<NestedRenderer>(\n (props) => (\n <JsonSchemaFormRenderer\n {...props}\n templates={resolvedTemplates}\n showActions={false}\n showExtraProperties={false}\n />\n ),\n [resolvedTemplates],\n );\n\n const contextValue = useMemo(\n () => ({ renderer: nestedRenderer, templates: resolvedTemplates }),\n [nestedRenderer, resolvedTemplates],\n );\n\n const needsBlurHandler = deferStateUpdates || !!onBlur;\n const fields = orderedProperties.map(([fieldName, property]) => (\n <FormFieldRenderer\n key={fieldName}\n fieldName={fieldName}\n property={property}\n value={displayData[fieldName]}\n onChange={(v) => handleFieldChange(fieldName, v)}\n onBlur={needsBlurHandler ? () => handleFieldBlur(fieldName) : undefined}\n required={isFieldRequired(resolvedSchema, fieldName)}\n disabled={disabled}\n readOnly={readOnly}\n schema={schema}\n uiSchema={uiSchema[fieldName]}\n registry={widgets}\n globalOptions={globalOptions}\n formData={displayData}\n />\n ));\n\n // Read row layout config from the uiSchema.\n const layoutConfig = uiSchema[\"x-ui-layout\"] as UILayoutConfig | undefined;\n const rowDefs = layoutConfig?.rows;\n // Default gap used within rows when no per-row gap is specified.\n const defaultRowGap = layoutConfig?.gap ?? 24;\n\n // When row definitions are present, group fields into CSS grid rows.\n // Fields not mentioned in any row are collected into a trailing vertical group.\n const layoutFields = useMemo(\n () =>\n rowDefs && rowDefs.length > 0\n ? layoutFieldsInRows(fields, rowDefs, defaultRowGap)\n : fields,\n [fields, rowDefs, defaultRowGap],\n );\n\n return (\n <NestedFormContext.Provider value={contextValue}>\n <FormContainer\n displayContents={displayContents}\n showExtraProperties={showExtraProperties}\n showActions={showActions}\n formData={formData}\n resolvedSchema={resolvedSchema}\n handleSave={handleSave}\n handleCancel={handleCancel}\n disabled={disabled}\n hasChanges={hasChanges}\n isValid={isValid}\n saveLabel={saveLabel}\n cancelLabel={cancelLabel}\n showCancel={showCancel}\n >\n {layoutFields}\n </FormContainer>\n </NestedFormContext.Provider>\n );\n}\n","/**\n * Widget Type System\n *\n * Type definitions for the JSON Schema Form widget architecture.\n * Based on react-jsonschema-form patterns with simplified Mantine-focused implementation.\n */\n\nimport {\n JsonSchema,\n JsonSchemaProperty,\n UISchema,\n UILayoutConfig,\n UISchemaOptions,\n} from \"@petrarca/sonnet-core/schema\";\nimport { ComponentType } from \"react\";\n\n// Re-export for convenience\nexport type {\n UISchema,\n UISchemaOptions,\n UILayoutConfig,\n} from \"@petrarca/sonnet-core/schema\";\n\n/**\n * WidgetRegistry - Map of widget name to component\n *\n * @example\n * ```typescript\n * const registry: WidgetRegistry = {\n * TextWidget: TextWidget,\n * SelectWidget: SelectWidget,\n * CustomWidget: MyCustomWidget\n * }\n * ```\n */\nexport type WidgetRegistry = {\n [widgetName: string]: Widget;\n};\n\n/**\n * WidgetProps - Props passed to every widget\n *\n * Widgets receive comprehensive context to make intelligent decisions.\n * All widgets must accept these props.\n *\n * @example\n * ```typescript\n * export function MyWidget({\n * id,\n * value,\n * onChange,\n * label,\n * propertySchema,\n * options\n * }: WidgetProps) {\n * const customOption = options?.myCustomOption ?? 'default';\n * // ...\n * }\n * ```\n */\nexport interface WidgetProps {\n // Identification\n /** Unique field ID */\n id: string;\n /** Field name */\n name: string;\n\n // Schema Context - Full access to make informed decisions\n /** Full form schema */\n schema: JsonSchema;\n /** This field's schema */\n propertySchema: JsonSchemaProperty;\n /** UI configuration for this field */\n uiSchema?: UISchema;\n /** Access to all widgets */\n registry: WidgetRegistry;\n\n // Data & Events\n /** Current field value */\n value: unknown;\n /** Called when value changes */\n onChange: (value: unknown) => void;\n /** Called when field loses focus */\n onBlur?: (id: string, value: unknown) => void;\n /** Called when field gains focus */\n onFocus?: (id: string, value: unknown) => void;\n\n // Form Context\n /** Current form data - all field values (for dependent/cascading widgets) */\n formData?: Record<string, unknown>;\n\n // Display\n /** Field label (empty string = hidden) */\n label: string;\n /** Field description */\n description?: string;\n /** Placeholder text */\n placeholder?: string;\n\n // State\n /** Is field required */\n required?: boolean;\n /** Is field disabled */\n disabled?: boolean;\n /** Is field readonly */\n readonly?: boolean;\n /** Should field autofocus */\n autofocus?: boolean;\n\n // Validation\n /** Raw validation errors */\n rawErrors?: string[];\n\n // Options - Widget accesses x-ui-options for any configuration it needs\n /** Widget-specific options from x-ui-options */\n options?: UISchemaOptions;\n}\n\n/**\n * Widget - React component type for form widgets\n *\n * @example\n * ```typescript\n * const TextWidget: Widget = ({ id, value, onChange, label }) => (\n * <TextInput id={id} value={value} onChange={e => onChange(e.target.value)} label={label} />\n * );\n * ```\n */\nexport type Widget = ComponentType<WidgetProps>;\n\n/**\n * WidgetDescriptor - Extended information for widget registration\n *\n * Allows providing metadata along with the widget component.\n *\n * @example\n * ```typescript\n * const descriptor: WidgetDescriptor = {\n * component: MyWidget,\n * displayName: 'My Custom Widget',\n * description: 'A widget for custom input',\n * defaultOptions: { rows: 3 }\n * }\n * ```\n */\nexport interface WidgetDescriptor {\n /** The widget component */\n component: Widget;\n /** Display name for debugging */\n displayName?: string;\n /** Description of what the widget does */\n description?: string;\n /** Default options to apply */\n defaultOptions?: UISchemaOptions;\n}\n\n/**\n * WidgetMap - Type/format to widget name mapping\n *\n * Defines the default widget to use for each schema type and format.\n *\n * @example\n * ```typescript\n * const map: WidgetMap = {\n * string: {\n * default: 'TextWidget',\n * email: 'EmailWidget',\n * textarea: 'TextareaWidget'\n * }\n * }\n * ```\n */\nexport type WidgetMap = {\n [schemaType: string]: {\n [variantOrFormat: string]: string;\n };\n};\n\n/**\n * Return the first validation error message, or undefined if there are none.\n * Avoids repeating `rawErrors && rawErrors.length > 0 ? rawErrors[0] : undefined`\n * in every widget.\n */\nexport function firstError(rawErrors?: string[]): string | undefined {\n return rawErrors && rawErrors.length > 0 ? rawErrors[0] : undefined;\n}\n\n/**\n * SelectOption - Single option in a select dropdown\n */\nexport interface SelectOption {\n value: string;\n label: string;\n}\n\n// Templates -- rendering functions for structural layout concerns.\n// Separate from widgets (which render input controls).\n// Injected via JsonSchemaFormRenderer's `templates` prop or per-field\n// via x-ui-options.itemTemplate / x-ui-options.containerTemplate.\n\n/** Props passed to an ArrayItemTemplate */\nexport interface ArrayItemTemplateProps {\n children: React.ReactNode;\n index: number;\n total: number;\n canRemove: boolean;\n orderable: boolean;\n disabled?: boolean;\n layout: UILayoutConfig;\n fieldCount: number;\n onRemove: () => void;\n onMoveUp?: () => void;\n onMoveDown?: () => void;\n}\n\n/** Props passed to an ArrayHeaderTemplate */\nexport interface ArrayHeaderTemplateProps {\n itemSchema: JsonSchemaProperty;\n layout: UILayoutConfig;\n canRemove: boolean;\n orderable: boolean;\n fieldCount: number;\n}\n\n/** Props passed to an ObjectContainerTemplate */\nexport interface ObjectContainerTemplateProps {\n children: React.ReactNode;\n label: string;\n description?: string;\n variant?: string;\n defaultOpen?: boolean;\n}\n\nexport type ArrayItemTemplate = (\n props: ArrayItemTemplateProps,\n) => React.ReactElement;\n\nexport type ArrayHeaderTemplate = (\n props: ArrayHeaderTemplateProps,\n) => React.ReactElement | null;\n\nexport type ObjectContainerTemplate = (\n props: ObjectContainerTemplateProps,\n) => React.ReactElement;\n\n/**\n * TemplateRegistry -- named rendering functions for structural layout.\n *\n * Built-in keys: ArrayItemTemplate, ArrayHeaderTemplate, ObjectContainerTemplate.\n * Custom keys are allowed for per-field template overrides (looked up by name).\n * The index signature uses `unknown` to avoid TypeScript variance conflicts with\n * the specifically-typed named properties.\n */\nexport type TemplateRegistry = {\n ArrayItemTemplate?: ArrayItemTemplate;\n HorizontalArrayItemTemplate?: ArrayItemTemplate;\n ArrayHeaderTemplate?: ArrayHeaderTemplate;\n ObjectContainerTemplate?: ObjectContainerTemplate;\n [templateName: string]: unknown;\n};\n","/**\n * TextInputWidget - Standard text input widget\n *\n * Renders a single-line text input field using FormInput.\n * Supports various input types via format (email, url, text).\n */\n\nimport { FormInput } from \"../FormInput\";\nimport { WidgetProps, firstError } from \"./types\";\n\n// Determine HTML input type based on JSON Schema format.\nfunction inputTypeFromFormat(format: string | undefined): string {\n if (format === \"email\") return \"email\";\n if (format === \"uri\" || format === \"url\") return \"url\";\n return \"text\";\n}\n\n/**\n * TextInputWidget renders a standard text input field.\n *\n * Supports:\n * - Basic string input\n * - Email input (format: 'email')\n * - URL input (format: 'uri' or 'url')\n * - Validation constraints (minLength, maxLength, pattern)\n */\nexport function TextInputWidget({\n id,\n name,\n value,\n onChange,\n onBlur,\n propertySchema,\n required,\n disabled,\n readonly,\n rawErrors,\n label,\n description,\n placeholder,\n autofocus,\n options,\n}: WidgetProps): React.ReactElement {\n const error = firstError(rawErrors);\n const compact = options?.compact;\n\n return (\n <FormInput\n id={id}\n name={name}\n value={value !== undefined && value !== null ? String(value) : \"\"}\n onChange={(event) => onChange(event.currentTarget.value)}\n onBlur={() => onBlur?.(id, value)}\n label={label}\n description={description}\n placeholder={placeholder}\n required={required}\n disabled={disabled}\n readOnly={readonly}\n error={error}\n type={options?.inputType ?? inputTypeFromFormat(propertySchema.format)}\n minLength={propertySchema.minLength}\n maxLength={propertySchema.maxLength}\n autoFocus={autofocus}\n compact={compact as boolean | undefined}\n className={compact ? \"h-8 text-xs\" : undefined}\n />\n );\n}\n","/**\n * TextareaWidget - Multi-line text input\n *\n * Renders a multi-line textarea field using FormTextarea.\n * Supports autosize and configurable rows.\n */\n\nimport { FormTextarea } from \"../FormTextarea\";\nimport { WidgetProps, firstError } from \"./types\";\n\n/**\n * TextareaWidget renders a multi-line text input field.\n *\n * Supports:\n * - Multi-line text input\n * - Autosize functionality\n * - Configurable minimum rows via x-ui-options\n * - Validation constraints (minLength, maxLength)\n *\n * @param props - WidgetProps\n */\nexport function TextareaWidget({\n id,\n name,\n value,\n onChange,\n onBlur,\n propertySchema,\n required,\n disabled,\n readonly,\n rawErrors,\n label,\n description,\n placeholder,\n autofocus,\n options = {},\n}: WidgetProps) {\n const minRows = options.rows || options.minRows || 3;\n const autosize = options.autosize !== false; // Default to true\n\n const error = firstError(rawErrors);\n\n return (\n <FormTextarea\n id={id}\n name={name}\n value={value !== undefined && value !== null ? String(value) : \"\"}\n onChange={(event) => onChange(event.currentTarget.value)}\n onBlur={() => onBlur?.(id, value)}\n label={label}\n description={description}\n placeholder={placeholder}\n required={required}\n disabled={disabled}\n readOnly={readonly}\n error={error}\n minRows={minRows}\n autosize={autosize}\n minLength={propertySchema.minLength}\n maxLength={propertySchema.maxLength}\n autoFocus={autofocus}\n />\n );\n}\n","/**\n * NumberWidget - Number/Integer input widget\n *\n * Renders a number input field using FormNumberInput.\n * Handles both number and integer types with appropriate step values.\n */\n\nimport { FormNumberInput } from \"../FormNumberInput\";\nimport { WidgetProps, firstError } from \"./types\";\n\n/**\n * NumberWidget renders a number input field.\n *\n * Supports:\n * - Number input (decimal allowed)\n * - Integer input (step = 1, no decimals)\n * - Min/max constraints from schema\n * - Step configuration via x-ui-options\n *\n * @param props - WidgetProps\n */\nexport function NumberWidget({\n id,\n name,\n value,\n onChange,\n onBlur,\n propertySchema,\n required,\n disabled,\n readonly,\n rawErrors,\n label,\n description,\n placeholder,\n autofocus,\n options = {},\n}: WidgetProps) {\n const isInteger = propertySchema.type === \"integer\";\n const step = options.step ?? (isInteger ? 1 : undefined);\n const allowDecimal = options.allowDecimal ?? !isInteger;\n\n const error = firstError(rawErrors);\n\n return (\n <FormNumberInput\n id={id}\n name={name}\n value={value !== undefined && value !== null ? Number(value) : undefined}\n onChange={(val) => onChange(val)}\n onBlur={() => onBlur?.(id, value)}\n label={label}\n description={description}\n placeholder={placeholder}\n required={required}\n disabled={disabled}\n readOnly={readonly}\n error={error}\n min={propertySchema.minimum}\n max={propertySchema.maximum}\n step={step}\n allowDecimal={allowDecimal}\n autoFocus={autofocus}\n />\n );\n}\n","/**\n * CheckboxWidget - Boolean checkbox widget\n *\n * Renders a checkbox input using FormCheckbox.\n * Used for boolean type fields.\n *\n * Supports tri-state behavior for nullable boolean fields (anyOf[boolean, null]):\n * - null (indeterminate) -> true (checked) -> false (unchecked) -> null\n */\n\nimport { useCallback } from \"react\";\nimport { FormCheckbox } from \"../FormCheckbox\";\nimport { isNullableBoolean } from \"@petrarca/sonnet-core/schema\";\nimport { WidgetProps, firstError } from \"./types\";\n\n/**\n * CheckboxWidget renders a checkbox for boolean values.\n *\n * Supports:\n * - Boolean true/false values (standard checkbox)\n * - Tri-state true/false/null values (indeterminate checkbox)\n * - Custom labels from schema or UISchema\n * - Description text\n *\n * Tri-state behavior (when anyOf[boolean, null] is detected):\n * - Click on null -> becomes true\n * - Click on true -> becomes false\n * - Click on false -> becomes null\n */\nexport function CheckboxWidget({\n id,\n value,\n onChange,\n onBlur,\n disabled,\n readonly,\n rawErrors,\n label,\n description,\n autofocus,\n propertySchema,\n options,\n}: WidgetProps): React.ReactElement {\n const error = firstError(rawErrors);\n const compact = options?.compact;\n\n // Detect if this is a nullable boolean (tri-state)\n const isTriState = isNullableBoolean(propertySchema);\n\n // Determine checkbox state\n const isChecked = value === true;\n const isIndeterminate = isTriState && value === null;\n const checkedState: boolean | \"indeterminate\" = isIndeterminate\n ? \"indeterminate\"\n : isChecked;\n\n // Handle change with tri-state logic\n const handleChange = useCallback(\n (_newChecked: boolean | \"indeterminate\") => {\n if (isTriState) {\n if (value === null) {\n onChange(true);\n } else if (value === true) {\n onChange(false);\n } else {\n onChange(null);\n }\n } else {\n onChange(_newChecked === true);\n }\n },\n [isTriState, value, onChange],\n );\n\n return (\n <FormCheckbox\n id={id}\n checked={checkedState}\n onChange={handleChange}\n onBlur={() => onBlur?.(id, value)}\n label={label}\n description={description}\n disabled={disabled}\n readOnly={readonly}\n error={error}\n autoFocus={autofocus}\n compact={compact as boolean | undefined}\n />\n );\n}\n","/**\n * SelectWidget - Dropdown selection widget\n *\n * Renders a dropdown select field using FormSelect or FormMultiSelect.\n * Used for enum fields with a list of predefined options.\n * Supports both single-select (returns string) and multi-select (returns array) modes.\n */\n\nimport { useRef } from \"react\";\nimport { FormSelect } from \"../FormSelect\";\nimport { FormMultiSelect } from \"../FormMultiSelect\";\nimport { extractEnumValues } from \"@petrarca/sonnet-core/schema\";\nimport { badgeVariants } from \"@petrarca/sonnet-ui\";\nimport type { VariantProps } from \"class-variance-authority\";\nimport { WidgetProps, firstError } from \"./types\";\n\ntype BadgeColor = NonNullable<VariantProps<typeof badgeVariants>[\"badgeColor\"]>;\n\n/**\n * SelectWidget renders a dropdown select for enum values.\n *\n * Supports:\n * - Enum values from schema\n * - Custom display names via x-ui-options.enumNames\n * - Searchable dropdown\n * - Clearable option (when not required)\n * - Multi-select mode (auto-detected from schema type='array' or explicit multiple option)\n * - Custom badge colors for multi-select mode\n *\n * @param props - WidgetProps\n */\n/** Build select options from enum values with optional display names. */\nfunction buildSelectOptions(\n propertySchema: WidgetProps[\"propertySchema\"],\n enumNames: Record<string | number, string>,\n) {\n const enumValues = extractEnumValues(propertySchema);\n return enumValues.map((val) => {\n const key = String(val);\n return { value: key, label: enumNames[key] || key };\n });\n}\n\n/** Normalize a value into a string array for multi-select. */\nfunction normalizeMultiValue(value: unknown): string[] {\n if (Array.isArray(value)) return value.map(String);\n if (value) return [String(value)];\n return [];\n}\n\n/** Normalize a value into a string or null for single-select. */\nfunction normalizeSingleValue(value: unknown): string | null {\n if (value !== undefined && value !== null) return String(value);\n return null;\n}\n\nexport function SelectWidget(props: WidgetProps) {\n const {\n id,\n name,\n value,\n onChange,\n onBlur,\n propertySchema,\n required,\n disabled,\n readonly,\n rawErrors,\n label,\n description,\n placeholder,\n autofocus,\n } = props;\n const widgetOptions = props.options ?? {};\n\n const valueRef = useRef(value);\n valueRef.current = value;\n\n const enumNames = widgetOptions.enumNames || {};\n const clearable = widgetOptions.clearable !== false && !required;\n const isMultiple = widgetOptions.multiple ?? propertySchema.type === \"array\";\n const selectOptions = buildSelectOptions(propertySchema, enumNames);\n const error = firstError(rawErrors);\n const compact = widgetOptions?.compact;\n const triggerClassName = compact ? \"h-8 text-xs\" : undefined;\n const handleBlur = () => onBlur?.(id, valueRef.current);\n\n if (isMultiple) {\n return (\n <FormMultiSelect\n id={id}\n name={name}\n options={selectOptions}\n value={normalizeMultiValue(value)}\n onChange={(newValue) => onChange(newValue || [])}\n label={label}\n description={description}\n placeholder={placeholder}\n required={required}\n disabled={disabled}\n readOnly={readonly}\n error={error}\n clearable={clearable}\n autoFocus={autofocus}\n badgeColor={widgetOptions.badgeColor as BadgeColor | undefined}\n onBlur={handleBlur}\n className={triggerClassName}\n />\n );\n }\n\n return (\n <FormSelect\n id={id}\n name={name}\n options={selectOptions}\n value={normalizeSingleValue(value)}\n onChange={(val) => onChange(val || \"\")}\n label={label}\n description={description}\n placeholder={placeholder}\n required={required}\n disabled={disabled}\n readOnly={readonly}\n error={error}\n clearable={clearable}\n autoFocus={autofocus}\n onBlur={handleBlur}\n className={triggerClassName}\n compact={compact}\n />\n );\n}\n","/**\n * TagsInputWidget - Free-text tag input widget\n *\n * Renders FormTagsInput for array-of-string fields where the user types\n * free-text values (no predefined enum). Tags are entered by pressing\n * Enter or comma and displayed as dismissible badges. Duplicates are\n * rejected by default.\n *\n * Use via x-ui-widget: \"tags\" in a JSON Schema or Zod .meta().\n */\n\nimport React from \"react\";\nimport { FormTagsInput } from \"../FormTagsInput\";\nimport { type WidgetProps, firstError } from \"./types\";\n\n/**\n * TagsInputWidget renders a free-text tag input field.\n *\n * Supports:\n * - Free-text tag creation (Enter or comma)\n * - Duplicate rejection (default)\n * - Max tags limit (via x-ui-options.maxTags)\n * - Custom split keys (via x-ui-options.splitKeys)\n */\nexport function TagsInputWidget({\n id,\n name,\n value,\n onChange,\n required,\n disabled,\n readonly,\n rawErrors,\n label,\n description,\n placeholder,\n options,\n}: WidgetProps): React.ReactElement {\n const error = firstError(rawErrors);\n const tags = Array.isArray(value) ? value.map(String) : [];\n\n return (\n <FormTagsInput\n id={id}\n name={name}\n value={tags}\n onChange={(newTags) => onChange(newTags)}\n label={label}\n description={description}\n placeholder={placeholder ?? \"Type and press Enter\"}\n required={required}\n disabled={disabled}\n readOnly={readonly}\n error={error}\n maxTags={options?.maxTags as number | undefined}\n splitKeys={options?.splitKeys as string[] | undefined}\n allowDuplicates={false}\n />\n );\n}\n","/**\n * JsonEditorWidget - JSON document editor widget.\n *\n * Renders JsonEditor for object/any fields where the user authors raw JSON.\n * The full document is editable. Invalid JSON is not propagated -- the last\n * valid value is retained until the user fixes the syntax error.\n *\n * Use via x-ui-widget: \"json-editor\" in a JSON Schema or Zod .meta().\n */\n\nimport React, { useCallback, useState } from \"react\";\nimport { JsonEditor } from \"@petrarca/sonnet-ui/json-editor\";\nimport { type WidgetProps } from \"./types\";\n\n// Single editable path covering the full document.\nconst FULL_DOCUMENT: string[] = [\"/\"];\n\n/**\n * JsonEditorWidget renders a full-document JSON editor.\n *\n * Supports:\n * - Full document editing (no readonly regions)\n * - Invalid JSON is silently retained until fixed\n * - Height configurable via x-ui-options.height (default: \"240px\")\n */\nexport function JsonEditorWidget({\n id,\n value,\n onChange,\n label,\n description,\n required,\n options,\n}: WidgetProps): React.ReactElement {\n const [raw, setRaw] = useState(\n value != null ? JSON.stringify(value, null, 2) : \"\",\n );\n\n const height = (options?.height as string | undefined) ?? \"240px\";\n\n const handleChange = useCallback(\n (val: string) => {\n setRaw(val);\n try {\n const parsed: unknown = JSON.parse(val);\n onChange(parsed);\n } catch {\n // Hold the last valid value -- do not propagate invalid JSON.\n }\n },\n [onChange],\n );\n\n return (\n <div className=\"space-y-2\">\n {label && (\n <label htmlFor={id} className=\"text-sm font-medium leading-none\">\n {label}\n {required && <span className=\"text-destructive ml-1\">*</span>}\n </label>\n )}\n {description && (\n <p className=\"text-sm text-muted-foreground\">{description}</p>\n )}\n <JsonEditor\n value={raw}\n editablePaths={FULL_DOCUMENT}\n onChange={handleChange}\n height={height}\n className=\"rounded-md border overflow-hidden\"\n />\n </div>\n );\n}\n","/**\n * EntitySelectWidget -- form widget for async entity reference selection.\n *\n * Wraps EntitySelect and adapts it to the WidgetProps contract. Reads\n * x-ui-options for fetcher configuration (REST or GraphQL) and uses the\n * FetcherProvider context to create the appropriate fetcher.\n *\n * Schema usage:\n * x-ui-widget: \"entity-select\"\n * x-ui-options: {\n * endpoint: \"/organizations\", // REST: relative to API base\n * valueKey: \"org_id\",\n * labelKey: \"name\",\n * }\n * -- or --\n * x-ui-options: {\n * query: \"query Orgs($search: String, $limit: Int) { ... }\",\n * dataPath: \"organizations\",\n * valueKey: \"org_id\",\n * labelKey: \"name\",\n * }\n */\n\nimport React, { useMemo } from \"react\";\nimport { EntitySelect } from \"@petrarca/sonnet-ui\";\nimport { useFetcherFactory } from \"@petrarca/sonnet-core/entityOptions\";\nimport type { EntitySelectMode } from \"@petrarca/sonnet-core/hooks\";\nimport type { WidgetProps, UISchemaOptions } from \"./types\";\nimport { firstError } from \"./types\";\nimport type {\n RestFetcherConfig,\n GraphqlFetcherConfig,\n} from \"@petrarca/sonnet-core/entityOptions\";\n\n// ---------------------------------------------------------------------------\n// Pure helpers\n// ---------------------------------------------------------------------------\n\nconst VALID_MODES: EntitySelectMode[] = [\"eager\", \"typeahead\", \"explicit\"];\n\n/** Resolve the select mode from widget options. */\nfunction resolveSelectMode(\n options: UISchemaOptions | undefined,\n): EntitySelectMode {\n const rawMode = options?.mode;\n if (\n typeof rawMode === \"string\" &&\n VALID_MODES.includes(rawMode as EntitySelectMode)\n ) {\n return rawMode as EntitySelectMode;\n }\n return \"eager\";\n}\n\n/** Resolve the minimum character threshold. */\nfunction resolveMinChars(options: UISchemaOptions | undefined): number {\n const rawMinChars = options?.minChars;\n if (typeof rawMinChars === \"number\" && rawMinChars >= 1) return rawMinChars;\n return 1;\n}\n\n/** Build a REST fetcher config from options. */\nfunction buildRestConfig(options: UISchemaOptions): RestFetcherConfig | null {\n if (!(\"endpoint\" in options) || !options.endpoint) return null;\n return {\n endpoint: String(options.endpoint),\n valueKey: String(options.valueKey ?? \"id\"),\n labelKey: String(options.labelKey ?? \"name\"),\n searchKey: options.searchKey ? String(options.searchKey) : undefined,\n };\n}\n\n/** Build a GraphQL fetcher config from options. */\nfunction buildGraphqlConfig(\n options: UISchemaOptions,\n): GraphqlFetcherConfig | null {\n if (!(\"query\" in options) || !options.query) return null;\n return {\n query: String(options.query),\n dataPath: String(options.dataPath ?? \"\"),\n valueKey: String(options.valueKey ?? \"id\"),\n labelKey: String(options.labelKey ?? \"name\"),\n };\n}\n\n/** Build fetcher config from widget options. Returns null if insufficient config. */\nfunction buildFetcherConfig(\n options: UISchemaOptions | undefined,\n): RestFetcherConfig | GraphqlFetcherConfig | null {\n if (!options) return null;\n return buildRestConfig(options) ?? buildGraphqlConfig(options);\n}\n\n/** Derive a stable query key from the fetcher config. */\nfunction deriveQueryKey(\n config: RestFetcherConfig | GraphqlFetcherConfig | null,\n fallbackName: string,\n): string {\n if (!config) return fallbackName;\n if (\"endpoint\" in config) return config.endpoint;\n return `graphql:${config.dataPath}`;\n}\n\n// ---------------------------------------------------------------------------\n// EntitySelectWidget\n// ---------------------------------------------------------------------------\n\nexport function EntitySelectWidget({\n id,\n name,\n value,\n onChange,\n onBlur,\n label,\n description,\n placeholder,\n required,\n disabled,\n readonly,\n rawErrors,\n options,\n}: WidgetProps): React.ReactElement {\n const createFetcher = useFetcherFactory();\n\n const selectMode = resolveSelectMode(options);\n const selectMinChars = resolveMinChars(options);\n\n const fetcherConfig = useMemo(() => buildFetcherConfig(options), [options]);\n const fetcher = useMemo(() => {\n if (!fetcherConfig) return null;\n return createFetcher(fetcherConfig);\n }, [createFetcher, fetcherConfig]);\n const queryKey = useMemo(\n () => deriveQueryKey(fetcherConfig, name ?? \"\"),\n [fetcherConfig, name],\n );\n\n if (!fetcher) {\n return (\n <div className=\"text-sm text-destructive\">\n EntitySelectWidget: missing endpoint or query in x-ui-options for field\n &quot;{name}&quot;\n </div>\n );\n }\n\n return (\n <EntitySelect\n id={id}\n fetcher={fetcher}\n queryKey={queryKey}\n mode={selectMode}\n minChars={selectMinChars}\n value={typeof value === \"string\" ? value : null}\n onChange={(v) => onChange(v ?? \"\")}\n onBlur={() => onBlur?.(id, value)}\n label={label || false}\n description={description}\n placeholder={placeholder}\n required={required}\n disabled={disabled || readonly}\n error={firstError(rawErrors)}\n />\n );\n}\n","/**\n * ObjectWidget -- renders a nested sub-form for type: \"object\" properties.\n *\n * Composes a JsonSchemaFormRenderer scoped to the sub-schema. The renderer\n * is injected via NestedFormContext so there is no circular import.\n *\n * Presentation is delegated to ObjectContainerTemplate (resolved from context,\n * defaulting to DefaultObjectContainerTemplate). The variant passed via\n * options controls which container is used (section, card, collapsible,\n * inline, borderless).\n *\n * When options.displayContents is true (set by ArrayWidget in horizontal mode)\n * the sub-renderer uses display:contents so its field divs become direct grid\n * cells in the parent row grid.\n *\n * When options.globalOptions is set, it is forwarded to the sub-renderer so\n * compact / label suppression propagates to all nested widgets.\n */\n\nimport { useMemo } from \"react\";\nimport type {\n JsonSchema,\n JsonSchemaProperty,\n UILayoutConfig,\n UISchema,\n} from \"@petrarca/sonnet-core/schema\";\nimport { useNestedFormContext } from \"../hooks/useNestedFormContext\";\nimport { DefaultObjectContainerTemplate } from \"../templates/DefaultObjectContainerTemplate\";\nimport type { WidgetProps } from \"./types\";\n\n// ---------------------------------------------------------------------------\n// Pure helpers\n// ---------------------------------------------------------------------------\n\n/** Build a JsonSchema from the property's nested structure. */\nfunction buildSubSchema(prop: JsonSchemaProperty): JsonSchema | null {\n const properties = prop.properties;\n if (!properties) return null;\n return {\n title: prop.title || \"\",\n type: \"object\",\n properties,\n required: prop.required,\n ...(prop.allOf ? { allOf: prop.allOf } : {}),\n ...(prop.if ? { if: prop.if } : {}),\n ...(prop.then ? { then: prop.then } : {}),\n ...(prop.else ? { else: prop.else } : {}),\n ...(prop[\"x-ui-order\"] ? { \"x-ui-order\": prop[\"x-ui-order\"] } : {}),\n };\n}\n\n/** Merge field-level uiSchema with globalOptions and layout for sub-renderer. */\nfunction buildEffectiveUiSchema(\n subUiSchema: { [fieldName: string]: UISchema },\n globalOptions: Record<string, unknown> | undefined,\n layout: UILayoutConfig | undefined,\n): { [fieldName: string]: UISchema } {\n return {\n ...subUiSchema,\n ...(globalOptions\n ? { \"x-ui-globalOptions\": globalOptions as UISchema }\n : {}),\n ...(layout ? { \"x-ui-layout\": layout as unknown as UISchema } : {}),\n };\n}\n\n/** Extract typed options from the generic options bag. */\nfunction resolveObjectOptions(options: WidgetProps[\"options\"]) {\n return {\n variant: (options?.variant as string) || \"section\",\n defaultOpen: options?.defaultOpen !== false,\n displayContents: (options?.displayContents as boolean) ?? false,\n globalOptions: options?.globalOptions as\n | Record<string, unknown>\n | undefined,\n };\n}\n\n/** Resolve layout from uiSchema and property schema. */\nfunction resolveLayout(\n uiSchema: WidgetProps[\"uiSchema\"],\n propertySchema: JsonSchemaProperty,\n): UILayoutConfig | undefined {\n return (\n (uiSchema?.[\"x-ui-layout\"] as UILayoutConfig | undefined) ??\n propertySchema[\"x-ui-layout\"]\n );\n}\n\n// ---------------------------------------------------------------------------\n// ObjectWidget\n// ---------------------------------------------------------------------------\n\nexport function ObjectWidget({\n propertySchema,\n value,\n onChange,\n registry,\n uiSchema,\n disabled,\n readonly,\n label,\n description,\n options,\n}: WidgetProps): React.ReactElement | null {\n const { renderer: Renderer, templates } = useNestedFormContext();\n const ContainerTemplate =\n templates.ObjectContainerTemplate ?? DefaultObjectContainerTemplate;\n\n const subSchema = useMemo(\n () => buildSubSchema(propertySchema),\n [propertySchema],\n );\n\n const subUiSchema = useMemo(\n () =>\n (uiSchema?.[\"x-ui-fields\"] ?? {}) as { [fieldName: string]: UISchema },\n [uiSchema],\n );\n\n if (!subSchema) return null;\n\n const { variant, defaultOpen, displayContents, globalOptions } =\n resolveObjectOptions(options);\n const layout = resolveLayout(uiSchema, propertySchema);\n const effectiveUiSchema = buildEffectiveUiSchema(\n subUiSchema,\n globalOptions,\n layout,\n );\n\n const content = (\n <Renderer\n schema={subSchema}\n data={(value as Record<string, unknown>) || {}}\n onChange={onChange}\n disabled={disabled}\n readOnly={readonly}\n widgets={registry}\n uiSchema={effectiveUiSchema}\n displayContents={displayContents}\n />\n );\n\n if (displayContents) return <>{content}</>;\n\n return (\n <ContainerTemplate\n label={label}\n description={description}\n variant={variant}\n defaultOpen={defaultOpen}\n >\n {content}\n </ContainerTemplate>\n );\n}\n","/**\n * useNestedFormContext -- returns the renderer and templates injected by\n * the nearest JsonSchemaFormRenderer via NestedFormContext.\n *\n * Used by ObjectWidget and ArrayWidget to render nested sub-forms and\n * resolve layout templates without a circular import.\n *\n * Throws if called outside a JsonSchemaFormRenderer tree. This is\n * intentional: ObjectWidget and ArrayWidget cannot function without\n * the renderer context, and a clear error is better than a silent null.\n */\n\nimport { useContext } from \"react\";\nimport { NestedFormContext } from \"../NestedFormContext\";\nimport type { NestedFormContextValue } from \"../NestedFormContext\";\n\nexport function useNestedFormContext(): NestedFormContextValue {\n const ctx = useContext(NestedFormContext);\n if (!ctx) {\n throw new Error(\n \"useNestedFormContext must be used inside a JsonSchemaFormRenderer.\",\n );\n }\n return ctx;\n}\n","/**\n * NestedFormContext -- provides the JsonSchemaFormRenderer and the active\n * TemplateRegistry to nested widgets (ObjectWidget, ArrayWidget) without\n * creating a circular import.\n *\n * JsonSchemaFormRenderer sets this context on mount. Nested widgets read\n * it via useNestedFormContext() to render sub-forms and resolve templates.\n */\n\nimport { createContext } from \"react\";\nimport type { JsonSchemaFormRendererProps } from \"./JsonSchemaFormRenderer\";\nimport type { TemplateRegistry } from \"./widgets/types\";\n\nexport type NestedRenderer = (\n props: Omit<\n JsonSchemaFormRendererProps,\n \"onUpdate\" | \"onCancel\" | \"showActions\" | \"showExtraProperties\"\n >,\n) => React.ReactElement | null;\n\nexport interface NestedFormContextValue {\n renderer: NestedRenderer;\n templates: TemplateRegistry;\n}\n\nexport const NestedFormContext = createContext<NestedFormContextValue | null>(\n null,\n);\n","/**\n * DefaultObjectContainerTemplate -- wraps an ObjectWidget sub-form with\n * the appropriate presentation based on the variant option.\n *\n * Variants: section (default), card, collapsible, inline, borderless.\n * Extracted from ObjectWidget so ObjectWidget can delegate to this template\n * or to a caller-supplied replacement.\n */\n\nimport { useState } from \"react\";\nimport { ChevronDown, ChevronRight } from \"lucide-react\";\nimport { Card, CardContent, CardHeader, CardTitle } from \"@petrarca/sonnet-ui\";\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"@petrarca/sonnet-ui\";\nimport type { ObjectContainerTemplateProps } from \"../widgets/types\";\n\n// -- Variant sub-components -----------------------------------------------\n\nfunction CardVariant({\n children,\n label,\n description,\n}: {\n children: React.ReactNode;\n label?: string;\n description?: string;\n}) {\n return (\n <Card>\n {label && (\n <CardHeader className=\"pb-3\">\n <CardTitle className=\"text-base\">{label}</CardTitle>\n {description && (\n <p className=\"text-sm text-muted-foreground\">{description}</p>\n )}\n </CardHeader>\n )}\n <CardContent>{children}</CardContent>\n </Card>\n );\n}\n\nfunction SectionVariant({\n children,\n label,\n description,\n}: {\n children: React.ReactNode;\n label?: string;\n description?: string;\n}) {\n return (\n <div className=\"space-y-3\">\n {label && (\n <div>\n <h4 className=\"text-sm font-medium\">{label}</h4>\n {description && (\n <p className=\"text-xs text-muted-foreground\">{description}</p>\n )}\n </div>\n )}\n <div className=\"pl-3 border-l-2 border-muted\">{children}</div>\n </div>\n );\n}\n\n// -- DefaultObjectContainerTemplate ----------------------------------------\n\nexport function DefaultObjectContainerTemplate({\n children,\n label,\n description,\n variant = \"section\",\n defaultOpen = true,\n}: ObjectContainerTemplateProps): React.ReactElement {\n switch (variant) {\n case \"card\":\n return (\n <CardVariant label={label} description={description}>\n {children}\n </CardVariant>\n );\n\n case \"collapsible\":\n if (!label) return <SectionVariant>{children}</SectionVariant>;\n return (\n <CollapsibleVariant\n label={label}\n description={description}\n defaultOpen={defaultOpen}\n >\n {children}\n </CollapsibleVariant>\n );\n\n case \"inline\":\n return <div>{children}</div>;\n\n case \"borderless\":\n return <div className=\"space-y-4\">{children}</div>;\n\n case \"section\":\n default:\n return (\n <SectionVariant label={label} description={description}>\n {children}\n </SectionVariant>\n );\n }\n}\n\n// Extracted to its own component so Collapsible state is isolated.\nfunction CollapsibleVariant({\n label,\n description,\n defaultOpen,\n children,\n}: {\n label: string;\n description?: string;\n defaultOpen: boolean;\n children: React.ReactNode;\n}): React.ReactElement {\n const [open, setOpen] = useState(defaultOpen);\n\n return (\n <Collapsible open={open} onOpenChange={setOpen}>\n <CollapsibleTrigger asChild>\n <button\n type=\"button\"\n className=\"flex w-full items-center gap-2 text-sm font-medium hover:text-foreground/80\"\n >\n {open ? (\n <ChevronDown className=\"h-4 w-4\" />\n ) : (\n <ChevronRight className=\"h-4 w-4\" />\n )}\n {label}\n </button>\n </CollapsibleTrigger>\n {description && (\n <p className=\"text-xs text-muted-foreground ml-6\">{description}</p>\n )}\n <CollapsibleContent className=\"mt-2 pl-3 border-l-2 border-muted\">\n {children}\n </CollapsibleContent>\n </Collapsible>\n );\n}\n","/**\n * ArrayWidget -- renders a repeatable list of sub-forms for\n * type: \"array\" properties whose items have type: \"object\".\n *\n * Layout is template-driven. The active templates are resolved from\n * NestedFormContext (injected by JsonSchemaFormRenderer):\n * - ArrayItemTemplate -- how each item is wrapped (default: vertical card)\n * - ArrayHeaderTemplate -- column headers for horizontal mode (default: none)\n *\n * Horizontal layout is activated by x-ui-layout.direction: \"horizontal\" on\n * the array property or UISchema. The HorizontalArrayItemTemplate renders a\n * CSS grid row; ObjectWidget sets displayContents=true on the sub-renderer so\n * field divs become direct grid cells.\n *\n * Each item carries a stable form-internal ID (_fid) assigned via generateId().\n * IDs are used as React keys and for structural diffing at save time. They\n * never leave the renderer boundary.\n */\n\nimport { useCallback, useMemo } from \"react\";\nimport { Plus } from \"lucide-react\";\nimport { Button } from \"@petrarca/sonnet-ui\";\nimport { useNestedFormContext } from \"../hooks/useNestedFormContext\";\nimport type { UILayoutConfig } from \"@petrarca/sonnet-core/schema\";\nimport { applySchemaDefaults } from \"@petrarca/sonnet-core/schema\";\nimport { FORM_ITEM_ID_FIELD, generateId } from \"@petrarca/sonnet-core\";\nimport type { WidgetProps, UISchemaOptions } from \"./types\";\nimport { ObjectWidget } from \"./ObjectWidget\";\nimport { DefaultArrayItemTemplate } from \"../templates/DefaultArrayItemTemplate\";\nimport { DefaultArrayHeaderTemplate } from \"../templates/DefaultArrayHeaderTemplate\";\n\n// ---------------------------------------------------------------------------\n// Pure helpers\n// ---------------------------------------------------------------------------\n\nfunction countFields(itemSchema: WidgetProps[\"propertySchema\"]): number {\n return Object.keys(itemSchema.properties ?? {}).length;\n}\n\nfunction allItemsComplete(\n items: Record<string, unknown>[],\n requiredFields: string[],\n): boolean {\n if (requiredFields.length === 0) return true;\n return items.every((item) =>\n requiredFields.every((field) => {\n const v = item[field];\n return v !== undefined && v !== null && v !== \"\";\n }),\n );\n}\n\n/** Ensure every item has a stable _fid. */\nfunction ensureItemIds(value: unknown): Record<string, unknown>[] {\n return (Array.isArray(value) ? value : []).map((item) =>\n item[FORM_ITEM_ID_FIELD]\n ? item\n : { ...item, [FORM_ITEM_ID_FIELD]: generateId() },\n );\n}\n\n/** Strip the _fid from an item for passing to sub-renderer. */\nfunction stripItemId(item: Record<string, unknown>): Record<string, unknown> {\n return Object.fromEntries(\n Object.entries(item).filter(([k]) => k !== FORM_ITEM_ID_FIELD),\n );\n}\n\n/** Resolve layout config from UISchema and property schema. */\nfunction resolveLayout(\n uiSchema: WidgetProps[\"uiSchema\"],\n propertySchema: WidgetProps[\"propertySchema\"],\n): UILayoutConfig {\n const schemaLayout = propertySchema[\"x-ui-layout\"];\n const uiLayout = uiSchema?.[\"x-ui-layout\"];\n return { ...schemaLayout, ...uiLayout };\n}\n\n/** Build global options for sub-form (compact / label suppression). */\nfunction buildSubGlobalOptions(\n layout: UILayoutConfig,\n isHorizontal: boolean,\n): Record<string, unknown> | undefined {\n const compactOptions = layout.compact ? { compact: true } : undefined;\n const labelsOption =\n layout.labels !== undefined\n ? layout.labels\n : isHorizontal\n ? false\n : undefined;\n if (!compactOptions && labelsOption !== false) return undefined;\n return {\n ...(compactOptions ?? {}),\n ...(labelsOption === false ? { label: false } : {}),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Sub-components\n// ---------------------------------------------------------------------------\n\ninterface ArrayHeaderProps {\n label: string | undefined;\n description: string | undefined;\n}\n\nfunction ArrayHeader({ label, description }: ArrayHeaderProps) {\n if (!label) return null;\n return (\n <div>\n <h4 className=\"text-sm font-medium\">{label}</h4>\n {description && (\n <p className=\"text-xs text-muted-foreground\">{description}</p>\n )}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Hooks\n// ---------------------------------------------------------------------------\n\nfunction useArrayHandlers(\n items: Record<string, unknown>[],\n onChange: (v: unknown) => void,\n propertySchema: WidgetProps[\"propertySchema\"],\n) {\n const handleItemChange = useCallback(\n (index: number, data: Record<string, unknown>) => {\n const next = [...items];\n next[index] = {\n ...data,\n [FORM_ITEM_ID_FIELD]: items[index][FORM_ITEM_ID_FIELD],\n };\n onChange(next);\n },\n [items, onChange],\n );\n\n const handleAdd = useCallback(() => {\n const base = propertySchema.items\n ? applySchemaDefaults({}, propertySchema.items)\n : {};\n onChange([...items, { ...base, [FORM_ITEM_ID_FIELD]: generateId() }]);\n }, [items, onChange, propertySchema.items]);\n\n const handleRemove = useCallback(\n (index: number) => {\n onChange(items.filter((_, i) => i !== index));\n },\n [items, onChange],\n );\n\n const handleMove = useCallback(\n (from: number, to: number) => {\n const next = [...items];\n const [movedItem] = next.splice(from, 1);\n next.splice(to, 0, movedItem);\n onChange(next);\n },\n [items, onChange],\n );\n\n return { handleItemChange, handleAdd, handleRemove, handleMove };\n}\n\n// ---------------------------------------------------------------------------\n// ArrayWidget\n// ---------------------------------------------------------------------------\n\nexport function ArrayWidget({\n propertySchema,\n value,\n onChange,\n registry,\n uiSchema,\n disabled,\n readonly,\n label,\n description,\n options,\n schema,\n name,\n}: WidgetProps): React.ReactElement {\n const { templates } = useNestedFormContext();\n\n const items = useMemo(() => ensureItemIds(value), [value]);\n const { handleItemChange, handleAdd, handleRemove, handleMove } =\n useArrayHandlers(items, onChange, propertySchema);\n\n const itemSchema = propertySchema.items;\n if (!itemSchema?.properties) {\n return (\n <p className=\"text-sm text-destructive\">\n ArrayWidget requires items with type &quot;object&quot; and properties.\n </p>\n );\n }\n\n const layout = resolveLayout(uiSchema, propertySchema);\n const isHorizontal = layout.direction === \"horizontal\";\n const subGlobalOptions = buildSubGlobalOptions(layout, isHorizontal);\n\n return (\n <ArrayWidgetInner\n items={items}\n propertySchema={propertySchema}\n itemSchema={itemSchema}\n schema={schema}\n name={name ?? \"\"}\n registry={registry}\n uiSchema={uiSchema}\n disabled={disabled}\n readonly={readonly}\n label={label}\n description={description}\n options={options}\n layout={layout}\n isHorizontal={isHorizontal}\n subGlobalOptions={subGlobalOptions}\n templates={templates}\n onItemChange={handleItemChange}\n onAdd={handleAdd}\n onRemove={handleRemove}\n onMove={handleMove}\n />\n );\n}\n\n// ---------------------------------------------------------------------------\n// Inner renderer (split to keep each function below complexity threshold)\n// ---------------------------------------------------------------------------\n\ninterface ArrayWidgetInnerProps {\n items: Record<string, unknown>[];\n propertySchema: WidgetProps[\"propertySchema\"];\n itemSchema: WidgetProps[\"propertySchema\"];\n schema: WidgetProps[\"schema\"];\n name: string;\n registry: WidgetProps[\"registry\"];\n uiSchema: WidgetProps[\"uiSchema\"];\n disabled?: boolean;\n readonly?: boolean;\n label?: string;\n description?: string;\n options?: UISchemaOptions;\n layout: UILayoutConfig;\n isHorizontal: boolean;\n subGlobalOptions: Record<string, unknown> | undefined;\n templates: ReturnType<typeof useNestedFormContext>[\"templates\"];\n onItemChange: (index: number, data: Record<string, unknown>) => void;\n onAdd: () => void;\n onRemove: (index: number) => void;\n onMove: (from: number, to: number) => void;\n}\n\n/** Resolve array schema constraints. */\nfunction resolveConstraints(\n arraySchema: WidgetProps[\"propertySchema\"],\n itemSchema: WidgetProps[\"propertySchema\"],\n readonly: boolean | undefined,\n disabled: boolean | undefined,\n itemCount: number,\n) {\n const minItems = arraySchema.minItems ?? 0;\n const maxItems = arraySchema.maxItems ?? Infinity;\n const requiredFields = itemSchema.required ?? [];\n const isEditable = !readonly && !disabled;\n return {\n canRemove: isEditable && itemCount > minItems,\n canAddBase: isEditable && itemCount < maxItems,\n requiredFields,\n };\n}\n\n/** Resolve display options from widget options. */\nfunction resolveDisplayOptions(\n options: UISchemaOptions | undefined,\n itemCount: number,\n) {\n return {\n addLabel: (options?.addLabel as string) ?? \"Add item\",\n itemTitle: options?.itemTitle as string | undefined,\n orderable: !!options?.orderable && itemCount > 1,\n emptyMessage: options?.emptyMessage as string | undefined,\n };\n}\n\n/** Resolve the active templates from context with defaults. */\nfunction resolveTemplates(\n templates: ReturnType<typeof useNestedFormContext>[\"templates\"],\n isHorizontal: boolean,\n) {\n const ItemTemplate = templates.ArrayItemTemplate ?? DefaultArrayItemTemplate;\n const HorizontalItemTemplate =\n templates.HorizontalArrayItemTemplate ?? undefined;\n const HeaderTemplate =\n templates.ArrayHeaderTemplate ?? DefaultArrayHeaderTemplate;\n const ActiveItemTemplate =\n isHorizontal && HorizontalItemTemplate\n ? HorizontalItemTemplate\n : ItemTemplate;\n return { ActiveItemTemplate, HeaderTemplate };\n}\n\n/** Build ObjectWidget options for a sub-item. */\nfunction buildItemOptions(\n isHorizontal: boolean,\n subGlobalOptions: Record<string, unknown> | undefined,\n): UISchemaOptions {\n return {\n variant: \"borderless\",\n displayContents: isHorizontal,\n ...(subGlobalOptions ? { globalOptions: subGlobalOptions } : {}),\n };\n}\n\n/** Resolve the label for an array item. */\nfunction resolveItemLabel(\n itemTitle: string | undefined,\n index: number,\n): string {\n return itemTitle ? itemTitle.replace(\"{index}\", String(index + 1)) : \"\";\n}\n\nfunction ArrayWidgetInner({\n items,\n propertySchema,\n itemSchema,\n schema,\n name,\n registry,\n uiSchema,\n disabled,\n readonly,\n label,\n description,\n options,\n layout,\n isHorizontal,\n subGlobalOptions,\n templates,\n onItemChange,\n onAdd,\n onRemove,\n onMove,\n}: ArrayWidgetInnerProps) {\n const constraints = resolveConstraints(\n propertySchema,\n itemSchema,\n readonly,\n disabled,\n items.length,\n );\n const display = resolveDisplayOptions(options, items.length);\n const canAdd =\n constraints.canAddBase &&\n allItemsComplete(items, constraints.requiredFields);\n const { ActiveItemTemplate, HeaderTemplate } = resolveTemplates(\n templates,\n isHorizontal,\n );\n const fieldCount = countFields(itemSchema);\n const itemOptions = buildItemOptions(isHorizontal, subGlobalOptions);\n\n return (\n <div className={isHorizontal ? \"space-y-1\" : \"space-y-3\"}>\n <ArrayHeader label={label} description={description} />\n\n {items.length === 0 && display.emptyMessage && (\n <p className=\"text-sm text-muted-foreground italic\">\n {display.emptyMessage}\n </p>\n )}\n\n {items.length > 0 && (\n <HeaderTemplate\n itemSchema={itemSchema}\n layout={layout}\n canRemove={constraints.canRemove}\n orderable={display.orderable}\n fieldCount={fieldCount}\n />\n )}\n\n {items.map((item, index) => (\n <ActiveItemTemplate\n key={item[FORM_ITEM_ID_FIELD] as string}\n index={index}\n total={items.length}\n canRemove={constraints.canRemove}\n orderable={display.orderable}\n disabled={disabled}\n layout={layout}\n fieldCount={fieldCount}\n onRemove={() => onRemove(index)}\n onMoveUp={index > 0 ? () => onMove(index, index - 1) : undefined}\n onMoveDown={\n index < items.length - 1\n ? () => onMove(index, index + 1)\n : undefined\n }\n >\n <ObjectWidget\n id={`field-${name}-${index}`}\n name={`${name}[${index}]`}\n schema={schema}\n propertySchema={itemSchema}\n uiSchema={uiSchema}\n registry={registry}\n value={stripItemId(item)}\n onChange={(data: unknown) =>\n onItemChange(index, data as Record<string, unknown>)\n }\n label={resolveItemLabel(display.itemTitle, index)}\n description={undefined}\n disabled={disabled}\n readonly={readonly}\n options={itemOptions}\n />\n </ActiveItemTemplate>\n ))}\n\n {canAdd && (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={onAdd}\n disabled={disabled}\n className=\"gap-1.5\"\n >\n <Plus className=\"h-3.5 w-3.5\" />\n {display.addLabel}\n </Button>\n )}\n </div>\n );\n}\n","/**\n * DefaultArrayItemTemplate -- vertical card layout for array items.\n *\n * Renders the item content with optional remove, move-up, and move-down\n * controls in a column on the right. This is the default (vertical) layout;\n * HorizontalArrayItemTemplate handles the grid-row case.\n */\n\nimport { Trash2, ChevronUp, ChevronDown } from \"lucide-react\";\nimport { Button } from \"@petrarca/sonnet-ui\";\nimport type { ArrayItemTemplateProps } from \"../widgets/types\";\n\nexport function DefaultArrayItemTemplate({\n children,\n index,\n total,\n canRemove,\n orderable,\n disabled,\n onRemove,\n onMoveUp,\n onMoveDown,\n}: ArrayItemTemplateProps): React.ReactElement {\n const showControls = canRemove || orderable;\n\n return (\n <div className=\"relative flex gap-2 rounded-md border border-border/50 bg-muted/20 p-3\">\n <div className=\"flex-1 min-w-0\">{children}</div>\n {showControls && (\n <div className=\"flex flex-col gap-1 pt-0.5\">\n {orderable && index > 0 && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"compact\"\n disabled={disabled}\n onClick={onMoveUp}\n title=\"Move up\"\n >\n <ChevronUp className=\"h-3.5 w-3.5\" />\n </Button>\n )}\n {orderable && index < total - 1 && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"compact\"\n disabled={disabled}\n onClick={onMoveDown}\n title=\"Move down\"\n >\n <ChevronDown className=\"h-3.5 w-3.5\" />\n </Button>\n )}\n {canRemove && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"compact\"\n disabled={disabled}\n onClick={onRemove}\n title=\"Remove item\"\n className=\"text-muted-foreground hover:text-destructive\"\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n </Button>\n )}\n </div>\n )}\n </div>\n );\n}\n","/**\n * Utility for building CSS grid-template-columns strings for array item rows.\n */\n\nimport type { UILayoutConfig } from \"@petrarca/sonnet-core/schema\";\n\n/** Build the CSS grid-template-columns string for a horizontal item row. */\nexport function buildGridTemplate(\n layout: UILayoutConfig,\n canRemove: boolean,\n fieldCount: number,\n orderable: boolean = false,\n): string {\n const base = layout.columns ?? `repeat(${fieldCount}, 1fr)`;\n const withOrder = orderable ? `${base} 32px` : base;\n return canRemove ? `${withOrder} 32px` : withOrder;\n}\n","/**\n * DefaultArrayHeaderTemplate -- column header row for horizontal array layout.\n *\n * Rendered once above all items by ArrayWidget when direction is \"horizontal\".\n * Returns null in vertical mode (no headers needed).\n */\n\nimport type { ArrayHeaderTemplateProps } from \"../widgets/types\";\nimport { buildGridTemplate } from \"./gridUtils\";\n\nexport function DefaultArrayHeaderTemplate({\n itemSchema,\n layout,\n canRemove,\n orderable,\n fieldCount,\n}: ArrayHeaderTemplateProps): React.ReactElement | null {\n if (layout.direction !== \"horizontal\") return null;\n\n const template = buildGridTemplate(layout, canRemove, fieldCount, orderable);\n const gap = layout.gap ?? 8;\n\n const properties = itemSchema.properties ?? {};\n const order = itemSchema[\"x-ui-order\"];\n const fieldNames = order\n ? order.filter((k) => k in properties)\n : Object.keys(properties);\n\n return (\n <div\n style={{\n display: \"grid\",\n gridTemplateColumns: template,\n gap: `${gap}px`,\n }}\n >\n {fieldNames.map((name) => (\n <span key={name} className=\"text-xs font-medium text-muted-foreground\">\n {properties[name]?.title ?? name}\n </span>\n ))}\n {orderable && <span />}\n {canRemove && <span />}\n </div>\n );\n}\n","/**\n * QuantityWidget - JSON-Schema-aware widget for compound value + unit input.\n *\n * Reads unit options from x-ui-options.units (static array) and delegates\n * rendering to FormQuantityInput. Registered as x-ui-widget: \"quantity\".\n *\n * x-ui-options:\n * units - Array of { value, label, min?, max?, position? } unit options\n * unitPosition - Default position for all units: \"prefix\" | \"suffix\"\n * precision - Number of decimal places to format on blur\n * step - Arrow-key increment\n *\n * Schema-level min/max come from propertySchema.minimum / propertySchema.maximum.\n *\n * Form value shape: { value: number | undefined, unit: string }\n */\n\nimport { useCallback, useRef } from \"react\";\nimport {\n FormQuantityInput,\n type QuantityValue,\n type UnitOption,\n type UnitPosition,\n} from \"../FormQuantityInput\";\nimport { WidgetProps, firstError } from \"./types\";\n\n/** Runtime shape guard for a single unit option from x-ui-options. */\nfunction isUnitOption(u: unknown): u is UnitOption {\n return (\n typeof u === \"object\" &&\n u !== null &&\n typeof (u as UnitOption).value === \"string\" &&\n typeof (u as UnitOption).label === \"string\"\n );\n}\n\nexport function QuantityWidget({\n id,\n name,\n value,\n onChange,\n onBlur,\n propertySchema,\n required,\n disabled,\n readonly,\n rawErrors,\n label,\n description,\n placeholder,\n autofocus,\n options = {},\n}: WidgetProps) {\n const error = firstError(rawErrors);\n\n // M5: Validate each entry's shape at runtime rather than casting blindly.\n const units: UnitOption[] = Array.isArray(options.units)\n ? (options.units as unknown[]).filter(isUnitOption)\n : [];\n\n const precision =\n typeof options.precision === \"number\" ? options.precision : undefined;\n const step = typeof options.step === \"number\" ? options.step : undefined;\n const unitPositionOpt: UnitPosition | undefined =\n options.unitPosition === \"prefix\" || options.unitPosition === \"suffix\"\n ? options.unitPosition\n : undefined;\n\n // Coerce incoming value to QuantityValue (unknown -> typed).\n const quantityValue: QuantityValue | undefined =\n value != null && typeof value === \"object\" && !Array.isArray(value)\n ? (value as QuantityValue)\n : undefined;\n\n // L5: We store the current value in a ref so the onBlur handler can pass it\n // to the form engine without capturing a stale snapshot in a useCallback\n // closure. Adding `value` to the useCallback dep array would cause the\n // handler to be recreated on every value change, which in turn makes\n // FormQuantityInput recreate its own blur handler -- unnecessary churn.\n const valueRef = useRef(value);\n valueRef.current = value;\n\n const handleBlur = useCallback(() => {\n onBlur?.(id, valueRef.current);\n }, [id, onBlur]);\n\n // M4: onChange is passed directly -- no wrapper needed. FormQuantityInput\n // calls onChange with a QuantityValue, which satisfies (value: unknown) => void.\n return (\n <FormQuantityInput\n id={id}\n name={name}\n value={quantityValue}\n onChange={onChange as (v: QuantityValue) => void}\n onBlur={handleBlur}\n units={units}\n unitPosition={unitPositionOpt}\n precision={precision}\n step={step}\n min={propertySchema.minimum}\n max={propertySchema.maximum}\n label={label}\n description={description}\n error={error}\n placeholder={placeholder}\n required={required}\n disabled={disabled}\n readOnly={readonly}\n autoFocus={autofocus}\n />\n );\n}\n","/**\n * Widget Resolution Algorithm\n *\n * Determines which widget to use for a given field based on:\n * 0. Schema x-ui-widget and x-ui-options (merged with uiSchema if present)\n * 1. UISchema x-ui-widget (highest priority - overrides x-ui-widget)\n * 2. Schema x-ui-widget (for widget name)\n * 3. Schema enum (uses SelectWidget)\n * 4. Schema format (email, date, color, etc.)\n * 5. Schema type (string, number, boolean, etc.)\n * 6. Fallback to TextWidget\n *\n * x-ui-widget is a simple string: 'textarea', 'select', etc.\n * x-ui-options is an object with configuration: { rows: 5, etc. }\n */\n\nimport { JsonSchemaProperty } from \"@petrarca/sonnet-core/schema\";\nimport {\n isNullableBoolean,\n extractEnumValues,\n getFieldType,\n} from \"@petrarca/sonnet-core/schema\";\nimport { Widget, WidgetRegistry, UISchema, WidgetMap } from \"./types\";\n\n/**\n * Default widget mapping: schema type → format/variant → widget name\n *\n * This defines which widget to use for each combination of schema type and format.\n * Follows the pattern established by react-jsonschema-form.\n *\n * Currently implemented widgets:\n * - TextInputWidget: Basic text input (email, url formats supported)\n * - TextareaWidget: Multi-line text input\n * - NumberWidget: Number and integer input\n * - CheckboxWidget: Boolean checkbox\n * - SelectWidget: Dropdown for enum values\n */\nexport const DEFAULT_WIDGET_MAP: WidgetMap = {\n string: {\n default: \"TextInputWidget\",\n textarea: \"TextareaWidget\",\n email: \"TextInputWidget\", // Uses email input type\n uri: \"TextInputWidget\", // Uses url input type\n url: \"TextInputWidget\", // Uses url input type\n },\n number: {\n default: \"NumberWidget\",\n },\n integer: {\n default: \"NumberWidget\", // NumberWidget handles both number and integer\n },\n boolean: {\n default: \"CheckboxWidget\",\n },\n};\n\n/**\n * Resolve a widget name to a widget component using unified resolution logic\n *\n * This function handles both exact widget names and lowercase format names consistently.\n * Used by both schema-embedded x-ui-widget and explicit uiSchema resolution.\n *\n * @param widgetName - The widget name to resolve (e.g., 'TextareaWidget' or 'textarea')\n * @param propertySchema - The JSON schema for context (needed for type-based resolution)\n * @param registry - Widget registry to look up widgets\n * @returns The resolved widget component or null if not found\n */\nfunction resolveWidgetByName(\n widgetName: string,\n propertySchema: JsonSchemaProperty,\n registry: WidgetRegistry,\n): Widget | null {\n // Strategy 1: Direct registry lookup (for exact widget names like 'TextareaWidget')\n if (registry[widgetName]) {\n return registry[widgetName];\n }\n\n // Strategy 2: Map lowercase format names to widget names\n // This allows using 'textarea' instead of 'TextareaWidget' for consistency\n const type = getFieldType(propertySchema);\n const resolvedWidgetName =\n DEFAULT_WIDGET_MAP[type]?.[widgetName.toLowerCase()];\n if (resolvedWidgetName && registry[resolvedWidgetName]) {\n return registry[resolvedWidgetName];\n }\n\n return null;\n}\n\n/**\n * Merge x-ui-* extensions from a property schema with an explicit uiSchema.\n *\n * The explicit uiSchema has higher priority and overrides schema-embedded hints.\n * Returns undefined when neither source provides any values.\n */\nfunction mergeUiSchema(\n propertySchema: JsonSchemaProperty,\n uiSchema: UISchema | undefined,\n): UISchema | undefined {\n const xWidgetName = propertySchema[\"x-ui-widget\"];\n const xWidgetOptions = propertySchema[\"x-ui-options\"];\n\n if (!xWidgetName && !xWidgetOptions) return uiSchema;\n\n if (!uiSchema) {\n return {\n ...(xWidgetName && { \"x-ui-widget\": xWidgetName }),\n ...(xWidgetOptions && { \"x-ui-options\": xWidgetOptions }),\n };\n }\n\n return {\n ...(xWidgetName && { \"x-ui-widget\": xWidgetName }), // lower priority\n ...uiSchema, // higher priority\n \"x-ui-options\": {\n ...(xWidgetOptions || {}), // lower priority\n ...(uiSchema[\"x-ui-options\"] || {}), // higher priority\n },\n };\n}\n\n/**\n * Resolve which widget to use for a field.\n *\n * Resolution order (highest to lowest priority):\n * 1. x-ui-widget (from explicit uiSchema or schema-embedded extension)\n * 2. anyOf boolean+null pattern (tri-state checkbox)\n * 3. enum in schema -- includes nullable anyOf enum pattern (SelectWidget)\n * 4. type + format in schema (string, number, boolean, etc.)\n * 5. Fallback to TextInputWidget\n *\n * @param propertySchema - The JSON schema for this field\n * @param uiSchema - Optional UI schema customization (takes priority over schema hints)\n * @param registry - Widget registry to look up widgets\n * @returns The resolved widget component\n */\n// Step 1: Resolve from explicit x-ui-widget hint.\nfunction resolveFromUiWidget(\n uiWidget: unknown,\n propertySchema: JsonSchemaProperty,\n registry: WidgetRegistry,\n): Widget | null {\n if (typeof uiWidget === \"function\") return uiWidget as Widget;\n if (typeof uiWidget === \"string\")\n return resolveWidgetByName(uiWidget, propertySchema, registry);\n return null;\n}\n\n/** Check if a schema describes an array of objects with properties. */\nfunction isObjectArraySchema(schema: JsonSchemaProperty): boolean {\n return (\n schema.type === \"array\" &&\n schema.items?.type === \"object\" &&\n !!schema.items?.properties\n );\n}\n\n/** Lookup a widget name in the registry, falling back to TextInputWidget. */\nfunction registryLookup(registry: WidgetRegistry, widgetName: string): Widget {\n return registry[widgetName] || registry[\"TextInputWidget\"];\n}\n\n// Step 2-3: Resolve from schema structure (nullable bool, enum, object, array).\nfunction resolveFromSchemaStructure(\n schema: JsonSchemaProperty,\n registry: WidgetRegistry,\n): Widget | null {\n if (isNullableBoolean(schema))\n return registryLookup(registry, \"CheckboxWidget\");\n if (extractEnumValues(schema).length > 0)\n return registryLookup(registry, \"SelectWidget\");\n if (schema.type === \"object\" && schema.properties)\n return registryLookup(registry, \"ObjectWidget\");\n if (isObjectArraySchema(schema))\n return registryLookup(registry, \"ArrayWidget\");\n return null;\n}\n\n// Step 4: Resolve from type + format via the default widget map.\nfunction resolveFromTypeFormat(\n schema: JsonSchemaProperty,\n registry: WidgetRegistry,\n): Widget {\n const type = getFieldType(schema);\n const format = schema.format;\n const widgetName =\n (format && DEFAULT_WIDGET_MAP[type]?.[format]) ||\n DEFAULT_WIDGET_MAP[type]?.default ||\n \"TextInputWidget\";\n return registry[widgetName] || registry[\"TextInputWidget\"];\n}\n\nexport function resolveWidget(\n propertySchema: JsonSchemaProperty,\n uiSchema: UISchema | undefined,\n registry: WidgetRegistry,\n): Widget {\n const effectiveUiSchema = mergeUiSchema(propertySchema, uiSchema);\n const uiWidget = effectiveUiSchema?.[\"x-ui-widget\"];\n if (uiWidget) {\n const resolved = resolveFromUiWidget(uiWidget, propertySchema, registry);\n if (resolved) return resolved;\n }\n return (\n resolveFromSchemaStructure(propertySchema, registry) ??\n resolveFromTypeFormat(propertySchema, registry)\n );\n}\n\n/**\n * Get the default widget name for a schema type\n *\n * Helper function to determine the default widget for a given type\n * without considering format or other factors.\n *\n * @param type - The JSON schema type\n * @returns The default widget name for that type\n *\n * @example\n * ```typescript\n * getDefaultWidgetForType('string'); // 'TextInputWidget'\n * getDefaultWidgetForType('number'); // 'NumberWidget'\n * getDefaultWidgetForType('boolean'); // 'CheckboxWidget'\n * ```\n */\nexport function getDefaultWidgetForType(type: string): string {\n return DEFAULT_WIDGET_MAP[type]?.default || \"TextInputWidget\";\n}\n","/**\n * Form Widgets - Index and Registry\n *\n * Each widget is imported once and re-exported. The same binding is used in\n * DEFAULT_WIDGETS to avoid the double-import anti-pattern.\n */\n\nimport { TextInputWidget } from \"./TextInputWidget\";\nimport { TextareaWidget } from \"./TextareaWidget\";\nimport { NumberWidget } from \"./NumberWidget\";\nimport { CheckboxWidget } from \"./CheckboxWidget\";\nimport { SelectWidget } from \"./SelectWidget\";\nimport { TagsInputWidget } from \"./TagsInputWidget\";\nimport { JsonEditorWidget } from \"./JsonEditorWidget\";\nimport { EntitySelectWidget } from \"./EntitySelectWidget\";\nimport { ObjectWidget } from \"./ObjectWidget\";\nimport { ArrayWidget } from \"./ArrayWidget\";\nimport { QuantityWidget } from \"./QuantityWidget\";\nimport type { WidgetRegistry } from \"./types\";\n\n// Re-export widget components\nexport {\n TextInputWidget,\n TextareaWidget,\n NumberWidget,\n CheckboxWidget,\n SelectWidget,\n TagsInputWidget,\n JsonEditorWidget,\n EntitySelectWidget,\n ObjectWidget,\n ArrayWidget,\n QuantityWidget,\n};\n\n// Export types and helpers\nexport type {\n Widget,\n WidgetProps,\n WidgetRegistry,\n WidgetDescriptor,\n WidgetMap,\n SelectOption,\n UISchema,\n UISchemaOptions,\n} from \"./types\";\nexport { firstError } from \"./types\";\n\n// Export resolver\nexport {\n resolveWidget,\n getDefaultWidgetForType,\n DEFAULT_WIDGET_MAP,\n} from \"./widgetResolver\";\n\n/**\n * DEFAULT_WIDGETS - The default widget registry.\n *\n * Contains all built-in widgets mapped by their names.\n * Use this as the base registry or extend it with custom widgets.\n *\n * @example\n * ```typescript\n * import { DEFAULT_WIDGETS } from './widgets';\n * import MyCustomWidget from './MyCustomWidget';\n *\n * const registry = { ...DEFAULT_WIDGETS, MyCustomWidget };\n * ```\n */\nexport const DEFAULT_WIDGETS: WidgetRegistry = {\n // Canonical PascalCase names\n TextInputWidget,\n TextareaWidget,\n NumberWidget,\n CheckboxWidget,\n SelectWidget,\n TagsInputWidget,\n JsonEditorWidget,\n EntitySelectWidget,\n ObjectWidget,\n ArrayWidget,\n QuantityWidget,\n\n // Lowercase aliases for x-ui-widget convenience\n text: TextInputWidget,\n textarea: TextareaWidget,\n number: NumberWidget,\n checkbox: CheckboxWidget,\n select: SelectWidget,\n tags: TagsInputWidget,\n \"json-editor\": JsonEditorWidget,\n \"entity-select\": EntitySelectWidget,\n object: ObjectWidget,\n array: ArrayWidget,\n quantity: QuantityWidget,\n};\n","/**\n * HorizontalArrayItemTemplate -- CSS grid row layout for array items.\n *\n * Renders each item as a grid row. The sub-form container uses\n * display:contents so its field divs become direct grid cells. The\n * remove button occupies the last column (32px).\n *\n * Activated by x-ui-layout.direction: \"horizontal\" on the array property.\n */\n\nimport { Trash2, ChevronUp, ChevronDown } from \"lucide-react\";\nimport { Button } from \"@petrarca/sonnet-ui\";\nimport type { ArrayItemTemplateProps } from \"../widgets/types\";\nimport { buildGridTemplate } from \"./gridUtils\";\n\nexport function HorizontalArrayItemTemplate({\n children,\n index,\n total,\n canRemove,\n orderable,\n disabled,\n layout,\n fieldCount,\n onRemove,\n onMoveUp,\n onMoveDown,\n}: ArrayItemTemplateProps): React.ReactElement {\n const resolvedLayout = layout;\n const template = buildGridTemplate(\n resolvedLayout,\n canRemove,\n fieldCount,\n orderable,\n );\n const gap = resolvedLayout.gap ?? 8;\n // compact rows center-align (controls are short); full-height rows stretch.\n const alignItems = resolvedLayout.compact ? \"center\" : \"start\";\n\n return (\n <div\n style={{\n display: \"grid\",\n gridTemplateColumns: template,\n gap: `${gap}px`,\n alignItems,\n }}\n >\n {children}\n {orderable && (\n <div className=\"flex flex-col items-center justify-center\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"compact\"\n disabled={disabled || index === 0}\n onClick={onMoveUp}\n title=\"Move up\"\n className=\"h-4 w-8 p-0\"\n >\n <ChevronUp className=\"h-3 w-3\" />\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"compact\"\n disabled={disabled || index >= total - 1}\n onClick={onMoveDown}\n title=\"Move down\"\n className=\"h-4 w-8 p-0\"\n >\n <ChevronDown className=\"h-3 w-3\" />\n </Button>\n </div>\n )}\n {canRemove && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"compact\"\n disabled={disabled}\n onClick={onRemove}\n title=\"Remove item\"\n className=\"text-muted-foreground hover:text-destructive h-8 w-8 p-0\"\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n </Button>\n )}\n </div>\n );\n}\n","/**\n * Default templates for structural layout rendering.\n *\n * These are the pre-built implementations used by ArrayWidget and\n * ObjectWidget when no custom template is injected. Callers override\n * specific templates by passing a partial TemplateRegistry to the\n * `templates` prop on JsonSchemaFormRenderer.\n */\n\nimport type { TemplateRegistry } from \"../widgets/types\";\nimport { DefaultArrayItemTemplate } from \"./DefaultArrayItemTemplate\";\nimport { HorizontalArrayItemTemplate } from \"./HorizontalArrayItemTemplate\";\nimport { DefaultArrayHeaderTemplate } from \"./DefaultArrayHeaderTemplate\";\nimport { DefaultObjectContainerTemplate } from \"./DefaultObjectContainerTemplate\";\n\nexport { DefaultArrayItemTemplate } from \"./DefaultArrayItemTemplate\";\nexport { HorizontalArrayItemTemplate } from \"./HorizontalArrayItemTemplate\";\nexport { DefaultArrayHeaderTemplate } from \"./DefaultArrayHeaderTemplate\";\nexport { DefaultObjectContainerTemplate } from \"./DefaultObjectContainerTemplate\";\n\n/**\n * DEFAULT_TEMPLATES -- the built-in template implementations.\n *\n * Pass a partial override to JsonSchemaFormRenderer's `templates` prop\n * to replace specific templates globally, or use x-ui-options on a\n * schema property for per-field overrides.\n */\nexport const DEFAULT_TEMPLATES: TemplateRegistry = {\n ArrayItemTemplate: DefaultArrayItemTemplate,\n HorizontalArrayItemTemplate: HorizontalArrayItemTemplate,\n ArrayHeaderTemplate: DefaultArrayHeaderTemplate,\n ObjectContainerTemplate: DefaultObjectContainerTemplate,\n};\n","/**\n * FormFieldRenderer - Renders a single form field via the widget system\n *\n * Replaces the `renderField` free function that previously lived in\n * JsonSchemaFormRenderer. Moving it to a proper component ensures the `key`\n * prop is set at the call site (in the parent's `.map()`), not buried inside\n * the function, which is the idiomatic React pattern.\n *\n * @module components/Forms/FormFieldRenderer\n */\n\nimport React from \"react\";\nimport { JsonSchema, JsonSchemaProperty } from \"@petrarca/sonnet-core/schema\";\nimport {\n getFieldTitle,\n getFieldHelpText,\n getFieldPlaceholder,\n} from \"@petrarca/sonnet-core/schema\";\nimport {\n resolveWidget,\n WidgetRegistry,\n UISchema,\n UISchemaOptions,\n} from \"./widgets\";\n\nexport interface FormFieldRendererProps {\n fieldName: string;\n property: JsonSchemaProperty;\n value: unknown;\n onChange: (value: unknown) => void;\n onBlur?: (id: string, value: unknown) => void;\n required: boolean;\n disabled: boolean;\n readOnly: boolean;\n schema: JsonSchema;\n uiSchema?: UISchema;\n registry: WidgetRegistry;\n globalOptions?: UISchemaOptions;\n formData?: Record<string, unknown>;\n}\n\n/** Merge options: field uiSchema > property x-ui-options > global. */\nfunction mergeFieldOptions(\n globalOptions: UISchemaOptions,\n property: JsonSchemaProperty,\n uiSchema: UISchema | undefined,\n): UISchemaOptions {\n const xWidgetOptions = property[\"x-ui-options\"] || {};\n const fieldOptions = uiSchema?.[\"x-ui-options\"] || {};\n return { ...globalOptions, ...xWidgetOptions, ...fieldOptions };\n}\n\n/** Resolve effective label: global label=false hides it; uiSchema x-ui-title overrides. */\nfunction resolveEffectiveLabel(\n label: string,\n uiTitle: string | boolean | undefined,\n globalLabelOption: string | false | undefined,\n): string {\n if (globalLabelOption === false) return \"\";\n if (typeof uiTitle === \"string\") return uiTitle;\n if (uiTitle === false) return \"\";\n return label;\n}\n\n/** Resolve cascading disabled/readonly flags. */\nfunction resolveFieldFlags(\n fieldOptions: UISchemaOptions,\n globalOptions: UISchemaOptions,\n disabled: boolean,\n readOnly: boolean,\n) {\n return {\n disabled: fieldOptions.disabled ?? globalOptions.disabled ?? disabled,\n readOnly: fieldOptions.readonly ?? globalOptions.readonly ?? readOnly,\n };\n}\n\nexport function FormFieldRenderer({\n fieldName,\n property,\n value,\n onChange,\n onBlur,\n required,\n disabled,\n readOnly,\n schema,\n uiSchema,\n registry,\n globalOptions = {},\n formData,\n}: FormFieldRendererProps): React.ReactElement | null {\n const label = getFieldTitle(fieldName, property);\n const description =\n uiSchema?.[\"x-ui-description\"] ?? getFieldHelpText(property);\n const placeholder =\n uiSchema?.[\"x-ui-placeholder\"] ?? getFieldPlaceholder(property);\n\n const Widget = resolveWidget(property, uiSchema, registry);\n const mergedOptions = mergeFieldOptions(globalOptions, property, uiSchema);\n\n if (mergedOptions.hidden) return null;\n\n const fieldOptions = uiSchema?.[\"x-ui-options\"] || {};\n const flags = resolveFieldFlags(\n fieldOptions,\n globalOptions,\n disabled,\n readOnly,\n );\n const effectiveLabel = resolveEffectiveLabel(\n label,\n uiSchema?.[\"x-ui-title\"],\n globalOptions.label,\n );\n\n return (\n <Widget\n id={`field-${fieldName}`}\n name={fieldName}\n value={value}\n onChange={onChange}\n onBlur={onBlur}\n schema={schema}\n propertySchema={property}\n uiSchema={uiSchema}\n registry={registry}\n label={effectiveLabel}\n description={description}\n placeholder={placeholder}\n required={required}\n disabled={flags.disabled}\n readonly={flags.readOnly}\n options={mergedOptions}\n formData={formData}\n />\n );\n}\n","/**\n * useFormEngine - Core form state, schema resolution, and update-mode logic\n *\n * Owns:\n * - formData state (internal working copy)\n * - resolvedSchema / orderedProperties (conditional schema + field ordering)\n * - originalData baseline for dirty-tracking\n * - nonSchemaData (fields not in the schema, preserved on save)\n * - pendingChanges (deferred-state-update buffer)\n * - isValid / validation errors\n * - handleFieldChange, handleFieldBlur, handleSave, handleCancel\n *\n * Supports all three update modes:\n * 1. Real-time — onChange on every keystroke\n * 2. Deferred — onChange on blur for text fields (deferChanges)\n * 3. Buffered — Save/Cancel flow (showActions + onUpdate)\n *\n * @module components/Forms/hooks/useFormEngine\n */\n\nimport { useState, useEffect, useMemo, useCallback, useRef } from \"react\";\nimport { isEqual } from \"@petrarca/sonnet-core\";\nimport { JsonSchema, JsonSchemaProperty } from \"@petrarca/sonnet-core/schema\";\nimport {\n getSchemaProperties,\n getFieldDefault,\n applySchemaDefaults,\n resolveSchema,\n resolveRefs,\n validateFormData,\n diffFormData,\n} from \"@petrarca/sonnet-core/schema\";\nimport type { FormDiff } from \"@petrarca/sonnet-core/schema\";\nimport { UISchema } from \"../widgets\";\nimport { orderProperties } from \"./orderProperties\";\n\n/**\n * Returns true for field types that should always trigger immediate updates\n * (checkboxes, enum-based selects), regardless of deferral settings.\n */\nfunction isImmediateField(\n fieldName: string,\n properties: Record<string, JsonSchemaProperty>,\n): boolean {\n const property = properties[fieldName];\n return property?.type === \"boolean\" || property?.enum !== undefined;\n}\n\n/**\n * Compute updated originalData baseline when external `data` expands.\n *\n * Returns a result object when an update is needed, null otherwise.\n * `shouldMarkInitialized` is true on first initialization, false on subsequent expansion.\n */\nfunction computeBaselineUpdate(\n newData: Record<string, any>,\n originalData: Record<string, any>,\n initialized: boolean,\n schemaPropertyNames: string[],\n): {\n shouldMarkInitialized: boolean;\n cleanedData: Record<string, any>;\n nonSchema: Record<string, any>;\n} | null {\n const newCount = Object.keys(newData).length;\n const origCount = Object.keys(originalData).length;\n\n if (!initialized && newCount > 0) {\n const cleanedData = Object.fromEntries(\n Object.entries(newData).filter(([k]) => schemaPropertyNames.includes(k)),\n );\n const nonSchema = Object.fromEntries(\n Object.entries(newData).filter(([k]) => !schemaPropertyNames.includes(k)),\n );\n return { shouldMarkInitialized: true, cleanedData, nonSchema };\n }\n\n if (initialized && newCount > origCount) {\n const cleanedData = Object.fromEntries(\n Object.entries(newData).filter(([k]) => schemaPropertyNames.includes(k)),\n );\n const nonSchema = Object.fromEntries(\n Object.entries(newData).filter(([k]) => !schemaPropertyNames.includes(k)),\n );\n return { shouldMarkInitialized: false, cleanedData, nonSchema };\n }\n\n return null;\n}\n\nexport interface UseFormEngineOptions {\n schema: JsonSchema;\n data: Record<string, any>;\n uiSchema: { [fieldName: string]: UISchema };\n onChange?: (data: Record<string, any>) => void;\n onBlur?: (fieldName: string, data: Record<string, any>) => void;\n onValidationChange?: (errors: string[], isValid: boolean) => void;\n onUpdate?: (\n data: Record<string, any>,\n changedFields: Record<string, any>,\n diff: FormDiff,\n ) => void;\n onCancel?: () => void;\n readOnly?: boolean;\n showActions?: boolean;\n deferChanges?: boolean;\n deferStateUpdates?: boolean;\n}\n\nexport interface UseFormEngineResult {\n /** The current working form data (for controlled field values) */\n formData: Record<string, any>;\n /**\n * Display data — formData merged with pending deferred changes.\n * Always use this for rendering field values.\n */\n displayData: Record<string, any>;\n /** Schema resolved against the current formData (conditional fields evaluated) */\n resolvedSchema: JsonSchema;\n /** Properties ordered by x-ui-order, ready for rendering */\n orderedProperties: [string, JsonSchemaProperty][];\n hasChanges: boolean;\n isValid: boolean;\n handleFieldChange: (fieldName: string, value: any) => void;\n handleFieldBlur: (fieldName: string) => void;\n handleSave: () => void;\n handleCancel: () => void;\n}\n\nexport function useFormEngine({\n schema,\n data,\n uiSchema,\n onChange,\n onBlur,\n onValidationChange,\n onUpdate,\n onCancel,\n readOnly = false,\n showActions = false,\n deferChanges = false,\n deferStateUpdates = false,\n}: UseFormEngineOptions): UseFormEngineResult {\n // Resolve $ref pointers before anything else. This is a pure transformation\n // that only depends on the schema object, not on form data.\n const refResolvedSchema = useMemo(() => resolveRefs(schema), [schema]);\n\n const [originalData, setOriginalData] = useState<Record<string, any>>(() =>\n applySchemaDefaults(data, refResolvedSchema),\n );\n const [originalDataInitialized, setOriginalDataInitialized] = useState(false);\n\n const [nonSchemaData, setNonSchemaData] = useState<Record<string, any>>(\n () => {\n const props = getSchemaProperties(refResolvedSchema);\n const names = Object.keys(props);\n return Object.fromEntries(\n Object.entries(data).filter(([k]) => !names.includes(k)),\n );\n },\n );\n\n const [formData, setFormData] = useState<Record<string, any>>(() =>\n applySchemaDefaults(data, refResolvedSchema),\n );\n\n const [pendingChanges, setPendingChanges] = useState<Record<string, any>>({});\n\n // Schema resolution depends on live formData so conditional fields\n // (if-then-else, allOf) are re-evaluated on every change.\n const resolvedSchema = useMemo(\n () => resolveSchema(refResolvedSchema, formData),\n [refResolvedSchema, formData],\n );\n\n const orderedProperties = useMemo(() => {\n const properties = getSchemaProperties(resolvedSchema);\n const rawOrder = uiSchema[\"x-ui-order\"] ?? resolvedSchema[\"x-ui-order\"];\n const orderArray = Array.isArray(rawOrder)\n ? (rawOrder as string[])\n : undefined;\n return orderProperties(properties, orderArray);\n }, [resolvedSchema, uiSchema]);\n\n const [isValid, setIsValid] = useState<boolean>(() => {\n const initResolved = resolveSchema(refResolvedSchema, data);\n const validation = validateFormData(initResolved, data);\n return validation.isValid;\n });\n\n const [initialDefaultsSent, setInitialDefaultsSent] = useState(false);\n\n const properties = getSchemaProperties(resolvedSchema);\n\n // On mount: if schema defaults were applied that the caller didn't supply,\n // push the initialized data up via onChange so the parent stays in sync.\n useEffect(() => {\n if (!initialDefaultsSent) {\n const hasDefaults = Object.entries(properties).some(\n ([fieldName, property]) =>\n data[fieldName] === undefined &&\n getFieldDefault(property) !== undefined,\n );\n\n if (hasDefaults && onChange) {\n onChange(formData);\n }\n setInitialDefaultsSent(true);\n }\n }, [initialDefaultsSent, properties, data, formData, onChange]);\n\n // Remove formData keys that are no longer present in the resolved schema.\n // This keeps internal state clean when a conditional branch hides a field.\n useEffect(() => {\n const currentPropertyNames = Object.keys(properties);\n const keysToRemove = Object.keys(formData).filter(\n (k) => !currentPropertyNames.includes(k),\n );\n\n if (keysToRemove.length > 0) {\n const cleanedData = { ...formData };\n keysToRemove.forEach((k) => {\n delete cleanedData[k];\n });\n setFormData(cleanedData);\n if (onChange) onChange(cleanedData);\n }\n }, [properties, formData, onChange]);\n\n // Sync formData when the external data prop changes. Uses a ref to track\n // the previous value so we can avoid triggering on every render while\n // keeping the dependency array honest.\n const prevDataRef = useRef(data);\n useEffect(() => {\n if (isEqual(prevDataRef.current, data)) return;\n prevDataRef.current = data;\n\n const newData = applySchemaDefaults(data, refResolvedSchema);\n setFormData(newData);\n\n const schemaPropertyNames = Object.keys(properties);\n const result = computeBaselineUpdate(\n newData,\n originalData,\n originalDataInitialized,\n schemaPropertyNames,\n );\n\n if (result) {\n setOriginalData(result.cleanedData);\n setNonSchemaData(result.nonSchema);\n if (result.shouldMarkInitialized) {\n setOriginalDataInitialized(true);\n }\n }\n\n const validation = validateFormData(resolvedSchema, newData);\n setIsValid(validation.isValid);\n }, [\n data,\n refResolvedSchema,\n resolvedSchema,\n properties,\n originalData,\n originalDataInitialized,\n ]);\n\n const hasChanges = useMemo(\n () => !isEqual(formData, originalData),\n [formData, originalData],\n );\n\n // In deferStateUpdates mode, pending (not-yet-blurred) text field changes\n // are held separately and merged here for display only.\n const displayData = useMemo(() => {\n if (deferStateUpdates && Object.keys(pendingChanges).length > 0) {\n return { ...formData, ...pendingChanges };\n }\n return formData;\n }, [formData, pendingChanges, deferStateUpdates]);\n\n const handleFieldChange = useCallback(\n (fieldName: string, value: any) => {\n if (readOnly) return;\n\n const immediate = isImmediateField(fieldName, properties);\n\n if (showActions && deferStateUpdates && !immediate) {\n setPendingChanges((prev) => ({ ...prev, [fieldName]: value }));\n return;\n }\n\n const newData = { ...formData, [fieldName]: value };\n setFormData(newData);\n\n if (!showActions) {\n const shouldCallOnChange = !deferChanges || immediate;\n if (shouldCallOnChange && onChange) onChange(newData);\n }\n\n const validation = validateFormData(resolvedSchema, newData);\n setIsValid(validation.isValid);\n if (onValidationChange) {\n onValidationChange(validation.errors, validation.isValid);\n }\n },\n [\n readOnly,\n formData,\n deferChanges,\n deferStateUpdates,\n showActions,\n onChange,\n resolvedSchema,\n onValidationChange,\n properties,\n ],\n );\n\n // Flush deferred pending changes for a field into formData on blur.\n const flushPendingField = useCallback(\n (fieldName: string) => {\n if (!showActions || !deferStateUpdates) return;\n if (pendingChanges[fieldName] === undefined) return;\n\n const newData = { ...formData, ...pendingChanges };\n setFormData(newData);\n setPendingChanges((prev) => {\n const updated = { ...prev };\n delete updated[fieldName];\n return updated;\n });\n\n const validation = validateFormData(resolvedSchema, newData);\n setIsValid(validation.isValid);\n if (onValidationChange) {\n onValidationChange(validation.errors, validation.isValid);\n }\n },\n [\n showActions,\n deferStateUpdates,\n pendingChanges,\n formData,\n resolvedSchema,\n onValidationChange,\n ],\n );\n\n const handleFieldBlur = useCallback(\n (fieldName: string) => {\n if (readOnly) return;\n\n flushPendingField(fieldName);\n\n if (!showActions && deferChanges && onChange) {\n onChange(formData);\n }\n\n if (onBlur) {\n const hasPending =\n deferStateUpdates && pendingChanges[fieldName] !== undefined;\n const dataToPass = hasPending\n ? { ...formData, [fieldName]: pendingChanges[fieldName] }\n : formData;\n onBlur(fieldName, dataToPass);\n }\n },\n [\n readOnly,\n formData,\n pendingChanges,\n deferChanges,\n deferStateUpdates,\n showActions,\n onChange,\n onBlur,\n flushPendingField,\n ],\n );\n\n const handleSave = useCallback(() => {\n if (!hasChanges) return;\n\n const finalData =\n deferStateUpdates && Object.keys(pendingChanges).length > 0\n ? { ...formData, ...pendingChanges }\n : formData;\n\n const completeData = { ...nonSchemaData, ...finalData };\n const validation = validateFormData(resolvedSchema, finalData);\n\n if (validation.isValid && onUpdate) {\n // Compute changed fields at save time (includes any pending changes).\n const changed: Record<string, any> = {};\n for (const key of Object.keys(finalData)) {\n if (!isEqual(finalData[key], originalData[key])) {\n changed[key] = finalData[key];\n }\n }\n const diff = diffFormData(originalData, finalData);\n onUpdate(completeData, changed, diff);\n setPendingChanges({});\n }\n }, [\n hasChanges,\n resolvedSchema,\n formData,\n originalData,\n pendingChanges,\n deferStateUpdates,\n nonSchemaData,\n onUpdate,\n ]);\n\n const handleCancel = useCallback(() => {\n setFormData({ ...originalData });\n setPendingChanges({});\n onCancel?.();\n }, [originalData, onCancel]);\n\n return {\n formData,\n displayData,\n resolvedSchema,\n orderedProperties,\n hasChanges,\n isValid,\n handleFieldChange,\n handleFieldBlur,\n handleSave,\n handleCancel,\n };\n}\n","import { JsonSchemaProperty } from \"@petrarca/sonnet-core/schema\";\n\n/**\n * Order properties based on the x-ui-order array.\n *\n * Fields listed in x-ui-order are rendered first (in that order).\n * Fields not listed are rendered after in their original schema order.\n * Names in x-ui-order that don't exist in properties are silently ignored.\n */\nexport function orderProperties(\n properties: Record<string, JsonSchemaProperty>,\n orderArray: string[] | undefined,\n): [string, JsonSchemaProperty][] {\n const allEntries = Object.entries(properties);\n\n if (!orderArray || orderArray.length === 0) return allEntries;\n\n const orderSet = new Set(orderArray);\n const map = new Map(allEntries);\n\n const ordered: [string, JsonSchemaProperty][] = [];\n for (const name of orderArray) {\n const prop = map.get(name);\n if (prop) ordered.push([name, prop]);\n }\n\n const unordered = allEntries.filter(([name]) => !orderSet.has(name));\n return [...ordered, ...unordered];\n}\n","/**\n * useResolvedSchema - Schema resolution and property ordering\n *\n * Resolves conditional schemas (if-then-else, allOf) based on the current\n * form data, and applies x-ui-order to produce a stable ordered list of\n * [fieldName, property] pairs for rendering.\n *\n * ## Relationship to useFormEngine\n *\n * `useFormEngine` already performs this same resolution internally so that\n * validation and field-cleanup effects have access to the live schema.\n * This hook exists as a **standalone composable** for consumers that need\n * schema resolution without the full form-state machinery — for example:\n *\n * - A read-only schema viewer that renders fields without tracking changes\n * - A field-count or schema-diff preview component\n * - A future form builder that needs to inspect the resolved structure\n * before mounting a full form engine\n *\n * Do **not** import both this hook and `useFormEngine` in the same component\n * for the same schema/data pair — that would resolve the schema twice.\n * Prefer the values returned by `useFormEngine` when the engine is already\n * in use.\n *\n * @module components/Forms/hooks/useResolvedSchema\n */\n\nimport { useMemo } from \"react\";\nimport { JsonSchema, JsonSchemaProperty } from \"@petrarca/sonnet-core/schema\";\nimport {\n getSchemaProperties,\n resolveSchema,\n} from \"@petrarca/sonnet-core/schema\";\nimport { UISchema } from \"../widgets\";\nimport { orderProperties } from \"./orderProperties\";\n\nexport interface UseResolvedSchemaOptions {\n schema: JsonSchema;\n formData: Record<string, any>;\n uiSchema: { [fieldName: string]: UISchema };\n}\n\nexport interface UseResolvedSchemaResult {\n resolvedSchema: JsonSchema;\n orderedProperties: [string, JsonSchemaProperty][];\n}\n\nexport function useResolvedSchema({\n schema,\n formData,\n uiSchema,\n}: UseResolvedSchemaOptions): UseResolvedSchemaResult {\n const resolvedSchema = useMemo(\n () => resolveSchema(schema, formData),\n [schema, formData],\n );\n\n const orderedProperties = useMemo(() => {\n const properties = getSchemaProperties(resolvedSchema);\n const rawOrder = uiSchema[\"x-ui-order\"] ?? resolvedSchema[\"x-ui-order\"];\n const orderArray = Array.isArray(rawOrder)\n ? (rawOrder as string[])\n : undefined;\n return orderProperties(properties, orderArray);\n }, [resolvedSchema, uiSchema]);\n\n return { resolvedSchema, orderedProperties };\n}\n"],"mappings":"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","names":["cn","jsx","jsxs","cn","React","useId","cn","jsx","jsxs","cn","React","useId","React","useId","Input","cn","jsx","React","useId","Input","cn","React","useId","cn","jsx","jsxs","cn","React","useId","React","cn","jsx","jsxs","cn","React","Check","ChevronsUpDown","X","cn","Button","Command","CommandEmpty","CommandGroup","CommandInput","CommandItem","CommandList","Popover","PopoverContent","PopoverTrigger","Fragment","jsx","jsxs","X","Command","CommandInput","CommandList","CommandEmpty","CommandGroup","CommandItem","Check","cn","Button","ChevronsUpDown","Popover","PopoverTrigger","PopoverContent","React","X","cn","Input","Badge","jsx","jsxs","Badge","X","cn","Input","React","useCallback","useEffect","useId","useState","ChevronsUpDown","cn","jsx","jsxs","ChevronsUpDown","useState","useEffect","useCallback","React","useId","cn","Button","jsx","jsxs","useMemo","jsx","jsxs","React","useCallback","useMemo","FORM_ITEM_ID_FIELD","jsx","jsx","jsx","useCallback","jsx","useCallback","useRef","jsx","useRef","jsx","useCallback","useState","jsx","jsxs","useMemo","jsx","jsxs","useMemo","useMemo","useState","ChevronDown","ChevronRight","Card","Collapsible","CollapsibleContent","jsx","jsxs","Fragment","jsx","useMemo","useCallback","useMemo","Button","ChevronDown","Button","jsx","jsxs","jsx","jsxs","jsx","jsxs","resolveLayout","useCallback","useMemo","Button","useCallback","useRef","jsx","useRef","useCallback","isNullableBoolean","extractEnumValues","Trash2","ChevronUp","ChevronDown","Button","jsx","jsxs","Button","ChevronUp","ChevronDown","Trash2","jsx","useState","useEffect","useMemo","useCallback","useRef","applySchemaDefaults","useMemo","useState","applySchemaDefaults","properties","useEffect","useRef","useCallback","jsx","jsxs","FORM_ITEM_ID_FIELD","useCallback","React","useMemo","props","useMemo","getSchemaProperties","resolveSchema","useMemo","resolveSchema","getSchemaProperties"]}