@dxos/react-ui-form 0.8.4-main.e8ec1fe → 0.8.4-main.effb148878

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 (268) hide show
  1. package/LICENSE +102 -5
  2. package/README.md +0 -1
  3. package/dist/lib/browser/index.mjs +3240 -2345
  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 +83 -0
  7. package/dist/lib/browser/translations.mjs.map +7 -0
  8. package/dist/lib/node-esm/index.mjs +3240 -2345
  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 +85 -0
  12. package/dist/lib/node-esm/translations.mjs.map +7 -0
  13. package/dist/types/src/components/FieldEditor/FieldEditor.d.ts +8 -7
  14. package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
  15. package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts +69 -59
  16. package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts.map +1 -1
  17. package/dist/types/src/components/Form/Form.d.ts +123 -27
  18. package/dist/types/src/components/Form/Form.d.ts.map +1 -1
  19. package/dist/types/src/components/Form/Form.stories.d.ts +175 -137
  20. package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
  21. package/dist/types/src/components/Form/FormField.d.ts +48 -0
  22. package/dist/types/src/components/Form/FormField.d.ts.map +1 -0
  23. package/dist/types/src/components/Form/FormFieldComponent.d.ts +95 -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 +21 -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 +25 -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 +116 -0
  34. package/dist/types/src/components/Form/Layout/FormLayout.stories.d.ts.map +1 -0
  35. package/dist/types/src/components/Form/Layout/annotation.d.ts +30 -0
  36. package/dist/types/src/components/Form/Layout/annotation.d.ts.map +1 -0
  37. package/dist/types/src/components/Form/Layout/index.d.ts +4 -0
  38. package/dist/types/src/components/Form/Layout/index.d.ts.map +1 -0
  39. package/dist/types/src/components/Form/Layout/parser.d.ts +31 -0
  40. package/dist/types/src/components/Form/Layout/parser.d.ts.map +1 -0
  41. package/dist/types/src/components/Form/Layout/parser.test.d.ts +2 -0
  42. package/dist/types/src/components/Form/Layout/parser.test.d.ts.map +1 -0
  43. package/dist/types/src/components/Form/fields/ArrayField.d.ts +18 -0
  44. package/dist/types/src/components/Form/fields/ArrayField.d.ts.map +1 -0
  45. package/dist/types/src/components/Form/fields/BooleanField.d.ts +4 -0
  46. package/dist/types/src/components/Form/fields/BooleanField.d.ts.map +1 -0
  47. package/dist/types/src/components/Form/fields/DateField.d.ts +4 -0
  48. package/dist/types/src/components/Form/fields/DateField.d.ts.map +1 -0
  49. package/dist/types/src/components/Form/fields/GeoPointField.d.ts +5 -0
  50. package/dist/types/src/components/Form/fields/GeoPointField.d.ts.map +1 -0
  51. package/dist/types/src/components/Form/fields/MarkdownField.d.ts +11 -0
  52. package/dist/types/src/components/Form/fields/MarkdownField.d.ts.map +1 -0
  53. package/dist/types/src/components/Form/fields/MarkdownField.stories.d.ts +85 -0
  54. package/dist/types/src/components/Form/fields/MarkdownField.stories.d.ts.map +1 -0
  55. package/dist/types/src/components/Form/fields/NumberField.d.ts +4 -0
  56. package/dist/types/src/components/Form/fields/NumberField.d.ts.map +1 -0
  57. package/dist/types/src/components/Form/fields/RefField.d.ts +22 -0
  58. package/dist/types/src/components/Form/fields/RefField.d.ts.map +1 -0
  59. package/dist/types/src/components/Form/fields/SelectField.d.ts +13 -0
  60. package/dist/types/src/components/Form/fields/SelectField.d.ts.map +1 -0
  61. package/dist/types/src/components/Form/fields/SelectOptionField.d.ts +5 -0
  62. package/dist/types/src/components/Form/fields/SelectOptionField.d.ts.map +1 -0
  63. package/dist/types/src/components/Form/fields/SelectOptionField.stories.d.ts +85 -0
  64. package/dist/types/src/components/Form/fields/SelectOptionField.stories.d.ts.map +1 -0
  65. package/dist/types/src/components/Form/fields/TextAreaField.d.ts +4 -0
  66. package/dist/types/src/components/Form/fields/TextAreaField.d.ts.map +1 -0
  67. package/dist/types/src/components/Form/fields/TextField.d.ts +4 -0
  68. package/dist/types/src/components/Form/fields/TextField.d.ts.map +1 -0
  69. package/dist/types/src/components/Form/fields/TupleField.d.ts +6 -0
  70. package/dist/types/src/components/Form/fields/TupleField.d.ts.map +1 -0
  71. package/dist/types/src/components/Form/fields/index.d.ts +13 -0
  72. package/dist/types/src/components/Form/fields/index.d.ts.map +1 -0
  73. package/dist/types/src/components/Form/index.d.ts +4 -4
  74. package/dist/types/src/components/Form/index.d.ts.map +1 -1
  75. package/dist/types/src/components/ObjectForm/ObjectForm.d.ts +8 -0
  76. package/dist/types/src/components/ObjectForm/ObjectForm.d.ts.map +1 -0
  77. package/dist/types/src/components/ObjectForm/index.d.ts +2 -0
  78. package/dist/types/src/components/ObjectForm/index.d.ts.map +1 -0
  79. package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts +37 -10
  80. package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts.map +1 -1
  81. package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts +65 -58
  82. package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts.map +1 -1
  83. package/dist/types/src/components/ObjectProperties/ObjectProperties.d.ts +9 -0
  84. package/dist/types/src/components/ObjectProperties/ObjectProperties.d.ts.map +1 -0
  85. package/dist/types/src/components/ObjectProperties/ObjectProperties.stories.d.ts +128 -0
  86. package/dist/types/src/components/ObjectProperties/ObjectProperties.stories.d.ts.map +1 -0
  87. package/dist/types/src/components/ObjectProperties/ObjectProperties.test.d.ts +2 -0
  88. package/dist/types/src/components/ObjectProperties/ObjectProperties.test.d.ts.map +1 -0
  89. package/dist/types/src/components/ObjectProperties/index.d.ts +2 -0
  90. package/dist/types/src/components/ObjectProperties/index.d.ts.map +1 -0
  91. package/dist/types/src/components/ObjectTree/ObjectTree.d.ts +9 -0
  92. package/dist/types/src/components/ObjectTree/ObjectTree.d.ts.map +1 -0
  93. package/dist/types/src/components/ObjectTree/ObjectTree.stories.d.ts +87 -0
  94. package/dist/types/src/components/ObjectTree/ObjectTree.stories.d.ts.map +1 -0
  95. package/dist/types/src/components/ObjectTree/index.d.ts +2 -0
  96. package/dist/types/src/components/ObjectTree/index.d.ts.map +1 -0
  97. package/dist/types/src/components/Settings/Settings.d.ts +51 -0
  98. package/dist/types/src/components/Settings/Settings.d.ts.map +1 -0
  99. package/dist/types/src/components/Settings/Settings.stories.d.ts +85 -0
  100. package/dist/types/src/components/Settings/Settings.stories.d.ts.map +1 -0
  101. package/dist/types/src/components/Settings/SettingsFieldSet.d.ts +43 -0
  102. package/dist/types/src/components/Settings/SettingsFieldSet.d.ts.map +1 -0
  103. package/dist/types/src/components/Settings/SettingsItem.d.ts +16 -0
  104. package/dist/types/src/components/Settings/SettingsItem.d.ts.map +1 -0
  105. package/dist/types/src/components/Settings/SettingsSelectField.d.ts +18 -0
  106. package/dist/types/src/components/Settings/SettingsSelectField.d.ts.map +1 -0
  107. package/dist/types/src/components/Settings/index.d.ts +4 -0
  108. package/dist/types/src/components/Settings/index.d.ts.map +1 -0
  109. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts +14 -18
  110. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
  111. package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts +71 -64
  112. package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
  113. package/dist/types/src/components/index.d.ts +4 -1
  114. package/dist/types/src/components/index.d.ts.map +1 -1
  115. package/dist/types/src/components/testing.d.ts +13 -6
  116. package/dist/types/src/components/testing.d.ts.map +1 -1
  117. package/dist/types/src/hooks/index.d.ts +2 -3
  118. package/dist/types/src/hooks/index.d.ts.map +1 -1
  119. package/dist/types/src/hooks/useFormHandler.d.ts +82 -0
  120. package/dist/types/src/hooks/useFormHandler.d.ts.map +1 -0
  121. package/dist/types/src/hooks/useKeyHandler.d.ts +7 -0
  122. package/dist/types/src/hooks/useKeyHandler.d.ts.map +1 -0
  123. package/dist/types/src/index.d.ts +0 -2
  124. package/dist/types/src/index.d.ts.map +1 -1
  125. package/dist/types/src/translations.d.ts +66 -59
  126. package/dist/types/src/translations.d.ts.map +1 -1
  127. package/dist/types/src/util/field-type.d.ts +19 -0
  128. package/dist/types/src/util/field-type.d.ts.map +1 -0
  129. package/dist/types/src/util/field.d.ts +3 -3
  130. package/dist/types/src/util/field.d.ts.map +1 -1
  131. package/dist/types/src/util/formatting.d.ts +2 -2
  132. package/dist/types/src/util/formatting.d.ts.map +1 -1
  133. package/dist/types/src/util/index.d.ts +2 -1
  134. package/dist/types/src/util/index.d.ts.map +1 -1
  135. package/dist/types/src/util/properties.d.ts +17 -0
  136. package/dist/types/src/util/properties.d.ts.map +1 -0
  137. package/dist/types/src/util/properties.test.d.ts +2 -0
  138. package/dist/types/src/util/properties.test.d.ts.map +1 -0
  139. package/dist/types/src/util/refs.d.ts +2 -2
  140. package/dist/types/src/util/refs.d.ts.map +1 -1
  141. package/dist/types/tsconfig.tsbuildinfo +1 -1
  142. package/package.json +61 -52
  143. package/src/components/FieldEditor/FieldEditor.stories.tsx +44 -25
  144. package/src/components/FieldEditor/FieldEditor.test.tsx +0 -1
  145. package/src/components/FieldEditor/FieldEditor.tsx +84 -84
  146. package/src/components/Form/AUDIT.md +17 -0
  147. package/src/components/Form/Form.stories.tsx +134 -252
  148. package/src/components/Form/Form.tsx +417 -109
  149. package/src/components/Form/FormField.tsx +332 -0
  150. package/src/components/Form/FormFieldComponent.stories.tsx +65 -0
  151. package/src/components/Form/FormFieldComponent.tsx +206 -0
  152. package/src/components/Form/FormFieldSet.tsx +173 -0
  153. package/src/components/Form/FormTooltipsContext.ts +25 -0
  154. package/src/components/Form/Layout/FormLayout.stories.tsx +339 -0
  155. package/src/components/Form/Layout/FormLayout.tsx +123 -0
  156. package/src/components/Form/Layout/annotation.ts +38 -0
  157. package/src/components/Form/Layout/index.ts +7 -0
  158. package/src/components/Form/Layout/parser.test.ts +120 -0
  159. package/src/components/Form/Layout/parser.ts +167 -0
  160. package/src/components/Form/README.md +3 -0
  161. package/src/components/Form/fields/ArrayField.tsx +185 -0
  162. package/src/components/Form/fields/BooleanField.tsx +22 -0
  163. package/src/components/Form/fields/DateField.tsx +95 -0
  164. package/src/components/Form/fields/GeoPointField.tsx +124 -0
  165. package/src/components/Form/fields/MarkdownField.stories.tsx +206 -0
  166. package/src/components/Form/fields/MarkdownField.tsx +168 -0
  167. package/src/components/Form/fields/NumberField.tsx +39 -0
  168. package/src/components/Form/fields/RefField.tsx +232 -0
  169. package/src/components/Form/fields/SelectField.tsx +77 -0
  170. package/src/components/Form/{custom/SelectOptionsInput.stories.tsx → fields/SelectOptionField.stories.tsx} +23 -18
  171. package/src/components/Form/{custom/SelectOptionsInput.tsx → fields/SelectOptionField.tsx} +32 -25
  172. package/src/components/Form/fields/TextAreaField.tsx +38 -0
  173. package/src/components/Form/fields/TextField.tsx +38 -0
  174. package/src/components/Form/{custom/TupleInput.tsx → fields/TupleField.tsx} +17 -9
  175. package/src/components/Form/fields/index.ts +16 -0
  176. package/src/components/Form/index.ts +5 -4
  177. package/src/components/ObjectForm/ObjectForm.tsx +115 -0
  178. package/src/components/{ControlSection → ObjectForm}/index.ts +1 -1
  179. package/src/components/ObjectPicker/ObjectPicker.stories.tsx +26 -21
  180. package/src/components/ObjectPicker/ObjectPicker.tsx +122 -81
  181. package/src/components/ObjectProperties/ObjectProperties.stories.tsx +350 -0
  182. package/src/components/ObjectProperties/ObjectProperties.test.tsx +108 -0
  183. package/src/components/ObjectProperties/ObjectProperties.tsx +147 -0
  184. package/src/components/ObjectProperties/index.ts +5 -0
  185. package/src/components/ObjectTree/ObjectTree.stories.tsx +134 -0
  186. package/src/components/ObjectTree/ObjectTree.tsx +190 -0
  187. package/src/components/ObjectTree/index.ts +5 -0
  188. package/src/components/Settings/AUDIT.md +51 -0
  189. package/src/components/Settings/Settings.stories.tsx +104 -0
  190. package/src/components/Settings/Settings.tsx +81 -0
  191. package/src/components/Settings/SettingsFieldSet.tsx +257 -0
  192. package/src/components/Settings/SettingsItem.tsx +58 -0
  193. package/src/components/Settings/SettingsSelectField.tsx +59 -0
  194. package/src/components/Settings/index.ts +7 -0
  195. package/src/components/ViewEditor/ViewEditor.stories.tsx +62 -71
  196. package/src/components/ViewEditor/ViewEditor.test.tsx +10 -10
  197. package/src/components/ViewEditor/ViewEditor.tsx +308 -217
  198. package/src/components/index.ts +4 -1
  199. package/src/components/testing.tsx +24 -11
  200. package/src/hooks/index.ts +2 -3
  201. package/src/hooks/useFormHandler.ts +380 -0
  202. package/src/hooks/useKeyHandler.tsx +37 -0
  203. package/src/index.ts +0 -4
  204. package/src/translations.ts +71 -64
  205. package/src/util/field-type.ts +60 -0
  206. package/src/util/field.ts +25 -25
  207. package/src/util/formatting.ts +22 -22
  208. package/src/util/index.ts +2 -1
  209. package/src/util/properties.test.ts +78 -0
  210. package/src/util/properties.ts +38 -0
  211. package/src/util/refs.ts +13 -15
  212. package/src/vite-env.d.ts +10 -0
  213. package/dist/types/src/components/ControlSection/ControlSection.d.ts +0 -23
  214. package/dist/types/src/components/ControlSection/ControlSection.d.ts.map +0 -1
  215. package/dist/types/src/components/ControlSection/ControlSection.stories.d.ts +0 -83
  216. package/dist/types/src/components/ControlSection/ControlSection.stories.d.ts.map +0 -1
  217. package/dist/types/src/components/ControlSection/index.d.ts +0 -2
  218. package/dist/types/src/components/ControlSection/index.d.ts.map +0 -1
  219. package/dist/types/src/components/Form/ArrayField.d.ts +0 -16
  220. package/dist/types/src/components/Form/ArrayField.d.ts.map +0 -1
  221. package/dist/types/src/components/Form/Defaults.d.ts +0 -14
  222. package/dist/types/src/components/Form/Defaults.d.ts.map +0 -1
  223. package/dist/types/src/components/Form/FormActions.d.ts +0 -9
  224. package/dist/types/src/components/Form/FormActions.d.ts.map +0 -1
  225. package/dist/types/src/components/Form/FormContent.d.ts +0 -63
  226. package/dist/types/src/components/Form/FormContent.d.ts.map +0 -1
  227. package/dist/types/src/components/Form/FormContext.d.ts +0 -23
  228. package/dist/types/src/components/Form/FormContext.d.ts.map +0 -1
  229. package/dist/types/src/components/Form/Input.d.ts +0 -29
  230. package/dist/types/src/components/Form/Input.d.ts.map +0 -1
  231. package/dist/types/src/components/Form/RefField.d.ts +0 -22
  232. package/dist/types/src/components/Form/RefField.d.ts.map +0 -1
  233. package/dist/types/src/components/Form/custom/GeoPointInput.d.ts +0 -4
  234. package/dist/types/src/components/Form/custom/GeoPointInput.d.ts.map +0 -1
  235. package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts +0 -4
  236. package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts.map +0 -1
  237. package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts +0 -78
  238. package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts.map +0 -1
  239. package/dist/types/src/components/Form/custom/TupleInput.d.ts +0 -6
  240. package/dist/types/src/components/Form/custom/TupleInput.d.ts.map +0 -1
  241. package/dist/types/src/components/Form/custom/index.d.ts +0 -4
  242. package/dist/types/src/components/Form/custom/index.d.ts.map +0 -1
  243. package/dist/types/src/components/Form/factory.d.ts +0 -8
  244. package/dist/types/src/components/Form/factory.d.ts.map +0 -1
  245. package/dist/types/src/hooks/useForm.d.ts +0 -67
  246. package/dist/types/src/hooks/useForm.d.ts.map +0 -1
  247. package/dist/types/src/hooks/useQueryRefOptions.d.ts +0 -29
  248. package/dist/types/src/hooks/useQueryRefOptions.d.ts.map +0 -1
  249. package/dist/types/src/hooks/useRefQueryLookupHandler.d.ts +0 -8
  250. package/dist/types/src/hooks/useRefQueryLookupHandler.d.ts.map +0 -1
  251. package/dist/types/src/util/schema.d.ts +0 -3
  252. package/dist/types/src/util/schema.d.ts.map +0 -1
  253. package/src/components/ControlSection/ControlSection.stories.tsx +0 -38
  254. package/src/components/ControlSection/ControlSection.tsx +0 -153
  255. package/src/components/Form/ArrayField.tsx +0 -125
  256. package/src/components/Form/Defaults.tsx +0 -205
  257. package/src/components/Form/FormActions.tsx +0 -54
  258. package/src/components/Form/FormContent.tsx +0 -362
  259. package/src/components/Form/FormContext.tsx +0 -110
  260. package/src/components/Form/Input.tsx +0 -54
  261. package/src/components/Form/RefField.tsx +0 -283
  262. package/src/components/Form/custom/GeoPointInput.tsx +0 -80
  263. package/src/components/Form/custom/index.ts +0 -7
  264. package/src/components/Form/factory.tsx +0 -31
  265. package/src/hooks/useForm.ts +0 -296
  266. package/src/hooks/useQueryRefOptions.ts +0 -62
  267. package/src/hooks/useRefQueryLookupHandler.ts +0 -39
  268. package/src/util/schema.ts +0 -12
