@dxos/react-ui-table 0.8.4-main.bc674ce → 0.8.4-main.bcb3aa67d6

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 (108) hide show
  1. package/dist/lib/browser/{chunk-OZBLY7XM.mjs → chunk-BF54SSNL.mjs} +12 -18
  2. package/dist/lib/browser/chunk-BF54SSNL.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-I5IFW7UF.mjs → chunk-EK6D2CVM.mjs} +37 -32
  4. package/dist/lib/browser/chunk-EK6D2CVM.mjs.map +7 -0
  5. package/dist/lib/browser/index.mjs +200 -173
  6. package/dist/lib/browser/index.mjs.map +4 -4
  7. package/dist/lib/browser/meta.json +1 -1
  8. package/dist/lib/browser/testing/index.mjs +4 -4
  9. package/dist/lib/browser/testing/index.mjs.map +2 -2
  10. package/dist/lib/browser/types/index.mjs +1 -1
  11. package/dist/lib/node-esm/{chunk-DDJKYJFY.mjs → chunk-LYYDF6JP.mjs} +37 -32
  12. package/dist/lib/node-esm/chunk-LYYDF6JP.mjs.map +7 -0
  13. package/dist/lib/node-esm/{chunk-WNZSKIRF.mjs → chunk-SIRDIPHZ.mjs} +12 -18
  14. package/dist/lib/node-esm/chunk-SIRDIPHZ.mjs.map +7 -0
  15. package/dist/lib/node-esm/index.mjs +200 -173
  16. package/dist/lib/node-esm/index.mjs.map +4 -4
  17. package/dist/lib/node-esm/meta.json +1 -1
  18. package/dist/lib/node-esm/testing/index.mjs +4 -4
  19. package/dist/lib/node-esm/testing/index.mjs.map +2 -2
  20. package/dist/lib/node-esm/types/index.mjs +1 -1
  21. package/dist/types/src/components/Table/ColumnSettings.d.ts.map +1 -1
  22. package/dist/types/src/components/Table/DynamicTable.d.ts +5 -4
  23. package/dist/types/src/components/Table/DynamicTable.d.ts.map +1 -1
  24. package/dist/types/src/components/Table/DynamicTable.stories.d.ts +20 -22
  25. package/dist/types/src/components/Table/DynamicTable.stories.d.ts.map +1 -1
  26. package/dist/types/src/components/Table/Relations.stories.d.ts +80 -82
  27. package/dist/types/src/components/Table/Relations.stories.d.ts.map +1 -1
  28. package/dist/types/src/components/Table/Table.d.ts +28 -21
  29. package/dist/types/src/components/Table/Table.d.ts.map +1 -1
  30. package/dist/types/src/components/Table/Table.stories.d.ts +82 -84
  31. package/dist/types/src/components/Table/Table.stories.d.ts.map +1 -1
  32. package/dist/types/src/components/Table/TableContent.d.ts +21 -0
  33. package/dist/types/src/components/Table/TableContent.d.ts.map +1 -0
  34. package/dist/types/src/components/Table/TableToolbar.d.ts +25 -0
  35. package/dist/types/src/components/Table/TableToolbar.d.ts.map +1 -0
  36. package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts +3 -3
  37. package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts.map +1 -1
  38. package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts +2 -2
  39. package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts.map +1 -1
  40. package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts +22 -24
  41. package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts.map +1 -1
  42. package/dist/types/src/components/index.d.ts +0 -1
  43. package/dist/types/src/components/index.d.ts.map +1 -1
  44. package/dist/types/src/hooks/useAddRow.d.ts +1 -1
  45. package/dist/types/src/hooks/useAddRow.d.ts.map +1 -1
  46. package/dist/types/src/hooks/useProjectionModel.d.ts +1 -1
  47. package/dist/types/src/hooks/useProjectionModel.d.ts.map +1 -1
  48. package/dist/types/src/hooks/useTableModel.d.ts +1 -1
  49. package/dist/types/src/model/table-model.d.ts +5 -4
  50. package/dist/types/src/model/table-model.d.ts.map +1 -1
  51. package/dist/types/src/model/table-presentation.d.ts.map +1 -1
  52. package/dist/types/src/playwright/TableManager.d.ts +2 -1
  53. package/dist/types/src/playwright/TableManager.d.ts.map +1 -1
  54. package/dist/types/src/testing/useTestTableModel.d.ts +2 -2
  55. package/dist/types/src/testing/useTestTableModel.d.ts.map +1 -1
  56. package/dist/types/src/translations.d.ts +19 -21
  57. package/dist/types/src/translations.d.ts.map +1 -1
  58. package/dist/types/src/types/Table.d.ts +1 -6
  59. package/dist/types/src/types/Table.d.ts.map +1 -1
  60. package/dist/types/src/util/dynamic-table.d.ts +6 -5
  61. package/dist/types/src/util/dynamic-table.d.ts.map +1 -1
  62. package/dist/types/src/util/dynamic-table.test.d.ts +2 -0
  63. package/dist/types/src/util/dynamic-table.test.d.ts.map +1 -0
  64. package/dist/types/src/util/query-ast.d.ts.map +1 -1
  65. package/dist/types/tsconfig.tsbuildinfo +1 -1
  66. package/package.json +43 -43
  67. package/src/components/Table/ColumnActionsMenu.tsx +5 -5
  68. package/src/components/Table/ColumnSettings.tsx +3 -4
  69. package/src/components/Table/DynamicTable.stories.tsx +6 -5
  70. package/src/components/Table/DynamicTable.tsx +13 -19
  71. package/src/components/Table/Relations.stories.tsx +35 -25
  72. package/src/components/Table/Table.stories.tsx +61 -40
  73. package/src/components/Table/Table.tsx +41 -434
  74. package/src/components/Table/TableContent.tsx +422 -0
  75. package/src/components/{TableToolbar → Table}/TableToolbar.tsx +35 -42
  76. package/src/components/TableCellEditor/CellValidationMessage.tsx +4 -4
  77. package/src/components/TableCellEditor/FormCellEditor.tsx +12 -6
  78. package/src/components/TableCellEditor/TableCellEditor.stories.tsx +6 -5
  79. package/src/components/TableCellEditor/TableCellEditor.tsx +10 -5
  80. package/src/components/index.ts +0 -1
  81. package/src/components/testing.ts +1 -1
  82. package/src/hooks/useAddRow.ts +1 -1
  83. package/src/hooks/useProjectionModel.ts +3 -3
  84. package/src/hooks/useTableModel.ts +1 -1
  85. package/src/model/table-model.test.ts +5 -5
  86. package/src/model/table-model.ts +13 -12
  87. package/src/model/table-presentation.test.ts +5 -5
  88. package/src/model/table-presentation.ts +12 -11
  89. package/src/playwright/TableManager.ts +10 -3
  90. package/src/playwright/playwright.config.ts +1 -1
  91. package/src/playwright/smoke.spec.ts +45 -2
  92. package/src/testing/useTestTableModel.ts +4 -4
  93. package/src/translations.ts +19 -21
  94. package/src/types/Table.ts +11 -22
  95. package/src/util/dynamic-table.test.ts +70 -0
  96. package/src/util/dynamic-table.ts +17 -16
  97. package/src/util/query-ast.ts +3 -0
  98. package/src/util/table-buttons.ts +1 -1
  99. package/src/util/table-controls.ts +2 -2
  100. package/dist/lib/browser/chunk-I5IFW7UF.mjs.map +0 -7
  101. package/dist/lib/browser/chunk-OZBLY7XM.mjs.map +0 -7
  102. package/dist/lib/node-esm/chunk-DDJKYJFY.mjs.map +0 -7
  103. package/dist/lib/node-esm/chunk-WNZSKIRF.mjs.map +0 -7
  104. package/dist/types/src/components/TableToolbar/TableToolbar.d.ts +0 -21
  105. package/dist/types/src/components/TableToolbar/TableToolbar.d.ts.map +0 -1
  106. package/dist/types/src/components/TableToolbar/index.d.ts +0 -2
  107. package/dist/types/src/components/TableToolbar/index.d.ts.map +0 -1
  108. package/src/components/TableToolbar/index.ts +0 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/react-ui-table",
