@dxos/react-ui-form 0.9.0 → 0.9.1-main.c7dcc2e112

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (282) hide show
  1. package/dist/lib/browser/index.mjs +2221 -2147
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node-esm/index.mjs +2221 -2147
  5. package/dist/lib/node-esm/index.mjs.map +4 -4
  6. package/dist/lib/node-esm/meta.json +1 -1
  7. package/dist/types/src/components/FieldEditor/FieldEditor.d.ts +3 -3
  8. package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
  9. package/dist/types/src/components/Form/Form.d.ts +15 -110
  10. package/dist/types/src/components/Form/Form.d.ts.map +1 -1
  11. package/dist/types/src/components/Form/Form.stories.d.ts +3 -37
  12. package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
  13. package/dist/types/src/components/Form/FormControls.d.ts +66 -0
  14. package/dist/types/src/components/Form/FormControls.d.ts.map +1 -0
  15. package/dist/types/src/components/Form/FormField/FieldHeader.d.ts +19 -0
  16. package/dist/types/src/components/Form/FormField/FieldHeader.d.ts.map +1 -0
  17. package/dist/types/src/components/Form/FormField/FormField.d.ts +30 -0
  18. package/dist/types/src/components/Form/FormField/FormField.d.ts.map +1 -0
  19. package/dist/types/src/components/Form/FormField/FormFieldWrapper.d.ts +47 -0
  20. package/dist/types/src/components/Form/FormField/FormFieldWrapper.d.ts.map +1 -0
  21. package/dist/types/src/components/Form/{FormFieldComponent.stories.d.ts → FormField/FormFieldWrapper.stories.d.ts} +3 -3
  22. package/dist/types/src/components/Form/FormField/FormFieldWrapper.stories.d.ts.map +1 -0
  23. package/dist/types/src/components/Form/{fields → FormField/fields/ArrayField}/ArrayField.d.ts +2 -2
  24. package/dist/types/src/components/Form/FormField/fields/ArrayField/ArrayField.d.ts.map +1 -0
  25. package/dist/types/src/components/Form/FormField/fields/ArrayField/ArrayField.stories.d.ts +87 -0
  26. package/dist/types/src/components/Form/FormField/fields/ArrayField/ArrayField.stories.d.ts.map +1 -0
  27. package/dist/types/src/components/Form/FormField/fields/ArrayField/index.d.ts +2 -0
  28. package/dist/types/src/components/Form/FormField/fields/ArrayField/index.d.ts.map +1 -0
  29. package/dist/types/src/components/Form/FormField/fields/BooleanField/BooleanField.d.ts +4 -0
  30. package/dist/types/src/components/Form/FormField/fields/BooleanField/BooleanField.d.ts.map +1 -0
  31. package/dist/types/src/components/Form/FormField/fields/BooleanField/BooleanField.stories.d.ts +88 -0
  32. package/dist/types/src/components/Form/FormField/fields/BooleanField/BooleanField.stories.d.ts.map +1 -0
  33. package/dist/types/src/components/Form/FormField/fields/BooleanField/index.d.ts +2 -0
  34. package/dist/types/src/components/Form/FormField/fields/BooleanField/index.d.ts.map +1 -0
  35. package/dist/types/src/components/Form/FormField/fields/DateField/DateField.d.ts +4 -0
  36. package/dist/types/src/components/Form/FormField/fields/DateField/DateField.d.ts.map +1 -0
  37. package/dist/types/src/components/Form/FormField/fields/DateField/DateField.stories.d.ts +88 -0
  38. package/dist/types/src/components/Form/FormField/fields/DateField/DateField.stories.d.ts.map +1 -0
  39. package/dist/types/src/components/Form/FormField/fields/DateField/index.d.ts +2 -0
  40. package/dist/types/src/components/Form/FormField/fields/DateField/index.d.ts.map +1 -0
  41. package/dist/types/src/components/Form/{fields → FormField/fields/GeoPointField}/GeoPointField.d.ts +2 -2
  42. package/dist/types/src/components/Form/FormField/fields/GeoPointField/GeoPointField.d.ts.map +1 -0
  43. package/dist/types/src/components/Form/FormField/fields/GeoPointField/GeoPointField.stories.d.ts +88 -0
  44. package/dist/types/src/components/Form/FormField/fields/GeoPointField/GeoPointField.stories.d.ts.map +1 -0
  45. package/dist/types/src/components/Form/FormField/fields/GeoPointField/index.d.ts +2 -0
  46. package/dist/types/src/components/Form/FormField/fields/GeoPointField/index.d.ts.map +1 -0
  47. package/dist/types/src/components/Form/{fields → FormField/fields/MarkdownField}/MarkdownField.d.ts +2 -2
  48. package/dist/types/src/components/Form/FormField/fields/MarkdownField/MarkdownField.d.ts.map +1 -0
  49. package/dist/types/src/components/Form/FormField/fields/MarkdownField/MarkdownField.stories.d.ts.map +1 -0
  50. package/dist/types/src/components/Form/FormField/fields/MarkdownField/index.d.ts +2 -0
  51. package/dist/types/src/components/Form/FormField/fields/MarkdownField/index.d.ts.map +1 -0
  52. package/dist/types/src/components/Form/FormField/fields/NumberField/NumberField.d.ts +4 -0
  53. package/dist/types/src/components/Form/FormField/fields/NumberField/NumberField.d.ts.map +1 -0
  54. package/dist/types/src/components/Form/FormField/fields/NumberField/NumberField.stories.d.ts +88 -0
  55. package/dist/types/src/components/Form/FormField/fields/NumberField/NumberField.stories.d.ts.map +1 -0
  56. package/dist/types/src/components/Form/FormField/fields/NumberField/index.d.ts +2 -0
  57. package/dist/types/src/components/Form/FormField/fields/NumberField/index.d.ts.map +1 -0
  58. package/dist/types/src/components/Form/FormField/fields/RefField/InlineRefField.d.ts.map +1 -0
  59. package/dist/types/src/components/Form/FormField/fields/RefField/RefField.d.ts +16 -0
  60. package/dist/types/src/components/Form/FormField/fields/RefField/RefField.d.ts.map +1 -0
  61. package/dist/types/src/components/Form/FormField/fields/RefField/RefField.stories.d.ts +92 -0
  62. package/dist/types/src/components/Form/FormField/fields/RefField/RefField.stories.d.ts.map +1 -0
  63. package/dist/types/src/components/Form/FormField/fields/RefField/RefField.test.d.ts.map +1 -0
  64. package/dist/types/src/components/Form/FormField/fields/RefField/index.d.ts +3 -0
  65. package/dist/types/src/components/Form/FormField/fields/RefField/index.d.ts.map +1 -0
  66. package/dist/types/src/components/Form/{fields → FormField/fields/SelectField}/SelectField.d.ts +2 -2
  67. package/dist/types/src/components/Form/FormField/fields/SelectField/SelectField.d.ts.map +1 -0
  68. package/dist/types/src/components/Form/FormField/fields/SelectField/SelectField.stories.d.ts +88 -0
  69. package/dist/types/src/components/Form/FormField/fields/SelectField/SelectField.stories.d.ts.map +1 -0
  70. package/dist/types/src/components/Form/FormField/fields/SelectField/index.d.ts +2 -0
  71. package/dist/types/src/components/Form/FormField/fields/SelectField/index.d.ts.map +1 -0
  72. package/dist/types/src/components/Form/FormField/fields/SelectOptionField/SelectOptionField.d.ts +5 -0
  73. package/dist/types/src/components/Form/FormField/fields/SelectOptionField/SelectOptionField.d.ts.map +1 -0
  74. package/dist/types/src/components/Form/FormField/fields/SelectOptionField/SelectOptionField.stories.d.ts.map +1 -0
  75. package/dist/types/src/components/Form/FormField/fields/SelectOptionField/index.d.ts +2 -0
  76. package/dist/types/src/components/Form/FormField/fields/SelectOptionField/index.d.ts.map +1 -0
  77. package/dist/types/src/components/Form/FormField/fields/TextAreaField/TextAreaField.d.ts +4 -0
  78. package/dist/types/src/components/Form/FormField/fields/TextAreaField/TextAreaField.d.ts.map +1 -0
  79. package/dist/types/src/components/Form/FormField/fields/TextAreaField/TextAreaField.stories.d.ts +88 -0
  80. package/dist/types/src/components/Form/FormField/fields/TextAreaField/TextAreaField.stories.d.ts.map +1 -0
  81. package/dist/types/src/components/Form/FormField/fields/TextAreaField/index.d.ts +2 -0
  82. package/dist/types/src/components/Form/FormField/fields/TextAreaField/index.d.ts.map +1 -0
  83. package/dist/types/src/components/Form/FormField/fields/TextField/TextField.d.ts +4 -0
  84. package/dist/types/src/components/Form/FormField/fields/TextField/TextField.d.ts.map +1 -0
  85. package/dist/types/src/components/Form/FormField/fields/TextField/TextField.stories.d.ts +88 -0
  86. package/dist/types/src/components/Form/FormField/fields/TextField/TextField.stories.d.ts.map +1 -0
  87. package/dist/types/src/components/Form/FormField/fields/TextField/index.d.ts +2 -0
  88. package/dist/types/src/components/Form/FormField/fields/TextField/index.d.ts.map +1 -0
  89. package/dist/types/src/components/Form/{fields → FormField/fields/TupleField}/TupleField.d.ts +2 -2
  90. package/dist/types/src/components/Form/FormField/fields/TupleField/TupleField.d.ts.map +1 -0
  91. package/dist/types/src/components/Form/FormField/fields/TupleField/TupleField.stories.d.ts +88 -0
  92. package/dist/types/src/components/Form/FormField/fields/TupleField/TupleField.stories.d.ts.map +1 -0
  93. package/dist/types/src/components/Form/FormField/fields/TupleField/index.d.ts +2 -0
  94. package/dist/types/src/components/Form/FormField/fields/TupleField/index.d.ts.map +1 -0
  95. package/dist/types/src/components/Form/{fields → FormField/fields}/index.d.ts +0 -1
  96. package/dist/types/src/components/Form/FormField/fields/index.d.ts.map +1 -0
  97. package/dist/types/src/components/Form/FormField/index.d.ts +5 -0
  98. package/dist/types/src/components/Form/FormField/index.d.ts.map +1 -0
  99. package/dist/types/src/components/Form/{FormFieldSet.d.ts → FormFieldSet/FormFieldSet.d.ts} +4 -3
  100. package/dist/types/src/components/Form/FormFieldSet/FormFieldSet.d.ts.map +1 -0
  101. package/dist/types/src/components/Form/FormFieldSet/index.d.ts +2 -0
  102. package/dist/types/src/components/Form/FormFieldSet/index.d.ts.map +1 -0
  103. package/dist/types/src/components/Form/FormLayout/FormLayout.d.ts.map +1 -0
  104. package/dist/types/src/components/Form/FormLayout/FormLayout.stories.d.ts.map +1 -0
  105. package/dist/types/src/components/Form/FormLayout/FormLayout.stories.test.d.ts.map +1 -0
  106. package/dist/types/src/components/Form/FormLayout/FormLayout.test.d.ts.map +1 -0
  107. package/dist/types/src/components/Form/FormLayout/index.d.ts +3 -0
  108. package/dist/types/src/components/Form/FormLayout/index.d.ts.map +1 -0
  109. package/dist/types/src/components/Form/FormLayout/parser.d.ts.map +1 -0
  110. package/dist/types/src/components/Form/FormLayout/parser.test.d.ts.map +1 -0
  111. package/dist/types/src/components/Form/index.d.ts +3 -5
  112. package/dist/types/src/components/Form/index.d.ts.map +1 -1
  113. package/dist/types/src/components/Form/meta-tags.d.ts +2 -2
  114. package/dist/types/src/components/ObjectForm/ObjectForm.d.ts.map +1 -1
  115. package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts +6 -23
  116. package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts.map +1 -1
  117. package/dist/types/src/components/ObjectProperties/ObjectProperties.d.ts.map +1 -1
  118. package/dist/types/src/components/RefEditor/RefEditor.stories.d.ts.map +1 -1
  119. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts +1 -1
  120. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
  121. package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
  122. package/dist/types/src/hooks/index.d.ts +1 -0
  123. package/dist/types/src/hooks/index.d.ts.map +1 -1
  124. package/dist/types/src/hooks/useFormContext.d.ts +37 -0
  125. package/dist/types/src/hooks/useFormContext.d.ts.map +1 -0
  126. package/dist/types/src/hooks/useFormHandler.d.ts +1 -4
  127. package/dist/types/src/hooks/useFormHandler.d.ts.map +1 -1
  128. package/dist/types/src/index.d.ts +1 -0
  129. package/dist/types/src/index.d.ts.map +1 -1
  130. package/dist/types/src/{components/testing.d.ts → testing/TestLayout.d.ts} +1 -1
  131. package/dist/types/src/testing/TestLayout.d.ts.map +1 -0
  132. package/dist/types/src/testing/index.d.ts +3 -0
  133. package/dist/types/src/testing/index.d.ts.map +1 -0
  134. package/dist/types/src/testing/schema.d.ts +43 -0
  135. package/dist/types/src/testing/schema.d.ts.map +1 -0
  136. package/dist/types/src/types.d.ts +112 -0
  137. package/dist/types/src/types.d.ts.map +1 -0
  138. package/dist/types/src/util/index.d.ts +1 -0
  139. package/dist/types/src/util/index.d.ts.map +1 -1
  140. package/dist/types/src/util/omit.d.ts +12 -0
  141. package/dist/types/src/util/omit.d.ts.map +1 -0
  142. package/dist/types/tsconfig.tsbuildinfo +1 -1
  143. package/package.json +35 -34
  144. package/src/components/FieldEditor/FieldEditor.stories.tsx +1 -1
  145. package/src/components/FieldEditor/FieldEditor.test.tsx +1 -1
  146. package/src/components/FieldEditor/FieldEditor.tsx +5 -4
  147. package/src/components/Form/Form.stories.tsx +4 -49
  148. package/src/components/Form/Form.tsx +18 -447
  149. package/src/components/Form/FormControls.tsx +320 -0
  150. package/src/components/Form/FormField/FieldHeader.tsx +36 -0
  151. package/src/components/Form/{FormField.tsx → FormField/FormField.tsx} +35 -59
  152. package/src/components/Form/{FormFieldComponent.stories.tsx → FormField/FormFieldWrapper.stories.tsx} +24 -17
  153. package/src/components/Form/{FormFieldComponent.tsx → FormField/FormFieldWrapper.tsx} +21 -95
  154. package/src/components/Form/FormField/fields/ArrayField/ArrayField.stories.tsx +103 -0
  155. package/src/components/Form/FormField/fields/ArrayField/ArrayField.tsx +269 -0
  156. package/src/components/Form/FormField/fields/ArrayField/index.ts +5 -0
  157. package/src/components/Form/FormField/fields/BooleanField/BooleanField.stories.tsx +52 -0
  158. package/src/components/Form/{fields → FormField/fields/BooleanField}/BooleanField.tsx +10 -3
  159. package/src/components/Form/FormField/fields/BooleanField/index.ts +5 -0
  160. package/src/components/Form/FormField/fields/DateField/DateField.stories.tsx +60 -0
  161. package/src/components/Form/{fields → FormField/fields/DateField}/DateField.tsx +4 -2
  162. package/src/components/Form/FormField/fields/DateField/index.ts +5 -0
  163. package/src/components/Form/FormField/fields/GeoPointField/GeoPointField.stories.tsx +53 -0
  164. package/src/components/Form/{fields → FormField/fields/GeoPointField}/GeoPointField.tsx +4 -3
  165. package/src/components/Form/FormField/fields/GeoPointField/index.ts +5 -0
  166. package/src/components/Form/{fields → FormField/fields/MarkdownField}/MarkdownField.stories.tsx +6 -6
  167. package/src/components/Form/{fields → FormField/fields/MarkdownField}/MarkdownField.tsx +3 -2
  168. package/src/components/Form/FormField/fields/MarkdownField/index.ts +5 -0
  169. package/src/components/Form/FormField/fields/NumberField/NumberField.stories.tsx +52 -0
  170. package/src/components/Form/{fields → FormField/fields/NumberField}/NumberField.tsx +27 -2
  171. package/src/components/Form/FormField/fields/NumberField/index.ts +5 -0
  172. package/src/components/Form/{fields → FormField/fields/RefField}/InlineRefField.tsx +8 -7
  173. package/src/components/Form/FormField/fields/RefField/RefField.stories.tsx +97 -0
  174. package/src/components/Form/{fields → FormField/fields/RefField}/RefField.test.ts +2 -1
  175. package/src/components/Form/{fields → FormField/fields/RefField}/RefField.tsx +6 -25
  176. package/src/components/Form/FormField/fields/RefField/index.ts +6 -0
  177. package/src/components/Form/FormField/fields/SelectField/SelectField.stories.tsx +53 -0
  178. package/src/components/Form/{fields → FormField/fields/SelectField}/SelectField.tsx +4 -2
  179. package/src/components/Form/FormField/fields/SelectField/index.ts +5 -0
  180. package/src/components/Form/{fields → FormField/fields/SelectOptionField}/SelectOptionField.stories.tsx +5 -5
  181. package/src/components/Form/{fields → FormField/fields/SelectOptionField}/SelectOptionField.tsx +55 -53
  182. package/src/components/Form/FormField/fields/SelectOptionField/index.ts +5 -0
  183. package/src/components/Form/FormField/fields/TextAreaField/TextAreaField.stories.tsx +53 -0
  184. package/src/components/Form/{fields → FormField/fields/TextAreaField}/TextAreaField.tsx +4 -2
  185. package/src/components/Form/FormField/fields/TextAreaField/index.ts +5 -0
  186. package/src/components/Form/FormField/fields/TextField/TextField.stories.tsx +52 -0
  187. package/src/components/Form/{fields → FormField/fields/TextField}/TextField.tsx +4 -2
  188. package/src/components/Form/FormField/fields/TextField/index.ts +5 -0
  189. package/src/components/Form/FormField/fields/TupleField/TupleField.stories.tsx +55 -0
  190. package/src/components/Form/{fields → FormField/fields/TupleField}/TupleField.tsx +4 -2
  191. package/src/components/Form/FormField/fields/TupleField/index.ts +5 -0
  192. package/src/components/Form/{fields → FormField/fields}/index.ts +0 -1
  193. package/src/components/Form/FormField/index.ts +8 -0
  194. package/src/components/Form/{FormFieldSet.tsx → FormFieldSet/FormFieldSet.tsx} +16 -32
  195. package/src/components/Form/FormFieldSet/index.ts +5 -0
  196. package/src/components/Form/{Layout → FormLayout}/FormLayout.stories.tsx +4 -4
  197. package/src/components/Form/{Layout → FormLayout}/FormLayout.tsx +7 -6
  198. package/src/components/Form/{Layout → FormLayout}/index.ts +1 -2
  199. package/src/components/Form/index.ts +3 -5
  200. package/src/components/Form/meta-tags.ts +1 -1
  201. package/src/components/ObjectForm/ObjectForm.tsx +15 -14
  202. package/src/components/ObjectPicker/ObjectPicker.tsx +19 -27
  203. package/src/components/ObjectProperties/ObjectProperties.stories.tsx +1 -1
  204. package/src/components/ObjectProperties/ObjectProperties.test.tsx +1 -1
  205. package/src/components/ObjectProperties/ObjectProperties.tsx +2 -1
  206. package/src/components/RefEditor/RefEditor.stories.tsx +0 -1
  207. package/src/components/ViewEditor/ViewEditor.stories.tsx +4 -5
  208. package/src/components/ViewEditor/ViewEditor.test.tsx +1 -1
  209. package/src/components/ViewEditor/ViewEditor.tsx +98 -128
  210. package/src/hooks/index.ts +1 -0
  211. package/src/hooks/useFormContext.ts +86 -0
  212. package/src/hooks/useFormHandler.ts +1 -4
  213. package/src/index.ts +1 -0
  214. package/src/{components/testing.tsx → testing/TestLayout.tsx} +1 -1
  215. package/src/testing/index.ts +7 -0
  216. package/src/testing/schema.ts +59 -0
  217. package/src/types.ts +134 -0
  218. package/src/util/index.ts +1 -0
  219. package/src/util/omit.ts +47 -0
  220. package/src/vitest-setup.ts +40 -0
  221. package/dist/types/src/components/Form/FormField.d.ts +0 -52
  222. package/dist/types/src/components/Form/FormField.d.ts.map +0 -1
  223. package/dist/types/src/components/Form/FormFieldComponent.d.ts +0 -98
  224. package/dist/types/src/components/Form/FormFieldComponent.d.ts.map +0 -1
  225. package/dist/types/src/components/Form/FormFieldComponent.stories.d.ts.map +0 -1
  226. package/dist/types/src/components/Form/FormFieldSet.d.ts.map +0 -1
  227. package/dist/types/src/components/Form/FormTooltipsContext.d.ts +0 -19
  228. package/dist/types/src/components/Form/FormTooltipsContext.d.ts.map +0 -1
  229. package/dist/types/src/components/Form/Layout/FormLayout.d.ts.map +0 -1
  230. package/dist/types/src/components/Form/Layout/FormLayout.stories.d.ts.map +0 -1
  231. package/dist/types/src/components/Form/Layout/FormLayout.stories.test.d.ts.map +0 -1
  232. package/dist/types/src/components/Form/Layout/FormLayout.test.d.ts.map +0 -1
  233. package/dist/types/src/components/Form/Layout/annotation.d.ts +0 -30
  234. package/dist/types/src/components/Form/Layout/annotation.d.ts.map +0 -1
  235. package/dist/types/src/components/Form/Layout/index.d.ts +0 -4
  236. package/dist/types/src/components/Form/Layout/index.d.ts.map +0 -1
  237. package/dist/types/src/components/Form/Layout/parser.d.ts.map +0 -1
  238. package/dist/types/src/components/Form/Layout/parser.test.d.ts.map +0 -1
  239. package/dist/types/src/components/Form/fields/ArrayField.d.ts.map +0 -1
  240. package/dist/types/src/components/Form/fields/BooleanField.d.ts +0 -4
  241. package/dist/types/src/components/Form/fields/BooleanField.d.ts.map +0 -1
  242. package/dist/types/src/components/Form/fields/DateField.d.ts +0 -4
  243. package/dist/types/src/components/Form/fields/DateField.d.ts.map +0 -1
  244. package/dist/types/src/components/Form/fields/GeoPointField.d.ts.map +0 -1
  245. package/dist/types/src/components/Form/fields/InlineRefField.d.ts.map +0 -1
  246. package/dist/types/src/components/Form/fields/MarkdownField.d.ts.map +0 -1
  247. package/dist/types/src/components/Form/fields/MarkdownField.stories.d.ts.map +0 -1
  248. package/dist/types/src/components/Form/fields/NumberField.d.ts +0 -4
  249. package/dist/types/src/components/Form/fields/NumberField.d.ts.map +0 -1
  250. package/dist/types/src/components/Form/fields/RefField.d.ts +0 -34
  251. package/dist/types/src/components/Form/fields/RefField.d.ts.map +0 -1
  252. package/dist/types/src/components/Form/fields/RefField.test.d.ts.map +0 -1
  253. package/dist/types/src/components/Form/fields/SelectField.d.ts.map +0 -1
  254. package/dist/types/src/components/Form/fields/SelectOptionField.d.ts +0 -5
  255. package/dist/types/src/components/Form/fields/SelectOptionField.d.ts.map +0 -1
  256. package/dist/types/src/components/Form/fields/SelectOptionField.stories.d.ts.map +0 -1
  257. package/dist/types/src/components/Form/fields/TextAreaField.d.ts +0 -4
  258. package/dist/types/src/components/Form/fields/TextAreaField.d.ts.map +0 -1
  259. package/dist/types/src/components/Form/fields/TextField.d.ts +0 -4
  260. package/dist/types/src/components/Form/fields/TextField.d.ts.map +0 -1
  261. package/dist/types/src/components/Form/fields/TupleField.d.ts.map +0 -1
  262. package/dist/types/src/components/Form/fields/index.d.ts.map +0 -1
  263. package/dist/types/src/components/testing.d.ts.map +0 -1
  264. package/src/components/Form/AUDIT.md +0 -17
  265. package/src/components/Form/FormTooltipsContext.ts +0 -25
  266. package/src/components/Form/Layout/annotation.ts +0 -38
  267. package/src/components/Form/README.md +0 -3
  268. package/src/components/Form/fields/ArrayField.tsx +0 -173
  269. /package/dist/types/src/components/Form/{fields → FormField/fields/MarkdownField}/MarkdownField.stories.d.ts +0 -0
  270. /package/dist/types/src/components/Form/{fields → FormField/fields/RefField}/InlineRefField.d.ts +0 -0
  271. /package/dist/types/src/components/Form/{fields → FormField/fields/RefField}/RefField.test.d.ts +0 -0
  272. /package/dist/types/src/components/Form/{fields → FormField/fields/SelectOptionField}/SelectOptionField.stories.d.ts +0 -0
  273. /package/dist/types/src/components/Form/{Layout → FormLayout}/FormLayout.d.ts +0 -0
  274. /package/dist/types/src/components/Form/{Layout → FormLayout}/FormLayout.stories.d.ts +0 -0
  275. /package/dist/types/src/components/Form/{Layout → FormLayout}/FormLayout.stories.test.d.ts +0 -0
  276. /package/dist/types/src/components/Form/{Layout → FormLayout}/FormLayout.test.d.ts +0 -0
  277. /package/dist/types/src/components/Form/{Layout → FormLayout}/parser.d.ts +0 -0
  278. /package/dist/types/src/components/Form/{Layout → FormLayout}/parser.test.d.ts +0 -0
  279. /package/src/components/Form/{Layout → FormLayout}/FormLayout.stories.test.tsx +0 -0
  280. /package/src/components/Form/{Layout → FormLayout}/FormLayout.test.ts +0 -0
  281. /package/src/components/Form/{Layout → FormLayout}/parser.test.ts +0 -0
  282. /package/src/components/Form/{Layout → FormLayout}/parser.ts +0 -0
