@dxos/react-ui-form 0.8.4-main.c4373fc → 0.8.4-main.c85a9c8dae

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.
Files changed (185) hide show
  1. package/README.md +0 -1
  2. package/dist/lib/browser/index.mjs +2289 -2269
  3. package/dist/lib/browser/index.mjs.map +4 -4
  4. package/dist/lib/browser/meta.json +1 -1
  5. package/dist/lib/node-esm/index.mjs +2289 -2269
  6. package/dist/lib/node-esm/index.mjs.map +4 -4
  7. package/dist/lib/node-esm/meta.json +1 -1
  8. package/dist/types/src/components/FieldEditor/FieldEditor.d.ts +8 -7
  9. package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
  10. package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts +13 -7
  11. package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts.map +1 -1
  12. package/dist/types/src/components/Form/Form.d.ts +81 -26
  13. package/dist/types/src/components/Form/Form.d.ts.map +1 -1
  14. package/dist/types/src/components/Form/Form.stories.d.ts +59 -84
  15. package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
  16. package/dist/types/src/components/Form/FormField.d.ts +37 -0
  17. package/dist/types/src/components/Form/FormField.d.ts.map +1 -0
  18. package/dist/types/src/components/Form/FormFieldComponent.d.ts +78 -0
  19. package/dist/types/src/components/Form/FormFieldComponent.d.ts.map +1 -0
  20. package/dist/types/src/components/Form/FormFieldComponent.stories.d.ts +9 -0
  21. package/dist/types/src/components/Form/FormFieldComponent.stories.d.ts.map +1 -0
  22. package/dist/types/src/components/Form/FormFieldSet.d.ts +19 -0
  23. package/dist/types/src/components/Form/FormFieldSet.d.ts.map +1 -0
  24. package/dist/types/src/components/Form/fields/ArrayField.d.ts +18 -0
  25. package/dist/types/src/components/Form/fields/ArrayField.d.ts.map +1 -0
  26. package/dist/types/src/components/Form/fields/BooleanField.d.ts +4 -0
  27. package/dist/types/src/components/Form/fields/BooleanField.d.ts.map +1 -0
  28. package/dist/types/src/components/Form/fields/GeoPointField.d.ts +5 -0
  29. package/dist/types/src/components/Form/fields/GeoPointField.d.ts.map +1 -0
  30. package/dist/types/src/components/Form/fields/MarkdownField.d.ts +4 -0
  31. package/dist/types/src/components/Form/fields/MarkdownField.d.ts.map +1 -0
  32. package/dist/types/src/components/Form/fields/NumberField.d.ts +4 -0
  33. package/dist/types/src/components/Form/fields/NumberField.d.ts.map +1 -0
  34. package/dist/types/src/components/Form/fields/RefField.d.ts +14 -0
  35. package/dist/types/src/components/Form/fields/RefField.d.ts.map +1 -0
  36. package/dist/types/src/components/Form/fields/SelectField.d.ts +10 -0
  37. package/dist/types/src/components/Form/fields/SelectField.d.ts.map +1 -0
  38. package/dist/types/src/components/Form/fields/SelectOptionField.d.ts +5 -0
  39. package/dist/types/src/components/Form/fields/SelectOptionField.d.ts.map +1 -0
  40. package/dist/types/src/components/{ControlSection/ControlSection.stories.d.ts → Form/fields/SelectOptionField.stories.d.ts} +12 -14
  41. package/dist/types/src/components/Form/fields/SelectOptionField.stories.d.ts.map +1 -0
  42. package/dist/types/src/components/Form/fields/TextAreaField.d.ts +4 -0
  43. package/dist/types/src/components/Form/fields/TextAreaField.d.ts.map +1 -0
  44. package/dist/types/src/components/Form/fields/TextField.d.ts +4 -0
  45. package/dist/types/src/components/Form/fields/TextField.d.ts.map +1 -0
  46. package/dist/types/src/components/Form/fields/TupleField.d.ts +6 -0
  47. package/dist/types/src/components/Form/fields/TupleField.d.ts.map +1 -0
  48. package/dist/types/src/components/Form/fields/index.d.ts +12 -0
  49. package/dist/types/src/components/Form/fields/index.d.ts.map +1 -0
  50. package/dist/types/src/components/Form/index.d.ts +2 -4
  51. package/dist/types/src/components/Form/index.d.ts.map +1 -1
  52. package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts +15 -10
  53. package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts.map +1 -1
  54. package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts +10 -6
  55. package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts.map +1 -1
  56. package/dist/types/src/components/Settings/Settings.d.ts +56 -0
  57. package/dist/types/src/components/Settings/Settings.d.ts.map +1 -0
  58. package/dist/types/src/components/{Form/custom/SelectOptionsInput.stories.d.ts → Settings/Settings.stories.d.ts} +10 -8
  59. package/dist/types/src/components/Settings/Settings.stories.d.ts.map +1 -0
  60. package/dist/types/src/components/Settings/index.d.ts +2 -0
  61. package/dist/types/src/components/Settings/index.d.ts.map +1 -0
  62. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts +16 -16
  63. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
  64. package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts +13 -9
  65. package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
  66. package/dist/types/src/components/index.d.ts +1 -1
  67. package/dist/types/src/components/index.d.ts.map +1 -1
  68. package/dist/types/src/components/testing.d.ts +0 -2
  69. package/dist/types/src/components/testing.d.ts.map +1 -1
  70. package/dist/types/src/hooks/index.d.ts +2 -3
  71. package/dist/types/src/hooks/index.d.ts.map +1 -1
  72. package/dist/types/src/hooks/useFormHandler.d.ts +82 -0
  73. package/dist/types/src/hooks/useFormHandler.d.ts.map +1 -0
  74. package/dist/types/src/hooks/useKeyHandler.d.ts +6 -0
  75. package/dist/types/src/hooks/useKeyHandler.d.ts.map +1 -0
  76. package/dist/types/src/translations.d.ts +10 -7
  77. package/dist/types/src/translations.d.ts.map +1 -1
  78. package/dist/types/src/util/field.d.ts +3 -3
  79. package/dist/types/src/util/field.d.ts.map +1 -1
  80. package/dist/types/src/util/formatting.d.ts +2 -2
  81. package/dist/types/src/util/formatting.d.ts.map +1 -1
  82. package/dist/types/src/util/index.d.ts +1 -1
  83. package/dist/types/src/util/index.d.ts.map +1 -1
  84. package/dist/types/src/util/properties.d.ts +7 -0
  85. package/dist/types/src/util/properties.d.ts.map +1 -0
  86. package/dist/types/src/util/refs.d.ts +1 -2
  87. package/dist/types/src/util/refs.d.ts.map +1 -1
  88. package/dist/types/tsconfig.tsbuildinfo +1 -1
  89. package/package.json +50 -46
  90. package/src/components/FieldEditor/FieldEditor.stories.tsx +43 -24
  91. package/src/components/FieldEditor/FieldEditor.tsx +74 -78
  92. package/src/components/Form/Form.stories.tsx +149 -248
  93. package/src/components/Form/Form.tsx +347 -107
  94. package/src/components/Form/FormField.tsx +294 -0
  95. package/src/components/Form/FormFieldComponent.stories.tsx +65 -0
  96. package/src/components/Form/FormFieldComponent.tsx +172 -0
  97. package/src/components/Form/FormFieldSet.tsx +123 -0
  98. package/src/components/Form/README.md +3 -0
  99. package/src/components/Form/fields/ArrayField.tsx +149 -0
  100. package/src/components/Form/fields/BooleanField.tsx +22 -0
  101. package/src/components/Form/fields/GeoPointField.tsx +120 -0
  102. package/src/components/Form/fields/MarkdownField.tsx +78 -0
  103. package/src/components/Form/fields/NumberField.tsx +39 -0
  104. package/src/components/Form/fields/RefField.tsx +189 -0
  105. package/src/components/Form/fields/SelectField.tsx +65 -0
  106. package/src/components/Form/{custom/SelectOptionsInput.stories.tsx → fields/SelectOptionField.stories.tsx} +19 -16
  107. package/src/components/Form/{custom/SelectOptionsInput.tsx → fields/SelectOptionField.tsx} +23 -17
  108. package/src/components/Form/fields/TextAreaField.tsx +38 -0
  109. package/src/components/Form/fields/TextField.tsx +38 -0
  110. package/src/components/Form/{custom/TupleInput.tsx → fields/TupleField.tsx} +15 -8
  111. package/src/components/Form/fields/index.ts +15 -0
  112. package/src/components/Form/index.ts +3 -4
  113. package/src/components/ObjectPicker/ObjectPicker.stories.tsx +40 -37
  114. package/src/components/ObjectPicker/ObjectPicker.tsx +84 -70
  115. package/src/components/Settings/Settings.stories.tsx +56 -0
  116. package/src/components/Settings/Settings.tsx +230 -0
  117. package/src/components/{ControlSection → Settings}/index.ts +1 -1
  118. package/src/components/ViewEditor/ViewEditor.stories.tsx +69 -49
  119. package/src/components/ViewEditor/ViewEditor.test.tsx +8 -6
  120. package/src/components/ViewEditor/ViewEditor.tsx +302 -271
  121. package/src/components/index.ts +1 -1
  122. package/src/components/testing.tsx +12 -7
  123. package/src/hooks/index.ts +2 -3
  124. package/src/hooks/useFormHandler.ts +380 -0
  125. package/src/hooks/useKeyHandler.tsx +37 -0
  126. package/src/translations.ts +12 -10
  127. package/src/util/field.ts +25 -25
  128. package/src/util/formatting.ts +22 -22
  129. package/src/util/index.ts +1 -1
  130. package/src/util/properties.ts +18 -0
  131. package/src/util/refs.ts +11 -17
  132. package/dist/types/src/components/ControlSection/ControlSection.d.ts +0 -23
  133. package/dist/types/src/components/ControlSection/ControlSection.d.ts.map +0 -1
  134. package/dist/types/src/components/ControlSection/ControlSection.stories.d.ts.map +0 -1
  135. package/dist/types/src/components/ControlSection/index.d.ts +0 -2
  136. package/dist/types/src/components/ControlSection/index.d.ts.map +0 -1
  137. package/dist/types/src/components/Form/ArrayField.d.ts +0 -16
  138. package/dist/types/src/components/Form/ArrayField.d.ts.map +0 -1
  139. package/dist/types/src/components/Form/Defaults.d.ts +0 -14
  140. package/dist/types/src/components/Form/Defaults.d.ts.map +0 -1
  141. package/dist/types/src/components/Form/FormActions.d.ts +0 -9
  142. package/dist/types/src/components/Form/FormActions.d.ts.map +0 -1
  143. package/dist/types/src/components/Form/FormContent.d.ts +0 -63
  144. package/dist/types/src/components/Form/FormContent.d.ts.map +0 -1
  145. package/dist/types/src/components/Form/FormContext.d.ts +0 -23
  146. package/dist/types/src/components/Form/FormContext.d.ts.map +0 -1
  147. package/dist/types/src/components/Form/Input.d.ts +0 -29
  148. package/dist/types/src/components/Form/Input.d.ts.map +0 -1
  149. package/dist/types/src/components/Form/RefField.d.ts +0 -21
  150. package/dist/types/src/components/Form/RefField.d.ts.map +0 -1
  151. package/dist/types/src/components/Form/custom/GeoPointInput.d.ts +0 -4
  152. package/dist/types/src/components/Form/custom/GeoPointInput.d.ts.map +0 -1
  153. package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts +0 -4
  154. package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts.map +0 -1
  155. package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts.map +0 -1
  156. package/dist/types/src/components/Form/custom/TupleInput.d.ts +0 -6
  157. package/dist/types/src/components/Form/custom/TupleInput.d.ts.map +0 -1
  158. package/dist/types/src/components/Form/custom/index.d.ts +0 -4
  159. package/dist/types/src/components/Form/custom/index.d.ts.map +0 -1
  160. package/dist/types/src/components/Form/factory.d.ts +0 -8
  161. package/dist/types/src/components/Form/factory.d.ts.map +0 -1
  162. package/dist/types/src/hooks/useForm.d.ts +0 -67
  163. package/dist/types/src/hooks/useForm.d.ts.map +0 -1
  164. package/dist/types/src/hooks/useQueryRefOptions.d.ts +0 -28
  165. package/dist/types/src/hooks/useQueryRefOptions.d.ts.map +0 -1
  166. package/dist/types/src/hooks/useRefQueryLookupHandler.d.ts +0 -8
  167. package/dist/types/src/hooks/useRefQueryLookupHandler.d.ts.map +0 -1
  168. package/dist/types/src/util/schema.d.ts +0 -3
  169. package/dist/types/src/util/schema.d.ts.map +0 -1
  170. package/src/components/ControlSection/ControlSection.stories.tsx +0 -38
  171. package/src/components/ControlSection/ControlSection.tsx +0 -153
  172. package/src/components/Form/ArrayField.tsx +0 -125
  173. package/src/components/Form/Defaults.tsx +0 -205
  174. package/src/components/Form/FormActions.tsx +0 -54
  175. package/src/components/Form/FormContent.tsx +0 -322
  176. package/src/components/Form/FormContext.tsx +0 -110
  177. package/src/components/Form/Input.tsx +0 -54
  178. package/src/components/Form/RefField.tsx +0 -269
  179. package/src/components/Form/custom/GeoPointInput.tsx +0 -80
  180. package/src/components/Form/custom/index.ts +0 -7
  181. package/src/components/Form/factory.tsx +0 -31
  182. package/src/hooks/useForm.ts +0 -295
  183. package/src/hooks/useQueryRefOptions.ts +0 -59
  184. package/src/hooks/useRefQueryLookupHandler.ts +0 -39
  185. package/src/util/schema.ts +0 -12
