@dxos/react-ui-form 0.8.4-main.406dc2a → 0.8.4-main.548089c

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 (37) hide show
  1. package/dist/lib/browser/index.mjs +30 -23
  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 +30 -23
  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 +2 -3
  8. package/dist/types/src/components/ControlSection/ControlSection.stories.d.ts.map +1 -1
  9. package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts +2 -3
  10. package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts.map +1 -1
  11. package/dist/types/src/components/Form/Form.d.ts +2 -1
  12. package/dist/types/src/components/Form/Form.d.ts.map +1 -1
  13. package/dist/types/src/components/Form/Form.stories.d.ts +3 -4
  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 +2 -3
  16. package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts.map +1 -1
  17. package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts +2 -3
  18. package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts.map +1 -1
  19. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts +5 -5
  20. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
  21. package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts +4 -5
  22. package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
  23. package/dist/types/src/translations.d.ts +2 -3
  24. package/dist/types/src/translations.d.ts.map +1 -1
  25. package/dist/types/tsconfig.tsbuildinfo +1 -1
  26. package/package.json +32 -31
  27. package/src/components/Form/Defaults.tsx +1 -1
  28. package/src/components/Form/Form.stories.tsx +3 -3
  29. package/src/components/Form/Form.tsx +3 -1
  30. package/src/components/Form/FormActions.tsx +2 -2
  31. package/src/components/Form/custom/SelectOptionsInput.tsx +1 -1
  32. package/src/components/ObjectPicker/ObjectPicker.stories.tsx +5 -5
  33. package/src/components/ViewEditor/ViewEditor.stories.tsx +11 -10
  34. package/src/components/ViewEditor/ViewEditor.test.tsx +2 -2
  35. package/src/components/ViewEditor/ViewEditor.tsx +10 -7
  36. package/src/translations.ts +2 -3
  37. package/src/util/refs.ts +5 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/react-ui-form",
3
- "version": "0.8.4-main.406dc2a",
3
+ "version": "0.8.4-main.548089c",
4
4
  "description": "Data components.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -32,50 +32,51 @@
32
32
  "@radix-ui/react-context": "1.1.1",
33
33
  "date-fns": "^3.3.1",
34
34
  "jsonpath": "^1.1.1",
35
- "@dxos/async": "0.8.4-main.406dc2a",
36
- "@dxos/debug": "0.8.4-main.406dc2a",
37
- "@dxos/echo": "0.8.4-main.406dc2a",
38
- "@dxos/echo-db": "0.8.4-main.406dc2a",
39
- "@dxos/echo-query": "0.8.4-main.406dc2a",
40
- "@dxos/effect": "0.8.4-main.406dc2a",
41
- "@dxos/invariant": "0.8.4-main.406dc2a",
42
- "@dxos/keys": "0.8.4-main.406dc2a",
43
- "@dxos/live-object": "0.8.4-main.406dc2a",
44
- "@dxos/lit-ui": "0.8.4-main.406dc2a",
45
- "@dxos/log": "0.8.4-main.406dc2a",
46
- "@dxos/react-client": "0.8.4-main.406dc2a",
47
- "@dxos/react-ui-components": "0.8.4-main.406dc2a",
48
- "@dxos/react-ui-editor": "0.8.4-main.406dc2a",
49
- "@dxos/react-ui-list": "0.8.4-main.406dc2a",
50
- "@dxos/react-ui-pickers": "0.8.4-main.406dc2a",
51
- "@dxos/react-ui-searchlist": "0.8.4-main.406dc2a",
52
- "@dxos/react-ui-types": "0.8.4-main.406dc2a",
53
- "@dxos/schema": "0.8.4-main.406dc2a",
54
- "@dxos/react-ui-stack": "0.8.4-main.406dc2a",
55
- "@dxos/util": "0.8.4-main.406dc2a"
35
+ "@dxos/async": "0.8.4-main.548089c",
36
+ "@dxos/debug": "0.8.4-main.548089c",
37
+ "@dxos/echo": "0.8.4-main.548089c",
38
+ "@dxos/echo-query": "0.8.4-main.548089c",
39
+ "@dxos/echo-db": "0.8.4-main.548089c",
40
+ "@dxos/invariant": "0.8.4-main.548089c",
41
+ "@dxos/effect": "0.8.4-main.548089c",
42
+ "@dxos/keys": "0.8.4-main.548089c",
43
+ "@dxos/lit-ui": "0.8.4-main.548089c",
44
+ "@dxos/log": "0.8.4-main.548089c",
45
+ "@dxos/react-client": "0.8.4-main.548089c",
46
+ "@dxos/live-object": "0.8.4-main.548089c",
47
+ "@dxos/react-ui-components": "0.8.4-main.548089c",
48
+ "@dxos/react-ui-pickers": "0.8.4-main.548089c",
49
+ "@dxos/react-ui-editor": "0.8.4-main.548089c",
50
+ "@dxos/react-ui-searchlist": "0.8.4-main.548089c",
51
+ "@dxos/react-ui-stack": "0.8.4-main.548089c",
52
+ "@dxos/react-ui-list": "0.8.4-main.548089c",
53
+ "@dxos/schema": "0.8.4-main.548089c",
54
+ "@dxos/react-ui-types": "0.8.4-main.548089c",
55
+ "@dxos/types": "0.8.4-main.548089c",
56
+ "@dxos/util": "0.8.4-main.548089c"
56
57
  },
