@dxos/react-ui-form 0.8.4-main.bc674ce → 0.8.4-main.c351d160a8
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/README.md +0 -1
- package/dist/lib/browser/index.mjs +538 -458
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +538 -458
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/components/FieldEditor/FieldEditor.d.ts +3 -3
- package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
- package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.d.ts +13 -13
- package/dist/types/src/components/Form/Form.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.stories.d.ts +3 -3
- package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormField.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormFieldComponent.d.ts +0 -1
- package/dist/types/src/components/Form/FormFieldComponent.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormFieldComponent.stories.d.ts +2 -2
- package/dist/types/src/components/Form/FormFieldComponent.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormFieldSet.d.ts +9 -10
- package/dist/types/src/components/Form/FormFieldSet.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/ArrayField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/RefField.d.ts +6 -4
- package/dist/types/src/components/Form/fields/RefField.d.ts.map +1 -1
- package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts.map +1 -1
- package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts.map +1 -1
- package/dist/types/src/components/Settings/Settings.d.ts +56 -0
- package/dist/types/src/components/Settings/Settings.d.ts.map +1 -0
- package/dist/types/src/components/{ControlSection/ControlSection.stories.d.ts → Settings/Settings.stories.d.ts} +2 -8
- package/dist/types/src/components/Settings/Settings.stories.d.ts.map +1 -0
- package/dist/types/src/components/Settings/index.d.ts +2 -0
- package/dist/types/src/components/Settings/index.d.ts.map +1 -0
- package/dist/types/src/components/ViewEditor/ViewEditor.d.ts +5 -5
- package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
- package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts +2 -1
- package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +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/useFormHandler.d.ts.map +1 -1
- package/dist/types/src/util/index.d.ts +0 -1
- package/dist/types/src/util/index.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +35 -37
- package/src/components/FieldEditor/FieldEditor.stories.tsx +4 -6
- package/src/components/FieldEditor/FieldEditor.tsx +2 -3
- package/src/components/Form/Form.stories.tsx +8 -7
- package/src/components/Form/Form.tsx +82 -55
- package/src/components/Form/FormField.tsx +12 -4
- package/src/components/Form/FormFieldComponent.stories.tsx +5 -5
- package/src/components/Form/FormFieldComponent.tsx +17 -20
- package/src/components/Form/FormFieldSet.tsx +106 -104
- package/src/components/Form/fields/ArrayField.tsx +6 -8
- package/src/components/Form/fields/MarkdownField.tsx +1 -1
- package/src/components/Form/fields/RefField.tsx +28 -15
- package/src/components/Form/fields/SelectField.tsx +1 -1
- package/src/components/Form/fields/SelectOptionField.stories.tsx +2 -2
- package/src/components/Form/fields/SelectOptionField.tsx +4 -4
- package/src/components/ObjectPicker/ObjectPicker.stories.tsx +9 -13
- package/src/components/Settings/Settings.stories.tsx +56 -0
- package/src/components/Settings/Settings.tsx +230 -0
- package/src/components/{ControlSection → Settings}/index.ts +1 -1
- package/src/components/ViewEditor/ViewEditor.stories.tsx +14 -12
- package/src/components/ViewEditor/ViewEditor.test.tsx +3 -6
- package/src/components/ViewEditor/ViewEditor.tsx +92 -63
- package/src/components/index.ts +1 -1
- package/src/components/testing.tsx +9 -6
- package/src/hooks/useFormHandler.ts +42 -24
- package/src/util/index.ts +0 -1
- package/dist/types/src/components/ControlSection/ControlSection.d.ts +0 -23
- package/dist/types/src/components/ControlSection/ControlSection.d.ts.map +0 -1
- 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/Form-old.stories.d.ts +0 -131
- package/dist/types/src/components/Form/Form-old.stories.d.ts.map +0 -1
- package/dist/types/src/util/echo.d.ts +0 -6
- package/dist/types/src/util/echo.d.ts.map +0 -1
- package/src/components/ControlSection/ControlSection.stories.tsx +0 -38
- package/src/components/ControlSection/ControlSection.tsx +0 -153
- package/src/components/Form/Form-old.stories.tsx +0 -314
- package/src/util/echo.ts +0 -25
|
@@ -1,314 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2024 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
6
|
-
import * as Schema from 'effect/Schema';
|
|
7
|
-
import React, { useCallback, useState } from 'react';
|
|
8
|
-
|
|
9
|
-
import { Format } from '@dxos/echo';
|
|
10
|
-
import { type AnyProperties } from '@dxos/echo/internal';
|
|
11
|
-
import { Tooltip } from '@dxos/react-ui';
|
|
12
|
-
import { withLayoutVariants, withTheme } from '@dxos/react-ui/testing';
|
|
13
|
-
import { TestSchema } from '@dxos/schema/testing';
|
|
14
|
-
|
|
15
|
-
import { translations } from '../../translations';
|
|
16
|
-
import { TestLayout } from '../testing';
|
|
17
|
-
|
|
18
|
-
import { SelectField } from './fields';
|
|
19
|
-
import { Form, type FormRootProps } from './Form';
|
|
20
|
-
|
|
21
|
-
// TODO(burdon): Extract into Form.stories.tsx
|
|
22
|
-
|
|
23
|
-
type StoryProps<T extends AnyProperties> = {
|
|
24
|
-
debug?: boolean;
|
|
25
|
-
schema: Schema.Schema.AnyNoContext;
|
|
26
|
-
} & FormRootProps<T>;
|
|
27
|
-
|
|
28
|
-
const DefaultStory = <T extends AnyProperties = any>({
|
|
29
|
-
debug,
|
|
30
|
-
schema,
|
|
31
|
-
values: valuesProp,
|
|
32
|
-
...props
|
|
33
|
-
}: StoryProps<T>) => {
|
|
34
|
-
const [values, setValues] = useState(valuesProp);
|
|
35
|
-
const handleSave = useCallback<NonNullable<FormRootProps<T>['onSave']>>((values) => {
|
|
36
|
-
setValues(values);
|
|
37
|
-
}, []);
|
|
38
|
-
|
|
39
|
-
if (debug) {
|
|
40
|
-
return (
|
|
41
|
-
<Tooltip.Provider>
|
|
42
|
-
<TestLayout json={{ values, schema: schema.ast }}>
|
|
43
|
-
<Form.Root<T> schema={schema} values={values} onSave={handleSave} {...props}>
|
|
44
|
-
<Form.Content>
|
|
45
|
-
<Form.FieldSet />
|
|
46
|
-
<Form.Actions />
|
|
47
|
-
</Form.Content>
|
|
48
|
-
</Form.Root>
|
|
49
|
-
</TestLayout>
|
|
50
|
-
</Tooltip.Provider>
|
|
51
|
-
);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return (
|
|
55
|
-
<Form.Root<T> schema={schema} values={values} onSave={handleSave} {...props}>
|
|
56
|
-
<Form.Content>
|
|
57
|
-
<Form.FieldSet />
|
|
58
|
-
<Form.Actions />
|
|
59
|
-
</Form.Content>
|
|
60
|
-
</Form.Root>
|
|
61
|
-
);
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
// const RefStory = <T extends AnyProperties = any>(props: StoryProps<T>) => {
|
|
65
|
-
// const onQueryRefOptions = useCallback<NonNullable<FormRootProps<T>['onQueryRefOptions']>>(({ typename }) => {
|
|
66
|
-
// switch (typename) {
|
|
67
|
-
// case TestSchema.Person.typename:
|
|
68
|
-
// return [
|
|
69
|
-
// { dxn: Obj.getDXN(contact1), label: 'Alice' },
|
|
70
|
-
// { dxn: Obj.getDXN(contact2), label: 'Bob' },
|
|
71
|
-
// ];
|
|
72
|
-
// default:
|
|
73
|
-
// return [];
|
|
74
|
-
// }
|
|
75
|
-
// }, []);
|
|
76
|
-
|
|
77
|
-
// return <DefaultStory<T> onQueryRefOptions={onQueryRefOptions} {...props} />;
|
|
78
|
-
// };
|
|
79
|
-
|
|
80
|
-
const AddressSchema = Schema.Struct({
|
|
81
|
-
street: Schema.optional(Schema.String.annotations({ title: 'Street' })),
|
|
82
|
-
city: Schema.optional(Schema.String.annotations({ title: 'City' })),
|
|
83
|
-
zip: Schema.optional(Schema.String.pipe(Schema.pattern(/^\d{5}(-\d{4})?$/)).annotations({ title: 'ZIP' })),
|
|
84
|
-
location: Schema.optional(Format.GeoPoint.annotations({ title: 'Location' })),
|
|
85
|
-
}).annotations({ title: 'Address' });
|
|
86
|
-
|
|
87
|
-
const PersonSchema = Schema.Struct({
|
|
88
|
-
name: Schema.optional(Schema.String.annotations({ title: 'Name' })),
|
|
89
|
-
active: Schema.optional(Schema.Boolean.annotations({ title: 'Active' })),
|
|
90
|
-
rank: Schema.optional(Schema.Number.annotations({ title: 'Rank' })),
|
|
91
|
-
website: Schema.optional(Format.URL.annotations({ title: 'Website' })),
|
|
92
|
-
address: Schema.optional(AddressSchema),
|
|
93
|
-
}).pipe(Schema.mutable);
|
|
94
|
-
|
|
95
|
-
type PersonSchema = Schema.Schema.Type<typeof PersonSchema>;
|
|
96
|
-
|
|
97
|
-
const meta = {
|
|
98
|
-
title: 'ui/react-ui-form/Form-Old',
|
|
99
|
-
component: Form.Root as any,
|
|
100
|
-
render: DefaultStory,
|
|
101
|
-
decorators: [withTheme, withLayoutVariants()],
|
|
102
|
-
parameters: {
|
|
103
|
-
layout: 'fullscreen',
|
|
104
|
-
translations,
|
|
105
|
-
},
|
|
106
|
-
argTypes: {
|
|
107
|
-
readonly: {
|
|
108
|
-
control: 'boolean',
|
|
109
|
-
description: 'Readonly',
|
|
110
|
-
},
|
|
111
|
-
},
|
|
112
|
-
} satisfies Meta<StoryProps<any>>;
|
|
113
|
-
|
|
114
|
-
export default meta;
|
|
115
|
-
|
|
116
|
-
type Story = StoryObj<typeof meta>;
|
|
117
|
-
|
|
118
|
-
export const Default: Story = {
|
|
119
|
-
args: {
|
|
120
|
-
schema: PersonSchema,
|
|
121
|
-
values: {
|
|
122
|
-
name: 'DXOS',
|
|
123
|
-
active: true,
|
|
124
|
-
address: {
|
|
125
|
-
zip: '11205',
|
|
126
|
-
},
|
|
127
|
-
},
|
|
128
|
-
readonly: false,
|
|
129
|
-
},
|
|
130
|
-
};
|
|
131
|
-
|
|
132
|
-
export const Organization: Story = {
|
|
133
|
-
args: {
|
|
134
|
-
debug: true,
|
|
135
|
-
schema: TestSchema.OrganizationSchema,
|
|
136
|
-
values: {
|
|
137
|
-
name: 'DXOS',
|
|
138
|
-
website: 'https://dxos.org',
|
|
139
|
-
},
|
|
140
|
-
readonly: false,
|
|
141
|
-
},
|
|
142
|
-
};
|
|
143
|
-
|
|
144
|
-
export const OrganizationAutoSave: Story = {
|
|
145
|
-
args: {
|
|
146
|
-
debug: true,
|
|
147
|
-
schema: TestSchema.OrganizationSchema,
|
|
148
|
-
values: {
|
|
149
|
-
name: 'DXOS',
|
|
150
|
-
website: 'https://dxos.org',
|
|
151
|
-
},
|
|
152
|
-
autoSave: true,
|
|
153
|
-
readonly: false,
|
|
154
|
-
},
|
|
155
|
-
};
|
|
156
|
-
|
|
157
|
-
// TODO(burdon): Type issue with employer reference.
|
|
158
|
-
// TODO(burdon): Test table/form with compound values (e.g., address).
|
|
159
|
-
// Property name is missing in type EncodedReference but required in type
|
|
160
|
-
export const Person: Story = {
|
|
161
|
-
args: {
|
|
162
|
-
debug: true,
|
|
163
|
-
schema: TestSchema.Person,
|
|
164
|
-
values: {
|
|
165
|
-
name: 'Bot',
|
|
166
|
-
},
|
|
167
|
-
},
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
//
|
|
171
|
-
// Union
|
|
172
|
-
//
|
|
173
|
-
|
|
174
|
-
const ShapeSchema = Schema.Struct({
|
|
175
|
-
shape: Schema.optional(
|
|
176
|
-
Schema.Union(
|
|
177
|
-
Schema.Struct({
|
|
178
|
-
type: Schema.Literal('circle').annotations({ title: 'Type' }),
|
|
179
|
-
radius: Schema.optional(Schema.Number.annotations({ title: 'Radius' })),
|
|
180
|
-
}),
|
|
181
|
-
Schema.Struct({
|
|
182
|
-
type: Schema.Literal('square').annotations({ title: 'Type' }),
|
|
183
|
-
size: Schema.optional(Schema.Number.pipe(Schema.nonNegative()).annotations({ title: 'Size' })),
|
|
184
|
-
}),
|
|
185
|
-
).annotations({ title: 'Shape' }),
|
|
186
|
-
),
|
|
187
|
-
}).pipe(Schema.mutable);
|
|
188
|
-
|
|
189
|
-
type ShapeSchema = Schema.Schema.Type<typeof ShapeSchema>;
|
|
190
|
-
|
|
191
|
-
export const DiscriminatedShape: StoryObj<StoryProps<ShapeSchema>> = {
|
|
192
|
-
args: {
|
|
193
|
-
debug: true,
|
|
194
|
-
schema: ShapeSchema,
|
|
195
|
-
readonly: false,
|
|
196
|
-
values: {
|
|
197
|
-
shape: {
|
|
198
|
-
type: 'circle',
|
|
199
|
-
radius: 5,
|
|
200
|
-
},
|
|
201
|
-
},
|
|
202
|
-
fieldMap: {
|
|
203
|
-
['shape.type' as const]: (props) => (
|
|
204
|
-
<SelectField
|
|
205
|
-
{...props}
|
|
206
|
-
options={['circle', 'square'].map((value) => ({
|
|
207
|
-
value,
|
|
208
|
-
label: value,
|
|
209
|
-
}))}
|
|
210
|
-
/>
|
|
211
|
-
),
|
|
212
|
-
},
|
|
213
|
-
},
|
|
214
|
-
};
|
|
215
|
-
|
|
216
|
-
//
|
|
217
|
-
// Arrays
|
|
218
|
-
//
|
|
219
|
-
|
|
220
|
-
const ArraysSchema = Schema.Struct({
|
|
221
|
-
names: Schema.Array(Schema.String.pipe(Schema.nonEmptyString())),
|
|
222
|
-
addresses: Schema.Array(AddressSchema),
|
|
223
|
-
}).pipe(Schema.mutable);
|
|
224
|
-
|
|
225
|
-
type ArraysSchema = Schema.Schema.Type<typeof ArraysSchema>;
|
|
226
|
-
|
|
227
|
-
export const Arrays: StoryObj<StoryProps<ArraysSchema>> = {
|
|
228
|
-
args: {
|
|
229
|
-
debug: true,
|
|
230
|
-
schema: ArraysSchema,
|
|
231
|
-
readonly: false,
|
|
232
|
-
values: {
|
|
233
|
-
names: ['Alice', 'Bob'],
|
|
234
|
-
addresses: [],
|
|
235
|
-
},
|
|
236
|
-
},
|
|
237
|
-
};
|
|
238
|
-
|
|
239
|
-
//
|
|
240
|
-
// Tuple
|
|
241
|
-
//
|
|
242
|
-
|
|
243
|
-
// TODO(wittjosiah): Only GeoPoint is works currently.
|
|
244
|
-
const TupleSchema = Schema.Struct({
|
|
245
|
-
tuple: Schema.Tuple(Schema.Number, Schema.String, Schema.Boolean),
|
|
246
|
-
geopoint: Format.GeoPoint,
|
|
247
|
-
}).pipe(Schema.mutable);
|
|
248
|
-
|
|
249
|
-
type TupleSchema = Schema.Schema.Type<typeof TupleSchema>;
|
|
250
|
-
|
|
251
|
-
export const Tuple: StoryObj<StoryProps<TupleSchema>> = {
|
|
252
|
-
args: {
|
|
253
|
-
debug: true,
|
|
254
|
-
schema: TupleSchema,
|
|
255
|
-
readonly: false,
|
|
256
|
-
values: {
|
|
257
|
-
tuple: [1, 'a', true],
|
|
258
|
-
geopoint: [-122.41941, 37.77492],
|
|
259
|
-
},
|
|
260
|
-
},
|
|
261
|
-
};
|
|
262
|
-
|
|
263
|
-
//
|
|
264
|
-
// Enum
|
|
265
|
-
//
|
|
266
|
-
|
|
267
|
-
const ColorSchema = Schema.Struct({
|
|
268
|
-
color: Schema.Union(Schema.Literal('red'), Schema.Literal('green'), Schema.Literal('blue')).annotations({
|
|
269
|
-
title: 'Color',
|
|
270
|
-
}),
|
|
271
|
-
}).pipe(Schema.mutable);
|
|
272
|
-
|
|
273
|
-
type ColorType = Schema.Schema.Type<typeof ColorSchema>;
|
|
274
|
-
|
|
275
|
-
export const Enum: StoryObj<StoryProps<ColorType>> = {
|
|
276
|
-
args: {
|
|
277
|
-
debug: true,
|
|
278
|
-
schema: ColorSchema,
|
|
279
|
-
readonly: false,
|
|
280
|
-
values: {
|
|
281
|
-
color: 'red',
|
|
282
|
-
},
|
|
283
|
-
},
|
|
284
|
-
};
|
|
285
|
-
|
|
286
|
-
//
|
|
287
|
-
// Refs
|
|
288
|
-
//
|
|
289
|
-
|
|
290
|
-
// const RefSchema = Schema.Struct({
|
|
291
|
-
// contact: Type.Ref(TestSchema.Person).annotations({ title: 'Contact Reference' }),
|
|
292
|
-
// optionalContact: Schema.optional(Type.Ref(TestSchema.Person).annotations({ title: 'Optional Contact Reference' })),
|
|
293
|
-
// refArray: Schema.optional(Schema.Array(Type.Ref(TestSchema.Person))),
|
|
294
|
-
// unknownExpando: Schema.optional(
|
|
295
|
-
// Type.Ref(TestSchema.Expando).annotations({ title: 'Optional Ref to an Expando (DXN Input)' }),
|
|
296
|
-
// ),
|
|
297
|
-
// });
|
|
298
|
-
|
|
299
|
-
// type RefSchema = Schema.Schema.Type<typeof RefSchema>;
|
|
300
|
-
|
|
301
|
-
// const contact1 = Obj.make(TestSchema.Person, { name: 'Alice' });
|
|
302
|
-
// const contact2 = Obj.make(TestSchema.Person, { name: 'Bob' });
|
|
303
|
-
|
|
304
|
-
// export const Refs: StoryObj<StoryProps<RefSchema>> = {
|
|
305
|
-
// render: RefStory,
|
|
306
|
-
// args: {
|
|
307
|
-
// debug: true,
|
|
308
|
-
// schema: RefSchema,
|
|
309
|
-
// readonly: false,
|
|
310
|
-
// values: {
|
|
311
|
-
// refArray: [Ref.make(contact1), Ref.make(contact2)],
|
|
312
|
-
// },
|
|
313
|
-
// },
|
|
314
|
-
// };
|
package/src/util/echo.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2025 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import { Obj } from '@dxos/echo';
|
|
6
|
-
import { type JsonPath, setValue as setValuePlain, splitJsonPath } from '@dxos/effect';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Sets a value on an object, using Obj.change() if it's an ECHO object.
|
|
10
|
-
*/
|
|
11
|
-
// TODO(wittjosiah): Consider refactoring Form to not know about ECHO at all.
|
|
12
|
-
// Instead of directly mutating the values object, Form could work with a plain
|
|
13
|
-
// object copy and communicate all mutations through callbacks (e.g., onValuesChanged).
|
|
14
|
-
// The caller would then be responsible for applying changes to ECHO objects via
|
|
15
|
-
// Obj.change(). This would keep Form agnostic to the underlying data layer and
|
|
16
|
-
// avoid coupling react-ui-form to @dxos/echo.
|
|
17
|
-
export const setValueEchoAware = <T extends object>(obj: T, path: JsonPath, value: any): T => {
|
|
18
|
-
if (Obj.isObject(obj)) {
|
|
19
|
-
Obj.change(obj, (mutableObj) => {
|
|
20
|
-
Obj.setValue(mutableObj, splitJsonPath(path), value);
|
|
21
|
-
});
|
|
22
|
-
return obj;
|
|
23
|
-
}
|
|
24
|
-
return setValuePlain(obj, path, value);
|
|
25
|
-
};
|