3
- "version": "0.8.4-main.bc674ce",
3
+ "version": "0.8.4-main.bcb3aa67d6",
4
4
  "description": "A table component.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -60,66 +60,66 @@
60
60
  "@codemirror/autocomplete": "^6.19.0",
61
61
  "@codemirror/state": "^6.5.2",
62
62
  "@codemirror/view": "^6.38.4",
63
- "@effect-atom/atom-react": "^0.4.6",
63
+ "@effect-atom/atom-react": "^0.5.0",
64
64
  "@fluentui/react-tabster": "9.26.11",
65
65
  "@radix-ui/react-context": "1.1.1",
66
66
  "@radix-ui/react-primitive": "2.0.2",
67
67
  "@radix-ui/react-slot": "1.1.2",
68
68
  "@radix-ui/react-use-controllable-state": "1.1.0",
69
- "date-fns": "^3.3.1",
69
+ "date-fns": "^3.6.0",
70
70
  "lodash.orderby": "^4.6.0",
71
- "@dxos/async": "0.8.4-main.bc674ce",
72
- "@dxos/context": "0.8.4-main.bc674ce",
73
- "@dxos/debug": "0.8.4-main.bc674ce",
74
- "@dxos/echo": "0.8.4-main.bc674ce",
75
- "@dxos/echo-atom": "0.8.4-main.bc674ce",
76
- "@dxos/effect": "0.8.4-main.bc674ce",
77
- "@dxos/invariant": "0.8.4-main.bc674ce",
78
- "@dxos/keys": "0.8.4-main.bc674ce",
79
- "@dxos/lit-grid": "0.8.4-main.bc674ce",
80
- "@dxos/log": "0.8.4-main.bc674ce",
81
- "@dxos/react-client": "0.8.4-main.bc674ce",
82
- "@dxos/random": "0.8.4-main.bc674ce",
83
- "@dxos/react-ui-components": "0.8.4-main.bc674ce",
84
- "@dxos/react-ui-attention": "0.8.4-main.bc674ce",
85
- "@dxos/react-ui-form": "0.8.4-main.bc674ce",
86
- "@dxos/react-ui-editor": "0.8.4-main.bc674ce",
87
- "@dxos/react-ui-grid": "0.8.4-main.bc674ce",
88
- "@dxos/react-ui-searchlist": "0.8.4-main.bc674ce",
89
- "@dxos/react-ui-menu": "0.8.4-main.bc674ce",
90
- "@dxos/react-ui-stack": "0.8.4-main.bc674ce",
91
- "@dxos/react-ui-syntax-highlighter": "0.8.4-main.bc674ce",
92
- "@dxos/types": "0.8.4-main.bc674ce",
93
- "@dxos/ui-types": "0.8.4-main.bc674ce",
94
- "@dxos/schema": "0.8.4-main.bc674ce",
95
- "@dxos/util": "0.8.4-main.bc674ce"
71
+ "@dxos/async": "0.8.4-main.bcb3aa67d6",
72
+ "@dxos/context": "0.8.4-main.bcb3aa67d6",
73
+ "@dxos/debug": "0.8.4-main.bcb3aa67d6",
74
+ "@dxos/echo": "0.8.4-main.bcb3aa67d6",
75
+ "@dxos/echo-atom": "0.8.4-main.bcb3aa67d6",
76
+ "@dxos/invariant": "0.8.4-main.bcb3aa67d6",
77
+ "@dxos/effect": "0.8.4-main.bcb3aa67d6",
78
+ "@dxos/lit-grid": "0.8.4-main.bcb3aa67d6",
79
+ "@dxos/keys": "0.8.4-main.bcb3aa67d6",
80
+ "@dxos/random": "0.8.4-main.bcb3aa67d6",
81
+ "@dxos/react-client": "0.8.4-main.bcb3aa67d6",
82
+ "@dxos/react-ui-attention": "0.8.4-main.bcb3aa67d6",
83
+ "@dxos/react-ui-components": "0.8.4-main.bcb3aa67d6",
84
+ "@dxos/react-ui-editor": "0.8.4-main.bcb3aa67d6",
85
+ "@dxos/log": "0.8.4-main.bcb3aa67d6",
86
+ "@dxos/react-ui-form": "0.8.4-main.bcb3aa67d6",
87
+ "@dxos/react-ui-grid": "0.8.4-main.bcb3aa67d6",
88
+ "@dxos/react-ui-menu": "0.8.4-main.bcb3aa67d6",
89
+ "@dxos/react-ui-search": "0.8.4-main.bcb3aa67d6",
90
+ "@dxos/react-ui-stack": "0.8.4-main.bcb3aa67d6",
91
+ "@dxos/react-ui-syntax-highlighter": "0.8.4-main.bcb3aa67d6",
92
+ "@dxos/schema": "0.8.4-main.bcb3aa67d6",
93
+ "@dxos/types": "0.8.4-main.bcb3aa67d6",
94
+ "@dxos/util": "0.8.4-main.bcb3aa67d6",
95
+ "@dxos/ui-types": "0.8.4-main.bcb3aa67d6"
96
96
  },