package/package.json CHANGED
@@ -1,9 +1,13 @@
1
1
  {
2
2
  "name": "@dxos/react-ui-form",
3
- "version": "0.8.4-main.c4373fc",
3
+ "version": "0.8.4-main.c85a9c8dae",
4
4
  "description": "Data components.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/dxos/dxos"
10
+ },
7
11
  "license": "MIT",
8
12
  "author": "DXOS.org",
9
13
  "type": "module",
@@ -24,58 +28,58 @@
24
28
  "src"
25
29
  ],
26
30
  "dependencies": {
27
- "@atlaskit/pragmatic-drag-and-drop": "^1.4.0",
28
- "@atlaskit/pragmatic-drag-and-drop-hitbox": "^1.0.3",
29
- "@fluentui/react-tabster": "^9.24.2",
30
- "@preact-signals/safe-react": "^0.9.0",
31
- "@preact/signals-react": "^3.2.0",
31
+ "@atlaskit/pragmatic-drag-and-drop": "1.7.7",
32
+ "@atlaskit/pragmatic-drag-and-drop-hitbox": "1.1.0",
33
+ "@effect-atom/atom-react": "^0.5.0",
34
+ "@fluentui/react-tabster": "9.26.11",
32
35
  "@radix-ui/react-context": "1.1.1",
36
+ "@radix-ui/react-use-controllable-state": "1.1.0",
33
37
  "date-fns": "^3.3.1",
34
- "jsonpath": "^1.1.1",
35
- "@dxos/async": "0.8.4-main.c4373fc",
36
- "@dxos/debug": "0.8.4-main.c4373fc",
37
- "@dxos/echo": "0.8.4-main.c4373fc",
38
- "@dxos/echo-db": "0.8.4-main.c4373fc",
39
- "@dxos/echo-query": "0.8.4-main.c4373fc",
40
- "@dxos/effect": "0.8.4-main.c4373fc",
41
- "@dxos/invariant": "0.8.4-main.c4373fc",
42
- "@dxos/keys": "0.8.4-main.c4373fc",
43
- "@dxos/lit-ui": "0.8.4-main.c4373fc",
44
- "@dxos/live-object": "0.8.4-main.c4373fc",
45
- "@dxos/log": "0.8.4-main.c4373fc",
46
- "@dxos/react-ui-editor": "0.8.4-main.c4373fc",
47
- "@dxos/react-ui-components": "0.8.4-main.c4373fc",
48
- "@dxos/react-ui-list": "0.8.4-main.c4373fc",
49
- "@dxos/react-ui-pickers": "0.8.4-main.c4373fc",
50
- "@dxos/react-client": "0.8.4-main.c4373fc",
51
- "@dxos/react-ui-stack": "0.8.4-main.c4373fc",
52
- "@dxos/react-ui-searchlist": "0.8.4-main.c4373fc",
53
- "@dxos/schema": "0.8.4-main.c4373fc",
54
- "@dxos/react-ui-types": "0.8.4-main.c4373fc",
55
- "@dxos/util": "0.8.4-main.c4373fc"
38
+ "tabster": "^8.5.5",
39
+ "@dxos/async": "0.8.4-main.c85a9c8dae",
40
+ "@dxos/echo": "0.8.4-main.c85a9c8dae",
41
+ "@dxos/echo-react": "0.8.4-main.c85a9c8dae",
42
+ "@dxos/echo-query": "0.8.4-main.c85a9c8dae",
43
+ "@dxos/invariant": "0.8.4-main.c85a9c8dae",
44
+ "@dxos/effect": "0.8.4-main.c85a9c8dae",
45
+ "@dxos/lit-ui": "0.8.4-main.c85a9c8dae",
46
+ "@dxos/keys": "0.8.4-main.c85a9c8dae",
47
+ "@dxos/log": "0.8.4-main.c85a9c8dae",
48
+ "@dxos/react-client": "0.8.4-main.c85a9c8dae",
49
+ "@dxos/react-ui-components": "0.8.4-main.c85a9c8dae",
50
+ "@dxos/react-ui-editor": "0.8.4-main.c85a9c8dae",
51
+ "@dxos/debug": "0.8.4-main.c85a9c8dae",
52
+ "@dxos/react-ui-list": "0.8.4-main.c85a9c8dae",
53
+ "@dxos/react-ui-mosaic": "0.8.4-main.c85a9c8dae",
54
+ "@dxos/react-ui-stack": "0.8.4-main.c85a9c8dae",
55
+ "@dxos/react-ui-pickers": "0.8.4-main.c85a9c8dae",
56
+ "@dxos/schema": "0.8.4-main.c85a9c8dae",
57
+ "@dxos/react-ui-searchlist": "0.8.4-main.c85a9c8dae",
58
+ "@dxos/types": "0.8.4-main.c85a9c8dae",
59
+ "@dxos/ui-types": "0.8.4-main.c85a9c8dae",
60
+ "@dxos/util": "0.8.4-main.c85a9c8dae"
56
61
  },