57
58
  "devDependencies": {
58
59
  "@types/jsonpath": "^0.2.4",
59
60
  "@types/react": "~19.2.2",
60
- "@types/react-dom": "~19.2.1",
61
+ "@types/react-dom": "~19.2.2",
61
62
  "effect": "3.18.3",
62
63
  "fast-check": "^3.19.0",
63
64
  "react": "~19.2.0",
64
65
  "react-dom": "~19.2.0",
65
66
  "vite": "7.1.9",
66
- "@dxos/echo-signals": "0.8.4-main.406dc2a",
67
- "@dxos/random": "0.8.4-main.406dc2a",
68
- "@dxos/react-ui": "0.8.4-main.406dc2a",
69
- "@dxos/react-ui-syntax-highlighter": "0.8.4-main.406dc2a",
70
- "@dxos/react-ui-theme": "0.8.4-main.406dc2a",
71
- "@dxos/storybook-utils": "0.8.4-main.406dc2a"
67
+ "@dxos/echo-signals": "0.8.4-main.548089c",
68
+ "@dxos/random": "0.8.4-main.548089c",
69
+ "@dxos/react-ui": "0.8.4-main.548089c",
70
+ "@dxos/react-ui-syntax-highlighter": "0.8.4-main.548089c",
71
+ "@dxos/react-ui-theme": "0.8.4-main.548089c",
72
+ "@dxos/storybook-utils": "0.8.4-main.548089c"
72
73
  },
73
74
  "peerDependencies": {
74
75
  "effect": "^3.13.3",
75
76
  "react": "^19.0.0",
76
77
  "react-dom": "^19.0.0",
77
- "@dxos/react-ui": "0.8.4-main.406dc2a",
78
- "@dxos/react-ui-theme": "0.8.4-main.406dc2a"
78
+ "@dxos/react-ui": "0.8.4-main.548089c",
79
+ "@dxos/react-ui-theme": "0.8.4-main.548089c"
79
80
  },