97
97
  "devDependencies": {
98
- "@effect/platform": "0.93.6",
98
+ "@effect/platform": "0.94.4",
99
99
  "@types/lodash.orderby": "^4.6.9",
100
100
  "@types/react": "~19.2.7",
101
101
  "@types/react-dom": "~19.2.3",
102
- "effect": "3.19.11",
102
+ "effect": "3.20.0",
103
103
  "fast-check": "^3.19.0",
104
104
  "react": "~19.2.3",
105
105
  "react-dom": "~19.2.3",
106
- "vite": "7.1.9",
107
- "@dxos/random": "0.8.4-main.bc674ce",
108
- "@dxos/lit-ui": "0.8.4-main.bc674ce",
109
- "@dxos/react-client": "0.8.4-main.bc674ce",
110
- "@dxos/react-ui": "0.8.4-main.bc674ce",
111
- "@dxos/storybook-utils": "0.8.4-main.bc674ce",
112
- "@dxos/ui-theme": "0.8.4-main.bc674ce",
113
- "@dxos/test-utils": "0.8.4-main.bc674ce"
106
+ "vite": "^7.1.11",
107
+ "@dxos/lit-ui": "0.8.4-main.bcb3aa67d6",
108
+ "@dxos/react-client": "0.8.4-main.bcb3aa67d6",
109
+ "@dxos/random": "0.8.4-main.bcb3aa67d6",
110
+ "@dxos/react-ui": "0.8.4-main.bcb3aa67d6",
111
+ "@dxos/storybook-utils": "0.8.4-main.bcb3aa67d6",
112
+ "@dxos/ui-theme": "0.8.4-main.bcb3aa67d6",
113
+ "@dxos/test-utils": "0.8.4-main.bcb3aa67d6"
114
114
  },