57
62
  "devDependencies": {
58
- "@types/jsonpath": "^0.2.4",
59
- "@types/react": "~19.2.2",
60
- "@types/react-dom": "~19.2.1",
61
- "effect": "3.18.3",
63
+ "@types/react": "~19.2.7",
64
+ "@types/react-dom": "~19.2.3",
65
+ "effect": "3.19.16",
62
66
  "fast-check": "^3.19.0",
63
- "react": "~19.2.0",
64
- "react-dom": "~19.2.0",
65
- "vite": "7.1.9",
66
- "@dxos/random": "0.8.4-main.c4373fc",
67
- "@dxos/react-ui": "0.8.4-main.c4373fc",
68
- "@dxos/echo-signals": "0.8.4-main.c4373fc",
69
- "@dxos/storybook-utils": "0.8.4-main.c4373fc",
70
- "@dxos/react-ui-syntax-highlighter": "0.8.4-main.c4373fc",
71
- "@dxos/react-ui-theme": "0.8.4-main.c4373fc"
67
+ "react": "~19.2.3",
68
+ "react-dom": "~19.2.3",
69
+ "vite": "^7.1.11",
70
+ "@dxos/random": "0.8.4-main.c85a9c8dae",
71
+ "@dxos/react-ui": "0.8.4-main.c85a9c8dae",
72
+ "@dxos/react-ui-syntax-highlighter": "0.8.4-main.c85a9c8dae",
73
+ "@dxos/react-client": "0.8.4-main.c85a9c8dae",
74
+ "@dxos/ui-theme": "0.8.4-main.c85a9c8dae",
75
+ "@dxos/storybook-utils": "0.8.4-main.c85a9c8dae"
72
76
  },
