@dxos/react-ui-form 0.8.4-main.fd6878d → 0.8.4-staging.60fe92afc8

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 (318) hide show
  1. package/LICENSE +102 -5
  2. package/README.md +0 -1
  3. package/dist/lib/browser/index.mjs +4054 -2217
  4. package/dist/lib/browser/index.mjs.map +4 -4
  5. package/dist/lib/browser/meta.json +1 -1
  6. package/dist/lib/browser/translations.mjs +87 -0
  7. package/dist/lib/browser/translations.mjs.map +7 -0
  8. package/dist/lib/node-esm/index.mjs +4054 -2217
  9. package/dist/lib/node-esm/index.mjs.map +4 -4
  10. package/dist/lib/node-esm/meta.json +1 -1
  11. package/dist/lib/node-esm/translations.mjs +89 -0
  12. package/dist/lib/node-esm/translations.mjs.map +7 -0
  13. package/dist/types/src/components/FieldEditor/FieldEditor.d.ts +8 -8
  14. package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
  15. package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts +89 -5
  16. package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts.map +1 -1
  17. package/dist/types/src/components/Form/Form.d.ts +135 -25
  18. package/dist/types/src/components/Form/Form.d.ts.map +1 -1
  19. package/dist/types/src/components/Form/Form.stories.d.ts +207 -56
  20. package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
  21. package/dist/types/src/components/Form/FormField.d.ts +52 -0
  22. package/dist/types/src/components/Form/FormField.d.ts.map +1 -0
  23. package/dist/types/src/components/Form/FormFieldComponent.d.ts +98 -0
  24. package/dist/types/src/components/Form/FormFieldComponent.d.ts.map +1 -0
  25. package/dist/types/src/components/Form/FormFieldComponent.stories.d.ts +9 -0
  26. package/dist/types/src/components/Form/FormFieldComponent.stories.d.ts.map +1 -0
  27. package/dist/types/src/components/Form/FormFieldSet.d.ts +26 -0
  28. package/dist/types/src/components/Form/FormFieldSet.d.ts.map +1 -0
  29. package/dist/types/src/components/Form/FormTooltipsContext.d.ts +19 -0
  30. package/dist/types/src/components/Form/FormTooltipsContext.d.ts.map +1 -0
  31. package/dist/types/src/components/Form/Layout/FormLayout.d.ts +50 -0
  32. package/dist/types/src/components/Form/Layout/FormLayout.d.ts.map +1 -0
  33. package/dist/types/src/components/Form/Layout/FormLayout.stories.d.ts +123 -0
  34. package/dist/types/src/components/Form/Layout/FormLayout.stories.d.ts.map +1 -0
  35. package/dist/types/src/components/Form/Layout/FormLayout.stories.test.d.ts +2 -0
  36. package/dist/types/src/components/Form/Layout/FormLayout.stories.test.d.ts.map +1 -0
  37. package/dist/types/src/components/Form/Layout/FormLayout.test.d.ts +2 -0
  38. package/dist/types/src/components/Form/Layout/FormLayout.test.d.ts.map +1 -0
  39. package/dist/types/src/components/Form/Layout/annotation.d.ts +30 -0
  40. package/dist/types/src/components/Form/Layout/annotation.d.ts.map +1 -0
  41. package/dist/types/src/components/Form/Layout/index.d.ts +4 -0
  42. package/dist/types/src/components/Form/Layout/index.d.ts.map +1 -0
  43. package/dist/types/src/components/Form/Layout/parser.d.ts +31 -0
  44. package/dist/types/src/components/Form/Layout/parser.d.ts.map +1 -0
  45. package/dist/types/src/components/Form/Layout/parser.test.d.ts +2 -0
  46. package/dist/types/src/components/Form/Layout/parser.test.d.ts.map +1 -0
  47. package/dist/types/src/components/Form/fields/ArrayField.d.ts +18 -0
  48. package/dist/types/src/components/Form/fields/ArrayField.d.ts.map +1 -0
  49. package/dist/types/src/components/Form/fields/BooleanField.d.ts +4 -0
  50. package/dist/types/src/components/Form/fields/BooleanField.d.ts.map +1 -0
  51. package/dist/types/src/components/Form/fields/DateField.d.ts +4 -0
  52. package/dist/types/src/components/Form/fields/DateField.d.ts.map +1 -0
  53. package/dist/types/src/components/Form/fields/GeoPointField.d.ts +5 -0
  54. package/dist/types/src/components/Form/fields/GeoPointField.d.ts.map +1 -0
  55. package/dist/types/src/components/Form/fields/InlineRefField.d.ts +13 -0
  56. package/dist/types/src/components/Form/fields/InlineRefField.d.ts.map +1 -0
  57. package/dist/types/src/components/Form/fields/MarkdownField.d.ts +11 -0
  58. package/dist/types/src/components/Form/fields/MarkdownField.d.ts.map +1 -0
  59. package/dist/types/src/components/Form/fields/MarkdownField.stories.d.ts +89 -0
  60. package/dist/types/src/components/Form/fields/MarkdownField.stories.d.ts.map +1 -0
  61. package/dist/types/src/components/Form/fields/NumberField.d.ts +4 -0
  62. package/dist/types/src/components/Form/fields/NumberField.d.ts.map +1 -0
  63. package/dist/types/src/components/Form/fields/RefField.d.ts +34 -0
  64. package/dist/types/src/components/Form/fields/RefField.d.ts.map +1 -0
  65. package/dist/types/src/components/Form/fields/RefField.test.d.ts +2 -0
  66. package/dist/types/src/components/Form/fields/RefField.test.d.ts.map +1 -0
  67. package/dist/types/src/components/Form/fields/SelectField.d.ts +13 -0
  68. package/dist/types/src/components/Form/fields/SelectField.d.ts.map +1 -0
  69. package/dist/types/src/components/Form/fields/SelectOptionField.d.ts +5 -0
  70. package/dist/types/src/components/Form/fields/SelectOptionField.d.ts.map +1 -0
  71. package/dist/types/src/components/Form/fields/SelectOptionField.stories.d.ts +89 -0
  72. package/dist/types/src/components/Form/fields/SelectOptionField.stories.d.ts.map +1 -0
  73. package/dist/types/src/components/Form/fields/TextAreaField.d.ts +4 -0
  74. package/dist/types/src/components/Form/fields/TextAreaField.d.ts.map +1 -0
  75. package/dist/types/src/components/Form/fields/TextField.d.ts +4 -0
  76. package/dist/types/src/components/Form/fields/TextField.d.ts.map +1 -0
  77. package/dist/types/src/components/Form/fields/TupleField.d.ts +6 -0
  78. package/dist/types/src/components/Form/fields/TupleField.d.ts.map +1 -0
  79. package/dist/types/src/components/Form/fields/index.d.ts +14 -0
  80. package/dist/types/src/components/Form/fields/index.d.ts.map +1 -0
  81. package/dist/types/src/components/Form/index.d.ts +5 -4
  82. package/dist/types/src/components/Form/index.d.ts.map +1 -1
  83. package/dist/types/src/components/Form/meta-tags.d.ts +30 -0
  84. package/dist/types/src/components/Form/meta-tags.d.ts.map +1 -0
  85. package/dist/types/src/components/Form/meta-tags.test.d.ts +2 -0
  86. package/dist/types/src/components/Form/meta-tags.test.d.ts.map +1 -0
  87. package/dist/types/src/components/ObjectForm/ObjectForm.d.ts +8 -0
  88. package/dist/types/src/components/ObjectForm/ObjectForm.d.ts.map +1 -0
  89. package/dist/types/src/components/ObjectForm/ObjectForm.stories.d.ts +87 -0
  90. package/dist/types/src/components/ObjectForm/ObjectForm.stories.d.ts.map +1 -0
  91. package/dist/types/src/components/ObjectForm/index.d.ts +2 -0
  92. package/dist/types/src/components/ObjectForm/index.d.ts.map +1 -0
  93. package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts +68 -0
  94. package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts.map +1 -0
  95. package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts +92 -0
  96. package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts.map +1 -0
  97. package/dist/types/src/components/ObjectPicker/index.d.ts +2 -0
  98. package/dist/types/src/components/ObjectPicker/index.d.ts.map +1 -0
  99. package/dist/types/src/components/ObjectProperties/ObjectProperties.d.ts +9 -0
  100. package/dist/types/src/components/ObjectProperties/ObjectProperties.d.ts.map +1 -0
  101. package/dist/types/src/components/ObjectProperties/ObjectProperties.stories.d.ts +132 -0
  102. package/dist/types/src/components/ObjectProperties/ObjectProperties.stories.d.ts.map +1 -0
  103. package/dist/types/src/components/ObjectProperties/ObjectProperties.test.d.ts +2 -0
  104. package/dist/types/src/components/ObjectProperties/ObjectProperties.test.d.ts.map +1 -0
  105. package/dist/types/src/components/ObjectProperties/index.d.ts +2 -0
  106. package/dist/types/src/components/ObjectProperties/index.d.ts.map +1 -0
  107. package/dist/types/src/components/ObjectTree/ObjectTree.d.ts +9 -0
  108. package/dist/types/src/components/ObjectTree/ObjectTree.d.ts.map +1 -0
  109. package/dist/types/src/components/ObjectTree/ObjectTree.stories.d.ts +91 -0
  110. package/dist/types/src/components/ObjectTree/ObjectTree.stories.d.ts.map +1 -0
  111. package/dist/types/src/components/ObjectTree/index.d.ts +2 -0
  112. package/dist/types/src/components/ObjectTree/index.d.ts.map +1 -0
  113. package/dist/types/src/components/RefEditor/RefEditor.d.ts +73 -0
  114. package/dist/types/src/components/RefEditor/RefEditor.d.ts.map +1 -0
  115. package/dist/types/src/components/RefEditor/RefEditor.stories.d.ts +92 -0
  116. package/dist/types/src/components/RefEditor/RefEditor.stories.d.ts.map +1 -0
  117. package/dist/types/src/components/RefEditor/index.d.ts +3 -0
  118. package/dist/types/src/components/RefEditor/index.d.ts.map +1 -0
  119. package/dist/types/src/components/RefEditor/ref-editor-extension.d.ts +47 -0
  120. package/dist/types/src/components/RefEditor/ref-editor-extension.d.ts.map +1 -0
  121. package/dist/types/src/components/Settings/Settings.d.ts +51 -0
  122. package/dist/types/src/components/Settings/Settings.d.ts.map +1 -0
  123. package/dist/types/src/components/Settings/Settings.stories.d.ts +89 -0
  124. package/dist/types/src/components/Settings/Settings.stories.d.ts.map +1 -0
  125. package/dist/types/src/components/Settings/SettingsFieldSet.d.ts +43 -0
  126. package/dist/types/src/components/Settings/SettingsFieldSet.d.ts.map +1 -0
  127. package/dist/types/src/components/Settings/SettingsItem.d.ts +16 -0
  128. package/dist/types/src/components/Settings/SettingsItem.d.ts.map +1 -0
  129. package/dist/types/src/components/Settings/SettingsSelectField.d.ts +18 -0
  130. package/dist/types/src/components/Settings/SettingsSelectField.d.ts.map +1 -0
  131. package/dist/types/src/components/Settings/index.d.ts +4 -0
  132. package/dist/types/src/components/Settings/index.d.ts.map +1 -0
  133. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts +21 -11
  134. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
  135. package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts +91 -9
  136. package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
  137. package/dist/types/src/components/index.d.ts +6 -2
  138. package/dist/types/src/components/index.d.ts.map +1 -1
  139. package/dist/types/src/components/testing.d.ts +14 -4
  140. package/dist/types/src/components/testing.d.ts.map +1 -1
  141. package/dist/types/src/hooks/index.d.ts +2 -3
  142. package/dist/types/src/hooks/index.d.ts.map +1 -1
  143. package/dist/types/src/hooks/useFormHandler.d.ts +82 -0
  144. package/dist/types/src/hooks/useFormHandler.d.ts.map +1 -0
  145. package/dist/types/src/hooks/useKeyHandler.d.ts +7 -0
  146. package/dist/types/src/hooks/useKeyHandler.d.ts.map +1 -0
  147. package/dist/types/src/index.d.ts +0 -2
  148. package/dist/types/src/index.d.ts.map +1 -1
  149. package/dist/types/src/translations.d.ts +70 -55
  150. package/dist/types/src/translations.d.ts.map +1 -1
  151. package/dist/types/src/util/field-type.d.ts +19 -0
  152. package/dist/types/src/util/field-type.d.ts.map +1 -0
  153. package/dist/types/src/util/field.d.ts +3 -3
  154. package/dist/types/src/util/field.d.ts.map +1 -1
  155. package/dist/types/src/util/formatting.d.ts +2 -2
  156. package/dist/types/src/util/formatting.d.ts.map +1 -1
  157. package/dist/types/src/util/index.d.ts +2 -1
  158. package/dist/types/src/util/index.d.ts.map +1 -1
  159. package/dist/types/src/util/properties.d.ts +35 -0
  160. package/dist/types/src/util/properties.d.ts.map +1 -0
  161. package/dist/types/src/util/properties.test.d.ts +2 -0
  162. package/dist/types/src/util/properties.test.d.ts.map +1 -0
  163. package/dist/types/src/util/refs.d.ts +3 -3
  164. package/dist/types/src/util/refs.d.ts.map +1 -1
  165. package/dist/types/tsconfig.tsbuildinfo +1 -1
  166. package/package.json +64 -47
  167. package/src/components/FieldEditor/FieldEditor.stories.tsx +49 -31
  168. package/src/components/FieldEditor/FieldEditor.test.tsx +4 -2
  169. package/src/components/FieldEditor/FieldEditor.tsx +100 -97
  170. package/src/components/Form/AUDIT.md +17 -0
  171. package/src/components/Form/Form.stories.tsx +151 -221
  172. package/src/components/Form/Form.tsx +461 -95
  173. package/src/components/Form/FormField.tsx +345 -0
  174. package/src/components/Form/FormFieldComponent.stories.tsx +65 -0
  175. package/src/components/Form/FormFieldComponent.tsx +253 -0
  176. package/src/components/Form/FormFieldSet.tsx +213 -0
  177. package/src/components/Form/FormTooltipsContext.ts +25 -0
  178. package/src/components/Form/Layout/FormLayout.stories.test.tsx +51 -0
  179. package/src/components/Form/Layout/FormLayout.stories.tsx +422 -0
  180. package/src/components/Form/Layout/FormLayout.test.ts +59 -0
  181. package/src/components/Form/Layout/FormLayout.tsx +251 -0
  182. package/src/components/Form/Layout/annotation.ts +38 -0
  183. package/src/components/Form/Layout/index.ts +7 -0
  184. package/src/components/Form/Layout/parser.test.ts +120 -0
  185. package/src/components/Form/Layout/parser.ts +167 -0
  186. package/src/components/Form/README.md +3 -0
  187. package/src/components/Form/fields/ArrayField.tsx +173 -0
  188. package/src/components/Form/fields/BooleanField.tsx +22 -0
  189. package/src/components/Form/fields/DateField.tsx +101 -0
  190. package/src/components/Form/fields/GeoPointField.tsx +124 -0
  191. package/src/components/Form/fields/InlineRefField.tsx +138 -0
  192. package/src/components/Form/fields/MarkdownField.stories.tsx +206 -0
  193. package/src/components/Form/fields/MarkdownField.tsx +167 -0
  194. package/src/components/Form/fields/NumberField.tsx +76 -0
  195. package/src/components/Form/fields/RefField.test.ts +45 -0
  196. package/src/components/Form/fields/RefField.tsx +266 -0
  197. package/src/components/Form/fields/SelectField.tsx +77 -0
  198. package/src/components/Form/fields/SelectOptionField.stories.tsx +66 -0
  199. package/src/components/Form/{custom/SelectOptionsInput.tsx → fields/SelectOptionField.tsx} +39 -32
  200. package/src/components/Form/fields/TextAreaField.tsx +38 -0
  201. package/src/components/Form/fields/TextField.tsx +38 -0
  202. package/src/components/Form/fields/TupleField.tsx +55 -0
  203. package/src/components/Form/fields/index.ts +17 -0
  204. package/src/components/Form/index.ts +6 -4
  205. package/src/components/Form/meta-tags.test.ts +47 -0
  206. package/src/components/Form/meta-tags.ts +33 -0
  207. package/src/components/ObjectForm/ObjectForm.stories.tsx +62 -0
  208. package/src/components/ObjectForm/ObjectForm.tsx +111 -0
  209. package/src/components/{ControlSection → ObjectForm}/index.ts +1 -1
  210. package/src/components/ObjectPicker/ObjectPicker.stories.tsx +212 -0
  211. package/src/components/ObjectPicker/ObjectPicker.tsx +202 -0
  212. package/src/components/ObjectPicker/index.ts +5 -0
  213. package/src/components/ObjectProperties/ObjectProperties.stories.tsx +350 -0
  214. package/src/components/ObjectProperties/ObjectProperties.test.tsx +111 -0
  215. package/src/components/ObjectProperties/ObjectProperties.tsx +146 -0
  216. package/src/components/ObjectProperties/index.ts +5 -0
  217. package/src/components/ObjectTree/ObjectTree.stories.tsx +134 -0
  218. package/src/components/ObjectTree/ObjectTree.tsx +190 -0
  219. package/src/components/ObjectTree/index.ts +5 -0
  220. package/src/components/RefEditor/RefEditor.stories.tsx +148 -0
  221. package/src/components/RefEditor/RefEditor.tsx +275 -0
  222. package/src/components/RefEditor/index.ts +6 -0
  223. package/src/components/RefEditor/ref-editor-extension.ts +254 -0
  224. package/src/components/Settings/AUDIT.md +51 -0
  225. package/src/components/Settings/Settings.stories.tsx +104 -0
  226. package/src/components/Settings/Settings.tsx +81 -0
  227. package/src/components/Settings/SettingsFieldSet.tsx +257 -0
  228. package/src/components/Settings/SettingsItem.tsx +58 -0
  229. package/src/components/Settings/SettingsSelectField.tsx +59 -0
  230. package/src/components/Settings/index.ts +7 -0
  231. package/src/components/ViewEditor/ViewEditor.stories.tsx +132 -64
  232. package/src/components/ViewEditor/ViewEditor.test.tsx +23 -22
  233. package/src/components/ViewEditor/ViewEditor.tsx +378 -216
  234. package/src/components/index.ts +6 -3
  235. package/src/components/testing.tsx +31 -12
  236. package/src/hooks/index.ts +2 -3
  237. package/src/hooks/useFormHandler.ts +380 -0
  238. package/src/hooks/useKeyHandler.tsx +37 -0
  239. package/src/index.ts +0 -4
  240. package/src/translations.ts +76 -59
  241. package/src/util/field-type.ts +60 -0
  242. package/src/util/field.ts +33 -43
  243. package/src/util/formatting.ts +22 -22
  244. package/src/util/index.ts +2 -1
  245. package/src/util/properties.test.ts +153 -0
  246. package/src/util/properties.ts +100 -0
  247. package/src/util/refs.ts +20 -19
  248. package/src/vite-env.d.ts +10 -0
  249. package/dist/types/src/components/ControlSection/ControlSection.d.ts +0 -23
  250. package/dist/types/src/components/ControlSection/ControlSection.d.ts.map +0 -1
  251. package/dist/types/src/components/ControlSection/ControlSection.stories.d.ts +0 -8
  252. package/dist/types/src/components/ControlSection/ControlSection.stories.d.ts.map +0 -1
  253. package/dist/types/src/components/ControlSection/index.d.ts +0 -2
  254. package/dist/types/src/components/ControlSection/index.d.ts.map +0 -1
  255. package/dist/types/src/components/Form/ArrayField.d.ts +0 -16
  256. package/dist/types/src/components/Form/ArrayField.d.ts.map +0 -1
  257. package/dist/types/src/components/Form/Defaults.d.ts +0 -14
  258. package/dist/types/src/components/Form/Defaults.d.ts.map +0 -1
  259. package/dist/types/src/components/Form/FormActions.d.ts +0 -9
  260. package/dist/types/src/components/Form/FormActions.d.ts.map +0 -1
  261. package/dist/types/src/components/Form/FormContent.d.ts +0 -57
  262. package/dist/types/src/components/Form/FormContent.d.ts.map +0 -1
  263. package/dist/types/src/components/Form/FormContext.d.ts +0 -23
  264. package/dist/types/src/components/Form/FormContext.d.ts.map +0 -1
  265. package/dist/types/src/components/Form/Input.d.ts +0 -26
  266. package/dist/types/src/components/Form/Input.d.ts.map +0 -1
  267. package/dist/types/src/components/Form/RefField.d.ts +0 -12
  268. package/dist/types/src/components/Form/RefField.d.ts.map +0 -1
  269. package/dist/types/src/components/Form/custom/GeoPointInput.d.ts +0 -4
  270. package/dist/types/src/components/Form/custom/GeoPointInput.d.ts.map +0 -1
  271. package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts +0 -4
  272. package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts.map +0 -1
  273. package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts +0 -7
  274. package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts.map +0 -1
  275. package/dist/types/src/components/Form/custom/TupleInput.d.ts +0 -6
  276. package/dist/types/src/components/Form/custom/TupleInput.d.ts.map +0 -1
  277. package/dist/types/src/components/Form/custom/index.d.ts +0 -4
  278. package/dist/types/src/components/Form/custom/index.d.ts.map +0 -1
  279. package/dist/types/src/components/Form/factory.d.ts +0 -8
  280. package/dist/types/src/components/Form/factory.d.ts.map +0 -1
  281. package/dist/types/src/components/deprecated/Form.d.ts +0 -15
  282. package/dist/types/src/components/deprecated/Form.d.ts.map +0 -1
  283. package/dist/types/src/components/deprecated/Form.stories.d.ts +0 -13
  284. package/dist/types/src/components/deprecated/Form.stories.d.ts.map +0 -1
  285. package/dist/types/src/components/deprecated/FormInput.d.ts +0 -16
  286. package/dist/types/src/components/deprecated/FormInput.d.ts.map +0 -1
  287. package/dist/types/src/components/deprecated/index.d.ts +0 -2
  288. package/dist/types/src/components/deprecated/index.d.ts.map +0 -1
  289. package/dist/types/src/hooks/useForm.d.ts +0 -67
  290. package/dist/types/src/hooks/useForm.d.ts.map +0 -1
  291. package/dist/types/src/hooks/useQueryRefOptions.d.ts +0 -23
  292. package/dist/types/src/hooks/useQueryRefOptions.d.ts.map +0 -1
  293. package/dist/types/src/hooks/useRefQueryLookupHandler.d.ts +0 -8
  294. package/dist/types/src/hooks/useRefQueryLookupHandler.d.ts.map +0 -1
  295. package/dist/types/src/util/schema.d.ts +0 -3
  296. package/dist/types/src/util/schema.d.ts.map +0 -1
  297. package/src/components/ControlSection/ControlSection.stories.tsx +0 -42
  298. package/src/components/ControlSection/ControlSection.tsx +0 -139
  299. package/src/components/Form/ArrayField.tsx +0 -125
  300. package/src/components/Form/Defaults.tsx +0 -204
  301. package/src/components/Form/FormActions.tsx +0 -54
  302. package/src/components/Form/FormContent.tsx +0 -241
  303. package/src/components/Form/FormContext.tsx +0 -110
  304. package/src/components/Form/Input.tsx +0 -51
  305. package/src/components/Form/RefField.tsx +0 -214
  306. package/src/components/Form/custom/GeoPointInput.tsx +0 -72
  307. package/src/components/Form/custom/SelectOptionsInput.stories.tsx +0 -62
  308. package/src/components/Form/custom/TupleInput.tsx +0 -47
  309. package/src/components/Form/custom/index.ts +0 -7
  310. package/src/components/Form/factory.tsx +0 -31
  311. package/src/components/deprecated/Form.stories.tsx +0 -63
  312. package/src/components/deprecated/Form.tsx +0 -119
  313. package/src/components/deprecated/FormInput.tsx +0 -71
  314. package/src/components/deprecated/index.ts +0 -5
  315. package/src/hooks/useForm.ts +0 -293
  316. package/src/hooks/useQueryRefOptions.ts +0 -53
  317. package/src/hooks/useRefQueryLookupHandler.ts +0 -39
  318. package/src/util/schema.ts +0 -14
