@dxos/react-ui-table 0.8.4-main.422d1c7879 → 0.8.4-main.43cb759274

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 (114) hide show
  1. package/LICENSE +102 -5
  2. package/dist/lib/browser/chunk-J5LGTIGS.mjs +10 -0
  3. package/dist/lib/browser/chunk-J5LGTIGS.mjs.map +7 -0
  4. package/dist/lib/browser/{chunk-G5EDJPD2.mjs → chunk-X7A7G6RR.mjs} +26 -81
  5. package/dist/lib/browser/chunk-X7A7G6RR.mjs.map +7 -0
  6. package/dist/lib/browser/{chunk-BF54SSNL.mjs → chunk-YURROGGF.mjs} +12 -15
  7. package/dist/lib/browser/chunk-YURROGGF.mjs.map +7 -0
  8. package/dist/lib/browser/index.mjs +48 -122
  9. package/dist/lib/browser/index.mjs.map +4 -4
  10. package/dist/lib/browser/meta.json +1 -1
  11. package/dist/lib/browser/testing/index.mjs +7 -6
  12. package/dist/lib/browser/testing/index.mjs.map +3 -3
  13. package/dist/lib/browser/translations.mjs +36 -0
  14. package/dist/lib/browser/translations.mjs.map +7 -0
  15. package/dist/lib/browser/types/index.mjs +2 -1
  16. package/dist/lib/node-esm/{chunk-SIRDIPHZ.mjs → chunk-DLAGRBKD.mjs} +12 -15
  17. package/dist/lib/node-esm/chunk-DLAGRBKD.mjs.map +7 -0
  18. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +11 -0
  19. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +7 -0
  20. package/dist/lib/node-esm/{chunk-ZZ3SYTIL.mjs → chunk-Q4HSBRJJ.mjs} +26 -81
  21. package/dist/lib/node-esm/chunk-Q4HSBRJJ.mjs.map +7 -0
  22. package/dist/lib/node-esm/index.mjs +48 -122
  23. package/dist/lib/node-esm/index.mjs.map +4 -4
  24. package/dist/lib/node-esm/meta.json +1 -1
  25. package/dist/lib/node-esm/testing/index.mjs +7 -6
  26. package/dist/lib/node-esm/testing/index.mjs.map +3 -3
  27. package/dist/lib/node-esm/translations.mjs +37 -0
  28. package/dist/lib/node-esm/translations.mjs.map +7 -0
  29. package/dist/lib/node-esm/types/index.mjs +2 -1
  30. package/dist/types/src/components/Table/ColumnActionsMenu.d.ts.map +1 -1
  31. package/dist/types/src/components/Table/ColumnSettings.d.ts +2 -2
  32. package/dist/types/src/components/Table/ColumnSettings.d.ts.map +1 -1
  33. package/dist/types/src/components/Table/DynamicTable.d.ts +3 -4
  34. package/dist/types/src/components/Table/DynamicTable.d.ts.map +1 -1
  35. package/dist/types/src/components/Table/DynamicTable.stories.d.ts +21 -20
  36. package/dist/types/src/components/Table/DynamicTable.stories.d.ts.map +1 -1
  37. package/dist/types/src/components/Table/Relations.stories.d.ts +83 -82
  38. package/dist/types/src/components/Table/Relations.stories.d.ts.map +1 -1
  39. package/dist/types/src/components/Table/RowActionsMenu.d.ts.map +1 -1
  40. package/dist/types/src/components/Table/Table.d.ts +2 -2
  41. package/dist/types/src/components/Table/Table.d.ts.map +1 -1
  42. package/dist/types/src/components/Table/Table.stories.d.ts +83 -82
  43. package/dist/types/src/components/Table/Table.stories.d.ts.map +1 -1
  44. package/dist/types/src/components/Table/TableContent.d.ts +2 -1
  45. package/dist/types/src/components/Table/TableContent.d.ts.map +1 -1
  46. package/dist/types/src/components/Table/TableToolbar.d.ts +1 -1
  47. package/dist/types/src/components/Table/TableToolbar.d.ts.map +1 -1
  48. package/dist/types/src/components/TableCellEditor/CellValidationMessage.d.ts.map +1 -1
  49. package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts +1 -1
  50. package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts.map +1 -1
  51. package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts.map +1 -1
  52. package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts +19 -19
  53. package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts.map +1 -1
  54. package/dist/types/src/components/testing.d.ts.map +1 -1
  55. package/dist/types/src/hooks/useAddRow.d.ts.map +1 -1
  56. package/dist/types/src/hooks/useProjectionModel.d.ts.map +1 -1
  57. package/dist/types/src/hooks/useTableModel.d.ts.map +1 -1
  58. package/dist/types/src/index.d.ts +0 -2
  59. package/dist/types/src/index.d.ts.map +1 -1
  60. package/dist/types/src/model/modal-controller.d.ts.map +1 -1
  61. package/dist/types/src/model/selection-model.d.ts +1 -1
  62. package/dist/types/src/model/selection-model.d.ts.map +1 -1
  63. package/dist/types/src/model/table-model.d.ts +4 -5
  64. package/dist/types/src/model/table-model.d.ts.map +1 -1
  65. package/dist/types/src/model/table-presentation.d.ts.map +1 -1
  66. package/dist/types/src/playwright/TableManager.d.ts.map +1 -1
  67. package/dist/types/src/playwright/playwright.config.d.ts.map +1 -1
  68. package/dist/types/src/testing/useTestTableModel.d.ts +1 -1
  69. package/dist/types/src/testing/useTestTableModel.d.ts.map +1 -1
  70. package/dist/types/src/translations.d.ts +19 -19
  71. package/dist/types/src/translations.d.ts.map +1 -1
  72. package/dist/types/src/types/Table.d.ts +11 -5
  73. package/dist/types/src/types/Table.d.ts.map +1 -1
  74. package/dist/types/src/util/dynamic-table.d.ts +6 -6
  75. package/dist/types/src/util/dynamic-table.d.ts.map +1 -1
  76. package/dist/types/src/util/query-ast.d.ts.map +1 -1
  77. package/dist/types/src/util/schema.d.ts.map +1 -1
  78. package/dist/types/src/util/signals.d.ts.map +1 -1
  79. package/dist/types/src/util/sort.d.ts.map +1 -1
  80. package/dist/types/src/util/table-buttons.d.ts +20 -20
  81. package/dist/types/src/util/table-buttons.d.ts.map +1 -1
  82. package/dist/types/src/util/table-controls.d.ts +4 -4
  83. package/dist/types/src/util/table-controls.d.ts.map +1 -1
  84. package/dist/types/src/util/tag.d.ts.map +1 -1
  85. package/dist/types/tsconfig.tsbuildinfo +1 -1
  86. package/package.json +54 -50
  87. package/src/components/Table/ColumnActionsMenu.tsx +2 -1
  88. package/src/components/Table/ColumnSettings.tsx +2 -2
  89. package/src/components/Table/DynamicTable.stories.tsx +8 -7
  90. package/src/components/Table/DynamicTable.tsx +10 -11
  91. package/src/components/Table/Relations.stories.tsx +8 -6
  92. package/src/components/Table/RowActionsMenu.tsx +3 -2
  93. package/src/components/Table/Table.stories.tsx +28 -29
  94. package/src/components/Table/TableContent.tsx +8 -3
  95. package/src/components/Table/TableToolbar.tsx +2 -2
  96. package/src/components/TableCellEditor/CellValidationMessage.tsx +1 -2
  97. package/src/components/TableCellEditor/FormCellEditor.tsx +6 -5
  98. package/src/components/TableCellEditor/TableCellEditor.stories.tsx +7 -4
  99. package/src/components/testing.ts +2 -7
  100. package/src/hooks/useProjectionModel.ts +5 -6
  101. package/src/hooks/useTableModel.ts +1 -1
  102. package/src/index.ts +0 -4
  103. package/src/model/table-model.test.ts +4 -9
  104. package/src/model/table-model.ts +13 -13
  105. package/src/model/table-presentation.test.ts +4 -9
  106. package/src/model/table-presentation.ts +5 -6
  107. package/src/testing/useTestTableModel.ts +4 -5
  108. package/src/types/Table.ts +12 -13
  109. package/src/util/dynamic-table.test.ts +12 -19
  110. package/src/util/dynamic-table.ts +19 -18
  111. package/dist/lib/browser/chunk-BF54SSNL.mjs.map +0 -7
  112. package/dist/lib/browser/chunk-G5EDJPD2.mjs.map +0 -7
  113. package/dist/lib/node-esm/chunk-SIRDIPHZ.mjs.map +0 -7
  114. package/dist/lib/node-esm/chunk-ZZ3SYTIL.mjs.map +0 -7
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/react-ui-table",
3
- "version": "0.8.4-main.422d1c7879",
3
+ "version": "0.8.4-main.43cb759274",
4
4
  "description": "A table component.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -8,17 +8,14 @@