73
77
  "peerDependencies": {
74
- "effect": "^3.13.3",
75
- "react": "^19.0.0",
76
- "react-dom": "^19.0.0",
77
- "@dxos/react-ui": "0.8.4-main.c4373fc",
78
- "@dxos/react-ui-theme": "0.8.4-main.c4373fc"
78
+ "effect": "3.19.16",
79
+ "react": "~19.2.3",
80
+ "react-dom": "~19.2.3",
81
+ "@dxos/react-ui": "0.8.4-main.c85a9c8dae",
82
+ "@dxos/ui-theme": "0.8.4-main.c85a9c8dae"
79
83
  },
80
84
  "publishConfig": {
81
85
  "access": "public"
@@ -5,51 +5,73 @@
5
5
  import { type Meta, type StoryObj } from '@storybook/react-vite';
6
6
  import React, { useEffect, useMemo } from 'react';
7
7
 
8
+ import { Filter, Query } from '@dxos/echo';
8
9
  import { createEchoSchema } from '@dxos/echo/testing';
9
10
  import { log } from '@dxos/log';
10
- import { withTheme } from '@dxos/react-ui/testing';
11
- import { ProjectionModel } from '@dxos/schema';
12
- import { TestSchema, testView } from '@dxos/schema/testing';
11
+ import { withLayout, withTheme } from '@dxos/react-ui/testing';
12
+ import { ProjectionModel, ViewModel, createEchoChangeCallback } from '@dxos/schema';
13
+ import { Example } from '@dxos/schema/testing';
13
14
 
14
15
  import { translations } from '../../translations';
15
- import { FIELD_EDITOR_DEBUG_SYMBOL, TestLayout, TestPanel } from '../testing';
16
+ import { FIELD_EDITOR_DEBUG_SYMBOL, TestLayout } from '../testing';
16
17
 
17
18
  import { FieldEditor, type FieldEditorProps } from './FieldEditor';
18
19
 
19
- // Type definition for debug objects exposed to tests.
20
20
  export type FieldEditorDebugObjects = {
21
21
  props: FieldEditorProps;
22
22
  projection: ProjectionModel;
23
23
  };
24
24
 
25
- const DefaultStory = (props: FieldEditorProps) => {
25
+ const useTestProjection = () => {
26
+ return useMemo(() => {
27
+ const schema = createEchoSchema(Example);
28
+ const view = ViewModel.make({
29
+ name: 'Test',
30
+ query: Query.select(Filter.type(Example)),
31
+ jsonSchema: schema.jsonSchema,
32
+ });
33
+ const projection = new ProjectionModel({
34
+ view,
35
+ baseSchema: schema.jsonSchema,
36
+ change: createEchoChangeCallback(view, schema),
37
+ });
38
+ projection.normalizeView();
39
+ return { view, projection };
40
+ }, []);
41
+ };
42
+
43
+ const DefaultStory = () => {
44
+ const { view, projection } = useTestProjection();
45
+
26
46
  const handleComplete: FieldEditorProps['onSave'] = () => {
27
- log.info('onClose', { props });
47
+ log.info('onClose');
48
+ };
49
+
50
+ const props: FieldEditorProps = {
51
+ projection,
52
+ field: view.projection.fields[0],
53
+ onSave: handleComplete,
28
54
  };
29
55
 
30
56
  // Expose objects on window for test access.
31
57
  useEffect(() => {
32
- props.projection.normalizeView();
33
-
34
58
  if (typeof window !== 'undefined') {
35
59
  (window as any)[FIELD_EDITOR_DEBUG_SYMBOL] = {
36
60
  props,
37
- projection: props.projection,
61
+ projection,
38
62
  } satisfies FieldEditorDebugObjects;
39
63
  }
40
- }, [props, props.projection]);
64
+ }, [props, projection]);
41
65
 
42
66
  // NOTE(ZaymonFC): This looks awkward but it resolves an infinite parsing issue with sb.
43
67
  const json = useMemo(
44
- () => JSON.parse(JSON.stringify({ props, projection: props.projection })),
45
- [JSON.stringify(props), JSON.stringify(props.projection)],
68
+ () => JSON.parse(JSON.stringify({ props, projection })),
69
+ [JSON.stringify(props), JSON.stringify(projection)],
46
70
  );
47
71
 
48
72
  return (
49
73
  <TestLayout json={json}>
50
- <TestPanel>
51
- <FieldEditor {...props} onSave={handleComplete} />
52
- </TestPanel>
74
+ <FieldEditor {...props} />
53
75
  </TestLayout>
54
76
  );
55
77
  };