@@ -2,102 +2,295 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import { Schema } from 'effect';
6
- import React, { useCallback, useMemo, useState } from 'react';
5
+ import { RegistryContext } from '@effect-atom/atom-react';
6
+ import * as Match from 'effect/Match';
7
+ import * as Option from 'effect/Option';
8
+ import * as Schema from 'effect/Schema';
9
+ import React, { forwardRef, useCallback, useContext, useImperativeHandle, useMemo, useState } from 'react';
7
10
 
8
- import { type SchemaRegistry } from '@dxos/echo-db';
9
- import { EchoSchema, Format, type JsonProp, isMutable, toJsonSchema } from '@dxos/echo-schema';
11
+ import {
12
+ DXN,
13
+ EID,
14
+ Entity,
15
+ Feed,
16
+ Filter,
17
+ Format,
18
+ Obj,
19
+ Query,
20
+ QueryAST,
21
+ Ref,
22
+ type Registry,
23
+ Type,
24
+ View,
25
+ } from '@dxos/echo';
26
+ import { SchemaEx } from '@dxos/effect';
10
27
  import { invariant } from '@dxos/invariant';
11
- import { Callout, IconButton, type ThemedClassName, useTranslation } from '@dxos/react-ui';
28
+ import { useObject, useQuery } from '@dxos/react-client/echo';
29
+ import { IconButton, Input, Message, type ThemedClassName, useTranslation } from '@dxos/react-ui';
30
+ import { QueryForm, type QueryFormProps } from '@dxos/react-ui-components';
12
31
  import { List } from '@dxos/react-ui-list';