@@ -3,76 +3,13 @@
3
3
  //
4
4
 
5
5
  import { format as formatDate } from 'date-fns';
6
- import type * as Schema from 'effect/Schema';
7
- import type * as SchemaAST from 'effect/SchemaAST';
8
- import React, {
9
- Component,
10
- type FC,
11
- type FocusEvent,
12
- type PropsWithChildren,
13
- type ReactElement,
14
- type ReactNode,
15
- } from 'react';
16
-
17
- import { type Database, Format } from '@dxos/echo';
18
- import { Icon, Input, ThemedClassName, Tooltip } from '@dxos/react-ui';
19
- import { inputTextLabel } from '@dxos/react-ui';
20
- import { mx } from '@dxos/ui-theme';
21
-
22
- import { type FormFieldStatus } from '../../hooks';
23
- import { useFormTooltips } from './FormTooltipsContext';
6
+ import React, { Component, type PropsWithChildren, type ReactNode } from 'react';
24
7
 
25
- /**
26
- * Dynamic props passed to input components.
27
- */
28
- export type FormFieldStateProps<T = any> = {
29
- getStatus: () => FormFieldStatus;
30
- getValue: () => T | undefined;
31
- onBlur: (event: FocusEvent<HTMLElement>) => void;
32
- onValueChange: (type: SchemaAST.AST, value: T) => void;
33
- };
34
-
35
- /**
36
- * Presentation mode.
37
- * - full: Show label, control, and status.
38
- * - compact: Show label and control.
39
- * - inline: Control only.
40
- * - static: Plain DOM; omit all undefined values.
41
- */
42
- // TODO(burdon): 'inline' should be orthogonal to the layout (e.g., array of inline static).
43
- export type Presentation = 'full' | 'compact' | 'inline' | 'static';
8
+ import { Format } from '@dxos/echo';
9
+ import { inputTextLabel, Icon, Input, ThemedClassName, Tooltip } from '@dxos/react-ui';
10
+ import { mx } from '@dxos/ui-theme';
44
11
 