115
115
  "peerDependencies": {
116
- "@effect-atom/atom-react": "^0.4.6",
117
- "@effect/platform": "0.93.6",
118
- "effect": "3.19.11",
116
+ "@effect-atom/atom-react": "^0.5.0",
117
+ "@effect/platform": "0.94.4",
118
+ "effect": "3.20.0",
119
119
  "react": "~19.2.3",
120
120
  "react-dom": "~19.2.3",
121
- "@dxos/react-ui": "0.8.4-main.bc674ce",
122
- "@dxos/ui-theme": "0.8.4-main.bc674ce"
121
+ "@dxos/ui-theme": "0.8.4-main.bcb3aa67d6",
122
+ "@dxos/react-ui": "0.8.4-main.bcb3aa67d6"
123
123
  },
124
124
  "publishConfig": {
125
125
  "access": "public"
@@ -36,7 +36,7 @@ export const ColumnActionsMenu = ({ model, modals }: ColumnActionsMenuProps) =>
36
36
  data-testid='column-sort-descending'
37
37
  onClick={() => model.setSort(state.fieldId, 'desc')}
38
38
  >
39
- {t('column action sort descending')}
39
+ {t('column-action-sort-descending.menu')}
40
40
  </DropdownMenu.Item>
41
41
  )}
42
42
  {(!isCurrentColumnSorted || currentSort?.direction === 'desc') && (
@@ -44,22 +44,22 @@ export const ColumnActionsMenu = ({ model, modals }: ColumnActionsMenuProps) =>
44
44
  data-testid='column-sort-ascending'
45
45
  onClick={() => model.setSort(state.fieldId, 'asc')}
46
46
  >
47
- {t('column action sort ascending')}
47
+ {t('column-action-sort-ascending.menu')}
48
48
  </DropdownMenu.Item>
49
49
  )}
