@dxos/react-ui-form 0.7.1-staging.8709ba7 → 0.7.2-staging.6d26b2a

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 (33) hide show
  1. package/dist/lib/browser/index.mjs +107 -81
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node/index.cjs +100 -74
  5. package/dist/lib/node/index.cjs.map +4 -4
  6. package/dist/lib/node/meta.json +1 -1
  7. package/dist/lib/node-esm/index.mjs +107 -81
  8. package/dist/lib/node-esm/index.mjs.map +4 -4
  9. package/dist/lib/node-esm/meta.json +1 -1
  10. package/dist/types/src/components/Form/Custom.d.ts +2 -1
  11. package/dist/types/src/components/Form/Custom.d.ts.map +1 -1
  12. package/dist/types/src/components/Form/Defaults.d.ts +11 -4
  13. package/dist/types/src/components/Form/Defaults.d.ts.map +1 -1
  14. package/dist/types/src/components/Form/Form.d.ts +5 -4
  15. package/dist/types/src/components/Form/Form.d.ts.map +1 -1
  16. package/dist/types/src/components/Form/Form.stories.d.ts +1 -4
  17. package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
  18. package/dist/types/src/components/Form/Input.d.ts +3 -8
  19. package/dist/types/src/components/Form/Input.d.ts.map +1 -1
  20. package/dist/types/src/components/Form/factory.d.ts +2 -2
  21. package/dist/types/src/components/Form/factory.d.ts.map +1 -1
  22. package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
  23. package/dist/types/src/hooks/useForm.d.ts +5 -4
  24. package/dist/types/src/hooks/useForm.d.ts.map +1 -1
  25. package/package.json +22 -24
  26. package/src/components/Form/Custom.tsx +9 -9
  27. package/src/components/Form/Defaults.tsx +10 -5
  28. package/src/components/Form/Form.stories.tsx +2 -2
  29. package/src/components/Form/Form.tsx +43 -19
  30. package/src/components/Form/Input.tsx +3 -7
  31. package/src/components/Form/factory.tsx +4 -4
  32. package/src/components/ViewEditor/ViewEditor.stories.tsx +1 -2
  33. package/src/hooks/useForm.ts +7 -6
@@ -1,27 +1,22 @@
1
1
  import React, { type FC, type PropsWithChildren } from 'react';
2
- import { type FormatEnum } from '@dxos/echo-schema';
2
+ import { type BaseObject, type FormatEnum, type PropertyKey } from '@dxos/echo-schema';
3
3
  import { type SimpleType } from '@dxos/effect';
4
- import { type PropertyKey } from '@dxos/schema';
5
4
  import { type FormHandler } from '../../hooks';
6
5
  /**
7
6
  * Props passed to input components.
8
7
  */