@@ -58,10 +80,13 @@ const meta = {
58
80
  title: 'ui/react-ui-form/FieldEditor',
59
81
  component: FieldEditor as any,
60
82
  render: DefaultStory,
61
- decorators: [withTheme],
83
+ decorators: [withTheme(), withLayout({ layout: 'fullscreen' })],
62
84
  parameters: {
63
85
  layout: 'fullscreen',
64
86
  translations,
87
+ controls: {
88
+ disabled: true,
89
+ },
65
90
  },
66
91
  } satisfies Meta<typeof DefaultStory>;
67
92
 
@@ -69,10 +94,4 @@ export default meta;
69
94
 
70
95
  type Story = StoryObj<typeof meta>;
71
96
 
72
- export const Default: Story = {
73
- args: {
74
- projection: new ProjectionModel(createEchoSchema(TestSchema).jsonSchema, testView.projection),
75
- field: testView.projection.fields[0],
76
- },
77
- parameters: { controls: { disabled: true } },
78
- };
97
+ export const Default: Story = {};
@@ -4,44 +4,35 @@
4
4
 
5
5
  import React, { useCallback, useEffect, useMemo, useState } from 'react';
6
6
 
7
- import { type EchoSchema, FormatEnum, FormatEnums, formatToType } from '@dxos/echo/internal';
8
- import { type SchemaRegistry } from '@dxos/echo-db';
7
+ import { Obj, type SchemaRegistry, type View } from '@dxos/echo';
8
+ import { type EchoSchema, Format, FormatEnums, formatToType } from '@dxos/echo/internal';
9
+ import { type SchemaProperty } from '@dxos/effect';
9
10
  import { log } from '@dxos/log';