45
- /**
46
- * Props passed to input components.
47
- */
48
- export type FormFieldComponentProps<T = any> = {
49
- /** Database the form is editing against; populated for fields whose value is an ECHO object/Ref. */
50
- db?: Database.Database;
51
- type: SchemaAST.AST;
52
- format?: Format.TypeFormat;
53
- readonly?: boolean;
54
- label: string;
55
- /**
56
- * Dotted JSON path of this field within the form values (e.g.
57
- * `runtime.client.storage.persistent`). Forwarded to `FormFieldLabel` so
58
- * that it can render the path as a debug hint when the enclosing
59
- * `Form.Root` has `debug` enabled.
60
- */
61
- jsonPath?: string;
62
- placeholder?: string;
63
- autoFocus?: boolean;
64
- layout?: Presentation;
65
- } & FormFieldStateProps<T>;
66
-
67
- export type FormFieldComponent = FC<FormFieldComponentProps>;
68
-
69
- export type FormFieldMap = Record<string, FormFieldComponent>;
70
-
71
- export type FormFieldProvider = (props: {
72
- prop: string;
73
- schema: Schema.Schema<any>;
74
- fieldProps: FormFieldComponentProps;
75
- }) => ReactElement | null | undefined;
12
+ import { type FormFieldRendererProps } from '#types';
76
13
 