9
- export type InputProps<T extends object = {}> = {
8
+ export type InputProps<T extends BaseObject> = {
10
9
  property: PropertyKey<T>;
11
10
  type: SimpleType;
12
11
  format?: FormatEnum;
13
12
  label: string;
14
13
  disabled?: boolean;
15
14
  placeholder?: string;
16
- options?: Array<{
17
- value: string | number;
18
- label?: string;
19
- }>;
20
15
  } & Pick<FormHandler<T>, 'getStatus' | 'getValue' | 'onValueChange' | 'onBlur'>;
21
16
  /**
22
17
  * Form input component.
23
18
  */
24
- export type InputComponent<T extends object = {}> = FC<InputProps<T>>;
19
+ export type InputComponent<T extends BaseObject> = FC<InputProps<T>>;
25
20
  export type InputHeaderProps = PropsWithChildren<{
26
21
  error?: string;
27
22
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"Input.d.ts","sourceRoot":"","sources":["../../../../../src/components/Form/Input.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,KAAK,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAE/D,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAG/C,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;;GAEG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,MAAM,GAAG,EAAE,IAAI;IAC9C,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;IACzB,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC7D,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,GAAG,UAAU,GAAG,eAAe,GAAG,QAAQ,CAAC,CAAC;AAEhF;;GAEG;AAEH,MAAM,MAAM,cAAc,CAAC,CAAC,SAAS,MAAM,GAAG,EAAE,IAAI,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AAEtE,MAAM,MAAM,gBAAgB,GAAG,iBAAiB,CAAC;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC,CAAC;AAEH,eAAO,MAAM,WAAW,wBAAyB,gBAAgB,sBAiBhE,CAAC"}
1
+ {"version":3,"file":"Input.d.ts","sourceRoot":"","sources":["../../../../../src/components/Form/Input.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,KAAK,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAE/D,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,UAAU,EAAE,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACvF,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAI/C,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;;GAEG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,UAAU,IAAI;IAC7C,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;IACzB,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,GAAG,UAAU,GAAG,eAAe,GAAG,QAAQ,CAAC,CAAC;AAEhF;;GAEG;AACH,MAAM,MAAM,cAAc,CAAC,CAAC,SAAS,UAAU,IAAI,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AAErE,MAAM,MAAM,gBAAgB,GAAG,iBAAiB,CAAC;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC,CAAC;AAEH,eAAO,MAAM,WAAW,wBAAyB,gBAAgB,sBAiBhE,CAAC"}
@@ -1,8 +1,8 @@
1
- import { FormatEnum } from '@dxos/echo-schema';
1
+ import { type BaseObject, FormatEnum } from '@dxos/echo-schema';
2
2
  import { type SimpleType } from '@dxos/effect';
3
3
  import { type InputComponent } from './Input';
4
4
  /**
5
5
  * Get property input component.
6
6
  */
7
- export declare const getInputComponent: <T extends object>(type: SimpleType, format?: FormatEnum) => InputComponent<T> | undefined;
7
+ export declare const getInputComponent: <T extends BaseObject>(type: SimpleType, format?: FormatEnum) => InputComponent<T> | undefined;
8
8
  //# sourceMappingURL=factory.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../../../src/components/Form/factory.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAI/C,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C;;GAEG;AACH,eAAO,MAAM,iBAAiB,GAAI,CAAC,SAAS,MAAM,QAC1C,UAAU,WACP,UAAU,KAClB,cAAc,CAAC,CAAC,CAAC,GAAG,SActB,CAAC"}
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../../../src/components/Form/factory.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,UAAU,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAI/C,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C;;GAEG;AACH,eAAO,MAAM,iBAAiB,GAAI,CAAC,SAAS,UAAU,QAC9C,UAAU,WACP,UAAU,KAClB,cAAc,CAAC,CAAC,CAAC,GAAG,SActB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ViewEditor.stories.d.ts","sourceRoot":"","sources":["../../../../../src/components/ViewEditor/ViewEditor.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,aAAa,CAAC;AAErB,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAU5D,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AA0C1C,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,UAAU,CAQjC,CAAC;AAEF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAC;AAEtB,eAAO,MAAM,OAAO,EAAE,KAAU,CAAC"}
1
+ {"version":3,"file":"ViewEditor.stories.d.ts","sourceRoot":"","sources":["../../../../../src/components/ViewEditor/ViewEditor.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,aAAa,CAAC;AAErB,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAS5D,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AA0C1C,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,UAAU,CAQjC,CAAC;AAEF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAC;AAEtB,eAAO,MAAM,OAAO,EAAE,KAAU,CAAC"}
@@ -1,10 +1,11 @@
1
1
  import { type FocusEvent } from 'react';
2
+ import { type BaseObject, type PropertyKey } from '@dxos/echo-schema';
2
3
  import { type SimpleType, type S } from '@dxos/effect';
3
- import { type PropertyKey, type ValidationError } from '@dxos/schema';
4
+ import { type ValidationError } from '@dxos/schema';
4
5
  /**
5
6
  * Return type from `useForm` hook.
6
7
  */
7
- export type FormHandler<T extends object = {}> = {
8
+ export type FormHandler<T extends BaseObject> = {
8
9
  values: T;
9
10
  errors: Record<PropertyKey<T>, string>;
10
11
  touched: Record<PropertyKey<T>, boolean>;
@@ -22,7 +23,7 @@ export type FormHandler<T extends object = {}> = {
22
23
  /**
23
24
  * Hook options.
24
25
  */
25
- export interface FormOptions<T extends object> {
26
+ export interface FormOptions<T extends BaseObject> {
26
27
  schema: S.Schema<T>;
27
28
  initialValues: T;
28
29
  /**
@@ -54,5 +55,5 @@ export interface FormOptions<T extends object> {
54
55
  * Creates a hook for managing form state, including values, validation, and submission.
55
56
  * Deeply integrated with `@dxos/schema` for schema-based validation.
56
57
  */
57
- export declare const useForm: <T extends object>({ schema, initialValues, onValuesChanged, onValidate, onValid, onSubmit, }: FormOptions<T>) => FormHandler<T>;
58
+ export declare const useForm: <T extends BaseObject>({ schema, initialValues, onValuesChanged, onValidate, onValid, onSubmit, }: FormOptions<T>) => FormHandler<T>;
58
59
  //# sourceMappingURL=useForm.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useForm.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useForm.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,UAAU,EAA6C,MAAM,OAAO,CAAC;AAEnF,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,CAAC,EAAE,MAAM,cAAc,CAAC;AAGvD,OAAO,EAAkB,KAAK,WAAW,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAEtF;;GAEG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,MAAM,GAAG,EAAE,IAAI;IAK/C,MAAM,EAAE,CAAC,CAAC;IACV,MAAM,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IACvC,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IACzC,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IACzC,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,MAAM,IAAI,CAAC;IAMzB,SAAS,EAAE,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK;QAAE,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9E,QAAQ,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAC7C,aAAa,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IACjF,MAAM,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,gBAAgB,GAAG,mBAAmB,CAAC,KAAK,IAAI,CAAC;CAC7E,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,WAAW,CAAC,CAAC,SAAS,MAAM;IAC3C,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAGpB,aAAa,EAAE,CAAC,CAAC;IAEjB;;;;OAIG;IACH,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,IAAI,CAAC;IAEtC;;;;OAIG;IAEH,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,eAAe,EAAE,GAAG,SAAS,CAAC;IAE1D;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE;QAAE,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;KAAE,KAAK,IAAI,CAAC;IAE5E;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE;QAAE,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;KAAE,KAAK,IAAI,CAAC;CAC9E;AAED;;;GAGG;AACH,eAAO,MAAM,OAAO,GAAI,CAAC,SAAS,MAAM,8EAOrC,WAAW,CAAC,CAAC,CAAC,KAAG,WAAW,CAAC,CAAC,CAiIhC,CAAC"}
1
+ {"version":3,"file":"useForm.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useForm.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,UAAU,EAA6C,MAAM,OAAO,CAAC;AAEnF,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,CAAC,EAAE,MAAM,cAAc,CAAC;AAGvD,OAAO,EAAkB,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpE;;GAEG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,UAAU,IAAI;IAK9C,MAAM,EAAE,CAAC,CAAC;IACV,MAAM,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IACvC,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IACzC,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IACzC,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,MAAM,IAAI,CAAC;IAMzB,SAAS,EAAE,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK;QAAE,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9E,QAAQ,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAC7C,aAAa,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IACjF,MAAM,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,gBAAgB,GAAG,mBAAmB,CAAC,KAAK,IAAI,CAAC;CAC7E,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,WAAW,CAAC,CAAC,SAAS,UAAU;IAC/C,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAGpB,aAAa,EAAE,CAAC,CAAC;IAEjB;;;;OAIG;IACH,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,IAAI,CAAC;IAEtC;;;;OAIG;IAEH,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,eAAe,EAAE,GAAG,SAAS,CAAC;IAE1D;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE;QAAE,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;KAAE,KAAK,IAAI,CAAC;IAE5E;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE;QAAE,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;KAAE,KAAK,IAAI,CAAC;CAC9E;AAED;;;GAGG;AACH,eAAO,MAAM,OAAO,GAAI,CAAC,SAAS,UAAU,8EAOzC,WAAW,CAAC,CAAC,CAAC,KAAG,WAAW,CAAC,CAAC,CAiIhC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/react-ui-form",
3
- "version": "0.7.1-staging.8709ba7",
3
+ "version": "0.7.2-staging.6d26b2a",
4
4
  "description": "Data components.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -23,27 +23,25 @@
23
23
  ],
24
24
  "dependencies": {
25
25
  "@atlaskit/pragmatic-drag-and-drop": "^1.4.0",
26
- "@atlaskit/pragmatic-drag-and-drop-flourish": "^1.1.2",
27
26
  "@atlaskit/pragmatic-drag-and-drop-hitbox": "^1.0.3",
28
- "@atlaskit/pragmatic-drag-and-drop-react-drop-indicator": "^1.1.3",
29
27
  "@effect/schema": "^0.75.5",
30
28
  "@radix-ui/react-context": "^1.0.0",
31
29
  "date-fns": "^3.3.1",
32
30
  "effect": "^3.9.2",
33
31
  "jsonpath": "^1.1.1",
34
- "@dxos/async": "0.7.1-staging.8709ba7",
35
- "@dxos/debug": "0.7.1-staging.8709ba7",
36
- "@dxos/echo-db": "0.7.1-staging.8709ba7",
37
- "@dxos/invariant": "0.7.1-staging.8709ba7",
38
- "@dxos/effect": "0.7.1-staging.8709ba7",
39
- "@dxos/echo-schema": "0.7.1-staging.8709ba7",
40
- "@dxos/keys": "0.7.1-staging.8709ba7",
41
- "@dxos/react-client": "0.7.1-staging.8709ba7",
42
- "@dxos/log": "0.7.1-staging.8709ba7",
43
- "@dxos/react-ui-list": "0.7.1-staging.8709ba7",
44
- "@dxos/schema": "0.7.1-staging.8709ba7",
45
- "@dxos/react-ui-types": "0.7.1-staging.8709ba7",
46
- "@dxos/util": "0.7.1-staging.8709ba7"
32
+ "@dxos/async": "0.7.2-staging.6d26b2a",
33
+ "@dxos/debug": "0.7.2-staging.6d26b2a",
34
+ "@dxos/echo-db": "0.7.2-staging.6d26b2a",
35
+ "@dxos/effect": "0.7.2-staging.6d26b2a",
36
+ "@dxos/invariant": "0.7.2-staging.6d26b2a",
37
+ "@dxos/echo-schema": "0.7.2-staging.6d26b2a",
38
+ "@dxos/keys": "0.7.2-staging.6d26b2a",
39
+ "@dxos/log": "0.7.2-staging.6d26b2a",
40
+ "@dxos/react-ui-list": "0.7.2-staging.6d26b2a",
41
+ "@dxos/react-ui-types": "0.7.2-staging.6d26b2a",
42
+ "@dxos/react-client": "0.7.2-staging.6d26b2a",
43
+ "@dxos/schema": "0.7.2-staging.6d26b2a",
44
+ "@dxos/util": "0.7.2-staging.6d26b2a"
47
45
  },
48
46
  "devDependencies": {
49
47
  "@phosphor-icons/react": "^2.1.5",
@@ -54,12 +52,12 @@
54
52
  "react": "~18.2.0",
55
53
  "react-dom": "~18.2.0",
56
54
  "vite": "5.4.7",
57
- "@dxos/echo-signals": "0.7.1-staging.8709ba7",
58
- "@dxos/random": "0.7.1-staging.8709ba7",
59
- "@dxos/react-ui-syntax-highlighter": "0.7.1-staging.8709ba7",
60
- "@dxos/react-ui": "0.7.1-staging.8709ba7",
61
- "@dxos/react-ui-theme": "0.7.1-staging.8709ba7",
62
- "@dxos/storybook-utils": "0.7.1-staging.8709ba7"
55
+ "@dxos/echo-signals": "0.7.2-staging.6d26b2a",
56
+ "@dxos/random": "0.7.2-staging.6d26b2a",
57
+ "@dxos/react-ui": "0.7.2-staging.6d26b2a",
58
+ "@dxos/react-ui-syntax-highlighter": "0.7.2-staging.6d26b2a",
59
+ "@dxos/react-ui-theme": "0.7.2-staging.6d26b2a",
60
+ "@dxos/storybook-utils": "0.7.2-staging.6d26b2a"
63
61
  },
64
62
  "peerDependencies": {
65
63
  "@effect/schema": "^0.75.5",
@@ -67,8 +65,8 @@
67
65
  "effect": "^3.9.2",
68
66
  "react": "~18.2.0",
69
67
  "react-dom": "~18.2.0",
70
- "@dxos/react-ui": "0.7.1-staging.8709ba7",
71
- "@dxos/react-ui-theme": "0.7.1-staging.8709ba7"
68
+ "@dxos/react-ui": "0.7.2-staging.6d26b2a",
69
+ "@dxos/react-ui-theme": "0.7.2-staging.6d26b2a"
72
70
  },
73
71
  "publishConfig": {
74
72
  "access": "public"
@@ -4,7 +4,7 @@
4
4
 
5
5
  import React from 'react';
6
6
 
7
- import { type LatLng } from '@dxos/echo-schema';
7
+ import { type BaseObject, type GeoPoint } from '@dxos/echo-schema';
8
8
  import { Input, useTranslation } from '@dxos/react-ui';
9
9
 
10
10
  import { InputHeader, type InputProps } from './Input';
@@ -14,7 +14,7 @@ import { translationKey } from '../../translations';
14
14
  // Custom format components.
15
15
  //
16
16
 
17
- export const LatLngInput = <T extends object>({
17
+ export const GeiPointInput = <T extends BaseObject>({
18
18
  property,
19
19
  type,
20
20
  label,
@@ -26,7 +26,7 @@ export const LatLngInput = <T extends object>({
26
26
  }: InputProps<T>) => {
27
27
  const { t } = useTranslation(translationKey);
28
28
  const { status, error } = getStatus?.(property);
29
- const { lat = 0, lng = 0 } = getValue<LatLng>(property) ?? {};
29
+ const [lng = 0, lat = 0] = getValue<GeoPoint>(property) ?? [];
30
30
 
31
31
  return (
32
32
  <Input.Root validationValence={status}>
@@ -37,17 +37,17 @@ export const LatLngInput = <T extends object>({
37
37
  <Input.TextInput
38
38
  type='number'
39
39
  disabled={disabled}
40
- placeholder={t('placeholder latitude')}
41
- value={lat}
42
- onChange={(event) => onValueChange(property, type, { lat: safeParseFloat(event.target.value, 0), lng })}
40
+ placeholder={t('placeholder longitude')}
41
+ value={lng}
42
+ onChange={(event) => onValueChange(property, type, [lat, safeParseFloat(event.target.value, 0)])}
43
43
  onBlur={onBlur}
44
44
  />
45
45
  <Input.TextInput
46
46
  type='number'
47
47
  disabled={disabled}
48
- placeholder={t('placeholder longitude')}
49
- value={lng}
50
- onChange={(event) => onValueChange(property, type, { lat, lng: safeParseFloat(event.target.value, 0) })}
48
+ placeholder={t('placeholder latitude')}
49
+ value={lat}
50
+ onChange={(event) => onValueChange(property, type, [safeParseFloat(event.target.value, 0), lng])}
51
51
  onBlur={onBlur}
52
52
  />
53
53
  </div>
@@ -4,11 +4,12 @@
4
4
 
5
5
  import React from 'react';
6
6
 
7
+ import { type BaseObject } from '@dxos/echo-schema';
7
8
  import { Input, Select } from '@dxos/react-ui';
8
9
 
9
10
  import { type InputProps, InputHeader } from './Input';
10
11
 
11
- export const TextInput = <T extends object>({
12
+ export const TextInput = <T extends BaseObject>({
12
13
  property,
13
14
  type,
14
15
  label,
@@ -37,7 +38,7 @@ export const TextInput = <T extends object>({
37
38
  );
38
39
  };
39
40
 
40
- export const NumberInput = <T extends object>({
41
+ export const NumberInput = <T extends BaseObject>({
41
42
  property,
42
43
  type,
43
44
  label,
@@ -68,7 +69,7 @@ export const NumberInput = <T extends object>({
68
69
  );
69
70
  };
70
71
 
71
- export const BooleanInput = <T extends object>({
72
+ export const BooleanInput = <T extends BaseObject>({
72
73
  property,
73
74
  type,
74
75
  label,
@@ -91,7 +92,11 @@ export const BooleanInput = <T extends object>({
91
92
  );
92
93
  };
93
94
 
94
- export const SelectInput = <T extends object>({
95
+ export type SelectInputOptions<T extends BaseObject> = InputProps<T> & {
96
+ options?: Array<{ value: string | number; label?: string }>;
97
+ };
98
+
99
+ export const SelectInput = <T extends BaseObject>({
95
100
  property,
96
101
  type,
97
102
  label,
@@ -101,7 +106,7 @@ export const SelectInput = <T extends object>({
101
106
  getStatus,
102
107
  getValue,
103
108
  onValueChange,
104
- }: InputProps<T>) => {
109
+ }: SelectInputOptions<T>) => {
105
110
  const { status, error } = getStatus?.(property);
106
111
 
107
112
  return (
@@ -26,7 +26,7 @@ const TestSchema = S.Struct({
26
26
  street: S.optional(S.String.annotations({ [AST.TitleAnnotationId]: 'Street' })),
27
27
  city: S.optional(S.String.annotations({ [AST.TitleAnnotationId]: 'City' })),
28
28
  zip: S.optional(S.String.pipe(S.pattern(/^\d{5}(-\d{4})?$/)).annotations({ [AST.TitleAnnotationId]: 'ZIP' })),
29
- location: S.optional(Format.LatLng.annotations({ [AST.TitleAnnotationId]: 'Location' })),
29
+ location: S.optional(Format.GeoPoint.annotations({ [AST.TitleAnnotationId]: 'Location' })),
30
30
  }).annotations({ [AST.TitleAnnotationId]: 'Address' }),
31
31
  ),
32
32
  }).pipe(S.mutable);
@@ -51,7 +51,7 @@ const DefaultStory = ({ values: initialValues }: StoryProps) => {
51
51
  };
52
52
 
53
53
  const meta: Meta<StoryProps> = {
54
- title: 'ui/react-ui-data/Form',
54
+ title: 'ui/react-ui-form/Form',
55
55
  component: Form,
56
56
  render: DefaultStory,
57
57
  decorators: [withLayout({ fullscreen: true, tooltips: true }), withTheme],
@@ -2,16 +2,19 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
+ import { pipe } from 'effect';
6
+ import { capitalize } from 'effect/String';
5
7
  import React, { useEffect, useMemo } from 'react';
6
8
 
7
- import { AST, S } from '@dxos/echo-schema';
9
+ import { AST, type BaseObject, S, type PropertyKey } from '@dxos/echo-schema';
8
10
  import { findNode, getDiscriminatedType, isDiscriminatedUnion } from '@dxos/effect';
9
11
  import { log } from '@dxos/log';
10
12
  import { IconButton, type ThemedClassName, useTranslation } from '@dxos/react-ui';
11
13
  import { mx } from '@dxos/react-ui-theme';
12
- import { getSchemaProperties, type PropertyKey, type SchemaProperty } from '@dxos/schema';
14
+ import { getSchemaProperties, type SchemaProperty } from '@dxos/schema';
13
15
  import { isNotFalsy } from '@dxos/util';
14
16
 
17
+ import { SelectInput } from './Defaults';
15
18
  import { type InputComponent } from './Input';
16
19
  import { getInputComponent } from './factory';
17
20
  import { type FormOptions, useForm } from '../../hooks';
@@ -21,9 +24,9 @@ import { translationKey } from '../../translations';
21
24
 
22
25
  const padding = 'px-2';
23
26
 
24
- export type PropsFilter<T extends Object> = (props: SchemaProperty<T>[]) => SchemaProperty<T>[];
27
+ export type PropsFilter<T extends BaseObject> = (props: SchemaProperty<T>[]) => SchemaProperty<T>[];
25
28
 
26
- export type FormProps<T extends object> = ThemedClassName<
29
+ export type FormProps<T extends BaseObject> = ThemedClassName<
27
30
  {
28
31
  values: T;
29
32
  /** Path to the current object from the root. Used with nested forms. */
@@ -48,7 +51,7 @@ export type FormProps<T extends object> = ThemedClassName<
48
51
  /**
49
52
  * General purpose form component that displays field controls based on the given schema.
50
53
  */
51
- export const Form = <T extends object = {}>({
54
+ export const Form = <T extends BaseObject>({
52
55
  classNames,
53
56
  schema,
54
57
  values: initialValues,
@@ -76,7 +79,7 @@ export const Form = <T extends object = {}>({
76
79
 
77
80
  // Filter and sort props.
78
81
  // TODO(burdon): Move into useForm?
79
- const props = useMemo(() => {
82
+ const properties = useMemo(() => {
80
83
  const props = getSchemaProperties<T>(schema.ast, values);
81
84
  const filtered = filter ? filter(props) : props;
82
85
  const findIndex = (props: PropertyKey<T>[], prop: PropertyKey<T>) => {
@@ -96,25 +99,50 @@ export const Form = <T extends object = {}>({
96
99
 
97
100
  return (
98
101
  <div role='form' className={mx('flex flex-col w-full gap-2 py-2', classNames)}>
99
- {props
100
- .map(({ prop, name, type, format, title, description, examples }) => {
101
- // Custom property allows for sub forms.
102
- // TODO(burdon): Use Select control if options are present in annotation?
102
+ {properties
103
+ .map((property) => {
104
+ const { ast, name, type, format, title, description, examples, options } = property;
103
105
  const key = [...path, name];
104
- const InputComponent = Custom?.[key.join('.')] ?? getInputComponent<T>(type, format);
106
+ const label = pipe(title ?? name, capitalize);
107
+ const placeholder = examples?.length ? `Example: "${examples[0]}"` : description;
108
+
109
+ // Get generic input.
110
+ let InputComponent = Custom?.[key.join('.')];
111
+ if (!InputComponent) {
112
+ // Select.
113
+ if (options) {
114
+ return (
115
+ <div key={name} role='none' className={padding}>
116
+ <SelectInput
117
+ type={type}
118
+ format={format}
119
+ property={name}
120
+ disabled={readonly}
121
+ label={label}
122
+ options={options.map((option) => ({ value: option, label: String(option) }))}
123
+ placeholder={placeholder}
124
+ {...inputProps}
125
+ />
126
+ </div>
127
+ );
128
+ }
129
+
130
+ InputComponent = getInputComponent<T>(type, format);
131
+ }
132
+
105
133
  if (!InputComponent) {
106
134
  // Recursively render form.
107
135
  if (type === 'object') {
108
- const baseNode = findNode(prop.type, isDiscriminatedUnion);
136
+ const baseNode = findNode(ast, isDiscriminatedUnion);
109
137
  const typeLiteral = baseNode
110
138
  ? getDiscriminatedType(baseNode, values[name] as any)
111
- : findNode(prop.type, AST.isTypeLiteral);
139
+ : findNode(ast, AST.isTypeLiteral);
112
140
 
113
141
  if (typeLiteral) {
114
142
  const schema = S.make(typeLiteral);
115
143
  return (
116
144
  <div key={name} role='none'>
117
- <div className={padding}>{title ?? name}</div>
145
+ <div className={padding}>{label}</div>
118
146
  <Form<any>
119
147
  schema={schema}
120
148
  path={key}
@@ -133,8 +161,6 @@ export const Form = <T extends object = {}>({
133
161
  return null;
134
162
  }
135
163
 
136
- const placeholder = examples?.length ? `Example: ${examples[0]}` : description;
137
-
138
164
  return (
139
165
  <div key={name} role='none' className={padding}>
140
166
  <InputComponent
@@ -142,7 +168,7 @@ export const Form = <T extends object = {}>({
142
168
  format={format}
143
169
  property={name}
144
170
  disabled={readonly}
145
- label={title ?? name}
171
+ label={label}
146
172
  placeholder={placeholder}
147
173
  {...inputProps}
148
174
  />
@@ -151,8 +177,6 @@ export const Form = <T extends object = {}>({
151
177
  })
152
178
  .filter(isNotFalsy)}
153
179
 
154
- {/* {errors && <div className='overflow-hidden text-sm'>{JSON.stringify(errors)}</div>} */}
155
-
156
180
  {(onCancel || onSubmit) && !autoSave && (
157
181
  <div role='none' className='flex justify-center'>
158
182
  <div role='none' className={mx(onCancel && !readonly && 'grid grid-cols-2 gap-2')}>
@@ -4,33 +4,29 @@
4
4
 
5
5
  import React, { type FC, type PropsWithChildren } from 'react';
6
6
 
7
- import { type FormatEnum } from '@dxos/echo-schema';
7
+ import { type BaseObject, type FormatEnum, type PropertyKey } from '@dxos/echo-schema';
8
8
  import { type SimpleType } from '@dxos/effect';
9
9
  import { Icon, Tooltip } from '@dxos/react-ui';
10
10
  import { errorText } from '@dxos/react-ui-theme';
11
- import { type PropertyKey } from '@dxos/schema';
12
11
 
13
12
  import { type FormHandler } from '../../hooks';
14
13
 
15
14
  /**
16
15
  * Props passed to input components.
17
16
  */
18
- export type InputProps<T extends object = {}> = {
17
+ export type InputProps<T extends BaseObject> = {
19
18
  property: PropertyKey<T>;
20
19
  type: SimpleType;
21
20
  format?: FormatEnum;
22
21
  label: string;
23
22
  disabled?: boolean;
24
23
  placeholder?: string;
25
- // TODO(burdon): Provide from annotations? E.g., enum.
26
- options?: Array<{ value: string | number; label?: string }>;
27
24
  } & Pick<FormHandler<T>, 'getStatus' | 'getValue' | 'onValueChange' | 'onBlur'>;
28
25
 
29
26
  /**
30
27
  * Form input component.
31
28
  */
32
- // TODO(burdon): Remove generic from inputs.
33
- export type InputComponent<T extends object = {}> = FC<InputProps<T>>;
29
+ export type InputComponent<T extends BaseObject> = FC<InputProps<T>>;
34
30
 
35
31
  export type InputHeaderProps = PropsWithChildren<{
36
32
  error?: string;
@@ -2,23 +2,23 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import { FormatEnum } from '@dxos/echo-schema';
5
+ import { type BaseObject, FormatEnum } from '@dxos/echo-schema';
6
6
  import { type SimpleType } from '@dxos/effect';
7
7
 
8
- import { LatLngInput } from './Custom';
8
+ import { GeiPointInput } from './Custom';
9
9
  import { BooleanInput, NumberInput, TextInput } from './Defaults';
10
10
  import { type InputComponent } from './Input';
11
11
 
12
12
  /**
13
13
  * Get property input component.
14
14
  */
15
- export const getInputComponent = <T extends object>(
15
+ export const getInputComponent = <T extends BaseObject>(
16
16
  type: SimpleType,
17
17
  format?: FormatEnum,
18
18
  ): InputComponent<T> | undefined => {
19
19
  switch (format) {
20
20
  case FormatEnum.LatLng:
21
- return LatLngInput;
21
+ return GeiPointInput;
22
22
  }
23
23
 
24
24
  switch (type) {
@@ -10,8 +10,7 @@ import React, { useCallback, useEffect, useState } from 'react';
10
10
  import { Format, type MutableSchema, S, toJsonSchema, TypedObject } from '@dxos/echo-schema';
11
11
  import { useSpace } from '@dxos/react-client/echo';
12
12
  import { withClientProvider } from '@dxos/react-client/testing';
13
- import { ViewProjection, createView } from '@dxos/schema';
14
- import { type ViewType } from '@dxos/schema';
13
+ import { type ViewType, ViewProjection, createView } from '@dxos/schema';
15
14
  import { withTheme, withLayout } from '@dxos/storybook-utils';
16
15
 
17
16
  import { ViewEditor } from './ViewEditor';
@@ -4,15 +4,16 @@
4
4
 
5
5
  import { type FocusEvent, useCallback, useEffect, useMemo, useState } from 'react';
6
6
 
7
+ import { type BaseObject, type PropertyKey } from '@dxos/echo-schema';
7
8
  import { type SimpleType, type S } from '@dxos/effect';
8
9
  import { invariant } from '@dxos/invariant';
9
10
  import { log } from '@dxos/log';
10
- import { validateSchema, type PropertyKey, type ValidationError } from '@dxos/schema';
11
+ import { validateSchema, type ValidationError } from '@dxos/schema';
11
12
 
12
13
  /**
13
14
  * Return type from `useForm` hook.
14
15
  */
15
- export type FormHandler<T extends object = {}> = {
16
+ export type FormHandler<T extends BaseObject> = {
16
17
  //
17
18
  // Form state management.
18
19
  //
@@ -37,7 +38,7 @@ export type FormHandler<T extends object = {}> = {
37
38
  /**
38
39
  * Hook options.
39
40
  */
40
- export interface FormOptions<T extends object> {
41
+ export interface FormOptions<T extends BaseObject> {
41
42
  schema: S.Schema<T>;
42
43
 
43
44
  // TODO(burdon): Are these reactive?
@@ -73,7 +74,7 @@ export interface FormOptions<T extends object> {
73
74
  * Creates a hook for managing form state, including values, validation, and submission.
74
75
  * Deeply integrated with `@dxos/schema` for schema-based validation.
75
76
  */
76
- export const useForm = <T extends object>({
77
+ export const useForm = <T extends BaseObject>({
77
78
  schema,
78
79
  initialValues,
79
80
  onValuesChanged,
@@ -211,12 +212,12 @@ export const useForm = <T extends object>({
211
212
  } satisfies FormHandler<T>;
212
213
  };
213
214
 
214
- const createKeySet = <T extends object, V>(obj: T, value: V): Record<PropertyKey<T>, V> => {
215
+ const createKeySet = <T extends BaseObject, V>(obj: T, value: V): Record<PropertyKey<T>, V> => {
215
216
  invariant(obj);
216
217
  return Object.keys(obj).reduce((acc, key) => ({ ...acc, [key]: value }), {} as Record<PropertyKey<T>, V>);
217
218
  };
218
219
 
219
- const flatMap = <T extends object>(errors: ValidationError[]) => {
220
+ const flatMap = <T extends BaseObject>(errors: ValidationError[]) => {
220
221
  return errors.reduce(
221
222
  (result, { path, message }) => {
222
223
  if (!(path in result)) {