@dxos/react-ui-form 0.8.4-main.9735255 → 0.8.4-main.9be5663bfe
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 +989 -674
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +989 -674
- 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 +62 -61
- package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.d.ts +23 -18
- package/dist/types/src/components/Form/Form.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.stories.d.ts +68 -67
- package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormField.d.ts +7 -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 +8 -6
- package/dist/types/src/components/Form/fields/RefField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/SelectOptionField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/SelectOptionField.stories.d.ts +62 -61
- package/dist/types/src/components/Form/fields/SelectOptionField.stories.d.ts.map +1 -1
- package/dist/types/src/components/ObjectForm/ObjectForm.d.ts +9 -0
- package/dist/types/src/components/ObjectForm/ObjectForm.d.ts.map +1 -0
- package/dist/types/src/components/ObjectForm/index.d.ts +2 -0
- package/dist/types/src/components/ObjectForm/index.d.ts.map +1 -0
- package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts +10 -2
- package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts.map +1 -1
- package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts +62 -61
- package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts.map +1 -1
- package/dist/types/src/components/ObjectProperties/ObjectProperties.d.ts +9 -0
- package/dist/types/src/components/ObjectProperties/ObjectProperties.d.ts.map +1 -0
- package/dist/types/src/components/ObjectProperties/ObjectProperties.stories.d.ts +83 -0
- package/dist/types/src/components/ObjectProperties/ObjectProperties.stories.d.ts.map +1 -0
- package/dist/types/src/components/ObjectProperties/index.d.ts +2 -0
- package/dist/types/src/components/ObjectProperties/index.d.ts.map +1 -0
- package/dist/types/src/components/Settings/Settings.d.ts +35 -0
- package/dist/types/src/components/Settings/Settings.d.ts.map +1 -0
- package/dist/types/src/components/Settings/Settings.stories.d.ts +82 -0
- 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 +66 -64
- package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +3 -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/hooks/useKeyHandler.d.ts +2 -1
- package/dist/types/src/hooks/useKeyHandler.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +62 -61
- package/dist/types/src/translations.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/src/util/refs.d.ts +1 -0
- package/dist/types/src/util/refs.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +37 -38
- package/src/components/FieldEditor/FieldEditor.stories.tsx +7 -8
- package/src/components/FieldEditor/FieldEditor.test.tsx +0 -1
- package/src/components/FieldEditor/FieldEditor.tsx +3 -4
- package/src/components/Form/AUDIT.md +17 -0
- package/src/components/Form/Form.stories.tsx +25 -26
- package/src/components/Form/Form.tsx +100 -66
- package/src/components/Form/FormField.tsx +32 -14
- package/src/components/Form/FormFieldComponent.stories.tsx +5 -5
- package/src/components/Form/FormFieldComponent.tsx +17 -20
- package/src/components/Form/FormFieldSet.tsx +126 -105
- package/src/components/Form/fields/ArrayField.tsx +11 -8
- package/src/components/Form/fields/GeoPointField.tsx +6 -6
- package/src/components/Form/fields/MarkdownField.tsx +1 -1
- package/src/components/Form/fields/RefField.tsx +37 -20
- package/src/components/Form/fields/SelectField.tsx +1 -1
- package/src/components/Form/fields/SelectOptionField.stories.tsx +2 -3
- package/src/components/Form/fields/SelectOptionField.tsx +9 -10
- package/src/components/Form/fields/TupleField.tsx +1 -1
- package/src/components/ObjectForm/ObjectForm.tsx +113 -0
- package/src/components/{ControlSection → ObjectForm}/index.ts +1 -1
- package/src/components/ObjectPicker/ObjectPicker.stories.tsx +13 -18
- package/src/components/ObjectPicker/ObjectPicker.tsx +71 -60
- package/src/components/ObjectProperties/ObjectProperties.stories.tsx +63 -0
- package/src/components/ObjectProperties/ObjectProperties.tsx +129 -0
- package/src/components/ObjectProperties/index.ts +5 -0
- package/src/components/Settings/Settings.stories.tsx +55 -0
- package/src/components/Settings/Settings.tsx +129 -0
- package/src/components/Settings/index.ts +5 -0
- package/src/components/ViewEditor/ViewEditor.stories.tsx +36 -33
- package/src/components/ViewEditor/ViewEditor.test.tsx +3 -7
- package/src/components/ViewEditor/ViewEditor.tsx +99 -70
- package/src/components/index.ts +3 -1
- package/src/components/testing.tsx +20 -8
- package/src/hooks/useFormHandler.ts +42 -24
- package/src/hooks/useKeyHandler.tsx +7 -7
- package/src/translations.ts +63 -63
- package/src/util/index.ts +0 -1
- package/src/util/refs.ts +7 -3
- 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 +0 -87
- 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,131 +0,0 @@
|
|
|
1
|
-
import { type StoryObj } from '@storybook/react-vite';
|
|
2
|
-
import * as Schema from 'effect/Schema';
|
|
3
|
-
import React from 'react';
|
|
4
|
-
import { type AnyProperties } from '@dxos/echo/internal';
|
|
5
|
-
import { type FormRootProps } from './Form';
|
|
6
|
-
type StoryProps<T extends AnyProperties> = {
|
|
7
|
-
debug?: boolean;
|
|
8
|
-
schema: Schema.Schema.AnyNoContext;
|
|
9
|
-
} & FormRootProps<T>;
|
|
10
|
-
declare const meta: {
|
|
11
|
-
title: string;
|
|
12
|
-
component: any;
|
|
13
|
-
render: <T extends AnyProperties = any>({ debug, schema, values: valuesProp, ...props }: StoryProps<T>) => React.JSX.Element;
|
|
14
|
-
decorators: import("@storybook/react").Decorator[];
|
|
15
|
-
parameters: {
|
|
16
|
-
layout: string;
|
|
17
|
-
translations: [{
|
|
18
|
-
readonly 'en-US': {
|
|
19
|
-
readonly "@dxos/react-ui-form": {
|
|
20
|
-
readonly 'fields label': "Fields";
|
|
21
|
-
readonly 'hidden fields label': "Hidden Fields";
|
|
22
|
-
readonly 'empty readonly ref field label': "(none)";
|
|
23
|
-
readonly 'add property button label': "Add property";
|
|
24
|
-
readonly 'field property label': "Property";
|
|
25
|
-
readonly 'field property placeholder': "Property name";
|
|
26
|
-
readonly 'field format label': "Type";
|
|
27
|
-
readonly 'field path label': "Field path";
|
|
28
|
-
readonly 'add field': "Add field";
|
|
29
|
-
readonly 'delete field': "Delete field";
|
|
30
|
-
readonly 'field limit reached': "Maximum number of fields reached";
|
|
31
|
-
readonly 'boolean input true value': "Yes";
|
|
32
|
-
readonly 'boolean input false value': "No";
|
|
33
|
-
readonly 'show field label': "Show field";
|
|
34
|
-
readonly 'hide field label': "Hide field";
|
|
35
|
-
readonly 'delete field label': "Delete field";
|
|
36
|
-
readonly 'ref field combobox input placeholder': "Search…";
|
|
37
|
-
readonly 'ref field placeholder_one': "Select…";
|
|
38
|
-
readonly 'ref field placeholder_other': "Select items…";
|
|
39
|
-
readonly 'example placeholder': "Example";
|
|
40
|
-
readonly 'latitude placeholder': "Latitude (e.g., 40.7128)";
|
|
41
|
-
readonly 'longitude placeholder': "Longitude (e.g., -74.0060)";
|
|
42
|
-
readonly 'cancel button label': "Cancel";
|
|
43
|
-
readonly 'save button label': "Save";
|
|
44
|
-
readonly 'format boolean': "Boolean";
|
|
45
|
-
readonly 'format currency': "Currency";
|
|
46
|
-
readonly 'format date': "Date";
|
|
47
|
-
readonly 'format date-time': "DateTime";
|
|
48
|
-
readonly 'format did': "DID";
|
|
49
|
-
readonly 'format duration': "Duration";
|
|
50
|
-
readonly 'format dxn': "DXN";
|
|
51
|
-
readonly 'format email': "Email";
|
|
52
|
-
readonly 'format formula': "Formula";
|
|
53
|
-
readonly 'format hostname': "Hostname";
|
|
54
|
-
readonly 'format integer': "Integer";
|
|
55
|
-
readonly 'format json': "JSON";
|
|
56
|
-
readonly 'format lnglat': "Geopoint";
|
|
57
|
-
readonly 'format markdown': "Markdown";
|
|
58
|
-
readonly 'format percent': "Percent";
|
|
59
|
-
readonly 'format ref': "Reference";
|
|
60
|
-
readonly 'format regex': "RegExp";
|
|
61
|
-
readonly 'format string': "String";
|
|
62
|
-
readonly 'format single-select': "Select";
|
|
63
|
-
readonly 'format multi-select': "Multi-select";
|
|
64
|
-
readonly 'format text': "Long text";
|
|
65
|
-
readonly 'format time': "Time";
|
|
66
|
-
readonly 'format timestamp': "Timestamp";
|
|
67
|
-
readonly 'format user': "User";
|
|
68
|
-
readonly 'format number': "Number";
|
|
69
|
-
readonly 'format uri': "URI";
|
|
70
|
-
readonly 'format url': "URL";
|
|
71
|
-
readonly 'format uuid': "UUID";
|
|
72
|
-
readonly 'latitude label': "Latitude";
|
|
73
|
-
readonly 'longitude label': "Longitude";
|
|
74
|
-
readonly 'select option label': "Label";
|
|
75
|
-
readonly 'select option label placeholder': "Option label";
|
|
76
|
-
readonly 'select option color': "Color";
|
|
77
|
-
readonly 'select option delete': "Delete";
|
|
78
|
-
readonly 'select option add': "Add option";
|
|
79
|
-
readonly 'system schema title': "System type";
|
|
80
|
-
readonly 'system schema description': "System type: cannot add or remove fields.";
|
|
81
|
-
};
|
|
82
|
-
};
|
|
83
|
-
}];
|
|
84
|
-
};
|
|
85
|
-
argTypes: {
|
|
86
|
-
readonly: {
|
|
87
|
-
control: "boolean";
|
|
88
|
-
description: string;
|
|
89
|
-
};
|
|
90
|
-
};
|
|
91
|
-
};
|
|
92
|
-
export default meta;
|
|
93
|
-
type Story = StoryObj<typeof meta>;
|
|
94
|
-
export declare const Default: Story;
|
|
95
|
-
export declare const Organization: Story;
|
|
96
|
-
export declare const OrganizationAutoSave: Story;
|
|
97
|
-
export declare const Person: Story;
|
|
98
|
-
declare const ShapeSchema: Schema.mutable<Schema.Struct<{
|
|
99
|
-
shape: Schema.optional<Schema.Union<[Schema.Struct<{
|
|
100
|
-
type: Schema.Literal<["circle"]>;
|
|
101
|
-
radius: Schema.optional<Schema.SchemaClass<number, number, never>>;
|
|
102
|
-
}>, Schema.Struct<{
|
|
103
|
-
type: Schema.Literal<["square"]>;
|
|
104
|
-
size: Schema.optional<Schema.refine<number, typeof Schema.Number>>;
|
|
105
|
-
}>]>>;
|
|
106
|
-
}>>;
|
|
107
|
-
type ShapeSchema = Schema.Schema.Type<typeof ShapeSchema>;
|
|
108
|
-
export declare const DiscriminatedShape: StoryObj<StoryProps<ShapeSchema>>;
|
|
109
|
-
declare const ArraysSchema: Schema.mutable<Schema.Struct<{
|
|
110
|
-
names: Schema.Array$<Schema.filter<typeof Schema.String>>;
|
|
111
|
-
addresses: Schema.Array$<Schema.Struct<{
|
|
112
|
-
street: Schema.optional<Schema.SchemaClass<string, string, never>>;
|
|
113
|
-
city: Schema.optional<Schema.SchemaClass<string, string, never>>;
|
|
114
|
-
zip: Schema.optional<Schema.refine<string, typeof Schema.String>>;
|
|
115
|
-
location: Schema.optional<Schema.Tuple<[Schema.filter<Schema.transform<Schema.SchemaClass<number, number, never>, Schema.filter<Schema.SchemaClass<number, number, never>>>>, Schema.filter<Schema.transform<Schema.SchemaClass<number, number, never>, Schema.filter<Schema.SchemaClass<number, number, never>>>>, Schema.Element<typeof Schema.Number, "?">]>>;
|
|
116
|
-
}>>;
|
|
117
|
-
}>>;
|
|
118
|
-
type ArraysSchema = Schema.Schema.Type<typeof ArraysSchema>;
|
|
119
|
-
export declare const Arrays: StoryObj<StoryProps<ArraysSchema>>;
|
|
120
|
-
declare const TupleSchema: Schema.mutable<Schema.Struct<{
|
|
121
|
-
tuple: Schema.Tuple<[typeof Schema.Number, typeof Schema.String, typeof Schema.Boolean]>;
|
|
122
|
-
geopoint: Schema.Tuple<[Schema.filter<Schema.transform<Schema.SchemaClass<number, number, never>, Schema.filter<Schema.SchemaClass<number, number, never>>>>, Schema.filter<Schema.transform<Schema.SchemaClass<number, number, never>, Schema.filter<Schema.SchemaClass<number, number, never>>>>, Schema.Element<typeof Schema.Number, "?">]>;
|
|
123
|
-
}>>;
|
|
124
|
-
type TupleSchema = Schema.Schema.Type<typeof TupleSchema>;
|
|
125
|
-
export declare const Tuple: StoryObj<StoryProps<TupleSchema>>;
|
|
126
|
-
declare const ColorSchema: Schema.mutable<Schema.Struct<{
|
|
127
|
-
color: Schema.Union<[Schema.Literal<["red"]>, Schema.Literal<["green"]>, Schema.Literal<["blue"]>]>;
|
|
128
|
-
}>>;
|
|
129
|
-
type ColorType = Schema.Schema.Type<typeof ColorSchema>;
|
|
130
|
-
export declare const Enum: StoryObj<StoryProps<ColorType>>;
|
|
131
|
-
//# sourceMappingURL=Form-old.stories.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Form-old.stories.d.ts","sourceRoot":"","sources":["../../../../../src/components/Form/Form-old.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAa,KAAK,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAgC,MAAM,OAAO,CAAC;AAGrD,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AASzD,OAAO,EAAQ,KAAK,aAAa,EAAE,MAAM,QAAQ,CAAC;AAIlD,KAAK,UAAU,CAAC,CAAC,SAAS,aAAa,IAAI;IACzC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC;CACpC,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;AAuErB,QAAA,MAAM,IAAI;;eAEgB,GAAG;aAvEP,CAAC,SAAS,aAAa,yDAK1C,UAAU,CAAC,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+EiB,CAAC;AAElC,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,OAAO,EAAE,KAYrB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAU1B,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,KAWlC,CAAC;AAKF,eAAO,MAAM,MAAM,EAAE,KAQpB,CAAC;AAMF,QAAA,MAAM,WAAW;;;;;;;;GAaM,CAAC;AAExB,KAAK,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,WAAW,CAAC,CAAC;AAE1D,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CAAC,UAAU,CAAC,WAAW,CAAC,CAuBhE,CAAC;AAMF,QAAA,MAAM,YAAY;;;;;;;;GAGK,CAAC;AAExB,KAAK,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,YAAY,CAAC,CAAC;AAE5D,eAAO,MAAM,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,YAAY,CAAC,CAUrD,CAAC;AAOF,QAAA,MAAM,WAAW;;;GAGM,CAAC;AAExB,KAAK,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,WAAW,CAAC,CAAC;AAE1D,eAAO,MAAM,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,WAAW,CAAC,CAUnD,CAAC;AAMF,QAAA,MAAM,WAAW;;GAIM,CAAC;AAExB,KAAK,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,WAAW,CAAC,CAAC;AAExD,eAAO,MAAM,IAAI,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,CAShD,CAAC"}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { type JsonPath } from '@dxos/effect';
|
|
2
|
-
/**
|
|
3
|
-
* Sets a value on an object, using Obj.change() if it's an ECHO object.
|
|
4
|
-
*/
|
|
5
|
-
export declare const setValueEchoAware: <T extends object>(obj: T, path: JsonPath, value: any) => T;
|
|
6
|
-
//# sourceMappingURL=echo.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"echo.d.ts","sourceRoot":"","sources":["../../../../src/util/echo.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,QAAQ,EAA4C,MAAM,cAAc,CAAC;AAEvF;;GAEG;AAOH,eAAO,MAAM,iBAAiB,GAAI,CAAC,SAAS,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,QAAQ,EAAE,OAAO,GAAG,KAAG,CAQxF,CAAC"}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2024 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
6
|
-
import React from 'react';
|
|
7
|
-
|
|
8
|
-
import { withTheme } from '@dxos/react-ui/testing';
|
|
9
|
-
|
|
10
|
-
import { translations } from '../../translations';
|
|
11
|
-
|
|
12
|
-
import { ControlPage, ControlSection } from './ControlSection';
|
|
13
|
-
|
|
14
|
-
const meta = {
|
|
15
|
-
title: 'ui/react-ui-form/ControlSection',
|
|
16
|
-
component: ControlSection,
|
|
17
|
-
render: (args) => (
|
|
18
|
-
<ControlPage classNames='is-[40rem]'>
|
|
19
|
-
<ControlSection {...args} />
|
|
20
|
-
</ControlPage>
|
|
21
|
-
),
|
|
22
|
-
decorators: [withTheme],
|
|
23
|
-
parameters: {
|
|
24
|
-
layout: 'centered',
|
|
25
|
-
translations,
|
|
26
|
-
},
|
|
27
|
-
} satisfies Meta<typeof ControlSection>;
|
|
28
|
-
|
|
29
|
-
export default meta;
|
|
30
|
-
|
|
31
|
-
type Story = StoryObj<typeof meta>;
|
|
32
|
-
|
|
33
|
-
export const Default: Story = {
|
|
34
|
-
args: {
|
|
35
|
-
title: 'Control Section',
|
|
36
|
-
description: 'This is a control section',
|
|
37
|
-
},
|
|
38
|
-
};
|
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2025 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import React, { type ComponentPropsWithoutRef, type PropsWithChildren } from 'react';
|
|
6
|
-
|
|
7
|
-
import {
|
|
8
|
-
Button,
|
|
9
|
-
type ButtonProps,
|
|
10
|
-
Input,
|
|
11
|
-
type Label,
|
|
12
|
-
type ThemedClassName,
|
|
13
|
-
toLocalizedString,
|
|
14
|
-
useTranslation,
|
|
15
|
-
} from '@dxos/react-ui';
|
|
16
|
-
import { Layout } from '@dxos/react-ui-mosaic';
|
|
17
|
-
import { mx } from '@dxos/ui-theme';
|
|
18
|
-
|
|
19
|
-
import { translationKey } from '../../translations';
|
|
20
|
-
|
|
21
|
-
export type ControlPageParams = ThemedClassName<ComponentPropsWithoutRef<'div'>>;
|
|
22
|
-
|
|
23
|
-
export const ControlPage = ({ children, classNames, ...props }: ControlPageParams) => {
|
|
24
|
-
return (
|
|
25
|
-
<Layout.Container scrollable classNames='[--control-spacing:var(--dx-trimMd)]'>
|
|
26
|
-
<div role='none' className={mx('pli-cardSpacingInline pbe-trimMd', classNames)} {...props}>
|
|
27
|
-
{children}
|
|
28
|
-
</div>
|
|
29
|
-
</Layout.Container>
|
|
30
|
-
);
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
export type ControlSectionProps = PropsWithChildren<{
|
|
34
|
-
title: Label;
|
|
35
|
-
description?: Label;
|
|
36
|
-
}>;
|
|
37
|
-
|
|
38
|
-
export const ControlSection = ({ title, description, children }: ControlSectionProps) => {
|
|
39
|
-
return (
|
|
40
|
-
<>
|
|
41
|
-
<ControlSectionHeading title={title} description={description} />
|
|
42
|
-
{children}
|
|
43
|
-
</>
|
|
44
|
-
);
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
export const ControlSectionHeading = ({ title, description }: Omit<ControlSectionProps, 'children'>) => {
|
|
48
|
-
const { t } = useTranslation(translationKey);
|
|
49
|
-
return (
|
|
50
|
-
<>
|
|
51
|
-
<h2 className='pli-trimMd container-max-width text-xl mbs-trimMd mbe-trimMd'>{toLocalizedString(title, t)}</h2>
|
|
52
|
-
{description && (
|
|
53
|
-
<p className='pli-trimMd mlb-trimMd container-max-width text-description'>
|
|
54
|
-
{toLocalizedString(description, t)}
|
|
55
|
-
</p>
|
|
56
|
-
)}
|
|
57
|
-
</>
|
|
58
|
-
);
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
export const ControlGroupButton = ({ classNames, ...props }: ButtonProps) => {
|
|
62
|
-
return <Button {...props} classNames={['md:col-span-2', classNames]} />;
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
export type ControlGroupProps = ThemedClassName<PropsWithChildren>;
|
|
66
|
-
|
|
67
|
-
export const ControlGroup = ({ children, classNames }: ControlGroupProps) => (
|
|
68
|
-
<div
|
|
69
|
-
role='none'
|
|
70
|
-
className={mx(
|
|
71
|
-
'group container-max-width grid grid-cols-1 md:grid-cols-[1fr_min-content] gap-trimMd',
|
|
72
|
-
'[--control-spacing:0px] [&_input]:justify-self-end [&_button]:justify-self-end',
|
|
73
|
-
classNames,
|
|
74
|
-
)}
|
|
75
|
-
>
|
|
76
|
-
{children}
|
|
77
|
-
</div>
|
|
78
|
-
);
|
|
79
|
-
|
|
80
|
-
export const ControlFrame = ({ children }: ControlGroupProps) => (
|
|
81
|
-
<div
|
|
82
|
-
role='none'
|
|
83
|
-
className={mx(
|
|
84
|
-
'container-max-width grid grid-cols-1 md:grid-cols-[1fr_1fr] gap-trimSm md:gap-trimMd p-trimMd',
|
|
85
|
-
'border border-separator rounded-md',
|
|
86
|
-
)}
|
|
87
|
-
>
|
|
88
|
-
{children}
|
|
89
|
-
</div>
|
|
90
|
-
);
|
|
91
|
-
|
|
92
|
-
export const controlItemClasses = mx([
|
|
93
|
-
'container-max-width grid md:col-span-2 grid-cols-subgrid gap-trimSm items-center',
|
|
94
|
-
// TODO(burdon): Use grid gap consistently or apply margins consistently?
|
|
95
|
-
'mlb-[--control-spacing] *:first:!mbs-0 *:last:!mbe-0 pli-trimMd plb-trimMd',
|
|
96
|
-
'border border-separator rounded-md',
|
|
97
|
-
]);
|
|
98
|
-
|
|
99
|
-
const controlItemTitleClasses = 'mbe-0 text-lg text-baseText font-normal';
|
|
100
|
-
const controlItemDescriptionClasses = 'mlb-trimSm md:mbe-0 text-base text-description';
|
|
101
|
-
|
|
102
|
-
export type ControlItemProps = PropsWithChildren<{
|
|
103
|
-
title: Label;
|
|
104
|
-
description?: Label;
|
|
105
|
-
}>;
|
|
106
|
-
|
|
107
|
-
export const ControlItem = ({ title, description, children }: ControlItemProps) => {
|
|
108
|
-
const { t } = useTranslation(translationKey);
|
|
109
|
-
|
|
110
|
-
return (
|
|
111
|
-
<div className={controlItemClasses}>
|
|
112
|
-
<div role='none'>
|
|
113
|
-
<h3 className={controlItemTitleClasses}>{toLocalizedString(title, t)}</h3>
|
|
114
|
-
{description && <p className={controlItemDescriptionClasses}>{toLocalizedString(description, t)}</p>}
|
|
115
|
-
</div>
|
|
116
|
-
{children}
|
|
117
|
-
</div>
|
|
118
|
-
);
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
export const ControlItemInput = ({ title, description, children }: ControlItemProps) => {
|
|
122
|
-
const { t } = useTranslation(translationKey);
|
|
123
|
-
|
|
124
|
-
return (
|
|
125
|
-
<Input.Root>
|
|
126
|
-
<div className={controlItemClasses}>
|
|
127
|
-
<div role='none'>
|
|
128
|
-
<Input.Label classNames={controlItemTitleClasses}>{toLocalizedString(title, t)}</Input.Label>
|
|
129
|
-
{description && (
|
|
130
|
-
<Input.DescriptionAndValidation>
|
|
131
|
-
<Input.Description classNames={controlItemDescriptionClasses}>
|
|
132
|
-
{toLocalizedString(description, t)}
|
|
133
|
-
</Input.Description>
|
|
134
|
-
</Input.DescriptionAndValidation>
|
|
135
|
-
)}
|
|
136
|
-
</div>
|
|
137
|
-
{children}
|
|
138
|
-
</div>
|
|
139
|
-
</Input.Root>
|
|
140
|
-
);
|
|
141
|
-
};
|
|
142
|
-
|
|
143
|
-
export const ControlFrameItem = ({ title, description, children }: ControlItemProps) => {
|
|
144
|
-
const { t } = useTranslation(translationKey);
|
|
145
|
-
|
|
146
|
-
return (
|
|
147
|
-
<div role='group' className='min-is-0'>
|
|
148
|
-
<h3 className='text-lg mbe-2'>{toLocalizedString(title, t)}</h3>
|
|
149
|
-
{description && <p className='mlb-trimSm md:mbe-0 text-description'>{toLocalizedString(description, t)}</p>}
|
|
150
|
-
{children}
|
|
151
|
-
</div>
|
|
152
|
-
);
|
|
153
|
-
};
|
|
@@ -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
|
-
};
|