50
50
  {isCurrentColumnSorted && (
51
51
  <DropdownMenu.Item data-testid='column-clear-sort' onClick={() => model.clearSort()}>
52
- {t('column action clear sorting')}
52
+ {t('column-action-clear-sorting.menu')}
53
53
  </DropdownMenu.Item>
54
54
  )}
55
55
  {model.getColumnCount() > 1 && model.features.schemaEditable && (
56
56
  <DropdownMenu.Item data-testid='column-delete' onClick={() => model.deleteColumn(state.fieldId)}>
57
- {t('column action delete')}
57
+ {t('column-action-delete.menu')}
58
58
  </DropdownMenu.Item>
59
59
  )}
60
60
  {model.features.schemaEditable && (
61
61
  <DropdownMenu.Item data-testid='column-settings' onClick={() => modals.openColumnSettings()}>
62
- {t('column action settings')}
62
+ {t('column-action-settings.menu')}
63
63
  </DropdownMenu.Item>
64
64
  )}
65
65
  </DropdownMenu.Viewport>
@@ -5,10 +5,9 @@
5
5
  import { useAtomValue } from '@effect-atom/atom-react';
6
6
  import React, { useCallback, useEffect, useMemo, useState } from 'react';
7
7
 
8
- import { type SchemaRegistry } from '@dxos/echo';
8
+ import { type SchemaRegistry, type View } from '@dxos/echo';
9
9
  import { Popover } from '@dxos/react-ui';
10
10
  import { FieldEditor } from '@dxos/react-ui-form';
11
- import { type FieldType } from '@dxos/schema';
12
11
 
13
12
  import { type ModalController, type TableModel } from '../../model';
14
13
 
@@ -20,7 +19,7 @@ type ColumnSettingsProps = {
20
19
  };
21
20
 
