@dxos/react-ui-form 0.8.3-staging.0fa589b → 0.8.4-main.2e9d522
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 +69 -75
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +69 -75
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/components/ControlSection/ControlSection.stories.d.ts +1 -1
- package/dist/types/src/components/ControlSection/ControlSection.stories.d.ts.map +1 -1
- package/dist/types/src/components/FieldEditor/FieldEditor.d.ts +3 -4
- package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
- package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts +3 -3
- package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.stories.d.ts +1 -1
- package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts +1 -1
- package/dist/types/src/components/Form/custom/SelectOptionsInput.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 +4 -4
- package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/deprecated/Form.d.ts +3 -3
- package/dist/types/src/components/deprecated/Form.d.ts.map +1 -1
- package/dist/types/src/components/deprecated/Form.stories.d.ts +1 -1
- package/dist/types/src/components/deprecated/Form.stories.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +56 -57
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +30 -32
- package/src/components/ControlSection/ControlSection.stories.tsx +2 -2
- package/src/components/FieldEditor/FieldEditor.stories.tsx +14 -12
- package/src/components/FieldEditor/FieldEditor.test.tsx +11 -11
- package/src/components/FieldEditor/FieldEditor.tsx +5 -15
- package/src/components/Form/ArrayField.tsx +1 -1
- package/src/components/Form/Form.stories.tsx +2 -2
- package/src/components/Form/RefField.tsx +1 -1
- package/src/components/Form/custom/SelectOptionsInput.stories.tsx +2 -2
- package/src/components/Form/custom/SelectOptionsInput.tsx +1 -1
- package/src/components/ViewEditor/ViewEditor.stories.tsx +16 -10
- package/src/components/ViewEditor/ViewEditor.test.tsx +37 -35
- package/src/components/ViewEditor/ViewEditor.tsx +17 -32
- package/src/components/deprecated/Form.stories.tsx +5 -5
- package/src/components/deprecated/Form.tsx +4 -4
- package/src/components/testing.tsx +1 -1
- package/src/index.ts +1 -1
- package/src/translations.ts +4 -2
- package/dist/lib/node/index.cjs +0 -2416
- package/dist/lib/node/index.cjs.map +0 -7
- package/dist/lib/node/meta.json +0 -1
- package/dist/types/src/components/ViewEditor/Test.stories.d.ts +0 -10
- package/dist/types/src/components/ViewEditor/Test.stories.d.ts.map +0 -1
- package/src/components/ViewEditor/Test.stories.tsx +0 -45
|
@@ -12,7 +12,7 @@ import { Callout, IconButton, type ThemedClassName, useTranslation } from '@dxos
|
|
|
12
12
|
import { List } from '@dxos/react-ui-list';
|
|
13
13
|
import { cardSpacing } from '@dxos/react-ui-stack';
|
|
14
14
|
import { ghostHover, inputTextLabel, mx } from '@dxos/react-ui-theme';
|
|
15
|
-
import { FieldSchema, type FieldType, type
|
|
15
|
+
import { FieldSchema, type FieldType, VIEW_FIELD_LIMIT, type DataType, ProjectionModel } from '@dxos/schema';
|
|
16
16
|
|
|
17
17
|
import { translationKey } from '../../translations';
|
|
18
18
|
import { FieldEditor } from '../FieldEditor';
|
|
@@ -21,9 +21,6 @@ import { Form, type FormProps } from '../Form';
|
|
|
21
21
|
const grid = 'grid grid-cols-[32px_1fr_32px_32px] min-bs-[2.5rem]';
|
|
22
22
|
|
|
23
23
|
const ViewMetaSchema = Schema.Struct({
|
|
24
|
-
name: Schema.String.annotations({
|
|
25
|
-
title: 'View',
|
|
26
|
-
}),
|
|
27
24
|
typename: Format.URL.annotations({
|
|
28
25
|
title: 'Typename',
|
|
29
26
|
}),
|
|
@@ -34,7 +31,7 @@ type ViewMetaType = Schema.Schema.Type<typeof ViewMetaSchema>;
|
|
|
34
31
|
export type ViewEditorProps = ThemedClassName<
|
|
35
32
|
{
|
|
36
33
|
schema: Schema.Schema.AnyNoContext;
|
|
37
|
-
view:
|
|
34
|
+
view: DataType.View;
|
|
38
35
|
registry?: SchemaRegistry;
|
|
39
36
|
readonly?: boolean;
|
|
40
37
|
showHeading?: boolean;
|
|
@@ -61,20 +58,19 @@ export const ViewEditor = ({
|
|
|
61
58
|
const projection = useMemo(() => {
|
|
62
59
|
// Use reactive and mutable version of json schema when schema is mutable.
|
|
63
60
|
const jsonSchema = schema instanceof EchoSchema ? schema.jsonSchema : toJsonSchema(schema);
|
|
64
|
-
return new
|
|
65
|
-
}, [schema, view]);
|
|
61
|
+
return new ProjectionModel(jsonSchema, view.projection);
|
|
62
|
+
}, [schema, view.projection]);
|
|
66
63
|
const [field, setField] = useState<FieldType>();
|
|
67
64
|
const readonly = _readonly || !isMutable(schema);
|
|
68
65
|
|
|
69
66
|
// TODO(burdon): Should be reactive.
|
|
70
67
|
const viewValues = useMemo(() => {
|
|
71
68
|
return {
|
|
72
|
-
name: view.name,
|
|
73
69
|
// TODO(burdon): Need to warn user of possible consequences of editing.
|
|
74
70
|
// TODO(burdon): Settings should have domain name owned by user.
|
|
75
71
|
typename: view.query.typename,
|
|
76
72
|
};
|
|
77
|
-
}, [view]);
|
|
73
|
+
}, [view.query.typename]);
|
|
78
74
|
|
|
79
75
|
const handleSelect = useCallback(
|
|
80
76
|
(field: FieldType) => {
|
|
@@ -92,22 +88,18 @@ export const ViewEditor = ({
|
|
|
92
88
|
invariant(!readonly);
|
|
93
89
|
const field = projection.createFieldProjection();
|
|
94
90
|
setField(field);
|
|
95
|
-
}, [schema,
|
|
91
|
+
}, [schema, projection, readonly]);
|
|
96
92
|
|
|
97
93
|
const handleUpdate = useCallback(
|
|
98
|
-
({
|
|
94
|
+
({ typename }: ViewMetaType) => {
|
|
99
95
|
invariant(!readonly);
|
|
100
96
|
requestAnimationFrame(() => {
|
|
101
|
-
if (view.name !== name) {
|
|
102
|
-
view.name = name;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
97
|
if (view.query.typename !== typename && !readonly) {
|
|
106
98
|
onTypenameChanged?.(typename);
|
|
107
99
|
}
|
|
108
100
|
});
|
|
109
101
|
},
|
|
110
|
-
[
|
|
102
|
+
[view.query.typename, onTypenameChanged, readonly],
|
|
111
103
|
);
|
|
112
104
|
|
|
113
105
|
const handleDelete = useCallback(
|
|
@@ -119,19 +111,19 @@ export const ViewEditor = ({
|
|
|
119
111
|
|
|
120
112
|
onDelete?.(fieldId);
|
|
121
113
|
},
|
|
122
|
-
[
|
|
114
|
+
[field, onDelete, readonly],
|
|
123
115
|
);
|
|
124
116
|
|
|
125
117
|
const handleMove = useCallback(
|
|
126
118
|
(fromIndex: number, toIndex: number) => {
|
|
127
119
|
invariant(!readonly);
|
|
128
120
|
// NOTE(ZaymonFC): Using arrayMove here causes a race condition with the kanban model.
|
|
129
|
-
const fields = [...view.fields];
|
|
121
|
+
const fields = [...view.projection.fields];
|
|
130
122
|
const [moved] = fields.splice(fromIndex, 1);
|
|
131
123
|
fields.splice(toIndex, 0, moved);
|
|
132
|
-
view.fields = fields;
|
|
124
|
+
view.projection.fields = fields;
|
|
133
125
|
},
|
|
134
|
-
[
|
|
126
|
+
[view.projection.fields, readonly],
|
|
135
127
|
);
|
|
136
128
|
|
|
137
129
|
const handleClose = useCallback(() => setField(undefined), []);
|
|
@@ -179,7 +171,7 @@ export const ViewEditor = ({
|
|
|
179
171
|
<label className={mx(inputTextLabel)}>{t('fields label')}</label>
|
|
180
172
|
|
|
181
173
|
<List.Root<FieldType>
|
|
182
|
-
items={view.fields}
|
|
174
|
+
items={view.projection.fields}
|
|
183
175
|
isItem={Schema.is(FieldSchema)}
|
|
184
176
|
getId={(field) => field.id}
|
|
185
177
|
readonly={readonly}
|
|
@@ -207,13 +199,13 @@ export const ViewEditor = ({
|
|
|
207
199
|
data-testid='hide-field-button'
|
|
208
200
|
icon='ph--eye-slash--regular'
|
|
209
201
|
// TDOO(burdon): Is this the correct test?
|
|
210
|
-
disabled={view.fields.length <= 1}
|
|
202
|
+
disabled={view.projection.fields.length <= 1}
|
|
211
203
|
onClick={() => handleHide(field.id)}
|
|
212
204
|
/>
|
|
213
205
|
{/* TODO(burdon): Remove unless implement undo. */}
|
|
214
206
|
{!readonly && (
|
|
215
207
|
<List.ItemDeleteButton
|
|
216
|
-
disabled={view.fields.length <= 1}
|
|
208
|
+
disabled={view.projection.fields.length <= 1}
|
|
217
209
|
onClick={() => handleDelete(field.id)}
|
|
218
210
|
/>
|
|
219
211
|
)}
|
|
@@ -258,14 +250,7 @@ export const ViewEditor = ({
|
|
|
258
250
|
</div>
|
|
259
251
|
|
|
260
252
|
{field && (
|
|
261
|
-
<FieldEditor
|
|
262
|
-
key={field.id}
|
|
263
|
-
view={view}
|
|
264
|
-
projection={projection}
|
|
265
|
-
field={field}
|
|
266
|
-
registry={registry}
|
|
267
|
-
onSave={handleClose}
|
|
268
|
-
/>
|
|
253
|
+
<FieldEditor key={field.id} projection={projection} field={field} registry={registry} onSave={handleClose} />
|
|
269
254
|
)}
|
|
270
255
|
|
|
271
256
|
{!readonly && !field && (
|
|
@@ -275,7 +260,7 @@ export const ViewEditor = ({
|
|
|
275
260
|
label={t('button add property')}
|
|
276
261
|
onClick={readonly ? undefined : handleAdd}
|
|
277
262
|
// TODO(burdon): Show field limit in ux (not tooltip).
|
|
278
|
-
disabled={view.fields.length >= VIEW_FIELD_LIMIT}
|
|
263
|
+
disabled={view.projection.fields.length >= VIEW_FIELD_LIMIT}
|
|
279
264
|
classNames='flex is-full'
|
|
280
265
|
/>
|
|
281
266
|
</div>
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import '@dxos-theme';
|
|
6
6
|
|
|
7
|
-
import { type Meta, type StoryObj } from '@storybook/react';
|
|
7
|
+
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
8
8
|
import React from 'react';
|
|
9
9
|
|
|
10
10
|
import { live } from '@dxos/live-object';
|
|
@@ -12,7 +12,7 @@ import { testData, TestSchema, testView, type TestType } from '@dxos/schema/test
|
|
|
12
12
|
import { withLayout, withTheme } from '@dxos/storybook-utils';
|
|
13
13
|
|
|
14
14
|
import { DeprecatedForm, type DeprecatedFormProps } from './Form';
|
|
15
|
-
import translations from '../../translations';
|
|
15
|
+
import { translations } from '../../translations';
|
|
16
16
|
import { TestLayout, TestPanel } from '../testing';
|
|
17
17
|
|
|
18
18
|
const DefaultStory = (props: DeprecatedFormProps) => (
|
|
@@ -40,14 +40,14 @@ type Story = StoryObj<DeprecatedFormProps<TestType>>;
|
|
|
40
40
|
export const Default: Story = {
|
|
41
41
|
args: {
|
|
42
42
|
object: live(testData),
|
|
43
|
-
|
|
43
|
+
projection: live(testView).projection,
|
|
44
44
|
schema: TestSchema,
|
|
45
45
|
},
|
|
46
46
|
};
|
|
47
47
|
|
|
48
48
|
export const Empty: Story = {
|
|
49
49
|
args: {
|
|
50
|
-
|
|
50
|
+
projection: live(testView).projection,
|
|
51
51
|
schema: TestSchema,
|
|
52
52
|
},
|
|
53
53
|
};
|
|
@@ -55,7 +55,7 @@ export const Empty: Story = {
|
|
|
55
55
|
export const Readonly: Story = {
|
|
56
56
|
args: {
|
|
57
57
|
object: live(testData),
|
|
58
|
-
|
|
58
|
+
projection: live(testView).projection,
|
|
59
59
|
schema: TestSchema,
|
|
60
60
|
readonly: true,
|
|
61
61
|
},
|
|
@@ -8,10 +8,10 @@ import React, { useState } from 'react';
|
|
|
8
8
|
import { findProperty } from '@dxos/effect';
|
|
9
9
|
import { Input, type ThemedClassName, type TextInputProps as NativeTextInputProps } from '@dxos/react-ui';
|
|
10
10
|
import { mx } from '@dxos/react-ui-theme';
|
|
11
|
-
import {
|
|
11
|
+
import { getFieldValue, setFieldValue, type Projection } from '@dxos/schema';
|
|
12
12
|
|
|
13
13
|
export type DeprecatedFormProps<T extends {} = {}> = ThemedClassName<{
|
|
14
|
-
|
|
14
|
+
projection: Projection;
|
|
15
15
|
object: T;
|
|
16
16
|
schema?: Schema.Schema<T>;
|
|
17
17
|
readonly?: boolean;
|
|
@@ -22,14 +22,14 @@ export type DeprecatedFormProps<T extends {} = {}> = ThemedClassName<{
|
|
|
22
22
|
*/
|
|
23
23
|
export const DeprecatedForm = <T extends {} = {}>({
|
|
24
24
|
classNames,
|
|
25
|
-
|
|
25
|
+
projection,
|
|
26
26
|
object,
|
|
27
27
|
schema,
|
|
28
28
|
readonly,
|
|
29
29
|
}: DeprecatedFormProps<T>) => {
|
|
30
30
|
return (
|
|
31
31
|
<div role='none' className={mx('flex flex-col w-full gap-2 p-2', classNames)}>
|
|
32
|
-
{
|
|
32
|
+
{projection.fields.map((field) => {
|
|
33
33
|
const prop = schema && findProperty(schema, field.path);
|
|
34
34
|
const title = (prop && pipe(SchemaAST.getTitleAnnotation(prop), Option.getOrUndefined)) ?? '';
|
|
35
35
|
const description = (prop && pipe(SchemaAST.getDescriptionAnnotation(prop), Option.getOrUndefined)) ?? title;
|
|
@@ -17,7 +17,7 @@ export const TestLayout = ({ classNames, json, children }: ThemedClassName<Props
|
|
|
17
17
|
);
|
|
18
18
|
|
|
19
19
|
export const TestPanel = ({ classNames, children }: ThemedClassName<PropsWithChildren>) => (
|
|
20
|
-
<Card.
|
|
20
|
+
<Card.StaticRoot classNames={[textBlockWidth, classNames]}>{children}</Card.StaticRoot>
|
|
21
21
|
);
|
|
22
22
|
|
|
23
23
|
// Symbol for accessing debug objects in tests.
|
package/src/index.ts
CHANGED
package/src/translations.ts
CHANGED
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import { type Resource } from '@dxos/react-ui';
|
|
6
|
+
|
|
5
7
|
export const translationKey = 'react-ui-form';
|
|
6
8
|
|
|
7
|
-
export
|
|
9
|
+
export const translations = [
|
|
8
10
|
{
|
|
9
11
|
'en-US': {
|
|
10
12
|
[translationKey]: {
|
|
@@ -75,4 +77,4 @@ export default [
|
|
|
75
77
|
},
|
|
76
78
|
},
|
|
77
79
|
},
|
|
78
|
-
];
|
|
80
|
+
] as const satisfies Resource[];
|