@fogpipe/forma-react 0.18.0 → 0.19.1
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.
- package/dist/{FormRenderer-D_ZVK44t.d.ts → FormRenderer-B7qwG4to.d.ts} +9 -1
- package/dist/{chunk-5K4QITFH.js → chunk-CFX3T5WK.js} +25 -3
- package/dist/chunk-CFX3T5WK.js.map +1 -0
- package/dist/defaults/index.d.ts +1 -1
- package/dist/defaults/index.js +7 -3
- package/dist/defaults/index.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +26 -2
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/FieldRenderer.tsx +33 -1
- package/src/FormRenderer.tsx +35 -1
- package/src/__tests__/defaults/components.test.tsx +256 -0
- package/src/__tests__/defaults/integration.test.tsx +132 -0
- package/src/__tests__/test-utils.tsx +4 -2
- package/src/defaults/components/ComputedDisplay.tsx +2 -1
- package/src/defaults/components/DisplayField.tsx +8 -1
- package/src/types.ts +7 -0
- package/dist/chunk-5K4QITFH.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/defaults/DefaultFormRenderer.tsx","../../src/defaults/components/TextInput.tsx","../../src/defaults/components/TextareaInput.tsx","../../src/defaults/components/NumberInput.tsx","../../src/defaults/components/BooleanInput.tsx","../../src/defaults/components/DateInput.tsx","../../src/defaults/components/SelectInput.tsx","../../src/defaults/components/MultiSelectInput.tsx","../../src/defaults/components/ArrayField.tsx","../../src/defaults/components/ObjectField.tsx","../../src/defaults/components/ComputedDisplay.tsx","../../src/defaults/components/DisplayField.tsx","../../src/defaults/components/MatrixField.tsx","../../src/defaults/components/FallbackField.tsx","../../src/defaults/layout/FieldWrapper.tsx","../../src/defaults/layout/FormLayout.tsx","../../src/defaults/layout/WizardLayout.tsx","../../src/defaults/layout/PageWrapper.tsx","../../src/defaults/componentMap.ts"],"sourcesContent":["import React, { forwardRef } from \"react\";\nimport { FormRenderer } from \"../FormRenderer.js\";\nimport type { FormRendererProps, FormRendererHandle } from \"../FormRenderer.js\";\nimport {\n defaultComponentMap,\n defaultFieldWrapper,\n defaultLayout,\n defaultWizardLayout,\n defaultPageWrapper,\n} from \"./componentMap.js\";\n\nexport interface DefaultFormRendererProps\n extends Omit<FormRendererProps, \"components\"> {\n /** Component map (defaults to defaultComponentMap if not provided) */\n components?: FormRendererProps[\"components\"];\n /** Use wizard layout for multi-page forms */\n wizardLayout?: boolean;\n}\n\nexport const DefaultFormRenderer = forwardRef<\n FormRendererHandle,\n DefaultFormRendererProps\n>(function DefaultFormRenderer(props, ref) {\n const {\n components,\n wizardLayout,\n layout,\n fieldWrapper,\n pageWrapper,\n ...rest\n } = props;\n\n return (\n <FormRenderer\n ref={ref}\n components={components ?? defaultComponentMap}\n fieldWrapper={fieldWrapper ?? defaultFieldWrapper}\n layout={layout ?? (wizardLayout ? defaultWizardLayout : defaultLayout)}\n pageWrapper={pageWrapper ?? defaultPageWrapper}\n {...rest}\n />\n );\n});\n","import React from \"react\";\nimport type { TextComponentProps } from \"../../types.js\";\n\nexport function TextInput({ field }: TextComponentProps) {\n const inputType = field.fieldType === \"phone\" ? \"tel\" : field.fieldType;\n\n const hasErrors = field.visibleErrors.length > 0;\n const describedBy = [\n field.description ? `${field.name}-description` : null,\n hasErrors ? `${field.name}-errors` : null,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const input = (\n <input\n id={field.name}\n name={field.name}\n type={inputType}\n className=\"forma-input\"\n value={field.value}\n onChange={(e) => field.onChange(e.target.value)}\n onBlur={field.onBlur}\n disabled={field.disabled}\n readOnly={field.readonly}\n placeholder={field.placeholder}\n aria-invalid={hasErrors || undefined}\n aria-required={field.required || undefined}\n aria-describedby={describedBy || undefined}\n />\n );\n\n if (field.prefix || field.suffix) {\n return (\n <div className=\"forma-input-adorner\">\n {field.prefix && (\n <span className=\"forma-input-adorner__prefix\">{field.prefix}</span>\n )}\n {input}\n {field.suffix && (\n <span className=\"forma-input-adorner__suffix\">{field.suffix}</span>\n )}\n </div>\n );\n }\n\n return input;\n}\n","import React from \"react\";\nimport type { TextComponentProps } from \"../../types.js\";\n\nexport function TextareaInput({ field }: TextComponentProps) {\n const hasErrors = field.visibleErrors.length > 0;\n const describedBy = [\n field.description ? `${field.name}-description` : null,\n hasErrors ? `${field.name}-errors` : null,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const textarea = (\n <textarea\n id={field.name}\n name={field.name}\n className=\"forma-textarea\"\n value={field.value}\n onChange={(e) => field.onChange(e.target.value)}\n onBlur={field.onBlur}\n disabled={field.disabled}\n readOnly={field.readonly}\n placeholder={field.placeholder}\n rows={3}\n aria-invalid={hasErrors || undefined}\n aria-required={field.required || undefined}\n aria-describedby={describedBy || undefined}\n />\n );\n\n if (field.prefix || field.suffix) {\n return (\n <div className=\"forma-input-adorner\">\n {field.prefix && (\n <span className=\"forma-input-adorner__prefix\">{field.prefix}</span>\n )}\n {textarea}\n {field.suffix && (\n <span className=\"forma-input-adorner__suffix\">{field.suffix}</span>\n )}\n </div>\n );\n }\n\n return textarea;\n}\n","import React from \"react\";\nimport type { NumberComponentProps, IntegerComponentProps } from \"../../types.js\";\n\nfunction NumberInputBase({\n field,\n parseValue,\n}: {\n field: NumberComponentProps[\"field\"] | IntegerComponentProps[\"field\"];\n parseValue: (val: string) => number;\n}) {\n const hasErrors = field.visibleErrors.length > 0;\n const describedBy = [\n field.description ? `${field.name}-description` : null,\n hasErrors ? `${field.name}-errors` : null,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const input = (\n <input\n id={field.name}\n name={field.name}\n type=\"number\"\n className={`forma-input forma-input--${field.fieldType}`}\n value={field.value != null ? String(field.value) : \"\"}\n onChange={(e) => {\n const val = e.target.value;\n if (val === \"\") {\n field.onChange(null);\n } else {\n const num = parseValue(val);\n field.onChange(isNaN(num) ? null : num);\n }\n }}\n onBlur={field.onBlur}\n disabled={field.disabled}\n readOnly={field.readonly}\n placeholder={field.placeholder}\n min={field.min}\n max={field.max}\n step={field.step ?? (field.fieldType === \"integer\" ? 1 : \"any\")}\n aria-invalid={hasErrors || undefined}\n aria-required={field.required || undefined}\n aria-describedby={describedBy || undefined}\n />\n );\n\n if (field.prefix || field.suffix) {\n return (\n <div className=\"forma-input-adorner\">\n {field.prefix && (\n <span className=\"forma-input-adorner__prefix\">{field.prefix}</span>\n )}\n {input}\n {field.suffix && (\n <span className=\"forma-input-adorner__suffix\">{field.suffix}</span>\n )}\n </div>\n );\n }\n\n return input;\n}\n\nexport function NumberInput({ field }: NumberComponentProps) {\n return <NumberInputBase field={field} parseValue={parseFloat} />;\n}\n\nexport function IntegerInput({ field }: IntegerComponentProps) {\n return (\n <NumberInputBase field={field} parseValue={(v) => parseInt(v, 10)} />\n );\n}\n","import React from \"react\";\nimport type { BooleanComponentProps } from \"../../types.js\";\n\nexport function BooleanInput({ field }: BooleanComponentProps) {\n const hasErrors = field.visibleErrors.length > 0;\n const describedBy = [\n field.description ? `${field.name}-description` : null,\n hasErrors ? `${field.name}-errors` : null,\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div className=\"forma-checkbox\">\n <input\n id={field.name}\n name={field.name}\n type=\"checkbox\"\n className=\"forma-checkbox__input\"\n checked={field.value ?? false}\n onChange={(e) => field.onChange(e.target.checked)}\n onBlur={field.onBlur}\n disabled={field.disabled}\n aria-invalid={hasErrors || undefined}\n aria-describedby={describedBy || undefined}\n />\n <label htmlFor={field.name} className=\"forma-checkbox__label\">\n {field.label}\n </label>\n </div>\n );\n}\n","import React from \"react\";\nimport type { DateComponentProps, DateTimeComponentProps } from \"../../types.js\";\n\nexport function DateInput({ field }: DateComponentProps) {\n const hasErrors = field.visibleErrors.length > 0;\n const describedBy = [\n field.description ? `${field.name}-description` : null,\n hasErrors ? `${field.name}-errors` : null,\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <input\n id={field.name}\n name={field.name}\n type=\"date\"\n className=\"forma-input forma-input--date\"\n value={field.value ?? \"\"}\n onChange={(e) => field.onChange(e.target.value || null)}\n onBlur={field.onBlur}\n disabled={field.disabled}\n readOnly={field.readonly}\n aria-invalid={hasErrors || undefined}\n aria-required={field.required || undefined}\n aria-describedby={describedBy || undefined}\n />\n );\n}\n\nexport function DateTimeInput({ field }: DateTimeComponentProps) {\n const hasErrors = field.visibleErrors.length > 0;\n const describedBy = [\n field.description ? `${field.name}-description` : null,\n hasErrors ? `${field.name}-errors` : null,\n ]\n .filter(Boolean)\n .join(\" \");\n\n // datetime-local expects \"YYYY-MM-DDTHH:mm\" format\n const inputValue = field.value ?? \"\";\n\n return (\n <input\n id={field.name}\n name={field.name}\n type=\"datetime-local\"\n className=\"forma-input forma-input--datetime\"\n value={inputValue}\n onChange={(e) => field.onChange(e.target.value || null)}\n onBlur={field.onBlur}\n disabled={field.disabled}\n readOnly={field.readonly}\n aria-invalid={hasErrors || undefined}\n aria-required={field.required || undefined}\n aria-describedby={describedBy || undefined}\n />\n );\n}\n","import React from \"react\";\nimport type { SelectComponentProps } from \"../../types.js\";\n\nexport function SelectInput({ field }: SelectComponentProps) {\n const hasErrors = field.visibleErrors.length > 0;\n const describedBy = [\n field.description ? `${field.name}-description` : null,\n hasErrors ? `${field.name}-errors` : null,\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <select\n id={field.name}\n name={field.name}\n className=\"forma-select\"\n value={field.value !== null ? String(field.value) : \"\"}\n onChange={(e) => {\n const value = e.target.value;\n if (!value) {\n field.onChange(null);\n } else {\n // Preserve string value\n field.onChange(value);\n }\n }}\n onBlur={field.onBlur}\n disabled={field.disabled}\n aria-invalid={hasErrors || undefined}\n aria-required={field.required || undefined}\n aria-describedby={describedBy || undefined}\n >\n {(!field.required || field.value === null) && (\n <option value=\"\">{field.placeholder ?? \"Select...\"}</option>\n )}\n {field.options.map((opt) => (\n <option key={String(opt.value)} value={String(opt.value)}>\n {opt.label}\n </option>\n ))}\n </select>\n );\n}\n","import React from \"react\";\nimport type { MultiSelectComponentProps } from \"../../types.js\";\n\nexport function MultiSelectInput({ field }: MultiSelectComponentProps) {\n const hasErrors = field.visibleErrors.length > 0;\n const describedBy = [\n field.description ? `${field.name}-description` : null,\n hasErrors ? `${field.name}-errors` : null,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const selected = field.value ?? [];\n\n const handleToggle = (optionValue: string) => {\n if (selected.includes(optionValue)) {\n field.onChange(selected.filter((v) => v !== optionValue));\n } else {\n field.onChange([...selected, optionValue]);\n }\n field.onBlur();\n };\n\n return (\n <fieldset\n className=\"forma-multiselect\"\n aria-describedby={describedBy || undefined}\n aria-invalid={hasErrors || undefined}\n >\n <legend className=\"forma-sr-only\">{field.label}</legend>\n {field.options.map((opt) => {\n const optId = `${field.name}-${opt.value}`;\n return (\n <div key={String(opt.value)} className=\"forma-multiselect__option\">\n <input\n id={optId}\n type=\"checkbox\"\n className=\"forma-checkbox__input\"\n checked={selected.includes(String(opt.value))}\n onChange={() => handleToggle(String(opt.value))}\n disabled={field.disabled}\n />\n <label htmlFor={optId} className=\"forma-checkbox__label\">\n {opt.label}\n </label>\n </div>\n );\n })}\n </fieldset>\n );\n}\n","import React, { useRef } from \"react\";\nimport type { ArrayComponentProps } from \"../../types.js\";\n\nexport function ArrayField({ field }: ArrayComponentProps) {\n const hasErrors = field.visibleErrors.length > 0;\n\n // Stable keys via ref-based sequential counter\n const itemKeysRef = useRef<string[]>([]);\n const nextKeyRef = useRef(0);\n\n const currentLength = field.helpers.items.length;\n const keysLength = itemKeysRef.current.length;\n\n if (currentLength > keysLength) {\n for (let i = keysLength; i < currentLength; i++) {\n itemKeysRef.current.push(`item-${nextKeyRef.current++}`);\n }\n } else if (currentLength < keysLength) {\n itemKeysRef.current.length = currentLength;\n }\n\n const fieldOrder =\n field.itemFieldOrder ?? Object.keys(field.itemFields);\n\n return (\n <div\n className=\"forma-array\"\n aria-invalid={hasErrors || undefined}\n >\n {field.helpers.items.length === 0 && (\n <p className=\"forma-array__empty\">No items</p>\n )}\n {field.helpers.items.map((_, index) => (\n <div\n key={itemKeysRef.current[index]}\n className=\"forma-array__item\"\n >\n <div className=\"forma-array__item-fields\">\n {fieldOrder.map((fieldName) => {\n const itemProps = field.helpers.getItemFieldProps(\n index,\n fieldName,\n );\n return (\n <div key={fieldName} className=\"forma-field\">\n <label\n htmlFor={itemProps.name}\n className=\"forma-label\"\n >\n {itemProps.label}\n </label>\n {renderItemField(itemProps)}\n {itemProps.errors.length > 0 && itemProps.touched && (\n <div className=\"forma-field__errors\" role=\"alert\">\n {itemProps.errors.map((err, i) => (\n <span key={i} className=\"forma-field__error\">\n {err.message}\n </span>\n ))}\n </div>\n )}\n </div>\n );\n })}\n </div>\n <button\n type=\"button\"\n className=\"forma-button forma-button--danger forma-array__remove\"\n onClick={() => field.helpers.remove(index)}\n disabled={!field.helpers.canRemove || field.disabled}\n >\n Remove\n </button>\n </div>\n ))}\n <button\n type=\"button\"\n className=\"forma-button forma-button--secondary forma-array__add\"\n onClick={() => field.helpers.push()}\n disabled={!field.helpers.canAdd || field.disabled}\n >\n + Add Item\n </button>\n </div>\n );\n}\n\nfunction renderItemField(\n itemProps: ReturnType<\n ArrayComponentProps[\"field\"][\"helpers\"][\"getItemFieldProps\"]\n >,\n) {\n const type = itemProps.type;\n\n if (type === \"select\" && itemProps.options) {\n return (\n <select\n id={itemProps.name}\n className=\"forma-select\"\n value={String(itemProps.value ?? \"\")}\n onChange={(e) => {\n const value = e.target.value;\n if (!value) {\n itemProps.onChange(null);\n } else {\n const option = itemProps.options?.find(\n (opt) => String(opt.value) === value,\n );\n itemProps.onChange(option ? option.value : value);\n }\n }}\n onBlur={itemProps.onBlur}\n disabled={!itemProps.enabled}\n >\n <option value=\"\">Select...</option>\n {itemProps.options.map((opt) => (\n <option key={String(opt.value)} value={String(opt.value)}>\n {opt.label}\n </option>\n ))}\n </select>\n );\n }\n\n if (type === \"number\" || type === \"integer\") {\n return (\n <input\n id={itemProps.name}\n type=\"number\"\n className=\"forma-input\"\n value={itemProps.value != null ? String(itemProps.value) : \"\"}\n onChange={(e) => {\n const val = e.target.value;\n if (val === \"\") {\n itemProps.onChange(null);\n } else {\n const num =\n type === \"integer\"\n ? parseInt(val, 10)\n : parseFloat(val);\n itemProps.onChange(isNaN(num) ? null : num);\n }\n }}\n onBlur={itemProps.onBlur}\n disabled={!itemProps.enabled}\n step={type === \"integer\" ? 1 : \"any\"}\n />\n );\n }\n\n if (type === \"boolean\") {\n return (\n <div className=\"forma-checkbox\">\n <input\n id={itemProps.name}\n type=\"checkbox\"\n className=\"forma-checkbox__input\"\n checked={Boolean(itemProps.value)}\n onChange={(e) => itemProps.onChange(e.target.checked)}\n onBlur={itemProps.onBlur}\n disabled={!itemProps.enabled}\n />\n <label htmlFor={itemProps.name} className=\"forma-checkbox__label\">\n {itemProps.label}\n </label>\n </div>\n );\n }\n\n // Default: text input\n return (\n <input\n id={itemProps.name}\n type=\"text\"\n className=\"forma-input\"\n value={String(itemProps.value ?? \"\")}\n onChange={(e) => itemProps.onChange(e.target.value)}\n onBlur={itemProps.onBlur}\n disabled={!itemProps.enabled}\n placeholder={itemProps.placeholder}\n />\n );\n}\n","import React from \"react\";\nimport type { ObjectComponentProps } from \"../../types.js\";\n\nexport function ObjectField({ field }: ObjectComponentProps) {\n const hasErrors = field.visibleErrors.length > 0;\n\n return (\n <fieldset\n className=\"forma-object\"\n aria-invalid={hasErrors || undefined}\n >\n <legend className=\"forma-object__legend\">{field.label}</legend>\n {field.description && (\n <p className=\"forma-object__description\">{field.description}</p>\n )}\n <div className=\"forma-object__fields\">\n {/* Object child fields are rendered by FormRenderer, not here.\n The object component is a visual container only. */}\n </div>\n </fieldset>\n );\n}\n","import React from \"react\";\nimport type { ComputedComponentProps } from \"../../types.js\";\n\nexport function ComputedDisplay({ field }: ComputedComponentProps) {\n let displayValue: string;\n if (field.value === null || field.value === undefined) {\n displayValue = \"\\u2014\";\n } else if (typeof field.value === \"object\") {\n try {\n displayValue = JSON.stringify(field.value);\n } catch {\n displayValue = String(field.value);\n }\n } else {\n displayValue = String(field.value);\n }\n\n return (\n <output\n id={field.name}\n className=\"forma-computed\"\n >\n {displayValue}\n </output>\n );\n}\n","import React from \"react\";\nimport type { DisplayComponentProps } from \"../../types.js\";\n\nexport function DisplayField({ field }: DisplayComponentProps) {\n const content =\n field.sourceValue !== undefined\n ? String(field.sourceValue)\n : field.content;\n\n return (\n <div className=\"forma-display\">\n {content && <p className=\"forma-display__content\">{content}</p>}\n </div>\n );\n}\n","import React from \"react\";\nimport type { MatrixComponentProps } from \"../../types.js\";\n\nexport function MatrixField({ field }: MatrixComponentProps) {\n const hasErrors = field.visibleErrors.length > 0;\n const visibleRows = field.rows.filter((r) => r.visible);\n const currentValue = field.value ?? {};\n\n const handleChange = (\n rowId: string,\n colValue: string | number,\n ) => {\n if (field.disabled) return;\n\n const next = { ...currentValue };\n if (field.multiSelect) {\n const current = (currentValue[rowId] ?? []) as string[];\n const colStr = String(colValue);\n const exists = current.includes(colStr);\n next[rowId] = exists\n ? current.filter((v) => v !== colStr)\n : [...current, colStr];\n } else {\n next[rowId] = colValue;\n }\n field.onChange(next as Record<string, string | number | string[] | number[]>);\n field.onBlur();\n };\n\n const isChecked = (\n rowId: string,\n colValue: string | number,\n ): boolean => {\n const rowValue = currentValue[rowId];\n if (rowValue === undefined || rowValue === null) return false;\n if (Array.isArray(rowValue)) {\n return (rowValue as (string | number)[]).includes(colValue);\n }\n return rowValue === colValue;\n };\n\n return (\n <div className=\"forma-matrix\" aria-invalid={hasErrors || undefined}>\n <table className=\"forma-matrix__table\" role=\"grid\">\n <thead>\n <tr>\n <th scope=\"col\" className=\"forma-matrix__corner\" />\n {field.columns.map((col) => (\n <th\n key={String(col.value)}\n scope=\"col\"\n className=\"forma-matrix__col-header\"\n >\n {col.label}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {visibleRows.map((row) => (\n <tr key={row.id} className=\"forma-matrix__row\">\n <th scope=\"row\" className=\"forma-matrix__row-header\">\n {row.label}\n </th>\n {field.columns.map((col) => {\n const cellId = `${field.name}-${row.id}-${col.value}`;\n return (\n <td key={String(col.value)} className=\"forma-matrix__cell\">\n <input\n id={cellId}\n type={field.multiSelect ? \"checkbox\" : \"radio\"}\n name={\n field.multiSelect\n ? cellId\n : `${field.name}-${row.id}`\n }\n className={\n field.multiSelect\n ? \"forma-checkbox__input\"\n : \"forma-radio__input\"\n }\n checked={isChecked(row.id, col.value)}\n onChange={() => handleChange(row.id, col.value)}\n disabled={field.disabled}\n />\n <label htmlFor={cellId} className=\"forma-sr-only\">\n {row.label}: {col.label}\n </label>\n </td>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n}\n","import React from \"react\";\nimport type { FieldComponentProps } from \"../../types.js\";\n\ndeclare const process: { env: { NODE_ENV?: string } } | undefined;\n\nexport function FallbackField({ field }: FieldComponentProps) {\n const hasErrors = field.visibleErrors.length > 0;\n const isDev =\n typeof process !== \"undefined\" && process.env.NODE_ENV !== \"production\";\n\n return (\n <div className=\"forma-fallback\">\n {isDev && (\n <p className=\"forma-fallback__warning\">\n Unknown field type: "{field.field.type}"\n </p>\n )}\n <input\n id={field.name}\n name={field.name}\n type=\"text\"\n className=\"forma-input\"\n value={String(field.value ?? \"\")}\n onChange={(e) => {\n if (\"onChange\" in field && typeof field.onChange === \"function\") {\n (field.onChange as (value: string) => void)(e.target.value);\n }\n }}\n onBlur={field.onBlur}\n disabled={field.disabled}\n aria-invalid={hasErrors || undefined}\n />\n </div>\n );\n}\n","import React from \"react\";\nimport type { FieldWrapperProps } from \"../../types.js\";\nimport { useFormaContext } from \"../../context.js\";\n\nexport function FieldWrapper({\n fieldPath,\n field,\n children,\n errors,\n touched,\n showRequiredIndicator,\n visible,\n}: FieldWrapperProps) {\n const { isSubmitted } = useFormaContext();\n\n if (!visible) return null;\n\n const shouldShowMessages = touched || isSubmitted;\n const visibleErrors = shouldShowMessages\n ? errors.filter((e) => e.severity === \"error\")\n : [];\n const visibleWarnings = shouldShowMessages\n ? errors.filter((e) => e.severity === \"warning\")\n : [];\n const hasErrors = visibleErrors.length > 0;\n const hasWarnings = visibleWarnings.length > 0;\n\n const classNames = [\n \"forma-field\",\n hasErrors && \"forma-field--error\",\n !hasErrors && hasWarnings && \"forma-field--warning\",\n showRequiredIndicator && \"forma-field--required\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div className={classNames} data-field-path={fieldPath}>\n {field.label && field.type !== \"boolean\" && (\n <label htmlFor={fieldPath} className=\"forma-label\">\n {field.label}\n {showRequiredIndicator && (\n <span className=\"forma-label__required\" aria-hidden=\"true\">\n {\" \"}\n *\n </span>\n )}\n </label>\n )}\n {field.description && (\n <div\n id={`${fieldPath}-description`}\n className=\"forma-field__description\"\n >\n {field.description}\n </div>\n )}\n {children}\n {hasErrors && (\n <div\n id={`${fieldPath}-errors`}\n className=\"forma-field__errors\"\n role=\"alert\"\n >\n {visibleErrors.map((error, i) => (\n <span key={i} className=\"forma-field__error\">\n {error.message}\n </span>\n ))}\n </div>\n )}\n {hasWarnings && (\n <div className=\"forma-field__warnings\">\n {visibleWarnings.map((warning, i) => (\n <span key={i} className=\"forma-field__warning\">\n {warning.message}\n </span>\n ))}\n </div>\n )}\n </div>\n );\n}\n","import React from \"react\";\nimport type { LayoutProps } from \"../../types.js\";\n\nexport function FormLayout({\n children,\n onSubmit,\n isSubmitting,\n}: LayoutProps) {\n return (\n <form\n className=\"forma-form\"\n onSubmit={(e) => {\n e.preventDefault();\n onSubmit();\n }}\n noValidate\n >\n {children}\n <div className=\"forma-form__actions\">\n {/* Submit is not disabled when invalid — intentional. Disabling prevents\n users from discovering which fields need attention. Instead, clicking\n submit triggers validation and displays errors via FieldWrapper. */}\n <button\n type=\"submit\"\n className={`forma-button forma-button--primary forma-submit${isSubmitting ? \" forma-submit--loading\" : \"\"}`}\n disabled={isSubmitting}\n aria-busy={isSubmitting || undefined}\n >\n {isSubmitting ? \"Submitting...\" : \"Submit\"}\n </button>\n </div>\n </form>\n );\n}\n","import React, { useCallback } from \"react\";\nimport type { LayoutProps } from \"../../types.js\";\nimport { useFormaContext } from \"../../context.js\";\n\nexport function WizardLayout({\n children,\n onSubmit,\n isSubmitting,\n}: LayoutProps) {\n const { wizard } = useFormaContext();\n\n const handleNext = useCallback(() => {\n if (!wizard) return;\n wizard.touchCurrentPageFields();\n if (wizard.validateCurrentPage()) {\n wizard.nextPage();\n }\n }, [wizard]);\n\n const handleSubmit = useCallback(\n (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n\n if (!wizard) {\n onSubmit();\n return;\n }\n\n const nativeEvent = e.nativeEvent as SubmitEvent;\n const submitter = nativeEvent.submitter as HTMLButtonElement | null;\n\n if (wizard.isLastPage && submitter?.dataset.action === \"submit\") {\n onSubmit();\n } else if (!wizard.isLastPage) {\n handleNext();\n }\n },\n [wizard, onSubmit, handleNext],\n );\n\n // Fallback to simple form layout if no wizard\n if (!wizard) {\n return (\n <form\n className=\"forma-form\"\n onSubmit={handleSubmit}\n noValidate\n >\n {children}\n <div className=\"forma-form__actions\">\n <button\n type=\"submit\"\n className=\"forma-button forma-button--primary forma-submit\"\n disabled={isSubmitting}\n aria-busy={isSubmitting || undefined}\n >\n {isSubmitting ? \"Submitting...\" : \"Submit\"}\n </button>\n </div>\n </form>\n );\n }\n\n return (\n <form className=\"forma-wizard\" onSubmit={handleSubmit} noValidate>\n {/* Step indicator */}\n <div className=\"forma-wizard__steps\" role=\"navigation\" aria-label=\"Form progress\">\n {wizard.pages.map((page, index) => {\n const isCompleted = index < wizard.currentPageIndex;\n const isCurrent = index === wizard.currentPageIndex;\n const stepClass = [\n \"forma-step\",\n isCompleted && \"forma-step--completed\",\n isCurrent && \"forma-step--current\",\n !isCompleted && !isCurrent && \"forma-step--upcoming\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div key={page.id} className={stepClass} aria-current={isCurrent ? \"step\" : undefined}>\n <span className=\"forma-step__indicator\">\n {isCompleted ? \"\\u2713\" : index + 1}\n </span>\n <span className=\"forma-step__label\">{page.title}</span>\n </div>\n );\n })}\n </div>\n\n {/* Page content */}\n {children}\n\n {/* Navigation */}\n <div className=\"forma-wizard__nav\">\n {wizard.hasPreviousPage ? (\n <button\n type=\"button\"\n className=\"forma-button forma-button--secondary\"\n onClick={() => wizard.previousPage()}\n >\n Previous\n </button>\n ) : (\n <div />\n )}\n\n {wizard.isLastPage ? (\n <button\n type=\"submit\"\n data-action=\"submit\"\n className={`forma-button forma-button--primary forma-submit${isSubmitting ? \" forma-submit--loading\" : \"\"}`}\n disabled={isSubmitting}\n aria-busy={isSubmitting || undefined}\n >\n {isSubmitting ? \"Submitting...\" : \"Submit\"}\n </button>\n ) : (\n <button\n type=\"button\"\n className=\"forma-button forma-button--primary\"\n onClick={handleNext}\n >\n Next\n </button>\n )}\n </div>\n </form>\n );\n}\n","import React from \"react\";\nimport type { PageWrapperProps } from \"../../types.js\";\n\nexport function PageWrapper({\n title,\n description,\n children,\n}: PageWrapperProps) {\n return (\n <div className=\"forma-page\">\n {title && <h2 className=\"forma-page__title\">{title}</h2>}\n {description && (\n <p className=\"forma-page__description\">{description}</p>\n )}\n {children}\n </div>\n );\n}\n","import type { ComponentMap } from \"../types.js\";\nimport { TextInput } from \"./components/TextInput.js\";\nimport { TextareaInput } from \"./components/TextareaInput.js\";\nimport { NumberInput, IntegerInput } from \"./components/NumberInput.js\";\nimport { BooleanInput } from \"./components/BooleanInput.js\";\nimport { DateInput, DateTimeInput } from \"./components/DateInput.js\";\nimport { SelectInput } from \"./components/SelectInput.js\";\nimport { MultiSelectInput } from \"./components/MultiSelectInput.js\";\nimport { ArrayField } from \"./components/ArrayField.js\";\nimport { ObjectField } from \"./components/ObjectField.js\";\nimport { ComputedDisplay } from \"./components/ComputedDisplay.js\";\nimport { DisplayField } from \"./components/DisplayField.js\";\nimport { MatrixField } from \"./components/MatrixField.js\";\nimport { FallbackField } from \"./components/FallbackField.js\";\nimport { FieldWrapper } from \"./layout/FieldWrapper.js\";\nimport { FormLayout } from \"./layout/FormLayout.js\";\nimport { WizardLayout } from \"./layout/WizardLayout.js\";\nimport { PageWrapper } from \"./layout/PageWrapper.js\";\n\nexport const defaultComponentMap: ComponentMap = {\n text: TextInput,\n email: TextInput,\n phone: TextInput,\n url: TextInput,\n password: TextInput,\n textarea: TextareaInput,\n number: NumberInput,\n integer: IntegerInput,\n boolean: BooleanInput,\n date: DateInput,\n datetime: DateTimeInput,\n select: SelectInput,\n multiselect: MultiSelectInput,\n array: ArrayField,\n object: ObjectField,\n computed: ComputedDisplay,\n display: DisplayField,\n matrix: MatrixField,\n fallback: FallbackField,\n};\n\nexport const defaultFieldWrapper = FieldWrapper;\nexport const defaultLayout = FormLayout;\nexport const defaultWizardLayout = WizardLayout;\nexport const defaultPageWrapper = PageWrapper;\n"],"mappings":"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","names":["jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsx","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","DefaultFormRenderer"]}
|
|
1
|
+
{"version":3,"sources":["../../src/defaults/DefaultFormRenderer.tsx","../../src/defaults/components/TextInput.tsx","../../src/defaults/components/TextareaInput.tsx","../../src/defaults/components/NumberInput.tsx","../../src/defaults/components/BooleanInput.tsx","../../src/defaults/components/DateInput.tsx","../../src/defaults/components/SelectInput.tsx","../../src/defaults/components/MultiSelectInput.tsx","../../src/defaults/components/ArrayField.tsx","../../src/defaults/components/ObjectField.tsx","../../src/defaults/components/ComputedDisplay.tsx","../../src/defaults/components/DisplayField.tsx","../../src/defaults/components/MatrixField.tsx","../../src/defaults/components/FallbackField.tsx","../../src/defaults/layout/FieldWrapper.tsx","../../src/defaults/layout/FormLayout.tsx","../../src/defaults/layout/WizardLayout.tsx","../../src/defaults/layout/PageWrapper.tsx","../../src/defaults/componentMap.ts"],"sourcesContent":["import React, { forwardRef } from \"react\";\nimport { FormRenderer } from \"../FormRenderer.js\";\nimport type { FormRendererProps, FormRendererHandle } from \"../FormRenderer.js\";\nimport {\n defaultComponentMap,\n defaultFieldWrapper,\n defaultLayout,\n defaultWizardLayout,\n defaultPageWrapper,\n} from \"./componentMap.js\";\n\nexport interface DefaultFormRendererProps\n extends Omit<FormRendererProps, \"components\"> {\n /** Component map (defaults to defaultComponentMap if not provided) */\n components?: FormRendererProps[\"components\"];\n /** Use wizard layout for multi-page forms */\n wizardLayout?: boolean;\n}\n\nexport const DefaultFormRenderer = forwardRef<\n FormRendererHandle,\n DefaultFormRendererProps\n>(function DefaultFormRenderer(props, ref) {\n const {\n components,\n wizardLayout,\n layout,\n fieldWrapper,\n pageWrapper,\n ...rest\n } = props;\n\n return (\n <FormRenderer\n ref={ref}\n components={components ?? defaultComponentMap}\n fieldWrapper={fieldWrapper ?? defaultFieldWrapper}\n layout={layout ?? (wizardLayout ? defaultWizardLayout : defaultLayout)}\n pageWrapper={pageWrapper ?? defaultPageWrapper}\n {...rest}\n />\n );\n});\n","import React from \"react\";\nimport type { TextComponentProps } from \"../../types.js\";\n\nexport function TextInput({ field }: TextComponentProps) {\n const inputType = field.fieldType === \"phone\" ? \"tel\" : field.fieldType;\n\n const hasErrors = field.visibleErrors.length > 0;\n const describedBy = [\n field.description ? `${field.name}-description` : null,\n hasErrors ? `${field.name}-errors` : null,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const input = (\n <input\n id={field.name}\n name={field.name}\n type={inputType}\n className=\"forma-input\"\n value={field.value}\n onChange={(e) => field.onChange(e.target.value)}\n onBlur={field.onBlur}\n disabled={field.disabled}\n readOnly={field.readonly}\n placeholder={field.placeholder}\n aria-invalid={hasErrors || undefined}\n aria-required={field.required || undefined}\n aria-describedby={describedBy || undefined}\n />\n );\n\n if (field.prefix || field.suffix) {\n return (\n <div className=\"forma-input-adorner\">\n {field.prefix && (\n <span className=\"forma-input-adorner__prefix\">{field.prefix}</span>\n )}\n {input}\n {field.suffix && (\n <span className=\"forma-input-adorner__suffix\">{field.suffix}</span>\n )}\n </div>\n );\n }\n\n return input;\n}\n","import React from \"react\";\nimport type { TextComponentProps } from \"../../types.js\";\n\nexport function TextareaInput({ field }: TextComponentProps) {\n const hasErrors = field.visibleErrors.length > 0;\n const describedBy = [\n field.description ? `${field.name}-description` : null,\n hasErrors ? `${field.name}-errors` : null,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const textarea = (\n <textarea\n id={field.name}\n name={field.name}\n className=\"forma-textarea\"\n value={field.value}\n onChange={(e) => field.onChange(e.target.value)}\n onBlur={field.onBlur}\n disabled={field.disabled}\n readOnly={field.readonly}\n placeholder={field.placeholder}\n rows={3}\n aria-invalid={hasErrors || undefined}\n aria-required={field.required || undefined}\n aria-describedby={describedBy || undefined}\n />\n );\n\n if (field.prefix || field.suffix) {\n return (\n <div className=\"forma-input-adorner\">\n {field.prefix && (\n <span className=\"forma-input-adorner__prefix\">{field.prefix}</span>\n )}\n {textarea}\n {field.suffix && (\n <span className=\"forma-input-adorner__suffix\">{field.suffix}</span>\n )}\n </div>\n );\n }\n\n return textarea;\n}\n","import React from \"react\";\nimport type { NumberComponentProps, IntegerComponentProps } from \"../../types.js\";\n\nfunction NumberInputBase({\n field,\n parseValue,\n}: {\n field: NumberComponentProps[\"field\"] | IntegerComponentProps[\"field\"];\n parseValue: (val: string) => number;\n}) {\n const hasErrors = field.visibleErrors.length > 0;\n const describedBy = [\n field.description ? `${field.name}-description` : null,\n hasErrors ? `${field.name}-errors` : null,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const input = (\n <input\n id={field.name}\n name={field.name}\n type=\"number\"\n className={`forma-input forma-input--${field.fieldType}`}\n value={field.value != null ? String(field.value) : \"\"}\n onChange={(e) => {\n const val = e.target.value;\n if (val === \"\") {\n field.onChange(null);\n } else {\n const num = parseValue(val);\n field.onChange(isNaN(num) ? null : num);\n }\n }}\n onBlur={field.onBlur}\n disabled={field.disabled}\n readOnly={field.readonly}\n placeholder={field.placeholder}\n min={field.min}\n max={field.max}\n step={field.step ?? (field.fieldType === \"integer\" ? 1 : \"any\")}\n aria-invalid={hasErrors || undefined}\n aria-required={field.required || undefined}\n aria-describedby={describedBy || undefined}\n />\n );\n\n if (field.prefix || field.suffix) {\n return (\n <div className=\"forma-input-adorner\">\n {field.prefix && (\n <span className=\"forma-input-adorner__prefix\">{field.prefix}</span>\n )}\n {input}\n {field.suffix && (\n <span className=\"forma-input-adorner__suffix\">{field.suffix}</span>\n )}\n </div>\n );\n }\n\n return input;\n}\n\nexport function NumberInput({ field }: NumberComponentProps) {\n return <NumberInputBase field={field} parseValue={parseFloat} />;\n}\n\nexport function IntegerInput({ field }: IntegerComponentProps) {\n return (\n <NumberInputBase field={field} parseValue={(v) => parseInt(v, 10)} />\n );\n}\n","import React from \"react\";\nimport type { BooleanComponentProps } from \"../../types.js\";\n\nexport function BooleanInput({ field }: BooleanComponentProps) {\n const hasErrors = field.visibleErrors.length > 0;\n const describedBy = [\n field.description ? `${field.name}-description` : null,\n hasErrors ? `${field.name}-errors` : null,\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div className=\"forma-checkbox\">\n <input\n id={field.name}\n name={field.name}\n type=\"checkbox\"\n className=\"forma-checkbox__input\"\n checked={field.value ?? false}\n onChange={(e) => field.onChange(e.target.checked)}\n onBlur={field.onBlur}\n disabled={field.disabled}\n aria-invalid={hasErrors || undefined}\n aria-describedby={describedBy || undefined}\n />\n <label htmlFor={field.name} className=\"forma-checkbox__label\">\n {field.label}\n </label>\n </div>\n );\n}\n","import React from \"react\";\nimport type { DateComponentProps, DateTimeComponentProps } from \"../../types.js\";\n\nexport function DateInput({ field }: DateComponentProps) {\n const hasErrors = field.visibleErrors.length > 0;\n const describedBy = [\n field.description ? `${field.name}-description` : null,\n hasErrors ? `${field.name}-errors` : null,\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <input\n id={field.name}\n name={field.name}\n type=\"date\"\n className=\"forma-input forma-input--date\"\n value={field.value ?? \"\"}\n onChange={(e) => field.onChange(e.target.value || null)}\n onBlur={field.onBlur}\n disabled={field.disabled}\n readOnly={field.readonly}\n aria-invalid={hasErrors || undefined}\n aria-required={field.required || undefined}\n aria-describedby={describedBy || undefined}\n />\n );\n}\n\nexport function DateTimeInput({ field }: DateTimeComponentProps) {\n const hasErrors = field.visibleErrors.length > 0;\n const describedBy = [\n field.description ? `${field.name}-description` : null,\n hasErrors ? `${field.name}-errors` : null,\n ]\n .filter(Boolean)\n .join(\" \");\n\n // datetime-local expects \"YYYY-MM-DDTHH:mm\" format\n const inputValue = field.value ?? \"\";\n\n return (\n <input\n id={field.name}\n name={field.name}\n type=\"datetime-local\"\n className=\"forma-input forma-input--datetime\"\n value={inputValue}\n onChange={(e) => field.onChange(e.target.value || null)}\n onBlur={field.onBlur}\n disabled={field.disabled}\n readOnly={field.readonly}\n aria-invalid={hasErrors || undefined}\n aria-required={field.required || undefined}\n aria-describedby={describedBy || undefined}\n />\n );\n}\n","import React from \"react\";\nimport type { SelectComponentProps } from \"../../types.js\";\n\nexport function SelectInput({ field }: SelectComponentProps) {\n const hasErrors = field.visibleErrors.length > 0;\n const describedBy = [\n field.description ? `${field.name}-description` : null,\n hasErrors ? `${field.name}-errors` : null,\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <select\n id={field.name}\n name={field.name}\n className=\"forma-select\"\n value={field.value !== null ? String(field.value) : \"\"}\n onChange={(e) => {\n const value = e.target.value;\n if (!value) {\n field.onChange(null);\n } else {\n // Preserve string value\n field.onChange(value);\n }\n }}\n onBlur={field.onBlur}\n disabled={field.disabled}\n aria-invalid={hasErrors || undefined}\n aria-required={field.required || undefined}\n aria-describedby={describedBy || undefined}\n >\n {(!field.required || field.value === null) && (\n <option value=\"\">{field.placeholder ?? \"Select...\"}</option>\n )}\n {field.options.map((opt) => (\n <option key={String(opt.value)} value={String(opt.value)}>\n {opt.label}\n </option>\n ))}\n </select>\n );\n}\n","import React from \"react\";\nimport type { MultiSelectComponentProps } from \"../../types.js\";\n\nexport function MultiSelectInput({ field }: MultiSelectComponentProps) {\n const hasErrors = field.visibleErrors.length > 0;\n const describedBy = [\n field.description ? `${field.name}-description` : null,\n hasErrors ? `${field.name}-errors` : null,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const selected = field.value ?? [];\n\n const handleToggle = (optionValue: string) => {\n if (selected.includes(optionValue)) {\n field.onChange(selected.filter((v) => v !== optionValue));\n } else {\n field.onChange([...selected, optionValue]);\n }\n field.onBlur();\n };\n\n return (\n <fieldset\n className=\"forma-multiselect\"\n aria-describedby={describedBy || undefined}\n aria-invalid={hasErrors || undefined}\n >\n <legend className=\"forma-sr-only\">{field.label}</legend>\n {field.options.map((opt) => {\n const optId = `${field.name}-${opt.value}`;\n return (\n <div key={String(opt.value)} className=\"forma-multiselect__option\">\n <input\n id={optId}\n type=\"checkbox\"\n className=\"forma-checkbox__input\"\n checked={selected.includes(String(opt.value))}\n onChange={() => handleToggle(String(opt.value))}\n disabled={field.disabled}\n />\n <label htmlFor={optId} className=\"forma-checkbox__label\">\n {opt.label}\n </label>\n </div>\n );\n })}\n </fieldset>\n );\n}\n","import React, { useRef } from \"react\";\nimport type { ArrayComponentProps } from \"../../types.js\";\n\nexport function ArrayField({ field }: ArrayComponentProps) {\n const hasErrors = field.visibleErrors.length > 0;\n\n // Stable keys via ref-based sequential counter\n const itemKeysRef = useRef<string[]>([]);\n const nextKeyRef = useRef(0);\n\n const currentLength = field.helpers.items.length;\n const keysLength = itemKeysRef.current.length;\n\n if (currentLength > keysLength) {\n for (let i = keysLength; i < currentLength; i++) {\n itemKeysRef.current.push(`item-${nextKeyRef.current++}`);\n }\n } else if (currentLength < keysLength) {\n itemKeysRef.current.length = currentLength;\n }\n\n const fieldOrder =\n field.itemFieldOrder ?? Object.keys(field.itemFields);\n\n return (\n <div\n className=\"forma-array\"\n aria-invalid={hasErrors || undefined}\n >\n {field.helpers.items.length === 0 && (\n <p className=\"forma-array__empty\">No items</p>\n )}\n {field.helpers.items.map((_, index) => (\n <div\n key={itemKeysRef.current[index]}\n className=\"forma-array__item\"\n >\n <div className=\"forma-array__item-fields\">\n {fieldOrder.map((fieldName) => {\n const itemProps = field.helpers.getItemFieldProps(\n index,\n fieldName,\n );\n return (\n <div key={fieldName} className=\"forma-field\">\n <label\n htmlFor={itemProps.name}\n className=\"forma-label\"\n >\n {itemProps.label}\n </label>\n {renderItemField(itemProps)}\n {itemProps.errors.length > 0 && itemProps.touched && (\n <div className=\"forma-field__errors\" role=\"alert\">\n {itemProps.errors.map((err, i) => (\n <span key={i} className=\"forma-field__error\">\n {err.message}\n </span>\n ))}\n </div>\n )}\n </div>\n );\n })}\n </div>\n <button\n type=\"button\"\n className=\"forma-button forma-button--danger forma-array__remove\"\n onClick={() => field.helpers.remove(index)}\n disabled={!field.helpers.canRemove || field.disabled}\n >\n Remove\n </button>\n </div>\n ))}\n <button\n type=\"button\"\n className=\"forma-button forma-button--secondary forma-array__add\"\n onClick={() => field.helpers.push()}\n disabled={!field.helpers.canAdd || field.disabled}\n >\n + Add Item\n </button>\n </div>\n );\n}\n\nfunction renderItemField(\n itemProps: ReturnType<\n ArrayComponentProps[\"field\"][\"helpers\"][\"getItemFieldProps\"]\n >,\n) {\n const type = itemProps.type;\n\n if (type === \"select\" && itemProps.options) {\n return (\n <select\n id={itemProps.name}\n className=\"forma-select\"\n value={String(itemProps.value ?? \"\")}\n onChange={(e) => {\n const value = e.target.value;\n if (!value) {\n itemProps.onChange(null);\n } else {\n const option = itemProps.options?.find(\n (opt) => String(opt.value) === value,\n );\n itemProps.onChange(option ? option.value : value);\n }\n }}\n onBlur={itemProps.onBlur}\n disabled={!itemProps.enabled}\n >\n <option value=\"\">Select...</option>\n {itemProps.options.map((opt) => (\n <option key={String(opt.value)} value={String(opt.value)}>\n {opt.label}\n </option>\n ))}\n </select>\n );\n }\n\n if (type === \"number\" || type === \"integer\") {\n return (\n <input\n id={itemProps.name}\n type=\"number\"\n className=\"forma-input\"\n value={itemProps.value != null ? String(itemProps.value) : \"\"}\n onChange={(e) => {\n const val = e.target.value;\n if (val === \"\") {\n itemProps.onChange(null);\n } else {\n const num =\n type === \"integer\"\n ? parseInt(val, 10)\n : parseFloat(val);\n itemProps.onChange(isNaN(num) ? null : num);\n }\n }}\n onBlur={itemProps.onBlur}\n disabled={!itemProps.enabled}\n step={type === \"integer\" ? 1 : \"any\"}\n />\n );\n }\n\n if (type === \"boolean\") {\n return (\n <div className=\"forma-checkbox\">\n <input\n id={itemProps.name}\n type=\"checkbox\"\n className=\"forma-checkbox__input\"\n checked={Boolean(itemProps.value)}\n onChange={(e) => itemProps.onChange(e.target.checked)}\n onBlur={itemProps.onBlur}\n disabled={!itemProps.enabled}\n />\n <label htmlFor={itemProps.name} className=\"forma-checkbox__label\">\n {itemProps.label}\n </label>\n </div>\n );\n }\n\n // Default: text input\n return (\n <input\n id={itemProps.name}\n type=\"text\"\n className=\"forma-input\"\n value={String(itemProps.value ?? \"\")}\n onChange={(e) => itemProps.onChange(e.target.value)}\n onBlur={itemProps.onBlur}\n disabled={!itemProps.enabled}\n placeholder={itemProps.placeholder}\n />\n );\n}\n","import React from \"react\";\nimport type { ObjectComponentProps } from \"../../types.js\";\n\nexport function ObjectField({ field }: ObjectComponentProps) {\n const hasErrors = field.visibleErrors.length > 0;\n\n return (\n <fieldset\n className=\"forma-object\"\n aria-invalid={hasErrors || undefined}\n >\n <legend className=\"forma-object__legend\">{field.label}</legend>\n {field.description && (\n <p className=\"forma-object__description\">{field.description}</p>\n )}\n <div className=\"forma-object__fields\">\n {/* Object child fields are rendered by FormRenderer, not here.\n The object component is a visual container only. */}\n </div>\n </fieldset>\n );\n}\n","import React from \"react\";\nimport { formatValue } from \"@fogpipe/forma-core\";\nimport type { ComputedComponentProps } from \"../../types.js\";\n\nexport function ComputedDisplay({ field }: ComputedComponentProps) {\n let displayValue: string;\n if (field.value === null || field.value === undefined) {\n displayValue = \"\\u2014\";\n } else if (typeof field.value === \"object\") {\n try {\n displayValue = JSON.stringify(field.value);\n } catch {\n displayValue = String(field.value);\n }\n } else {\n displayValue = formatValue(field.value, field.format, field.formatOptions);\n }\n\n return (\n <output\n id={field.name}\n className=\"forma-computed\"\n >\n {displayValue}\n </output>\n );\n}\n","import React from \"react\";\nimport type { FormatOptions } from \"@fogpipe/forma-core\";\nimport { formatValue } from \"@fogpipe/forma-core\";\nimport type { DisplayComponentProps } from \"../../types.js\";\n\nconst FORMAT_DEFAULTS: FormatOptions = { nullDisplay: \"\\u2014\" };\n\nexport function DisplayField({ field }: DisplayComponentProps) {\n const options = field.formatOptions\n ? { ...FORMAT_DEFAULTS, ...field.formatOptions }\n : FORMAT_DEFAULTS;\n const content =\n field.sourceValue !== undefined\n ? formatValue(field.sourceValue, field.format, options)\n : field.content;\n\n return (\n <div className=\"forma-display\">\n {content && <p className=\"forma-display__content\">{content}</p>}\n </div>\n );\n}\n","import React from \"react\";\nimport type { MatrixComponentProps } from \"../../types.js\";\n\nexport function MatrixField({ field }: MatrixComponentProps) {\n const hasErrors = field.visibleErrors.length > 0;\n const visibleRows = field.rows.filter((r) => r.visible);\n const currentValue = field.value ?? {};\n\n const handleChange = (\n rowId: string,\n colValue: string | number,\n ) => {\n if (field.disabled) return;\n\n const next = { ...currentValue };\n if (field.multiSelect) {\n const current = (currentValue[rowId] ?? []) as string[];\n const colStr = String(colValue);\n const exists = current.includes(colStr);\n next[rowId] = exists\n ? current.filter((v) => v !== colStr)\n : [...current, colStr];\n } else {\n next[rowId] = colValue;\n }\n field.onChange(next as Record<string, string | number | string[] | number[]>);\n field.onBlur();\n };\n\n const isChecked = (\n rowId: string,\n colValue: string | number,\n ): boolean => {\n const rowValue = currentValue[rowId];\n if (rowValue === undefined || rowValue === null) return false;\n if (Array.isArray(rowValue)) {\n return (rowValue as (string | number)[]).includes(colValue);\n }\n return rowValue === colValue;\n };\n\n return (\n <div className=\"forma-matrix\" aria-invalid={hasErrors || undefined}>\n <table className=\"forma-matrix__table\" role=\"grid\">\n <thead>\n <tr>\n <th scope=\"col\" className=\"forma-matrix__corner\" />\n {field.columns.map((col) => (\n <th\n key={String(col.value)}\n scope=\"col\"\n className=\"forma-matrix__col-header\"\n >\n {col.label}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {visibleRows.map((row) => (\n <tr key={row.id} className=\"forma-matrix__row\">\n <th scope=\"row\" className=\"forma-matrix__row-header\">\n {row.label}\n </th>\n {field.columns.map((col) => {\n const cellId = `${field.name}-${row.id}-${col.value}`;\n return (\n <td key={String(col.value)} className=\"forma-matrix__cell\">\n <input\n id={cellId}\n type={field.multiSelect ? \"checkbox\" : \"radio\"}\n name={\n field.multiSelect\n ? cellId\n : `${field.name}-${row.id}`\n }\n className={\n field.multiSelect\n ? \"forma-checkbox__input\"\n : \"forma-radio__input\"\n }\n checked={isChecked(row.id, col.value)}\n onChange={() => handleChange(row.id, col.value)}\n disabled={field.disabled}\n />\n <label htmlFor={cellId} className=\"forma-sr-only\">\n {row.label}: {col.label}\n </label>\n </td>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n}\n","import React from \"react\";\nimport type { FieldComponentProps } from \"../../types.js\";\n\ndeclare const process: { env: { NODE_ENV?: string } } | undefined;\n\nexport function FallbackField({ field }: FieldComponentProps) {\n const hasErrors = field.visibleErrors.length > 0;\n const isDev =\n typeof process !== \"undefined\" && process.env.NODE_ENV !== \"production\";\n\n return (\n <div className=\"forma-fallback\">\n {isDev && (\n <p className=\"forma-fallback__warning\">\n Unknown field type: "{field.field.type}"\n </p>\n )}\n <input\n id={field.name}\n name={field.name}\n type=\"text\"\n className=\"forma-input\"\n value={String(field.value ?? \"\")}\n onChange={(e) => {\n if (\"onChange\" in field && typeof field.onChange === \"function\") {\n (field.onChange as (value: string) => void)(e.target.value);\n }\n }}\n onBlur={field.onBlur}\n disabled={field.disabled}\n aria-invalid={hasErrors || undefined}\n />\n </div>\n );\n}\n","import React from \"react\";\nimport type { FieldWrapperProps } from \"../../types.js\";\nimport { useFormaContext } from \"../../context.js\";\n\nexport function FieldWrapper({\n fieldPath,\n field,\n children,\n errors,\n touched,\n showRequiredIndicator,\n visible,\n}: FieldWrapperProps) {\n const { isSubmitted } = useFormaContext();\n\n if (!visible) return null;\n\n const shouldShowMessages = touched || isSubmitted;\n const visibleErrors = shouldShowMessages\n ? errors.filter((e) => e.severity === \"error\")\n : [];\n const visibleWarnings = shouldShowMessages\n ? errors.filter((e) => e.severity === \"warning\")\n : [];\n const hasErrors = visibleErrors.length > 0;\n const hasWarnings = visibleWarnings.length > 0;\n\n const classNames = [\n \"forma-field\",\n hasErrors && \"forma-field--error\",\n !hasErrors && hasWarnings && \"forma-field--warning\",\n showRequiredIndicator && \"forma-field--required\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div className={classNames} data-field-path={fieldPath}>\n {field.label && field.type !== \"boolean\" && (\n <label htmlFor={fieldPath} className=\"forma-label\">\n {field.label}\n {showRequiredIndicator && (\n <span className=\"forma-label__required\" aria-hidden=\"true\">\n {\" \"}\n *\n </span>\n )}\n </label>\n )}\n {field.description && (\n <div\n id={`${fieldPath}-description`}\n className=\"forma-field__description\"\n >\n {field.description}\n </div>\n )}\n {children}\n {hasErrors && (\n <div\n id={`${fieldPath}-errors`}\n className=\"forma-field__errors\"\n role=\"alert\"\n >\n {visibleErrors.map((error, i) => (\n <span key={i} className=\"forma-field__error\">\n {error.message}\n </span>\n ))}\n </div>\n )}\n {hasWarnings && (\n <div className=\"forma-field__warnings\">\n {visibleWarnings.map((warning, i) => (\n <span key={i} className=\"forma-field__warning\">\n {warning.message}\n </span>\n ))}\n </div>\n )}\n </div>\n );\n}\n","import React from \"react\";\nimport type { LayoutProps } from \"../../types.js\";\n\nexport function FormLayout({\n children,\n onSubmit,\n isSubmitting,\n}: LayoutProps) {\n return (\n <form\n className=\"forma-form\"\n onSubmit={(e) => {\n e.preventDefault();\n onSubmit();\n }}\n noValidate\n >\n {children}\n <div className=\"forma-form__actions\">\n {/* Submit is not disabled when invalid — intentional. Disabling prevents\n users from discovering which fields need attention. Instead, clicking\n submit triggers validation and displays errors via FieldWrapper. */}\n <button\n type=\"submit\"\n className={`forma-button forma-button--primary forma-submit${isSubmitting ? \" forma-submit--loading\" : \"\"}`}\n disabled={isSubmitting}\n aria-busy={isSubmitting || undefined}\n >\n {isSubmitting ? \"Submitting...\" : \"Submit\"}\n </button>\n </div>\n </form>\n );\n}\n","import React, { useCallback } from \"react\";\nimport type { LayoutProps } from \"../../types.js\";\nimport { useFormaContext } from \"../../context.js\";\n\nexport function WizardLayout({\n children,\n onSubmit,\n isSubmitting,\n}: LayoutProps) {\n const { wizard } = useFormaContext();\n\n const handleNext = useCallback(() => {\n if (!wizard) return;\n wizard.touchCurrentPageFields();\n if (wizard.validateCurrentPage()) {\n wizard.nextPage();\n }\n }, [wizard]);\n\n const handleSubmit = useCallback(\n (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n\n if (!wizard) {\n onSubmit();\n return;\n }\n\n const nativeEvent = e.nativeEvent as SubmitEvent;\n const submitter = nativeEvent.submitter as HTMLButtonElement | null;\n\n if (wizard.isLastPage && submitter?.dataset.action === \"submit\") {\n onSubmit();\n } else if (!wizard.isLastPage) {\n handleNext();\n }\n },\n [wizard, onSubmit, handleNext],\n );\n\n // Fallback to simple form layout if no wizard\n if (!wizard) {\n return (\n <form\n className=\"forma-form\"\n onSubmit={handleSubmit}\n noValidate\n >\n {children}\n <div className=\"forma-form__actions\">\n <button\n type=\"submit\"\n className=\"forma-button forma-button--primary forma-submit\"\n disabled={isSubmitting}\n aria-busy={isSubmitting || undefined}\n >\n {isSubmitting ? \"Submitting...\" : \"Submit\"}\n </button>\n </div>\n </form>\n );\n }\n\n return (\n <form className=\"forma-wizard\" onSubmit={handleSubmit} noValidate>\n {/* Step indicator */}\n <div className=\"forma-wizard__steps\" role=\"navigation\" aria-label=\"Form progress\">\n {wizard.pages.map((page, index) => {\n const isCompleted = index < wizard.currentPageIndex;\n const isCurrent = index === wizard.currentPageIndex;\n const stepClass = [\n \"forma-step\",\n isCompleted && \"forma-step--completed\",\n isCurrent && \"forma-step--current\",\n !isCompleted && !isCurrent && \"forma-step--upcoming\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div key={page.id} className={stepClass} aria-current={isCurrent ? \"step\" : undefined}>\n <span className=\"forma-step__indicator\">\n {isCompleted ? \"\\u2713\" : index + 1}\n </span>\n <span className=\"forma-step__label\">{page.title}</span>\n </div>\n );\n })}\n </div>\n\n {/* Page content */}\n {children}\n\n {/* Navigation */}\n <div className=\"forma-wizard__nav\">\n {wizard.hasPreviousPage ? (\n <button\n type=\"button\"\n className=\"forma-button forma-button--secondary\"\n onClick={() => wizard.previousPage()}\n >\n Previous\n </button>\n ) : (\n <div />\n )}\n\n {wizard.isLastPage ? (\n <button\n type=\"submit\"\n data-action=\"submit\"\n className={`forma-button forma-button--primary forma-submit${isSubmitting ? \" forma-submit--loading\" : \"\"}`}\n disabled={isSubmitting}\n aria-busy={isSubmitting || undefined}\n >\n {isSubmitting ? \"Submitting...\" : \"Submit\"}\n </button>\n ) : (\n <button\n type=\"button\"\n className=\"forma-button forma-button--primary\"\n onClick={handleNext}\n >\n Next\n </button>\n )}\n </div>\n </form>\n );\n}\n","import React from \"react\";\nimport type { PageWrapperProps } from \"../../types.js\";\n\nexport function PageWrapper({\n title,\n description,\n children,\n}: PageWrapperProps) {\n return (\n <div className=\"forma-page\">\n {title && <h2 className=\"forma-page__title\">{title}</h2>}\n {description && (\n <p className=\"forma-page__description\">{description}</p>\n )}\n {children}\n </div>\n );\n}\n","import type { ComponentMap } from \"../types.js\";\nimport { TextInput } from \"./components/TextInput.js\";\nimport { TextareaInput } from \"./components/TextareaInput.js\";\nimport { NumberInput, IntegerInput } from \"./components/NumberInput.js\";\nimport { BooleanInput } from \"./components/BooleanInput.js\";\nimport { DateInput, DateTimeInput } from \"./components/DateInput.js\";\nimport { SelectInput } from \"./components/SelectInput.js\";\nimport { MultiSelectInput } from \"./components/MultiSelectInput.js\";\nimport { ArrayField } from \"./components/ArrayField.js\";\nimport { ObjectField } from \"./components/ObjectField.js\";\nimport { ComputedDisplay } from \"./components/ComputedDisplay.js\";\nimport { DisplayField } from \"./components/DisplayField.js\";\nimport { MatrixField } from \"./components/MatrixField.js\";\nimport { FallbackField } from \"./components/FallbackField.js\";\nimport { FieldWrapper } from \"./layout/FieldWrapper.js\";\nimport { FormLayout } from \"./layout/FormLayout.js\";\nimport { WizardLayout } from \"./layout/WizardLayout.js\";\nimport { PageWrapper } from \"./layout/PageWrapper.js\";\n\nexport const defaultComponentMap: ComponentMap = {\n text: TextInput,\n email: TextInput,\n phone: TextInput,\n url: TextInput,\n password: TextInput,\n textarea: TextareaInput,\n number: NumberInput,\n integer: IntegerInput,\n boolean: BooleanInput,\n date: DateInput,\n datetime: DateTimeInput,\n select: SelectInput,\n multiselect: MultiSelectInput,\n array: ArrayField,\n object: ObjectField,\n computed: ComputedDisplay,\n display: DisplayField,\n matrix: MatrixField,\n fallback: FallbackField,\n};\n\nexport const defaultFieldWrapper = FieldWrapper;\nexport const defaultLayout = FormLayout;\nexport const defaultWizardLayout = WizardLayout;\nexport const defaultPageWrapper = PageWrapper;\n"],"mappings":"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","names":["jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","formatValue","jsx","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","DefaultFormRenderer"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { FieldError, Forma, OptionsVisibilityResult, ValidationResult } from '@fogpipe/forma-core';
|
|
2
2
|
export { ComputedField, FieldDefinition, FieldError, FieldType, Forma, PageDefinition, SelectOption, ValidationResult, ValidationRule } from '@fogpipe/forma-core';
|
|
3
|
-
import { G as GetFieldPropsResult, a as GetSelectFieldPropsResult, b as GetArrayHelpersResult, C as ComponentMap } from './FormRenderer-
|
|
4
|
-
export { v as ArrayComponentProps, A as ArrayFieldProps, j as ArrayHelpers, k as ArrayItemFieldProps, l as ArrayItemFieldPropsResult, B as BaseFieldProps, q as BooleanComponentProps, f as BooleanFieldProps, x as ComputedComponentProps, i as ComputedFieldProps, r as DateComponentProps, D as DateFieldProps, s as DateTimeComponentProps, g as DateTimeFieldProps, z as DisplayComponentProps, y as DisplayFieldProps, m as FieldComponentProps, e as FieldProps, K as FieldWrapperProps, F as FormRenderer, d as FormRendererHandle, c as FormRendererProps, p as IntegerComponentProps, I as IntegerFieldProps, J as LayoutProps, L as LegacyFieldProps, H as MatrixComponentProps, E as MatrixFieldProps, u as MultiSelectComponentProps, M as MultiSelectFieldProps, o as NumberComponentProps, N as NumberFieldProps, w as ObjectComponentProps, O as ObjectFieldProps, P as PageWrapperProps, t as SelectComponentProps, S as SelectFieldProps, h as SelectionFieldProps, n as TextComponentProps, T as TextFieldProps } from './FormRenderer-
|
|
3
|
+
import { G as GetFieldPropsResult, a as GetSelectFieldPropsResult, b as GetArrayHelpersResult, C as ComponentMap } from './FormRenderer-B7qwG4to.js';
|
|
4
|
+
export { v as ArrayComponentProps, A as ArrayFieldProps, j as ArrayHelpers, k as ArrayItemFieldProps, l as ArrayItemFieldPropsResult, B as BaseFieldProps, q as BooleanComponentProps, f as BooleanFieldProps, x as ComputedComponentProps, i as ComputedFieldProps, r as DateComponentProps, D as DateFieldProps, s as DateTimeComponentProps, g as DateTimeFieldProps, z as DisplayComponentProps, y as DisplayFieldProps, m as FieldComponentProps, e as FieldProps, K as FieldWrapperProps, F as FormRenderer, d as FormRendererHandle, c as FormRendererProps, p as IntegerComponentProps, I as IntegerFieldProps, J as LayoutProps, L as LegacyFieldProps, H as MatrixComponentProps, E as MatrixFieldProps, u as MultiSelectComponentProps, M as MultiSelectFieldProps, o as NumberComponentProps, N as NumberFieldProps, w as ObjectComponentProps, O as ObjectFieldProps, P as PageWrapperProps, t as SelectComponentProps, S as SelectFieldProps, h as SelectionFieldProps, n as TextComponentProps, T as TextFieldProps } from './FormRenderer-B7qwG4to.js';
|
|
5
5
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
6
6
|
import * as React from 'react';
|
|
7
7
|
import React__default from 'react';
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
FormaContext,
|
|
4
4
|
useForma,
|
|
5
5
|
useFormaContext
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-CFX3T5WK.js";
|
|
7
7
|
|
|
8
8
|
// src/FieldRenderer.tsx
|
|
9
9
|
import React from "react";
|
|
@@ -42,8 +42,14 @@ function FieldRenderer({
|
|
|
42
42
|
components,
|
|
43
43
|
className
|
|
44
44
|
}) {
|
|
45
|
+
var _a, _b, _c;
|
|
45
46
|
const forma = useFormaContext();
|
|
46
47
|
const { spec } = forma;
|
|
48
|
+
const resolvedFormatOptions = {
|
|
49
|
+
locale: spec.meta.locale,
|
|
50
|
+
currency: spec.meta.currency,
|
|
51
|
+
nullDisplay: "\u2014"
|
|
52
|
+
};
|
|
47
53
|
const fieldDef = spec.fields[fieldPath];
|
|
48
54
|
if (!fieldDef) {
|
|
49
55
|
console.warn(`Field not found: ${fieldPath}`);
|
|
@@ -233,6 +239,7 @@ function FieldRenderer({
|
|
|
233
239
|
};
|
|
234
240
|
} else if (fieldType === "display" && fieldDef.type === "display") {
|
|
235
241
|
const sourceValue = fieldDef.source ? forma.data[fieldDef.source] ?? forma.computed[fieldDef.source] : void 0;
|
|
242
|
+
const format = fieldDef.format ?? (fieldDef.source ? (_b = (_a = spec.computed) == null ? void 0 : _a[fieldDef.source]) == null ? void 0 : _b.format : void 0);
|
|
236
243
|
const {
|
|
237
244
|
onChange: _onChange,
|
|
238
245
|
// omit from display props
|
|
@@ -247,7 +254,24 @@ function FieldRenderer({
|
|
|
247
254
|
fieldType: "display",
|
|
248
255
|
content: fieldDef.content,
|
|
249
256
|
sourceValue,
|
|
250
|
-
format
|
|
257
|
+
format,
|
|
258
|
+
formatOptions: resolvedFormatOptions
|
|
259
|
+
};
|
|
260
|
+
} else if (fieldType === "computed" && fieldDef.type === "computed") {
|
|
261
|
+
const computedDef = (_c = spec.computed) == null ? void 0 : _c[fieldPath];
|
|
262
|
+
const {
|
|
263
|
+
onChange: _onChangeC,
|
|
264
|
+
// omit from computed props
|
|
265
|
+
...computedBaseProps
|
|
266
|
+
} = baseProps;
|
|
267
|
+
void _onChangeC;
|
|
268
|
+
fieldProps = {
|
|
269
|
+
...computedBaseProps,
|
|
270
|
+
fieldType: "computed",
|
|
271
|
+
value: forma.computed[fieldPath],
|
|
272
|
+
expression: (computedDef == null ? void 0 : computedDef.expression) ?? "",
|
|
273
|
+
format: computedDef == null ? void 0 : computedDef.format,
|
|
274
|
+
formatOptions: resolvedFormatOptions
|
|
251
275
|
};
|
|
252
276
|
} else {
|
|
253
277
|
fieldProps = {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/FieldRenderer.tsx","../src/ErrorBoundary.tsx"],"sourcesContent":["/**\n * FieldRenderer Component\n *\n * Routes a single field to the appropriate component based on its type.\n * This is useful for custom form layouts where you need field-by-field control.\n */\n\nimport React from \"react\";\nimport type {\n FieldDefinition,\n JSONSchemaProperty,\n SelectOption,\n} from \"@fogpipe/forma-core\";\nimport { isAdornableField } from \"@fogpipe/forma-core\";\nimport { useFormaContext } from \"./context.js\";\nimport type {\n ComponentMap,\n BaseFieldProps,\n TextFieldProps,\n NumberFieldProps,\n IntegerFieldProps,\n SelectFieldProps,\n MultiSelectFieldProps,\n ArrayFieldProps,\n ArrayHelpers,\n DisplayFieldProps,\n MatrixFieldProps,\n} from \"./types.js\";\n\n/**\n * Props for FieldRenderer component\n */\nexport interface FieldRendererProps {\n /** Field path (e.g., \"firstName\" or \"address.city\") */\n fieldPath: string;\n /** Component map for rendering fields */\n components: ComponentMap;\n /** Optional class name for the wrapper */\n className?: string;\n}\n\n/**\n * Extract numeric constraints from JSON Schema property\n */\nfunction getNumberConstraints(schema?: JSONSchemaProperty): {\n min?: number;\n max?: number;\n step?: number;\n} {\n if (!schema) return {};\n if (schema.type !== \"number\" && schema.type !== \"integer\") return {};\n\n // Extract min/max from schema\n const min =\n \"minimum\" in schema && typeof schema.minimum === \"number\"\n ? schema.minimum\n : undefined;\n const max =\n \"maximum\" in schema && typeof schema.maximum === \"number\"\n ? schema.maximum\n : undefined;\n\n // Use multipleOf for step if defined, otherwise default to 1 for integers\n let step: number | undefined;\n if (\"multipleOf\" in schema && typeof schema.multipleOf === \"number\") {\n step = schema.multipleOf;\n } else if (schema.type === \"integer\") {\n step = 1;\n }\n\n return { min, max, step };\n}\n\n/**\n * Create a default item for an array field based on item field definitions\n */\nfunction createDefaultItem(\n itemFields: Record<string, FieldDefinition>,\n): Record<string, unknown> {\n const item: Record<string, unknown> = {};\n for (const [fieldName, fieldDef] of Object.entries(itemFields)) {\n if (fieldDef.defaultValue !== undefined) {\n item[fieldName] = fieldDef.defaultValue;\n } else if (fieldDef.type === \"boolean\") {\n item[fieldName] = false;\n } else if (fieldDef.type === \"number\" || fieldDef.type === \"integer\") {\n item[fieldName] = null;\n } else {\n item[fieldName] = \"\";\n }\n }\n return item;\n}\n\n/**\n * FieldRenderer component\n *\n * @example\n * ```tsx\n * // Render a specific field with custom components\n * <FieldRenderer fieldPath=\"email\" components={componentMap} />\n * ```\n */\nexport function FieldRenderer({\n fieldPath,\n components,\n className,\n}: FieldRendererProps) {\n const forma = useFormaContext();\n const { spec } = forma;\n\n const fieldDef = spec.fields[fieldPath];\n if (!fieldDef) {\n console.warn(`Field not found: ${fieldPath}`);\n return null;\n }\n\n const isVisible = forma.visibility[fieldPath] !== false;\n if (!isVisible) {\n return <div data-field-path={fieldPath} hidden />;\n }\n\n // Get field type (type is required on all field definitions)\n const fieldType = fieldDef.type;\n const componentKey = fieldType as keyof ComponentMap;\n const Component = components[componentKey] || components.fallback;\n\n if (!Component) {\n console.warn(`No component found for field type: ${fieldType}`);\n return null;\n }\n\n const errors = forma.errors.filter((e) => e.field === fieldPath);\n const touched = forma.touched[fieldPath] ?? false;\n // FieldRenderer doesn't have access to validateOn (it's a FormRenderer prop),\n // so it uses the default \"blur\" behavior: show errors after touch or submit.\n const visibleErrors = touched || forma.isSubmitted ? errors : [];\n const required = forma.required[fieldPath] ?? false;\n const disabled = forma.enabled[fieldPath] === false;\n\n // Get schema property for additional constraints\n const schemaProperty = spec.schema.properties[fieldPath];\n\n // Base field props\n const isReadonly = forma.readonly[fieldPath] ?? false;\n const baseProps: BaseFieldProps = {\n name: fieldPath,\n field: fieldDef,\n value: forma.data[fieldPath],\n touched,\n required,\n disabled,\n errors,\n visibleErrors,\n onChange: (value: unknown) => forma.setFieldValue(fieldPath, value),\n onBlur: () => forma.setFieldTouched(fieldPath),\n // Convenience properties\n visible: true, // Always true since we already filtered for visibility\n enabled: !disabled,\n readonly: isReadonly,\n label: fieldDef.label ?? fieldPath,\n description: fieldDef.description,\n placeholder: fieldDef.placeholder,\n // Adorner properties (only for adornable field types)\n ...(isAdornableField(fieldDef) && {\n prefix: fieldDef.prefix,\n suffix: fieldDef.suffix,\n }),\n // Presentation variant\n variant: fieldDef.variant,\n variantConfig: fieldDef.variantConfig,\n };\n\n // Build type-specific props\n let fieldProps:\n | BaseFieldProps\n | TextFieldProps\n | NumberFieldProps\n | IntegerFieldProps\n | SelectFieldProps\n | MultiSelectFieldProps\n | ArrayFieldProps\n | DisplayFieldProps\n | MatrixFieldProps = baseProps;\n\n if (fieldType === \"number\") {\n const constraints = getNumberConstraints(schemaProperty);\n fieldProps = {\n ...baseProps,\n fieldType: \"number\",\n value: baseProps.value as number | null,\n onChange: baseProps.onChange as (value: number | null) => void,\n ...constraints,\n } as NumberFieldProps;\n } else if (fieldType === \"integer\") {\n const constraints = getNumberConstraints(schemaProperty);\n fieldProps = {\n ...baseProps,\n fieldType: \"integer\",\n value: baseProps.value as number | null,\n onChange: baseProps.onChange as (value: number | null) => void,\n min: constraints.min,\n max: constraints.max,\n } as IntegerFieldProps;\n } else if (fieldType === \"select\") {\n // Use pre-computed visible options from memoized map\n const visibleOptions = (forma.optionsVisibility[fieldPath] ??\n []) as SelectOption[];\n fieldProps = {\n ...baseProps,\n fieldType: \"select\",\n value: baseProps.value as string | null,\n onChange: baseProps.onChange as (value: string | null) => void,\n options: visibleOptions,\n } as SelectFieldProps;\n } else if (fieldType === \"multiselect\") {\n // Use pre-computed visible options from memoized map\n const visibleOptions = (forma.optionsVisibility[fieldPath] ??\n []) as SelectOption[];\n fieldProps = {\n ...baseProps,\n fieldType: \"multiselect\",\n value: (baseProps.value as string[] | undefined) ?? [],\n onChange: baseProps.onChange as (value: string[]) => void,\n options: visibleOptions,\n } as MultiSelectFieldProps;\n } else if (\n fieldType === \"array\" &&\n fieldDef.type === \"array\" &&\n fieldDef.itemFields\n ) {\n const arrayValue = (baseProps.value as unknown[] | undefined) ?? [];\n const minItems = fieldDef.minItems ?? 0;\n const maxItems = fieldDef.maxItems ?? Infinity;\n const itemFieldDefs = fieldDef.itemFields;\n\n const helpers: ArrayHelpers = {\n items: arrayValue,\n push: (item?: unknown) => {\n const newItem = item ?? createDefaultItem(itemFieldDefs);\n forma.setFieldValue(fieldPath, [...arrayValue, newItem]);\n },\n insert: (index: number, item: unknown) => {\n const newArray = [...arrayValue];\n newArray.splice(index, 0, item);\n forma.setFieldValue(fieldPath, newArray);\n },\n remove: (index: number) => {\n const newArray = [...arrayValue];\n newArray.splice(index, 1);\n forma.setFieldValue(fieldPath, newArray);\n },\n move: (from: number, to: number) => {\n const newArray = [...arrayValue];\n const [item] = newArray.splice(from, 1);\n newArray.splice(to, 0, item);\n forma.setFieldValue(fieldPath, newArray);\n },\n swap: (indexA: number, indexB: number) => {\n const newArray = [...arrayValue];\n [newArray[indexA], newArray[indexB]] = [\n newArray[indexB],\n newArray[indexA],\n ];\n forma.setFieldValue(fieldPath, newArray);\n },\n getItemFieldProps: (index: number, fieldName: string) => {\n const itemFieldDef = itemFieldDefs[fieldName];\n const itemPath = `${fieldPath}[${index}].${fieldName}`;\n const item = (arrayValue[index] as Record<string, unknown>) ?? {};\n const itemValue = item[fieldName];\n\n // Use pre-computed visible options from memoized map\n const visibleOptions = forma.optionsVisibility[itemPath] as\n | SelectOption[]\n | undefined;\n\n return {\n name: itemPath,\n value: itemValue,\n type: itemFieldDef?.type ?? \"text\",\n label: itemFieldDef?.label ?? fieldName,\n description: itemFieldDef?.description,\n placeholder: itemFieldDef?.placeholder,\n visible: true,\n enabled: !disabled,\n readonly: forma.readonly[itemPath] ?? false,\n required: itemFieldDef?.requiredWhen === \"true\",\n touched: forma.touched[itemPath] ?? false,\n errors: forma.errors.filter((e) => e.field === itemPath),\n onChange: (value: unknown) => {\n const newArray = [...arrayValue];\n const existingItem = (newArray[index] ?? {}) as Record<\n string,\n unknown\n >;\n newArray[index] = { ...existingItem, [fieldName]: value };\n forma.setFieldValue(fieldPath, newArray);\n },\n onBlur: () => forma.setFieldTouched(itemPath),\n itemIndex: index,\n fieldName,\n options: visibleOptions,\n };\n },\n minItems,\n maxItems,\n canAdd: arrayValue.length < maxItems,\n canRemove: arrayValue.length > minItems,\n };\n fieldProps = {\n ...baseProps,\n fieldType: \"array\",\n value: arrayValue,\n onChange: baseProps.onChange as (value: unknown[]) => void,\n helpers,\n itemFields: itemFieldDefs,\n itemFieldOrder: fieldDef.itemFieldOrder,\n minItems,\n maxItems,\n } as ArrayFieldProps;\n } else if (fieldType === \"matrix\" && fieldDef.type === \"matrix\") {\n // Matrix fields — compute visible rows from visibility engine\n const matrixValue =\n (baseProps.value as Record<\n string,\n string | number | string[] | number[]\n > | null) ?? null;\n const rows = fieldDef.rows.map((row) => ({\n id: row.id,\n label: row.label,\n visible: forma.visibility[`${fieldPath}.${row.id}`] !== false,\n }));\n fieldProps = {\n ...baseProps,\n fieldType: \"matrix\",\n value: matrixValue,\n onChange: baseProps.onChange as (\n value: Record<string, string | number | string[] | number[]>,\n ) => void,\n rows,\n columns: fieldDef.columns,\n multiSelect: fieldDef.multiSelect ?? false,\n } as MatrixFieldProps;\n } else if (fieldType === \"display\" && fieldDef.type === \"display\") {\n // Display fields (read-only presentation content)\n const sourceValue = fieldDef.source\n ? (forma.data[fieldDef.source] ?? forma.computed[fieldDef.source])\n : undefined;\n const {\n onChange: _onChange, // omit from display props\n value: _value, // omit from display props\n ...displayBaseProps\n } = baseProps;\n void _onChange;\n void _value;\n fieldProps = {\n ...displayBaseProps,\n fieldType: \"display\",\n content: fieldDef.content,\n sourceValue,\n format: fieldDef.format,\n } as DisplayFieldProps;\n } else {\n // Text-based fields\n fieldProps = {\n ...baseProps,\n fieldType: fieldType as\n | \"text\"\n | \"phone\"\n | \"email\"\n | \"password\"\n | \"url\"\n | \"textarea\",\n value: (baseProps.value as string) ?? \"\",\n onChange: baseProps.onChange as (value: string) => void,\n };\n }\n\n // Wrap props in { field, spec } structure for components\n const componentProps = { field: fieldProps, spec };\n const element = React.createElement(\n Component as React.ComponentType<typeof componentProps>,\n componentProps,\n );\n\n if (className) {\n return (\n <div data-field-path={fieldPath} className={className}>\n {element}\n </div>\n );\n }\n\n return <div data-field-path={fieldPath}>{element}</div>;\n}\n","/**\n * FormaErrorBoundary Component\n *\n * Error boundary for catching render errors in form components.\n * Provides graceful error handling and recovery options.\n */\n\nimport React from \"react\";\n\n/**\n * Props for FormaErrorBoundary component\n */\nexport interface FormaErrorBoundaryProps {\n /** Child components to render */\n children: React.ReactNode;\n /** Custom fallback UI to show when an error occurs */\n fallback?:\n | React.ReactNode\n | ((error: Error, reset: () => void) => React.ReactNode);\n /** Callback when an error is caught */\n onError?: (error: Error, errorInfo: React.ErrorInfo) => void;\n /** Key to reset the error boundary (change this to reset) */\n resetKey?: string | number;\n}\n\n/**\n * State for FormaErrorBoundary component\n */\ninterface FormaErrorBoundaryState {\n hasError: boolean;\n error: Error | null;\n}\n\n/**\n * Default fallback component shown when an error occurs\n */\nfunction DefaultErrorFallback({\n error,\n onReset,\n}: {\n error: Error;\n onReset: () => void;\n}) {\n return (\n <div className=\"forma-error-boundary\" role=\"alert\">\n <h3>Something went wrong</h3>\n <p>An error occurred while rendering the form.</p>\n <details>\n <summary>Error details</summary>\n <pre>{error.message}</pre>\n </details>\n <button type=\"button\" onClick={onReset}>\n Try again\n </button>\n </div>\n );\n}\n\n/**\n * Error boundary component for Forma forms\n *\n * Catches JavaScript errors in child component tree and displays\n * a fallback UI instead of crashing the entire application.\n *\n * @example\n * ```tsx\n * <FormaErrorBoundary\n * fallback={<div>Form error occurred</div>}\n * onError={(error) => logError(error)}\n * >\n * <FormRenderer spec={spec} components={components} />\n * </FormaErrorBoundary>\n * ```\n */\nexport class FormaErrorBoundary extends React.Component<\n FormaErrorBoundaryProps,\n FormaErrorBoundaryState\n> {\n constructor(props: FormaErrorBoundaryProps) {\n super(props);\n this.state = { hasError: false, error: null };\n }\n\n static getDerivedStateFromError(error: Error): FormaErrorBoundaryState {\n return { hasError: true, error };\n }\n\n componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void {\n this.props.onError?.(error, errorInfo);\n }\n\n componentDidUpdate(prevProps: FormaErrorBoundaryProps): void {\n // Reset error state when resetKey changes\n if (this.state.hasError && prevProps.resetKey !== this.props.resetKey) {\n this.setState({ hasError: false, error: null });\n }\n }\n\n reset = (): void => {\n this.setState({ hasError: false, error: null });\n };\n\n render(): React.ReactNode {\n if (this.state.hasError && this.state.error) {\n const { fallback } = this.props;\n\n if (typeof fallback === \"function\") {\n return fallback(this.state.error, this.reset);\n }\n\n if (fallback) {\n return fallback;\n }\n\n return (\n <DefaultErrorFallback error={this.state.error} onReset={this.reset} />\n );\n }\n\n return this.props.children;\n }\n}\n"],"mappings":"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","names":["React","jsx"]}
|
|
1
|
+
{"version":3,"sources":["../src/FieldRenderer.tsx","../src/ErrorBoundary.tsx"],"sourcesContent":["/**\n * FieldRenderer Component\n *\n * Routes a single field to the appropriate component based on its type.\n * This is useful for custom form layouts where you need field-by-field control.\n */\n\nimport React from \"react\";\nimport type {\n FieldDefinition,\n JSONSchemaProperty,\n SelectOption,\n FormatOptions,\n} from \"@fogpipe/forma-core\";\nimport { isAdornableField } from \"@fogpipe/forma-core\";\nimport { useFormaContext } from \"./context.js\";\nimport type {\n ComponentMap,\n BaseFieldProps,\n TextFieldProps,\n NumberFieldProps,\n IntegerFieldProps,\n SelectFieldProps,\n MultiSelectFieldProps,\n ArrayFieldProps,\n ArrayHelpers,\n DisplayFieldProps,\n ComputedFieldProps,\n MatrixFieldProps,\n} from \"./types.js\";\n\n/**\n * Props for FieldRenderer component\n */\nexport interface FieldRendererProps {\n /** Field path (e.g., \"firstName\" or \"address.city\") */\n fieldPath: string;\n /** Component map for rendering fields */\n components: ComponentMap;\n /** Optional class name for the wrapper */\n className?: string;\n}\n\n/**\n * Extract numeric constraints from JSON Schema property\n */\nfunction getNumberConstraints(schema?: JSONSchemaProperty): {\n min?: number;\n max?: number;\n step?: number;\n} {\n if (!schema) return {};\n if (schema.type !== \"number\" && schema.type !== \"integer\") return {};\n\n // Extract min/max from schema\n const min =\n \"minimum\" in schema && typeof schema.minimum === \"number\"\n ? schema.minimum\n : undefined;\n const max =\n \"maximum\" in schema && typeof schema.maximum === \"number\"\n ? schema.maximum\n : undefined;\n\n // Use multipleOf for step if defined, otherwise default to 1 for integers\n let step: number | undefined;\n if (\"multipleOf\" in schema && typeof schema.multipleOf === \"number\") {\n step = schema.multipleOf;\n } else if (schema.type === \"integer\") {\n step = 1;\n }\n\n return { min, max, step };\n}\n\n/**\n * Create a default item for an array field based on item field definitions\n */\nfunction createDefaultItem(\n itemFields: Record<string, FieldDefinition>,\n): Record<string, unknown> {\n const item: Record<string, unknown> = {};\n for (const [fieldName, fieldDef] of Object.entries(itemFields)) {\n if (fieldDef.defaultValue !== undefined) {\n item[fieldName] = fieldDef.defaultValue;\n } else if (fieldDef.type === \"boolean\") {\n item[fieldName] = false;\n } else if (fieldDef.type === \"number\" || fieldDef.type === \"integer\") {\n item[fieldName] = null;\n } else {\n item[fieldName] = \"\";\n }\n }\n return item;\n}\n\n/**\n * FieldRenderer component\n *\n * @example\n * ```tsx\n * // Render a specific field with custom components\n * <FieldRenderer fieldPath=\"email\" components={componentMap} />\n * ```\n */\nexport function FieldRenderer({\n fieldPath,\n components,\n className,\n}: FieldRendererProps) {\n const forma = useFormaContext();\n const { spec } = forma;\n\n // Resolve format options from spec.meta\n const resolvedFormatOptions: FormatOptions = {\n locale: spec.meta.locale,\n currency: spec.meta.currency,\n nullDisplay: \"—\",\n };\n\n const fieldDef = spec.fields[fieldPath];\n if (!fieldDef) {\n console.warn(`Field not found: ${fieldPath}`);\n return null;\n }\n\n const isVisible = forma.visibility[fieldPath] !== false;\n if (!isVisible) {\n return <div data-field-path={fieldPath} hidden />;\n }\n\n // Get field type (type is required on all field definitions)\n const fieldType = fieldDef.type;\n const componentKey = fieldType as keyof ComponentMap;\n const Component = components[componentKey] || components.fallback;\n\n if (!Component) {\n console.warn(`No component found for field type: ${fieldType}`);\n return null;\n }\n\n const errors = forma.errors.filter((e) => e.field === fieldPath);\n const touched = forma.touched[fieldPath] ?? false;\n // FieldRenderer doesn't have access to validateOn (it's a FormRenderer prop),\n // so it uses the default \"blur\" behavior: show errors after touch or submit.\n const visibleErrors = touched || forma.isSubmitted ? errors : [];\n const required = forma.required[fieldPath] ?? false;\n const disabled = forma.enabled[fieldPath] === false;\n\n // Get schema property for additional constraints\n const schemaProperty = spec.schema.properties[fieldPath];\n\n // Base field props\n const isReadonly = forma.readonly[fieldPath] ?? false;\n const baseProps: BaseFieldProps = {\n name: fieldPath,\n field: fieldDef,\n value: forma.data[fieldPath],\n touched,\n required,\n disabled,\n errors,\n visibleErrors,\n onChange: (value: unknown) => forma.setFieldValue(fieldPath, value),\n onBlur: () => forma.setFieldTouched(fieldPath),\n // Convenience properties\n visible: true, // Always true since we already filtered for visibility\n enabled: !disabled,\n readonly: isReadonly,\n label: fieldDef.label ?? fieldPath,\n description: fieldDef.description,\n placeholder: fieldDef.placeholder,\n // Adorner properties (only for adornable field types)\n ...(isAdornableField(fieldDef) && {\n prefix: fieldDef.prefix,\n suffix: fieldDef.suffix,\n }),\n // Presentation variant\n variant: fieldDef.variant,\n variantConfig: fieldDef.variantConfig,\n };\n\n // Build type-specific props\n let fieldProps:\n | BaseFieldProps\n | TextFieldProps\n | NumberFieldProps\n | IntegerFieldProps\n | SelectFieldProps\n | MultiSelectFieldProps\n | ArrayFieldProps\n | DisplayFieldProps\n | ComputedFieldProps\n | MatrixFieldProps = baseProps;\n\n if (fieldType === \"number\") {\n const constraints = getNumberConstraints(schemaProperty);\n fieldProps = {\n ...baseProps,\n fieldType: \"number\",\n value: baseProps.value as number | null,\n onChange: baseProps.onChange as (value: number | null) => void,\n ...constraints,\n } as NumberFieldProps;\n } else if (fieldType === \"integer\") {\n const constraints = getNumberConstraints(schemaProperty);\n fieldProps = {\n ...baseProps,\n fieldType: \"integer\",\n value: baseProps.value as number | null,\n onChange: baseProps.onChange as (value: number | null) => void,\n min: constraints.min,\n max: constraints.max,\n } as IntegerFieldProps;\n } else if (fieldType === \"select\") {\n // Use pre-computed visible options from memoized map\n const visibleOptions = (forma.optionsVisibility[fieldPath] ??\n []) as SelectOption[];\n fieldProps = {\n ...baseProps,\n fieldType: \"select\",\n value: baseProps.value as string | null,\n onChange: baseProps.onChange as (value: string | null) => void,\n options: visibleOptions,\n } as SelectFieldProps;\n } else if (fieldType === \"multiselect\") {\n // Use pre-computed visible options from memoized map\n const visibleOptions = (forma.optionsVisibility[fieldPath] ??\n []) as SelectOption[];\n fieldProps = {\n ...baseProps,\n fieldType: \"multiselect\",\n value: (baseProps.value as string[] | undefined) ?? [],\n onChange: baseProps.onChange as (value: string[]) => void,\n options: visibleOptions,\n } as MultiSelectFieldProps;\n } else if (\n fieldType === \"array\" &&\n fieldDef.type === \"array\" &&\n fieldDef.itemFields\n ) {\n const arrayValue = (baseProps.value as unknown[] | undefined) ?? [];\n const minItems = fieldDef.minItems ?? 0;\n const maxItems = fieldDef.maxItems ?? Infinity;\n const itemFieldDefs = fieldDef.itemFields;\n\n const helpers: ArrayHelpers = {\n items: arrayValue,\n push: (item?: unknown) => {\n const newItem = item ?? createDefaultItem(itemFieldDefs);\n forma.setFieldValue(fieldPath, [...arrayValue, newItem]);\n },\n insert: (index: number, item: unknown) => {\n const newArray = [...arrayValue];\n newArray.splice(index, 0, item);\n forma.setFieldValue(fieldPath, newArray);\n },\n remove: (index: number) => {\n const newArray = [...arrayValue];\n newArray.splice(index, 1);\n forma.setFieldValue(fieldPath, newArray);\n },\n move: (from: number, to: number) => {\n const newArray = [...arrayValue];\n const [item] = newArray.splice(from, 1);\n newArray.splice(to, 0, item);\n forma.setFieldValue(fieldPath, newArray);\n },\n swap: (indexA: number, indexB: number) => {\n const newArray = [...arrayValue];\n [newArray[indexA], newArray[indexB]] = [\n newArray[indexB],\n newArray[indexA],\n ];\n forma.setFieldValue(fieldPath, newArray);\n },\n getItemFieldProps: (index: number, fieldName: string) => {\n const itemFieldDef = itemFieldDefs[fieldName];\n const itemPath = `${fieldPath}[${index}].${fieldName}`;\n const item = (arrayValue[index] as Record<string, unknown>) ?? {};\n const itemValue = item[fieldName];\n\n // Use pre-computed visible options from memoized map\n const visibleOptions = forma.optionsVisibility[itemPath] as\n | SelectOption[]\n | undefined;\n\n return {\n name: itemPath,\n value: itemValue,\n type: itemFieldDef?.type ?? \"text\",\n label: itemFieldDef?.label ?? fieldName,\n description: itemFieldDef?.description,\n placeholder: itemFieldDef?.placeholder,\n visible: true,\n enabled: !disabled,\n readonly: forma.readonly[itemPath] ?? false,\n required: itemFieldDef?.requiredWhen === \"true\",\n touched: forma.touched[itemPath] ?? false,\n errors: forma.errors.filter((e) => e.field === itemPath),\n onChange: (value: unknown) => {\n const newArray = [...arrayValue];\n const existingItem = (newArray[index] ?? {}) as Record<\n string,\n unknown\n >;\n newArray[index] = { ...existingItem, [fieldName]: value };\n forma.setFieldValue(fieldPath, newArray);\n },\n onBlur: () => forma.setFieldTouched(itemPath),\n itemIndex: index,\n fieldName,\n options: visibleOptions,\n };\n },\n minItems,\n maxItems,\n canAdd: arrayValue.length < maxItems,\n canRemove: arrayValue.length > minItems,\n };\n fieldProps = {\n ...baseProps,\n fieldType: \"array\",\n value: arrayValue,\n onChange: baseProps.onChange as (value: unknown[]) => void,\n helpers,\n itemFields: itemFieldDefs,\n itemFieldOrder: fieldDef.itemFieldOrder,\n minItems,\n maxItems,\n } as ArrayFieldProps;\n } else if (fieldType === \"matrix\" && fieldDef.type === \"matrix\") {\n // Matrix fields — compute visible rows from visibility engine\n const matrixValue =\n (baseProps.value as Record<\n string,\n string | number | string[] | number[]\n > | null) ?? null;\n const rows = fieldDef.rows.map((row) => ({\n id: row.id,\n label: row.label,\n visible: forma.visibility[`${fieldPath}.${row.id}`] !== false,\n }));\n fieldProps = {\n ...baseProps,\n fieldType: \"matrix\",\n value: matrixValue,\n onChange: baseProps.onChange as (\n value: Record<string, string | number | string[] | number[]>,\n ) => void,\n rows,\n columns: fieldDef.columns,\n multiSelect: fieldDef.multiSelect ?? false,\n } as MatrixFieldProps;\n } else if (fieldType === \"display\" && fieldDef.type === \"display\") {\n // Display fields (read-only presentation content)\n const sourceValue = fieldDef.source\n ? (forma.data[fieldDef.source] ?? forma.computed[fieldDef.source])\n : undefined;\n // Resolve format: display field's own format takes priority,\n // fall back to the source computed field's format\n const format =\n fieldDef.format ??\n (fieldDef.source ? spec.computed?.[fieldDef.source]?.format : undefined);\n const {\n onChange: _onChange, // omit from display props\n value: _value, // omit from display props\n ...displayBaseProps\n } = baseProps;\n void _onChange;\n void _value;\n fieldProps = {\n ...displayBaseProps,\n fieldType: \"display\",\n content: fieldDef.content,\n sourceValue,\n format,\n formatOptions: resolvedFormatOptions,\n } as DisplayFieldProps;\n } else if (fieldType === \"computed\" && fieldDef.type === \"computed\") {\n // Computed fields (read-only calculated values)\n const computedDef = spec.computed?.[fieldPath];\n const {\n onChange: _onChangeC, // omit from computed props\n ...computedBaseProps\n } = baseProps;\n void _onChangeC;\n fieldProps = {\n ...computedBaseProps,\n fieldType: \"computed\",\n value: forma.computed[fieldPath],\n expression: computedDef?.expression ?? \"\",\n format: computedDef?.format,\n formatOptions: resolvedFormatOptions,\n } as ComputedFieldProps;\n } else {\n // Text-based fields\n fieldProps = {\n ...baseProps,\n fieldType: fieldType as\n | \"text\"\n | \"phone\"\n | \"email\"\n | \"password\"\n | \"url\"\n | \"textarea\",\n value: (baseProps.value as string) ?? \"\",\n onChange: baseProps.onChange as (value: string) => void,\n };\n }\n\n // Wrap props in { field, spec } structure for components\n const componentProps = { field: fieldProps, spec };\n const element = React.createElement(\n Component as React.ComponentType<typeof componentProps>,\n componentProps,\n );\n\n if (className) {\n return (\n <div data-field-path={fieldPath} className={className}>\n {element}\n </div>\n );\n }\n\n return <div data-field-path={fieldPath}>{element}</div>;\n}\n","/**\n * FormaErrorBoundary Component\n *\n * Error boundary for catching render errors in form components.\n * Provides graceful error handling and recovery options.\n */\n\nimport React from \"react\";\n\n/**\n * Props for FormaErrorBoundary component\n */\nexport interface FormaErrorBoundaryProps {\n /** Child components to render */\n children: React.ReactNode;\n /** Custom fallback UI to show when an error occurs */\n fallback?:\n | React.ReactNode\n | ((error: Error, reset: () => void) => React.ReactNode);\n /** Callback when an error is caught */\n onError?: (error: Error, errorInfo: React.ErrorInfo) => void;\n /** Key to reset the error boundary (change this to reset) */\n resetKey?: string | number;\n}\n\n/**\n * State for FormaErrorBoundary component\n */\ninterface FormaErrorBoundaryState {\n hasError: boolean;\n error: Error | null;\n}\n\n/**\n * Default fallback component shown when an error occurs\n */\nfunction DefaultErrorFallback({\n error,\n onReset,\n}: {\n error: Error;\n onReset: () => void;\n}) {\n return (\n <div className=\"forma-error-boundary\" role=\"alert\">\n <h3>Something went wrong</h3>\n <p>An error occurred while rendering the form.</p>\n <details>\n <summary>Error details</summary>\n <pre>{error.message}</pre>\n </details>\n <button type=\"button\" onClick={onReset}>\n Try again\n </button>\n </div>\n );\n}\n\n/**\n * Error boundary component for Forma forms\n *\n * Catches JavaScript errors in child component tree and displays\n * a fallback UI instead of crashing the entire application.\n *\n * @example\n * ```tsx\n * <FormaErrorBoundary\n * fallback={<div>Form error occurred</div>}\n * onError={(error) => logError(error)}\n * >\n * <FormRenderer spec={spec} components={components} />\n * </FormaErrorBoundary>\n * ```\n */\nexport class FormaErrorBoundary extends React.Component<\n FormaErrorBoundaryProps,\n FormaErrorBoundaryState\n> {\n constructor(props: FormaErrorBoundaryProps) {\n super(props);\n this.state = { hasError: false, error: null };\n }\n\n static getDerivedStateFromError(error: Error): FormaErrorBoundaryState {\n return { hasError: true, error };\n }\n\n componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void {\n this.props.onError?.(error, errorInfo);\n }\n\n componentDidUpdate(prevProps: FormaErrorBoundaryProps): void {\n // Reset error state when resetKey changes\n if (this.state.hasError && prevProps.resetKey !== this.props.resetKey) {\n this.setState({ hasError: false, error: null });\n }\n }\n\n reset = (): void => {\n this.setState({ hasError: false, error: null });\n };\n\n render(): React.ReactNode {\n if (this.state.hasError && this.state.error) {\n const { fallback } = this.props;\n\n if (typeof fallback === \"function\") {\n return fallback(this.state.error, this.reset);\n }\n\n if (fallback) {\n return fallback;\n }\n\n return (\n <DefaultErrorFallback error={this.state.error} onReset={this.reset} />\n );\n }\n\n return this.props.children;\n }\n}\n"],"mappings":";;;;;;;;AAOA,OAAO,WAAW;AAOlB,SAAS,wBAAwB;AAkHtB;AAlFX,SAAS,qBAAqB,QAI5B;AACA,MAAI,CAAC,OAAQ,QAAO,CAAC;AACrB,MAAI,OAAO,SAAS,YAAY,OAAO,SAAS,UAAW,QAAO,CAAC;AAGnE,QAAM,MACJ,aAAa,UAAU,OAAO,OAAO,YAAY,WAC7C,OAAO,UACP;AACN,QAAM,MACJ,aAAa,UAAU,OAAO,OAAO,YAAY,WAC7C,OAAO,UACP;AAGN,MAAI;AACJ,MAAI,gBAAgB,UAAU,OAAO,OAAO,eAAe,UAAU;AACnE,WAAO,OAAO;AAAA,EAChB,WAAW,OAAO,SAAS,WAAW;AACpC,WAAO;AAAA,EACT;AAEA,SAAO,EAAE,KAAK,KAAK,KAAK;AAC1B;AAKA,SAAS,kBACP,YACyB;AACzB,QAAM,OAAgC,CAAC;AACvC,aAAW,CAAC,WAAW,QAAQ,KAAK,OAAO,QAAQ,UAAU,GAAG;AAC9D,QAAI,SAAS,iBAAiB,QAAW;AACvC,WAAK,SAAS,IAAI,SAAS;AAAA,IAC7B,WAAW,SAAS,SAAS,WAAW;AACtC,WAAK,SAAS,IAAI;AAAA,IACpB,WAAW,SAAS,SAAS,YAAY,SAAS,SAAS,WAAW;AACpE,WAAK,SAAS,IAAI;AAAA,IACpB,OAAO;AACL,WAAK,SAAS,IAAI;AAAA,IACpB;AAAA,EACF;AACA,SAAO;AACT;AAWO,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AACF,GAAuB;AA7GvB;AA8GE,QAAM,QAAQ,gBAAgB;AAC9B,QAAM,EAAE,KAAK,IAAI;AAGjB,QAAM,wBAAuC;AAAA,IAC3C,QAAQ,KAAK,KAAK;AAAA,IAClB,UAAU,KAAK,KAAK;AAAA,IACpB,aAAa;AAAA,EACf;AAEA,QAAM,WAAW,KAAK,OAAO,SAAS;AACtC,MAAI,CAAC,UAAU;AACb,YAAQ,KAAK,oBAAoB,SAAS,EAAE;AAC5C,WAAO;AAAA,EACT;AAEA,QAAM,YAAY,MAAM,WAAW,SAAS,MAAM;AAClD,MAAI,CAAC,WAAW;AACd,WAAO,oBAAC,SAAI,mBAAiB,WAAW,QAAM,MAAC;AAAA,EACjD;AAGA,QAAM,YAAY,SAAS;AAC3B,QAAM,eAAe;AACrB,QAAM,YAAY,WAAW,YAAY,KAAK,WAAW;AAEzD,MAAI,CAAC,WAAW;AACd,YAAQ,KAAK,sCAAsC,SAAS,EAAE;AAC9D,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,MAAM,OAAO,OAAO,CAAC,MAAM,EAAE,UAAU,SAAS;AAC/D,QAAM,UAAU,MAAM,QAAQ,SAAS,KAAK;AAG5C,QAAM,gBAAgB,WAAW,MAAM,cAAc,SAAS,CAAC;AAC/D,QAAM,WAAW,MAAM,SAAS,SAAS,KAAK;AAC9C,QAAM,WAAW,MAAM,QAAQ,SAAS,MAAM;AAG9C,QAAM,iBAAiB,KAAK,OAAO,WAAW,SAAS;AAGvD,QAAM,aAAa,MAAM,SAAS,SAAS,KAAK;AAChD,QAAM,YAA4B;AAAA,IAChC,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO,MAAM,KAAK,SAAS;AAAA,IAC3B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU,CAAC,UAAmB,MAAM,cAAc,WAAW,KAAK;AAAA,IAClE,QAAQ,MAAM,MAAM,gBAAgB,SAAS;AAAA;AAAA,IAE7C,SAAS;AAAA;AAAA,IACT,SAAS,CAAC;AAAA,IACV,UAAU;AAAA,IACV,OAAO,SAAS,SAAS;AAAA,IACzB,aAAa,SAAS;AAAA,IACtB,aAAa,SAAS;AAAA;AAAA,IAEtB,GAAI,iBAAiB,QAAQ,KAAK;AAAA,MAChC,QAAQ,SAAS;AAAA,MACjB,QAAQ,SAAS;AAAA,IACnB;AAAA;AAAA,IAEA,SAAS,SAAS;AAAA,IAClB,eAAe,SAAS;AAAA,EAC1B;AAGA,MAAI,aAUmB;AAEvB,MAAI,cAAc,UAAU;AAC1B,UAAM,cAAc,qBAAqB,cAAc;AACvD,iBAAa;AAAA,MACX,GAAG;AAAA,MACH,WAAW;AAAA,MACX,OAAO,UAAU;AAAA,MACjB,UAAU,UAAU;AAAA,MACpB,GAAG;AAAA,IACL;AAAA,EACF,WAAW,cAAc,WAAW;AAClC,UAAM,cAAc,qBAAqB,cAAc;AACvD,iBAAa;AAAA,MACX,GAAG;AAAA,MACH,WAAW;AAAA,MACX,OAAO,UAAU;AAAA,MACjB,UAAU,UAAU;AAAA,MACpB,KAAK,YAAY;AAAA,MACjB,KAAK,YAAY;AAAA,IACnB;AAAA,EACF,WAAW,cAAc,UAAU;AAEjC,UAAM,iBAAkB,MAAM,kBAAkB,SAAS,KACvD,CAAC;AACH,iBAAa;AAAA,MACX,GAAG;AAAA,MACH,WAAW;AAAA,MACX,OAAO,UAAU;AAAA,MACjB,UAAU,UAAU;AAAA,MACpB,SAAS;AAAA,IACX;AAAA,EACF,WAAW,cAAc,eAAe;AAEtC,UAAM,iBAAkB,MAAM,kBAAkB,SAAS,KACvD,CAAC;AACH,iBAAa;AAAA,MACX,GAAG;AAAA,MACH,WAAW;AAAA,MACX,OAAQ,UAAU,SAAkC,CAAC;AAAA,MACrD,UAAU,UAAU;AAAA,MACpB,SAAS;AAAA,IACX;AAAA,EACF,WACE,cAAc,WACd,SAAS,SAAS,WAClB,SAAS,YACT;AACA,UAAM,aAAc,UAAU,SAAmC,CAAC;AAClE,UAAM,WAAW,SAAS,YAAY;AACtC,UAAM,WAAW,SAAS,YAAY;AACtC,UAAM,gBAAgB,SAAS;AAE/B,UAAM,UAAwB;AAAA,MAC5B,OAAO;AAAA,MACP,MAAM,CAAC,SAAmB;AACxB,cAAM,UAAU,QAAQ,kBAAkB,aAAa;AACvD,cAAM,cAAc,WAAW,CAAC,GAAG,YAAY,OAAO,CAAC;AAAA,MACzD;AAAA,MACA,QAAQ,CAAC,OAAe,SAAkB;AACxC,cAAM,WAAW,CAAC,GAAG,UAAU;AAC/B,iBAAS,OAAO,OAAO,GAAG,IAAI;AAC9B,cAAM,cAAc,WAAW,QAAQ;AAAA,MACzC;AAAA,MACA,QAAQ,CAAC,UAAkB;AACzB,cAAM,WAAW,CAAC,GAAG,UAAU;AAC/B,iBAAS,OAAO,OAAO,CAAC;AACxB,cAAM,cAAc,WAAW,QAAQ;AAAA,MACzC;AAAA,MACA,MAAM,CAAC,MAAc,OAAe;AAClC,cAAM,WAAW,CAAC,GAAG,UAAU;AAC/B,cAAM,CAAC,IAAI,IAAI,SAAS,OAAO,MAAM,CAAC;AACtC,iBAAS,OAAO,IAAI,GAAG,IAAI;AAC3B,cAAM,cAAc,WAAW,QAAQ;AAAA,MACzC;AAAA,MACA,MAAM,CAAC,QAAgB,WAAmB;AACxC,cAAM,WAAW,CAAC,GAAG,UAAU;AAC/B,SAAC,SAAS,MAAM,GAAG,SAAS,MAAM,CAAC,IAAI;AAAA,UACrC,SAAS,MAAM;AAAA,UACf,SAAS,MAAM;AAAA,QACjB;AACA,cAAM,cAAc,WAAW,QAAQ;AAAA,MACzC;AAAA,MACA,mBAAmB,CAAC,OAAe,cAAsB;AACvD,cAAM,eAAe,cAAc,SAAS;AAC5C,cAAM,WAAW,GAAG,SAAS,IAAI,KAAK,KAAK,SAAS;AACpD,cAAM,OAAQ,WAAW,KAAK,KAAiC,CAAC;AAChE,cAAM,YAAY,KAAK,SAAS;AAGhC,cAAM,iBAAiB,MAAM,kBAAkB,QAAQ;AAIvD,eAAO;AAAA,UACL,MAAM;AAAA,UACN,OAAO;AAAA,UACP,OAAM,6CAAc,SAAQ;AAAA,UAC5B,QAAO,6CAAc,UAAS;AAAA,UAC9B,aAAa,6CAAc;AAAA,UAC3B,aAAa,6CAAc;AAAA,UAC3B,SAAS;AAAA,UACT,SAAS,CAAC;AAAA,UACV,UAAU,MAAM,SAAS,QAAQ,KAAK;AAAA,UACtC,WAAU,6CAAc,kBAAiB;AAAA,UACzC,SAAS,MAAM,QAAQ,QAAQ,KAAK;AAAA,UACpC,QAAQ,MAAM,OAAO,OAAO,CAAC,MAAM,EAAE,UAAU,QAAQ;AAAA,UACvD,UAAU,CAAC,UAAmB;AAC5B,kBAAM,WAAW,CAAC,GAAG,UAAU;AAC/B,kBAAM,eAAgB,SAAS,KAAK,KAAK,CAAC;AAI1C,qBAAS,KAAK,IAAI,EAAE,GAAG,cAAc,CAAC,SAAS,GAAG,MAAM;AACxD,kBAAM,cAAc,WAAW,QAAQ;AAAA,UACzC;AAAA,UACA,QAAQ,MAAM,MAAM,gBAAgB,QAAQ;AAAA,UAC5C,WAAW;AAAA,UACX;AAAA,UACA,SAAS;AAAA,QACX;AAAA,MACF;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ,WAAW,SAAS;AAAA,MAC5B,WAAW,WAAW,SAAS;AAAA,IACjC;AACA,iBAAa;AAAA,MACX,GAAG;AAAA,MACH,WAAW;AAAA,MACX,OAAO;AAAA,MACP,UAAU,UAAU;AAAA,MACpB;AAAA,MACA,YAAY;AAAA,MACZ,gBAAgB,SAAS;AAAA,MACzB;AAAA,MACA;AAAA,IACF;AAAA,EACF,WAAW,cAAc,YAAY,SAAS,SAAS,UAAU;AAE/D,UAAM,cACH,UAAU,SAGE;AACf,UAAM,OAAO,SAAS,KAAK,IAAI,CAAC,SAAS;AAAA,MACvC,IAAI,IAAI;AAAA,MACR,OAAO,IAAI;AAAA,MACX,SAAS,MAAM,WAAW,GAAG,SAAS,IAAI,IAAI,EAAE,EAAE,MAAM;AAAA,IAC1D,EAAE;AACF,iBAAa;AAAA,MACX,GAAG;AAAA,MACH,WAAW;AAAA,MACX,OAAO;AAAA,MACP,UAAU,UAAU;AAAA,MAGpB;AAAA,MACA,SAAS,SAAS;AAAA,MAClB,aAAa,SAAS,eAAe;AAAA,IACvC;AAAA,EACF,WAAW,cAAc,aAAa,SAAS,SAAS,WAAW;AAEjE,UAAM,cAAc,SAAS,SACxB,MAAM,KAAK,SAAS,MAAM,KAAK,MAAM,SAAS,SAAS,MAAM,IAC9D;AAGJ,UAAM,SACJ,SAAS,WACR,SAAS,UAAS,gBAAK,aAAL,mBAAgB,SAAS,YAAzB,mBAAkC,SAAS;AAChE,UAAM;AAAA,MACJ,UAAU;AAAA;AAAA,MACV,OAAO;AAAA;AAAA,MACP,GAAG;AAAA,IACL,IAAI;AACJ,SAAK;AACL,SAAK;AACL,iBAAa;AAAA,MACX,GAAG;AAAA,MACH,WAAW;AAAA,MACX,SAAS,SAAS;AAAA,MAClB;AAAA,MACA;AAAA,MACA,eAAe;AAAA,IACjB;AAAA,EACF,WAAW,cAAc,cAAc,SAAS,SAAS,YAAY;AAEnE,UAAM,eAAc,UAAK,aAAL,mBAAgB;AACpC,UAAM;AAAA,MACJ,UAAU;AAAA;AAAA,MACV,GAAG;AAAA,IACL,IAAI;AACJ,SAAK;AACL,iBAAa;AAAA,MACX,GAAG;AAAA,MACH,WAAW;AAAA,MACX,OAAO,MAAM,SAAS,SAAS;AAAA,MAC/B,aAAY,2CAAa,eAAc;AAAA,MACvC,QAAQ,2CAAa;AAAA,MACrB,eAAe;AAAA,IACjB;AAAA,EACF,OAAO;AAEL,iBAAa;AAAA,MACX,GAAG;AAAA,MACH;AAAA,MAOA,OAAQ,UAAU,SAAoB;AAAA,MACtC,UAAU,UAAU;AAAA,IACtB;AAAA,EACF;AAGA,QAAM,iBAAiB,EAAE,OAAO,YAAY,KAAK;AACjD,QAAM,UAAU,MAAM;AAAA,IACpB;AAAA,IACA;AAAA,EACF;AAEA,MAAI,WAAW;AACb,WACE,oBAAC,SAAI,mBAAiB,WAAW,WAC9B,mBACH;AAAA,EAEJ;AAEA,SAAO,oBAAC,SAAI,mBAAiB,WAAY,mBAAQ;AACnD;;;ACpaA,OAAOA,YAAW;AAsCZ,gBAAAC,MAEA,YAFA;AATN,SAAS,qBAAqB;AAAA,EAC5B;AAAA,EACA;AACF,GAGG;AACD,SACE,qBAAC,SAAI,WAAU,wBAAuB,MAAK,SACzC;AAAA,oBAAAA,KAAC,QAAG,kCAAoB;AAAA,IACxB,gBAAAA,KAAC,OAAE,yDAA2C;AAAA,IAC9C,qBAAC,aACC;AAAA,sBAAAA,KAAC,aAAQ,2BAAa;AAAA,MACtB,gBAAAA,KAAC,SAAK,gBAAM,SAAQ;AAAA,OACtB;AAAA,IACA,gBAAAA,KAAC,YAAO,MAAK,UAAS,SAAS,SAAS,uBAExC;AAAA,KACF;AAEJ;AAkBO,IAAM,qBAAN,cAAiCD,OAAM,UAG5C;AAAA,EACA,YAAY,OAAgC;AAC1C,UAAM,KAAK;AACX,SAAK,QAAQ,EAAE,UAAU,OAAO,OAAO,KAAK;AAAA,EAC9C;AAAA,EAEA,OAAO,yBAAyB,OAAuC;AACrE,WAAO,EAAE,UAAU,MAAM,MAAM;AAAA,EACjC;AAAA,EAEA,kBAAkB,OAAc,WAAkC;AAvFpE;AAwFI,qBAAK,OAAM,YAAX,4BAAqB,OAAO;AAAA,EAC9B;AAAA,EAEA,mBAAmB,WAA0C;AAE3D,QAAI,KAAK,MAAM,YAAY,UAAU,aAAa,KAAK,MAAM,UAAU;AACrE,WAAK,SAAS,EAAE,UAAU,OAAO,OAAO,KAAK,CAAC;AAAA,IAChD;AAAA,EACF;AAAA,EAEA,QAAQ,MAAY;AAClB,SAAK,SAAS,EAAE,UAAU,OAAO,OAAO,KAAK,CAAC;AAAA,EAChD;AAAA,EAEA,SAA0B;AACxB,QAAI,KAAK,MAAM,YAAY,KAAK,MAAM,OAAO;AAC3C,YAAM,EAAE,SAAS,IAAI,KAAK;AAE1B,UAAI,OAAO,aAAa,YAAY;AAClC,eAAO,SAAS,KAAK,MAAM,OAAO,KAAK,KAAK;AAAA,MAC9C;AAEA,UAAI,UAAU;AACZ,eAAO;AAAA,MACT;AAEA,aACE,gBAAAC,KAAC,wBAAqB,OAAO,KAAK,MAAM,OAAO,SAAS,KAAK,OAAO;AAAA,IAExE;AAEA,WAAO,KAAK,MAAM;AAAA,EACpB;AACF;","names":["React","jsx"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fogpipe/forma-react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.1",
|
|
4
4
|
"description": "Headless React form renderer for Forma specifications",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"test:coverage": "vitest run --coverage"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@fogpipe/forma-core": "^0.
|
|
51
|
+
"@fogpipe/forma-core": "^0.19.1"
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|
|
54
54
|
"react": "^18.0.0 || ^19.0.0"
|
package/src/FieldRenderer.tsx
CHANGED
|
@@ -10,6 +10,7 @@ import type {
|
|
|
10
10
|
FieldDefinition,
|
|
11
11
|
JSONSchemaProperty,
|
|
12
12
|
SelectOption,
|
|
13
|
+
FormatOptions,
|
|
13
14
|
} from "@fogpipe/forma-core";
|
|
14
15
|
import { isAdornableField } from "@fogpipe/forma-core";
|
|
15
16
|
import { useFormaContext } from "./context.js";
|
|
@@ -24,6 +25,7 @@ import type {
|
|
|
24
25
|
ArrayFieldProps,
|
|
25
26
|
ArrayHelpers,
|
|
26
27
|
DisplayFieldProps,
|
|
28
|
+
ComputedFieldProps,
|
|
27
29
|
MatrixFieldProps,
|
|
28
30
|
} from "./types.js";
|
|
29
31
|
|
|
@@ -109,6 +111,13 @@ export function FieldRenderer({
|
|
|
109
111
|
const forma = useFormaContext();
|
|
110
112
|
const { spec } = forma;
|
|
111
113
|
|
|
114
|
+
// Resolve format options from spec.meta
|
|
115
|
+
const resolvedFormatOptions: FormatOptions = {
|
|
116
|
+
locale: spec.meta.locale,
|
|
117
|
+
currency: spec.meta.currency,
|
|
118
|
+
nullDisplay: "—",
|
|
119
|
+
};
|
|
120
|
+
|
|
112
121
|
const fieldDef = spec.fields[fieldPath];
|
|
113
122
|
if (!fieldDef) {
|
|
114
123
|
console.warn(`Field not found: ${fieldPath}`);
|
|
@@ -181,6 +190,7 @@ export function FieldRenderer({
|
|
|
181
190
|
| MultiSelectFieldProps
|
|
182
191
|
| ArrayFieldProps
|
|
183
192
|
| DisplayFieldProps
|
|
193
|
+
| ComputedFieldProps
|
|
184
194
|
| MatrixFieldProps = baseProps;
|
|
185
195
|
|
|
186
196
|
if (fieldType === "number") {
|
|
@@ -347,6 +357,11 @@ export function FieldRenderer({
|
|
|
347
357
|
const sourceValue = fieldDef.source
|
|
348
358
|
? (forma.data[fieldDef.source] ?? forma.computed[fieldDef.source])
|
|
349
359
|
: undefined;
|
|
360
|
+
// Resolve format: display field's own format takes priority,
|
|
361
|
+
// fall back to the source computed field's format
|
|
362
|
+
const format =
|
|
363
|
+
fieldDef.format ??
|
|
364
|
+
(fieldDef.source ? spec.computed?.[fieldDef.source]?.format : undefined);
|
|
350
365
|
const {
|
|
351
366
|
onChange: _onChange, // omit from display props
|
|
352
367
|
value: _value, // omit from display props
|
|
@@ -359,8 +374,25 @@ export function FieldRenderer({
|
|
|
359
374
|
fieldType: "display",
|
|
360
375
|
content: fieldDef.content,
|
|
361
376
|
sourceValue,
|
|
362
|
-
format
|
|
377
|
+
format,
|
|
378
|
+
formatOptions: resolvedFormatOptions,
|
|
363
379
|
} as DisplayFieldProps;
|
|
380
|
+
} else if (fieldType === "computed" && fieldDef.type === "computed") {
|
|
381
|
+
// Computed fields (read-only calculated values)
|
|
382
|
+
const computedDef = spec.computed?.[fieldPath];
|
|
383
|
+
const {
|
|
384
|
+
onChange: _onChangeC, // omit from computed props
|
|
385
|
+
...computedBaseProps
|
|
386
|
+
} = baseProps;
|
|
387
|
+
void _onChangeC;
|
|
388
|
+
fieldProps = {
|
|
389
|
+
...computedBaseProps,
|
|
390
|
+
fieldType: "computed",
|
|
391
|
+
value: forma.computed[fieldPath],
|
|
392
|
+
expression: computedDef?.expression ?? "",
|
|
393
|
+
format: computedDef?.format,
|
|
394
|
+
formatOptions: resolvedFormatOptions,
|
|
395
|
+
} as ComputedFieldProps;
|
|
364
396
|
} else {
|
|
365
397
|
// Text-based fields
|
|
366
398
|
fieldProps = {
|