22
21
  export const ColumnSettings = ({ registry, model, modals, onNewColumn }: ColumnSettingsProps) => {
23
- const [newField, setNewField] = useState<FieldType>();
22
+ const [newField, setNewField] = useState<View.FieldType>();
24
23
  const state = useAtomValue(modals.state);
25
24
 
26
25
  useEffect(() => {
@@ -64,7 +63,7 @@ export const ColumnSettings = ({ registry, model, modals, onNewColumn }: ColumnS
64
63
  <Popover.Root modal={false} open={state?.type === 'columnSettings'}>
65
64
  <Popover.VirtualTrigger virtualRef={modals.trigger} />
66
65
  <Popover.Portal>
67
- <Popover.Content classNames='md:is-64'>
66
+ <Popover.Content classNames='md:w-64'>
68
67
  <Popover.Viewport>
69
68
  <FieldEditor
70
69
  projection={model.projection}
@@ -3,14 +3,15 @@
3
3
  //
4
4
 
5
5
  import { type Meta, type StoryObj } from '@storybook/react-vite';
6
+ import type * as Types from 'effect/Types';
6
7
  import React, { useMemo, useState } from 'react';
7
8
 
8
- import { Obj } from '@dxos/echo';
9
- import { Format, type JsonSchemaType } from '@dxos/echo/internal';
9
+ import { type JsonSchema, Obj } from '@dxos/echo';
10
+ import { Format } from '@dxos/echo/internal';
10
11
  import { faker } from '@dxos/random';
11
12
  import { Filter, useQuery, useSchema } from '@dxos/react-client/echo';
12
13
  import { useClientStory, withClientProvider } from '@dxos/react-client/testing';
13
- import { withTheme } from '@dxos/react-ui/testing';
14
+ import { withLayout, withTheme } from '@dxos/react-ui/testing';
14
15
  import { type SchemaPropertyDefinition } from '@dxos/schema';
15
16
  import { TestSchema } from '@dxos/schema/testing';
16
17
  import { withRegistry } from '@dxos/storybook-utils';
@@ -58,7 +59,7 @@ const DynamicTableStory = () => {
58
59
  const meta = {
59
60
  title: 'ui/react-ui-table/DynamicTable',
60
61
  component: DynamicTable,
61
- decorators: [withTheme, withRegistry],
62
+ decorators: [withTheme(), withLayout({ layout: 'fullscreen' }), withRegistry],
62
63
  parameters: {
63
64
  layout: 'fullscreen',
64
65
  translations,
@@ -101,7 +102,7 @@ export const WithClickToSelect: StoryObj = {
101
102
 
102
103
  export const WithJsonSchema: StoryObj = {
103
104
  render: () => {
104
- const schema = useMemo<JsonSchemaType>(
105
+ const schema = useMemo<Types.DeepMutable<JsonSchema.JsonSchema>>(
105
106
  () => ({
106
107
  type: 'object',
107
108
  properties: {
@@ -3,10 +3,11 @@
3
3
  //
4
4
 
5
5
  import { RegistryContext } from '@effect-atom/atom-react';
6
+ import type * as Types from 'effect/Types';
6
7
  import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
7
8
 
8
9
  import { type Type } from '@dxos/echo';
9
- import { type JsonSchemaType } from '@dxos/echo/internal';
10
+ import { type JsonSchema } from '@dxos/echo';
10
11
  import { type ThemedClassName, useDefaultValue } from '@dxos/react-ui';
11
12
  import { type ProjectionModel } from '@dxos/schema';
12
13
  import { mx } from '@dxos/ui-theme';
@@ -18,12 +19,12 @@ import { type TablePropertyDefinition, getBaseSchema, makeDynamicTable } from '.
18
19
 
19
20
  import { Table, type TableController } from './Table';
20
21
 
21
- export type DynamicTableProps<T extends Type.Entity.Any = Type.Entity.Any> = ThemedClassName<{
22
+ export type DynamicTableProps<T extends Type.AnyEntity = Type.AnyEntity> = ThemedClassName<{
22
23
  schema?: T;
23
24
  name?: string; // TODO(burdon): Remove?
24
25
  rows: any[];
25
26
  properties?: TablePropertyDefinition[];
26
- jsonSchema?: JsonSchemaType;
27
+ jsonSchema?: Types.DeepMutable<JsonSchema.JsonSchema>;
27
28
  features?: Partial<TableFeatures>;
28
29
  rowActions?: TableRowAction[];
29
30
  onRowClick?: (row: any) => void;
@@ -35,13 +36,13 @@ export type DynamicTableProps<T extends Type.Entity.Any = Type.Entity.Any> = The
35
36
  */
36
37
  // TODO(burdon): Instead of creating component variants, create helpers/hooks that normalize the props.
37
38
  // TODO(burdon): Warning: Cannot update a component (`DynamicTable`) while rendering a different component (`DynamicTable`).
38
- export const DynamicTable = <T extends Type.Entity.Any = Type.Entity.Any>({
39
+ export const DynamicTable = <T extends Type.AnyEntity = Type.AnyEntity>({
39
40
  classNames,
40
41
  schema,
41
- name = 'example.com/dynamic-table', // Rmove default or make random; this will lead to type collisions.
42
+ name = 'com.example.dynamic-table', // Remove default or make random; this will lead to type collisions.
42
43
  rows,
43
44
  properties,
44
- jsonSchema: _jsonSchema,
45
+ jsonSchema: jsonSchemaProp,
45
46
  rowActions,
46
47
  onRowClick,
47
48
  onRowAction,
@@ -52,8 +53,8 @@ export const DynamicTable = <T extends Type.Entity.Any = Type.Entity.Any>({
52
53
 
53
54
  // TODO(burdon): Remove variance from the props (should be normalized externally; possibly via hooks).
54
55
  const { jsonSchema } = useMemo(
55
- () => getBaseSchema({ typename: name, properties, jsonSchema: _jsonSchema, schema }),
56
- [name, properties, _jsonSchema, schema],
56
+ () => getBaseSchema({ typename: name, properties, jsonSchema: jsonSchemaProp, schema }),
57
+ [name, properties, jsonSchemaProp, schema],
57
58
  );
58
59
 
59
60
  useEffect(() => {
@@ -95,18 +96,11 @@ export const DynamicTable = <T extends Type.Entity.Any = Type.Entity.Any>({
95
96
  }
96
97
  }, [registry, model]);
97
98
 
98
- // TODO(burdon): Do we need the outer divs?
99
99
  return (
100
- <div role='none' className={mx('is-full bs-full grow grid', classNames)}>
101
- <div role='none' className='grid min-bs-0 overflow-hidden'>
102
- <Table.Root>
103
- <Table.Main
104
- ref={tableRef}
105
- model={model}
106
- presentation={presentation}
107
- ignoreAttention
108
- onRowClick={onRowClick}
109
- />
100
+ <div role='none' className={mx('dx-expander grid', classNames)}>
101
+ <div role='none' className='grid min-h-0 overflow-hidden'>
102
+ <Table.Root ref={tableRef}>
103
+ <Table.Content model={model} presentation={presentation} ignoreAttention onRowClick={onRowClick} />
110
104
  </Table.Root>
111
105
  </div>
112
106
  </div>
@@ -5,22 +5,24 @@
5
5
  import { RegistryContext } from '@effect-atom/atom-react';
6
6
  import { type Meta, type StoryObj } from '@storybook/react-vite';
7
7
  import React, { useCallback, useContext, useEffect, useMemo, useState } from 'react';
8
- import { expect, userEvent, within } from 'storybook/test';
8
+ import { expect, userEvent, waitFor, within } from 'storybook/test';
9
9
 
10
10
  import { Obj, Type } from '@dxos/echo';
11
+ import { View } from '@dxos/echo';
11
12
  import { invariant } from '@dxos/invariant';
12
13
  import { type DxGrid } from '@dxos/lit-grid';
13
- import '@dxos/lit-ui/dx-tag-picker.pcss';
14
14
  import { faker } from '@dxos/random';
15
15
  import { useClientStory, withClientProvider } from '@dxos/react-client/testing';
16
16
  import { useAsyncEffect } from '@dxos/react-ui';
17
17
  import { withLayout, withTheme } from '@dxos/react-ui/testing';
18
18
  import { translations as formTranslations } from '@dxos/react-ui-form';
19
- import { View } from '@dxos/schema';
19
+ import { ViewModel } from '@dxos/schema';
20
20
  import { type ValueGenerator, createAsyncGenerator } from '@dxos/schema/testing';
21
21
  import { withRegistry } from '@dxos/storybook-utils';
22
22
  import { Organization, Person } from '@dxos/types';
23
23
 
24
+ import '@dxos/lit-ui/dx-tag-picker.pcss';
25
+
24
26
  import { useProjectionModel, useTableModel } from '../../hooks';
25
27
  import { type TableFeatures, TablePresentation, type TableRow } from '../../model';
26
28
  import { translations } from '../../translations';
@@ -35,7 +37,7 @@ const generator: ValueGenerator = faker as any;
35
37
  // TODO(burdon): Mutable and immutable views.
36
38
  // TODO(burdon): Reconcile schemas types and utils (see API PR).
37
39
  // TODO(burdon): Base type for T (with id); see ECHO API PR?
38
- const useTestModel = <S extends Type.Obj.Any>(schema: S, count: number) => {
40
+ const useTestModel = <S extends Type.AnyObj>(schema: S, count: number) => {
39
41
  const registry = useContext(RegistryContext);
40
42
  const { space } = useClientStory();
41
43
  const [object, setObject] = useState<Table.Table>();
@@ -50,7 +52,7 @@ const useTestModel = <S extends Type.Obj.Any>(schema: S, count: number) => {
50
52
  return;
51
53
  }
52
54
 
53
- const { view, jsonSchema } = await View.makeFromDatabase({ db: space.db, typename: Type.getTypename(schema) });
55
+ const { view, jsonSchema } = await ViewModel.makeFromDatabase({ db: space.db, typename: Type.getTypename(schema) });
54
56
  const object = Table.make({ view, jsonSchema });
55
57
  setObject(object);
56
58
  space.db.add(object);
@@ -87,7 +89,7 @@ const DefaultStory = () => {
87
89
  const { space } = useClientStory();
88
90
 
89
91
  const handleCreate = useCallback(
90
- (schema: Type.Entity.Any, values: any) => {
92
+ (schema: Type.AnyEntity, values: any) => {
91
93
  invariant(Type.isObjectSchema(schema));
92
94
  invariant(space);
93
95
  return space.db.add(Obj.make(schema, values));
@@ -96,9 +98,9 @@ const DefaultStory = () => {
96
98
  );
97
99
 
98
100
  return (
99
- <div className='is-full bs-full grid grid-cols-2 divide-x divide-separator'>
101
+ <div className='dx-expander grid grid-cols-2 divide-x divide-separator'>
100
102
  <TableComponent.Root>
101
- <TableComponent.Main
103
+ <TableComponent.Content
102
104
  model={orgModel}
103
105
  schema={Organization.Organization}
104
106
  presentation={orgPresentation}
@@ -108,7 +110,7 @@ const DefaultStory = () => {
108
110
  />
109
111
  </TableComponent.Root>
110
112
  <TableComponent.Root>
111
- <TableComponent.Main
113
+ <TableComponent.Content
112
114
  model={contactModel}
113
115
  schema={Person.Person}
114
116
  presentation={contactPresentation}
@@ -125,7 +127,7 @@ const meta = {
125
127
  title: 'ui/react-ui-table/Relations',
126
128
  render: DefaultStory,
127
129
  decorators: [
128
- withTheme,
130
+ withTheme(),
129
131
  withRegistry,
130
132
  // TODO(thure): Shouldn't `layout: 'fullscreen'` below make this unnecessary?
131
133
  withLayout({ classNames: 'fixed inset-0' }),
@@ -147,7 +149,7 @@ export default meta;
147
149
  type Story = StoryObj<typeof meta>;
148
150
 
149
151
  export const Default: Story = {
150
- play: async ({ canvasElement }: any) => {
152
+ play: async ({ canvasElement }) => {
151
153
  const canvas = within(canvasElement);
152
154
  const body = within(document.body);
153
155
 
@@ -195,8 +197,15 @@ export const Default: Story = {
195
197
  const saveButton = await body.findByTestId('save-button');
196
198
  await userEvent.click(saveButton);
197
199
 
198
- // Verify the relation was set (cell should now contain the org name)
199
- await expect(targetCell).toHaveTextContent(orgName.substring(0, 4));
200
+ // Verify the relation was set (cell should now contain the org name).
201
+ // Wait for the grid (Lit web component) to repaint after the reactive data update.
202
+ await waitFor(
203
+ async () => {
204
+ const updatedCell = within(secondGrid).getByTestId('grid.4.0');
205
+ await expect(updatedCell).toHaveTextContent(orgName.substring(0, 4));
206
+ },
207
+ { timeout: 5000 },
208
+ );
200
209
 
201
210
  // Test object creation (new relations) - equivalent to "new relations work as expected" test
202
211
  // Find a different cell to test object creation (second row, relations column)
@@ -215,23 +224,24 @@ export const Default: Story = {
215
224
  const newSearchField = await body.findByPlaceholderText('Search…');
216
225
  await userEvent.click(newSearchField);
217
226
 
218
- // Type a new object name (this will create a new object)
227
+ // Type a new object name (this will create a new object).
219
228
  const newOrgName = 'Salieri LLC';
220
229
  await userEvent.type(newSearchField, newOrgName);
221
230
 
222
- // Wait for the create option to appear (debounce is 200ms, allow time for render)
223
- const createOption = await body.findByRole('option', undefined, { timeout: 500 });
224
- await expect(createOption).toBeVisible();
225
-
226
- // Press Enter to select/create
227
- await userEvent.keyboard('{Enter}');
231
+ // Click the create option directly to open the create form.
232
+ const createOptionLabel = await body.findByText(/Create new object/, undefined, { timeout: 2000 });
233
+ await userEvent.click(createOptionLabel.closest('[role="option"]') as HTMLElement);
228
234
 
229
- // Look for and click save button
230
- const createReferencedObjectForm = await body.findByTestId('create-referenced-object-form');
235
+ // Look for and click save button.
236
+ const createReferencedObjectForm = await body.findByTestId('create-referenced-object-form', undefined, {
237
+ timeout: 2000,
238
+ });
231
239
  const saveObjectButton = await within(createReferencedObjectForm).findByTestId('save-button');
240
+ await expect(saveObjectButton).not.toBeDisabled();
232
241
  await userEvent.click(saveObjectButton);
233
242
 
234
- // Verify the new object was created and relation was set
235
- await expect(newTargetCell).toHaveTextContent(newOrgName);
243
+ // Verify the relation was set by checking for the accessory link anchor in the cell.
244
+ const updatedNewCell = await within(secondGrid).findByTestId('grid.4.1', undefined, { timeout: 5000 });
245
+ await expect(updatedNewCell.querySelector('dx-anchor')).toBeTruthy();
236
246
  },
237
- } as any;
247
+ };