@dxos/react-ui-form 0.8.4-main.f9ba587 → 0.8.4-main.fcfe5033a5

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 (229) hide show
  1. package/README.md +0 -1
  2. package/dist/lib/browser/index.mjs +2758 -2113
  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 +2758 -2113
  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 +9 -9
  9. package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
  10. package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts +85 -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 +86 -25
  13. package/dist/types/src/components/Form/Form.d.ts.map +1 -1
  14. package/dist/types/src/components/Form/Form.stories.d.ts +129 -56
  15. package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
  16. package/dist/types/src/components/Form/FormField.d.ts +43 -0
  17. package/dist/types/src/components/Form/FormField.d.ts.map +1 -0
  18. package/dist/types/src/components/Form/FormFieldComponent.d.ts +77 -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 +18 -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 +16 -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/Form/fields/SelectOptionField.stories.d.ts +83 -0
  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/ObjectForm/ObjectForm.d.ts +9 -0
  53. package/dist/types/src/components/ObjectForm/ObjectForm.d.ts.map +1 -0
  54. package/dist/types/src/components/ObjectForm/index.d.ts +2 -0
  55. package/dist/types/src/components/ObjectForm/index.d.ts.map +1 -0
  56. package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts +54 -0
  57. package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts.map +1 -0
  58. package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts +86 -0
  59. package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts.map +1 -0
  60. package/dist/types/src/components/ObjectPicker/index.d.ts +2 -0
  61. package/dist/types/src/components/ObjectPicker/index.d.ts.map +1 -0
  62. package/dist/types/src/components/ObjectProperties/ObjectProperties.d.ts +9 -0
  63. package/dist/types/src/components/ObjectProperties/ObjectProperties.d.ts.map +1 -0
  64. package/dist/types/src/components/ObjectProperties/ObjectProperties.stories.d.ts +83 -0
  65. package/dist/types/src/components/ObjectProperties/ObjectProperties.stories.d.ts.map +1 -0
  66. package/dist/types/src/components/ObjectProperties/index.d.ts +2 -0
  67. package/dist/types/src/components/ObjectProperties/index.d.ts.map +1 -0
  68. package/dist/types/src/components/Settings/Settings.d.ts +43 -0
  69. package/dist/types/src/components/Settings/Settings.d.ts.map +1 -0
  70. package/dist/types/src/components/Settings/Settings.stories.d.ts +83 -0
  71. package/dist/types/src/components/Settings/Settings.stories.d.ts.map +1 -0
  72. package/dist/types/src/components/Settings/SettingsFieldSet.d.ts +38 -0
  73. package/dist/types/src/components/Settings/SettingsFieldSet.d.ts.map +1 -0
  74. package/dist/types/src/components/Settings/SettingsItem.d.ts +17 -0
  75. package/dist/types/src/components/Settings/SettingsItem.d.ts.map +1 -0
  76. package/dist/types/src/components/Settings/index.d.ts +3 -0
  77. package/dist/types/src/components/Settings/index.d.ts.map +1 -0
  78. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts +22 -10
  79. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
  80. package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts +86 -9
  81. package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
  82. package/dist/types/src/components/index.d.ts +4 -2
  83. package/dist/types/src/components/index.d.ts.map +1 -1
  84. package/dist/types/src/components/testing.d.ts +4 -4
  85. package/dist/types/src/components/testing.d.ts.map +1 -1
  86. package/dist/types/src/hooks/index.d.ts +2 -3
  87. package/dist/types/src/hooks/index.d.ts.map +1 -1
  88. package/dist/types/src/hooks/useFormHandler.d.ts +82 -0
  89. package/dist/types/src/hooks/useFormHandler.d.ts.map +1 -0
  90. package/dist/types/src/hooks/useKeyHandler.d.ts +7 -0
  91. package/dist/types/src/hooks/useKeyHandler.d.ts.map +1 -0
  92. package/dist/types/src/translations.d.ts +64 -54
  93. package/dist/types/src/translations.d.ts.map +1 -1
  94. package/dist/types/src/util/field-type.d.ts +19 -0
  95. package/dist/types/src/util/field-type.d.ts.map +1 -0
  96. package/dist/types/src/util/field.d.ts +3 -3
  97. package/dist/types/src/util/field.d.ts.map +1 -1
  98. package/dist/types/src/util/formatting.d.ts +2 -2
  99. package/dist/types/src/util/formatting.d.ts.map +1 -1
  100. package/dist/types/src/util/index.d.ts +2 -1
  101. package/dist/types/src/util/index.d.ts.map +1 -1
  102. package/dist/types/src/util/properties.d.ts +7 -0
  103. package/dist/types/src/util/properties.d.ts.map +1 -0
  104. package/dist/types/src/util/refs.d.ts +3 -3
  105. package/dist/types/src/util/refs.d.ts.map +1 -1
  106. package/dist/types/tsconfig.tsbuildinfo +1 -1
  107. package/package.json +46 -43
  108. package/src/components/FieldEditor/FieldEditor.stories.tsx +51 -31
  109. package/src/components/FieldEditor/FieldEditor.test.tsx +13 -13
  110. package/src/components/FieldEditor/FieldEditor.tsx +88 -94
  111. package/src/components/Form/AUDIT.md +17 -0
  112. package/src/components/Form/Form.stories.tsx +144 -221
  113. package/src/components/Form/Form.tsx +359 -95
  114. package/src/components/Form/FormField.tsx +304 -0
  115. package/src/components/Form/FormFieldComponent.stories.tsx +65 -0
  116. package/src/components/Form/FormFieldComponent.tsx +171 -0
  117. package/src/components/Form/FormFieldSet.tsx +144 -0
  118. package/src/components/Form/README.md +3 -0
  119. package/src/components/Form/fields/ArrayField.tsx +154 -0
  120. package/src/components/Form/fields/BooleanField.tsx +22 -0
  121. package/src/components/Form/fields/GeoPointField.tsx +120 -0
  122. package/src/components/Form/fields/MarkdownField.tsx +78 -0
  123. package/src/components/Form/fields/NumberField.tsx +39 -0
  124. package/src/components/Form/fields/RefField.tsx +198 -0
  125. package/src/components/Form/fields/SelectField.tsx +65 -0
  126. package/src/components/Form/fields/SelectOptionField.stories.tsx +65 -0
  127. package/src/components/Form/{custom/SelectOptionsInput.tsx → fields/SelectOptionField.tsx} +49 -45
  128. package/src/components/Form/fields/TextAreaField.tsx +38 -0
  129. package/src/components/Form/fields/TextField.tsx +38 -0
  130. package/src/components/Form/{custom/TupleInput.tsx → fields/TupleField.tsx} +17 -10
  131. package/src/components/Form/fields/index.ts +15 -0
  132. package/src/components/Form/index.ts +3 -4
  133. package/src/components/ObjectForm/ObjectForm.tsx +113 -0
  134. package/src/components/{ControlSection → ObjectForm}/index.ts +1 -1
  135. package/src/components/ObjectPicker/ObjectPicker.stories.tsx +209 -0
  136. package/src/components/ObjectPicker/ObjectPicker.tsx +186 -0
  137. package/src/components/ObjectPicker/index.ts +5 -0
  138. package/src/components/ObjectProperties/ObjectProperties.stories.tsx +63 -0
  139. package/src/components/ObjectProperties/ObjectProperties.tsx +129 -0
  140. package/src/components/ObjectProperties/index.ts +5 -0
  141. package/src/components/Settings/Settings.stories.tsx +103 -0
  142. package/src/components/Settings/Settings.tsx +81 -0
  143. package/src/components/Settings/SettingsFieldSet.tsx +211 -0
  144. package/src/components/Settings/SettingsItem.tsx +62 -0
  145. package/src/components/Settings/index.ts +6 -0
  146. package/src/components/ViewEditor/ViewEditor.stories.tsx +144 -61
  147. package/src/components/ViewEditor/ViewEditor.test.tsx +22 -22
  148. package/src/components/ViewEditor/ViewEditor.tsx +353 -218
  149. package/src/components/index.ts +4 -3
  150. package/src/components/testing.tsx +28 -12
  151. package/src/hooks/index.ts +2 -3
  152. package/src/hooks/useFormHandler.ts +380 -0
  153. package/src/hooks/useKeyHandler.tsx +37 -0
  154. package/src/translations.ts +67 -58
  155. package/src/util/field-type.ts +57 -0
  156. package/src/util/field.ts +33 -43
  157. package/src/util/formatting.ts +22 -22
  158. package/src/util/index.ts +2 -1
  159. package/src/util/properties.ts +18 -0
  160. package/src/util/refs.ts +17 -19
  161. package/dist/types/src/components/ControlSection/ControlSection.d.ts +0 -23
  162. package/dist/types/src/components/ControlSection/ControlSection.d.ts.map +0 -1
  163. package/dist/types/src/components/ControlSection/ControlSection.stories.d.ts +0 -8
  164. package/dist/types/src/components/ControlSection/ControlSection.stories.d.ts.map +0 -1
  165. package/dist/types/src/components/ControlSection/index.d.ts +0 -2
  166. package/dist/types/src/components/ControlSection/index.d.ts.map +0 -1
  167. package/dist/types/src/components/Form/ArrayField.d.ts +0 -16
  168. package/dist/types/src/components/Form/ArrayField.d.ts.map +0 -1
  169. package/dist/types/src/components/Form/Defaults.d.ts +0 -14
  170. package/dist/types/src/components/Form/Defaults.d.ts.map +0 -1
  171. package/dist/types/src/components/Form/FormActions.d.ts +0 -9
  172. package/dist/types/src/components/Form/FormActions.d.ts.map +0 -1
  173. package/dist/types/src/components/Form/FormContent.d.ts +0 -57
  174. package/dist/types/src/components/Form/FormContent.d.ts.map +0 -1
  175. package/dist/types/src/components/Form/FormContext.d.ts +0 -23
  176. package/dist/types/src/components/Form/FormContext.d.ts.map +0 -1
  177. package/dist/types/src/components/Form/Input.d.ts +0 -26
  178. package/dist/types/src/components/Form/Input.d.ts.map +0 -1
  179. package/dist/types/src/components/Form/RefField.d.ts +0 -12
  180. package/dist/types/src/components/Form/RefField.d.ts.map +0 -1
  181. package/dist/types/src/components/Form/custom/GeoPointInput.d.ts +0 -4
  182. package/dist/types/src/components/Form/custom/GeoPointInput.d.ts.map +0 -1
  183. package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts +0 -4
  184. package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts.map +0 -1
  185. package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts +0 -7
  186. package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts.map +0 -1
  187. package/dist/types/src/components/Form/custom/TupleInput.d.ts +0 -6
  188. package/dist/types/src/components/Form/custom/TupleInput.d.ts.map +0 -1
  189. package/dist/types/src/components/Form/custom/index.d.ts +0 -4
  190. package/dist/types/src/components/Form/custom/index.d.ts.map +0 -1
  191. package/dist/types/src/components/Form/factory.d.ts +0 -8
  192. package/dist/types/src/components/Form/factory.d.ts.map +0 -1
  193. package/dist/types/src/components/deprecated/Form.d.ts +0 -15
  194. package/dist/types/src/components/deprecated/Form.d.ts.map +0 -1
  195. package/dist/types/src/components/deprecated/Form.stories.d.ts +0 -13
  196. package/dist/types/src/components/deprecated/Form.stories.d.ts.map +0 -1
  197. package/dist/types/src/components/deprecated/FormInput.d.ts +0 -16
  198. package/dist/types/src/components/deprecated/FormInput.d.ts.map +0 -1
  199. package/dist/types/src/components/deprecated/index.d.ts +0 -2
  200. package/dist/types/src/components/deprecated/index.d.ts.map +0 -1
  201. package/dist/types/src/hooks/useForm.d.ts +0 -67
  202. package/dist/types/src/hooks/useForm.d.ts.map +0 -1
  203. package/dist/types/src/hooks/useQueryRefOptions.d.ts +0 -23
  204. package/dist/types/src/hooks/useQueryRefOptions.d.ts.map +0 -1
  205. package/dist/types/src/hooks/useRefQueryLookupHandler.d.ts +0 -8
  206. package/dist/types/src/hooks/useRefQueryLookupHandler.d.ts.map +0 -1
  207. package/dist/types/src/util/schema.d.ts +0 -3
  208. package/dist/types/src/util/schema.d.ts.map +0 -1
  209. package/src/components/ControlSection/ControlSection.stories.tsx +0 -41
  210. package/src/components/ControlSection/ControlSection.tsx +0 -139
  211. package/src/components/Form/ArrayField.tsx +0 -124
  212. package/src/components/Form/Defaults.tsx +0 -203
  213. package/src/components/Form/FormActions.tsx +0 -53
  214. package/src/components/Form/FormContent.tsx +0 -240
  215. package/src/components/Form/FormContext.tsx +0 -110
  216. package/src/components/Form/Input.tsx +0 -51
  217. package/src/components/Form/RefField.tsx +0 -213
  218. package/src/components/Form/custom/GeoPointInput.tsx +0 -72
  219. package/src/components/Form/custom/SelectOptionsInput.stories.tsx +0 -61
  220. package/src/components/Form/custom/index.ts +0 -7
  221. package/src/components/Form/factory.tsx +0 -31
  222. package/src/components/deprecated/Form.stories.tsx +0 -62
  223. package/src/components/deprecated/Form.tsx +0 -119
  224. package/src/components/deprecated/FormInput.tsx +0 -71
  225. package/src/components/deprecated/index.ts +0 -5
  226. package/src/hooks/useForm.ts +0 -291
  227. package/src/hooks/useQueryRefOptions.ts +0 -53
  228. package/src/hooks/useRefQueryLookupHandler.ts +0 -39
  229. package/src/util/schema.ts +0 -14