13
- import { cardSpacing } from '@dxos/react-ui-stack';
14
- import { inputTextLabel, mx, subtleHover } from '@dxos/react-ui-theme';
15
- import { type DataType, FieldSchema, type FieldType, ProjectionModel, VIEW_FIELD_LIMIT } from '@dxos/schema';
32
+ import {
33
+ ParentLabelAnnotation,
34
+ ProjectionModel,
35
+ VIEW_FIELD_LIMIT,
36
+ createEchoChangeCallback,
37
+ getTypeURIFromQuery,
38
+ } from '@dxos/schema';
39
+ import { mx, osTranslations } from '@dxos/ui-theme';
16
40
 
17
- import { translationKey } from '../../translations';
18
- import { FieldEditor } from '../FieldEditor';
19
- import { Form, type FormProps } from '../Form';
20
-
21
- const listGrid = 'grid grid-cols-[min-content_1fr_min-content_min-content_min-content]';
22
- const listItemGrid = 'grid grid-cols-subgrid col-span-5';
23
-
24
- const ViewMetaSchema = Schema.Struct({
25
- typename: Format.URL.annotations({
26
- title: 'Record type',
27
- }),
28
- }).pipe(Schema.mutable);
41
+ import { translationKey } from '#translations';
29
42
 
30
- type ViewMetaType = Schema.Schema.Type<typeof ViewMetaSchema>;
43
+ 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';
31
52
 
