@dxos/react-ui-form 0.9.0 → 0.9.1-main.c7dcc2e112
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/lib/browser/index.mjs +2221 -2147
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +2221 -2147
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/components/FieldEditor/FieldEditor.d.ts +3 -3
- package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.d.ts +15 -110
- package/dist/types/src/components/Form/Form.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.stories.d.ts +3 -37
- package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormControls.d.ts +66 -0
- package/dist/types/src/components/Form/FormControls.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormField/FieldHeader.d.ts +19 -0
- package/dist/types/src/components/Form/FormField/FieldHeader.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormField/FormField.d.ts +30 -0
- package/dist/types/src/components/Form/FormField/FormField.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormField/FormFieldWrapper.d.ts +47 -0
- package/dist/types/src/components/Form/FormField/FormFieldWrapper.d.ts.map +1 -0
- package/dist/types/src/components/Form/{FormFieldComponent.stories.d.ts → FormField/FormFieldWrapper.stories.d.ts} +3 -3
- package/dist/types/src/components/Form/FormField/FormFieldWrapper.stories.d.ts.map +1 -0
- package/dist/types/src/components/Form/{fields → FormField/fields/ArrayField}/ArrayField.d.ts +2 -2
- package/dist/types/src/components/Form/FormField/fields/ArrayField/ArrayField.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormField/fields/ArrayField/ArrayField.stories.d.ts +87 -0
- package/dist/types/src/components/Form/FormField/fields/ArrayField/ArrayField.stories.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormField/fields/ArrayField/index.d.ts +2 -0
- package/dist/types/src/components/Form/FormField/fields/ArrayField/index.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormField/fields/BooleanField/BooleanField.d.ts +4 -0
- package/dist/types/src/components/Form/FormField/fields/BooleanField/BooleanField.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormField/fields/BooleanField/BooleanField.stories.d.ts +88 -0
- package/dist/types/src/components/Form/FormField/fields/BooleanField/BooleanField.stories.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormField/fields/BooleanField/index.d.ts +2 -0
- package/dist/types/src/components/Form/FormField/fields/BooleanField/index.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormField/fields/DateField/DateField.d.ts +4 -0
- package/dist/types/src/components/Form/FormField/fields/DateField/DateField.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormField/fields/DateField/DateField.stories.d.ts +88 -0
- package/dist/types/src/components/Form/FormField/fields/DateField/DateField.stories.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormField/fields/DateField/index.d.ts +2 -0
- package/dist/types/src/components/Form/FormField/fields/DateField/index.d.ts.map +1 -0
- package/dist/types/src/components/Form/{fields → FormField/fields/GeoPointField}/GeoPointField.d.ts +2 -2
- package/dist/types/src/components/Form/FormField/fields/GeoPointField/GeoPointField.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormField/fields/GeoPointField/GeoPointField.stories.d.ts +88 -0
- package/dist/types/src/components/Form/FormField/fields/GeoPointField/GeoPointField.stories.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormField/fields/GeoPointField/index.d.ts +2 -0
- package/dist/types/src/components/Form/FormField/fields/GeoPointField/index.d.ts.map +1 -0
- package/dist/types/src/components/Form/{fields → FormField/fields/MarkdownField}/MarkdownField.d.ts +2 -2
- package/dist/types/src/components/Form/FormField/fields/MarkdownField/MarkdownField.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormField/fields/MarkdownField/MarkdownField.stories.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormField/fields/MarkdownField/index.d.ts +2 -0
- package/dist/types/src/components/Form/FormField/fields/MarkdownField/index.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormField/fields/NumberField/NumberField.d.ts +4 -0
- package/dist/types/src/components/Form/FormField/fields/NumberField/NumberField.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormField/fields/NumberField/NumberField.stories.d.ts +88 -0
- package/dist/types/src/components/Form/FormField/fields/NumberField/NumberField.stories.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormField/fields/NumberField/index.d.ts +2 -0
- package/dist/types/src/components/Form/FormField/fields/NumberField/index.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormField/fields/RefField/InlineRefField.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormField/fields/RefField/RefField.d.ts +16 -0
- package/dist/types/src/components/Form/FormField/fields/RefField/RefField.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormField/fields/RefField/RefField.stories.d.ts +92 -0
- package/dist/types/src/components/Form/FormField/fields/RefField/RefField.stories.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormField/fields/RefField/RefField.test.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormField/fields/RefField/index.d.ts +3 -0
- package/dist/types/src/components/Form/FormField/fields/RefField/index.d.ts.map +1 -0
- package/dist/types/src/components/Form/{fields → FormField/fields/SelectField}/SelectField.d.ts +2 -2
- package/dist/types/src/components/Form/FormField/fields/SelectField/SelectField.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormField/fields/SelectField/SelectField.stories.d.ts +88 -0
- package/dist/types/src/components/Form/FormField/fields/SelectField/SelectField.stories.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormField/fields/SelectField/index.d.ts +2 -0
- package/dist/types/src/components/Form/FormField/fields/SelectField/index.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormField/fields/SelectOptionField/SelectOptionField.d.ts +5 -0
- package/dist/types/src/components/Form/FormField/fields/SelectOptionField/SelectOptionField.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormField/fields/SelectOptionField/SelectOptionField.stories.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormField/fields/SelectOptionField/index.d.ts +2 -0
- package/dist/types/src/components/Form/FormField/fields/SelectOptionField/index.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormField/fields/TextAreaField/TextAreaField.d.ts +4 -0
- package/dist/types/src/components/Form/FormField/fields/TextAreaField/TextAreaField.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormField/fields/TextAreaField/TextAreaField.stories.d.ts +88 -0
- package/dist/types/src/components/Form/FormField/fields/TextAreaField/TextAreaField.stories.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormField/fields/TextAreaField/index.d.ts +2 -0
- package/dist/types/src/components/Form/FormField/fields/TextAreaField/index.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormField/fields/TextField/TextField.d.ts +4 -0
- package/dist/types/src/components/Form/FormField/fields/TextField/TextField.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormField/fields/TextField/TextField.stories.d.ts +88 -0
- package/dist/types/src/components/Form/FormField/fields/TextField/TextField.stories.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormField/fields/TextField/index.d.ts +2 -0
- package/dist/types/src/components/Form/FormField/fields/TextField/index.d.ts.map +1 -0
- package/dist/types/src/components/Form/{fields → FormField/fields/TupleField}/TupleField.d.ts +2 -2
- package/dist/types/src/components/Form/FormField/fields/TupleField/TupleField.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormField/fields/TupleField/TupleField.stories.d.ts +88 -0
- package/dist/types/src/components/Form/FormField/fields/TupleField/TupleField.stories.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormField/fields/TupleField/index.d.ts +2 -0
- package/dist/types/src/components/Form/FormField/fields/TupleField/index.d.ts.map +1 -0
- package/dist/types/src/components/Form/{fields → FormField/fields}/index.d.ts +0 -1
- package/dist/types/src/components/Form/FormField/fields/index.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormField/index.d.ts +5 -0
- package/dist/types/src/components/Form/FormField/index.d.ts.map +1 -0
- package/dist/types/src/components/Form/{FormFieldSet.d.ts → FormFieldSet/FormFieldSet.d.ts} +4 -3
- package/dist/types/src/components/Form/FormFieldSet/FormFieldSet.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormFieldSet/index.d.ts +2 -0
- package/dist/types/src/components/Form/FormFieldSet/index.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormLayout/FormLayout.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormLayout/FormLayout.stories.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormLayout/FormLayout.stories.test.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormLayout/FormLayout.test.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormLayout/index.d.ts +3 -0
- package/dist/types/src/components/Form/FormLayout/index.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormLayout/parser.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormLayout/parser.test.d.ts.map +1 -0
- package/dist/types/src/components/Form/index.d.ts +3 -5
- package/dist/types/src/components/Form/index.d.ts.map +1 -1
- package/dist/types/src/components/Form/meta-tags.d.ts +2 -2
- package/dist/types/src/components/ObjectForm/ObjectForm.d.ts.map +1 -1
- package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts +6 -23
- package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts.map +1 -1
- package/dist/types/src/components/ObjectProperties/ObjectProperties.d.ts.map +1 -1
- package/dist/types/src/components/RefEditor/RefEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/ViewEditor/ViewEditor.d.ts +1 -1
- package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
- package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +1 -0
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useFormContext.d.ts +37 -0
- package/dist/types/src/hooks/useFormContext.d.ts.map +1 -0
- package/dist/types/src/hooks/useFormHandler.d.ts +1 -4
- package/dist/types/src/hooks/useFormHandler.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/{components/testing.d.ts → testing/TestLayout.d.ts} +1 -1
- package/dist/types/src/testing/TestLayout.d.ts.map +1 -0
- package/dist/types/src/testing/index.d.ts +3 -0
- package/dist/types/src/testing/index.d.ts.map +1 -0
- package/dist/types/src/testing/schema.d.ts +43 -0
- package/dist/types/src/testing/schema.d.ts.map +1 -0
- package/dist/types/src/types.d.ts +112 -0
- package/dist/types/src/types.d.ts.map +1 -0
- package/dist/types/src/util/index.d.ts +1 -0
- package/dist/types/src/util/index.d.ts.map +1 -1
- package/dist/types/src/util/omit.d.ts +12 -0
- package/dist/types/src/util/omit.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +35 -34
- package/src/components/FieldEditor/FieldEditor.stories.tsx +1 -1
- package/src/components/FieldEditor/FieldEditor.test.tsx +1 -1
- package/src/components/FieldEditor/FieldEditor.tsx +5 -4
- package/src/components/Form/Form.stories.tsx +4 -49
- package/src/components/Form/Form.tsx +18 -447
- package/src/components/Form/FormControls.tsx +320 -0
- package/src/components/Form/FormField/FieldHeader.tsx +36 -0
- package/src/components/Form/{FormField.tsx → FormField/FormField.tsx} +35 -59
- package/src/components/Form/{FormFieldComponent.stories.tsx → FormField/FormFieldWrapper.stories.tsx} +24 -17
- package/src/components/Form/{FormFieldComponent.tsx → FormField/FormFieldWrapper.tsx} +21 -95
- package/src/components/Form/FormField/fields/ArrayField/ArrayField.stories.tsx +103 -0
- package/src/components/Form/FormField/fields/ArrayField/ArrayField.tsx +269 -0
- package/src/components/Form/FormField/fields/ArrayField/index.ts +5 -0
- package/src/components/Form/FormField/fields/BooleanField/BooleanField.stories.tsx +52 -0
- package/src/components/Form/{fields → FormField/fields/BooleanField}/BooleanField.tsx +10 -3
- package/src/components/Form/FormField/fields/BooleanField/index.ts +5 -0
- package/src/components/Form/FormField/fields/DateField/DateField.stories.tsx +60 -0
- package/src/components/Form/{fields → FormField/fields/DateField}/DateField.tsx +4 -2
- package/src/components/Form/FormField/fields/DateField/index.ts +5 -0
- package/src/components/Form/FormField/fields/GeoPointField/GeoPointField.stories.tsx +53 -0
- package/src/components/Form/{fields → FormField/fields/GeoPointField}/GeoPointField.tsx +4 -3
- package/src/components/Form/FormField/fields/GeoPointField/index.ts +5 -0
- package/src/components/Form/{fields → FormField/fields/MarkdownField}/MarkdownField.stories.tsx +6 -6
- package/src/components/Form/{fields → FormField/fields/MarkdownField}/MarkdownField.tsx +3 -2
- package/src/components/Form/FormField/fields/MarkdownField/index.ts +5 -0
- package/src/components/Form/FormField/fields/NumberField/NumberField.stories.tsx +52 -0
- package/src/components/Form/{fields → FormField/fields/NumberField}/NumberField.tsx +27 -2
- package/src/components/Form/FormField/fields/NumberField/index.ts +5 -0
- package/src/components/Form/{fields → FormField/fields/RefField}/InlineRefField.tsx +8 -7
- package/src/components/Form/FormField/fields/RefField/RefField.stories.tsx +97 -0
- package/src/components/Form/{fields → FormField/fields/RefField}/RefField.test.ts +2 -1
- package/src/components/Form/{fields → FormField/fields/RefField}/RefField.tsx +6 -25
- package/src/components/Form/FormField/fields/RefField/index.ts +6 -0
- package/src/components/Form/FormField/fields/SelectField/SelectField.stories.tsx +53 -0
- package/src/components/Form/{fields → FormField/fields/SelectField}/SelectField.tsx +4 -2
- package/src/components/Form/FormField/fields/SelectField/index.ts +5 -0
- package/src/components/Form/{fields → FormField/fields/SelectOptionField}/SelectOptionField.stories.tsx +5 -5
- package/src/components/Form/{fields → FormField/fields/SelectOptionField}/SelectOptionField.tsx +55 -53
- package/src/components/Form/FormField/fields/SelectOptionField/index.ts +5 -0
- package/src/components/Form/FormField/fields/TextAreaField/TextAreaField.stories.tsx +53 -0
- package/src/components/Form/{fields → FormField/fields/TextAreaField}/TextAreaField.tsx +4 -2
- package/src/components/Form/FormField/fields/TextAreaField/index.ts +5 -0
- package/src/components/Form/FormField/fields/TextField/TextField.stories.tsx +52 -0
- package/src/components/Form/{fields → FormField/fields/TextField}/TextField.tsx +4 -2
- package/src/components/Form/FormField/fields/TextField/index.ts +5 -0
- package/src/components/Form/FormField/fields/TupleField/TupleField.stories.tsx +55 -0
- package/src/components/Form/{fields → FormField/fields/TupleField}/TupleField.tsx +4 -2
- package/src/components/Form/FormField/fields/TupleField/index.ts +5 -0
- package/src/components/Form/{fields → FormField/fields}/index.ts +0 -1
- package/src/components/Form/FormField/index.ts +8 -0
- package/src/components/Form/{FormFieldSet.tsx → FormFieldSet/FormFieldSet.tsx} +16 -32
- package/src/components/Form/FormFieldSet/index.ts +5 -0
- package/src/components/Form/{Layout → FormLayout}/FormLayout.stories.tsx +4 -4
- package/src/components/Form/{Layout → FormLayout}/FormLayout.tsx +7 -6
- package/src/components/Form/{Layout → FormLayout}/index.ts +1 -2
- package/src/components/Form/index.ts +3 -5
- package/src/components/Form/meta-tags.ts +1 -1
- package/src/components/ObjectForm/ObjectForm.tsx +15 -14
- package/src/components/ObjectPicker/ObjectPicker.tsx +19 -27
- package/src/components/ObjectProperties/ObjectProperties.stories.tsx +1 -1
- package/src/components/ObjectProperties/ObjectProperties.test.tsx +1 -1
- package/src/components/ObjectProperties/ObjectProperties.tsx +2 -1
- package/src/components/RefEditor/RefEditor.stories.tsx +0 -1
- package/src/components/ViewEditor/ViewEditor.stories.tsx +4 -5
- package/src/components/ViewEditor/ViewEditor.test.tsx +1 -1
- package/src/components/ViewEditor/ViewEditor.tsx +98 -128
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useFormContext.ts +86 -0
- package/src/hooks/useFormHandler.ts +1 -4
- package/src/index.ts +1 -0
- package/src/{components/testing.tsx → testing/TestLayout.tsx} +1 -1
- package/src/testing/index.ts +7 -0
- package/src/testing/schema.ts +59 -0
- package/src/types.ts +134 -0
- package/src/util/index.ts +1 -0
- package/src/util/omit.ts +47 -0
- package/src/vitest-setup.ts +40 -0
- package/dist/types/src/components/Form/FormField.d.ts +0 -52
- package/dist/types/src/components/Form/FormField.d.ts.map +0 -1
- package/dist/types/src/components/Form/FormFieldComponent.d.ts +0 -98
- package/dist/types/src/components/Form/FormFieldComponent.d.ts.map +0 -1
- package/dist/types/src/components/Form/FormFieldComponent.stories.d.ts.map +0 -1
- package/dist/types/src/components/Form/FormFieldSet.d.ts.map +0 -1
- package/dist/types/src/components/Form/FormTooltipsContext.d.ts +0 -19
- package/dist/types/src/components/Form/FormTooltipsContext.d.ts.map +0 -1
- package/dist/types/src/components/Form/Layout/FormLayout.d.ts.map +0 -1
- package/dist/types/src/components/Form/Layout/FormLayout.stories.d.ts.map +0 -1
- package/dist/types/src/components/Form/Layout/FormLayout.stories.test.d.ts.map +0 -1
- package/dist/types/src/components/Form/Layout/FormLayout.test.d.ts.map +0 -1
- package/dist/types/src/components/Form/Layout/annotation.d.ts +0 -30
- package/dist/types/src/components/Form/Layout/annotation.d.ts.map +0 -1
- package/dist/types/src/components/Form/Layout/index.d.ts +0 -4
- package/dist/types/src/components/Form/Layout/index.d.ts.map +0 -1
- package/dist/types/src/components/Form/Layout/parser.d.ts.map +0 -1
- package/dist/types/src/components/Form/Layout/parser.test.d.ts.map +0 -1
- package/dist/types/src/components/Form/fields/ArrayField.d.ts.map +0 -1
- package/dist/types/src/components/Form/fields/BooleanField.d.ts +0 -4
- package/dist/types/src/components/Form/fields/BooleanField.d.ts.map +0 -1
- package/dist/types/src/components/Form/fields/DateField.d.ts +0 -4
- package/dist/types/src/components/Form/fields/DateField.d.ts.map +0 -1
- package/dist/types/src/components/Form/fields/GeoPointField.d.ts.map +0 -1
- package/dist/types/src/components/Form/fields/InlineRefField.d.ts.map +0 -1
- package/dist/types/src/components/Form/fields/MarkdownField.d.ts.map +0 -1
- package/dist/types/src/components/Form/fields/MarkdownField.stories.d.ts.map +0 -1
- package/dist/types/src/components/Form/fields/NumberField.d.ts +0 -4
- package/dist/types/src/components/Form/fields/NumberField.d.ts.map +0 -1
- package/dist/types/src/components/Form/fields/RefField.d.ts +0 -34
- package/dist/types/src/components/Form/fields/RefField.d.ts.map +0 -1
- package/dist/types/src/components/Form/fields/RefField.test.d.ts.map +0 -1
- package/dist/types/src/components/Form/fields/SelectField.d.ts.map +0 -1
- package/dist/types/src/components/Form/fields/SelectOptionField.d.ts +0 -5
- package/dist/types/src/components/Form/fields/SelectOptionField.d.ts.map +0 -1
- package/dist/types/src/components/Form/fields/SelectOptionField.stories.d.ts.map +0 -1
- package/dist/types/src/components/Form/fields/TextAreaField.d.ts +0 -4
- package/dist/types/src/components/Form/fields/TextAreaField.d.ts.map +0 -1
- package/dist/types/src/components/Form/fields/TextField.d.ts +0 -4
- package/dist/types/src/components/Form/fields/TextField.d.ts.map +0 -1
- package/dist/types/src/components/Form/fields/TupleField.d.ts.map +0 -1
- package/dist/types/src/components/Form/fields/index.d.ts.map +0 -1
- package/dist/types/src/components/testing.d.ts.map +0 -1
- package/src/components/Form/AUDIT.md +0 -17
- package/src/components/Form/FormTooltipsContext.ts +0 -25
- package/src/components/Form/Layout/annotation.ts +0 -38
- package/src/components/Form/README.md +0 -3
- package/src/components/Form/fields/ArrayField.tsx +0 -173
- /package/dist/types/src/components/Form/{fields → FormField/fields/MarkdownField}/MarkdownField.stories.d.ts +0 -0
- /package/dist/types/src/components/Form/{fields → FormField/fields/RefField}/InlineRefField.d.ts +0 -0
- /package/dist/types/src/components/Form/{fields → FormField/fields/RefField}/RefField.test.d.ts +0 -0
- /package/dist/types/src/components/Form/{fields → FormField/fields/SelectOptionField}/SelectOptionField.stories.d.ts +0 -0
- /package/dist/types/src/components/Form/{Layout → FormLayout}/FormLayout.d.ts +0 -0
- /package/dist/types/src/components/Form/{Layout → FormLayout}/FormLayout.stories.d.ts +0 -0
- /package/dist/types/src/components/Form/{Layout → FormLayout}/FormLayout.stories.test.d.ts +0 -0
- /package/dist/types/src/components/Form/{Layout → FormLayout}/FormLayout.test.d.ts +0 -0
- /package/dist/types/src/components/Form/{Layout → FormLayout}/parser.d.ts +0 -0
- /package/dist/types/src/components/Form/{Layout → FormLayout}/parser.test.d.ts +0 -0
- /package/src/components/Form/{Layout → FormLayout}/FormLayout.stories.test.tsx +0 -0
- /package/src/components/Form/{Layout → FormLayout}/FormLayout.test.ts +0 -0
- /package/src/components/Form/{Layout → FormLayout}/parser.test.ts +0 -0
- /package/src/components/Form/{Layout → FormLayout}/parser.ts +0 -0
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import React, { type PropsWithChildren, useRef } from 'react';
|
|
6
|
+
|
|
7
|
+
import { type AnyProperties } from '@dxos/echo/internal';
|
|
8
|
+
import {
|
|
9
|
+
Column,
|
|
10
|
+
type ColumnRootProps,
|
|
11
|
+
IconButton,
|
|
12
|
+
type IconButtonProps,
|
|
13
|
+
Input,
|
|
14
|
+
ScrollArea,
|
|
15
|
+
type ThemedClassName,
|
|
16
|
+
composable,
|
|
17
|
+
composableProps,
|
|
18
|
+
useMergeRefs,
|
|
19
|
+
useTranslation,
|
|
20
|
+
withColumn,
|
|
21
|
+
} from '@dxos/react-ui';
|
|
22
|
+
import { mx } from '@dxos/ui-theme';
|
|
23
|
+
|
|
24
|
+
import { translationKey } from '#translations';
|
|
25
|
+
|
|
26
|
+
import {
|
|
27
|
+
FormContextProvider,
|
|
28
|
+
type FormContextValue,
|
|
29
|
+
type FormHandlerProps,
|
|
30
|
+
type FormUpdateMeta,
|
|
31
|
+
useFormContext,
|
|
32
|
+
useFormHandler,
|
|
33
|
+
useKeyHandler,
|
|
34
|
+
} from '../../hooks';
|
|
35
|
+
import {
|
|
36
|
+
FormFieldSet as NaturalFormFieldSet,
|
|
37
|
+
type FormFieldSetProps as NaturalFormFieldSetProps,
|
|
38
|
+
} from './FormFieldSet';
|
|
39
|
+
import { FormLayout as NaturalFormLayout, type FormLayoutProps as NaturalFormLayoutProps } from './FormLayout';
|
|
40
|
+
|
|
41
|
+
//
|
|
42
|
+
// Root
|
|
43
|
+
//
|
|
44
|
+
|
|
45
|
+
export type FormRootProps<T extends AnyProperties = AnyProperties> = PropsWithChildren<
|
|
46
|
+
{
|
|
47
|
+
/**
|
|
48
|
+
* Called when the form is submitted and passes validation.
|
|
49
|
+
*/
|
|
50
|
+
onSave?: (values: T, meta: FormUpdateMeta<T>) => void;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Called when the form is canceled to abandon/undo any pending changes.
|
|
54
|
+
*/
|
|
55
|
+
onCancel?: () => void;
|
|
56
|
+
} & Omit<FormContextValue<T>, 'form'> &
|
|
57
|
+
Pick<FormHandlerProps<T>, 'schema' | 'autoSave' | 'values' | 'defaultValues' | 'onValidate' | 'onValuesChanged'> &
|
|
58
|
+
Omit<NaturalFormFieldSetProps<T>, 'schema' | 'path'>
|
|
59
|
+
>;
|
|
60
|
+
|
|
61
|
+
export const FormRoot = <T extends AnyProperties = AnyProperties>({
|
|
62
|
+
children,
|
|
63
|
+
schema,
|
|
64
|
+
values,
|
|
65
|
+
onSave,
|
|
66
|
+
onCancel,
|
|
67
|
+
...props
|
|
68
|
+
}: FormRootProps<T>) => {
|
|
69
|
+
const form = useFormHandler({ schema, values, onSave, onCancel, ...props });
|
|
70
|
+
|
|
71
|
+
return (
|
|
72
|
+
<FormContextProvider form={form} {...props}>
|
|
73
|
+
{children}
|
|
74
|
+
</FormContextProvider>
|
|
75
|
+
);
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
FormRoot.displayName = 'Form.Root';
|
|
79
|
+
|
|
80
|
+
//
|
|
81
|
+
// Viewport
|
|
82
|
+
//
|
|
83
|
+
|
|
84
|
+
const FORM_VIEWPORT_NAME = 'Form.Viewport';
|
|
85
|
+
|
|
86
|
+
export type FormViewportProps = { scroll?: boolean; gutter?: ColumnRootProps['gutter'] };
|
|
87
|
+
|
|
88
|
+
// The viewing window: owns the gutter Column (chrome/side-padding).
|
|
89
|
+
// Content-height by default; `scroll` makes it fill its parent and scroll (the gutter then hosts the scrollbar).
|
|
90
|
+
export const FormViewport = composable<HTMLDivElement, FormViewportProps>(
|
|
91
|
+
({ children, scroll, gutter = 'xs', ...props }, forwardedRef) => {
|
|
92
|
+
// Span the full width when nested inside another Column grid (e.g. Card.Root)
|
|
93
|
+
// instead of landing in a single narrow track.
|
|
94
|
+
const span = '[.dx-column-root_&]:col-span-full';
|
|
95
|
+
if (scroll) {
|
|
96
|
+
return (
|
|
97
|
+
<Column.Root gutter={gutter} classNames={['dx-expander', span]}>
|
|
98
|
+
<ScrollArea.Root {...composableProps(props)} orientation='vertical' centered padding thin ref={forwardedRef}>
|
|
99
|
+
<ScrollArea.Viewport>{children}</ScrollArea.Viewport>
|
|
100
|
+
</ScrollArea.Root>
|
|
101
|
+
</Column.Root>
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return (
|
|
106
|
+
<Column.Root {...composableProps(props)} gutter={gutter} classNames={['w-full min-w-0', span]} ref={forwardedRef}>
|
|
107
|
+
{children}
|
|
108
|
+
</Column.Root>
|
|
109
|
+
);
|
|
110
|
+
},
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
FormViewport.displayName = FORM_VIEWPORT_NAME;
|
|
114
|
+
|
|
115
|
+
//
|
|
116
|
+
// Content
|
|
117
|
+
//
|
|
118
|
+
|
|
119
|
+
const FORM_CONTENT_NAME = 'Form.Content';
|
|
120
|
+
|
|
121
|
+
export type FormContentProps = ThemedClassName<PropsWithChildren<{}>>;
|
|
122
|
+
|
|
123
|
+
// The viewed body: centered in the viewport's gutter. Pure body — the gutter Column is owned by `Form.Viewport`.
|
|
124
|
+
export const FormContent = composable<HTMLDivElement, FormContentProps>(({ children, ...props }, forwardedRef) => {
|
|
125
|
+
const { form, testId } = useFormContext(FORM_CONTENT_NAME);
|
|
126
|
+
const localRef = useRef<HTMLDivElement>(null);
|
|
127
|
+
const mergedRef = useMergeRefs([forwardedRef, localRef]);
|
|
128
|
+
useKeyHandler(localRef, form);
|
|
129
|
+
|
|
130
|
+
return (
|
|
131
|
+
<div
|
|
132
|
+
{...composableProps(props, {
|
|
133
|
+
role: 'form',
|
|
134
|
+
classNames: mx(withColumn.center(), 'flex flex-col w-full'),
|
|
135
|
+
})}
|
|
136
|
+
data-testid={testId}
|
|
137
|
+
ref={mergedRef}
|
|
138
|
+
>
|
|
139
|
+
{children}
|
|
140
|
+
</div>
|
|
141
|
+
);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
FormContent.displayName = FORM_CONTENT_NAME;
|
|
145
|
+
|
|
146
|
+
//
|
|
147
|
+
// FieldSet
|
|
148
|
+
//
|
|
149
|
+
|
|
150
|
+
const FORM_FIELDSET_NAME = 'Form.FieldSet';
|
|
151
|
+
|
|
152
|
+
export type FormFieldSetProps = ThemedClassName<NaturalFormFieldSetProps<any>>;
|
|
153
|
+
|
|
154
|
+
export const FormFieldSet = (props: FormFieldSetProps) => {
|
|
155
|
+
const { form, ...contextProps } = useFormContext(FORM_FIELDSET_NAME);
|
|
156
|
+
|
|
157
|
+
return <NaturalFormFieldSet schema={form.schema} {...contextProps} {...props} />;
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
FormFieldSet.displayName = FORM_FIELDSET_NAME;
|
|
161
|
+
|
|
162
|
+
//
|
|
163
|
+
// Layout
|
|
164
|
+
//
|
|
165
|
+
|
|
166
|
+
const FORM_LAYOUT_NAME = 'Form.Layout';
|
|
167
|
+
|
|
168
|
+
export type FormLayoutProps = Omit<NaturalFormLayoutProps, 'schema'> & { schema?: NaturalFormLayoutProps['schema'] };
|
|
169
|
+
|
|
170
|
+
export const FormLayout = ({ schema, ...props }: FormLayoutProps) => {
|
|
171
|
+
const { form, ...contextProps } = useFormContext(FORM_LAYOUT_NAME);
|
|
172
|
+
const resolvedSchema = schema ?? form.schema;
|
|
173
|
+
if (!resolvedSchema) {
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return <NaturalFormLayout schema={resolvedSchema} {...contextProps} {...props} />;
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
FormLayout.displayName = FORM_LAYOUT_NAME;
|
|
181
|
+
|
|
182
|
+
//
|
|
183
|
+
// Actions
|
|
184
|
+
//
|
|
185
|
+
|
|
186
|
+
const FORM_ACTIONS_NAME = 'Form.Actions';
|
|
187
|
+
|
|
188
|
+
export type FormActionsProps = ThemedClassName<{}>;
|
|
189
|
+
|
|
190
|
+
export const FormActions = ({ classNames }: FormActionsProps) => {
|
|
191
|
+
const { t } = useTranslation(translationKey);
|
|
192
|
+
const {
|
|
193
|
+
form: { canSave, onSave, onCancel },
|
|
194
|
+
readonly,
|
|
195
|
+
layout,
|
|
196
|
+
} = useFormContext(FORM_ACTIONS_NAME);
|
|
197
|
+
|
|
198
|
+
if (readonly || layout === 'static') {
|
|
199
|
+
return null;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// TODO(burdon): Currently onCancel is a no-op; implement "revert values".
|
|
203
|
+
// Deprecate FormSubmit ans use FormActions without Cancel button if no callback is supplied.
|
|
204
|
+
|
|
205
|
+
return (
|
|
206
|
+
<div
|
|
207
|
+
className={mx(withColumn.center(), 'grid grid-flow-col gap-form-gap auto-cols-fr py-form-padding', classNames)}
|
|
208
|
+
>
|
|
209
|
+
{onCancel && (
|
|
210
|
+
<IconButton
|
|
211
|
+
icon='ph--x--regular'
|
|
212
|
+
iconEnd
|
|
213
|
+
label={t('cancel-button.label')}
|
|
214
|
+
onClick={onCancel}
|
|
215
|
+
data-testid='cancel-button'
|
|
216
|
+
/>
|
|
217
|
+
)}
|
|
218
|
+
{onSave && (
|
|
219
|
+
<IconButton
|
|
220
|
+
type='submit'
|
|
221
|
+
variant='primary'
|
|
222
|
+
disabled={!canSave}
|
|
223
|
+
icon='ph--check--regular'
|
|
224
|
+
iconEnd
|
|
225
|
+
label={t('save-button.label')}
|
|
226
|
+
onClick={onSave}
|
|
227
|
+
data-testid='save-button'
|
|
228
|
+
/>
|
|
229
|
+
)}
|
|
230
|
+
</div>
|
|
231
|
+
);
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
FormActions.displayName = FORM_ACTIONS_NAME;
|
|
235
|
+
|
|
236
|
+
//
|
|
237
|
+
// Section
|
|
238
|
+
//
|
|
239
|
+
|
|
240
|
+
const FORM_SECTION_NAME = 'Form.Section';
|
|
241
|
+
|
|
242
|
+
export type FormSectionProps = ThemedClassName<{ label?: string; description?: string }>;
|
|
243
|
+
|
|
244
|
+
export const FormSection = composable<HTMLDivElement, FormSectionProps>(
|
|
245
|
+
({ children, label, description, ...props }, forwardedRef) => {
|
|
246
|
+
return (
|
|
247
|
+
<div
|
|
248
|
+
{...composableProps(props, { classNames: 'flex flex-col pt-form-section-gap first:pt-0' })}
|
|
249
|
+
ref={forwardedRef}
|
|
250
|
+
>
|
|
251
|
+
{label && <h2 className='text-lg'>{label}</h2>}
|
|
252
|
+
{description && <p className='text-description'>{description}</p>}
|
|
253
|
+
{children}
|
|
254
|
+
</div>
|
|
255
|
+
);
|
|
256
|
+
},
|
|
257
|
+
);
|
|
258
|
+
|
|
259
|
+
FormSection.displayName = FORM_SECTION_NAME;
|
|
260
|
+
|
|
261
|
+
//
|
|
262
|
+
// Submit
|
|
263
|
+
//
|
|
264
|
+
|
|
265
|
+
const FORM_SUBMIT_NAME = 'Form.Submit';
|
|
266
|
+
|
|
267
|
+
export type FormSubmitProps = ThemedClassName<Partial<Pick<IconButtonProps, 'icon' | 'label' | 'disabled'>>>;
|
|
268
|
+
|
|
269
|
+
export const FormSubmit = ({ classNames, label, icon, disabled }: FormSubmitProps) => {
|
|
270
|
+
const { t } = useTranslation(translationKey);
|
|
271
|
+
const {
|
|
272
|
+
form: { canSave, onSave },
|
|
273
|
+
readonly,
|
|
274
|
+
layout,
|
|
275
|
+
} = useFormContext(FORM_SUBMIT_NAME);
|
|
276
|
+
|
|
277
|
+
if (readonly || layout === 'static') {
|
|
278
|
+
return null;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
return (
|
|
282
|
+
<div className={mx('flex w-full pt-form-padding', classNames)}>
|
|
283
|
+
<IconButton
|
|
284
|
+
classNames='w-full'
|
|
285
|
+
type='submit'
|
|
286
|
+
variant='primary'
|
|
287
|
+
disabled={disabled ?? !canSave}
|
|
288
|
+
icon={icon ?? 'ph--check--regular'}
|
|
289
|
+
label={label ?? t('save-button.label')}
|
|
290
|
+
onClick={onSave}
|
|
291
|
+
data-testid='save-button'
|
|
292
|
+
/>
|
|
293
|
+
</div>
|
|
294
|
+
);
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
FormSubmit.displayName = FORM_SUBMIT_NAME;
|
|
298
|
+
|
|
299
|
+
//
|
|
300
|
+
// Error
|
|
301
|
+
//
|
|
302
|
+
|
|
303
|
+
const FORM_ERROR_NAME = 'Form.Error';
|
|
304
|
+
|
|
305
|
+
export type FormErrorProps = ThemedClassName<PropsWithChildren>;
|
|
306
|
+
|
|
307
|
+
/** Form-level error/validation message (e.g. a failed submit), styled via the error valence. */
|
|
308
|
+
export const FormError = ({ children, classNames }: FormErrorProps) => {
|
|
309
|
+
if (!children) {
|
|
310
|
+
return null;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
return (
|
|
314
|
+
<Input.Root validationValence='error'>
|
|
315
|
+
<Input.Validation classNames={classNames}>{children}</Input.Validation>
|
|
316
|
+
</Input.Root>
|
|
317
|
+
);
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
FormError.displayName = FORM_ERROR_NAME;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import React from 'react';
|
|
6
|
+
|
|
7
|
+
import { CompactIconButton } from './FormField';
|
|
8
|
+
import { FormFieldLabel } from './FormFieldWrapper';
|
|
9
|
+
|
|
10
|
+
export type FieldHeaderProps = {
|
|
11
|
+
label: string;
|
|
12
|
+
/** JSON path forwarded to the label as field metadata. */
|
|
13
|
+
path?: string;
|
|
14
|
+
readonly?: boolean;
|
|
15
|
+
/** Trailing inline add affordance; omit to hide it. */
|
|
16
|
+
add?: { icon?: string; label: string; disabled?: boolean; onClick: () => void };
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Header row for an array/list field: a label with an optional inline add button.
|
|
21
|
+
*/
|
|
22
|
+
export const FieldHeader = ({ label, path, readonly, add }: FieldHeaderProps) => (
|
|
23
|
+
<div className='flex items-center gap-2'>
|
|
24
|
+
<div className='flex-1 min-w-0'>
|
|
25
|
+
<FormFieldLabel readonly={readonly} label={label} path={path} standalone />
|
|
26
|
+
</div>
|
|
27
|
+
{!readonly && add && (
|
|
28
|
+
<CompactIconButton
|
|
29
|
+
disabled={add.disabled}
|
|
30
|
+
icon={add.icon ?? 'ph--plus--regular'}
|
|
31
|
+
label={add.label}
|
|
32
|
+
onClick={add.onClick}
|
|
33
|
+
/>
|
|
34
|
+
)}
|
|
35
|
+
</div>
|
|
36
|
+
);
|
|
@@ -11,13 +11,20 @@ import React, { useMemo } from 'react';
|
|
|
11
11
|
|
|
12
12
|
import { Annotation, Format } from '@dxos/echo';
|
|
13
13
|
import { SchemaEx } from '@dxos/effect';
|
|
14
|
-
import { IconButton, IconButtonProps, useTranslation } from '@dxos/react-ui';
|
|
15
|
-
import { type ProjectionModel } from '@dxos/schema';
|
|
16
|
-
import { mx } from '@dxos/ui-theme';
|
|
14
|
+
import { IconBlock, IconButton, IconButtonProps, useTranslation } from '@dxos/react-ui';
|
|
17
15
|
|
|
18
16
|
import { translationKey } from '#translations';
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
import {
|
|
18
|
+
type CreateOptions,
|
|
19
|
+
type FormFieldOptions,
|
|
20
|
+
type FormFieldRenderer,
|
|
21
|
+
type FormFieldRendererProps,
|
|
22
|
+
type RefFieldDataProps,
|
|
23
|
+
} from '#types';
|
|
24
|
+
|
|
25
|
+
import { useFormFieldState } from '../../../hooks';
|
|
26
|
+
import { getRefProps } from '../../../util';
|
|
27
|
+
import { FormFieldSet } from '../FormFieldSet';
|
|
21
28
|
import {
|
|
22
29
|
ArrayField,
|
|
23
30
|
BooleanField,
|
|
@@ -27,19 +34,10 @@ import {
|
|
|
27
34
|
MarkdownField,
|
|
28
35
|
NumberField,
|
|
29
36
|
RefField,
|
|
30
|
-
type RefFieldProps,
|
|
31
37
|
SelectField,
|
|
32
38
|
TextAreaField,
|
|
33
39
|
TextField,
|
|
34
40
|
} from './fields';
|
|
35
|
-
import { useFormFieldState } from './Form';
|
|
36
|
-
import {
|
|
37
|
-
type FormFieldComponent,
|
|
38
|
-
type FormFieldComponentProps,
|
|
39
|
-
type FormFieldMap,
|
|
40
|
-
type FormFieldProvider,
|
|
41
|
-
} from './FormFieldComponent';
|
|
42
|
-
import { FormFieldSet } from './FormFieldSet';
|
|
43
41
|
|
|
44
42
|
export type FormFieldProps = {
|
|
45
43
|
/**
|
|
@@ -61,41 +59,10 @@ export type FormFieldProps = {
|
|
|
61
59
|
* Path to the current object from the root. Used with nested forms.
|
|
62
60
|
*/
|
|
63
61
|
path?: (string | number)[];
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
projection?: ProjectionModel;
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Map of custom renderers for specific properties.
|
|
72
|
-
* Prefer fieldProvider for plugin specific input surfaces.
|
|
73
|
-
*/
|
|
74
|
-
fieldMap?: FormFieldMap;
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Function to lookup custom renderers for specific properties.
|
|
78
|
-
*/
|
|
79
|
-
fieldProvider?: FormFieldProvider;
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Typename of the ref type that the create props apply to.
|
|
83
|
-
* When set, createOptionLabel/createOptionIcon/createInitialValuePath/createFieldMap/onCreate
|
|
84
|
-
* are only passed to ref fields whose typename matches.
|
|
85
|
-
*/
|
|
86
|
-
createTypename?: string;
|
|
87
|
-
} & Pick<FormFieldComponentProps, 'autoFocus' | 'readonly' | 'layout'> &
|
|
88
|
-
Pick<
|
|
89
|
-
RefFieldProps,
|
|
90
|
-
| 'createOptionLabel'
|
|
91
|
-
| 'createOptionIcon'
|
|
92
|
-
| 'createInitialValuePath'
|
|
93
|
-
| 'createFieldMap'
|
|
94
|
-
| 'db'
|
|
95
|
-
| 'useType'
|
|
96
|
-
| 'getOptions'
|
|
97
|
-
| 'onCreate'
|
|
98
|
-
>;
|
|
62
|
+
autoFocus?: boolean;
|
|
63
|
+
} & FormFieldOptions &
|
|
64
|
+
Pick<RefFieldDataProps, 'getOptions' | 'onCreate' | 'useType'> &
|
|
65
|
+
CreateOptions;
|
|
99
66
|
|
|
100
67
|
export const FormField = (props: FormFieldProps) => {
|
|
101
68
|
const {
|
|
@@ -115,7 +82,7 @@ export const FormField = (props: FormFieldProps) => {
|
|
|
115
82
|
createInitialValuePath,
|
|
116
83
|
createFieldMap,
|
|
117
84
|
db,
|
|
118
|
-
useType
|
|
85
|
+
useType,
|
|
119
86
|
getOptions,
|
|
120
87
|
onCreate,
|
|
121
88
|
} = props;
|
|
@@ -136,7 +103,7 @@ export const FormField = (props: FormFieldProps) => {
|
|
|
136
103
|
|
|
137
104
|
const fieldState = useFormFieldState(FormField.displayName, path);
|
|
138
105
|
const jsonPath = SchemaEx.createJsonPath(path ?? []);
|
|
139
|
-
const fieldProps:
|
|
106
|
+
const fieldProps: FormFieldRendererProps = {
|
|
140
107
|
type,
|
|
141
108
|
format: Format.FormatAnnotation.getFromAst(type).pipe((annotation) => Option.getOrUndefined(annotation)),
|
|
142
109
|
readonly,
|
|
@@ -226,7 +193,7 @@ export const FormField = (props: FormFieldProps) => {
|
|
|
226
193
|
// Inline a single referenced object's own fields (nested form) instead of a picker.
|
|
227
194
|
const inline = Annotation.FormInlineAnnotation.getFromAst(refProps.ast).pipe(Option.getOrElse(() => false));
|
|
228
195
|
if (inline && !refProps.isArray) {
|
|
229
|
-
return <InlineRefField {...fieldProps} {...refProps} db={db} useType={
|
|
196
|
+
return <InlineRefField {...fieldProps} {...refProps} db={db} useType={useType} onCreate={onCreate} />;
|
|
230
197
|
}
|
|
231
198
|
|
|
232
199
|
const isCreateTarget = !createTypename || refProps.typename === createTypename;
|
|
@@ -239,7 +206,7 @@ export const FormField = (props: FormFieldProps) => {
|
|
|
239
206
|
createInitialValuePath={isCreateTarget ? createInitialValuePath : undefined}
|
|
240
207
|
createFieldMap={isCreateTarget ? createFieldMap : undefined}
|
|
241
208
|
db={db}
|
|
242
|
-
useType={
|
|
209
|
+
useType={useType}
|
|
243
210
|
getOptions={getOptions}
|
|
244
211
|
onCreate={onCreate}
|
|
245
212
|
/>
|
|
@@ -273,7 +240,7 @@ export const FormField = (props: FormFieldProps) => {
|
|
|
273
240
|
createOptionIcon={createOptionIcon}
|
|
274
241
|
createInitialValuePath={createInitialValuePath}
|
|
275
242
|
db={db}
|
|
276
|
-
useType={
|
|
243
|
+
useType={useType}
|
|
277
244
|
getOptions={getOptions}
|
|
278
245
|
onCreate={onCreate}
|
|
279
246
|
/>
|
|
@@ -290,24 +257,33 @@ FormField.displayName = 'Form.FormField';
|
|
|
290
257
|
// Layout components
|
|
291
258
|
//
|
|
292
259
|
|
|
293
|
-
export const
|
|
260
|
+
export const CompactIconButton = (props: IconButtonProps) => {
|
|
294
261
|
return (
|
|
295
|
-
|
|
262
|
+
// IconBlock defaults to aria-hidden (decorative slot); the button is interactive, so un-hide it.
|
|
263
|
+
<IconBlock aria-hidden={false} classNames='my-[1px]'>
|
|
296
264
|
<IconButton variant='ghost' density='xs' square iconOnly {...props} />
|
|
297
|
-
</
|
|
265
|
+
</IconBlock>
|
|
298
266
|
);
|
|
299
267
|
};
|
|
300
268
|
|
|
301
269
|
/**
|
|
302
270
|
* Get property input component.
|
|
303
271
|
*/
|
|
304
|
-
const getFormField = ({
|
|
272
|
+
const getFormField = ({
|
|
273
|
+
type,
|
|
274
|
+
format,
|
|
275
|
+
}: Pick<FormFieldRendererProps, 'type' | 'format'>): FormFieldRenderer | undefined => {
|
|
276
|
+
// Unwrap refinements (e.g. Schema.Number.pipe(Schema.between(...))) to their base type.
|
|
277
|
+
if (SchemaAST.isRefinement(type)) {
|
|
278
|
+
return getFormField({ type: type.from, format });
|
|
279
|
+
}
|
|
280
|
+
|
|
305
281
|
//
|
|
306
282
|
// Standard formats.
|
|
307
283
|
//
|
|
308
284
|
|
|
309
285
|
const formatField = Match.value(format).pipe(
|
|
310
|
-
Match.withReturnType<
|
|
286
|
+
Match.withReturnType<FormFieldRenderer | undefined>(),
|
|
311
287
|
Match.when(Format.TypeFormat.Date, () => DateField),
|
|
312
288
|
Match.when(Format.TypeFormat.DateTime, () => DateField),
|
|
313
289
|
Match.when(Format.TypeFormat.GeoPoint, () => GeoPointField),
|
|
@@ -8,7 +8,10 @@ import React, { type ChangeEvent, useCallback } from 'react';
|
|
|
8
8
|
import { Input } from '@dxos/react-ui';
|
|
9
9
|
import { withLayout, withTheme } from '@dxos/react-ui/testing';
|
|
10
10
|
|
|
11
|
-
import { type
|
|
11
|
+
import { type FormFieldRendererProps } from '#types';
|
|
12
|
+
|
|
13
|
+
import { Form } from '../Form';
|
|
14
|
+
import { FormFieldWrapper } from './FormFieldWrapper';
|
|
12
15
|
|
|
13
16
|
const DefaultStory = ({
|
|
14
17
|
type,
|
|
@@ -17,32 +20,36 @@ const DefaultStory = ({
|
|
|
17
20
|
onBlur,
|
|
18
21
|
onValueChange,
|
|
19
22
|
...props
|
|
20
|
-
}:
|
|
23
|
+
}: FormFieldRendererProps<string>) => {
|
|
21
24
|
const handleChange = useCallback(
|
|
22
25
|
(event: ChangeEvent<HTMLInputElement>) => onValueChange(type, event.target.value),
|
|
23
26
|
[type, onValueChange],
|
|
24
27
|
);
|
|
25
28
|
|
|
26
29
|
return (
|
|
27
|
-
<
|
|
28
|
-
<
|
|
29
|
-
|
|
30
|
-
<
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
30
|
+
<Form.Root>
|
|
31
|
+
<Form.Viewport>
|
|
32
|
+
<Form.Content>
|
|
33
|
+
<FormFieldWrapper<string> {...props}>
|
|
34
|
+
{({ value = '' }) => (
|
|
35
|
+
<Input.TextInput
|
|
36
|
+
disabled={!!readonly}
|
|
37
|
+
placeholder={placeholder}
|
|
38
|
+
noAutoFill
|
|
39
|
+
value={value}
|
|
40
|
+
onChange={handleChange}
|
|
41
|
+
onBlur={onBlur}
|
|
42
|
+
/>
|
|
43
|
+
)}
|
|
44
|
+
</FormFieldWrapper>
|
|
45
|
+
</Form.Content>
|
|
46
|
+
</Form.Viewport>
|
|
47
|
+
</Form.Root>
|
|
41
48
|
);
|
|
42
49
|
};
|
|
43
50
|
|
|
44
51
|
const meta: Meta<typeof DefaultStory> = {
|
|
45
|
-
title: 'ui/react-ui-form/
|
|
52
|
+
title: 'ui/react-ui-form/FormFieldWrapper',
|
|
46
53
|
component: DefaultStory,
|
|
47
54
|
decorators: [withTheme(), withLayout({ layout: 'column' })],
|
|
48
55
|
parameters: {
|