@@ -6,297 +6,179 @@ import { type Meta, type StoryObj } from '@storybook/react-vite';
6
6
  import * as Schema from 'effect/Schema';
7
7
  import React, { useCallback, useState } from 'react';
8
8
 
9
- import { ContactType } from '@dxos/client/testing';
10
- import { type Type } from '@dxos/echo';
11
- import { type BaseObject, Expando, Format, Ref, type TypeAnnotation, getObjectDXN } from '@dxos/echo/internal';
12
- import { live } from '@dxos/echo/internal';
9
+ import { DXN, Annotation, Format, Obj, Ref, Tag, Type } from '@dxos/echo';
10
+ import { type AnyProperties } from '@dxos/echo/internal';
11
+ import { log } from '@dxos/log';
12
+ import { useSpaces } from '@dxos/react-client/echo';
13
+ import { withClientProvider } from '@dxos/react-client/testing';
13
14
  import { Tooltip } from '@dxos/react-ui';
14
- import { withLayoutVariants, withTheme } from '@dxos/react-ui/testing';
15
- import { Testing } from '@dxos/schema/testing';
15
+ import { Loading, withLayout, withTheme } from '@dxos/react-ui/testing';
16
16
 
17
- import { translations } from '../../translations';
18
- import { TestLayout, TestPanel } from '../testing';
17
+ import { translations } from '#translations';
19
18
 
