@dxos/react-ui-form 0.8.3-staging.0fa589b → 0.8.4-main.3a94e84

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.
Files changed (53) hide show
  1. package/dist/lib/browser/index.mjs +69 -75
  2. package/dist/lib/browser/index.mjs.map +3 -3
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node-esm/index.mjs +69 -75
  5. package/dist/lib/node-esm/index.mjs.map +3 -3
  6. package/dist/lib/node-esm/meta.json +1 -1
  7. package/dist/types/src/components/ControlSection/ControlSection.stories.d.ts +1 -1
  8. package/dist/types/src/components/ControlSection/ControlSection.stories.d.ts.map +1 -1
  9. package/dist/types/src/components/FieldEditor/FieldEditor.d.ts +3 -4
  10. package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
  11. package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts +3 -3
  12. package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts.map +1 -1
  13. package/dist/types/src/components/Form/Form.stories.d.ts +1 -1
  14. package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
  15. package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts +1 -1
  16. package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts.map +1 -1
  17. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts +2 -2
  18. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
  19. package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts +4 -4
  20. package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
  21. package/dist/types/src/components/deprecated/Form.d.ts +3 -3
  22. package/dist/types/src/components/deprecated/Form.d.ts.map +1 -1
  23. package/dist/types/src/components/deprecated/Form.stories.d.ts +1 -1
  24. package/dist/types/src/components/deprecated/Form.stories.d.ts.map +1 -1
  25. package/dist/types/src/index.d.ts +1 -1
  26. package/dist/types/src/index.d.ts.map +1 -1
  27. package/dist/types/src/translations.d.ts +56 -57
  28. package/dist/types/src/translations.d.ts.map +1 -1
  29. package/dist/types/tsconfig.tsbuildinfo +1 -1
  30. package/package.json +30 -32
  31. package/src/components/ControlSection/ControlSection.stories.tsx +2 -2
  32. package/src/components/FieldEditor/FieldEditor.stories.tsx +14 -12
  33. package/src/components/FieldEditor/FieldEditor.test.tsx +11 -11
  34. package/src/components/FieldEditor/FieldEditor.tsx +5 -15
  35. package/src/components/Form/ArrayField.tsx +1 -1
  36. package/src/components/Form/Form.stories.tsx +2 -2
  37. package/src/components/Form/RefField.tsx +1 -1
  38. package/src/components/Form/custom/SelectOptionsInput.stories.tsx +2 -2
  39. package/src/components/Form/custom/SelectOptionsInput.tsx +1 -1
  40. package/src/components/ViewEditor/ViewEditor.stories.tsx +16 -10
  41. package/src/components/ViewEditor/ViewEditor.test.tsx +37 -35
  42. package/src/components/ViewEditor/ViewEditor.tsx +17 -32
  43. package/src/components/deprecated/Form.stories.tsx +5 -5
  44. package/src/components/deprecated/Form.tsx +4 -4
  45. package/src/components/testing.tsx +1 -1
  46. package/src/index.ts +1 -1
  47. package/src/translations.ts +4 -2
  48. package/dist/lib/node/index.cjs +0 -2416
  49. package/dist/lib/node/index.cjs.map +0 -7
  50. package/dist/lib/node/meta.json +0 -1
  51. package/dist/types/src/components/ViewEditor/Test.stories.d.ts +0 -10
  52. package/dist/types/src/components/ViewEditor/Test.stories.d.ts.map +0 -1
  53. 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 ViewType, ViewProjection, VIEW_FIELD_LIMIT } from '@dxos/schema';
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: ViewType;
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 ViewProjection(jsonSchema, view);
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, view, readonly]);
91
+ }, [schema, projection, readonly]);
96
92
 
97
93
  const handleUpdate = useCallback(
98
- ({ name, typename }: ViewMetaType) => {
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
- [schema, view, onTypenameChanged, readonly],
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
- [schema, field, onDelete, readonly],
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
- [schema, view.fields, readonly],
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
- view: live(testView),
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
- view: live(testView),
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
- view: live(testView),
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 { type ViewType, getFieldValue, setFieldValue } from '@dxos/schema';
11
+ import { getFieldValue, setFieldValue, type Projection } from '@dxos/schema';
12
12
 
13
13
  export type DeprecatedFormProps<T extends {} = {}> = ThemedClassName<{
14
- view: ViewType;
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
- view,
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
- {view.fields.map((field) => {
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.Content classNames={[textBlockWidth, classNames]}>{children}</Card.Content>
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
@@ -2,7 +2,7 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import translations from './translations';
5
+ import { translations } from './translations';
6
6
 
7
7
  export * from './components';
8
8
  export * from './hooks';
@@ -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 default [
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[];