package/package.json CHANGED
@@ -1,14 +1,19 @@
1
1
  {
2
2
  "name": "@dxos/react-ui-form",
3
- "version": "0.8.4-main.f9ba587",
3
+ "version": "0.8.4-main.fcfe5033a5",
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",
10
14
  "exports": {
11
15
  ".": {
16
+ "source": "./src/index.ts",
12
17
  "types": "./dist/types/src/index.d.ts",
13
18
  "browser": "./dist/lib/browser/index.mjs",
14
19
  "node": "./dist/lib/node-esm/index.mjs"
@@ -23,54 +28,52 @@
23
28
  "src"
24
29
  ],
25
30
  "dependencies": {
26
- "@atlaskit/pragmatic-drag-and-drop": "^1.4.0",
27
- "@atlaskit/pragmatic-drag-and-drop-hitbox": "^1.0.3",
28
- "@preact-signals/safe-react": "^0.9.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",
29
35
  "@radix-ui/react-context": "1.1.1",
30
- "date-fns": "^3.3.1",
31
- "jsonpath": "^1.1.1",
32
- "@dxos/async": "0.8.4-main.f9ba587",
33
- "@dxos/debug": "0.8.4-main.f9ba587",
34
- "@dxos/echo": "0.8.4-main.f9ba587",
35
- "@dxos/echo-db": "0.8.4-main.f9ba587",
36
- "@dxos/echo-schema": "0.8.4-main.f9ba587",
37
- "@dxos/effect": "0.8.4-main.f9ba587",
38
- "@dxos/invariant": "0.8.4-main.f9ba587",
39
- "@dxos/keys": "0.8.4-main.f9ba587",
40
- "@dxos/lit-ui": "0.8.4-main.f9ba587",
41
- "@dxos/live-object": "0.8.4-main.f9ba587",
42
- "@dxos/log": "0.8.4-main.f9ba587",
43
- "@dxos/react-client": "0.8.4-main.f9ba587",
44
- "@dxos/react-ui-list": "0.8.4-main.f9ba587",
45
- "@dxos/react-ui-stack": "0.8.4-main.f9ba587",
46
- "@dxos/react-ui-pickers": "0.8.4-main.f9ba587",
47
- "@dxos/react-ui-tag-picker": "0.8.4-main.f9ba587",
48
- "@dxos/react-ui-types": "0.8.4-main.f9ba587",
49
- "@dxos/schema": "0.8.4-main.f9ba587",
50
- "@dxos/util": "0.8.4-main.f9ba587"
36
+ "@radix-ui/react-use-controllable-state": "1.1.0",
37
+ "date-fns": "^3.6.0",
38
+ "tabster": "^8.5.5",
39
+ "@dxos/async": "0.8.4-main.fcfe5033a5",
40
+ "@dxos/echo-react": "0.8.4-main.fcfe5033a5",
41
+ "@dxos/effect": "0.8.4-main.fcfe5033a5",
42
+ "@dxos/echo": "0.8.4-main.fcfe5033a5",
43
+ "@dxos/invariant": "0.8.4-main.fcfe5033a5",
44
+ "@dxos/log": "0.8.4-main.fcfe5033a5",
45
+ "@dxos/keys": "0.8.4-main.fcfe5033a5",
46
+ "@dxos/react-client": "0.8.4-main.fcfe5033a5",
47
+ "@dxos/react-ui-components": "0.8.4-main.fcfe5033a5",
48
+ "@dxos/react-ui-list": "0.8.4-main.fcfe5033a5",
49
+ "@dxos/react-ui-pickers": "0.8.4-main.fcfe5033a5",
50
+ "@dxos/react-ui-search": "0.8.4-main.fcfe5033a5",
51
+ "@dxos/schema": "0.8.4-main.fcfe5033a5",
52
+ "@dxos/types": "0.8.4-main.fcfe5033a5",
53
+ "@dxos/util": "0.8.4-main.fcfe5033a5",
54
+ "@dxos/lit-ui": "0.8.4-main.fcfe5033a5"
51
55
  },
52
56
  "devDependencies": {
53
- "@types/jsonpath": "^0.2.4",
54
- "@types/react": "~18.2.0",
55
- "@types/react-dom": "~18.2.0",
56
- "effect": "3.16.13",
57
+ "@types/react": "~19.2.7",
58
+ "@types/react-dom": "~19.2.3",
59
+ "effect": "3.20.0",
57
60
  "fast-check": "^3.19.0",
58
- "react": "~18.2.0",
59
- "react-dom": "~18.2.0",
60
- "vite": "5.4.7",
61
- "@dxos/echo-signals": "0.8.4-main.f9ba587",
62
- "@dxos/random": "0.8.4-main.f9ba587",
63
- "@dxos/react-ui": "0.8.4-main.f9ba587",
64
- "@dxos/react-ui-syntax-highlighter": "0.8.4-main.f9ba587",
65
- "@dxos/react-ui-theme": "0.8.4-main.f9ba587",
66
- "@dxos/storybook-utils": "0.8.4-main.f9ba587"
61
+ "react": "~19.2.3",
62
+ "react-dom": "~19.2.3",
63
+ "vite": "^7.1.11",
64
+ "@dxos/random": "0.8.4-main.fcfe5033a5",
65
+ "@dxos/react-client": "0.8.4-main.fcfe5033a5",
66
+ "@dxos/react-ui": "0.8.4-main.fcfe5033a5",
67
+ "@dxos/react-ui-syntax-highlighter": "0.8.4-main.fcfe5033a5",
68
+ "@dxos/storybook-utils": "0.8.4-main.fcfe5033a5",
69
+ "@dxos/ui-theme": "0.8.4-main.fcfe5033a5"
67
70
  },
68
71
  "peerDependencies": {
69
- "effect": "^3.13.3",
70
- "react": "~18.2.0",
71
- "react-dom": "~18.2.0",
72
- "@dxos/react-ui": "0.8.4-main.f9ba587",
73
- "@dxos/react-ui-theme": "0.8.4-main.f9ba587"
72
+ "effect": "3.20.0",
73
+ "react": "~19.2.3",
74
+ "react-dom": "~19.2.3",
75
+ "@dxos/react-ui": "0.8.4-main.fcfe5033a5",
76
+ "@dxos/ui-theme": "0.8.4-main.fcfe5033a5"
74
77
  },
75
78
  "publishConfig": {
76
79
  "access": "public"
@@ -2,39 +2,63 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
6
-
7
5
  import { type Meta, type StoryObj } from '@storybook/react-vite';
8
- import React, { useMemo, useEffect } from 'react';
6
+ import React, { useEffect, useMemo } from 'react';
9
7
 
10
- import { createEchoSchema } from '@dxos/live-object/testing';
8
+ import { Filter, Query } from '@dxos/echo';
9
+ import { createEchoSchema } from '@dxos/echo/testing';
11
10
  import { log } from '@dxos/log';
12
- import { ViewProjection } from '@dxos/schema';
13
- import { TestSchema, testView } from '@dxos/schema/testing';
14
- import { withLayout, withTheme } from '@dxos/storybook-utils';
11
+ import { withLayout, withTheme } from '@dxos/react-ui/testing';
12
+ import { ProjectionModel, ViewModel, createEchoChangeCallback } from '@dxos/schema';
13
+ import { Example } from '@dxos/schema/testing';
15
14
 
16
- import { FieldEditor, type FieldEditorProps } from './FieldEditor';
17
15
  import { translations } from '../../translations';
18
- import { TestLayout, TestPanel, FIELD_EDITOR_DEBUG_SYMBOL } from '../testing';
16
+ import { FIELD_EDITOR_DEBUG_SYMBOL, TestLayout } from '../testing';
17
+ import { FieldEditor, type FieldEditorProps } from './FieldEditor';
19
18
 
20
- // Type definition for debug objects exposed to tests.
21
19
  export type FieldEditorDebugObjects = {
22
20
  props: FieldEditorProps;
23
- projection: ViewProjection;
21
+ projection: ProjectionModel;
22
+ };
23
+
24
+ const useTestProjection = () => {
25
+ return useMemo(() => {
26
+ const schema = createEchoSchema(Example);
27
+ const view = ViewModel.make({
28
+ name: 'Test',
29
+ query: Query.select(Filter.type(Example)),
30
+ jsonSchema: schema.jsonSchema,
31
+ });
32
+ const projection = new ProjectionModel({
33
+ view,
34
+ baseSchema: schema.jsonSchema,
35
+ change: createEchoChangeCallback(view, schema),
36
+ });
37
+ projection.normalizeView();
38
+ return { view, projection };
39
+ }, []);
24
40
  };
25
41
 
26
- type StoryProps = FieldEditorProps;
42
+ const DefaultStory = () => {
43
+ const { view, projection } = useTestProjection();
27
44
 
28
- const DefaultStory = (props: FieldEditorProps) => {
29
- const projection = useMemo(() => new ViewProjection(createEchoSchema(TestSchema).jsonSchema, testView), []);
30
45
  const handleComplete: FieldEditorProps['onSave'] = () => {
31
- log.info('onClose', { props });
46
+ log.info('onClose');
47
+ };
48
+
49
+ const props: FieldEditorProps = {
50
+ projection,
51
+ field: view.projection.fields[0],
52
+ onSave: handleComplete,
32
53
  };
33
54
 
34
55
  // Expose objects on window for test access.
35
56
  useEffect(() => {
36
57
  if (typeof window !== 'undefined') {
37
- (window as any)[FIELD_EDITOR_DEBUG_SYMBOL] = { props, projection } satisfies FieldEditorDebugObjects;
58
+ (window as any)[FIELD_EDITOR_DEBUG_SYMBOL] = {
59
+ props,
60
+ projection,
61
+ } satisfies FieldEditorDebugObjects;
38
62
  }
39
63
  }, [props, projection]);
40
64
 
@@ -46,31 +70,27 @@ const DefaultStory = (props: FieldEditorProps) => {
46
70
 
47
71
  return (
48
72
  <TestLayout json={json}>
49
- <TestPanel>
50
- <FieldEditor {...props} projection={projection} onSave={handleComplete} />
51
- </TestPanel>
73
+ <FieldEditor {...props} />
52
74
  </TestLayout>
53
75
  );
54
76
  };
55
77
 
56
- const meta: Meta<StoryProps> = {
78
+ const meta = {
57
79
  title: 'ui/react-ui-form/FieldEditor',
58
- component: FieldEditor,
80
+ component: FieldEditor as any,
59
81
  render: DefaultStory,
60
- decorators: [withLayout({ fullscreen: true }), withTheme],
82
+ decorators: [withTheme(), withLayout({ layout: 'fullscreen' })],
61
83
  parameters: {
84
+ layout: 'fullscreen',
62
85
  translations,
86
+ controls: {
87
+ disabled: true,
88
+ },
63
89
  },
64
- };
90
+ } satisfies Meta<typeof DefaultStory>;
65
91
 
66
92
  export default meta;
67
93
 
68
- type Story = StoryObj<StoryProps>;
94
+ type Story = StoryObj<typeof meta>;
69
95
 
70
- export const Default: Story = {
71
- args: {
72
- view: testView,
73
- field: testView.fields[0],
74
- },
75
- parameters: { controls: { disabled: true } },
76
- };
96
+ export const Default: Story = {};
@@ -3,25 +3,17 @@
3
3
  //
4
4
 
5
5
  import { composeStories } from '@storybook/react';
6
- import { screen, cleanup, fireEvent, act } from '@testing-library/react';
6
+ import { act, cleanup, fireEvent, screen } from '@testing-library/react';
7
7
  import { afterEach, describe, expect, test } from 'vitest';
8
8
 
9
- import { ViewProjection } from '@dxos/schema';
9
+ import { ProjectionModel } from '@dxos/schema';
10
10
 
11
+ import { FIELD_EDITOR_DEBUG_SYMBOL } from '../testing';
11
12
  import * as stories from './FieldEditor.stories';
12
13
  import { type FieldEditorDebugObjects } from './FieldEditor.stories';
13
- import { FIELD_EDITOR_DEBUG_SYMBOL } from '../testing';
14
14
 
15
15
  const { Default } = composeStories(stories);
16
16
 
17
- const getFieldEditorDebugObjects = (): FieldEditorDebugObjects => {
18
- const debugObjects = (window as any)[FIELD_EDITOR_DEBUG_SYMBOL] as FieldEditorDebugObjects;
19
- expect(debugObjects).toBeDefined();
20
- expect(debugObjects.props).toBeInstanceOf(Object); // Props object
21
- expect(debugObjects.projection).toBeInstanceOf(ViewProjection);
22
- return debugObjects;
23
- };
24
-
25
17
  describe('FieldEditor', () => {
26
18
  afterEach(() => {
27
19
  cleanup();
@@ -33,7 +25,7 @@ describe('FieldEditor', () => {
33
25
  expect(screen.getByText('Type format')).toBeInTheDocument();
34
26
  expect(screen.getByText('String')).toBeInTheDocument();
35
27
 
36
- // Verify the initial field shows as String type
28
+ // Verify the initial field shows as String type.
37
29
  expect(screen.getByText('String')).toBeInTheDocument();
38
30
 
39
31
  fireEvent.click(screen.getByRole('combobox'));
@@ -49,9 +41,17 @@ describe('FieldEditor', () => {
49
41
  // Access the live objects directly from window using symbol.
50
42
  const debugObjects = getFieldEditorDebugObjects();
51
43
 
52
- const name = debugObjects.projection.schema.properties!.name;
44
+ const name = debugObjects.projection.baseSchema.properties!.name;
53
45
  expect(name.type).toBe('number');
54
46
  expect(name.format).toBe('number');
55
47
  expect(name.description).toBe('Full name.');
56
48
  });
57
49
  });
50
+
51
+ const getFieldEditorDebugObjects = (): FieldEditorDebugObjects => {
52
+ const debugObjects = (window as any)[FIELD_EDITOR_DEBUG_SYMBOL] as FieldEditorDebugObjects;
53
+ expect(debugObjects).toBeDefined();
54
+ expect(debugObjects.props).toBeInstanceOf(Object); // Props object
55
+ expect(debugObjects.projection).toBeInstanceOf(ProjectionModel);
56
+ return debugObjects;
57
+ };
@@ -4,51 +4,41 @@
4
4
 
5
5
  import React, { useCallback, useEffect, useMemo, useState } from 'react';
6
6
 
7
- import { type SchemaRegistry } from '@dxos/echo-db';
8
- import { FormatEnum, FormatEnums, formatToType, type EchoSchema } from '@dxos/echo-schema';
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
- import { useTranslation } from '@dxos/react-ui';
11
+ import { useAsyncEffect, useTranslation } from '@dxos/react-ui';
11
12
  import {
12
- getFormatSchema,
13
- getSchemaProperties,
14
- sortProperties,
15
- type FieldType,
13
+ type ProjectionModel,
16
14
  type PropertyType,
17
- type ViewType,
18
- type ViewProjection,
19
- type SchemaProperty,
15
+ formatToAdditionalPropertyAttributes,
16
+ getFormatSchema,
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
- view: ViewType;
27
- projection: ViewProjection;
28
- field: FieldType;
29
- registry?: SchemaRegistry;
24
+ projection: ProjectionModel;
25
+ field: View.FieldType;
26
+ registry?: SchemaRegistry.SchemaRegistry;
27
+ view?: Obj.Unknown;
30
28
  onSave: () => void;
31
29
  onCancel?: () => void;
32
- } & Pick<FormProps<any>, 'outerSpacing'>;
30
+ } & Pick<FormRootProps<any>, 'readonly'>;
33
31
 
34
32
  /**
35
33
  * Displays a Form representing the metadata for a given `Field` and `View`.
36
34
  */
37
- export const FieldEditor = ({
38
- view,
39
- projection,
40
- field,
41
- registry,
42
- onSave,
43
- onCancel,
44
- outerSpacing,
45
- }: FieldEditorProps) => {
35
+ export const FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCancel }: FieldEditorProps) => {
46
36
  const { t } = useTranslation(translationKey);
47
37
  const [props, setProps] = useState<PropertyType>(projection.getFieldProjection(field.id).props);
48
38
  useEffect(() => setProps(projection.getFieldProjection(field.id).props), [field, projection]);
49
39
 
50
40
  const [schemas, setSchemas] = useState<EchoSchema[]>([]);
51
- useEffect(() => {
41
+ useAsyncEffect(async () => {
52
42
  if (!registry) {
53
43
  return;
54
44
  }
@@ -56,14 +46,10 @@ export const FieldEditor = ({
56
46
  const subscription = registry.query().subscribe((query) => setSchemas(query.results), { fire: true });
57
47
 
58
48
  // TODO(dmaretskyi): This shouldn't be needed.
59
- const t = setTimeout(async () => {
60
- const schemas = await registry.query().run();
61
- setSchemas(schemas);
62
- });
63
- return () => {
64
- clearTimeout(t);
65
- subscription?.();
66
- };
49
+ const schemas = await registry.query().run();
50
+ setSchemas(schemas);
51
+
52
+ return () => subscription?.();
67
53
  }, [registry]);
68
54
 
69
55
  const [referenceSchema, setReferenceSchema] = useState<EchoSchema>();
@@ -75,11 +61,47 @@ export const FieldEditor = ({
75
61
  // Class constructor SchemaClass cannot be invoked without 'new'.
76
62
  const [{ fieldSchema }, setFieldSchema] = useState({ fieldSchema: getFormatSchema(props?.format) });
77
63
 
78
- 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}.label`),
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']>>(
79
103
  (_props) => {
80
- // TODO(burdon): Callback should pass `changed` to indicate which fields have changed.
81
- // TODO(Zaymon): Workout why old and new format values are the same sometimes even when
82
- // selecting novel format values.
104
+ // TODO(Zaymon): Workout why old and new format values are the same sometimes even when selecting novel format values.
83
105
  setFieldSchema((prev) => {
84
106
  const fieldSchema = getFormatSchema(_props.format);
85
107
  if (prev.fieldSchema === fieldSchema) {
@@ -100,8 +122,10 @@ export const FieldEditor = ({
100
122
 
101
123
  setProps((props) => {
102
124
  const type = formatToType[_props.format as keyof typeof formatToType];
125
+ const additionalProps =
126
+ formatToAdditionalPropertyAttributes[_props.format as keyof typeof formatToAdditionalPropertyAttributes];
103
127
  if (props.type !== type) {
104
- return { ...props, ..._props, type };
128
+ return { ...props, ..._props, ...additionalProps, type } as PropertyType;
105
129
  }
106
130
 
107
131
  return _props as PropertyType;
@@ -110,9 +134,9 @@ export const FieldEditor = ({
110
134
  [schemas, props.format, props.referenceSchema],
111
135
  );
112
136
 
113
- const handleValidate = useCallback<NonNullable<FormProps<PropertyType>['onValidate']>>(
137
+ const handleValidate = useCallback<NonNullable<FormRootProps<PropertyType>['onValidate']>>(
114
138
  ({ property }) => {
115
- if (property && view.fields.find((f) => f.path === property && f.path !== field.path)) {
139
+ if (property && projection.getFields().find((f) => f.path === property && f.path !== field.path)) {
116
140
  return [
117
141
  {
118
142
  path: 'property',
@@ -121,83 +145,53 @@ export const FieldEditor = ({
121
145
  ];
122
146
  }
123
147
  },
124
- [view.fields, field],
148
+ [projection.getFields(), field],
125
149
  );
126
150
 
127
- const handleSave = useCallback<NonNullable<FormProps<PropertyType>['onSave']>>(
151
+ const handleSave = useCallback<NonNullable<FormRootProps<PropertyType>['onSave']>>(
128
152
  (props) => {
129
- 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
+ }
130
160
  onSave();
131
161
  },
132
- [projection, field, onSave],
162
+ [projection, field, view, onSave],
133
163
  );
134
164
 
135
- const handleCancel = useCallback<NonNullable<FormProps<PropertyType>['onCancel']>>(() => {
165
+ const handleCancel = useCallback<NonNullable<FormRootProps<PropertyType>['onCancel']>>(() => {
166
+ onSave();
136
167
  // Need to defer to allow form to close.
137
168
  requestAnimationFrame(() => onCancel?.());
138
- onSave();
139
169
  }, [onSave]);
140
170
 
141
- const custom: Partial<Record<string, InputComponent>> = useMemo(
142
- () => ({
143
- ['format' satisfies keyof PropertyType]: (props) => (
144
- <SelectInput
145
- {...props}
146
- options={FormatEnums.filter((value) => value !== FormatEnum.None).map((value) => ({
147
- value,
148
- label: t(`format ${value}`),
149
- }))}
150
- />
151
- ),
152
- ['referenceSchema' satisfies keyof PropertyType]: (props) => (
153
- <SelectInput
154
- {...props}
155
- options={schemas.map((schema) => ({
156
- value: schema.typename,
157
- }))}
158
- />
159
- ),
160
- ['referencePath' satisfies keyof PropertyType]: (props) => (
161
- <SelectInput
162
- {...props}
163
- options={
164
- referenceSchema
165
- ? getSchemaProperties(referenceSchema.ast)
166
- .sort(sortProperties)
167
- .map((p) => ({ value: p.name }))
168
- : []
169
- }
170
- />
171
- ),
172
- ['options' satisfies keyof PropertyType]: (props) => <SelectOptionInput {...props} />,
173
- }),
174
- [t, schemas, referenceSchema],
175
- );
176
-
177
- const propIsNotType = useCallback(
178
- (props: SchemaProperty<PropertyType>[]) => props.filter((p) => p.name !== 'type'),
179
- [],
180
- );
181
-
182
171
  if (!fieldSchema) {
183
172
  log.warn('invalid format', { props });
184
173
  return null;
185
174
  }
186
175
 
187
176
  return (
188
- <Form<PropertyType>
177
+ <Form.Root<PropertyType>
189
178
  key={field.id}
179
+ fieldMap={fieldMap}
190
180
  autoFocus
191
- values={props}
181
+ readonly={readonly}
192
182
  schema={fieldSchema}
193
- filter={propIsNotType}
183
+ values={props}
184
+ exclude={propIsNotType}
194
185
  sort={['property', 'format']}
195
186
  onValuesChanged={handleValuesChanged}
196
187
  onValidate={handleValidate}
197
188
  onSave={handleSave}
198
189
  onCancel={handleCancel}
199
- Custom={custom}
200
- outerSpacing={outerSpacing}
201
- />
190
+ >
191
+ <Form.Content>
192
+ <Form.FieldSet />
193
+ <Form.Actions />
194
+ </Form.Content>
195
+ </Form.Root>
202
196
  );
203
197
  };
@@ -0,0 +1,17 @@
1
+ # Form
2
+
3
+ ## New features/polish
4
+
5
+ - [x] Unify readonly/inline modes.
6
+ - [x] Refs
7
+ - [x] Single-select (fix popover)
8
+ - [x] Multi-select (array)
9
+ - [ ] auto save doesn't work for combobox + select due to only firing on blur (workaround is to use onValuesChanged).
10
+ - [ ] Don't call save/autoSave if value hasn't changed.
11
+ - [ ] Fix onCancel (restore values).
12
+ - [ ] Fix useSchema Type.AnyObj cast.
13
+ - [ ] TableCellEditor (handleEnter/ModalController).
14
+ - [ ] Use FormFieldWrapper uniformly
15
+ - [ ] Inline tables.
16
+ - [ ] Defer query until popover.
17
+ - [ ] Omit id from sub properties (tune Omit)