77
14
  //
78
15
  // FormFieldLabel
@@ -80,15 +17,12 @@ export type FormFieldProvider = (props: {
80
17
 
81
18
  export type FormFieldLabelProps = ThemedClassName<
82
19
  {
83
- asChild?: boolean;
20
+ /** Render a plain `<span>` instead of an input-associated `Input.Label`, for labels used outside an `Input.Root` (e.g. section/group headers). */
21
+ standalone?: boolean;
84
22
  error?: string;
85
23
  /**
86
24
  * JSON path of the field this label describes (e.g. `runtime.client.storage.persistent`).
87
- * Surfaced as a hover tooltip on the label when the enclosing `Form.Root`
88
- * has `tooltips` enabled (the default) -- useful for spotting which field
89
- * maps to which path when authoring schemas or filing bugs against a form.
90
- * Callers can supply the path unconditionally; the label suppresses the
91
- * tooltip when `Form.Root tooltips={false}`.
25
+ * Field metadata; accepted by callers but not currently rendered.
92
26
  */
93
27
  path?: string;
94
28
  /**
@@ -97,7 +31,7 @@ export type FormFieldLabelProps = ThemedClassName<
97
31
  */
98
32
  button?: ReactNode;
99
33
  onClick?: () => void;
100
- } & Pick<FormFieldComponentProps, 'label' | 'readonly'>
34
+ } & Pick<FormFieldRendererProps, 'label' | 'readonly'>
101
35
  >;
102
36
 
103
37
  export const FormFieldLabel = ({
@@ -105,13 +39,11 @@ export const FormFieldLabel = ({
105
39
  label,
106
40
  error,
107
41
  readonly,
108
- asChild,
109
- path,
42
+ standalone,
110
43
  button,
111
44
  onClick,
112
45
  }: FormFieldLabelProps) => {
113
- const tooltips = useFormTooltips();
114
- const Label = readonly || asChild ? 'span' : Input.Label;
46
+ const Label = readonly || standalone ? 'span' : Input.Label;
115
47
  const labelNode = <Label className={mx(inputTextLabel, 'text-sm')}>{label}</Label>;
116
48
 
117
49
  return (
@@ -119,13 +51,7 @@ export const FormFieldLabel = ({
119
51
  className={mx('grid grid-cols-[1fr_auto_auto] items-center select-none', onClick && 'cursor-pointer', classNames)}
120
52
  onClick={onClick}
121
53
  >
122
- {tooltips && path ? (
123
- <Tooltip.Trigger asChild content={path} side='bottom'>
124
- {labelNode}
125
- </Tooltip.Trigger>
126
- ) : (
127
- labelNode
128
- )}
54
+ {labelNode}
129
55
  {error ? (
130
56
  <Tooltip.Trigger asChild content={error} side='bottom'>
131
57
  <Icon icon='ph--warning--regular' size={4} classNames='text-error-text' />
@@ -144,13 +70,6 @@ FormFieldLabel.displayName = 'Form.FieldLabel';
144
70
  // FormFieldWrapper
145
71
  //
146
72
 
147
- export type FormFieldWrapperProps<T = any> = Pick<
148
- FormFieldComponentProps,
149
- 'readonly' | 'label' | 'layout' | 'getStatus' | 'getValue' | 'jsonPath' | 'format'
150
- > & {
151
- children?: (props: { value: T }) => ReactNode;
152
- };
153
-
154
73
  /**
155
74
  * Formats a value for `static` (read-only, plain-DOM) presentation based on its
156
75
  * type `format`. Dates/times are rendered human-readable; everything else falls
@@ -177,6 +96,13 @@ const formatStaticValue = (value: unknown, format?: Format.TypeFormat): string =
177
96
  }
178
97
  };
179
98
 
99
+ export type FormFieldWrapperProps<T = any> = Pick<
100
+ FormFieldRendererProps,
101
+ 'readonly' | 'label' | 'layout' | 'getStatus' | 'getValue' | 'jsonPath' | 'format'
102
+ > & {
103
+ children?: (props: { value: T }) => ReactNode;
104
+ };
105
+
180
106
  export const FormFieldWrapper = <T,>(props: FormFieldWrapperProps<T>) => {
181
107
  const { children, readonly, layout, label, jsonPath, format, getStatus, getValue } = props;
182
108
  const { status, error } = getStatus();
@@ -237,8 +163,8 @@ export class FormFieldErrorBoundary extends Component<FormFieldErrorBoundaryProp
237
163
  override render() {
238
164
  if (this.state.error) {
239
165
  return (
240
- <div className='flex gap-2 border border-rose-bg font-mono text-sm'>
241
- <span className='bg-rose-bg text-base-fg px-1 font-thin'>ERROR</span>
166
+ <div className='flex gap-2 border border-error-border font-mono text-sm'>
167
+ <span className='bg-error-bg text-base-fg px-1 font-thin'>ERROR</span>
242
168
  {String(this.props.path?.join('.'))}
243
169
  </div>
244
170
  );
@@ -0,0 +1,103 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
6
+ import * as Schema from 'effect/Schema';
7
+ import React, { useState } from 'react';
8
+
9
+ import { FormLayoutAnnotation, FormOrderedAnnotation, LabelAnnotation } from '@dxos/echo/Annotation';
10
+ import { withLayout, withTheme } from '@dxos/react-ui/testing';
11
+ import { trim } from '@dxos/util';
12
+
13
+ import { translations } from '#translations';
14
+
15
+ import { TestLayout } from '../../../../../testing';
16
+ import { Form } from '../../../Form';
17
+
18
+ // Mirrors the structure of `Pipeline` (`@dxos/types`): a scalar header plus an
19
+ // array of `Column`-like structs. The array is the field we render as either a
20
+ // static or an ordered (drag-to-reorder) list.
21
+ const Column = Schema.Struct({
22
+ name: Schema.String.annotations({ title: 'Name' }),
23
+ value: Schema.optional(Schema.Number.annotations({ title: 'Value' })),
24
+ }).pipe(
25
+ Schema.mutable,
26
+ LabelAnnotation.set(['name']),
27
+ FormLayoutAnnotation.set({
28
+ default: trim`
29
+ <grid cols="2">
30
+ <field name="name"/>
31
+ <field name="value"/>
32
+ </grid>
33
+ `,
34
+ }),
35
+ );
36
+ type Column = Schema.Schema.Type<typeof Column>;
37
+
38
+ const columnsField = Schema.Array(Column).pipe(Schema.mutable, Schema.annotations({ title: 'Columns' }));
39
+
40
+ const headerFields = {
41
+ name: Schema.String.pipe(Schema.annotations({ title: 'Name' }), Schema.optional),
42
+ description: Schema.String.pipe(Schema.annotations({ title: 'Description' }), Schema.optional),
43
+ };
44
+
45
+ const Pipeline = Schema.Struct({
46
+ ...headerFields,
47
+ columns: columnsField,
48
+ }).pipe(Schema.mutable);
49
+
50
+ // `FormOrderedAnnotation` opts the array into a drag-to-reorder list (see `ArrayField`).
51
+ const OrderedPipeline = Schema.Struct({
52
+ ...headerFields,
53
+ columns: columnsField.pipe(FormOrderedAnnotation.set(true)),
54
+ }).pipe(Schema.mutable);
55
+
56
+ type Pipeline = Schema.Schema.Type<typeof Pipeline>;
57
+
58
+ const initialValues: Pipeline = {
59
+ name: 'Sales',
60
+ description: 'Lead qualification pipeline.',
61
+ columns: [{ name: 'Contacts' }, { name: 'Organizations' }, { name: 'Tasks' }, { name: 'Messages', value: 100 }],
62
+ };
63
+
64
+ const StoryComponent = ({ schema }: { schema: typeof Pipeline }) => {
65
+ const [values, setValues] = useState<Pipeline>(initialValues);
66
+
67
+ return (
68
+ <TestLayout json={values}>
69
+ <Form.Root
70
+ schema={schema}
71
+ values={values}
72
+ onValuesChanged={(values) => setValues((prev) => ({ ...prev, ...values }))}
73
+ >
74
+ <Form.Viewport scroll>
75
+ <Form.Content>
76
+ <Form.FieldSet />
77
+ </Form.Content>
78
+ </Form.Viewport>
79
+ </Form.Root>
80
+ </TestLayout>
81
+ );
82
+ };
83
+
84
+ const meta = {
85
+ title: 'ui/react-ui-form/FormField/ArrayField',
86
+ decorators: [withTheme(), withLayout({ layout: 'fullscreen' })],
87
+ parameters: {
88
+ layout: 'fullscreen',
89
+ translations,
90
+ },
91
+ } satisfies Meta<typeof StoryComponent>;
92
+
93
+ export default meta;
94
+
95
+ type Story = StoryObj<typeof meta>;
96
+
97
+ export const Default: Story = {
98
+ render: () => <StoryComponent schema={Pipeline} />,
99
+ };
100
+
101
+ export const Ordered: Story = {
102
+ render: () => <StoryComponent schema={OrderedPipeline} />,
103
+ };
@@ -0,0 +1,269 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import * as Option from 'effect/Option';
6
+ import * as SchemaAST from 'effect/SchemaAST';
7
+ import React, { type ReactNode, useCallback, useRef } from 'react';
8
+
9
+ import { Annotation, Ref } from '@dxos/echo';
10
+ import { SchemaEx } from '@dxos/effect';
11
+ import { useTranslation } from '@dxos/react-ui';
12
+ import { OrderedList } from '@dxos/react-ui-list';
13
+ import { arrayMove } from '@dxos/util';
14
+
15
+ import { translationKey } from '#translations';
16
+ import { type FormFieldStateProps } from '#types';
17
+
18
+ import { useFormValues } from '../../../../../hooks';
19
+ import { getFormProperties } from '../../../../../util';
20
+ import { FieldHeader } from '../../FieldHeader';
21
+ import { CompactIconButton, FormField, type FormFieldProps } from '../../FormField';
22
+
23
+ // Synthetic id assigned to each row when rendering an ordered list. Plain form
24
+ // values have no stable identity, so drag-and-drop (which requires a stable key
25
+ // surviving the `onValuesChanged` round-trip) is given one here and kept in
26
+ // lockstep with the array via the add/delete/move handlers.
27
+ const DND_ID = '__dndId';
28
+
29
+ type OrderedItem = {
30
+ [DND_ID]: string;
31
+ value: unknown;
32
+ index: number;
33
+ };
34
+
35
+ const isOrderedItem = (item: any): item is OrderedItem =>
36
+ !!item && typeof item === 'object' && typeof item[DND_ID] === 'string';
37
+
38
+ const getOrderedId = (item: OrderedItem): string => item[DND_ID];
39
+
40
+ export type ArrayFieldProps = {
41
+ label: string;
42
+ fieldProps: FormFieldStateProps;
43
+ } & FormFieldProps;
44
+
45
+ export const ArrayField = ({
46
+ type,
47
+ path,
48
+ label,
49
+ readonly,
50
+ layout,
51
+ fieldProps: inputProps,
52
+ ...props
53
+ }: ArrayFieldProps) => {
54
+ const { t } = useTranslation(translationKey);
55
+ const elementType = SchemaEx.getArrayElementType(type);
56
+ const { onValueChange } = inputProps;
57
+ const values = useFormValues(ArrayField.displayName, path, () => []);
58
+
59
+ // Order is meaningful and user-controllable -> render as a drag-to-reorder list.
60
+ const ordered = Annotation.FormOrderedAnnotation.getFromAst(type).pipe(Option.getOrElse(() => false));
61
+
62
+ // Synthetic identity map (see `DND_ID`). The counter only advances when the
63
+ // array grows; reconciliation here covers the initial mount and any external
64
+ // length change, while the handlers below keep ids aligned on mutation.
65
+ const idsRef = useRef<string[]>([]);
66
+ const counterRef = useRef(0);
67
+ const nextId = useCallback(() => `${DND_ID}-${counterRef.current++}`, []);
68
+
69
+ const getDefaultObjectValue = (typeNode: SchemaAST.AST): any => {
70
+ const baseNode = SchemaEx.findNode(typeNode, SchemaEx.isDiscriminatedUnion);
71
+ const typeLiteral = baseNode
72
+ ? SchemaEx.getDiscriminatedType(baseNode, {})
73
+ : SchemaEx.findNode(typeNode, SchemaAST.isTypeLiteral);
74
+ if (!typeLiteral) {
75
+ return {};
76
+ }
77
+
78
+ return Object.fromEntries(
79
+ getFormProperties(typeLiteral).map((prop) => {
80
+ const defaultValue = SchemaAST.getDefaultAnnotation(prop.type).pipe((annotation) =>
81
+ Option.getOrUndefined(annotation),
82
+ );
83
+ return [prop.name, defaultValue];
84
+ }),
85
+ );
86
+ };
87
+
88
+ const handleAdd = useCallback(() => {
89
+ const defaultValue =
90
+ elementType && SchemaEx.isNestedType(elementType)
91
+ ? getDefaultObjectValue(elementType)
92
+ : getDefaultValue(elementType);
93
+ idsRef.current.push(nextId());
94
+ // `values` is `undefined` on first render for arrays whose parent path
95
+ // hasn't been materialised in the form values yet (e.g. `package.repos`
96
+ // when the form starts with no `package`). `useFormValues`'s default-
97
+ // value effect would eventually backfill it to `[]`, but until then the
98
+ // old `values && ...` guard silently swallowed the click. Treat a
99
+ // missing array as empty so Add always produces `[defaultValue]`.
100
+ onValueChange(type, [...(values ?? []), defaultValue]);
101
+ }, [onValueChange, type, elementType, values, nextId]);
102
+
103
+ const handleDelete = useCallback(
104
+ (idx: number) => {
105
+ idsRef.current.splice(idx, 1);
106
+ onValueChange(
107
+ type,
108
+ values?.filter((_, i) => i !== idx),
109
+ );
110
+ },
111
+ [onValueChange, type, values],
112
+ );
113
+
114
+ const handleMove = useCallback(
115
+ (fromIndex: number, toIndex: number) => {
116
+ const next = [...(values ?? [])];
117
+ arrayMove(next, fromIndex, toIndex);
118
+ arrayMove(idsRef.current, fromIndex, toIndex);
119
+ onValueChange(type, next);
120
+ },
121
+ [onValueChange, type, values],
122
+ );
123
+
124
+ if (!elementType || ((readonly || layout === 'static') && values && values.length < 1)) {
125
+ return null;
126
+ }
127
+
128
+ const renderItemAsObject = elementType && SchemaEx.isNestedType(elementType) && !Ref.isRefType(elementType);
129
+
130
+ // Object items: a recursively-rendered FormField (multiple sub-rows for the
131
+ // object's fields). Scalar items (refs, primitives): a single inline FormField.
132
+ const renderField = (index: number, isLast: boolean): ReactNode => (
133
+ <FormField
134
+ {...props}
135
+ autoFocus={isLast}
136
+ type={elementType}
137
+ // Suppress the per-item header for object items only — the recursive
138
+ // form already renders labels for each sub-field. Scalar items
139
+ // (refs, primitives) keep the parent name so inline-layout children
140
+ // (e.g. RefField) have a real label to use as a fallback placeholder.
141
+ {...(renderItemAsObject && { name: null })}
142
+ path={[...(path ?? []), index]}
143
+ readonly={readonly || layout === 'static'}
144
+ layout={renderItemAsObject ? (layout === 'static' ? 'static' : undefined) : 'inline'}
145
+ />
146
+ );
147
+
148
+ const header = (layout !== 'static' || (values && values.length > 0)) && (
149
+ <FieldHeader
150
+ label={label}
151
+ path={SchemaEx.createJsonPath(path ?? [])}
152
+ readonly={readonly}
153
+ add={layout !== 'static' ? { label: t('add-item.button'), onClick: handleAdd } : undefined}
154
+ />
155
+ );
156
+
157
+ //
158
+ // Ordered (drag-to-reorder) list.
159
+ //
160
+
161
+ if (ordered && !readonly && layout !== 'static') {
162
+ // Reconcile synthetic ids with the current values (initial mount / external change).
163
+ const ids = idsRef.current;
164
+ const count = values?.length ?? 0;
165
+ while (ids.length < count) {
166
+ ids.push(nextId());
167
+ }
168
+ if (ids.length > count) {
169
+ ids.length = count;
170
+ }
171
+
172
+ const items: OrderedItem[] = (values ?? []).map((value, index) => ({ value, index, [DND_ID]: ids[index] }));
173
+
174
+ return (
175
+ <>
176
+ {header}
177
+ <OrderedList.Root<OrderedItem> items={items} isItem={isOrderedItem} getId={getOrderedId} onMove={handleMove}>
178
+ {({ items }) => (
179
+ <OrderedList.Content>
180
+ {items.map((item) => (
181
+ <OrderedList.Item<OrderedItem>
182
+ key={getOrderedId(item)}
183
+ id={getOrderedId(item)}
184
+ item={item}
185
+ classNames='grid grid-cols-[min-content_1fr_min-content] items-start gap-1 p-0 pb-1'
186
+ >
187
+ <OrderedList.DragHandle />
188
+ {renderField(item.index, item.index === items.length - 1)}
189
+ <CompactIconButton
190
+ icon='ph--x--regular'
191
+ label={t('remove-item.button')}
192
+ onClick={() => handleDelete(item.index)}
193
+ />
194
+ </OrderedList.Item>
195
+ ))}
196
+ </OrderedList.Content>
197
+ )}
198
+ </OrderedList.Root>
199
+ </>
200
+ );
201
+ }
202
+
203
+ //
204
+ // Static list.
205
+ //
206
+
207
+ return (
208
+ <>
209
+ {header}
210
+ <div className='flex flex-col'>
211
+ {values?.map((_, index) => {
212
+ const isLast = index === values.length - 1;
213
+ return (
214
+ <div key={index} className='grid grid-cols-[1fr_min-content] items-center mb-1 last:mb-form-gap'>
215
+ {renderField(index, isLast)}
216
+ {!readonly && layout !== 'static' && (
217
+ <CompactIconButton
218
+ icon='ph--x--regular'
219
+ label={t('remove-item.button')}
220
+ onClick={() => handleDelete(index)}
221
+ />
222
+ )}
223
+ </div>
224
+ );
225
+ })}
226
+ </div>
227
+ </>
228
+ );
229
+ };
230
+
231
+ ArrayField.displayName = 'Form.ArrayField';
232
+
233
+ /**
234
+ * Returns the default empty value for a given AST.
235
+ * Used for initializing new array values etc.
236
+ */
237
+ // TODO(wittjosiah): Factor out?
238
+ export const getDefaultValue = (ast?: SchemaAST.AST): any => {
239
+ switch (ast?._tag) {
240
+ case 'StringKeyword': {
241
+ return '';
242
+ }
243
+ case 'NumberKeyword': {
244
+ return 0;
245
+ }
246
+ case 'BooleanKeyword': {
247
+ return false;
248
+ }
249
+ case 'Suspend': {
250
+ return getDefaultValue(ast.f());
251
+ }
252
+ case 'Refinement': {
253
+ // Use minimum from JSON schema annotation (e.g. Schema.between(1, 31)) as the default
254
+ // so new array items start within the valid range.
255
+ const jsonSchema = Option.getOrUndefined(SchemaAST.getJSONSchemaAnnotation(ast));
256
+ if (jsonSchema != null && 'minimum' in jsonSchema && typeof jsonSchema.minimum === 'number') {
257
+ return jsonSchema.minimum;
258
+ }
259
+ return getDefaultValue(ast.from);
260
+ }
261
+ default: {
262
+ if (ast && SchemaEx.isNestedType(ast)) {
263
+ return {};
264
+ } else {
265
+ throw new Error(`Unsupported type: ${ast?._tag}`);
266
+ }
267
+ }
268
+ }
269
+ };
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ export * from './ArrayField';
@@ -0,0 +1,52 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
6
+ import * as Schema from 'effect/Schema';
7
+ import React, { useState } from 'react';
8
+
9
+ import { withLayout, withTheme } from '@dxos/react-ui/testing';
10
+
11
+ import { translations } from '#translations';
12
+
13
+ import { TestLayout } from '../../../../../testing';
14
+ import { Form } from '../../../Form';
15
+
16
+ const schema = Schema.Struct({
17
+ active: Schema.Boolean.annotations({ title: 'Active' }),
18
+ }).pipe(Schema.mutable);
19
+
20
+ type Values = Schema.Schema.Type<typeof schema>;
21
+
22
+ const DefaultStory = () => {
23
+ const [values, setValues] = useState<Values>({ active: true });
24
+ return (
25
+ <TestLayout json={values}>
26
+ <Form.Root
27
+ schema={schema}
28
+ values={values}
29
+ onValuesChanged={(values) => setValues((prev) => ({ ...prev, ...values }))}
30
+ >
31
+ <Form.Viewport>
32
+ <Form.Content>
33
+ <Form.FieldSet />
34
+ </Form.Content>
35
+ </Form.Viewport>
36
+ </Form.Root>
37
+ </TestLayout>
38
+ );
39
+ };
40
+
41
+ const meta = {
42
+ title: 'ui/react-ui-form/FormField/BooleanField',
43
+ render: DefaultStory,
44
+ decorators: [withTheme(), withLayout({ layout: 'fullscreen' })],
45
+ parameters: { layout: 'fullscreen', translations },
46
+ } satisfies Meta<typeof DefaultStory>;
47
+
48
+ export default meta;
49
+
50
+ type Story = StoryObj<typeof meta>;
51
+
52
+ export const Default: Story = {};
@@ -6,9 +6,11 @@ import React, { useCallback } from 'react';
6
6
 
7
7
  import { Input, type SwitchProps } from '@dxos/react-ui';
8
8
 
9
- import { type FormFieldComponentProps, FormFieldWrapper } from '../FormFieldComponent';
9
+ import { type FormFieldRendererProps } from '#types';
10
10
 
11
- export const BooleanField = ({ type, readonly, onValueChange, ...props }: FormFieldComponentProps<boolean>) => {
11
+ import { FormFieldWrapper } from '../../FormFieldWrapper';
12
+
13
+ export const BooleanField = ({ type, readonly, onValueChange, ...props }: FormFieldRendererProps<boolean>) => {
12
14
  const handleChange = useCallback<NonNullable<SwitchProps['onCheckedChange']>>(
13
15
  (value) => onValueChange?.(type, value),
14
16
  [type, onValueChange],
@@ -16,7 +18,12 @@ export const BooleanField = ({ type, readonly, onValueChange, ...props }: FormFi
16
18
 
17
19
  return (
18
20
  <FormFieldWrapper<boolean> readonly={readonly} {...props}>
19
- {({ value }) => <Input.Switch disabled={!!readonly} checked={value} onCheckedChange={handleChange} />}
21
+ {({ value }) => (
22
+ // TODO(burdon) Push down to react-ui components (e.g., Input.Root).
23
+ <div className='flex items-center px-0.5 h-8'>
24
+ <Input.Switch disabled={!!readonly} checked={value} onCheckedChange={handleChange} />
25
+ </div>
26
+ )}
20
27
  </FormFieldWrapper>
21
28
  );
22
29
  };
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ export * from './BooleanField';