@dxos/react-ui-form 0.8.2-main.5885341 → 0.8.2-main.5ca3450
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.
- package/dist/lib/browser/index.mjs +83 -49
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +210 -177
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +83 -49
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/components/ControlSection/ControlSection.d.ts.map +1 -1
- package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
- package/dist/types/src/components/Form/ArrayField.d.ts.map +1 -1
- package/dist/types/src/components/Form/Defaults.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.d.ts +3 -2
- package/dist/types/src/components/Form/Form.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.stories.d.ts +33 -32
- package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormActions.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormContent.d.ts +2 -2
- package/dist/types/src/components/Form/FormContent.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormContext.d.ts.map +1 -1
- package/dist/types/src/components/Form/Input.d.ts.map +1 -1
- package/dist/types/src/components/Form/RefField.d.ts +3 -2
- package/dist/types/src/components/Form/RefField.d.ts.map +1 -1
- package/dist/types/src/components/Form/custom/GeoPointInput.d.ts.map +1 -1
- package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts.map +1 -1
- package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/custom/TupleInput.d.ts.map +1 -1
- package/dist/types/src/components/Form/factory.d.ts.map +1 -1
- package/dist/types/src/components/Form/index.d.ts +1 -0
- package/dist/types/src/components/Form/index.d.ts.map +1 -1
- package/dist/types/src/components/ViewEditor/Test.stories.d.ts.map +1 -1
- package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
- package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/deprecated/Form.d.ts +2 -2
- package/dist/types/src/components/deprecated/Form.d.ts.map +1 -1
- package/dist/types/src/components/deprecated/Form.stories.d.ts.map +1 -1
- package/dist/types/src/components/deprecated/FormInput.d.ts.map +1 -1
- package/dist/types/src/components/testing.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +1 -0
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useForm.d.ts +2 -2
- package/dist/types/src/hooks/useForm.d.ts.map +1 -1
- package/dist/types/src/hooks/useRefQueryLookupHandler.d.ts +8 -0
- package/dist/types/src/hooks/useRefQueryLookupHandler.d.ts.map +1 -0
- package/dist/types/src/util/field.d.ts.map +1 -1
- package/dist/types/src/util/formatting.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +24 -24
- package/src/components/Form/ArrayField.tsx +5 -6
- package/src/components/Form/Defaults.tsx +4 -1
- package/src/components/Form/Form.stories.tsx +46 -41
- package/src/components/Form/Form.tsx +3 -2
- package/src/components/Form/FormContent.tsx +5 -6
- package/src/components/Form/RefField.tsx +2 -2
- package/src/components/Form/custom/SelectOptionsInput.stories.tsx +5 -4
- package/src/components/Form/index.ts +1 -1
- package/src/components/ViewEditor/ViewEditor.stories.tsx +3 -2
- package/src/components/ViewEditor/ViewEditor.tsx +9 -8
- package/src/components/deprecated/Form.tsx +6 -6
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useForm.ts +3 -3
- package/src/hooks/useRefQueryLookupHandler.ts +43 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useForm.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useForm.ts"],"names":[],"mappings":"AAIA,OAAO,
|
|
1
|
+
{"version":3,"file":"useForm.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useForm.ts"],"names":[],"mappings":"AAIA,OAAO,EAAa,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGhD,OAAO,EAAE,KAAK,UAAU,EAAsB,MAAM,mBAAmB,CAAC;AACxE,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,QAAQ,EAA4C,MAAM,cAAc,CAAC;AAGxG,OAAO,EAAkB,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AACpE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C;;GAEG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,UAAU,IAAI;IAK9C,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACjC,OAAO,EAAE,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACnC,OAAO,EAAE,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,MAAM,IAAI,CAAC;IAMvB,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,KAAK;QAAE,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACxF,QAAQ,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,KAAK,CAAC,GAAG,SAAS,CAAC;IAC1D,aAAa,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAClF,SAAS,EAAE,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,KAAK,IAAI,CAAC;CAChD,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,WAAW,CAAC,CAAC,SAAS,UAAU;IAC/C;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAE9B;;OAEG;IACH,aAAa,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAE1B;;;;OAIG;IACH,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;IAE/C;;;;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,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE;QAAE,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;KAAE,KAAK,YAAY,CAAC,IAAI,CAAC,CAAC;CAC1F;AAED;;;GAGG;AACH,eAAO,MAAM,OAAO,GAAI,CAAC,SAAS,UAAU,EAAE,0EAO3C,WAAW,CAAC,CAAC,CAAC,KAAG,WAAW,CAAC,CAAC,CAmLhC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type Space } from '@dxos/react-client/echo';
|
|
2
|
+
import { type QueryRefOptions } from '../components';
|
|
3
|
+
type UseRefQueryLookupProps = {
|
|
4
|
+
space?: Space;
|
|
5
|
+
};
|
|
6
|
+
export declare const useRefQueryLookupHandler: ({ space }: UseRefQueryLookupProps) => QueryRefOptions;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=useRefQueryLookupHandler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useRefQueryLookupHandler.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useRefQueryLookupHandler.ts"],"names":[],"mappings":"AAOA,OAAO,EAAU,KAAK,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAG7D,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD,KAAK,sBAAsB,GAAG;IAC5B,KAAK,CAAC,EAAE,KAAK,CAAC;CACf,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAI,WAAW,sBAAsB,KAAG,eA0B5E,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"field.d.ts","sourceRoot":"","sources":["../../../../src/util/field.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,UAAU,EAAe,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,KAAK,EAAE,GAAG,CAAC;CACZ,CAAC;AAEF,eAAO,MAAM,UAAU,
|
|
1
|
+
{"version":3,"file":"field.d.ts","sourceRoot":"","sources":["../../../../src/util/field.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,UAAU,EAAe,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,KAAK,EAAE,GAAG,CAAC;CACZ,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,yBAAyB,UAAU,QAsF7D,CAAC;AAGF,MAAM,MAAM,4BAA4B,GAAG;IACzC,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAI,kBAAkB,4BAA4B,KAAG,MAAM,EAAE,GAAG,SAmCnG,CAAC;AAGF,eAAO,MAAM,kBAAkB,GAAI,MAAM,MAAM,KAAG,eAGhD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formatting.d.ts","sourceRoot":"","sources":["../../../../src/util/formatting.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,UAAU,EAAe,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAEtE,KAAK,gBAAgB,GAAG;IACtB,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IAChC,KAAK,EAAE,GAAG,CAAC;IACX,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B,CAAC;AAEF;;;GAGG;AAGH,eAAO,MAAM,gBAAgB,
|
|
1
|
+
{"version":3,"file":"formatting.d.ts","sourceRoot":"","sources":["../../../../src/util/formatting.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,UAAU,EAAe,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAEtE,KAAK,gBAAgB,GAAG;IACtB,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IAChC,KAAK,EAAE,GAAG,CAAC;IACX,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B,CAAC;AAEF;;;GAGG;AAGH,eAAO,MAAM,gBAAgB,GAAI,iCAA6C,gBAAgB,KAAG,MAqFhG,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,iCAA6C,gBAAgB,KAAG,MA8DhG,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"5.
|
|
1
|
+
{"version":"5.8.3"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/react-ui-form",
|
|
3
|
-
"version": "0.8.2-main.
|
|
3
|
+
"version": "0.8.2-main.5ca3450",
|
|
4
4
|
"description": "Data components.",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -28,21 +28,21 @@
|
|
|
28
28
|
"@radix-ui/react-context": "1.1.1",
|
|
29
29
|
"date-fns": "^3.3.1",
|
|
30
30
|
"jsonpath": "^1.1.1",
|
|
31
|
-
"@dxos/async": "0.8.2-main.
|
|
32
|
-
"@dxos/debug": "0.8.2-main.
|
|
33
|
-
"@dxos/echo-db": "0.8.2-main.
|
|
34
|
-
"@dxos/echo-schema": "0.8.2-main.
|
|
35
|
-
"@dxos/effect": "0.8.2-main.
|
|
36
|
-
"@dxos/invariant": "0.8.2-main.
|
|
37
|
-
"@dxos/
|
|
38
|
-
"@dxos/
|
|
39
|
-
"@dxos/react-client": "0.8.2-main.
|
|
40
|
-
"@dxos/
|
|
41
|
-
"@dxos/
|
|
42
|
-
"@dxos/react-ui-
|
|
43
|
-
"@dxos/react-ui-types": "0.8.2-main.
|
|
44
|
-
"@dxos/schema": "0.8.2-main.
|
|
45
|
-
"@dxos/util": "0.8.2-main.
|
|
31
|
+
"@dxos/async": "0.8.2-main.5ca3450",
|
|
32
|
+
"@dxos/debug": "0.8.2-main.5ca3450",
|
|
33
|
+
"@dxos/echo-db": "0.8.2-main.5ca3450",
|
|
34
|
+
"@dxos/echo-schema": "0.8.2-main.5ca3450",
|
|
35
|
+
"@dxos/effect": "0.8.2-main.5ca3450",
|
|
36
|
+
"@dxos/invariant": "0.8.2-main.5ca3450",
|
|
37
|
+
"@dxos/keys": "0.8.2-main.5ca3450",
|
|
38
|
+
"@dxos/live-object": "0.8.2-main.5ca3450",
|
|
39
|
+
"@dxos/react-client": "0.8.2-main.5ca3450",
|
|
40
|
+
"@dxos/react-ui-list": "0.8.2-main.5ca3450",
|
|
41
|
+
"@dxos/log": "0.8.2-main.5ca3450",
|
|
42
|
+
"@dxos/react-ui-pickers": "0.8.2-main.5ca3450",
|
|
43
|
+
"@dxos/react-ui-types": "0.8.2-main.5ca3450",
|
|
44
|
+
"@dxos/schema": "0.8.2-main.5ca3450",
|
|
45
|
+
"@dxos/util": "0.8.2-main.5ca3450"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@phosphor-icons/react": "^2.1.5",
|
|
@@ -54,20 +54,20 @@
|
|
|
54
54
|
"react": "~18.2.0",
|
|
55
55
|
"react-dom": "~18.2.0",
|
|
56
56
|
"vite": "5.4.7",
|
|
57
|
-
"@dxos/echo-signals": "0.8.2-main.
|
|
58
|
-
"@dxos/random": "0.8.2-main.
|
|
59
|
-
"@dxos/react-ui": "0.8.2-main.
|
|
60
|
-
"@dxos/react-ui-syntax-highlighter": "0.8.2-main.
|
|
61
|
-
"@dxos/react-ui-theme": "0.8.2-main.
|
|
62
|
-
"@dxos/storybook-utils": "0.8.2-main.
|
|
57
|
+
"@dxos/echo-signals": "0.8.2-main.5ca3450",
|
|
58
|
+
"@dxos/random": "0.8.2-main.5ca3450",
|
|
59
|
+
"@dxos/react-ui": "0.8.2-main.5ca3450",
|
|
60
|
+
"@dxos/react-ui-syntax-highlighter": "0.8.2-main.5ca3450",
|
|
61
|
+
"@dxos/react-ui-theme": "0.8.2-main.5ca3450",
|
|
62
|
+
"@dxos/storybook-utils": "0.8.2-main.5ca3450"
|
|
63
63
|
},
|
|
64
64
|
"peerDependencies": {
|
|
65
65
|
"@phosphor-icons/react": "^2.1.5",
|
|
66
66
|
"effect": "3.13.3",
|
|
67
67
|
"react": "~18.2.0",
|
|
68
68
|
"react-dom": "~18.2.0",
|
|
69
|
-
"@dxos/react-ui": "0.8.2-main.
|
|
70
|
-
"@dxos/react-ui-theme": "0.8.2-main.
|
|
69
|
+
"@dxos/react-ui": "0.8.2-main.5ca3450",
|
|
70
|
+
"@dxos/react-ui-theme": "0.8.2-main.5ca3450"
|
|
71
71
|
},
|
|
72
72
|
"publishConfig": {
|
|
73
73
|
"access": "public"
|
|
@@ -2,11 +2,10 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { pipe } from 'effect';
|
|
5
|
+
import { SchemaAST, pipe } from 'effect';
|
|
6
6
|
import { capitalize } from 'effect/String';
|
|
7
7
|
import React, { useCallback, useMemo } from 'react';
|
|
8
8
|
|
|
9
|
-
import { AST } from '@dxos/echo-schema';
|
|
10
9
|
import { findNode, getDiscriminatedType, isDiscriminatedUnion, SimpleType } from '@dxos/effect';
|
|
11
10
|
import { invariant } from '@dxos/invariant';
|
|
12
11
|
import { IconButton, useTranslation } from '@dxos/react-ui';
|
|
@@ -39,12 +38,12 @@ export const ArrayField = ({ property, readonly, path, inputProps, Custom, looku
|
|
|
39
38
|
invariant(Array.isArray(values), `Values at path ${path?.join('.')} must be an array.`);
|
|
40
39
|
const label = title ?? pipe(name, capitalize);
|
|
41
40
|
|
|
42
|
-
const tupleType = findNode(ast,
|
|
43
|
-
const elementType = (tupleType as
|
|
41
|
+
const tupleType = findNode(ast, SchemaAST.isTupleType);
|
|
42
|
+
const elementType = (tupleType as SchemaAST.TupleType | undefined)?.rest[0]?.type;
|
|
44
43
|
|
|
45
|
-
const getDefaultObjectValue = (typeNode:
|
|
44
|
+
const getDefaultObjectValue = (typeNode: SchemaAST.AST): any => {
|
|
46
45
|
const baseNode = findNode(typeNode, isDiscriminatedUnion);
|
|
47
|
-
const typeLiteral = baseNode ? getDiscriminatedType(baseNode, {}) : findNode(typeNode,
|
|
46
|
+
const typeLiteral = baseNode ? getDiscriminatedType(baseNode, {}) : findNode(typeNode, SchemaAST.isTypeLiteral);
|
|
48
47
|
if (!typeLiteral) {
|
|
49
48
|
return {};
|
|
50
49
|
}
|
|
@@ -107,6 +107,9 @@ export const SelectInput = ({
|
|
|
107
107
|
}: SelectInputOptions) => {
|
|
108
108
|
const { status, error } = getStatus();
|
|
109
109
|
|
|
110
|
+
const value = getValue() as string | undefined;
|
|
111
|
+
const handleValueChange = useCallback((value: string | number) => onValueChange(type, value), [type, onValueChange]);
|
|
112
|
+
|
|
110
113
|
return (
|
|
111
114
|
<Input.Root validationValence={status}>
|
|
112
115
|
{!inputOnly && (
|
|
@@ -114,7 +117,7 @@ export const SelectInput = ({
|
|
|
114
117
|
<Input.Label>{label}</Input.Label>
|
|
115
118
|
</InputHeader>
|
|
116
119
|
)}
|
|
117
|
-
<Select.Root value={
|
|
120
|
+
<Select.Root value={value} onValueChange={handleValueChange}>
|
|
118
121
|
{/* TODO(burdon): Placeholder not working? */}
|
|
119
122
|
<Select.TriggerButton classNames='is-full' disabled={disabled} placeholder={placeholder} />
|
|
120
123
|
<Select.Portal>
|
|
@@ -5,10 +5,11 @@
|
|
|
5
5
|
import '@dxos-theme';
|
|
6
6
|
|
|
7
7
|
import { type Meta, type StoryObj } from '@storybook/react';
|
|
8
|
+
import { Schema, SchemaAST } from 'effect';
|
|
8
9
|
import React, { useCallback, useState } from 'react';
|
|
9
10
|
|
|
10
11
|
import { ContactType } from '@dxos/client/testing';
|
|
11
|
-
import {
|
|
12
|
+
import { type BaseObject, Expando, Format, getDXN, Ref, type TypeAnnotation } from '@dxos/echo-schema';
|
|
12
13
|
import { live } from '@dxos/live-object';
|
|
13
14
|
import { Testing } from '@dxos/schema/testing';
|
|
14
15
|
import { withLayout, withTheme } from '@dxos/storybook-utils';
|
|
@@ -18,25 +19,27 @@ import { Form, type FormProps } from './Form';
|
|
|
18
19
|
import translations from '../../translations';
|
|
19
20
|
import { TestLayout, TestPanel } from '../testing';
|
|
20
21
|
|
|
21
|
-
const AddressSchema =
|
|
22
|
-
street:
|
|
23
|
-
city:
|
|
24
|
-
zip:
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
const AddressSchema = Schema.Struct({
|
|
23
|
+
street: Schema.optional(Schema.String.annotations({ [SchemaAST.TitleAnnotationId]: 'Street' })),
|
|
24
|
+
city: Schema.optional(Schema.String.annotations({ [SchemaAST.TitleAnnotationId]: 'City' })),
|
|
25
|
+
zip: Schema.optional(
|
|
26
|
+
Schema.String.pipe(Schema.pattern(/^\d{5}(-\d{4})?$/)).annotations({ [SchemaAST.TitleAnnotationId]: 'ZIP' }),
|
|
27
|
+
),
|
|
28
|
+
location: Schema.optional(Format.GeoPoint.annotations({ [SchemaAST.TitleAnnotationId]: 'Location' })),
|
|
29
|
+
}).annotations({ [SchemaAST.TitleAnnotationId]: 'Address' });
|
|
27
30
|
|
|
28
31
|
// TODO(burdon): Translations?
|
|
29
|
-
const TestSchema =
|
|
30
|
-
name:
|
|
31
|
-
active:
|
|
32
|
-
rank:
|
|
33
|
-
website:
|
|
34
|
-
address:
|
|
35
|
-
}).pipe(
|
|
32
|
+
const TestSchema = Schema.Struct({
|
|
33
|
+
name: Schema.optional(Schema.String.annotations({ [SchemaAST.TitleAnnotationId]: 'Name' })),
|
|
34
|
+
active: Schema.optional(Schema.Boolean.annotations({ [SchemaAST.TitleAnnotationId]: 'Active' })),
|
|
35
|
+
rank: Schema.optional(Schema.Number.annotations({ [SchemaAST.TitleAnnotationId]: 'Rank' })),
|
|
36
|
+
website: Schema.optional(Format.URL.annotations({ [SchemaAST.TitleAnnotationId]: 'Website' })),
|
|
37
|
+
address: Schema.optional(AddressSchema),
|
|
38
|
+
}).pipe(Schema.mutable);
|
|
36
39
|
|
|
37
|
-
type TestType =
|
|
40
|
+
type TestType = Schema.Schema.Type<typeof TestSchema>;
|
|
38
41
|
|
|
39
|
-
type StoryProps<T extends BaseObject> = { schema:
|
|
42
|
+
type StoryProps<T extends BaseObject> = { schema: Schema.Schema<T> } & FormProps<T>;
|
|
40
43
|
|
|
41
44
|
const DefaultStory = <T extends BaseObject>({ schema, values: initialValues, ...props }: StoryProps<T>) => {
|
|
42
45
|
const [values, setValues] = useState(initialValues);
|
|
@@ -117,22 +120,24 @@ export const OrganizationAutoSave: Story<Testing.Organization> = {
|
|
|
117
120
|
// TODO(burdon): Move into separate storybook and use test types.
|
|
118
121
|
//
|
|
119
122
|
|
|
120
|
-
const ShapeSchema =
|
|
121
|
-
shape:
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
type:
|
|
125
|
-
radius:
|
|
123
|
+
const ShapeSchema = Schema.Struct({
|
|
124
|
+
shape: Schema.optional(
|
|
125
|
+
Schema.Union(
|
|
126
|
+
Schema.Struct({
|
|
127
|
+
type: Schema.Literal('circle').annotations({ [SchemaAST.TitleAnnotationId]: 'Type' }),
|
|
128
|
+
radius: Schema.optional(Schema.Number.annotations({ [SchemaAST.TitleAnnotationId]: 'Radius' })),
|
|
126
129
|
}),
|
|
127
|
-
|
|
128
|
-
type:
|
|
129
|
-
size:
|
|
130
|
+
Schema.Struct({
|
|
131
|
+
type: Schema.Literal('square').annotations({ [SchemaAST.TitleAnnotationId]: 'Type' }),
|
|
132
|
+
size: Schema.optional(
|
|
133
|
+
Schema.Number.pipe(Schema.nonNegative()).annotations({ [SchemaAST.TitleAnnotationId]: 'Size' }),
|
|
134
|
+
),
|
|
130
135
|
}),
|
|
131
|
-
).annotations({ [
|
|
136
|
+
).annotations({ [SchemaAST.TitleAnnotationId]: 'Shape' }),
|
|
132
137
|
),
|
|
133
|
-
}).pipe(
|
|
138
|
+
}).pipe(Schema.mutable);
|
|
134
139
|
|
|
135
|
-
type ShapeType =
|
|
140
|
+
type ShapeType = Schema.Schema.Type<typeof ShapeSchema>;
|
|
136
141
|
|
|
137
142
|
type DiscriminatedUnionStoryProps = FormProps<ShapeType>;
|
|
138
143
|
|
|
@@ -178,12 +183,12 @@ export const DiscriminatedShape: StoryObj<DiscriminatedUnionStoryProps> = {
|
|
|
178
183
|
},
|
|
179
184
|
};
|
|
180
185
|
|
|
181
|
-
const ArraysSchema =
|
|
182
|
-
names:
|
|
183
|
-
addresses:
|
|
184
|
-
}).pipe(
|
|
186
|
+
const ArraysSchema = Schema.Struct({
|
|
187
|
+
names: Schema.Array(Schema.String.pipe(Schema.nonEmptyString())),
|
|
188
|
+
addresses: Schema.Array(AddressSchema),
|
|
189
|
+
}).pipe(Schema.mutable);
|
|
185
190
|
|
|
186
|
-
type ArraysType =
|
|
191
|
+
type ArraysType = Schema.Schema.Type<typeof ArraysSchema>;
|
|
187
192
|
|
|
188
193
|
const ArraysStory = ({ values: initialValues }: FormProps<ArraysType>) => {
|
|
189
194
|
const [values, setValues] = useState(initialValues);
|
|
@@ -210,13 +215,13 @@ export const Arrays: StoryObj<FormProps<ArraysType>> = {
|
|
|
210
215
|
},
|
|
211
216
|
};
|
|
212
217
|
|
|
213
|
-
const ColorSchema =
|
|
214
|
-
color:
|
|
215
|
-
[
|
|
218
|
+
const ColorSchema = Schema.Struct({
|
|
219
|
+
color: Schema.Union(Schema.Literal('red'), Schema.Literal('green'), Schema.Literal('blue')).annotations({
|
|
220
|
+
[SchemaAST.TitleAnnotationId]: 'Color',
|
|
216
221
|
}),
|
|
217
|
-
}).pipe(
|
|
222
|
+
}).pipe(Schema.mutable);
|
|
218
223
|
|
|
219
|
-
type ColorType =
|
|
224
|
+
type ColorType = Schema.Schema.Type<typeof ColorSchema>;
|
|
220
225
|
|
|
221
226
|
const EnumStory = ({ values: initialValues }: FormProps<ColorType>) => {
|
|
222
227
|
const [values, setValues] = useState(initialValues);
|
|
@@ -242,10 +247,10 @@ export const Enum: StoryObj<FormProps<ColorType>> = {
|
|
|
242
247
|
},
|
|
243
248
|
};
|
|
244
249
|
|
|
245
|
-
const RefSchema =
|
|
250
|
+
const RefSchema = Schema.Struct({
|
|
246
251
|
contact: Ref(ContactType).annotations({ title: 'Contact Reference' }),
|
|
247
|
-
optionalContact:
|
|
248
|
-
unknownExpando:
|
|
252
|
+
optionalContact: Schema.optional(Ref(ContactType).annotations({ title: 'Optional Contact Reference' })),
|
|
253
|
+
unknownExpando: Schema.optional(Ref(Expando).annotations({ title: 'Optional Ref to an Expando (DXN Input)' })),
|
|
249
254
|
});
|
|
250
255
|
|
|
251
256
|
const RefStory = ({ values: initialValues }: FormProps<any>) => {
|
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import { type Schema } from 'effect';
|
|
5
6
|
import React, { type ReactElement, useEffect, useMemo, useRef } from 'react';
|
|
6
7
|
|
|
7
|
-
import { type BaseObject, type
|
|
8
|
+
import { type BaseObject, type PropertyKey } from '@dxos/echo-schema';
|
|
8
9
|
import { type ThemedClassName } from '@dxos/react-ui';
|
|
9
10
|
import { mx } from '@dxos/react-ui-theme';
|
|
10
11
|
import { type SchemaProperty } from '@dxos/schema';
|
|
@@ -20,7 +21,7 @@ export type PropsFilter<T extends BaseObject> = (props: SchemaProperty<T>[]) =>
|
|
|
20
21
|
|
|
21
22
|
export type ComponentLookup = (args: {
|
|
22
23
|
prop: string;
|
|
23
|
-
schema:
|
|
24
|
+
schema: Schema.Schema<any>;
|
|
24
25
|
inputProps: InputProps;
|
|
25
26
|
}) => ReactElement | undefined;
|
|
26
27
|
|
|
@@ -2,11 +2,10 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { pipe } from 'effect';
|
|
5
|
+
import { Schema, SchemaAST, pipe } from 'effect';
|
|
6
6
|
import { capitalize } from 'effect/String';
|
|
7
7
|
import React, { useMemo } from 'react';
|
|
8
8
|
|
|
9
|
-
import { AST, S } from '@dxos/echo-schema';
|
|
10
9
|
import { createJsonPath, findNode, getDiscriminatedType, isDiscriminatedUnion } from '@dxos/effect';
|
|
11
10
|
import { mx } from '@dxos/react-ui-theme';
|
|
12
11
|
import { getSchemaProperties, type SchemaProperty } from '@dxos/schema';
|
|
@@ -51,7 +50,7 @@ export const FormField = ({
|
|
|
51
50
|
|
|
52
51
|
const FoundComponent = lookupComponent?.({
|
|
53
52
|
prop: name,
|
|
54
|
-
schema:
|
|
53
|
+
schema: Schema.make(ast),
|
|
55
54
|
inputProps: {
|
|
56
55
|
type,
|
|
57
56
|
format,
|
|
@@ -140,14 +139,14 @@ export const FormField = ({
|
|
|
140
139
|
const baseNode = findNode(ast, isDiscriminatedUnion);
|
|
141
140
|
const typeLiteral = baseNode
|
|
142
141
|
? getDiscriminatedType(baseNode, inputProps.getValue() as any)
|
|
143
|
-
: findNode(ast,
|
|
142
|
+
: findNode(ast, SchemaAST.isTypeLiteral);
|
|
144
143
|
|
|
145
144
|
if (typeLiteral) {
|
|
146
145
|
return (
|
|
147
146
|
<div role='none'>
|
|
148
147
|
{!inline && <h3 className='text-lg mbs-2 mbe-1'>{label}</h3>}
|
|
149
148
|
<FormFields
|
|
150
|
-
schema={
|
|
149
|
+
schema={Schema.make(typeLiteral)}
|
|
151
150
|
path={path}
|
|
152
151
|
readonly={readonly}
|
|
153
152
|
onQueryRefOptions={onQueryRefOptions}
|
|
@@ -163,7 +162,7 @@ export const FormField = ({
|
|
|
163
162
|
};
|
|
164
163
|
|
|
165
164
|
export type FormContentProps = {
|
|
166
|
-
schema:
|
|
165
|
+
schema: Schema.Schema.All;
|
|
167
166
|
path?: (string | number)[];
|
|
168
167
|
filter?: (props: SchemaProperty<any>[]) => SchemaProperty<any>[];
|
|
169
168
|
sort?: string[];
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import { type SchemaAST } from 'effect';
|
|
5
6
|
import React, { useEffect, useState } from 'react';
|
|
6
7
|
|
|
7
8
|
import {
|
|
8
|
-
type AST,
|
|
9
9
|
Expando,
|
|
10
10
|
getTypeAnnotation,
|
|
11
11
|
Ref,
|
|
@@ -25,7 +25,7 @@ import { type FormInputStateProps } from './FormContext';
|
|
|
25
25
|
export type QueryRefOptions = (type: TypeAnnotation) => MaybePromise<{ dxn: DXN; label?: string }[]>;
|
|
26
26
|
|
|
27
27
|
type RefFieldProps = {
|
|
28
|
-
ast:
|
|
28
|
+
ast: SchemaAST.AST;
|
|
29
29
|
type: SimpleType;
|
|
30
30
|
label: string;
|
|
31
31
|
readonly?: boolean;
|
|
@@ -5,9 +5,10 @@
|
|
|
5
5
|
import '@dxos-theme';
|
|
6
6
|
|
|
7
7
|
import { type Meta, type StoryObj } from '@storybook/react';
|
|
8
|
+
import { Schema } from 'effect';
|
|
8
9
|
import React, { useState } from 'react';
|
|
9
10
|
|
|
10
|
-
import {
|
|
11
|
+
import { SelectOptionSchema, type SelectOption } from '@dxos/echo-schema';
|
|
11
12
|
import { withLayout, withTheme } from '@dxos/storybook-utils';
|
|
12
13
|
|
|
13
14
|
import { SelectOptionInput } from './SelectOptionsInput';
|
|
@@ -15,9 +16,9 @@ import translations from '../../../translations';
|
|
|
15
16
|
import { TestLayout, TestPanel } from '../../testing';
|
|
16
17
|
import { Form } from '../Form';
|
|
17
18
|
|
|
18
|
-
const schema =
|
|
19
|
-
options:
|
|
20
|
-
}).pipe(
|
|
19
|
+
const schema = Schema.Struct({
|
|
20
|
+
options: Schema.Array(SelectOptionSchema).pipe(Schema.mutable),
|
|
21
|
+
}).pipe(Schema.mutable);
|
|
21
22
|
|
|
22
23
|
const DefaultStory = () => {
|
|
23
24
|
const [values, setValues] = useState<{ options: SelectOption[] }>({
|
|
@@ -5,9 +5,10 @@
|
|
|
5
5
|
import '@dxos-theme';
|
|
6
6
|
|
|
7
7
|
import { type Meta, type StoryObj } from '@storybook/react';
|
|
8
|
+
import { Schema } from 'effect';
|
|
8
9
|
import React, { useCallback, useMemo, useState } from 'react';
|
|
9
10
|
|
|
10
|
-
import { Format, type EchoSchema,
|
|
11
|
+
import { Format, type EchoSchema, toJsonSchema, TypedObject } from '@dxos/echo-schema';
|
|
11
12
|
import { Filter, useQuery, useSpace } from '@dxos/react-client/echo';
|
|
12
13
|
import { withClientProvider } from '@dxos/react-client/testing';
|
|
13
14
|
import { useAsyncEffect } from '@dxos/react-ui';
|
|
@@ -26,7 +27,7 @@ const DefaultStory = () => {
|
|
|
26
27
|
useAsyncEffect(async () => {
|
|
27
28
|
if (space) {
|
|
28
29
|
class TestSchema extends TypedObject({ typename: 'example.com/type/Test', version: '0.1.0' })({
|
|
29
|
-
name:
|
|
30
|
+
name: Schema.String,
|
|
30
31
|
email: Format.Email,
|
|
31
32
|
salary: Format.Currency(),
|
|
32
33
|
}) {}
|
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import { Schema, SchemaAST } from 'effect';
|
|
5
6
|
import React, { useCallback, useMemo, useState } from 'react';
|
|
6
7
|
|
|
7
8
|
import { type SchemaRegistry } from '@dxos/echo-db';
|
|
8
|
-
import {
|
|
9
|
+
import { Format, type BaseSchema, type JsonProp } from '@dxos/echo-schema';
|
|
9
10
|
import { invariant } from '@dxos/invariant';
|
|
10
11
|
import { IconButton, type ThemedClassName, useTranslation } from '@dxos/react-ui';
|
|
11
12
|
import { List } from '@dxos/react-ui-list';
|
|
@@ -18,16 +19,16 @@ import { Form } from '../Form';
|
|
|
18
19
|
|
|
19
20
|
const grid = 'grid grid-cols-[32px_1fr_32px] min-bs-[2.5rem]';
|
|
20
21
|
|
|
21
|
-
const ViewMetaSchema =
|
|
22
|
-
name:
|
|
23
|
-
[
|
|
22
|
+
const ViewMetaSchema = Schema.Struct({
|
|
23
|
+
name: Schema.String.annotations({
|
|
24
|
+
[SchemaAST.TitleAnnotationId]: 'View',
|
|
24
25
|
}),
|
|
25
26
|
typename: Format.URL.annotations({
|
|
26
|
-
[
|
|
27
|
+
[SchemaAST.TitleAnnotationId]: 'Typename',
|
|
27
28
|
}),
|
|
28
|
-
}).pipe(
|
|
29
|
+
}).pipe(Schema.mutable);
|
|
29
30
|
|
|
30
|
-
type ViewMetaType =
|
|
31
|
+
type ViewMetaType = Schema.Schema.Type<typeof ViewMetaSchema>;
|
|
31
32
|
|
|
32
33
|
export type ViewEditorProps = ThemedClassName<{
|
|
33
34
|
schema: BaseSchema;
|
|
@@ -156,7 +157,7 @@ export const ViewEditor = ({
|
|
|
156
157
|
|
|
157
158
|
<List.Root<FieldType>
|
|
158
159
|
items={view.fields}
|
|
159
|
-
isItem={
|
|
160
|
+
isItem={Schema.is(FieldSchema)}
|
|
160
161
|
getId={(field) => field.id}
|
|
161
162
|
onMove={schema.readonly ? undefined : handleMove}
|
|
162
163
|
>
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { SchemaAST
|
|
5
|
+
import { SchemaAST, type Schema, Option, pipe } from 'effect';
|
|
6
6
|
import React, { useState } from 'react';
|
|
7
7
|
|
|
8
8
|
import { findProperty } from '@dxos/effect';
|
|
@@ -13,7 +13,7 @@ import { type ViewType, getFieldValue, setFieldValue } from '@dxos/schema';
|
|
|
13
13
|
export type DeprecatedFormProps<T extends {} = {}> = ThemedClassName<{
|
|
14
14
|
view: ViewType;
|
|
15
15
|
object: T;
|
|
16
|
-
schema?:
|
|
16
|
+
schema?: Schema.Schema<T>;
|
|
17
17
|
readonly?: boolean;
|
|
18
18
|
}>;
|
|
19
19
|
|
|
@@ -31,16 +31,16 @@ export const DeprecatedForm = <T extends {} = {}>({
|
|
|
31
31
|
<div role='none' className={mx('flex flex-col w-full gap-2 p-2', classNames)}>
|
|
32
32
|
{view.fields.map((field) => {
|
|
33
33
|
const prop = schema && findProperty(schema, field.path);
|
|
34
|
-
const title = (prop && pipe(
|
|
35
|
-
const description = (prop && pipe(
|
|
34
|
+
const title = (prop && pipe(SchemaAST.getTitleAnnotation(prop), Option.getOrUndefined)) ?? '';
|
|
35
|
+
const description = (prop && pipe(SchemaAST.getDescriptionAnnotation(prop), Option.getOrUndefined)) ?? title;
|
|
36
36
|
// const format =
|
|
37
|
-
// (prop && (getPatternAnnotation(prop) ?? (
|
|
37
|
+
// (prop && (getPatternAnnotation(prop) ?? (SchemaAST.isNumberKeyword(prop) && RealNumberFormat))) || undefined;
|
|
38
38
|
|
|
39
39
|
//
|
|
40
40
|
// Boolean
|
|
41
41
|
//
|
|
42
42
|
|
|
43
|
-
if (prop &&
|
|
43
|
+
if (prop && SchemaAST.isBooleanKeyword(prop)) {
|
|
44
44
|
const value = object && getFieldValue(object, field);
|
|
45
45
|
const onChange = (checked: boolean) => {
|
|
46
46
|
setFieldValue(object, field, checked);
|
package/src/hooks/index.ts
CHANGED
package/src/hooks/useForm.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { SchemaAST
|
|
5
|
+
import { SchemaAST, type Schema } from 'effect';
|
|
6
6
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
7
7
|
|
|
8
8
|
import { type BaseObject, getValue, setValue } from '@dxos/echo-schema';
|
|
@@ -45,7 +45,7 @@ export interface FormOptions<T extends BaseObject> {
|
|
|
45
45
|
/**
|
|
46
46
|
* Effect schema (Type literal).
|
|
47
47
|
*/
|
|
48
|
-
schema:
|
|
48
|
+
schema: Schema.Schema<T, any>;
|
|
49
49
|
|
|
50
50
|
/**
|
|
51
51
|
* Initial values (which may not pass validation).
|
|
@@ -90,7 +90,7 @@ export const useForm = <T extends BaseObject>({
|
|
|
90
90
|
onValid,
|
|
91
91
|
onSave,
|
|
92
92
|
}: FormOptions<T>): FormHandler<T> => {
|
|
93
|
-
invariant(
|
|
93
|
+
invariant(SchemaAST.isTypeLiteral(schema.ast));
|
|
94
94
|
|
|
95
95
|
const [values, setValues] = useState<Partial<T>>(initialValues);
|
|
96
96
|
useEffect(() => {
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { useCallback } from 'react';
|
|
6
|
+
|
|
7
|
+
import { getDXN, type TypeAnnotation } from '@dxos/echo-schema';
|
|
8
|
+
import { Filter, type Space } from '@dxos/react-client/echo';
|
|
9
|
+
import { isNonNullable } from '@dxos/util';
|
|
10
|
+
|
|
11
|
+
import { type QueryRefOptions } from '../components';
|
|
12
|
+
|
|
13
|
+
type UseRefQueryLookupProps = {
|
|
14
|
+
space?: Space;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const useRefQueryLookupHandler = ({ space }: UseRefQueryLookupProps): QueryRefOptions => {
|
|
18
|
+
const handleRefQueryLookup = useCallback(
|
|
19
|
+
async (typeInfo: TypeAnnotation) => {
|
|
20
|
+
if (!space) {
|
|
21
|
+
return [];
|
|
22
|
+
}
|
|
23
|
+
const query = space.db.query(Filter.typename(typeInfo.typename));
|
|
24
|
+
const { objects } = await query.run();
|
|
25
|
+
|
|
26
|
+
return objects
|
|
27
|
+
.map((object) => {
|
|
28
|
+
const dxn = getDXN(object);
|
|
29
|
+
if (!dxn) {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// TODO(Zaymon): Better fallback object names?
|
|
34
|
+
const item = { dxn, label: object?.name ?? object?.id ?? '' };
|
|
35
|
+
return item;
|
|
36
|
+
})
|
|
37
|
+
.filter(isNonNullable);
|
|
38
|
+
},
|
|
39
|
+
[space],
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
return handleRefQueryLookup;
|
|
43
|
+
};
|