8
8
  "type": "git",
9
9
  "url": "https://github.com/dxos/dxos"
10
10
  },
11
- "license": "MIT",
11
+ "license": "FSL-1.1-Apache-2.0",
12
12
  "author": "DXOS.org",
13
13
  "sideEffects": false,
14
14
  "type": "module",
15
+ "imports": {
16
+ "#translations": "./src/translations.ts"
17
+ },
15
18
  "exports": {
16
- "./deprecated": {
17
- "source": "./src/deprecated/index.ts",
18
- "types": "./dist/types/src/deprecated/index.d.ts",
19
- "browser": "./dist/lib/browser/deprecated/index.mjs",
20
- "node": "./dist/lib/node-esm/deprecated/index.mjs"
21
- },
22
19
  ".": {
23
20
  "source": "./src/index.ts",
24
21
  "types": "./dist/types/src/index.d.ts",
@@ -31,6 +28,12 @@
31
28
  "browser": "./dist/lib/browser/testing/index.mjs",
32
29
  "node": "./dist/lib/node-esm/testing/index.mjs"
33
30
  },
31
+ "./translations": {
32
+ "source": "./src/translations.ts",
33
+ "types": "./dist/types/src/translations.d.ts",
34
+ "browser": "./dist/lib/browser/translations.mjs",
35
+ "node": "./dist/lib/node-esm/translations.mjs"
36
+ },
34
37
  "./types": {
35
38
  "source": "./src/types/index.ts",
36
39
  "types": "./dist/types/src/types/index.d.ts",
@@ -44,9 +47,9 @@
44
47
  "src"
45
48
  ],
46
49
  "dependencies": {
47
- "@codemirror/autocomplete": "^6.19.0",
48
- "@codemirror/state": "^6.5.2",
49
- "@codemirror/view": "^6.38.4",
50
+ "@codemirror/autocomplete": "^6.20.2",
51
+ "@codemirror/state": "^6.6.0",
52
+ "@codemirror/view": "^6.43.0",
50
53
  "@effect-atom/atom-react": "^0.5.0",
51
54
  "@fluentui/react-tabster": "9.26.11",
52
55
  "@radix-ui/react-context": "1.1.1",
@@ -55,58 +58,59 @@
55
58
  "@radix-ui/react-use-controllable-state": "1.1.0",
56
59
  "date-fns": "^3.6.0",
57
60
  "lodash.orderby": "^4.6.0",
58
- "@dxos/context": "0.8.4-main.422d1c7879",
59
- "@dxos/async": "0.8.4-main.422d1c7879",
60
- "@dxos/debug": "0.8.4-main.422d1c7879",
61
- "@dxos/echo": "0.8.4-main.422d1c7879",
62
- "@dxos/effect": "0.8.4-main.422d1c7879",
63
- "@dxos/invariant": "0.8.4-main.422d1c7879",
64
- "@dxos/keys": "0.8.4-main.422d1c7879",
65
- "@dxos/echo-atom": "0.8.4-main.422d1c7879",
66
- "@dxos/lit-grid": "0.8.4-main.422d1c7879",
67
- "@dxos/log": "0.8.4-main.422d1c7879",
68
- "@dxos/react-ui-attention": "0.8.4-main.422d1c7879",
69
- "@dxos/react-client": "0.8.4-main.422d1c7879",
70
- "@dxos/random": "0.8.4-main.422d1c7879",
71
- "@dxos/react-ui-components": "0.8.4-main.422d1c7879",
72
- "@dxos/react-ui-form": "0.8.4-main.422d1c7879",
73
- "@dxos/react-ui-editor": "0.8.4-main.422d1c7879",
74
- "@dxos/react-ui-grid": "0.8.4-main.422d1c7879",
75
- "@dxos/react-ui-search": "0.8.4-main.422d1c7879",
76
- "@dxos/react-ui-menu": "0.8.4-main.422d1c7879",
77
- "@dxos/react-ui-stack": "0.8.4-main.422d1c7879",
78
- "@dxos/react-ui-syntax-highlighter": "0.8.4-main.422d1c7879",
79
- "@dxos/schema": "0.8.4-main.422d1c7879",
80
- "@dxos/ui-types": "0.8.4-main.422d1c7879",
81
- "@dxos/util": "0.8.4-main.422d1c7879",
82
- "@dxos/types": "0.8.4-main.422d1c7879"
61
+ "@dxos/async": "0.8.4-main.43cb759274",
62
+ "@dxos/context": "0.8.4-main.43cb759274",
63
+ "@dxos/debug": "0.8.4-main.43cb759274",
64
+ "@dxos/effect": "0.8.4-main.43cb759274",
65
+ "@dxos/echo-atom": "0.8.4-main.43cb759274",
66
+ "@dxos/lit-grid": "0.8.4-main.43cb759274",
67
+ "@dxos/invariant": "0.8.4-main.43cb759274",
68
+ "@dxos/echo": "0.8.4-main.43cb759274",
69
+ "@dxos/keys": "0.8.4-main.43cb759274",
70
+ "@dxos/log": "0.8.4-main.43cb759274",
71
+ "@dxos/random": "0.8.4-main.43cb759274",
72
+ "@dxos/react-ui-attention": "0.8.4-main.43cb759274",
73
+ "@dxos/react-client": "0.8.4-main.43cb759274",
74
+ "@dxos/react-ui-components": "0.8.4-main.43cb759274",
75
+ "@dxos/react-ui-editor": "0.8.4-main.43cb759274",
76
+ "@dxos/react-ui-grid": "0.8.4-main.43cb759274",
77
+ "@dxos/react-ui-form": "0.8.4-main.43cb759274",
78
+ "@dxos/react-ui-list": "0.8.4-main.43cb759274",
79
+ "@dxos/react-ui-menu": "0.8.4-main.43cb759274",
80
+ "@dxos/react-ui-search": "0.8.4-main.43cb759274",
81
+ "@dxos/types": "0.8.4-main.43cb759274",
82
+ "@dxos/react-ui-syntax-highlighter": "0.8.4-main.43cb759274",
83
+ "@dxos/schema": "0.8.4-main.43cb759274",
84
+ "@dxos/react-ui-stack": "0.8.4-main.43cb759274",
85
+ "@dxos/ui-types": "0.8.4-main.43cb759274",
86
+ "@dxos/util": "0.8.4-main.43cb759274"
83
87
  },
84
88
  "devDependencies": {
85
- "@effect/platform": "0.94.4",
89
+ "@effect/platform": "0.96.1",
86
90
  "@types/lodash.orderby": "^4.6.9",
87
91
  "@types/react": "~19.2.7",
88
92
  "@types/react-dom": "~19.2.3",
89
- "effect": "3.20.0",
93
+ "effect": "3.21.2",
90
94
  "fast-check": "^3.19.0",
91
95
  "react": "~19.2.3",
92
96
  "react-dom": "~19.2.3",
93
- "vite": "^7.1.11",
94
- "@dxos/lit-ui": "0.8.4-main.422d1c7879",
95
- "@dxos/random": "0.8.4-main.422d1c7879",
96
- "@dxos/react-client": "0.8.4-main.422d1c7879",
97
- "@dxos/react-ui": "0.8.4-main.422d1c7879",
98
- "@dxos/storybook-utils": "0.8.4-main.422d1c7879",
99
- "@dxos/test-utils": "0.8.4-main.422d1c7879",
100
- "@dxos/ui-theme": "0.8.4-main.422d1c7879"
97
+ "vite": "^8.0.14",
98
+ "@dxos/lit-ui": "0.8.4-main.43cb759274",
99
+ "@dxos/random": "0.8.4-main.43cb759274",
100
+ "@dxos/react-client": "0.8.4-main.43cb759274",
101
+ "@dxos/react-ui": "0.8.4-main.43cb759274",
102
+ "@dxos/test-utils": "0.8.4-main.43cb759274",
103
+ "@dxos/storybook-utils": "0.8.4-main.43cb759274",
104
+ "@dxos/ui-theme": "0.8.4-main.43cb759274"
101
105
  },
102
106
  "peerDependencies": {
103
107
  "@effect-atom/atom-react": "^0.5.0",
104
- "@effect/platform": "0.94.4",
105
- "effect": "3.20.0",
108
+ "@effect/platform": "0.96.1",
109
+ "effect": "3.21.2",
106
110
  "react": "~19.2.3",
107
111
  "react-dom": "~19.2.3",
108
- "@dxos/ui-theme": "0.8.4-main.422d1c7879",
109
- "@dxos/react-ui": "0.8.4-main.422d1c7879"
112
+ "@dxos/ui-theme": "0.8.4-main.43cb759274",
113
+ "@dxos/react-ui": "0.8.4-main.43cb759274"
110
114
  },
111
115
  "publishConfig": {
112
116
  "access": "public"
@@ -7,8 +7,9 @@ import React from 'react';
7
7
 
8
8
  import { DropdownMenu, useTranslation } from '@dxos/react-ui';
9
9
 
10
+ import { translationKey } from '#translations';
11
+
10
12
  import { type ModalController, type TableModel } from '../../model';
11
- import { translationKey } from '../../translations';
12
13
 
13
14
  export type ColumnActionsMenuProps = {
14
15
  model: TableModel;
@@ -5,14 +5,14 @@
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, type View } from '@dxos/echo';
8
+ import { type Registry, type View } from '@dxos/echo';
9
9
  import { Popover } from '@dxos/react-ui';
10
10
  import { FieldEditor } from '@dxos/react-ui-form';
11
11
 
12
12
  import { type ModalController, type TableModel } from '../../model';
13
13
 
14
14
  type ColumnSettingsProps = {
15
- registry?: SchemaRegistry.SchemaRegistry;
15
+ registry?: Registry.Registry;
16
16
  model?: TableModel;
17
17
  modals: ModalController;
18
18
  onNewColumn: () => void;
@@ -6,18 +6,19 @@ import { type Meta, type StoryObj } from '@storybook/react-vite';
6
6
  import type * as Types from 'effect/Types';
7
7
  import React, { useMemo, useState } from 'react';
8
8
 
9
- import { type JsonSchema, Obj } from '@dxos/echo';
9
+ import { Filter, type JsonSchema, Obj, Type } from '@dxos/echo';
10
10
  import { Format } from '@dxos/echo/internal';
11
11
  import { random } from '@dxos/random';
12
- import { Filter, useQuery, useSchema } from '@dxos/react-client/echo';
12
+ import { useQuery, useType } from '@dxos/react-client/echo';
13
13
  import { useClientStory, withClientProvider } from '@dxos/react-client/testing';
14
14
  import { withLayout, withTheme } from '@dxos/react-ui/testing';
15
15
  import { type SchemaPropertyDefinition } from '@dxos/schema';
16
16
  import { TestSchema } from '@dxos/schema/testing';
17
17
  import { withRegistry } from '@dxos/storybook-utils';
18
18
 
19
+ import { translations } from '#translations';
20
+
19
21
  import { type TableFeatures } from '../../model';
20
- import { translations } from '../../translations';
21
22
  import { DynamicTable } from './DynamicTable';
22
23
 
23
24
  random.seed(0);
@@ -131,13 +132,13 @@ export const WithJsonSchema: StoryObj = {
131
132
  export const WithEchoSchema: StoryObj = {
132
133
  render: () => {
133
134
  const { space } = useClientStory();
134
- const schema = useSchema(space?.db, TestSchema.Person.typename);
135
- const objects = useQuery(space?.db, schema ? Filter.type(schema) : Filter.nothing());
136
- if (!schema) {
135
+ const type = useType(space?.db, Type.getTypename(TestSchema.Person));
136
+ const objects = useQuery(space?.db, type ? Filter.type(type) : Filter.nothing());
137
+ if (!type) {
137
138
  return <div>Loading schema...</div>;
138
139
  }
139
140
 
140
- return <DynamicTable schema={schema} rows={objects} />;
141
+ return <DynamicTable type={type} rows={objects} />;
141
142
  },
142
143
  decorators: [
143
144
  withClientProvider({
@@ -6,8 +6,7 @@ import { RegistryContext } from '@effect-atom/atom-react';
6
6
  import type * as Types from 'effect/Types';
7
7
  import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
8
8
 
9
- import { type Type } from '@dxos/echo';
10
- import { type JsonSchema } from '@dxos/echo';
9
+ import { type JsonSchema, type Type } from '@dxos/echo';
11
10
  import { type ThemedClassName, useDefaultValue } from '@dxos/react-ui';
12
11
  import { type ProjectionModel } from '@dxos/schema';
13
12
  import { mx } from '@dxos/ui-theme';
@@ -19,7 +18,7 @@ import { type TablePropertyDefinition, getBaseSchema, makeDynamicTable } from '.
19
18
  import { Table, type TableController } from './Table';
20
19
 
21
20
  export type DynamicTableProps<T extends Type.AnyEntity = Type.AnyEntity> = ThemedClassName<{
22
- schema?: T;
21
+ type?: T;
23
22
  name?: string; // TODO(burdon): Remove?
24
23
  rows: any[];
25
24
  properties?: TablePropertyDefinition[];
@@ -37,7 +36,7 @@ export type DynamicTableProps<T extends Type.AnyEntity = Type.AnyEntity> = Theme
37
36
  // TODO(burdon): Warning: Cannot update a component (`DynamicTable`) while rendering a different component (`DynamicTable`).
38
37
  export const DynamicTable = <T extends Type.AnyEntity = Type.AnyEntity>({
39
38
  classNames,
40
- schema,
39
+ type: typeProp,
41
40
  name = 'com.example.dynamicTable', // Remove default or make random; this will lead to type collisions.
42
41
  rows,
43
42
  properties,
@@ -51,14 +50,14 @@ export const DynamicTable = <T extends Type.AnyEntity = Type.AnyEntity>({
51
50
  const [dynamicTable, setDynamicTable] = useState<{ object: TableType.Table; projection: ProjectionModel }>();
52
51
 
53
52
  // TODO(burdon): Remove variance from the props (should be normalized externally; possibly via hooks).
54
- const { jsonSchema } = useMemo(
55
- () => getBaseSchema({ typename: name, properties, jsonSchema: jsonSchemaProp, schema }),
56
- [name, properties, jsonSchemaProp, schema],
53
+ const { type } = useMemo(
54
+ () => getBaseSchema({ typename: name, properties, jsonSchema: jsonSchemaProp, type: typeProp }),
55
+ [name, properties, jsonSchemaProp, typeProp],
57
56
  );
58
57
 
59
58
  useEffect(() => {
60
- setDynamicTable(makeDynamicTable({ registry, jsonSchema, properties }));
61
- }, [registry, jsonSchema, properties]);
59
+ setDynamicTable(makeDynamicTable({ registry, type, properties }));
60
+ }, [registry, type, properties]);
62
61
 
63
62
  const tableRef = useRef<TableController>(null);
64
63
  const handleCellUpdate = useCallback((cell: any) => {
@@ -96,8 +95,8 @@ export const DynamicTable = <T extends Type.AnyEntity = Type.AnyEntity>({
96
95
  }, [registry, model]);
97
96
 
98
97
  return (
99
- <div role='none' className={mx('dx-expander grid', classNames)}>
100
- <div role='none' className='grid min-h-0 overflow-hidden'>
98
+ <div className={mx('dx-expander grid', classNames)}>
99
+ <div className='grid min-h-0 overflow-hidden'>
101
100
  <Table.Root ref={tableRef}>
102
101
  <Table.Content model={model} presentation={presentation} ignoreAttention onRowClick={onRowClick} />
103
102
  </Table.Root>
@@ -7,14 +7,13 @@ import { type Meta, type StoryObj } from '@storybook/react-vite';
7
7
  import React, { useCallback, useContext, useEffect, useMemo, useState } from 'react';
8
8
  import { expect, userEvent, waitFor, within } from 'storybook/test';
9
9
 
10
- import { Obj, Type } from '@dxos/echo';
11
- import { View } from '@dxos/echo';
10
+ import { Obj, Type, View } from '@dxos/echo';
12
11
  import { invariant } from '@dxos/invariant';
13
12
  import { type DxGrid } from '@dxos/lit-grid';
14
13
  import { random } from '@dxos/random';
15
14
  import { useClientStory, withClientProvider } from '@dxos/react-client/testing';
16
15
  import { useAsyncEffect } from '@dxos/react-ui';
17
- import { translations as formTranslations } from '@dxos/react-ui-form';
16
+ import { translations as formTranslations } from '@dxos/react-ui-form/translations';
18
17
  import { withLayout, withTheme } from '@dxos/react-ui/testing';
19
18
  import { ViewModel } from '@dxos/schema';
20
19
  import { type ValueGenerator, createAsyncGenerator } from '@dxos/schema/testing';
@@ -22,9 +21,10 @@ import { withRegistry } from '@dxos/storybook-utils';
22
21
  import { Organization, Person } from '@dxos/types';
23
22
  import '@dxos/lit-ui/dx-tag-picker.pcss';
24
23
 
24
+ import { translations } from '#translations';
25
+
25
26
  import { useProjectionModel, useTableModel } from '../../hooks';
26
27
  import { type TableFeatures, TablePresentation, type TableRow } from '../../model';
27
- import { translations } from '../../translations';
28
28
  import { Table } from '../../types';
29
29
  import { Table as TableComponent } from './Table';
30
30
 
@@ -66,7 +66,9 @@ const useTestModel = <S extends Type.AnyObj>(schema: S, count: number) => {
66
66
 
67
67
  const objectGenerator = createAsyncGenerator(generator, schema, { db: space?.db, force: true });
68
68
  void objectGenerator.createObjects(count).then((objects) => {
69
- model.setRows(objects);
69
+ // TODO(wittjosiah): Remove cast. Type.InstanceType is now strict (no index signature),
70
+ // so it isn't assignable to TableRow (Record<JsonProp, any>); reconcile the row model type.
71
+ model.setRows(objects as unknown as TableRow[]);
70
72
  });
71
73
  }, [model, space]);
72
74
 
@@ -88,7 +90,7 @@ const DefaultStory = () => {
88
90
 
89
91
  const handleCreate = useCallback(
90
92
  (schema: Type.AnyEntity, values: any) => {
91
- invariant(Type.isObjectSchema(schema));
93
+ invariant(Type.isObject(schema));
92
94
  invariant(space);
93
95
  return space.db.add(Obj.make(schema, values));
94
96
  },
@@ -7,8 +7,9 @@ import React from 'react';
7
7
 
8
8
  import { DropdownMenu, toLocalizedString, useTranslation } from '@dxos/react-ui';
9
9
 
10
+ import { translationKey } from '#translations';
11
+
10
12
  import { type ModalController, type TableModel } from '../../model';
11
- import { translationKey } from '../../translations';
12
13
 
13
14
  type RowActionsMenuProps = { model: TableModel; modals: ModalController };
14
15
 
@@ -47,7 +48,7 @@ export const RowActionsMenu = ({ model, modals }: RowActionsMenuProps) => {
47
48
  {/* Default actions */}
48
49
  {model.features.dataEditable !== false && (
49
50
  <DropdownMenu.Item data-testid='row-menu-delete' onClick={() => model.deleteRow(state.rowIndex)}>
50
- {t(hasSelection ? 'bulk delete row label' : 'delete row label')}
51
+ {t(hasSelection ? 'bulk-delete-row.label' : 'delete-row.label')}
51
52
  </DropdownMenu.Item>
52
53
  )}
53
54
  </DropdownMenu.Viewport>
@@ -6,23 +6,24 @@ import { type Meta, type StoryObj } from '@storybook/react-vite';
6
6
  import * as Schema from 'effect/Schema';
7
7
  import React, { useCallback } from 'react';
8
8
 
9
- import { Annotation, type Database, Format, Obj, type QueryAST, Ref, Type } from '@dxos/echo';
10
- import { View } from '@dxos/echo';
9
+ import { DXN, Annotation, type Database, Format, Obj, type QueryAST, Ref, Type, View } from '@dxos/echo';
11
10
  import { type Mutable, PropertyMetaAnnotationId } from '@dxos/echo/internal';
12
11
  import { invariant } from '@dxos/invariant';
13
12
  import { random } from '@dxos/random';
14
13
  import { PublicKey } from '@dxos/react-client';
15
14
  import { withClientProvider } from '@dxos/react-client/testing';
16
15
  import { Panel, ScrollArea } from '@dxos/react-ui';
17
- import { ViewEditor, translations as formTranslations } from '@dxos/react-ui-form';
16
+ import { ViewEditor } from '@dxos/react-ui-form';
17
+ import { translations as formTranslations } from '@dxos/react-ui-form/translations';
18
18
  import { JsonHighlighter } from '@dxos/react-ui-syntax-highlighter';
19
19
  import { withLayout, withTheme } from '@dxos/react-ui/testing';
20
- import { ViewModel, getSchemaFromPropertyDefinitions, getTypenameFromQuery } from '@dxos/schema';
20
+ import { ViewModel, getSchemaFromPropertyDefinitions } from '@dxos/schema';
21
21
  import { TestSchema, createObjectFactory } from '@dxos/schema/testing';
22
22
  import { withRegistry } from '@dxos/storybook-utils';
23
23
 
24
+ import { translations } from '#translations';
25
+
24
26
  import { useTestTableModel } from '../../testing';
25
- import { translations } from '../../translations';
26
27
  import { Table } from '../../types';
27
28
  import { Table as TableComponent } from './Table';
28
29
 
@@ -51,10 +52,11 @@ const Example = Schema.Struct({
51
52
  title: 'Parent',
52
53
  }),
53
54
  }).pipe(
54
- Type.object({ typename: `com.example.type.${PublicKey.random().truncate()}`, version: '0.1.0' }),
55
55
  Annotation.LabelAnnotation.set(['name']),
56
+ // NSID last segment must start with a letter (DXN spec), so prefix the random hex.
57
+ Type.makeObject(DXN.make(`com.example.type.example${PublicKey.random().truncate()}`, '0.1.0')),
56
58
  );
57
- interface Example extends Schema.Schema.Type<typeof Example> {}
59
+ interface Example extends Type.InstanceType<typeof Example> {}
58
60
 
59
61
  const StoryViewEditor = ({
60
62
  view,
@@ -63,17 +65,16 @@ const StoryViewEditor = ({
63
65
  handleDeleteColumn,
64
66
  }: {
65
67
  view?: View.View;
66
- schema?: Schema.Schema.AnyNoContext;
68
+ schema?: Type.AnyEntity;
67
69
  db?: Database.Database;
68
70
  handleDeleteColumn: (fieldId: string) => void;
69
71
  }) => {
70
72
  const handleQueryChanged = useCallback(
71
73
  (newQuery: QueryAST.Query) => {
72
74
  invariant(schema);
73
- invariant(Type.isMutable(schema));
74
- schema.updateTypename(getTypenameFromQuery(newQuery));
75
+ invariant(Type.getDatabase(schema) != null);
75
76
  invariant(view);
76
- Obj.change(view, (view) => {
77
+ Obj.update(view, (view) => {
77
78
  view.query.ast = newQuery as Mutable<typeof newQuery>;
78
79
  });
79
80
  },
@@ -86,8 +87,8 @@ const StoryViewEditor = ({
86
87
 
87
88
  return (
88
89
  <ViewEditor
89
- registry={db?.schemaRegistry}
90
- schema={schema}
90
+ registry={db?.graph.registry}
91
+ type={schema}
91
92
  view={view}
92
93
  onQueryChanged={handleQueryChanged}
93
94
  onDelete={handleDeleteColumn}
@@ -168,10 +169,13 @@ const meta = {
168
169
  createIdentity: true,
169
170
  createSpace: true,
170
171
  onCreateSpace: async ({ space }) => {
171
- const [schema] = await space.db.schemaRegistry.register([Example]);
172
- const { view, jsonSchema } = await ViewModel.makeFromDatabase({ db: space.db, typename: schema.typename });
172
+ const type = await space.db.addType(Example);
173
+ const { view, jsonSchema } = await ViewModel.makeFromDatabase({
174
+ db: space.db,
175
+ typename: Type.getTypename(type),
176
+ });
173
177
  const table = Table.make({ view, jsonSchema });
174
- Obj.change(view, (view) => {
178
+ Obj.update(view, (view) => {
175
179
  view.projection.fields = [
176
180
  view.projection.fields.find((field) => field.path === 'name')!,
177
181
  ...view.projection.fields.filter((field) => field.path !== 'name'),
@@ -182,7 +186,7 @@ const meta = {
182
186
 
183
187
  Array.from({ length: 10 }).map(() => {
184
188
  return space.db.add(
185
- Obj.make(schema, {
189
+ Obj.make(type, {
186
190
  name: random.lorem.sentence(),
187
191
  status: random.helpers.arrayElement(['todo', 'in-progress', 'done'] as const),
188
192
  description: random.lorem.paragraph(),
@@ -217,7 +221,7 @@ export const StaticSchema: StoryObj = {
217
221
  onCreateSpace: async ({ space }) => {
218
222
  const { view, jsonSchema } = await ViewModel.makeFromDatabase({
219
223
  db: space.db,
220
- typename: TestSchema.Person.typename,
224
+ typename: Type.getTypename(TestSchema.Person),
221
225
  });
222
226
  const table = Table.make({ view, jsonSchema });
223
227
  space.db.add(table);
@@ -246,12 +250,7 @@ const ContactWithArrayOfEmails = Schema.Struct({
246
250
  }),
247
251
  ),
248
252
  ),
249
- }).pipe(
250
- Type.object({
251
- typename: 'org.dxos.type.contactWithArrayOfEmails',
252
- version: '0.1.0',
253
- }),
254
- );
253
+ }).pipe(Type.makeObject(DXN.make('org.dxos.type.contactWithArrayOfEmails', '0.1.0')));
255
254
 
256
255
  export const ArrayOfObjects: StoryObj = {
257
256
  render: DefaultStory,
@@ -263,7 +262,7 @@ export const ArrayOfObjects: StoryObj = {
263
262
  onCreateSpace: async ({ space }) => {
264
263
  const { view, jsonSchema } = await ViewModel.makeFromDatabase({
265
264
  db: space.db,
266
- typename: ContactWithArrayOfEmails.typename,
265
+ typename: Type.getTypename(ContactWithArrayOfEmails),
267
266
  });
268
267
  const table = Table.make({ view, jsonSchema });
269
268
  space.db.add(table);
@@ -293,7 +292,7 @@ export const Tags: Meta<DefaultStoryProps> = {
293
292
  createSpace: true,
294
293
  onCreateSpace: async ({ space }) => {
295
294
  // Configure schema.
296
- const typename = 'com.example.type.single-select';
295
+ const typename = 'com.example.type.singleSelect';
297
296
  const selectOptions = [
298
297
  { id: 'one', title: 'One', color: 'emerald' },
299
298
  { id: 'two', title: 'Two', color: 'blue' },
@@ -304,7 +303,7 @@ export const Tags: Meta<DefaultStoryProps> = {
304
303
 
305
304
  const selectOptionIds = selectOptions.map((o) => o.id);
306
305
 
307
- const schema = getSchemaFromPropertyDefinitions(typename, [
306
+ const type = getSchemaFromPropertyDefinitions(typename, [
308
307
  {
309
308
  name: 'single',
310
309
  format: Format.TypeFormat.SingleSelect,
@@ -316,7 +315,7 @@ export const Tags: Meta<DefaultStoryProps> = {
316
315
  config: { options: selectOptions },
317
316
  },
318
317
  ]);
319
- const [storedSchema] = await space.db.schemaRegistry.register([schema]);
318
+ const storedType = await space.db.addType(type);
320
319
 
321
320
  // Initialize table.
322
321
  const { view, jsonSchema } = await ViewModel.makeFromDatabase({ db: space.db, typename });
@@ -326,7 +325,7 @@ export const Tags: Meta<DefaultStoryProps> = {
326
325
  // Populate.
327
326
  Array.from({ length: 10 }).map(() => {
328
327
  return space.db.add(
329
- Obj.make(storedSchema, {
328
+ Obj.make(Type.assertObject(storedType), {
330
329
  single: random.helpers.arrayElement([...selectOptionIds, undefined]),
331
330
  multiple: random.helpers.randomSubset(selectOptionIds),
332
331
  }),
@@ -8,6 +8,7 @@ import React, { type MouseEvent, type WheelEvent, useCallback, useContext, useEf
8
8
 
9
9
  import { type Type } from '@dxos/echo';
10
10
  import { log } from '@dxos/log';
11
+ import { composable, composableProps } from '@dxos/react-ui';
11
12
  import { useAttention } from '@dxos/react-ui-attention';
12
13
  import {
13
14
  type DxGridAxisMeta,
@@ -21,7 +22,7 @@ import {
21
22
  gridSeparatorInlineEnd,
22
23
  } from '@dxos/react-ui-grid';
23
24
  import { DxEditRequest } from '@dxos/react-ui-grid';
24
- import { composable, composableProps, mx } from '@dxos/ui-theme';
25
+ import { mx } from '@dxos/ui-theme';
25
26
 
26
27
  import { type InsertRowResult, ModalController, type TableModel, type TablePresentation } from '../../model';
27
28
  import { tableButtons, tableControls } from '../../util';
@@ -49,16 +50,20 @@ export type TableContentProps = {
49
50
  presentation?: TablePresentation;
50
51
  // TODO(burdon): Factor out attention.
51
52
  ignoreAttention?: boolean;
53
+ attendableId?: string;
52
54
  onCreate?: OnCreateHandler;
53
55
  onRowClick?: (row: any) => void;
54
56
  testId?: string;
55
57
  };
56
58
 
57
59
  export const TableContent = composable<HTMLDivElement, TableContentProps>(
58
- ({ schema, model, presentation, ignoreAttention, onCreate, onRowClick, testId, ...props }, forwardedRef) => {
60
+ (
61
+ { schema, model, presentation, ignoreAttention, attendableId, onCreate, onRowClick, testId, ...props },
62
+ forwardedRef,
63
+ ) => {
59
64
  const registry = useContext(RegistryContext);
60
65
  const [dxGrid, setDxGrid] = useState<DxGridElement | null>(null);
61
- const { hasAttention } = useAttention(model?.id ?? 'table');
66
+ const { hasAttention } = useAttention(attendableId ?? model?.id ?? 'table');
62
67
  const modals = useMemo(() => new ModalController(registry), [registry]);
63
68
  const columnMeta = useAtomValue(model?.columnMeta ?? emptyColumnMeta);
64
69
  // Subscribe to rows atom to trigger re-render when rows change.
@@ -5,6 +5,7 @@
5
5
  import { Atom, RegistryContext } from '@effect-atom/atom-react';
6
6
  import React, { useContext, useEffect, useMemo } from 'react';
7
7
 
8
+ import { composable, composableProps } from '@dxos/react-ui';
8
9
  import {
9
10
  type ActionGraphEdges,
10
11
  type ActionGraphNodes,
@@ -16,9 +17,8 @@ import {
16
17
  createMenuAction,
17
18
  useMenuActions,
18
19
  } from '@dxos/react-ui-menu';
19
- import { composable, composableProps } from '@dxos/ui-theme';
20
20
 
21
- import { translationKey } from '../../translations';
21
+ import { translationKey } from '#translations';
22
22
 
23
23
  export type TableToolbarActionProperties = { type: TableToolbarActionType };
24
24
 
@@ -23,11 +23,10 @@ export const CellValidationMessage = ({
23
23
  }
24
24
 
25
25
  const bgClass = variant === 'error' ? 'bg-error-surface' : 'bg-warning-surface';
26
- const textClass = variant === 'error' ? 'text-error-surface-text' : 'text-warning-surface-text';
26
+ const textClass = variant === 'error' ? 'text-error-fg' : 'text-warning-fg';
27
27
 
28
28
  return (
29
29
  <div
30
- role='none'
31
30
  className={`absolute ${bgClass} ${textClass} rounded-h-sm text-xs p-1`}
32
31
  style={{
33
32
  ...{ '--dx-grid-cell-width': `${box?.inlineSize ?? 200}px` },
@@ -5,7 +5,7 @@
5
5
  import type * as Schema from 'effect/Schema';
6
6
  import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
7
7
 
8
- import { Entity, type Type } from '@dxos/echo';
8
+ import { Entity, Type } from '@dxos/echo';
9
9
  import { Ref, getValue } from '@dxos/echo/internal';
10
10
  import { invariant } from '@dxos/invariant';
11
11
  import { type Label, Popover } from '@dxos/react-ui';
@@ -14,8 +14,9 @@ import { parseCellIndex, useGridContext } from '@dxos/react-ui-grid';
14
14
  import { type FieldProjection } from '@dxos/schema';
15
15
  import { getDeep, isTruthy, setDeep } from '@dxos/util';
16
16
 
17
+ import { translationKey } from '#translations';
18
+
17
19
  import { type ModalController, type TableModel, type TableRow } from '../../model';
18
- import { translationKey } from '../../translations';
19
20
  import { narrowSchema } from '../../util';
20
21
 
21
22
  const createOptionLabel: Label = ['create-new-object.label', { ns: translationKey }];
@@ -62,7 +63,7 @@ export const FormCellEditor = <T extends Type.AnyEntity = Type.AnyEntity>({
62
63
  return undefined;
63
64
  }
64
65
 
65
- return narrowSchema(schema, [fieldProjection.field.path]);
66
+ return narrowSchema(Type.getSchema(schema), [fieldProjection.field.path]);
66
67
  }, [JSON.stringify(schema), fieldProjection.field.path]); // TODO(burdon): Avoid stringify.
67
68
 
68
69
  const originalRow = useMemo<TableRow | undefined>(() => {
@@ -150,7 +151,7 @@ export const FormCellEditor = <T extends Type.AnyEntity = Type.AnyEntity>({
150
151
  results
151
152
  .map((obj) => {
152
153
  return {
153
- id: Entity.getDXN(obj).toString(),
154
+ id: Entity.getURI(obj),
154
155
  label: getValue(obj, fieldProjection.field.referencePath!) || obj.id.toString(),
155
156
  };
156
157
  })
@@ -166,7 +167,7 @@ export const FormCellEditor = <T extends Type.AnyEntity = Type.AnyEntity>({
166
167
  <Popover.Root open={editing} onOpenChange={handleOpenChange}>
167
168
  <Popover.VirtualTrigger virtualRef={anchorRef} />
168
169
  <Popover.Portal>
169
- <Popover.Content tabIndex={-1} classNames='dx-card-popover-width dx-density-fine'>
170
+ <Popover.Content tabIndex={-1} classNames='dx-card-popover-width dx-density-md'>
170
171
  <Popover.Arrow />
171
172
  <Popover.Viewport>
172
173
  <Form.Root