@dxos/react-ui-form 0.8.2-main.12df754 → 0.8.2-main.30e4dbb
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 +823 -524
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +661 -372
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +823 -524
- 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 +6 -4
- package/dist/types/src/components/Form/Form.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.stories.d.ts +37 -34
- 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 +14 -11
- package/dist/types/src/components/Form/FormContent.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormContext.d.ts +2 -2
- 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 +12 -0
- package/dist/types/src/components/Form/RefField.d.ts.map +1 -0
- 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 +1 -1
- package/dist/types/src/components/Form/factory.d.ts.map +1 -1
- 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 +2 -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/useQueryRefOptions.d.ts +23 -0
- package/dist/types/src/hooks/useQueryRefOptions.d.ts.map +1 -0
- 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/src/util/index.d.ts +2 -0
- package/dist/types/src/util/index.d.ts.map +1 -1
- package/dist/types/src/util/refs.d.ts +9 -0
- package/dist/types/src/util/refs.d.ts.map +1 -0
- package/dist/types/src/util/schema.d.ts +3 -0
- package/dist/types/src/util/schema.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +26 -25
- package/src/components/ControlSection/ControlSection.stories.tsx +1 -1
- package/src/components/FieldEditor/FieldEditor.stories.tsx +1 -1
- package/src/components/Form/ArrayField.tsx +8 -7
- package/src/components/Form/Defaults.tsx +4 -1
- package/src/components/Form/Form.stories.tsx +92 -43
- package/src/components/Form/Form.tsx +7 -3
- package/src/components/Form/FormContent.tsx +90 -19
- package/src/components/Form/FormContext.tsx +13 -3
- package/src/components/Form/Input.tsx +3 -9
- package/src/components/Form/RefField.tsx +197 -0
- package/src/components/Form/custom/GeoPointInput.tsx +2 -2
- package/src/components/Form/custom/SelectOptionsInput.stories.tsx +6 -5
- package/src/components/Form/custom/SelectOptionsInput.tsx +2 -2
- package/src/components/Form/factory.tsx +1 -1
- package/src/components/Form/index.ts +0 -1
- package/src/components/ViewEditor/ViewEditor.stories.tsx +4 -3
- package/src/components/ViewEditor/ViewEditor.tsx +12 -10
- package/src/components/deprecated/Form.tsx +6 -6
- package/src/hooks/index.ts +3 -1
- package/src/hooks/useForm.ts +3 -3
- package/src/hooks/useQueryRefOptions.ts +53 -0
- package/src/hooks/useRefQueryLookupHandler.ts +41 -0
- package/src/util/formatting.ts +15 -3
- package/src/util/index.ts +3 -1
- package/src/util/refs.ts +38 -0
- package/src/util/schema.ts +14 -0
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,53 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { useEffect, useState } from 'react';
|
|
6
|
+
|
|
7
|
+
import { type TypeAnnotation } from '@dxos/echo-schema';
|
|
8
|
+
import { type DXN } from '@dxos/keys';
|
|
9
|
+
import { log } from '@dxos/log';
|
|
10
|
+
import { type TagPickerItemData } from '@dxos/react-ui-tag-picker';
|
|
11
|
+
import { type MaybePromise } from '@dxos/util';
|
|
12
|
+
|
|
13
|
+
export type RefOption = { dxn: DXN; label?: string };
|
|
14
|
+
export type QueryRefOptions = (type: TypeAnnotation) => MaybePromise<RefOption[]>;
|
|
15
|
+
|
|
16
|
+
type UseQueryRefOptionsProps = { refTypeInfo: TypeAnnotation | undefined; onQueryRefOptions?: QueryRefOptions };
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Hook to query reference options based on type information.
|
|
20
|
+
* Used internally within forms to fetch and format reference options for reference fields.
|
|
21
|
+
*/
|
|
22
|
+
export const useQueryRefOptions = ({ refTypeInfo, onQueryRefOptions }: UseQueryRefOptionsProps) => {
|
|
23
|
+
const [options, setOptions] = useState<TagPickerItemData[]>([]);
|
|
24
|
+
const [loading, setLoading] = useState(false);
|
|
25
|
+
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
if (!refTypeInfo || !onQueryRefOptions) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const fetchOptions = async () => {
|
|
32
|
+
setLoading(true);
|
|
33
|
+
try {
|
|
34
|
+
const fetchedOptions = await onQueryRefOptions(refTypeInfo);
|
|
35
|
+
setOptions(
|
|
36
|
+
fetchedOptions.map((option) => {
|
|
37
|
+
const dxn = option.dxn.toString() as string;
|
|
38
|
+
return { id: dxn, label: option.label ?? dxn, hue: 'neutral' as any };
|
|
39
|
+
}),
|
|
40
|
+
);
|
|
41
|
+
} catch (error) {
|
|
42
|
+
log.error('Failed to fetch ref options:', error);
|
|
43
|
+
setOptions([]);
|
|
44
|
+
} finally {
|
|
45
|
+
setLoading(false);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
void fetchOptions();
|
|
50
|
+
}, [refTypeInfo, onQueryRefOptions]);
|
|
51
|
+
|
|
52
|
+
return { options, loading };
|
|
53
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
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 './useQueryRefOptions';
|
|
12
|
+
|
|
13
|
+
type UseRefQueryLookupProps = { space?: Space };
|
|
14
|
+
|
|
15
|
+
export const useRefQueryLookupHandler = ({ space }: UseRefQueryLookupProps): QueryRefOptions => {
|
|
16
|
+
const handleRefQueryLookup = useCallback(
|
|
17
|
+
async (typeInfo: TypeAnnotation) => {
|
|
18
|
+
if (!space) {
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
21
|
+
const query = space.db.query(Filter.typename(typeInfo.typename));
|
|
22
|
+
const { objects } = await query.run();
|
|
23
|
+
|
|
24
|
+
return objects
|
|
25
|
+
.map((object) => {
|
|
26
|
+
const dxn = getDXN(object);
|
|
27
|
+
if (!dxn) {
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// TODO(Zaymon): Better fallback object names?
|
|
32
|
+
const item = { dxn, label: object?.name ?? object?.id ?? '' };
|
|
33
|
+
return item;
|
|
34
|
+
})
|
|
35
|
+
.filter(isNonNullable);
|
|
36
|
+
},
|
|
37
|
+
[space],
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
return handleRefQueryLookup;
|
|
41
|
+
};
|
package/src/util/formatting.ts
CHANGED
|
@@ -64,13 +64,25 @@ export const formatForDisplay = ({ type, format, value, locale = undefined }: Va
|
|
|
64
64
|
});
|
|
65
65
|
}
|
|
66
66
|
case FormatEnum.Date: {
|
|
67
|
-
|
|
67
|
+
try {
|
|
68
|
+
return formatDate(new Date(value as number), 'yyyy-MM-dd');
|
|
69
|
+
} catch (error) {
|
|
70
|
+
return 'Invalid Date';
|
|
71
|
+
}
|
|
68
72
|
}
|
|
69
73
|
case FormatEnum.Time: {
|
|
70
|
-
|
|
74
|
+
try {
|
|
75
|
+
return formatDate(new Date(value as number), 'HH:mm:ss');
|
|
76
|
+
} catch (error) {
|
|
77
|
+
return 'Invalid Time';
|
|
78
|
+
}
|
|
71
79
|
}
|
|
72
80
|
case FormatEnum.DateTime: {
|
|
73
|
-
|
|
81
|
+
try {
|
|
82
|
+
return formatDate(new Date(value as number), 'yyyy-MM-dd HH:mm:ss');
|
|
83
|
+
} catch (error) {
|
|
84
|
+
return 'Invalid DateTime';
|
|
85
|
+
}
|
|
74
86
|
}
|
|
75
87
|
case FormatEnum.GeoPoint: {
|
|
76
88
|
if (value === null || value === undefined) {
|
package/src/util/index.ts
CHANGED
package/src/util/refs.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type SchemaAST } from 'effect';
|
|
6
|
+
|
|
7
|
+
import { FormatEnum, ReferenceAnnotationId } from '@dxos/echo-schema';
|
|
8
|
+
import { findAnnotation } from '@dxos/effect';
|
|
9
|
+
import { type SchemaProperty } from '@dxos/schema';
|
|
10
|
+
|
|
11
|
+
import { findArrayElementType } from './schema';
|
|
12
|
+
|
|
13
|
+
type RefProps = {
|
|
14
|
+
ast: SchemaAST.AST;
|
|
15
|
+
isArray: boolean;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const getRefProps = (property: SchemaProperty<any>): RefProps | undefined => {
|
|
19
|
+
const { ast, format, array } = property;
|
|
20
|
+
|
|
21
|
+
// Direct reference.
|
|
22
|
+
if (format === FormatEnum.Ref) {
|
|
23
|
+
return { ast, isArray: false };
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Array of references.
|
|
27
|
+
if (array) {
|
|
28
|
+
const elementType = findArrayElementType(ast);
|
|
29
|
+
if (elementType) {
|
|
30
|
+
const annotation = findAnnotation(elementType, ReferenceAnnotationId);
|
|
31
|
+
if (annotation) {
|
|
32
|
+
return { ast: elementType, isArray: true };
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return undefined;
|
|
38
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { SchemaAST } from 'effect';
|
|
6
|
+
|
|
7
|
+
import { findNode } from '@dxos/effect';
|
|
8
|
+
|
|
9
|
+
export const findArrayElementType = (ast: SchemaAST.AST) => {
|
|
10
|
+
const tupleType = findNode(ast, SchemaAST.isTupleType);
|
|
11
|
+
const elementType = (tupleType as SchemaAST.TupleType | undefined)?.rest[0]?.type;
|
|
12
|
+
|
|
13
|
+
return elementType;
|
|
14
|
+
};
|