32
53
  export type ViewEditorProps = ThemedClassName<
33
54
  {
34
- schema: Schema.Schema.AnyNoContext;
35
- view: DataType.View;
36
- registry?: SchemaRegistry;
37
- readonly?: boolean;
55
+ type?: Type.AnyEntity;
56
+ view: View.View;
57
+ mode?: 'schema' | 'tag';
58
+ registry?: Registry.Registry;
38
59
  showHeading?: boolean;
39
- onTypenameChanged?: (typename: string) => void;
60
+ onQueryChanged?: (query: QueryAST.Query, target?: EID.EID) => void;
40
61
  onDelete?: (fieldId: string) => void;
41
- } & Pick<FormProps<any>, 'outerSpacing'>
62
+ } & Pick<QueryFormProps, 'types' | 'tags'> &
63
+ Pick<FormRootProps<any>, 'readonly' | 'db'>
42
64
  >;
43
65
 
44
66
  /**
45
67
  * Schema-based object form.
46
68
  */
47
- export const ViewEditor = ({
48
- classNames,
49
- schema,
50
- view,
51
- registry,
52
- readonly: _readonly,
53
- showHeading = false,
54
- onTypenameChanged,
55
- onDelete,
56
- outerSpacing = true,
57
- }: ViewEditorProps) => {
69
+ export const ViewEditor = forwardRef<ProjectionModel | null, ViewEditorProps>(
70
+ (
71
+ {
72
+ classNames,
73
+ type,
74
+ view,
75
+ mode = 'schema',
76
+ registry,
77
+ db,
78
+ readonly,
79
+ showHeading = false,
80
+ types,
81
+ tags,
82
+ onQueryChanged,
83
+ onDelete,
84
+ },
85
+ forwardedRef,
86
+ ) => {
87
+ const atomRegistry = useContext(RegistryContext);
88
+ const schemaReadonly = type == null || Type.getDatabase(type) == null;
89
+ const { t } = useTranslation(translationKey);
90
+
91
+ const projectionModel = useMemo(() => {
92
+ if (!type) {
93
+ return null;
94
+ }
95
+ const jsonSchema = type.jsonSchema;
96
+
97
+ // Always use createEchoChangeCallback since the view is ECHO-backed.
98
+ // Pass type only when mutable to allow schema mutations.
99
+ const change = createEchoChangeCallback(view, Type.getDatabase(type) != null ? type : undefined);
100
+
101
+ const model = new ProjectionModel({
102
+ registry: atomRegistry,
103
+ view,
104
+ baseSchema: jsonSchema,
105
+ change,
106
+ });
107
+
108
+ return model;
109
+ }, [atomRegistry, type, view]);
110
+
111
+ useImperativeHandle<ProjectionModel | null, ProjectionModel | null>(forwardedRef, () => projectionModel, [
112
+ projectionModel,
113
+ ]);
114
+
115
+ const queueTarget = Match.value(view.query.ast).pipe(
116
+ Match.when({ type: 'from' }, ({ from }) => {
117
+ if (from._tag !== 'scope') {
118
+ return undefined;
119
+ }
120
+ const feedScope = from.scopes.find((s) => s._tag === 'feed');
121
+ return Option.fromNullable(feedScope).pipe(
122
+ Option.map((s) => s.feedUri),
123
+ Option.getOrUndefined,
124
+ );
125
+ }),
126
+ Match.orElse(() => undefined),
127
+ );
128
+
129
+ const feeds = useQuery(db, Filter.type(Feed.Feed));
130
+
131
+ const targetRef = useMemo(() => {
132
+ if (!queueTarget) {
133
+ return undefined;
134
+ }
135
+ const targetEid = EID.tryParse(queueTarget);
136
+ const feed = feeds.find((feed) => {
137
+ const feedEid = Feed.getQueueUri(feed);
138
+ return feedEid != null && targetEid != null && EID.equals(feedEid, targetEid);
139
+ });
140
+ return feed ? Ref.fromURI(Entity.getURI(feed)) : undefined;
141
+ }, [queueTarget, feeds]);
142
+
143
+ const viewSchema = useMemo(() => {
144
+ const base = Schema.Struct({
145
+ query:
146
+ mode === 'schema'
147
+ ? Format.URL.annotations({ title: 'Record type' })
148
+ : QueryAST.Query.annotations({ title: 'Query' }),
149
+ });
150
+
151
+ if (mode === 'tag') {
152
+ return Schema.Struct({
153
+ ...base.fields,
154
+ // TODO(wittjosiah): Replace Type.Feed with Dataset.Dataset when Ref.Ref supports unions.
155
+ target: Ref.Ref(Feed.Feed).pipe(
156
+ Schema.annotations({ title: 'Target Feed' }),
157
+ ParentLabelAnnotation.set(true),
158
+ Schema.optional,
159
+ ),
160
+ }).pipe(Schema.mutable);
161
+ }
162
+
163
+ return base.pipe(Schema.mutable);
164
+ }, [mode]);
165
+
166
+ // TODO(burdon): Need to warn user of possible consequences of editing.
167
+ // TODO(burdon): Settings should have domain name owned by user.
168
+ const viewValues = useMemo(() => {
169
+ // Schema mode edits a typename; show the version-less name of the type DXN.
170
+ const typeUri = getTypeURIFromQuery(view.query.ast);
171
+ const typeDxn = typeUri ? DXN.tryMake(typeUri) : undefined;
172
+ return {
173
+ query: mode === 'schema' ? (typeDxn ? DXN.getName(typeDxn) : (typeUri ?? '')) : view.query.ast,
174
+ target: targetRef,
175
+ };
176
+ }, [mode, view.query.ast, targetRef]);
177
+
178
+ const fieldMap = useMemo<FormFieldMap | undefined>(
179
+ () => (mode === 'tag' ? customFields({ types, tags }) : undefined),
180
+ [mode, types, tags],
181
+ );
182
+
183
+ const handleUpdate = useCallback(
184
+ (values: any) => {
185
+ const targetValue = values.target;
186
+ let queueDxn: EID.EID | undefined;
187
+
188
+ if (Ref.isRef(targetValue)) {
189
+ const feedUri = targetValue.uri;
190
+ const feed = feeds.find((feed) => Obj.getURI(feed) === feedUri);
191
+ if (feed) {
192
+ queueDxn = Feed.getQueueUri(feed);
193
+ }
194
+ }
195
+
196
+ // TODO(wittjosiah): Deep-clone the AST to plain JS or ECHO proxy arrays become objects with numeric keys.
197
+ // In schema mode, values.query is either a DXN name (static types) or a raw `echo:` EID
198
+ // (db-backed types, which have no DXN). Preserve EIDs verbatim; wrap bare names as DXN.
199
+ const query =
200
+ mode === 'schema'
201
+ ? Query.select(Filter.type(EID.isEID(values.query) ? (values.query as EID.EID) : DXN.make(values.query)))
202
+ .ast
203
+ : JSON.parse(JSON.stringify(values.query));
204
+ onQueryChanged?.(query, queueDxn);
205
+ },
206
+ [onQueryChanged, mode, feeds],
207
+ );
208
+
209
+ const handleDelete = useCallback(
210
+ (fieldId: string) => {
211
+ invariant(!readonly);
212
+ onDelete?.(fieldId);
213
+ },
214
+ [onDelete, readonly],
215
+ );
216
+
217
+ return (
218
+ <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
+ {/* TODO(burdon): Is the form read-only or just the schema? */}
227
+ <Form.Root schema={viewSchema} values={viewValues} fieldMap={fieldMap} db={db} onValuesChanged={handleUpdate}>
228
+ <Form.FieldSet />
229
+
230
+ {type && (
231
+ <>
232
+ <FormFieldLabel label={t('fields.label')} asChild />
233
+ <FieldList
234
+ type={type}
235
+ view={view}
236
+ registry={registry}
237
+ readonly={readonly}
238
+ showHeading={showHeading}
239
+ onDelete={handleDelete}
240
+ />
241
+ </>
242
+ )}
243
+ </Form.Root>
244
+ </div>
245
+ );
246
+ },
247
+ );
248
+
249
+ type FieldListProps = Omit<
250
+ Pick<ViewEditorProps, 'type' | 'view' | 'registry' | 'readonly' | 'showHeading' | 'onDelete'>,
251
+ 'type'
252
+ > & {
253
+ type: Type.AnyEntity;
254
+ };
255
+
256
+ const FieldList = ({ type, view, registry, readonly, showHeading = false, onDelete }: FieldListProps) => {
257
+ const atomRegistry = useContext(RegistryContext);
258
+ const schemaReadonly = Type.getDatabase(type) == null;
58
259
  const { t } = useTranslation(translationKey);
59
- const projection = useMemo(() => {
60
- // Use reactive and mutable version of json schema when schema is mutable.
61
- const jsonSchema = schema instanceof EchoSchema ? schema.jsonSchema : toJsonSchema(schema);
62
- return new ProjectionModel(jsonSchema, view.projection);
63
- }, [schema, view.projection]);
64
- const [expandedField, setExpandedField] = useState<FieldType['id']>();
65
- const readonly = _readonly || !isMutable(schema);
66
-
67
- // TODO(burdon): Should be reactive.
68
- const viewValues = useMemo(() => {
69
- return {
70
- // TODO(burdon): Need to warn user of possible consequences of editing.
71
- // TODO(burdon): Settings should have domain name owned by user.
72
- typename: view.query.typename,
73
- };
74
- }, [view.query.typename]);
75
260
 
76
- const handleToggleField = useCallback(
77
- (field: FieldType) => {
78
- setExpandedField((prevExpandedFieldId) => (prevExpandedFieldId === field.id ? undefined : field.id));
79
- },
80
- [readonly],
81
- );
261
+ // Subscribe to view changes for reactivity.
262
+ const [viewSnapshot] = useObject(view);
263
+
264
+ const projectionModel = useMemo(() => {
265
+ const jsonSchema = type.jsonSchema;
266
+
267
+ // Always use createEchoChangeCallback since the view is ECHO-backed.
268
+ // Pass type only when mutable to allow schema mutations.
269
+ const change = createEchoChangeCallback(view, Type.getDatabase(type) != null ? type : undefined);
82
270
 
83
- // TODO(burdon): Check if mutable; variant of useCallback that return undefined if readonly?
271
+ const model = new ProjectionModel({
272
+ registry: atomRegistry,
273
+ view,
274
+ baseSchema: jsonSchema,
275
+ change,
276
+ });
277
+
278
+ return model;
279
+ }, [atomRegistry, type, view]);
280
+
281
+ const [expandedField, setExpandedField] = useState<View.FieldType['id']>();
84
282
 
85
283
  const handleAdd = useCallback(() => {
86
284
  invariant(!readonly);
87
- const field = projection.createFieldProjection();
285
+ const field = projectionModel.createFieldProjection();
88
286
  setExpandedField(field.id);
89
- }, [schema, projection, readonly]);
287
+ }, [projectionModel, readonly]);
90
288
 