20
- import { SelectInput } from './Defaults';
21
- import { Form, type FormProps } from './Form';
19
+ import { TestLayout } from '../testing';
20
+ import { type ExcludeId, Form, type FormRootProps, omitId } from './Form';
22
21
 
23
- type StoryProps<T extends BaseObject> = {
24
- debug?: boolean;
25
- schema: Type.Obj.Any;
26
- } & FormProps<T>;
22
+ const Organization = Schema.Struct({
23
+ name: Schema.String.pipe(Schema.minLength(1)).annotations({ title: 'Full name' }),
24
+ }).pipe(Type.makeObject(DXN.make('com.example.type.organization', '0.1.0')));
27
25
 
28
- const DefaultStory = <T extends BaseObject = any>({
29
- debug,
26
+ export type Organization = Type.InstanceType<typeof Organization>;
27
+
28
+ const Person = Schema.Struct({
29
+ name: Schema.String.pipe(Schema.minLength(1)).annotations({ title: 'Full name' }),
30
+ ignore: Schema.String.pipe(Annotation.FormInputAnnotation.set(false), Schema.optional),
31
+ active: Schema.optional(Schema.Boolean.annotations({ title: 'Active' })),
32
+ address: Schema.optional(
33
+ Schema.Struct({
34
+ street: Schema.String,
35
+ city: Schema.String,
36
+ // TODO(burdon): Constrain input control.
37
+ state: Schema.String.pipe(Schema.minLength(2), Schema.maxLength(2)).annotations({
38
+ title: 'State',
39
+ description: 'State code',
40
+ }),
41
+ zip: Schema.Number.annotations({ title: 'ZIP Code' }),
42
+ }).annotations({ title: 'Address' }),
43
+ ),
44
+ employer: Schema.optional(Ref.Ref(Organization).annotations({ title: 'Employer' })),
45
+ tags: Schema.optional(Schema.Array(Ref.Ref(Tag.Tag)).annotations({ title: 'Tags' })),
46
+ status: Schema.optional(Schema.Literal('active', 'inactive').annotations({ title: 'Status' })),
47
+ notes: Schema.optional(Format.Text.annotations({ title: 'Notes' })),
48
+ location: Schema.optional(Format.GeoPoint.annotations({ title: 'Location' })),
49
+ birthday: Schema.optional(Format.DateOnly.annotations({ title: 'Birthday' })),
50
+ meetingAt: Schema.optional(Format.DateTime.annotations({ title: 'Next meeting' })),
51
+ reminderAt: Schema.optional(Format.TimeOnly.annotations({ title: 'Reminder time' })),
52
+ tasks: Schema.optional(Schema.Array(Schema.String).annotations({ title: 'Tasks' })),
53
+ locations: Schema.optional(Schema.Array(Format.GeoPoint).annotations({ title: 'Locations' })),
54
+ identities: Schema.optional(
55
+ Schema.Array(
56
+ Schema.Struct({
57
+ type: Schema.String.annotations({ title: 'Type' }),
58
+ value: Schema.String.annotations({ title: 'Value' }),
59
+ }).annotations({ title: 'Identities' }),
60
+ ).annotations({
61
+ title: 'Identities',
62
+ }),
63
+ ),
64
+ }).pipe(Type.makeObject(DXN.make('org.dxos.type.person', '0.1.0')));
65
+
66
+ export type Person = Type.InstanceType<typeof Person>;
67
+
68
+ type DefaultStoryProps<T extends AnyProperties> = {
69
+ schema?: Schema.Schema<T>;
70
+ } & FormRootProps<T>;
71
+
72
+ const DefaultStory = <T extends AnyProperties = AnyProperties>({
30
73
  schema,
31
- values: initialValues,
74
+ values: valuesProp,
32
75
  ...props
33
- }: StoryProps<T>) => {
34
- const [values, setValues] = useState(initialValues);
35
- const handleSave = useCallback<NonNullable<FormProps<T>['onSave']>>((values) => {
76
+ }: DefaultStoryProps<T>) => {
77
+ const [values, setValues] = useState<Partial<T>>(valuesProp ?? {});
78
+ const spaces = useSpaces();
79
+ const space = spaces[0];
80
+ const handleSave = useCallback<NonNullable<FormRootProps<T>['onSave']>>((values) => {
81
+ log.info('save', { values, meta });
36
82
  setValues(values);
37
83
  }, []);
38
84
 
39
- if (debug) {
40
- return (
41
- <Tooltip.Provider>
42
- <TestLayout json={{ values, schema: schema.ast }}>
43
- <TestPanel>
44
- <Form<T> schema={schema} values={values} onSave={handleSave} {...props} />
45
- </TestPanel>
46
- </TestLayout>
47
- </Tooltip.Provider>
48
- );
49
- }
50
-
51
- return <Form<T> schema={schema} values={values} onSave={handleSave} {...props} />;
52
- };
53
-
54
- const RefStory = <T extends BaseObject = any>(props: StoryProps<T>) => {
55
- const onQueryRefOptions = useCallback((typeInfo: TypeAnnotation) => {
56
- switch (typeInfo.typename) {
57
- case Testing.Person.typename:
58
- return [
59
- { dxn: getObjectDXN(contact1)!, label: 'John Coltraine' },
60
- { dxn: getObjectDXN(contact2)!, label: 'Erykah Badu' },
61
- ];
62
- default:
63
- return [];
64
- }
85
+ const handleCancel = useCallback<NonNullable<FormRootProps<T>['onCancel']>>(() => {
86
+ log.info('cancel');
87
+ setValues(valuesProp ?? {});
65
88
  }, []);
66
89
 
67
- return <DefaultStory<T> onQueryRefOptions={onQueryRefOptions} {...props} />;
68
- };
69
-
70
- const AddressSchema = Schema.Struct({
71
- street: Schema.optional(Schema.String.annotations({ title: 'Street' })),
72
- city: Schema.optional(Schema.String.annotations({ title: 'City' })),
73
- zip: Schema.optional(Schema.String.pipe(Schema.pattern(/^\d{5}(-\d{4})?$/)).annotations({ title: 'ZIP' })),
74
- location: Schema.optional(Format.GeoPoint.annotations({ title: 'Location' })),
75
- }).annotations({ title: 'Address' });
76
-
77
- const ContactSchema = Schema.Struct({
78
- name: Schema.optional(Schema.String.annotations({ title: 'Name' })),
79
- active: Schema.optional(Schema.Boolean.annotations({ title: 'Active' })),
80
- rank: Schema.optional(Schema.Number.annotations({ title: 'Rank' })),
81
- website: Schema.optional(Format.URL.annotations({ title: 'Website' })),
82
- address: Schema.optional(AddressSchema),
83
- }).pipe(Schema.mutable);
90
+ if (!space) {
91
+ return <Loading />;
92
+ }
84
93
 
85
- type ContactSchema = Schema.Schema.Type<typeof ContactSchema>;
94
+ return (
95
+ <Tooltip.Provider>
96
+ <TestLayout json={{ values, schema: schema?.ast }}>
97
+ <Form.Root
98
+ schema={schema}
99
+ defaultValues={values}
100
+ db={space.db}
101
+ onSave={handleSave}
102
+ onCancel={handleCancel}
103
+ {...props}
104
+ >
105
+ <Form.Viewport>
106
+ <Form.Content>
107
+ <Form.Section label='Section' description='This is a section' />
108
+ <Form.FieldSet />
109
+ <Form.Actions />
110
+ </Form.Content>
111
+ </Form.Viewport>
112
+ </Form.Root>
113
+ </TestLayout>
114
+ </Tooltip.Provider>
115
+ );
116
+ };
86
117
 
87
118
  const meta = {
88
119
  title: 'ui/react-ui-form/Form',
89
- component: Form as any,
120
+ component: Form.Root,
90
121
  render: DefaultStory,
91
- decorators: [withTheme, withLayoutVariants()],
122
+ decorators: [
123
+ withTheme(),
124
+ withLayout({ layout: 'fullscreen' }),
125
+ withClientProvider({
126
+ createIdentity: true,
127
+ createSpace: true,
128
+ types: [Tag.Tag, Organization, Person],
129
+ onCreateSpace: ({ space }) => {
130
+ [
131
+ ...Array.from({ length: 3 }).map((_, i) => Obj.make(Tag.Tag, { label: `Tag ${i}` })),
132
+ ...Array.from({ length: 50 }).map((_, i) => Obj.make(Organization, { name: `Organization ${i}` })),
133
+ ].map((obj) => space.db.add(obj));
134
+ },
135
+ }),
136
+ ],
92
137
  parameters: {
93
138
  layout: 'fullscreen',
94
139
  translations,
95
140
  },
96
- argTypes: {
97
- readonly: {
98
- control: 'boolean',
99
- description: 'Readonly',
100
- },
101
- },
102
- } satisfies Meta<StoryProps<any>>;
141
+ } satisfies Meta<DefaultStoryProps<any>>;
103
142
 
104
143
  export default meta;
105
144
 
106
- type Story = StoryObj<typeof meta>;
145
+ type Story<T extends AnyProperties> = StoryObj<DefaultStoryProps<T>>;
107
146
 
108
- export const Default: Story = {
109
- args: {
110
- schema: ContactSchema,
111
- values: {
112
- name: 'DXOS',
113
- active: true,
114
- address: {
115
- zip: '11205',
116
- },
117
- },
118
- readonly: false,
119
- },
120
- };
147
+ const PersonSchema = Type.getSchema(Person);
121
148
 
122
- export const Organization: Story = {
123
- args: {
124
- debug: true,
125
- schema: Testing.OrganizationSchema,
126
- values: {
127
- name: 'DXOS',
128
- website: 'https://dxos.org',
129
- },
130
- readonly: false,
131
- },
149
+ const values: Partial<Person> = {
150
+ name: 'Alice',
151
+ location: [40.7128, -74.006],
152
+ tasks: ['task 1', 'task 2'],
153
+ birthday: '1990-05-12',
154
+ meetingAt: '2026-06-01T15:30:00.000Z',
155
+ reminderAt: '09:00:00',
132
156
  };
133
157
 
134
- export const OrganizationAutoSave: Story = {
158
+ export const Default: Story<ExcludeId<typeof PersonSchema>> = {
135
159
  args: {
136
- debug: true,
137
- schema: Testing.OrganizationSchema,
138
- values: {
139
- name: 'DXOS',
140
- website: 'https://dxos.org',
141
- },
160
+ schema: omitId(PersonSchema),
161
+ values,
142
162
  autoSave: true,
143
- readonly: false,
144
163
  },
145
164
  };
146
165
 
147
- // TODO(burdon): Type issue with employer reference.
148
- // TODO(burdon): Test table/form with compound values (e.g., address).
149
- // Property name is missing in type EncodedReference but required in type
150
- export const Person: Story = {
166
+ export const Readonly: Story<ExcludeId<typeof PersonSchema>> = {
151
167
  args: {
152
- debug: true,
153
- schema: Testing.Person,
154
- values: {
155
- name: 'Bot',
156
- },
168
+ schema: omitId(PersonSchema),
169
+ values,
170
+ readonly: true,
157
171
  },
158
172
  };
159
173
 
160
- //
161
- // Union
162
- //
163
-
164
- const ShapeSchema = Schema.Struct({
165
- shape: Schema.optional(
166
- Schema.Union(
167
- Schema.Struct({
168
- type: Schema.Literal('circle').annotations({ title: 'Type' }),
169
- radius: Schema.optional(Schema.Number.annotations({ title: 'Radius' })),
170
- }),
171
- Schema.Struct({
172
- type: Schema.Literal('square').annotations({ title: 'Type' }),
173
- size: Schema.optional(Schema.Number.pipe(Schema.nonNegative()).annotations({ title: 'Size' })),
174
- }),
175
- ).annotations({ title: 'Shape' }),
176
- ),
177
- }).pipe(Schema.mutable);
178
-
179
- type ShapeSchema = Schema.Schema.Type<typeof ShapeSchema>;
180
-
181
- export const DiscriminatedShape: StoryObj<StoryProps<ShapeSchema>> = {
182
- args: {
183
- debug: true,
184
- schema: ShapeSchema,
185
- readonly: false,
186
- values: {
187
- shape: {
188
- type: 'circle',
189
- radius: 5,
190
- },
191
- },
192
- Custom: {
193
- ['shape.type' as const]: (props) => (
194
- <SelectInput
195
- {...props}
196
- options={['circle', 'square'].map((value) => ({
197
- value,
198
- label: value,
199
- }))}
200
- />
201
- ),
202
- },
203
- },
204
- };
205
-
206
- //
207
- // Arrays
208
- //
209
-
210
- const ArraysSchema = Schema.Struct({
211
- names: Schema.Array(Schema.String.pipe(Schema.nonEmptyString())),
212
- addresses: Schema.Array(AddressSchema),
213
- }).pipe(Schema.mutable);
214
-
215
- type ArraysSchema = Schema.Schema.Type<typeof ArraysSchema>;
216
-
217
- export const Arrays: StoryObj<StoryProps<ArraysSchema>> = {
218
- args: {
219
- debug: true,
220
- schema: ArraysSchema,
221
- readonly: false,
222
- values: {
223
- names: ['Alice', 'Bob'],
224
- addresses: [],
225
- },
226
- },
227
- };
228
-
229
- //
230
- // Tuple
231
- //
232
-
233
- // TODO(wittjosiah): Only GeoPoint is works currently.
234
- const TupleSchema = Schema.Struct({
235
- tuple: Schema.Tuple(Schema.Number, Schema.String, Schema.Boolean),
236
- geopoint: Format.GeoPoint,
237
- }).pipe(Schema.mutable);
238
-
239
- type TupleSchema = Schema.Schema.Type<typeof TupleSchema>;
240
-
241
- export const Tuple: StoryObj<StoryProps<TupleSchema>> = {
174
+ export const Static: Story<ExcludeId<typeof PersonSchema>> = {
242
175
  args: {
243
- debug: true,
244
- schema: TupleSchema,
245
- readonly: false,
246
- values: {
247
- tuple: [1, 'a', true],
248
- geopoint: [-122.41941, 37.77492],
249
- },
176
+ schema: omitId(PersonSchema),
177
+ values,
178
+ layout: 'static',
250
179
  },
251
180
  };
252
181
 
253
- //
254
- // Enum
255
- //
256
-
257
- const ColorSchema = Schema.Struct({
258
- color: Schema.Union(Schema.Literal('red'), Schema.Literal('green'), Schema.Literal('blue')).annotations({
259
- title: 'Color',
260
- }),
261
- }).pipe(Schema.mutable);
262
-
263
- type ColorType = Schema.Schema.Type<typeof ColorSchema>;
264
-
265
- export const Enum: StoryObj<StoryProps<ColorType>> = {
266
- args: {
267
- debug: true,
268
- schema: ColorSchema,
269
- readonly: false,
270
- values: {
271
- color: 'red',
272
- },
273
- },
274
- };
275
-
276
- //
277
- // Refs
278
- //
279
-
280
- const RefSchema = Schema.Struct({
281
- contact: Ref(ContactType).annotations({ title: 'Contact Reference' }),
282
- optionalContact: Schema.optional(Ref(ContactType).annotations({ title: 'Optional Contact Reference' })),
283
- refArray: Schema.optional(Schema.Array(Ref(ContactType))),
284
- unknownExpando: Schema.optional(Ref(Expando).annotations({ title: 'Optional Ref to an Expando (DXN Input)' })),
285
- });
286
-
287
- type RefSchema = Schema.Schema.Type<typeof RefSchema>;
288
-
289
- const contact1 = live(ContactType, { identifiers: [] });
290
- const contact2 = live(ContactType, { identifiers: [] });
291
-
292
- export const Refs: StoryObj<StoryProps<RefSchema>> = {
293
- render: RefStory,
294
- args: {
295
- debug: true,
296
- schema: RefSchema,
297
- readonly: false,
298
- values: {
299
- refArray: [Ref.make(contact1), Ref.make(contact2)],
300
- },
301
- },
182
+ export const Empty: Story<ExcludeId<typeof PersonSchema>> = {
183
+ args: {},
302
184
  };