@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
|
@@ -10,27 +10,15 @@ import { invariant } from '@dxos/invariant';
|
|
|
10
10
|
import { HuePicker } from '@dxos/react-ui-pickers';
|
|
11
11
|
|
|
12
12
|
import { translationKey } from '#translations';
|
|
13
|
+
import { type FormFieldMap } from '#types';
|
|
13
14
|
|
|
14
|
-
import { Form,
|
|
15
|
+
import { Form, META_TAGS_KEY, withMetaTags } from '../Form';
|
|
15
16
|
|
|
16
17
|
export type ObjectFormProps = {
|
|
17
18
|
type: Type.AnyEntity;
|
|
18
19
|
object: Obj.Unknown;
|
|
19
20
|
};
|
|
20
21
|
|
|
21
|
-
const createFieldMap: FormFieldMap = {
|
|
22
|
-
hue: ({ type, label, layout, getValue, onValueChange }) => {
|
|
23
|
-
const handleChange = useCallback((nextHue: string) => onValueChange(type, nextHue), [onValueChange, type]);
|
|
24
|
-
const handleReset = useCallback(() => onValueChange(type, undefined), [onValueChange, type]);
|
|
25
|
-
return (
|
|
26
|
-
<>
|
|
27
|
-
{layout !== 'inline' && <Form.Label label={label} />}
|
|
28
|
-
<HuePicker value={getValue()} onChange={handleChange} onReset={handleReset} />
|
|
29
|
-
</>
|
|
30
|
-
);
|
|
31
|
-
},
|
|
32
|
-
};
|
|
33
|
-
|
|
34
22
|
export const ObjectForm = ({ object, type }: ObjectFormProps) => {
|
|
35
23
|
const db = Obj.getDatabase(object);
|
|
36
24
|
const meta = Obj.getMeta(object);
|
|
@@ -109,3 +97,16 @@ export const ObjectForm = ({ object, type }: ObjectFormProps) => {
|
|
|
109
97
|
</Form.Root>
|
|
110
98
|
);
|
|
111
99
|
};
|
|
100
|
+
|
|
101
|
+
const createFieldMap: FormFieldMap = {
|
|
102
|
+
hue: ({ type, label, layout, getValue, onValueChange }) => {
|
|
103
|
+
const handleChange = useCallback((nextHue: string) => onValueChange(type, nextHue), [onValueChange, type]);
|
|
104
|
+
const handleReset = useCallback(() => onValueChange(type, undefined), [onValueChange, type]);
|
|
105
|
+
return (
|
|
106
|
+
<>
|
|
107
|
+
{layout !== 'inline' && <Form.Label label={label} />}
|
|
108
|
+
<HuePicker value={getValue()} onChange={handleChange} onReset={handleReset} />
|
|
109
|
+
</>
|
|
110
|
+
);
|
|
111
|
+
},
|
|
112
|
+
};
|
|
@@ -5,39 +5,31 @@
|
|
|
5
5
|
import type * as Schema from 'effect/Schema';
|
|
6
6
|
import React, { type KeyboardEvent, forwardRef, useCallback, useState } from 'react';
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { Popover, type ThemedClassName, useTranslation } from '@dxos/react-ui';
|
|
9
9
|
import { Combobox } from '@dxos/react-ui-list';
|
|
10
10
|
import { useSearchListResults } from '@dxos/react-ui-search';
|
|
11
11
|
|
|
12
12
|
import { translationKey } from '#translations';
|
|
13
|
+
import { type CreateOptions, type RefOption } from '#types';
|
|
13
14
|
|
|
14
15
|
import { Form } from '../Form';
|
|
15
|
-
import { type FormFieldMap } from '../Form/FormFieldComponent';
|
|
16
16
|
|
|
17
|
-
export type
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
* to write to a database). The Promise is awaited before the inline create
|
|
34
|
-
* form is collapsed back to the picker list, so consumers can complete
|
|
35
|
-
* follow-up work (assign the new ref to a parent slot, close the popover)
|
|
36
|
-
* before the picker UI re-renders.
|
|
37
|
-
*/
|
|
38
|
-
onCreate?: (values: any) => unknown | Promise<unknown>;
|
|
39
|
-
onSelect: (id: string) => void;
|
|
40
|
-
}>;
|
|
17
|
+
export type ObjectPickerContentProps = ThemedClassName<
|
|
18
|
+
CreateOptions & {
|
|
19
|
+
options: RefOption[];
|
|
20
|
+
selectedIds?: string[];
|
|
21
|
+
createSchema?: Schema.Schema.AnyNoContext;
|
|
22
|
+
/**
|
|
23
|
+
* Persist a newly-created object given the form values. May be async (e.g.
|
|
24
|
+
* to write to a database). The Promise is awaited before the inline create
|
|
25
|
+
* form is collapsed back to the picker list, so consumers can complete
|
|
26
|
+
* follow-up work (assign the new ref to a parent slot, close the popover)
|
|
27
|
+
* before the picker UI re-renders.
|
|
28
|
+
*/
|
|
29
|
+
onCreate?: (values: any) => unknown | Promise<unknown>;
|
|
30
|
+
onSelect?: (id: string) => void;
|
|
31
|
+
}
|
|
32
|
+
>;
|
|
41
33
|
|
|
42
34
|
const ObjectPickerContent = forwardRef<HTMLDivElement, ObjectPickerContentProps>(
|
|
43
35
|
(
|
|
@@ -138,7 +130,7 @@ const ObjectPickerContent = forwardRef<HTMLDivElement, ObjectPickerContentProps>
|
|
|
138
130
|
value={option.id}
|
|
139
131
|
label={option.label}
|
|
140
132
|
checked={selectedIds?.includes(option.id)}
|
|
141
|
-
onSelect={() => onSelect(option.id)}
|
|
133
|
+
onSelect={() => onSelect?.(option.id)}
|
|
142
134
|
classNames='flex items-center gap-2'
|
|
143
135
|
/>
|
|
144
136
|
))}
|
|
@@ -18,7 +18,7 @@ import { Pipeline } from '@dxos/types';
|
|
|
18
18
|
|
|
19
19
|
import { translations } from '#translations';
|
|
20
20
|
|
|
21
|
-
import { OBJECT_PROPERTIES_DEBUG_SYMBOL } from '
|
|
21
|
+
import { OBJECT_PROPERTIES_DEBUG_SYMBOL } from '../../testing';
|
|
22
22
|
import { ObjectProperties } from './ObjectProperties';
|
|
23
23
|
|
|
24
24
|
//
|
|
@@ -9,7 +9,7 @@ import { afterEach, describe, expect, test } from 'vitest';
|
|
|
9
9
|
import { Filter, Obj, Tag } from '@dxos/echo';
|
|
10
10
|
import { DXN, EID } from '@dxos/keys';
|
|
11
11
|
|
|
12
|
-
import { OBJECT_PROPERTIES_DEBUG_SYMBOL } from '
|
|
12
|
+
import { OBJECT_PROPERTIES_DEBUG_SYMBOL } from '../../testing';
|
|
13
13
|
import * as stories from './ObjectProperties.stories';
|
|
14
14
|
import { type ObjectPropertiesDebug } from './ObjectProperties.stories';
|
|
15
15
|
|
|
@@ -15,8 +15,9 @@ import { HuePicker } from '@dxos/react-ui-pickers';
|
|
|
15
15
|
import { FactoryAnnotation } from '@dxos/schema';
|
|
16
16
|
|
|
17
17
|
import { translationKey } from '#translations';
|
|
18
|
+
import { type FormFieldMap } from '#types';
|
|
18
19
|
|
|
19
|
-
import { Form,
|
|
20
|
+
import { Form, META_TAGS_KEY, withMetaTags } from '../Form';
|
|
20
21
|
|
|
21
22
|
export type ObjectPropertiesProps = PropsWithChildren<{ object: Obj.Unknown }>;
|
|
22
23
|
|
|
@@ -88,7 +88,6 @@ const DefaultStory = ({ value: initialValue, ...args }: StoryProps) => {
|
|
|
88
88
|
icon='ph--user--regular'
|
|
89
89
|
db={space?.db}
|
|
90
90
|
onChange={setValue}
|
|
91
|
-
classNames='border'
|
|
92
91
|
/>
|
|
93
92
|
<JsonHighlighter data={{ value }} classNames='text-xs' />
|
|
94
93
|
<PeopleGrid db={space?.db} />
|
|
@@ -12,17 +12,16 @@ import { type Mutable } from '@dxos/echo/Obj';
|
|
|
12
12
|
import { useQuery } from '@dxos/react-client/echo';
|
|
13
13
|
import { useClientStory, withClientProvider } from '@dxos/react-client/testing';
|
|
14
14
|
import { useAsyncEffect } from '@dxos/react-ui';
|
|
15
|
-
import { withLayout, withTheme } from '@dxos/react-ui/testing';
|
|
15
|
+
import { Loading, withLayout, withTheme } from '@dxos/react-ui/testing';
|
|
16
16
|
import { type ProjectionModel, ViewModel, getTypeURIFromQuery } from '@dxos/schema';
|
|
17
17
|
import { Employer, Organization, Person, Pipeline } from '@dxos/types';
|
|
18
18
|
|
|
19
19
|
import { translations } from '#translations';
|
|
20
20
|
|
|
21
|
-
import { TestLayout, VIEW_EDITOR_DEBUG_SYMBOL } from '
|
|
21
|
+
import { TestLayout, VIEW_EDITOR_DEBUG_SYMBOL } from '../../testing';
|
|
22
22
|
import { ViewEditor, type ViewEditorProps } from './ViewEditor';
|
|
23
23
|
|
|
24
24
|
const types = [
|
|
25
|
-
// TODO(burdon): Get label from annotation.
|
|
26
25
|
{ value: Type.getURI(Organization.Organization), label: 'Organization' },
|
|
27
26
|
{ value: Type.getURI(Person.Person), label: 'Person' },
|
|
28
27
|
{ value: Type.getURI(Pipeline.Pipeline), label: 'Project' },
|
|
@@ -126,14 +125,14 @@ const DefaultStory = (props: DefaultStoryProps) => {
|
|
|
126
125
|
}
|
|
127
126
|
}, [type, view]);
|
|
128
127
|
|
|
129
|
-
// NOTE(ZaymonFC):
|
|
128
|
+
// NOTE(ZaymonFC): Avoids infinite parsing issue with storybook args.
|
|
130
129
|
const json = useMemo(
|
|
131
130
|
() => JSON.parse(JSON.stringify({ schema: type, view, projection: projectionRef.current })),
|
|
132
131
|
[JSON.stringify(type), JSON.stringify(view)],
|
|
133
132
|
);
|
|
134
133
|
|
|
135
134
|
if (!type || !view) {
|
|
136
|
-
return <
|
|
135
|
+
return <Loading />;
|
|
137
136
|
}
|
|
138
137
|
|
|
139
138
|
return (
|
|
@@ -10,7 +10,7 @@ import { Type, View } from '@dxos/echo';
|
|
|
10
10
|
import { instanceOf as isInstanceOf } from '@dxos/echo/Obj';
|
|
11
11
|
import { ProjectionModel } from '@dxos/schema';
|
|
12
12
|
|
|
13
|
-
import { VIEW_EDITOR_DEBUG_SYMBOL } from '
|
|
13
|
+
import { VIEW_EDITOR_DEBUG_SYMBOL } from '../../testing';
|
|
14
14
|
import * as stories from './ViewEditor.stories';
|
|
15
15
|
import { type ViewEditorDebugObjects } from './ViewEditor.stories';
|
|
16
16
|
|
|
@@ -26,9 +26,9 @@ import {
|
|
|
26
26
|
import { SchemaEx } from '@dxos/effect';
|
|
27
27
|
import { invariant } from '@dxos/invariant';
|
|
28
28
|
import { useObject, useQuery } from '@dxos/react-client/echo';
|
|
29
|
-
import {
|
|
29
|
+
import { Input, Message, type ThemedClassName, ToggleIconButton, useTranslation } from '@dxos/react-ui';
|
|
30
30
|
import { QueryForm, type QueryFormProps } from '@dxos/react-ui-components';
|
|
31
|
-
import {
|
|
31
|
+
import { OrderedList } from '@dxos/react-ui-list';
|
|
32
32
|
import {
|
|
33
33
|
ParentLabelAnnotation,
|
|
34
34
|
ProjectionModel,
|
|
@@ -36,19 +36,13 @@ import {
|
|
|
36
36
|
createEchoChangeCallback,
|
|
37
37
|
getTypeURIFromQuery,
|
|
38
38
|
} from '@dxos/schema';
|
|
39
|
-
import { mx
|
|
39
|
+
import { mx } from '@dxos/ui-theme';
|
|
40
40
|
|
|
41
41
|
import { translationKey } from '#translations';
|
|
42
|
+
import { type FormFieldRenderer, type FormFieldRendererProps, type FormFieldMap } from '#types';
|
|
42
43
|
|
|
43
44
|
import { FieldEditor } from '../FieldEditor';
|
|
44
|
-
import {
|
|
45
|
-
Form,
|
|
46
|
-
type FormFieldComponent,
|
|
47
|
-
type FormFieldComponentProps,
|
|
48
|
-
FormFieldLabel,
|
|
49
|
-
type FormFieldMap,
|
|
50
|
-
type FormRootProps,
|
|
51
|
-
} from '../Form';
|
|
45
|
+
import { CompactIconButton, FieldHeader, Form, FormFieldLabel, type FormRootProps } from '../Form';
|
|
52
46
|
|
|
53
47
|
export type ViewEditorProps = ThemedClassName<
|
|
54
48
|
{
|
|
@@ -64,7 +58,7 @@ export type ViewEditorProps = ThemedClassName<
|
|
|
64
58
|
>;
|
|
65
59
|
|
|
66
60
|
/**
|
|
67
|
-
*
|
|
61
|
+
* View editor form.
|
|
68
62
|
*/
|
|
69
63
|
export const ViewEditor = forwardRef<ProjectionModel | null, ViewEditorProps>(
|
|
70
64
|
(
|
|
@@ -92,6 +86,7 @@ export const ViewEditor = forwardRef<ProjectionModel | null, ViewEditorProps>(
|
|
|
92
86
|
if (!type) {
|
|
93
87
|
return null;
|
|
94
88
|
}
|
|
89
|
+
|
|
95
90
|
const jsonSchema = type.jsonSchema;
|
|
96
91
|
|
|
97
92
|
// Always use createEchoChangeCallback since the view is ECHO-backed.
|
|
@@ -117,6 +112,7 @@ export const ViewEditor = forwardRef<ProjectionModel | null, ViewEditorProps>(
|
|
|
117
112
|
if (from._tag !== 'scope') {
|
|
118
113
|
return undefined;
|
|
119
114
|
}
|
|
115
|
+
|
|
120
116
|
const feedScope = from.scopes.find((s) => s._tag === 'feed');
|
|
121
117
|
return Option.fromNullable(feedScope).pipe(
|
|
122
118
|
Option.map((s) => s.feedUri),
|
|
@@ -216,42 +212,54 @@ export const ViewEditor = forwardRef<ProjectionModel | null, ViewEditorProps>(
|
|
|
216
212
|
|
|
217
213
|
return (
|
|
218
214
|
<div className={mx(classNames)}>
|
|
219
|
-
{/* If readonly is set, then the callout is not needed. */}
|
|
220
|
-
{schemaReadonly && !readonly && (
|
|
221
|
-
<Message.Root valence='info' classNames='my-form-padding'>
|
|
222
|
-
<Message.Title>{t('system-schema.description')}</Message.Title>
|
|
223
|
-
</Message.Root>
|
|
224
|
-
)}
|
|
225
|
-
|
|
226
215
|
{/* TODO(burdon): Is the form read-only or just the schema? */}
|
|
227
216
|
<Form.Root schema={viewSchema} values={viewValues} fieldMap={fieldMap} db={db} onValuesChanged={handleUpdate}>
|
|
228
|
-
<Form.
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
217
|
+
<Form.Viewport>
|
|
218
|
+
<Form.Content>
|
|
219
|
+
{/* If readonly is set, then the callout is not needed. */}
|
|
220
|
+
{schemaReadonly && !readonly && (
|
|
221
|
+
<Message.Root valence='info' classNames='my-form-padding'>
|
|
222
|
+
<Message.Title>{t('system-schema.description')}</Message.Title>
|
|
223
|
+
</Message.Root>
|
|
224
|
+
)}
|
|
225
|
+
<Form.FieldSet />
|
|
226
|
+
{type && (
|
|
227
|
+
<FieldList
|
|
228
|
+
type={type}
|
|
229
|
+
view={view}
|
|
230
|
+
registry={registry}
|
|
231
|
+
readonly={readonly}
|
|
232
|
+
showHeading={showHeading}
|
|
233
|
+
onDelete={handleDelete}
|
|
234
|
+
/>
|
|
235
|
+
)}
|
|
236
|
+
</Form.Content>
|
|
237
|
+
</Form.Viewport>
|
|
243
238
|
</Form.Root>
|
|
244
239
|
</div>
|
|
245
240
|
);
|
|
246
241
|
},
|
|
247
242
|
);
|
|
248
243
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
244
|
+
const customFields = ({ types, tags }: Pick<ViewEditorProps, 'types' | 'tags'>): Record<string, FormFieldRenderer> => ({
|
|
245
|
+
query: ({ type, readonly, label, getValue, onValueChange }: FormFieldRendererProps) => {
|
|
246
|
+
const handleChange = useCallback<NonNullable<QueryFormProps['onChange']>>(
|
|
247
|
+
(query) => onValueChange(type, query.ast),
|
|
248
|
+
[onValueChange],
|
|
249
|
+
);
|
|
250
|
+
|
|
251
|
+
return (
|
|
252
|
+
<Input.Root>
|
|
253
|
+
<FormFieldLabel readonly={readonly} label={label} />
|
|
254
|
+
<QueryForm initialQuery={getValue()} types={types} tags={tags} onChange={handleChange} />
|
|
255
|
+
</Input.Root>
|
|
256
|
+
);
|
|
257
|
+
},
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
type FieldListProps = {
|
|
253
261
|
type: Type.AnyEntity;
|
|
254
|
-
}
|
|
262
|
+
} & Pick<ViewEditorProps, 'view' | 'registry' | 'readonly' | 'showHeading' | 'onDelete'>;
|
|
255
263
|
|
|
256
264
|
const FieldList = ({ type, view, registry, readonly, showHeading = false, onDelete }: FieldListProps) => {
|
|
257
265
|
const atomRegistry = useContext(RegistryContext);
|
|
@@ -268,14 +276,12 @@ const FieldList = ({ type, view, registry, readonly, showHeading = false, onDele
|
|
|
268
276
|
// Pass type only when mutable to allow schema mutations.
|
|
269
277
|
const change = createEchoChangeCallback(view, Type.getDatabase(type) != null ? type : undefined);
|
|
270
278
|
|
|
271
|
-
|
|
279
|
+
return new ProjectionModel({
|
|
272
280
|
registry: atomRegistry,
|
|
273
281
|
view,
|
|
274
282
|
baseSchema: jsonSchema,
|
|
275
283
|
change,
|
|
276
284
|
});
|
|
277
|
-
|
|
278
|
-
return model;
|
|
279
285
|
}, [atomRegistry, type, view]);
|
|
280
286
|
|
|
281
287
|
const [expandedField, setExpandedField] = useState<View.FieldType['id']>();
|
|
@@ -286,13 +292,6 @@ const FieldList = ({ type, view, registry, readonly, showHeading = false, onDele
|
|
|
286
292
|
setExpandedField(field.id);
|
|
287
293
|
}, [projectionModel, readonly]);
|
|
288
294
|
|
|
289
|
-
const handleToggleField = useCallback(
|
|
290
|
-
(field: View.FieldType) => {
|
|
291
|
-
setExpandedField((prevExpandedFieldId) => (prevExpandedFieldId === field.id ? undefined : field.id));
|
|
292
|
-
},
|
|
293
|
-
[readonly],
|
|
294
|
-
);
|
|
295
|
-
|
|
296
295
|
const handleDelete = useCallback(
|
|
297
296
|
(fieldId: string) => {
|
|
298
297
|
invariant(!readonly);
|
|
@@ -342,106 +341,77 @@ const FieldList = ({ type, view, registry, readonly, showHeading = false, onDele
|
|
|
342
341
|
}
|
|
343
342
|
|
|
344
343
|
return (
|
|
345
|
-
<
|
|
344
|
+
<OrderedList.Root<View.FieldType>
|
|
346
345
|
items={viewSnapshot.projection.fields as View.FieldType[]}
|
|
347
346
|
isItem={Schema.is(View.FieldSchema)}
|
|
348
347
|
getId={(field) => field.id}
|
|
349
348
|
onMove={readonly ? undefined : handleMove}
|
|
350
349
|
readonly={readonly}
|
|
350
|
+
expandedId={expandedField}
|
|
351
|
+
onExpandedChange={setExpandedField}
|
|
351
352
|
>
|
|
352
353
|
{({ items: fields }) => (
|
|
353
354
|
<>
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
{
|
|
355
|
+
<FieldHeader
|
|
356
|
+
label={t('fields.label')}
|
|
357
|
+
readonly={readonly}
|
|
358
|
+
add={{
|
|
359
|
+
label: t('add-property-button.label'),
|
|
360
|
+
disabled: viewSnapshot.projection.fields.length >= VIEW_FIELD_LIMIT,
|
|
361
|
+
onClick: handleAdd,
|
|
362
|
+
}}
|
|
363
|
+
/>
|
|
364
|
+
{showHeading && <FormFieldLabel standalone classNames='py-1' label={t('field-path.label')} />}
|
|
365
|
+
<OrderedList.Content>
|
|
366
|
+
{fields.map((field) => {
|
|
357
367
|
const hidden = field.visible === false;
|
|
358
368
|
return (
|
|
359
|
-
<
|
|
369
|
+
<OrderedList.DetailItem<View.FieldType>
|
|
360
370
|
key={field.id}
|
|
371
|
+
id={field.id}
|
|
361
372
|
item={field}
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
<
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
373
|
+
canDrag={!readonly && !schemaReadonly}
|
|
374
|
+
expandable={!readonly}
|
|
375
|
+
title={field.path}
|
|
376
|
+
titleClassNames={hidden ? 'text-subdued' : undefined}
|
|
377
|
+
actions={
|
|
378
|
+
<ToggleIconButton
|
|
379
|
+
iconOnly
|
|
380
|
+
variant='ghost'
|
|
381
|
+
active={hidden}
|
|
382
|
+
icon='ph--eye--regular'
|
|
383
|
+
activeIcon='ph--eye-closed--regular'
|
|
371
384
|
label={t(hidden ? 'show-field.label' : 'hide-field.label')}
|
|
372
385
|
data-testid={hidden ? 'show-field-button' : 'hide-field-button'}
|
|
373
|
-
icon={hidden ? 'ph--eye-closed--regular' : 'ph--eye--regular'}
|
|
374
|
-
autoHide={false}
|
|
375
386
|
disabled={readonly || (!hidden && projectionModel.getFields().length <= 1)}
|
|
376
387
|
onClick={() => (hidden ? handleShow(field.path) : handleHide(field.id))}
|
|
377
388
|
/>
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
<List.ItemIconButton
|
|
388
|
-
iconOnly
|
|
389
|
-
variant='ghost'
|
|
390
|
-
label={t('toggle-expand.label', { ns: osTranslations })}
|
|
391
|
-
icon={expandedField === field.id ? 'ph--caret-down--regular' : 'ph--caret-right--regular'}
|
|
392
|
-
onClick={() => handleToggleField(field)}
|
|
393
|
-
data-testid='field.toggle'
|
|
394
|
-
/>
|
|
395
|
-
</>
|
|
396
|
-
)}
|
|
397
|
-
</div>
|
|
398
|
-
{expandedField === field.id && !readonly && (
|
|
399
|
-
<div className='col-span-full mt-1 mb-1 border border-separator rounded-md'>
|
|
400
|
-
<FieldEditor
|
|
401
|
-
readonly={readonly || schemaReadonly}
|
|
402
|
-
registry={registry}
|
|
403
|
-
projection={projectionModel}
|
|
404
|
-
field={field}
|
|
405
|
-
onSave={handleClose}
|
|
389
|
+
}
|
|
390
|
+
trailing={
|
|
391
|
+
!readonly && (
|
|
392
|
+
<CompactIconButton
|
|
393
|
+
icon='ph--x--regular'
|
|
394
|
+
label={t('delete-field.label')}
|
|
395
|
+
disabled={schemaReadonly || viewSnapshot.projection.fields.length <= 1}
|
|
396
|
+
onClick={() => handleDelete(field.id)}
|
|
397
|
+
data-testid='field.delete'
|
|
406
398
|
/>
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
399
|
+
)
|
|
400
|
+
}
|
|
401
|
+
>
|
|
402
|
+
<FieldEditor
|
|
403
|
+
readonly={readonly || schemaReadonly}
|
|
404
|
+
registry={registry}
|
|
405
|
+
projection={projectionModel}
|
|
406
|
+
field={field}
|
|
407
|
+
onSave={handleClose}
|
|
408
|
+
/>
|
|
409
|
+
</OrderedList.DetailItem>
|
|
410
410
|
);
|
|
411
411
|
})}
|
|
412
|
-
</
|
|
413
|
-
{!readonly && !expandedField && (
|
|
414
|
-
<div className='my-form-padding'>
|
|
415
|
-
<IconButton
|
|
416
|
-
icon='ph--plus--regular'
|
|
417
|
-
label={t('add-property-button.label')}
|
|
418
|
-
onClick={handleAdd}
|
|
419
|
-
disabled={viewSnapshot.projection.fields.length >= VIEW_FIELD_LIMIT}
|
|
420
|
-
classNames='w-full'
|
|
421
|
-
/>
|
|
422
|
-
</div>
|
|
423
|
-
)}
|
|
412
|
+
</OrderedList.Content>
|
|
424
413
|
</>
|
|
425
414
|
)}
|
|
426
|
-
</
|
|
415
|
+
</OrderedList.Root>
|
|
427
416
|
);
|
|
428
417
|
};
|
|
429
|
-
|
|
430
|
-
const customFields = ({
|
|
431
|
-
types,
|
|
432
|
-
tags,
|
|
433
|
-
}: Pick<ViewEditorProps, 'types' | 'tags'>): Record<string, FormFieldComponent> => ({
|
|
434
|
-
query: ({ type, readonly, label, getValue, onValueChange }: FormFieldComponentProps) => {
|
|
435
|
-
const handleChange = useCallback<NonNullable<QueryFormProps['onChange']>>(
|
|
436
|
-
(query) => onValueChange(type, query.ast),
|
|
437
|
-
[onValueChange],
|
|
438
|
-
);
|
|
439
|
-
|
|
440
|
-
return (
|
|
441
|
-
<Input.Root>
|
|
442
|
-
<FormFieldLabel readonly={readonly} label={label} />
|
|
443
|
-
<QueryForm initialQuery={getValue()} types={types} tags={tags} onChange={handleChange} />
|
|
444
|
-
</Input.Root>
|
|
445
|
-
);
|
|
446
|
-
},
|
|
447
|
-
});
|
package/src/hooks/index.ts
CHANGED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { createContext } from '@radix-ui/react-context';
|
|
6
|
+
import * as SchemaAST from 'effect/SchemaAST';
|
|
7
|
+
import { useEffect, useMemo, useRef } from 'react';
|
|
8
|
+
|
|
9
|
+
import { type AnyProperties } from '@dxos/echo/internal';
|
|
10
|
+
import { SchemaEx } from '@dxos/effect';
|
|
11
|
+
|
|
12
|
+
import { type CreateOptions, type FormFieldOptions, type FormFieldStateProps } from '#types';
|
|
13
|
+
|
|
14
|
+
import { type FormHandler } from './useFormHandler';
|
|
15
|
+
|
|
16
|
+
//
|
|
17
|
+
// Context
|
|
18
|
+
//
|
|
19
|
+
|
|
20
|
+
export type FormContextValue<T extends AnyProperties = any> = {
|
|
21
|
+
/**
|
|
22
|
+
* Form handler.
|
|
23
|
+
*/
|
|
24
|
+
form: FormHandler<T>;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Testing.
|
|
28
|
+
*/
|
|
29
|
+
testId?: string;
|
|
30
|
+
} & FormFieldOptions &
|
|
31
|
+
Pick<CreateOptions, 'createFieldMap'>;
|
|
32
|
+
|
|
33
|
+
export const [FormContextProvider, useFormContext] = createContext<FormContextValue>('Form');
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Get the current form values.
|
|
37
|
+
*/
|
|
38
|
+
export const useFormValues: {
|
|
39
|
+
<T extends AnyProperties>(componentName: string, path?: (string | number)[]): T;
|
|
40
|
+
<T extends AnyProperties>(
|
|
41
|
+
componentName: string,
|
|
42
|
+
path: (string | number)[] | undefined,
|
|
43
|
+
defaultValue: () => T,
|
|
44
|
+
): T | undefined;
|
|
45
|
+
} = (componentName: string, path?: (string | number)[], defaultValue?: () => any) => {
|
|
46
|
+
const stablePath = useMemo(() => path ?? [], [path ? path.join('.') : undefined]);
|
|
47
|
+
const jsonPath = SchemaEx.createJsonPath(stablePath);
|
|
48
|
+
const {
|
|
49
|
+
form: { values, onValueChange },
|
|
50
|
+
} = useFormContext(componentName);
|
|
51
|
+
|
|
52
|
+
const value = SchemaEx.getValue(values, jsonPath);
|
|
53
|
+
|
|
54
|
+
// Apply default value once when the field has no value. lastAppliedPathRef prevents
|
|
55
|
+
// re-applying on every render (e.g. when defaultValue() returns null) and ensures
|
|
56
|
+
// we apply per path when the hook is used for different fields.
|
|
57
|
+
const lastAppliedPathRef = useRef<string | null>(null);
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
if (value == null && defaultValue && lastAppliedPathRef.current !== jsonPath) {
|
|
60
|
+
lastAppliedPathRef.current = jsonPath;
|
|
61
|
+
onValueChange(stablePath, SchemaAST.stringKeyword, defaultValue());
|
|
62
|
+
}
|
|
63
|
+
}, [value, defaultValue, onValueChange, stablePath, jsonPath]);
|
|
64
|
+
|
|
65
|
+
return value;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Get the state props for the given field.
|
|
70
|
+
*/
|
|
71
|
+
export const useFormFieldState = (componentName: string, path: (string | number)[] = []): FormFieldStateProps => {
|
|
72
|
+
const stablePath = useMemo(() => path, [Array.isArray(path) ? path.join('.') : path]);
|
|
73
|
+
const {
|
|
74
|
+
form: { getStatus, getValue, onBlur, onValueChange },
|
|
75
|
+
} = useFormContext(componentName);
|
|
76
|
+
|
|
77
|
+
return useMemo(
|
|
78
|
+
() => ({
|
|
79
|
+
getStatus: () => getStatus(stablePath),
|
|
80
|
+
getValue: () => getValue(stablePath),
|
|
81
|
+
onBlur: () => onBlur(stablePath),
|
|
82
|
+
onValueChange: (ast: SchemaAST.AST, value: any) => onValueChange(stablePath, ast, value),
|
|
83
|
+
}),
|
|
84
|
+
[getStatus, getValue, onBlur, onValueChange, stablePath],
|
|
85
|
+
);
|
|
86
|
+
};
|
|
@@ -14,10 +14,7 @@ import { useDefaultValue } from '@dxos/react-ui';
|
|
|
14
14
|
import { type ValidationError, validateSchema } from '@dxos/schema';
|
|
15
15
|
import { type MaybePromise } from '@dxos/util';
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
status?: 'error';
|
|
19
|
-
error?: string;
|
|
20
|
-
};
|
|
17
|
+
import { type FormFieldStatus } from '#types';
|
|
21
18
|
|
|
22
19
|
/**
|
|
23
20
|
* Form properties.
|
package/src/index.ts
CHANGED
|
@@ -32,7 +32,7 @@ type TestPanelProps = ThemedClassName<PropsWithChildren>;
|
|
|
32
32
|
|
|
33
33
|
export const TestPanel = slottable<HTMLDivElement, TestPanelProps>(({ children }, forwardedRef) => {
|
|
34
34
|
return (
|
|
35
|
-
<div {...composableProps({ classNames: 'dx-container
|
|
35
|
+
<div {...composableProps({ classNames: 'dx-container dx-card-surface rounded-sm' })} ref={forwardedRef}>
|
|
36
36
|
{children}
|
|
37
37
|
</div>
|
|
38
38
|
);
|