91
- const handleUpdate = useCallback(
92
- ({ typename }: ViewMetaType) => {
93
- invariant(!readonly);
94
- requestAnimationFrame(() => {
95
- if (view.query.typename !== typename && !readonly) {
96
- onTypenameChanged?.(typename);
97
- }
98
- });
289
+ const handleToggleField = useCallback(
290
+ (field: View.FieldType) => {
291
+ setExpandedField((prevExpandedFieldId) => (prevExpandedFieldId === field.id ? undefined : field.id));
99
292
  },
100
- [view.query.typename, onTypenameChanged, readonly],
293
+ [readonly],
101
294
  );
102
295
 
103
296
  const handleDelete = useCallback(
@@ -115,171 +308,140 @@ export const ViewEditor = ({
115
308
  const handleMove = useCallback(
116
309
  (fromIndex: number, toIndex: number) => {
117
310
  invariant(!readonly);
118
- // NOTE(ZaymonFC): Using arrayMove here causes a race condition with the kanban model.
119
- const fields = [...view.projection.fields];
120
- const [moved] = fields.splice(fromIndex, 1);
121
- fields.splice(toIndex, 0, moved);
122
- view.projection.fields = fields;
311
+ Obj.update(view, (view) => {
312
+ // NOTE(ZaymonFC): Using arrayMove here causes a race condition with the kanban model.
313
+ const fields = [...view.projection.fields];
314
+ const [moved] = fields.splice(fromIndex, 1);
315
+ fields.splice(toIndex, 0, moved);
316
+ view.projection.fields = fields;
317
+ });
123
318
  },
124
- [view.projection.fields, readonly],
319
+ [view, readonly],
125
320
  );
126
321
 
127
322
  const handleClose = useCallback(() => setExpandedField(undefined), []);
128
323
 
129
- const hiddenProperties = projection.getHiddenProperties();
130
-
131
324
  const handleHide = useCallback(
132
325
  (fieldId: string) => {
133
326
  setExpandedField(undefined);
134
- projection.hideFieldProjection(fieldId);
327
+ projectionModel.hideFieldProjection(fieldId);
135
328
  },
136
- [projection],
329
+ [projectionModel],
137
330
  );
138
331
 
139
332
  const handleShow = useCallback(
140
333
  (property: string) => {
141
334
  setExpandedField(undefined);
142
- projection.showFieldProjection(property as JsonProp);
335
+ projectionModel.showFieldProjection(property as SchemaEx.JsonProp);
143
336
  },
144
- [projection],
337
+ [projectionModel],
145
338
  );
146
339
 
147
- return (
148
- <div role='none' className={mx(classNames)}>
149
- {readonly && (
150
- <Callout.Root
151
- valence='info'
152
- classNames={['is-full mlb-cardSpacingBlock', outerSpacing && 'mli-cardSpacingInline']}
153
- >
154
- <Callout.Title>{t('system schema description')}</Callout.Title>
155
- </Callout.Root>
156
- )}
340
+ if (!viewSnapshot) {
341
+ return null;
342
+ }
157
343
 
158
- {/* TODO(burdon): Is the form read-only or just the schema? */}
159
- {/* TODO(burdon): Readonly fields should take up the same space as editable fields (just be ghosted). */}
160
- <Form<ViewMetaType>
161
- autoSave
162
- schema={ViewMetaSchema}
163
- values={viewValues}
164
- readonly={readonly}
165
- onSave={handleUpdate}
166
- outerSpacing={outerSpacing}
167
- />
168
-
169
- <div role='none' className={outerSpacing ? cardSpacing : 'mlb-cardSpacingBlock'}>
170
- <h2 className={mx(inputTextLabel)}>{t('fields label')}</h2>
171
-
172
- <List.Root<FieldType>
173
- items={view.projection.fields}
174
- isItem={Schema.is(FieldSchema)}
175
- getId={(field) => field.id}
176
- onMove={readonly ? undefined : handleMove}
177
- readonly={readonly}
178
- >
179
- {({ items: fields }) => (
180
- <>
181
- {showHeading && <h3 className='text-sm'>{t('field path label')}</h3>}
182
-
183
- <div role='list' className={listGrid}>
184
- {fields?.map((field) => (
185
- <List.Item<FieldType>
186
- key={field.id}
187
- item={field}
188
- classNames={listItemGrid}
189
- aria-expanded={expandedField === field.id}
190
- >
191
- <div role='none' className={mx(subtleHover, listItemGrid, 'rounded-sm cursor-pointer min-bs-10')}>
192
- <List.ItemDragHandle disabled={readonly} />
193
- <List.ItemTitle onClick={() => handleToggleField(field)}>{field.path}</List.ItemTitle>
194
- <List.ItemButton
195
- label={t('hide field label')}
196
- data-testid='hide-field-button'
197
- icon='ph--eye-slash--regular'
198
- autoHide={false}
199
- // TDOO(burdon): Is this the correct test?
200
- disabled={readonly || view.projection.fields.length <= 1}
201
- onClick={() => handleHide(field.id)}
202
- />
203
- {/* TODO(burdon): Remove unless implement undo. */}
204
- <List.ItemDeleteButton
205
- label={t('delete field label')}
206
- autoHide={false}
207
- disabled={readonly || view.projection.fields.length <= 1}
208
- onClick={() => handleDelete(field.id)}
209
- data-testid='field.delete'
210
- />
211
- <IconButton
212
- iconOnly
213
- variant='ghost'
214
- label={t('toggle expand label', { ns: 'os' })}
215
- icon={expandedField === field.id ? 'ph--caret-down--regular' : 'ph--caret-right--regular'}
216
- onClick={() => handleToggleField(field)}
217
- />
218
- </div>
219
- {expandedField === field.id && (
220
- <div role='none' className='col-span-5'>
221
- <FieldEditor
222
- readonly={readonly}
223
- projection={projection}
224
- field={field}
225
- registry={registry}
226
- onSave={handleClose}
344
+ return (
345
+ <List.Root<View.FieldType>
346
+ items={viewSnapshot.projection.fields as View.FieldType[]}
347
+ isItem={Schema.is(View.FieldSchema)}
348
+ getId={(field) => field.id}
349
+ onMove={readonly ? undefined : handleMove}
350
+ readonly={readonly}
351
+ >
352
+ {({ items: fields }) => (
353
+ <>
354
+ {showHeading && <h3 className='text-sm'>{t('field-path.label')}</h3>}
355
+ <div role='list' className='grid grid-cols-[min-content_1fr_min-content_min-content_min-content]'>
356
+ {fields?.map((field) => {
357
+ const hidden = field.visible === false;
358
+ return (
359
+ <List.Item<View.FieldType>
360
+ key={field.id}
361
+ item={field}
362
+ classNames={'grid grid-cols-subgrid col-span-5'}
363
+ aria-expanded={expandedField === field.id}
364
+ >
365
+ <div className='grid grid-cols-subgrid col-span-5 rounded-xs cursor-pointer min-h-10 dx-hover'>
366
+ <List.ItemDragHandle disabled={readonly || schemaReadonly} />
367
+ <List.ItemTitle classNames={hidden && 'text-subdued'} onClick={() => handleToggleField(field)}>
368
+ {field.path}
369
+ </List.ItemTitle>
370
+ <List.ItemIconButton
371
+ label={t(hidden ? 'show-field.label' : 'hide-field.label')}
372
+ data-testid={hidden ? 'show-field-button' : 'hide-field-button'}
373
+ icon={hidden ? 'ph--eye-closed--regular' : 'ph--eye--regular'}
374
+ autoHide={false}
375
+ disabled={readonly || (!hidden && projectionModel.getFields().length <= 1)}
376
+ onClick={() => (hidden ? handleShow(field.path) : handleHide(field.id))}
377
+ />
378
+ {!readonly && (
379
+ <>
380
+ <List.ItemDeleteButton
381
+ label={t('delete-field.label')}
382
+ autoHide={false}
383
+ disabled={readonly || schemaReadonly || viewSnapshot.projection.fields.length <= 1}
384
+ onClick={() => handleDelete(field.id)}
385
+ data-testid='field.delete'
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'
227
394
  />
228
- </div>
395
+ </>
229
396
  )}
230
- </List.Item>
231
- ))}
232
- </div>
233
- </>
234
- )}
235
- </List.Root>
236
-
237
- {hiddenProperties.length > 0 && (
238
- <>
239
- <h2 className={mx(inputTextLabel)}>{t('hidden fields label')}</h2>
240
-
241
- <List.Root<string>
242
- items={hiddenProperties}
243
- isItem={(item): item is string => typeof item === 'string'}
244
- getId={(property) => property}
245
- >
246
- {({ items: properties }) => (
247
- <div role='list' className='grid grid-cols-[1fr_min-content]'>
248
- {properties?.map((property) => (
249
- <List.Item<string>
250
- key={property}
251
- item={property}
252
- classNames={mx('grid grid-cols-subgrid col-span-2 rounded-sm', subtleHover)}
253
- >
254
- <List.ItemTitle>{property}</List.ItemTitle>
255
- <List.ItemButton
256
- label={t('show field label')}
257
- disabled={readonly}
258
- icon='ph--eye--regular'
259
- onClick={() => handleShow(property)}
260
- data-testid='show-field-button'
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}
261
406
  />
262
- </List.Item>
263
- ))}
264
- </div>
265
- )}
266
- </List.Root>
267
- </>
268
- )}
269
- </div>
270
-
271
- {!readonly && !expandedField && (
272
- <div role='none' className={outerSpacing ? cardSpacing : 'mlb-cardSpacingBlock'}>
273
- <IconButton
274
- icon='ph--plus--regular'
275
- label={t('button add property')}
276
- onClick={readonly ? undefined : handleAdd}
277
- // TODO(burdon): Show field limit in ux (not tooltip).
278
- disabled={view.projection.fields.length >= VIEW_FIELD_LIMIT}
279
- classNames='is-full'
280
- />
281
- </div>
407
+ </div>
408
+ )}
409
+ </List.Item>
410
+ );
411
+ })}
412
+ </div>
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
+ )}
424
+ </>
282
425
  )}
283
- </div>
426
+ </List.Root>
284
427
  );
285
428
  };
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
+ });
@@ -2,9 +2,12 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- export * from './deprecated';
6
-
7
- export * from './ControlSection';
8
5
  export * from './FieldEditor';
9
6
  export * from './Form';
7
+ export * from './ObjectForm';
8
+ export * from './ObjectPicker';
9
+ export * from './ObjectProperties';
10
+ export * from './ObjectTree';
11
+ export * from './RefEditor';
12
+ export * from './Settings';
10
13
  export * from './ViewEditor';