10
11
  import { useAsyncEffect, useTranslation } from '@dxos/react-ui';
11
12
  import {
12
- type FieldType,
13
13
  type ProjectionModel,
14
14
  type PropertyType,
15
- type SchemaProperty,
16
15
  formatToAdditionalPropertyAttributes,
17
16
  getFormatSchema,
18
- getSchemaProperties,
19
- sortProperties,
20
17
  } from '@dxos/schema';
21
18
 
22
19
  import { translationKey } from '../../translations';
23
- import { Form, type FormProps, type InputComponent, SelectInput, SelectOptionInput } from '../Form';
20
+ import { getFormProperties } from '../../util';
21
+ import { Form, type FormFieldMap, type FormRootProps, SelectField, SelectOptionField } from '../Form';
24
22
 
25
23
  export type FieldEditorProps = {
26
24
  projection: ProjectionModel;
27
- field: FieldType;
28
- registry?: SchemaRegistry;
25
+ field: View.FieldType;
26
+ registry?: SchemaRegistry.SchemaRegistry;
27
+ view?: Obj.Unknown;
29
28
  onSave: () => void;
30
29
  onCancel?: () => void;
31
- } & Pick<FormProps<any>, 'outerSpacing' | 'readonly'>;
30
+ } & Pick<FormRootProps<any>, 'readonly'>;
32
31
 