80
81
  "publishConfig": {
81
82
  "access": "public"
@@ -192,7 +192,7 @@ export const MarkdownInput = ({
192
192
  disabled={!!readonly}
193
193
  placeholder={placeholder}
194
194
  value={getValue() ?? ''}
195
- classNames={'min-bs-auto max-h-40 overflow-auto'}
195
+ classNames={'min-bs-auto max-bs-40 overflow-auto'}
196
196
  onChange={(event) => onValueChange(type, event.target.value)}
197
197
  onBlur={onBlur}
198
198
  style={{ resize: 'none' }}
@@ -54,7 +54,7 @@ const DefaultStory = <T extends BaseObject = any>({
54
54
  const RefStory = <T extends BaseObject = any>(props: StoryProps<T>) => {
55
55
  const onQueryRefOptions = useCallback((typeInfo: TypeAnnotation) => {
56
56
  switch (typeInfo.typename) {
57
- case ContactType.typename:
57
+ case Testing.Person.typename:
58
58
  return [
59
59
  { dxn: getObjectDXN(contact1)!, label: 'John Coltraine' },
60
60
  { dxn: getObjectDXN(contact2)!, label: 'Erykah Badu' },
@@ -147,10 +147,10 @@ export const OrganizationAutoSave: Story = {
147
147
  // TODO(burdon): Type issue with employer reference.
148
148
  // TODO(burdon): Test table/form with compound values (e.g., address).
149
149
  // Property name is missing in type EncodedReference but required in type
150
- export const Contact: Story = {
150
+ export const Person: Story = {
151
151
  args: {
152
152
  debug: true,
153
- schema: Testing.ContactSchema,
153
+ schema: Testing.Person,
154
154
  values: {
155
155
  name: 'Bot',
156
156
  },
@@ -29,6 +29,7 @@ export type ComponentLookup = (args: {
29
29
  export type CustomInputMap = Partial<Record<string, InputComponent>>;
30
30
 
31
31
  export type FormProps<T extends BaseObject> = ThemedClassName<{
32
+ id?: string;
32
33
  values: Partial<T>;
33
34
  // TODO(burdon): Autofocus first input.
34
35
  autoFocus?: boolean;
@@ -46,6 +47,7 @@ export type FormProps<T extends BaseObject> = ThemedClassName<{
46
47
 
47
48
  export const Form = <T extends BaseObject>({
48
49
  classNames,
50
+ id,
49
51
  testId,
50
52
  values: initialValues,
51
53
  autoFocus,
@@ -93,7 +95,7 @@ export const Form = <T extends BaseObject>({
93
95
  onValid={handleValid}
94
96
  onSave={onSave}
95
97
  >
96
- <div role='none' className='contents' data-testid={testId}>
98
+ <div role='none' className='contents' {...(id && { 'data-object-id': id })} data-testid={testId}>
97
99
  <FormFields
98
100
  {...props}
99
101
  ref={formRef}
@@ -37,7 +37,7 @@ export const FormActions = ({ readonly, onCancel, outerSpacing = true }: FormAct
37
37
  )}
38
38
  >
39
39
  {onCancel && !readonly && (
40
- <IconButton data-testid='cancel-button' icon='ph--x--regular' label={t('button cancel')} onClick={onCancel} />
40
+ <IconButton data-testid='cancel-button' icon='ph--x--regular' label={t('cancel button')} onClick={onCancel} />
41
41
  )}
42
42
  {handleSave && (
43
43
  <IconButton
@@ -45,7 +45,7 @@ export const FormActions = ({ readonly, onCancel, outerSpacing = true }: FormAct
45
45
  data-testid='save-button'
46
46
  disabled={!canSave}
47
47
  icon='ph--check--regular'
48
- label={t('button save')}
48
+ label={t('save button')}
49
49
  onClick={handleSave}
50
50
  />
51
51
  )}
@@ -121,7 +121,7 @@ export const SelectOptionInput = ({ type, label, readonly, getStatus, getValue,
121
121
  readonly={!!readonly}
122
122
  >
123
123
  {({ items }) => (
124
- <div role='list' className='w-full overflow-auto'>
124
+ <div role='list' className='is-full overflow-auto'>
125
125
  {items?.map((item) => (
126
126
  <div key={item.id}>
127
127
  <List.Item
@@ -13,7 +13,7 @@ import { Filter, useQuery } from '@dxos/react-client/echo';
13
13
  import { useClientProvider, withClientProvider } from '@dxos/react-client/testing';
14
14
  import { Button } from '@dxos/react-ui';
15
15
  import { withTheme } from '@dxos/react-ui/testing';
16
- import { DataType } from '@dxos/schema';
16
+ import { Person } from '@dxos/types';
17
17
 
18
18
  import { translations } from '../../translations';
19
19
 
@@ -22,12 +22,12 @@ import { ObjectPicker } from './ObjectPicker';
22
22
  faker.seed(1);
23
23
 
24
24
  const createPerson = () =>
25
- Obj.make(DataType.Person, {
25
+ Obj.make(Person.Person, {
26
26
  fullName: faker.person.fullName(),
27
27
  });
28
28
 
29
29
  const omitId = Schema.omit<any, any, ['id']>('id');
30
- const personSchema = omitId(DataType.Person);
30
+ const personSchema = omitId(Person.Person);
31
31
 
32
32
  // Mock functions for testing
33
33
  const mockHandleSelect = fn();
@@ -65,7 +65,7 @@ const DefaultStory = () => {
65
65
  (values: any) => {
66
66
  console.log('[on create]', values);
67
67
  if (!space) return;
68
- const newPerson = space.db.add(Obj.make(DataType.Person, values));
68
+ const newPerson = space.db.add(Obj.make(Person.Person, values));
69
69
  mockHandleCreate(values);
70
70
  return newPerson;
71
71
  },
@@ -101,7 +101,7 @@ const meta = {
101
101
  decorators: [
102
102
  withTheme,
103
103
  withClientProvider({
104
- types: [DataType.Person],
104
+ types: [Person.Person],
105
105
  createIdentity: true,
106
106
  createSpace: true,
107
107
  }),
@@ -12,7 +12,8 @@ import { useQuery } from '@dxos/react-client/echo';
12
12
  import { useClientProvider, withClientProvider } from '@dxos/react-client/testing';
13
13
  import { useAsyncEffect } from '@dxos/react-ui';
14
14
  import { withTheme } from '@dxos/react-ui/testing';
15
- import { DataType, type ProjectionModel, createView, getTypenameFromQuery } from '@dxos/schema';
15
+ import { type ProjectionModel, View, getTypenameFromQuery } from '@dxos/schema';
16
+ import { Employer, Organization, Person, Project } from '@dxos/types';
16
17
 
17
18
  import { translations } from '../../translations';
18
19
  import { TestLayout, TestPanel, VIEW_EDITOR_DEBUG_SYMBOL } from '../testing';
@@ -21,16 +22,16 @@ import { ViewEditor, type ViewEditorProps } from './ViewEditor';
21
22
 
22
23
  const types = [
23
24
  // TODO(burdon): Get label from annotation.
24
- { value: Type.getTypename(DataType.Organization), label: 'Organization' },
25
- { value: Type.getTypename(DataType.Person), label: 'Person' },
26
- { value: Type.getTypename(DataType.Project), label: 'Project' },
27
- { value: Type.getTypename(DataType.Employer), label: 'Employer' },
25
+ { value: Organization.Organization.typename, label: 'Organization' },
26
+ { value: Person.Person.typename, label: 'Person' },
27
+ { value: Type.getTypename(Project.Project), label: 'Project' },
28
+ { value: Employer.Employer.typename, label: 'Employer' },
28
29
  ];
29
30
 
30
31
  // Type definition for debug objects exposed to tests.
31
32
  export type ViewEditorDebugObjects = {
32
33
  schema: EchoSchema;
33
- view: DataType.View;
34
+ view: View.View;
34
35
  projection: ProjectionModel;
35
36
  };
36
37
 
@@ -39,7 +40,7 @@ type StoryProps = Pick<ViewEditorProps, 'readonly' | 'mode'>;
39
40
  const DefaultStory = (props: StoryProps) => {
40
41
  const { space } = useClientProvider();
41
42
  const [schema, setSchema] = useState<EchoSchema>();
42
- const [view, setView] = useState<DataType.View>();
43
+ const [view, setView] = useState<View.View>();
43
44
  const projectionRef = useRef<ProjectionModel>(null);
44
45
 
45
46
  const tags = useQuery(space, Filter.type(Tag.Tag));
@@ -69,9 +70,9 @@ const DefaultStory = (props: StoryProps) => {
69
70
  );
70
71
 
71
72
  const [testSchema] = await space.db.schemaRegistry.register([TestSchema, AlternateSchema]);
72
- const view = createView({
73
+ const view = View.make({
73
74
  name: 'Test',
74
- query: Query.select(Filter.typename(TestSchema.typename)),
75
+ query: Query.select(Filter.type(TestSchema)),
75
76
  jsonSchema: Type.toJsonSchema(TestSchema),
76
77
  presentation: Obj.make(Type.Expando, {}),
77
78
  });
@@ -98,7 +99,7 @@ const DefaultStory = (props: StoryProps) => {
98
99
  return;
99
100
  }
100
101
 
101
- const newView = createView({
102
+ const newView = View.make({
102
103
  query,
103
104
  jsonSchema: newSchema.jsonSchema,
104
105
  presentation: Obj.make(Type.Expando, {}),
@@ -7,7 +7,7 @@ import { cleanup, fireEvent, screen, waitFor } from '@testing-library/react';
7
7
  import { afterEach, describe, expect, test } from 'vitest';
8
8
 
9
9
  import { EchoSchema, isInstanceOf } from '@dxos/echo/internal';
10
- import { DataType, ProjectionModel } from '@dxos/schema';
10
+ import { ProjectionModel, View } from '@dxos/schema';
11
11
 
12
12
  import { VIEW_EDITOR_DEBUG_SYMBOL } from '../testing';
13
13
 
@@ -20,7 +20,7 @@ const getViewEditorDebugObjects = (): ViewEditorDebugObjects => {
20
20
  const debugObjects = (window as any)[VIEW_EDITOR_DEBUG_SYMBOL] as ViewEditorDebugObjects;
21
21
  expect(debugObjects).toBeDefined();
22
22
  expect(debugObjects.schema).toBeInstanceOf(EchoSchema);
23
- expect(isInstanceOf(DataType.View, debugObjects.view)).toBeTruthy();
23
+ expect(isInstanceOf(View.View, debugObjects.view)).toBeTruthy();
24
24
  expect(debugObjects.projection).toBeInstanceOf(ProjectionModel);
25
25
  return debugObjects;
26
26
  };
@@ -18,11 +18,11 @@ import { List } from '@dxos/react-ui-list';
18
18
  import { cardSpacing } from '@dxos/react-ui-stack';
19
19
  import { inputTextLabel, mx, subtleHover } from '@dxos/react-ui-theme';
20
20
  import {
21
- type DataType,
22
21
  FieldSchema,
23
22
  type FieldType,
24
23
  ProjectionModel,
25
24
  VIEW_FIELD_LIMIT,
25
+ type View,
26
26
  getTypenameFromQuery,
27
27
  } from '@dxos/schema';
28
28
 
@@ -36,8 +36,8 @@ const listItemGrid = 'grid grid-cols-subgrid col-span-5';
36
36
  export type ViewEditorProps = ThemedClassName<
37
37
  {
38
38
  schema: Schema.Schema.AnyNoContext;
39
- view: DataType.View;
40
- mode?: 'schema' | 'query';
39
+ view: View.View;
40
+ mode?: 'schema' | 'query' | 'named-query';
41
41
  registry?: SchemaRegistry;
42
42
  readonly?: boolean;
43
43
  showHeading?: boolean;
@@ -96,10 +96,13 @@ export const ViewEditor = forwardRef<ProjectionModel, ViewEditorProps>(
96
96
  : QueryAST.Query.annotations({ title: 'Query' }),
97
97
  });
98
98
 
99
- if (mode === 'query') {
100
- return Schema.Struct({
99
+ if (mode === 'query' || mode === 'named-query') {
100
+ const name = Schema.Struct({
101
101
  name: Schema.optional(Schema.String.annotations({ title: 'Name' })),
102
- ...base.fields,
102
+ });
103
+
104
+ return Schema.Struct({
105
+ ...(mode === 'named-query' ? { ...name.fields, ...base.fields } : base.fields),
103
106
  target: Schema.optional(Schema.String.annotations({ title: 'Target Queue' })),
104
107
  }).pipe(Schema.mutable);
105
108
  }
@@ -300,7 +303,7 @@ export const ViewEditor = forwardRef<ProjectionModel, ViewEditorProps>(
300
303
  <div role='none' className={outerSpacing ? cardSpacing : 'mlb-cardSpacingBlock'}>
301
304
  <IconButton
302
305
  icon='ph--plus--regular'
303
- label={t('button add property')}
306
+ label={t('add property button')}
304
307
  onClick={readonly ? undefined : handleAdd}
305
308
  // TODO(burdon): Show field limit in ux (not tooltip).
306
309
  disabled={view.projection.fields.length >= VIEW_FIELD_LIMIT}
@@ -15,7 +15,7 @@ export const translations = [
15
15
  'empty readonly ref field label': '(none)',
16
16
 
17
17
  // TODO(burdon): Standardize field/property.
18
- 'button add property': 'Add property',
18
+ 'add property button': 'Add property',
19
19
  'field property label': 'Property',
20
20
  'field property placeholder': 'Property name',
21
21
  'field format label': 'Type',
@@ -33,8 +33,7 @@ export const translations = [
33
33
  'ref field placeholder_other': 'Select items…',
34
34
 
35
35
  // TODO(burdon): Factor out?
36
- 'button cancel': 'Cancel',
37
- 'button save': 'Save',
36
+ 'save button': 'Save',
38
37
 
39
38
  // FormatEnum
40
39
  'format boolean': 'Boolean',
package/src/util/refs.ts CHANGED
@@ -18,11 +18,6 @@ type RefProps = {
18
18
  export const getRefProps = (property: SchemaProperty<any>): RefProps | undefined => {
19
19
  const { ast, format, array } = property;
20
20
 
21
- // Direct reference.
22
- if (format === FormatEnum.Ref) {
23
- return { ast, isArray: false };
24
- }
25
-
26
21
  // Array of references.
27
22
  if (array) {
28
23
  const elementType = findArrayElementType(ast);
@@ -34,5 +29,10 @@ export const getRefProps = (property: SchemaProperty<any>): RefProps | undefined
34
29
  }
35
30
  }
36
31
 
32
+ // Direct reference.
33
+ if (format === FormatEnum.Ref) {
34
+ return { ast, isArray: false };
35
+ }
36
+
37
37
  return undefined;
38
38
  };