@dxos/react-ui-form 0.8.2-main.fbd8ed0 → 0.8.2-staging.7ac8446
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 +537 -846
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +506 -807
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +537 -846
- 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 → ControlSection.d.ts} +5 -8
- package/dist/types/src/components/ControlSection.d.ts.map +1 -0
- 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 +4 -6
- package/dist/types/src/components/Form/Form.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.stories.d.ts +34 -37
- 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 +11 -14
- 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/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 +2 -2
- 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/index.d.ts.map +1 -1
- package/dist/types/src/components/testing.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +0 -2
- 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/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 +0 -2
- package/dist/types/src/util/index.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +25 -26
- package/src/components/{ControlSection/ControlSection.tsx → ControlSection.tsx} +14 -38
- package/src/components/FieldEditor/FieldEditor.stories.tsx +1 -1
- package/src/components/Form/ArrayField.tsx +17 -13
- package/src/components/Form/Defaults.tsx +1 -4
- package/src/components/Form/Form.stories.tsx +43 -92
- package/src/components/Form/Form.tsx +3 -7
- package/src/components/Form/FormContent.tsx +19 -90
- package/src/components/Form/FormContext.tsx +3 -13
- package/src/components/Form/Input.tsx +9 -3
- package/src/components/Form/custom/GeoPointInput.tsx +2 -2
- package/src/components/Form/custom/SelectOptionsInput.stories.tsx +5 -6
- package/src/components/Form/custom/SelectOptionsInput.tsx +2 -2
- package/src/components/Form/factory.tsx +1 -1
- package/src/components/Form/index.ts +1 -0
- package/src/components/ViewEditor/ViewEditor.stories.tsx +4 -5
- package/src/components/ViewEditor/ViewEditor.tsx +20 -23
- package/src/components/deprecated/Form.stories.tsx +6 -6
- package/src/components/deprecated/Form.tsx +6 -6
- package/src/components/deprecated/FormInput.tsx +1 -1
- package/src/components/index.ts +0 -1
- package/src/hooks/index.ts +1 -3
- package/src/hooks/useForm.ts +3 -4
- package/src/util/formatting.ts +3 -15
- package/src/util/index.ts +1 -3
- package/dist/types/src/components/ControlSection/ControlSection.d.ts.map +0 -1
- package/dist/types/src/components/ControlSection/ControlSection.stories.d.ts +0 -8
- package/dist/types/src/components/ControlSection/ControlSection.stories.d.ts.map +0 -1
- package/dist/types/src/components/ControlSection/index.d.ts +0 -2
- package/dist/types/src/components/ControlSection/index.d.ts.map +0 -1
- package/dist/types/src/components/Form/RefField.d.ts +0 -12
- package/dist/types/src/components/Form/RefField.d.ts.map +0 -1
- package/dist/types/src/hooks/useQueryRefOptions.d.ts +0 -23
- package/dist/types/src/hooks/useQueryRefOptions.d.ts.map +0 -1
- package/dist/types/src/hooks/useRefQueryLookupHandler.d.ts +0 -8
- package/dist/types/src/hooks/useRefQueryLookupHandler.d.ts.map +0 -1
- package/dist/types/src/util/refs.d.ts +0 -9
- package/dist/types/src/util/refs.d.ts.map +0 -1
- package/dist/types/src/util/schema.d.ts +0 -3
- package/dist/types/src/util/schema.d.ts.map +0 -1
- package/src/components/ControlSection/ControlSection.stories.tsx +0 -29
- package/src/components/ControlSection/index.ts +0 -5
- package/src/components/Form/RefField.tsx +0 -197
- package/src/hooks/useQueryRefOptions.ts +0 -53
- package/src/hooks/useRefQueryLookupHandler.ts +0 -41
- package/src/util/refs.ts +0 -38
- package/src/util/schema.ts +0 -14
package/src/util/formatting.ts
CHANGED
|
@@ -64,25 +64,13 @@ export const formatForDisplay = ({ type, format, value, locale = undefined }: Va
|
|
|
64
64
|
});
|
|
65
65
|
}
|
|
66
66
|
case FormatEnum.Date: {
|
|
67
|
-
|
|
68
|
-
return formatDate(new Date(value as number), 'yyyy-MM-dd');
|
|
69
|
-
} catch (error) {
|
|
70
|
-
return 'Invalid Date';
|
|
71
|
-
}
|
|
67
|
+
return formatDate(new Date(value as number), 'yyyy-MM-dd');
|
|
72
68
|
}
|
|
73
69
|
case FormatEnum.Time: {
|
|
74
|
-
|
|
75
|
-
return formatDate(new Date(value as number), 'HH:mm:ss');
|
|
76
|
-
} catch (error) {
|
|
77
|
-
return 'Invalid Time';
|
|
78
|
-
}
|
|
70
|
+
return formatDate(new Date(value as number), 'HH:mm:ss');
|
|
79
71
|
}
|
|
80
72
|
case FormatEnum.DateTime: {
|
|
81
|
-
|
|
82
|
-
return formatDate(new Date(value as number), 'yyyy-MM-dd HH:mm:ss');
|
|
83
|
-
} catch (error) {
|
|
84
|
-
return 'Invalid DateTime';
|
|
85
|
-
}
|
|
73
|
+
return formatDate(new Date(value as number), 'yyyy-MM-dd HH:mm:ss');
|
|
86
74
|
}
|
|
87
75
|
case FormatEnum.GeoPoint: {
|
|
88
76
|
if (value === null || value === undefined) {
|
package/src/util/index.ts
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ControlSection.d.ts","sourceRoot":"","sources":["../../../../../src/components/ControlSection/ControlSection.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,EAAE,KAAK,wBAAwB,EAAE,KAAK,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAErF,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,KAAK,EAEV,KAAK,eAAe,EAGrB,MAAM,gBAAgB,CAAC;AAKxB,MAAM,MAAM,gBAAgB,GAAG,eAAe,CAAC,wBAAwB,CAAC,KAAK,CAAC,CAAC,CAAC;AAEhF,eAAO,MAAM,WAAW,GAAI,oCAAoC,gBAAgB,sBAM/E,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,iBAAiB,CAAC;IAClD,KAAK,EAAE,KAAK,CAAC;IACb,WAAW,CAAC,EAAE,KAAK,CAAC;CACrB,CAAC,CAAC;AAEH,eAAO,MAAM,cAAc,GAAI,kCAAkC,mBAAmB,sBAOnF,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,wBAAwB,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,sBAUlG,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,0BAA0B,WAAW,sBAEvE,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,eAAe,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC,CAAC;AAEvE,eAAO,MAAM,YAAY,GAAI,0BAA0B,iBAAiB,sBAOvE,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,cAAc,iBAAiB,sBAO3D,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,iBAAiB,CAAC;IAC/C,KAAK,EAAE,KAAK,CAAC;IACb,WAAW,CAAC,EAAE,KAAK,CAAC;CACrB,CAAC,CAAC;AAEH,eAAO,MAAM,kBAAkB,iHACiF,CAAC;AAKjH,eAAO,MAAM,WAAW,GAAI,kCAAkC,gBAAgB,sBAY7E,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,kCAAkC,gBAAgB,sBAoBlF,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,kCAAkC,gBAAgB,sBAUlF,CAAC"}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import '@dxos-theme';
|
|
2
|
-
import { type Meta, type StoryObj } from '@storybook/react';
|
|
3
|
-
import { type ControlSectionProps } from './ControlSection';
|
|
4
|
-
declare const meta: Meta<ControlSectionProps>;
|
|
5
|
-
export default meta;
|
|
6
|
-
type Story = StoryObj<ControlSectionProps>;
|
|
7
|
-
export declare const Default: Story;
|
|
8
|
-
//# sourceMappingURL=ControlSection.stories.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ControlSection.stories.d.ts","sourceRoot":"","sources":["../../../../../src/components/ControlSection/ControlSection.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,aAAa,CAAC;AAErB,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAI5D,OAAO,EAAkB,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAG5E,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,mBAAmB,CAOnC,CAAC;AAEF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAC,mBAAmB,CAAC,CAAC;AAE3C,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/components/ControlSection/index.ts"],"names":[],"mappings":"AAIA,cAAc,kBAAkB,CAAC"}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { type SchemaAST } from 'effect';
|
|
2
|
-
import React from 'react';
|
|
3
|
-
import { type InputProps } from './Input';
|
|
4
|
-
import { type QueryRefOptions } from '../../hooks';
|
|
5
|
-
type RefFieldProps = InputProps & {
|
|
6
|
-
ast?: SchemaAST.AST;
|
|
7
|
-
array?: boolean;
|
|
8
|
-
onQueryRefOptions?: QueryRefOptions;
|
|
9
|
-
};
|
|
10
|
-
export declare const RefField: ({ type, label, disabled, placeholder, inputOnly, array, ast, getValue, onBlur, onQueryRefOptions, onValueChange, ...restInputProps }: RefFieldProps) => React.JSX.Element | null;
|
|
11
|
-
export {};
|
|
12
|
-
//# sourceMappingURL=RefField.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"RefField.d.ts","sourceRoot":"","sources":["../../../../../src/components/Form/RefField.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,KAAgD,MAAM,OAAO,CAAC;AAgBrE,OAAO,EAAe,KAAK,UAAU,EAAE,MAAM,SAAS,CAAC;AACvD,OAAO,EAAE,KAAK,eAAe,EAAsB,MAAM,aAAa,CAAC;AAEvE,KAAK,aAAa,GAAG,UAAU,GAAG;IAChC,GAAG,CAAC,EAAE,SAAS,CAAC,GAAG,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,iBAAiB,CAAC,EAAE,eAAe,CAAC;CACrC,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAI,sIAatB,aAAa,6BA0Gf,CAAC"}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { type TypeAnnotation } from '@dxos/echo-schema';
|
|
2
|
-
import { type DXN } from '@dxos/keys';
|
|
3
|
-
import { type TagPickerItemData } from '@dxos/react-ui-tag-picker';
|
|
4
|
-
import { type MaybePromise } from '@dxos/util';
|
|
5
|
-
export type RefOption = {
|
|
6
|
-
dxn: DXN;
|
|
7
|
-
label?: string;
|
|
8
|
-
};
|
|
9
|
-
export type QueryRefOptions = (type: TypeAnnotation) => MaybePromise<RefOption[]>;
|
|
10
|
-
type UseQueryRefOptionsProps = {
|
|
11
|
-
refTypeInfo: TypeAnnotation | undefined;
|
|
12
|
-
onQueryRefOptions?: QueryRefOptions;
|
|
13
|
-
};
|
|
14
|
-
/**
|
|
15
|
-
* Hook to query reference options based on type information.
|
|
16
|
-
* Used internally within forms to fetch and format reference options for reference fields.
|
|
17
|
-
*/
|
|
18
|
-
export declare const useQueryRefOptions: ({ refTypeInfo, onQueryRefOptions }: UseQueryRefOptionsProps) => {
|
|
19
|
-
options: TagPickerItemData[];
|
|
20
|
-
loading: boolean;
|
|
21
|
-
};
|
|
22
|
-
export {};
|
|
23
|
-
//# sourceMappingURL=useQueryRefOptions.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useQueryRefOptions.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useQueryRefOptions.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,MAAM,MAAM,SAAS,GAAG;IAAE,GAAG,EAAE,GAAG,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AACrD,MAAM,MAAM,eAAe,GAAG,CAAC,IAAI,EAAE,cAAc,KAAK,YAAY,CAAC,SAAS,EAAE,CAAC,CAAC;AAElF,KAAK,uBAAuB,GAAG;IAAE,WAAW,EAAE,cAAc,GAAG,SAAS,CAAC;IAAC,iBAAiB,CAAC,EAAE,eAAe,CAAA;CAAE,CAAC;AAEhH;;;GAGG;AACH,eAAO,MAAM,kBAAkB,GAAI,oCAAoC,uBAAuB;;;CA+B7F,CAAC"}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { type Space } from '@dxos/react-client/echo';
|
|
2
|
-
import { type QueryRefOptions } from './useQueryRefOptions';
|
|
3
|
-
type UseRefQueryLookupProps = {
|
|
4
|
-
space?: Space;
|
|
5
|
-
};
|
|
6
|
-
export declare const useRefQueryLookupHandler: ({ space }: UseRefQueryLookupProps) => QueryRefOptions;
|
|
7
|
-
export {};
|
|
8
|
-
//# sourceMappingURL=useRefQueryLookupHandler.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
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,sBAAsB,CAAC;AAE5D,KAAK,sBAAsB,GAAG;IAAE,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC;AAEhD,eAAO,MAAM,wBAAwB,GAAI,WAAW,sBAAsB,KAAG,eA0B5E,CAAC"}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { type SchemaAST } from 'effect';
|
|
2
|
-
import { type SchemaProperty } from '@dxos/schema';
|
|
3
|
-
type RefProps = {
|
|
4
|
-
ast: SchemaAST.AST;
|
|
5
|
-
isArray: boolean;
|
|
6
|
-
};
|
|
7
|
-
export declare const getRefProps: (property: SchemaProperty<any>) => RefProps | undefined;
|
|
8
|
-
export {};
|
|
9
|
-
//# sourceMappingURL=refs.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"refs.d.ts","sourceRoot":"","sources":["../../../../src/util/refs.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,QAAQ,CAAC;AAIxC,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAInD,KAAK,QAAQ,GAAG;IACd,GAAG,EAAE,SAAS,CAAC,GAAG,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,UAAU,cAAc,CAAC,GAAG,CAAC,KAAG,QAAQ,GAAG,SAoBtE,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../../src/util/schema.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAInC,eAAO,MAAM,oBAAoB,GAAI,KAAK,SAAS,CAAC,GAAG,8BAKtD,CAAC"}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2024 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import '@dxos-theme';
|
|
6
|
-
|
|
7
|
-
import { type Meta, type StoryObj } from '@storybook/react';
|
|
8
|
-
|
|
9
|
-
import { withLayout, withTheme } from '@dxos/storybook-utils';
|
|
10
|
-
|
|
11
|
-
import { ControlSection, type ControlSectionProps } from './ControlSection';
|
|
12
|
-
import translations from '../../translations';
|
|
13
|
-
|
|
14
|
-
const meta: Meta<ControlSectionProps> = {
|
|
15
|
-
title: 'ui/react-ui-form/ControlSection',
|
|
16
|
-
component: ControlSection,
|
|
17
|
-
decorators: [withLayout(), withTheme],
|
|
18
|
-
parameters: {
|
|
19
|
-
translations,
|
|
20
|
-
},
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
export default meta;
|
|
24
|
-
|
|
25
|
-
type Story = StoryObj<ControlSectionProps>;
|
|
26
|
-
|
|
27
|
-
export const Default: Story = {
|
|
28
|
-
args: {},
|
|
29
|
-
};
|
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2025 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import { type SchemaAST } from 'effect';
|
|
6
|
-
import React, { useCallback, useMemo, type FocusEvent } from 'react';
|
|
7
|
-
|
|
8
|
-
import {
|
|
9
|
-
Expando,
|
|
10
|
-
getTypeAnnotation,
|
|
11
|
-
Ref,
|
|
12
|
-
ReferenceAnnotationId,
|
|
13
|
-
type ReferenceAnnotationValue,
|
|
14
|
-
} from '@dxos/echo-schema';
|
|
15
|
-
import { findAnnotation } from '@dxos/effect';
|
|
16
|
-
import { DXN } from '@dxos/keys';
|
|
17
|
-
import { Input } from '@dxos/react-ui';
|
|
18
|
-
import { TagPicker, type TagPickerMode, type TagPickerItemData } from '@dxos/react-ui-tag-picker';
|
|
19
|
-
import { isNonNullable } from '@dxos/util';
|
|
20
|
-
|
|
21
|
-
import { TextInput } from './Defaults';
|
|
22
|
-
import { InputHeader, type InputProps } from './Input';
|
|
23
|
-
import { type QueryRefOptions, useQueryRefOptions } from '../../hooks';
|
|
24
|
-
|
|
25
|
-
type RefFieldProps = InputProps & {
|
|
26
|
-
ast?: SchemaAST.AST;
|
|
27
|
-
array?: boolean;
|
|
28
|
-
onQueryRefOptions?: QueryRefOptions;
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
export const RefField = ({
|
|
32
|
-
type,
|
|
33
|
-
label,
|
|
34
|
-
disabled,
|
|
35
|
-
placeholder,
|
|
36
|
-
inputOnly,
|
|
37
|
-
array,
|
|
38
|
-
ast,
|
|
39
|
-
getValue,
|
|
40
|
-
onBlur,
|
|
41
|
-
onQueryRefOptions,
|
|
42
|
-
onValueChange,
|
|
43
|
-
...restInputProps
|
|
44
|
-
}: RefFieldProps) => {
|
|
45
|
-
const refTypeInfo = useMemo(
|
|
46
|
-
() => (ast ? findAnnotation<ReferenceAnnotationValue>(ast, ReferenceAnnotationId) : undefined),
|
|
47
|
-
[ast],
|
|
48
|
-
);
|
|
49
|
-
const { options: availableOptions, loading: _loading } = useQueryRefOptions({ refTypeInfo, onQueryRefOptions });
|
|
50
|
-
|
|
51
|
-
if ((refTypeInfo && refTypeInfo?.typename === getTypeAnnotation(Expando)?.typename) || !onQueryRefOptions) {
|
|
52
|
-
// If ref type is expando, fall back to taking a DXN in string format.
|
|
53
|
-
return (
|
|
54
|
-
<RefFieldFallback
|
|
55
|
-
{...{ type, label, placeholder, disabled, inputOnly, getValue, onBlur, onValueChange, ...restInputProps }}
|
|
56
|
-
/>
|
|
57
|
-
);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const handleGetValue = useCallback((): TagPickerItemData[] => {
|
|
61
|
-
const formValue = getValue();
|
|
62
|
-
|
|
63
|
-
const unknownToRefOption = (val: unknown) => {
|
|
64
|
-
if (Ref.isRef(val)) {
|
|
65
|
-
const dxnString = val.dxn.toString();
|
|
66
|
-
const matchingOption = availableOptions.find((option) => option.id === dxnString);
|
|
67
|
-
if (matchingOption) {
|
|
68
|
-
return matchingOption;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
return undefined;
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
if (array && Array.isArray(formValue)) {
|
|
75
|
-
return formValue.map(unknownToRefOption).filter(isNonNullable) ?? [];
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const option = unknownToRefOption(formValue);
|
|
79
|
-
if (option) {
|
|
80
|
-
return [option];
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
return [];
|
|
84
|
-
}, [getValue, availableOptions, array]);
|
|
85
|
-
|
|
86
|
-
const handleSearch = useCallback(
|
|
87
|
-
(text: string, ids: string[]): TagPickerItemData[] =>
|
|
88
|
-
availableOptions
|
|
89
|
-
.filter((option) => !ids.includes(option.id))
|
|
90
|
-
.filter((option) => option.label.toLowerCase().includes(text.toLowerCase()))
|
|
91
|
-
.map((option) => ({ id: option.id, label: option.label, hue: option.hue as any })),
|
|
92
|
-
[availableOptions],
|
|
93
|
-
);
|
|
94
|
-
|
|
95
|
-
const handleUpdate = useCallback(
|
|
96
|
-
(ids: string[]) => {
|
|
97
|
-
if (ids.length === 0) {
|
|
98
|
-
onValueChange('object', undefined);
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const refs = ids
|
|
103
|
-
.map((id) => {
|
|
104
|
-
const item = availableOptions.find((option) => option.id === id);
|
|
105
|
-
if (item) {
|
|
106
|
-
const dxn = DXN.parse(item.id);
|
|
107
|
-
return Ref.fromDXN(dxn);
|
|
108
|
-
}
|
|
109
|
-
return null;
|
|
110
|
-
})
|
|
111
|
-
.filter(isNonNullable);
|
|
112
|
-
|
|
113
|
-
if (array) {
|
|
114
|
-
onValueChange('object', refs);
|
|
115
|
-
} else {
|
|
116
|
-
onValueChange('object', refs[0]);
|
|
117
|
-
}
|
|
118
|
-
},
|
|
119
|
-
[availableOptions, array, onValueChange],
|
|
120
|
-
);
|
|
121
|
-
|
|
122
|
-
const tagPickerMode: TagPickerMode = useMemo(() => (array ? 'multi-select' : 'single-select'), [array]);
|
|
123
|
-
|
|
124
|
-
if (!refTypeInfo) {
|
|
125
|
-
return null;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
const { status, error } = restInputProps.getStatus();
|
|
129
|
-
|
|
130
|
-
return (
|
|
131
|
-
<Input.Root validationValence={status}>
|
|
132
|
-
{!inputOnly && (
|
|
133
|
-
<InputHeader error={error}>
|
|
134
|
-
<Input.Label>{label}</Input.Label>
|
|
135
|
-
</InputHeader>
|
|
136
|
-
)}
|
|
137
|
-
<div data-no-submit>
|
|
138
|
-
<TagPicker
|
|
139
|
-
items={handleGetValue()}
|
|
140
|
-
mode={tagPickerMode}
|
|
141
|
-
onBlur={(event) => onBlur(event as unknown as FocusEvent<HTMLElement>)}
|
|
142
|
-
onUpdate={handleUpdate}
|
|
143
|
-
onSearch={handleSearch}
|
|
144
|
-
classNames='rounded-sm bg-input p-1.5'
|
|
145
|
-
/>
|
|
146
|
-
</div>
|
|
147
|
-
{inputOnly && <Input.DescriptionAndValidation>{error}</Input.DescriptionAndValidation>}
|
|
148
|
-
</Input.Root>
|
|
149
|
-
);
|
|
150
|
-
};
|
|
151
|
-
|
|
152
|
-
const RefFieldFallback = ({
|
|
153
|
-
type,
|
|
154
|
-
label,
|
|
155
|
-
disabled,
|
|
156
|
-
placeholder,
|
|
157
|
-
inputOnly,
|
|
158
|
-
getValue,
|
|
159
|
-
onValueChange,
|
|
160
|
-
...restInputProps
|
|
161
|
-
}: InputProps) => {
|
|
162
|
-
const handleOnValueChange = (_type: any, dxnString: string) => {
|
|
163
|
-
const dxn = DXN.tryParse(dxnString);
|
|
164
|
-
if (dxn) {
|
|
165
|
-
onValueChange?.('object', Ref.fromDXN(dxn));
|
|
166
|
-
} else if (dxnString === '') {
|
|
167
|
-
onValueChange?.('object', undefined);
|
|
168
|
-
} else {
|
|
169
|
-
onValueChange?.('string', dxnString);
|
|
170
|
-
}
|
|
171
|
-
};
|
|
172
|
-
|
|
173
|
-
const handleGetValue = () => {
|
|
174
|
-
const formValue = getValue();
|
|
175
|
-
if (typeof formValue === 'string') {
|
|
176
|
-
return formValue;
|
|
177
|
-
}
|
|
178
|
-
if (Ref.isRef(formValue)) {
|
|
179
|
-
return formValue.dxn.toString();
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
return undefined;
|
|
183
|
-
};
|
|
184
|
-
|
|
185
|
-
return (
|
|
186
|
-
<TextInput
|
|
187
|
-
type={type}
|
|
188
|
-
label={label}
|
|
189
|
-
disabled={disabled}
|
|
190
|
-
placeholder={placeholder}
|
|
191
|
-
inputOnly={inputOnly}
|
|
192
|
-
getValue={handleGetValue as <V>() => V | undefined}
|
|
193
|
-
onValueChange={handleOnValueChange}
|
|
194
|
-
{...restInputProps}
|
|
195
|
-
/>
|
|
196
|
-
);
|
|
197
|
-
};
|
|
@@ -1,53 +0,0 @@
|
|
|
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
|
-
};
|
|
@@ -1,41 +0,0 @@
|
|
|
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/refs.ts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
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
|
-
};
|
package/src/util/schema.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
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
|
-
};
|