33
32
  /**
34
33
  * Displays a Form representing the metadata for a given `Field` and `View`.
35
34
  */
36
- export const FieldEditor = ({
37
- readonly,
38
- projection,
39
- field,
40
- registry,
41
- onSave,
42
- onCancel,
43
- outerSpacing,
44
- }: FieldEditorProps) => {
35
+ export const FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCancel }: FieldEditorProps) => {
45
36
  const { t } = useTranslation(translationKey);
46
37
  const [props, setProps] = useState<PropertyType>(projection.getFieldProjection(field.id).props);
47
38
  useEffect(() => setProps(projection.getFieldProjection(field.id).props), [field, projection]);
@@ -70,11 +61,47 @@ export const FieldEditor = ({
70
61
  // Class constructor SchemaClass cannot be invoked without 'new'.
71
62
  const [{ fieldSchema }, setFieldSchema] = useState({ fieldSchema: getFormatSchema(props?.format) });
72
63
 
73
- const handleValuesChanged = useCallback<NonNullable<FormProps<PropertyType>['onValuesChanged']>>(
64
+ const fieldMap = useMemo<FormFieldMap>(
65
+ () => ({
66
+ ['format' satisfies keyof PropertyType]: (props) => (
67
+ <SelectField
68
+ {...props}
69
+ options={FormatEnums.filter((value) => value !== Format.TypeFormat.None).map((value) => ({
70
+ value,
71
+ label: t(`format ${value}`),
72
+ }))}
73
+ />
74
+ ),
75
+ ['referenceSchema' satisfies keyof PropertyType]: (props) => (
76
+ <SelectField
77
+ {...props}
78
+ options={schemas.map((schema) => ({
79
+ value: schema.typename,
80
+ }))}
81
+ />
82
+ ),
83
+ ['referencePath' satisfies keyof PropertyType]: (props) => (
84
+ <SelectField
85
+ {...props}
86
+ options={
87
+ referenceSchema
88
+ ? getFormProperties(referenceSchema.ast)
89
+ .sort((a, b) => a.name.toString().localeCompare(b.name.toString()))
90
+ .map((p) => ({ value: p.name.toString() }))
91
+ : []
92
+ }
93
+ />
94
+ ),
95
+ ['options' satisfies keyof PropertyType]: (props) => <SelectOptionField {...props} />,
96
+ }),
97
+ [t, schemas, referenceSchema],
98
+ );
99
+
100
+ const propIsNotType = useCallback((props: SchemaProperty[]) => props.filter((prop) => prop.name !== 'type'), []);
101
+
102
+ const handleValuesChanged = useCallback<NonNullable<FormRootProps<PropertyType>['onValuesChanged']>>(
74
103
  (_props) => {
75
- // TODO(burdon): Callback should pass `changed` to indicate which fields have changed.
76
- // TODO(Zaymon): Workout why old and new format values are the same sometimes even when
77
- // selecting novel format values.
104
+ // TODO(Zaymon): Workout why old and new format values are the same sometimes even when selecting novel format values.
78
105
  setFieldSchema((prev) => {
79
106
  const fieldSchema = getFormatSchema(_props.format);
80
107
  if (prev.fieldSchema === fieldSchema) {
@@ -107,9 +134,9 @@ export const FieldEditor = ({
107
134
  [schemas, props.format, props.referenceSchema],
108
135
  );
109
136
 
110
- const handleValidate = useCallback<NonNullable<FormProps<PropertyType>['onValidate']>>(
137
+ const handleValidate = useCallback<NonNullable<FormRootProps<PropertyType>['onValidate']>>(
111
138
  ({ property }) => {
112
- if (property && projection.fields.find((f) => f.path === property && f.path !== field.path)) {
139
+ if (property && projection.getFields().find((f) => f.path === property && f.path !== field.path)) {
113
140
  return [
114
141
  {
115
142
  path: 'property',
@@ -118,84 +145,53 @@ export const FieldEditor = ({
118
145
  ];
119
146
  }
120
147
  },
121
- [projection.fields, field],
148
+ [projection.getFields(), field],
122
149
  );
123
150
 
124
- const handleSave = useCallback<NonNullable<FormProps<PropertyType>['onSave']>>(
151
+ const handleSave = useCallback<NonNullable<FormRootProps<PropertyType>['onSave']>>(
125
152
  (props) => {
126
- projection.setFieldProjection({ field, props });
153
+ if (view) {
154
+ Obj.change(view, () => {
155
+ projection.setFieldProjection({ field, props });
156
+ });
157
+ } else {
158
+ projection.setFieldProjection({ field, props });
159
+ }
127
160
  onSave();
128
161
  },
129
- [projection, field, onSave],
162
+ [projection, field, view, onSave],
130
163
  );
131
164
 
132
- const handleCancel = useCallback<NonNullable<FormProps<PropertyType>['onCancel']>>(() => {
165
+ const handleCancel = useCallback<NonNullable<FormRootProps<PropertyType>['onCancel']>>(() => {
166
+ onSave();
133
167
  // Need to defer to allow form to close.
134
168
  requestAnimationFrame(() => onCancel?.());
135
- onSave();
136
169
  }, [onSave]);
137
170
 
138
- const custom: Partial<Record<string, InputComponent>> = useMemo(
139
- () => ({
140
- ['format' satisfies keyof PropertyType]: (props) => (
141
- <SelectInput
142
- {...props}
143
- options={FormatEnums.filter((value) => value !== FormatEnum.None).map((value) => ({
144
- value,
145
- label: t(`format ${value}`),
146
- }))}
147
- />
148
- ),
149
- ['referenceSchema' satisfies keyof PropertyType]: (props) => (
150
- <SelectInput
151
- {...props}
152
- options={schemas.map((schema) => ({
153
- value: schema.typename,
154
- }))}
155
- />
156
- ),
157
- ['referencePath' satisfies keyof PropertyType]: (props) => (
158
- <SelectInput
159
- {...props}
160
- options={
161
- referenceSchema
162
- ? getSchemaProperties(referenceSchema.ast)
163
- .sort(sortProperties)
164
- .map((p) => ({ value: p.name }))
165
- : []
166
- }
167
- />
168
- ),
169
- ['options' satisfies keyof PropertyType]: (props) => <SelectOptionInput {...props} />,
170
- }),
171
- [t, schemas, referenceSchema],
172
- );
173
-
174
- const propIsNotType = useCallback(
175
- (props: SchemaProperty<PropertyType>[]) => props.filter((p) => p.name !== 'type'),
176
- [],
177
- );
178
-
179
171
  if (!fieldSchema) {
180
172
  log.warn('invalid format', { props });
181
173
  return null;
182
174
  }
183
175
 
184
176
  return (
185
- <Form<PropertyType>
177
+ <Form.Root<PropertyType>
186
178
  key={field.id}
179
+ fieldMap={fieldMap}
187
180
  autoFocus
188
181
  readonly={readonly}
189
- values={props}
190
182
  schema={fieldSchema}
191
- filter={propIsNotType}
183
+ values={props}
184
+ exclude={propIsNotType}
192
185
  sort={['property', 'format']}
193
186
  onValuesChanged={handleValuesChanged}
194
187
  onValidate={handleValidate}
195
188
  onSave={handleSave}
196
189
  onCancel={handleCancel}
197
- Custom={custom}
198
- outerSpacing={outerSpacing}
199
- />
190
+ >
191
+ <Form.Content>
192
+ <Form.FieldSet />
193
+ <Form.Actions />
194
+ </Form.Content>
195
+ </Form.Root>
200
196
  );
201
197
  };