@dxos/react-ui-form 0.8.2-main.f11618f → 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 +102 -253
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +161 -312
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +102 -253
- 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/Form/ArrayField.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.d.ts +1 -3
- package/dist/types/src/components/Form/Form.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.stories.d.ts +2 -4
- package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormContent.d.ts +10 -13
- 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/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/index.d.ts.map +1 -1
- package/dist/types/src/util/formatting.d.ts.map +1 -1
- package/package.json +24 -24
- package/src/components/{ControlSection/ControlSection.tsx → ControlSection.tsx} +14 -38
- package/src/components/Form/ArrayField.tsx +1 -3
- package/src/components/Form/Form.stories.tsx +5 -48
- package/src/components/Form/Form.tsx +0 -4
- package/src/components/Form/FormContent.tsx +15 -59
- package/src/components/Form/FormContext.tsx +2 -10
- package/src/components/Form/custom/GeoPointInput.tsx +2 -2
- package/src/components/Form/custom/SelectOptionsInput.tsx +2 -2
- package/src/components/deprecated/Form.stories.tsx +6 -6
- package/src/components/deprecated/FormInput.tsx +1 -1
- package/src/components/index.ts +0 -1
- package/src/util/formatting.ts +3 -15
- 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 -23
- package/dist/types/src/components/Form/RefField.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 -151
|
@@ -7,9 +7,7 @@ import '@dxos-theme';
|
|
|
7
7
|
import { type Meta, type StoryObj } from '@storybook/react';
|
|
8
8
|
import React, { useCallback, useState } from 'react';
|
|
9
9
|
|
|
10
|
-
import {
|
|
11
|
-
import { AST, type BaseObject, Expando, Format, getDXN, Ref, S, type TypeAnnotation } from '@dxos/echo-schema';
|
|
12
|
-
import { live } from '@dxos/live-object';
|
|
10
|
+
import { AST, type BaseObject, Format, S } from '@dxos/echo-schema';
|
|
13
11
|
import { Testing } from '@dxos/schema/testing';
|
|
14
12
|
import { withLayout, withTheme } from '@dxos/storybook-utils';
|
|
15
13
|
|
|
@@ -80,9 +78,9 @@ export const Default: Story<TestType> = {
|
|
|
80
78
|
},
|
|
81
79
|
};
|
|
82
80
|
|
|
83
|
-
export const
|
|
81
|
+
export const Org: Story<Testing.Org> = {
|
|
84
82
|
args: {
|
|
85
|
-
schema: Testing.
|
|
83
|
+
schema: Testing.OrgSchema,
|
|
86
84
|
values: {
|
|
87
85
|
name: 'DXOS',
|
|
88
86
|
// website: 'https://dxos.org',
|
|
@@ -90,9 +88,9 @@ export const Organization: Story<Testing.Organization> = {
|
|
|
90
88
|
},
|
|
91
89
|
};
|
|
92
90
|
|
|
93
|
-
export const
|
|
91
|
+
export const OrgAutoSave: Story<Testing.Org> = {
|
|
94
92
|
args: {
|
|
95
|
-
schema: Testing.
|
|
93
|
+
schema: Testing.OrgSchema,
|
|
96
94
|
values: {
|
|
97
95
|
name: 'DXOS',
|
|
98
96
|
// website: 'https://dxos.org',
|
|
@@ -241,44 +239,3 @@ export const Enum: StoryObj<FormProps<ColorType>> = {
|
|
|
241
239
|
},
|
|
242
240
|
},
|
|
243
241
|
};
|
|
244
|
-
|
|
245
|
-
const RefSchema = S.Struct({
|
|
246
|
-
contact: Ref(ContactType).annotations({ title: 'Contact Reference' }),
|
|
247
|
-
optionalContact: S.optional(Ref(ContactType).annotations({ title: 'Optional Contact Reference' })),
|
|
248
|
-
unknownExpando: S.optional(Ref(Expando).annotations({ title: 'Optional Ref to an Expando (DXN Input)' })),
|
|
249
|
-
});
|
|
250
|
-
|
|
251
|
-
const RefStory = ({ values: initialValues }: FormProps<any>) => {
|
|
252
|
-
const [values, setValues] = useState(initialValues);
|
|
253
|
-
const handleSave = useCallback<NonNullable<FormProps<any>['onSave']>>((values) => {
|
|
254
|
-
setValues(values);
|
|
255
|
-
}, []);
|
|
256
|
-
|
|
257
|
-
const contact1 = live(ContactType, { identifiers: [] });
|
|
258
|
-
const contact2 = live(ContactType, { identifiers: [] });
|
|
259
|
-
|
|
260
|
-
const onQueryRefOptions = useCallback((typeInfo: TypeAnnotation) => {
|
|
261
|
-
switch (typeInfo.typename) {
|
|
262
|
-
case ContactType.typename:
|
|
263
|
-
return [
|
|
264
|
-
{ dxn: getDXN(contact1)!, label: 'John Coltraine' },
|
|
265
|
-
{ dxn: getDXN(contact2)!, label: 'Erykah Badu' },
|
|
266
|
-
];
|
|
267
|
-
default:
|
|
268
|
-
return [];
|
|
269
|
-
}
|
|
270
|
-
}, []);
|
|
271
|
-
|
|
272
|
-
return (
|
|
273
|
-
<TestLayout json={{ values, schema: RefSchema.ast.toJSON() }}>
|
|
274
|
-
<TestPanel>
|
|
275
|
-
<Form schema={RefSchema} values={values} onSave={handleSave} onQueryRefOptions={onQueryRefOptions} />
|
|
276
|
-
</TestPanel>
|
|
277
|
-
</TestLayout>
|
|
278
|
-
);
|
|
279
|
-
};
|
|
280
|
-
|
|
281
|
-
export const Refs: StoryObj<FormProps<ContactType>> = {
|
|
282
|
-
render: RefStory,
|
|
283
|
-
args: { values: {} },
|
|
284
|
-
};
|
|
@@ -13,7 +13,6 @@ import { FormActions } from './FormActions';
|
|
|
13
13
|
import { FormFields } from './FormContent';
|
|
14
14
|
import { FormProvider } from './FormContext';
|
|
15
15
|
import { type InputProps, type InputComponent } from './Input';
|
|
16
|
-
import { type QueryRefOptions } from './RefField';
|
|
17
16
|
import { type FormOptions } from '../../hooks';
|
|
18
17
|
|
|
19
18
|
export type PropsFilter<T extends BaseObject> = (props: SchemaProperty<T>[]) => SchemaProperty<T>[];
|
|
@@ -42,7 +41,6 @@ export type FormProps<T extends BaseObject> = ThemedClassName<
|
|
|
42
41
|
autoSave?: boolean;
|
|
43
42
|
testId?: string;
|
|
44
43
|
onCancel?: () => void;
|
|
45
|
-
onQueryRefOptions?: QueryRefOptions;
|
|
46
44
|
lookupComponent?: ComponentLookup;
|
|
47
45
|
/**
|
|
48
46
|
* Map of custom renderers for specific properties.
|
|
@@ -67,7 +65,6 @@ export const Form = <T extends BaseObject>({
|
|
|
67
65
|
onValidate,
|
|
68
66
|
onSave,
|
|
69
67
|
onCancel,
|
|
70
|
-
onQueryRefOptions,
|
|
71
68
|
lookupComponent,
|
|
72
69
|
Custom,
|
|
73
70
|
}: FormProps<T>) => {
|
|
@@ -103,7 +100,6 @@ export const Form = <T extends BaseObject>({
|
|
|
103
100
|
readonly={readonly}
|
|
104
101
|
filter={filter}
|
|
105
102
|
sort={sort}
|
|
106
|
-
onQueryRefOptions={onQueryRefOptions}
|
|
107
103
|
lookupComponent={lookupComponent}
|
|
108
104
|
Custom={Custom}
|
|
109
105
|
/>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//
|
|
2
|
-
// Copyright
|
|
2
|
+
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { pipe } from 'effect';
|
|
@@ -17,29 +17,29 @@ import { SelectInput } from './Defaults';
|
|
|
17
17
|
import { type ComponentLookup } from './Form';
|
|
18
18
|
import { useInputProps, useFormValues } from './FormContext';
|
|
19
19
|
import { type InputComponent } from './Input';
|
|
20
|
-
import { RefField, type QueryRefOptions } from './RefField';
|
|
21
20
|
import { getInputComponent } from './factory';
|
|
22
21
|
|
|
22
|
+
export type FormContentProps = {
|
|
23
|
+
schema: S.Schema.All;
|
|
24
|
+
path?: (string | number)[];
|
|
25
|
+
filter?: (props: SchemaProperty<any>[]) => SchemaProperty<any>[];
|
|
26
|
+
sort?: string[];
|
|
27
|
+
readonly?: boolean;
|
|
28
|
+
lookupComponent?: ComponentLookup;
|
|
29
|
+
Custom?: Partial<Record<string, InputComponent>>;
|
|
30
|
+
};
|
|
31
|
+
|
|
23
32
|
export type FormFieldProps = {
|
|
24
33
|
property: SchemaProperty<any>;
|
|
25
34
|
path?: (string | number)[];
|
|
26
35
|
readonly?: boolean;
|
|
27
36
|
/** Used to indicate if input should be presented inline (e.g. for array items). */
|
|
28
37
|
inline?: boolean;
|
|
29
|
-
onQueryRefOptions?: QueryRefOptions;
|
|
30
38
|
lookupComponent?: ComponentLookup;
|
|
31
39
|
Custom?: Partial<Record<string, InputComponent>>;
|
|
32
40
|
};
|
|
33
41
|
|
|
34
|
-
export const FormField = ({
|
|
35
|
-
property,
|
|
36
|
-
path,
|
|
37
|
-
readonly,
|
|
38
|
-
inline,
|
|
39
|
-
onQueryRefOptions,
|
|
40
|
-
lookupComponent,
|
|
41
|
-
Custom,
|
|
42
|
-
}: FormFieldProps) => {
|
|
42
|
+
export const FormField = ({ property, path, readonly, inline, lookupComponent, Custom }: FormFieldProps) => {
|
|
43
43
|
const inputProps = useInputProps(path);
|
|
44
44
|
const { ast, name, type, format, title, description, options, examples, array } = property;
|
|
45
45
|
|
|
@@ -120,22 +120,6 @@ export const FormField = ({
|
|
|
120
120
|
);
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
-
// TODO(ZaymonFC): Extract this to it's own component.
|
|
124
|
-
if (format === 'ref') {
|
|
125
|
-
return (
|
|
126
|
-
<RefField
|
|
127
|
-
ast={ast}
|
|
128
|
-
type={type}
|
|
129
|
-
label={label}
|
|
130
|
-
readonly={readonly}
|
|
131
|
-
placeholder={placeholder}
|
|
132
|
-
inline={inline}
|
|
133
|
-
onQueryRefOptions={onQueryRefOptions}
|
|
134
|
-
inputProps={inputProps}
|
|
135
|
-
/>
|
|
136
|
-
);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
123
|
if (type === 'object') {
|
|
140
124
|
const baseNode = findNode(ast, isDiscriminatedUnion);
|
|
141
125
|
const typeLiteral = baseNode
|
|
@@ -145,15 +129,8 @@ export const FormField = ({
|
|
|
145
129
|
if (typeLiteral) {
|
|
146
130
|
return (
|
|
147
131
|
<div role='none'>
|
|
148
|
-
{!inline && <
|
|
149
|
-
<FormFields
|
|
150
|
-
schema={S.make(typeLiteral)}
|
|
151
|
-
path={path}
|
|
152
|
-
readonly={readonly}
|
|
153
|
-
onQueryRefOptions={onQueryRefOptions}
|
|
154
|
-
Custom={Custom}
|
|
155
|
-
lookupComponent={lookupComponent}
|
|
156
|
-
/>
|
|
132
|
+
{!inline && <div>{label}</div>}
|
|
133
|
+
<FormFields schema={S.make(typeLiteral)} path={path} readonly={readonly} Custom={Custom} />
|
|
157
134
|
</div>
|
|
158
135
|
);
|
|
159
136
|
}
|
|
@@ -162,27 +139,7 @@ export const FormField = ({
|
|
|
162
139
|
return null;
|
|
163
140
|
};
|
|
164
141
|
|
|
165
|
-
export
|
|
166
|
-
schema: S.Schema.All;
|
|
167
|
-
path?: (string | number)[];
|
|
168
|
-
filter?: (props: SchemaProperty<any>[]) => SchemaProperty<any>[];
|
|
169
|
-
sort?: string[];
|
|
170
|
-
readonly?: boolean;
|
|
171
|
-
onQueryRefOptions?: QueryRefOptions;
|
|
172
|
-
lookupComponent?: ComponentLookup;
|
|
173
|
-
Custom?: Partial<Record<string, InputComponent>>;
|
|
174
|
-
};
|
|
175
|
-
|
|
176
|
-
export const FormFields = ({
|
|
177
|
-
schema,
|
|
178
|
-
path,
|
|
179
|
-
filter,
|
|
180
|
-
sort,
|
|
181
|
-
readonly,
|
|
182
|
-
onQueryRefOptions,
|
|
183
|
-
lookupComponent,
|
|
184
|
-
Custom,
|
|
185
|
-
}: FormContentProps) => {
|
|
142
|
+
export const FormFields = ({ schema, path, filter, sort, readonly, lookupComponent, Custom }: FormContentProps) => {
|
|
186
143
|
const values = useFormValues(path);
|
|
187
144
|
|
|
188
145
|
const properties = useMemo(() => {
|
|
@@ -202,7 +159,6 @@ export const FormFields = ({
|
|
|
202
159
|
property={property}
|
|
203
160
|
path={[...(path ?? []), property.name]}
|
|
204
161
|
readonly={readonly}
|
|
205
|
-
onQueryRefOptions={onQueryRefOptions}
|
|
206
162
|
lookupComponent={lookupComponent}
|
|
207
163
|
Custom={Custom}
|
|
208
164
|
/>
|
|
@@ -2,15 +2,7 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import React, {
|
|
6
|
-
createContext,
|
|
7
|
-
type RefObject,
|
|
8
|
-
useContext,
|
|
9
|
-
useEffect,
|
|
10
|
-
useMemo,
|
|
11
|
-
type FocusEvent,
|
|
12
|
-
type PropsWithChildren,
|
|
13
|
-
} from 'react';
|
|
5
|
+
import React, { createContext, useContext, useEffect, useMemo, type FocusEvent, type PropsWithChildren } from 'react';
|
|
14
6
|
|
|
15
7
|
import { raise } from '@dxos/debug';
|
|
16
8
|
import { type BaseObject, getValue } from '@dxos/echo-schema';
|
|
@@ -61,7 +53,7 @@ export const FormProvider = ({
|
|
|
61
53
|
...formOptions
|
|
62
54
|
}: PropsWithChildren<
|
|
63
55
|
FormOptions<any> & {
|
|
64
|
-
formRef?: RefObject<HTMLDivElement>;
|
|
56
|
+
formRef?: React.RefObject<HTMLDivElement>;
|
|
65
57
|
autoSave?: boolean;
|
|
66
58
|
}
|
|
67
59
|
>) => {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import React, { useCallback, useState, useEffect, useMemo
|
|
5
|
+
import React, { useCallback, useState, useEffect, useMemo } from 'react';
|
|
6
6
|
|
|
7
7
|
import { type GeoPoint, GeoLocation } from '@dxos/echo-schema';
|
|
8
8
|
import { Input, useTranslation } from '@dxos/react-ui';
|
|
@@ -28,7 +28,7 @@ export const GeoPointInput = ({ type, label, disabled, getStatus, getValue, onVa
|
|
|
28
28
|
|
|
29
29
|
const handleCoordinateChange = useCallback(
|
|
30
30
|
(coordinateType: keyof Pick<GeoLocation, 'longitude' | 'latitude'>, setText: (text: string) => void) =>
|
|
31
|
-
(event: ChangeEvent<HTMLInputElement>) => {
|
|
31
|
+
(event: React.ChangeEvent<HTMLInputElement>) => {
|
|
32
32
|
const inputText = event.target.value;
|
|
33
33
|
setText(inputText);
|
|
34
34
|
if (inputText !== '' && inputText !== '-') {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import React, {
|
|
5
|
+
import React, { useCallback, useEffect, useState, type ChangeEvent, useRef } from 'react';
|
|
6
6
|
|
|
7
7
|
import { type SelectOption } from '@dxos/echo-schema';
|
|
8
8
|
import { PublicKey } from '@dxos/keys';
|
|
@@ -89,7 +89,7 @@ export const SelectOptionInput = ({ type, label, disabled, getStatus, getValue,
|
|
|
89
89
|
[options, type, onValueChange],
|
|
90
90
|
);
|
|
91
91
|
|
|
92
|
-
const handleKeyDown = useCallback((e: KeyboardEvent<HTMLInputElement>) => {
|
|
92
|
+
const handleKeyDown = useCallback((e: React.KeyboardEvent<HTMLInputElement>) => {
|
|
93
93
|
if (e.key === 'Enter') {
|
|
94
94
|
setSelectedId(null);
|
|
95
95
|
}
|
|
@@ -7,7 +7,7 @@ import '@dxos-theme';
|
|
|
7
7
|
import { type Meta, type StoryObj } from '@storybook/react';
|
|
8
8
|
import React from 'react';
|
|
9
9
|
|
|
10
|
-
import {
|
|
10
|
+
import { create } from '@dxos/live-object';
|
|
11
11
|
import { testData, TestSchema, testView, type TestType } from '@dxos/schema/testing';
|
|
12
12
|
import { withLayout, withTheme } from '@dxos/storybook-utils';
|
|
13
13
|
|
|
@@ -39,23 +39,23 @@ type Story = StoryObj<DeprecatedFormProps<TestType>>;
|
|
|
39
39
|
|
|
40
40
|
export const Default: Story = {
|
|
41
41
|
args: {
|
|
42
|
-
object:
|
|
43
|
-
view:
|
|
42
|
+
object: create(testData),
|
|
43
|
+
view: create(testView),
|
|
44
44
|
schema: TestSchema,
|
|
45
45
|
},
|
|
46
46
|
};
|
|
47
47
|
|
|
48
48
|
export const Empty: Story = {
|
|
49
49
|
args: {
|
|
50
|
-
view:
|
|
50
|
+
view: create(testView),
|
|
51
51
|
schema: TestSchema,
|
|
52
52
|
},
|
|
53
53
|
};
|
|
54
54
|
|
|
55
55
|
export const Readonly: Story = {
|
|
56
56
|
args: {
|
|
57
|
-
object:
|
|
58
|
-
view:
|
|
57
|
+
object: create(testData),
|
|
58
|
+
view: create(testView),
|
|
59
59
|
schema: TestSchema,
|
|
60
60
|
readonly: true,
|
|
61
61
|
},
|
|
@@ -12,7 +12,7 @@ import { mx, textBlockWidth } from '@dxos/react-ui-theme';
|
|
|
12
12
|
*/
|
|
13
13
|
export const DeprecatedFormContainer = ({ children, classNames }: ThemedClassName<PropsWithChildren>) => {
|
|
14
14
|
return (
|
|
15
|
-
<div role='none' className='
|
|
15
|
+
<div role='none' className='w-full p-4 justify-center overflow-x-hidden overflow-y-auto'>
|
|
16
16
|
<div role='form' className={mx('flex flex-col', textBlockWidth, classNames)}>
|
|
17
17
|
{children}
|
|
18
18
|
</div>
|
package/src/components/index.ts
CHANGED
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) {
|
|
@@ -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,uCAAwC,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,qCAAsC,mBAAmB,sBAOnF,CAAC;AAEF,eAAO,MAAM,qBAAqB,2BAA4B,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,sBAUlG,CAAC;AAEF,eAAO,MAAM,kBAAkB,6BAA8B,WAAW,sBAEvE,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,eAAe,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC,CAAC;AAEvE,eAAO,MAAM,YAAY,6BAA8B,iBAAiB,sBAOvE,CAAC;AAEF,eAAO,MAAM,YAAY,iBAAkB,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,qCAAsC,gBAAgB,sBAY7E,CAAC;AAEF,eAAO,MAAM,gBAAgB,qCAAsC,gBAAgB,sBAoBlF,CAAC;AAEF,eAAO,MAAM,gBAAgB,qCAAsC,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,23 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { type AST, type TypeAnnotation } from '@dxos/echo-schema';
|
|
3
|
-
import { type SimpleType } from '@dxos/effect';
|
|
4
|
-
import { DXN } from '@dxos/keys';
|
|
5
|
-
import { type MaybePromise } from '@dxos/util';
|
|
6
|
-
import { type FormInputStateProps } from './FormContext';
|
|
7
|
-
export type QueryRefOptions = (type: TypeAnnotation) => MaybePromise<{
|
|
8
|
-
dxn: DXN;
|
|
9
|
-
label?: string;
|
|
10
|
-
}[]>;
|
|
11
|
-
type RefFieldProps = {
|
|
12
|
-
ast: AST.AST;
|
|
13
|
-
type: SimpleType;
|
|
14
|
-
label: string;
|
|
15
|
-
readonly?: boolean;
|
|
16
|
-
placeholder?: string;
|
|
17
|
-
inline?: boolean;
|
|
18
|
-
onQueryRefOptions?: QueryRefOptions;
|
|
19
|
-
inputProps: FormInputStateProps;
|
|
20
|
-
};
|
|
21
|
-
export declare const RefField: ({ ast, type, label, readonly, placeholder, inline, onQueryRefOptions, inputProps, }: RefFieldProps) => React.JSX.Element | null;
|
|
22
|
-
export {};
|
|
23
|
-
//# 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,KAA8B,MAAM,OAAO,CAAC;AAEnD,OAAO,EACL,KAAK,GAAG,EAKR,KAAK,cAAc,EACpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAkB,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAGjC,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAG/C,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAEzD,MAAM,MAAM,eAAe,GAAG,CAAC,IAAI,EAAE,cAAc,KAAK,YAAY,CAAC;IAAE,GAAG,EAAE,GAAG,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC,CAAC;AAErG,KAAK,aAAa,GAAG;IACnB,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC;IACb,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,iBAAiB,CAAC,EAAE,eAAe,CAAC;IACpC,UAAU,EAAE,mBAAmB,CAAC;CACjC,CAAC;AAEF,eAAO,MAAM,QAAQ,wFASlB,aAAa,6BAyGf,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({ tooltips: true }), 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,151 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2025 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import React, { useEffect, useState } from 'react';
|
|
6
|
-
|
|
7
|
-
import {
|
|
8
|
-
type AST,
|
|
9
|
-
Expando,
|
|
10
|
-
getTypeAnnotation,
|
|
11
|
-
ReferenceAnnotationId,
|
|
12
|
-
type ReferenceAnnotationValue,
|
|
13
|
-
type TypeAnnotation,
|
|
14
|
-
} from '@dxos/echo-schema';
|
|
15
|
-
import { findAnnotation, type SimpleType } from '@dxos/effect';
|
|
16
|
-
import { DXN } from '@dxos/keys';
|
|
17
|
-
import { refFromDXN, RefImpl } from '@dxos/live-object';
|
|
18
|
-
import { log } from '@dxos/log';
|
|
19
|
-
import { type MaybePromise } from '@dxos/util';
|
|
20
|
-
|
|
21
|
-
import { SelectInput, TextInput } from './Defaults';
|
|
22
|
-
import { type FormInputStateProps } from './FormContext';
|
|
23
|
-
|
|
24
|
-
export type QueryRefOptions = (type: TypeAnnotation) => MaybePromise<{ dxn: DXN; label?: string }[]>;
|
|
25
|
-
|
|
26
|
-
type RefFieldProps = {
|
|
27
|
-
ast: AST.AST;
|
|
28
|
-
type: SimpleType;
|
|
29
|
-
label: string;
|
|
30
|
-
readonly?: boolean;
|
|
31
|
-
placeholder?: string;
|
|
32
|
-
inline?: boolean;
|
|
33
|
-
onQueryRefOptions?: QueryRefOptions;
|
|
34
|
-
inputProps: FormInputStateProps;
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
export const RefField = ({
|
|
38
|
-
ast,
|
|
39
|
-
type,
|
|
40
|
-
label,
|
|
41
|
-
readonly,
|
|
42
|
-
placeholder,
|
|
43
|
-
inline,
|
|
44
|
-
onQueryRefOptions,
|
|
45
|
-
inputProps,
|
|
46
|
-
}: RefFieldProps) => {
|
|
47
|
-
const { getValue, onValueChange, ...restInputProps } = inputProps;
|
|
48
|
-
const refTypeInfo = findAnnotation<ReferenceAnnotationValue>(ast, ReferenceAnnotationId);
|
|
49
|
-
const [refOptions, setRefOptions] = useState<Array<{ value: string; label?: string }>>([]);
|
|
50
|
-
const [loading, setLoading] = useState(false);
|
|
51
|
-
|
|
52
|
-
useEffect(() => {
|
|
53
|
-
if (!refTypeInfo || !onQueryRefOptions) {
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const fetchOptions = async () => {
|
|
58
|
-
setLoading(true);
|
|
59
|
-
try {
|
|
60
|
-
const options = await onQueryRefOptions(refTypeInfo);
|
|
61
|
-
setRefOptions(
|
|
62
|
-
options.map((option) => ({
|
|
63
|
-
label: option.label,
|
|
64
|
-
value: option.dxn.toString(),
|
|
65
|
-
})),
|
|
66
|
-
);
|
|
67
|
-
} catch (error) {
|
|
68
|
-
log.error('Failed to fetch ref options:', error);
|
|
69
|
-
setRefOptions([]);
|
|
70
|
-
} finally {
|
|
71
|
-
setLoading(false);
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
void fetchOptions();
|
|
76
|
-
}, [refTypeInfo, onQueryRefOptions]);
|
|
77
|
-
|
|
78
|
-
if (!refTypeInfo) {
|
|
79
|
-
return null;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// If ref type is expando, fall back to taking a DXN in string format.
|
|
83
|
-
if (refTypeInfo.typename === getTypeAnnotation(Expando)?.typename || !onQueryRefOptions) {
|
|
84
|
-
const handleOnValueChange = (_type: any, dxnString: string) => {
|
|
85
|
-
const dxn = DXN.tryParse(dxnString);
|
|
86
|
-
if (dxn) {
|
|
87
|
-
onValueChange?.('object', refFromDXN(dxn));
|
|
88
|
-
} else if (dxnString === '') {
|
|
89
|
-
onValueChange?.('object', undefined);
|
|
90
|
-
} else {
|
|
91
|
-
onValueChange?.('string', dxnString);
|
|
92
|
-
}
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
const handleGetValue = () => {
|
|
96
|
-
const formValue = getValue();
|
|
97
|
-
if (typeof formValue === 'string') {
|
|
98
|
-
return formValue;
|
|
99
|
-
}
|
|
100
|
-
if (formValue instanceof RefImpl) {
|
|
101
|
-
return formValue.dxn.toString();
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
return undefined;
|
|
105
|
-
};
|
|
106
|
-
|
|
107
|
-
return (
|
|
108
|
-
<TextInput
|
|
109
|
-
type={type}
|
|
110
|
-
label={label}
|
|
111
|
-
disabled={readonly}
|
|
112
|
-
placeholder={placeholder}
|
|
113
|
-
inputOnly={inline}
|
|
114
|
-
getValue={handleGetValue as <V>() => V | undefined}
|
|
115
|
-
onValueChange={handleOnValueChange}
|
|
116
|
-
{...restInputProps}
|
|
117
|
-
/>
|
|
118
|
-
);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
const handleGetValue = () => {
|
|
122
|
-
const formValue = getValue();
|
|
123
|
-
|
|
124
|
-
if (formValue instanceof RefImpl) {
|
|
125
|
-
return formValue.dxn.toString();
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
return undefined;
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
const handleValueChanged = (_type: any, dxnString: string) => {
|
|
132
|
-
const dxn = DXN.parse(dxnString);
|
|
133
|
-
const ref = refFromDXN(dxn);
|
|
134
|
-
|
|
135
|
-
onValueChange('object', ref);
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
return (
|
|
139
|
-
<SelectInput
|
|
140
|
-
type={type}
|
|
141
|
-
label={label}
|
|
142
|
-
disabled={readonly || loading}
|
|
143
|
-
placeholder={loading ? 'Loading options...' : placeholder}
|
|
144
|
-
inputOnly={inline}
|
|
145
|
-
getValue={handleGetValue as <V>() => V | undefined}
|
|
146
|
-
onValueChange={handleValueChanged}
|
|
147
|
-
options={refOptions}
|
|
148
|
-
{...restInputProps}
|
|
149
|
-
/>
|
|
150
|
-
);
|
|
151
|
-
};
|