@dxos/react-ui-table 0.8.4-main.fd6878d → 0.9.0

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 (183) hide show
  1. package/LICENSE +102 -5
  2. package/dist/lib/browser/chunk-4KOQTPFC.mjs +1702 -0
  3. package/dist/lib/browser/chunk-4KOQTPFC.mjs.map +7 -0
  4. package/dist/lib/browser/chunk-62PYOJPY.mjs +67 -0
  5. package/dist/lib/browser/chunk-62PYOJPY.mjs.map +7 -0
  6. package/dist/lib/browser/chunk-J5LGTIGS.mjs +10 -0
  7. package/dist/lib/browser/chunk-J5LGTIGS.mjs.map +7 -0
  8. package/dist/lib/browser/index.mjs +1151 -1175
  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 +37 -45
  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 +4 -3
  16. package/dist/lib/node-esm/chunk-7LMOZUTS.mjs +68 -0
  17. package/dist/lib/node-esm/chunk-7LMOZUTS.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-KOSV2J5N.mjs +1704 -0
  21. package/dist/lib/node-esm/chunk-KOSV2J5N.mjs.map +7 -0
  22. package/dist/lib/node-esm/index.mjs +1151 -1175
  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 +37 -45
  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 +4 -3
  30. package/dist/types/src/components/Table/ColumnActionsMenu.d.ts +1 -2
  31. package/dist/types/src/components/Table/ColumnActionsMenu.d.ts.map +1 -1
  32. package/dist/types/src/components/Table/ColumnSettings.d.ts +2 -2
  33. package/dist/types/src/components/Table/ColumnSettings.d.ts.map +1 -1
  34. package/dist/types/src/components/Table/DynamicTable.d.ts +6 -7
  35. package/dist/types/src/components/Table/DynamicTable.d.ts.map +1 -1
  36. package/dist/types/src/components/Table/DynamicTable.stories.d.ts +36 -3
  37. package/dist/types/src/components/Table/DynamicTable.stories.d.ts.map +1 -1
  38. package/dist/types/src/components/Table/Relations.stories.d.ts +112 -5
  39. package/dist/types/src/components/Table/Relations.stories.d.ts.map +1 -1
  40. package/dist/types/src/components/Table/RowActionsMenu.d.ts.map +1 -1
  41. package/dist/types/src/components/Table/Table.d.ts +21 -19
  42. package/dist/types/src/components/Table/Table.d.ts.map +1 -1
  43. package/dist/types/src/components/Table/Table.stories.d.ts +115 -5
  44. package/dist/types/src/components/Table/Table.stories.d.ts.map +1 -1
  45. package/dist/types/src/components/Table/TableContent.d.ts +18 -0
  46. package/dist/types/src/components/Table/TableContent.d.ts.map +1 -0
  47. package/dist/types/src/components/Table/TableToolbar.d.ts +21 -0
  48. package/dist/types/src/components/Table/TableToolbar.d.ts.map +1 -0
  49. package/dist/types/src/components/TableCellEditor/CellValidationMessage.d.ts +1 -1
  50. package/dist/types/src/components/TableCellEditor/CellValidationMessage.d.ts.map +1 -1
  51. package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts +12 -9
  52. package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts.map +1 -1
  53. package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts +7 -14
  54. package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts.map +1 -1
  55. package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts +38 -5
  56. package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts.map +1 -1
  57. package/dist/types/src/components/TableCellEditor/index.d.ts +1 -0
  58. package/dist/types/src/components/TableCellEditor/index.d.ts.map +1 -1
  59. package/dist/types/src/components/index.d.ts +0 -1
  60. package/dist/types/src/components/index.d.ts.map +1 -1
  61. package/dist/types/src/components/testing.d.ts +23 -16
  62. package/dist/types/src/components/testing.d.ts.map +1 -1
  63. package/dist/types/src/hooks/index.d.ts +2 -1
  64. package/dist/types/src/hooks/index.d.ts.map +1 -1
  65. package/dist/types/src/hooks/useAddRow.d.ts +6 -6
  66. package/dist/types/src/hooks/useAddRow.d.ts.map +1 -1
  67. package/dist/types/src/hooks/useProjectionModel.d.ts +6 -0
  68. package/dist/types/src/hooks/useProjectionModel.d.ts.map +1 -0
  69. package/dist/types/src/hooks/useTableModel.d.ts +9 -9
  70. package/dist/types/src/hooks/useTableModel.d.ts.map +1 -1
  71. package/dist/types/src/index.d.ts +0 -2
  72. package/dist/types/src/index.d.ts.map +1 -1
  73. package/dist/types/src/model/modal-controller.d.ts +5 -8
  74. package/dist/types/src/model/modal-controller.d.ts.map +1 -1
  75. package/dist/types/src/model/selection-model.d.ts +18 -9
  76. package/dist/types/src/model/selection-model.d.ts.map +1 -1
  77. package/dist/types/src/model/table-model.d.ts +111 -30
  78. package/dist/types/src/model/table-model.d.ts.map +1 -1
  79. package/dist/types/src/model/table-presentation.d.ts +4 -2
  80. package/dist/types/src/model/table-presentation.d.ts.map +1 -1
  81. package/dist/types/src/playwright/TableManager.d.ts +2 -1
  82. package/dist/types/src/playwright/TableManager.d.ts.map +1 -1
  83. package/dist/types/src/playwright/playwright.config.d.ts.map +1 -1
  84. package/dist/types/src/testing/useTestTableModel.d.ts +18 -34
  85. package/dist/types/src/testing/useTestTableModel.d.ts.map +1 -1
  86. package/dist/types/src/translations.d.ts +21 -23
  87. package/dist/types/src/translations.d.ts.map +1 -1
  88. package/dist/types/src/types/Table.d.ts +32 -0
  89. package/dist/types/src/types/Table.d.ts.map +1 -0
  90. package/dist/types/src/types/index.d.ts +1 -1
  91. package/dist/types/src/types/index.d.ts.map +1 -1
  92. package/dist/types/src/util/dynamic-table.d.ts +14 -12
  93. package/dist/types/src/util/dynamic-table.d.ts.map +1 -1
  94. package/dist/types/src/util/dynamic-table.test.d.ts +2 -0
  95. package/dist/types/src/util/dynamic-table.test.d.ts.map +1 -0
  96. package/dist/types/src/util/index.d.ts +2 -1
  97. package/dist/types/src/util/index.d.ts.map +1 -1
  98. package/dist/types/src/util/query-ast.d.ts +7 -0
  99. package/dist/types/src/util/query-ast.d.ts.map +1 -0
  100. package/dist/types/src/util/schema.d.ts +1 -1
  101. package/dist/types/src/util/schema.d.ts.map +1 -1
  102. package/dist/types/src/util/signals.d.ts.map +1 -1
  103. package/dist/types/src/util/sort.d.ts +12 -0
  104. package/dist/types/src/util/sort.d.ts.map +1 -0
  105. package/dist/types/src/util/table-buttons.d.ts +20 -20
  106. package/dist/types/src/util/table-buttons.d.ts.map +1 -1
  107. package/dist/types/src/util/table-controls.d.ts +4 -4
  108. package/dist/types/src/util/table-controls.d.ts.map +1 -1
  109. package/dist/types/src/util/tag.d.ts.map +1 -1
  110. package/dist/types/tsconfig.tsbuildinfo +1 -1
  111. package/package.json +68 -77
  112. package/src/components/Table/ColumnActionsMenu.tsx +17 -12
  113. package/src/components/Table/ColumnSettings.tsx +8 -9
  114. package/src/components/Table/DynamicTable.stories.tsx +41 -38
  115. package/src/components/Table/DynamicTable.tsx +32 -36
  116. package/src/components/Table/Relations.stories.tsx +219 -61
  117. package/src/components/Table/RowActionsMenu.tsx +27 -17
  118. package/src/components/Table/Table.stories.tsx +217 -141
  119. package/src/components/Table/Table.tsx +46 -391
  120. package/src/components/Table/TableContent.tsx +426 -0
  121. package/src/components/Table/TableToolbar.tsx +111 -0
  122. package/src/components/TableCellEditor/CellValidationMessage.tsx +5 -6
  123. package/src/components/TableCellEditor/FormCellEditor.tsx +136 -41
  124. package/src/components/TableCellEditor/TableCellEditor.stories.tsx +39 -73
  125. package/src/components/TableCellEditor/TableCellEditor.tsx +81 -223
  126. package/src/components/TableCellEditor/index.ts +1 -0
  127. package/src/components/index.ts +0 -1
  128. package/src/components/testing.ts +42 -21
  129. package/src/hooks/index.ts +2 -1
  130. package/src/hooks/useAddRow.ts +14 -14
  131. package/src/hooks/useProjectionModel.ts +38 -0
  132. package/src/hooks/useTableModel.ts +36 -34
  133. package/src/index.ts +0 -4
  134. package/src/model/modal-controller.ts +23 -40
  135. package/src/model/selection-model.ts +75 -44
  136. package/src/model/table-model.test.ts +86 -56
  137. package/src/model/table-model.ts +464 -182
  138. package/src/model/table-presentation.test.ts +64 -59
  139. package/src/model/table-presentation.ts +107 -83
  140. package/src/playwright/TableManager.ts +13 -6
  141. package/src/playwright/playwright.config.ts +1 -1
  142. package/src/playwright/smoke.spec.ts +92 -46
  143. package/src/testing/useTestTableModel.ts +51 -42
  144. package/src/translations.ts +20 -22
  145. package/src/types/Table.ts +80 -0
  146. package/src/types/index.ts +1 -1
  147. package/src/util/dynamic-table.test.ts +63 -0
  148. package/src/util/dynamic-table.ts +53 -39
  149. package/src/util/index.ts +2 -1
  150. package/src/util/query-ast.ts +22 -0
  151. package/src/util/schema.ts +4 -4
  152. package/src/util/sort.ts +90 -0
  153. package/src/util/table-buttons.ts +3 -3
  154. package/src/util/table-controls.ts +2 -2
  155. package/dist/lib/browser/chunk-L2LSB6KV.mjs +0 -18
  156. package/dist/lib/browser/chunk-L2LSB6KV.mjs.map +0 -7
  157. package/dist/lib/browser/chunk-ZAOSIG3L.mjs +0 -1814
  158. package/dist/lib/browser/chunk-ZAOSIG3L.mjs.map +0 -7
  159. package/dist/lib/node-esm/chunk-NXZ4CJYX.mjs +0 -20
  160. package/dist/lib/node-esm/chunk-NXZ4CJYX.mjs.map +0 -7
  161. package/dist/lib/node-esm/chunk-ZOFFI3JJ.mjs +0 -1815
  162. package/dist/lib/node-esm/chunk-ZOFFI3JJ.mjs.map +0 -7
  163. package/dist/types/src/components/Table/CreateRefPanel.d.ts +0 -9
  164. package/dist/types/src/components/Table/CreateRefPanel.d.ts.map +0 -1
  165. package/dist/types/src/components/TableCellEditor/extension.d.ts +0 -13
  166. package/dist/types/src/components/TableCellEditor/extension.d.ts.map +0 -1
  167. package/dist/types/src/components/TableToolbar/TableToolbar.d.ts +0 -21
  168. package/dist/types/src/components/TableToolbar/TableToolbar.d.ts.map +0 -1
  169. package/dist/types/src/components/TableToolbar/index.d.ts +0 -2
  170. package/dist/types/src/components/TableToolbar/index.d.ts.map +0 -1
  171. package/dist/types/src/model/table-sorting.d.ts +0 -53
  172. package/dist/types/src/model/table-sorting.d.ts.map +0 -1
  173. package/dist/types/src/types/schema.d.ts +0 -8
  174. package/dist/types/src/types/schema.d.ts.map +0 -1
  175. package/dist/types/src/util/table.d.ts +0 -12
  176. package/dist/types/src/util/table.d.ts.map +0 -1
  177. package/src/components/Table/CreateRefPanel.tsx +0 -86
  178. package/src/components/TableCellEditor/extension.ts +0 -61
  179. package/src/components/TableToolbar/TableToolbar.tsx +0 -102
  180. package/src/components/TableToolbar/index.ts +0 -5
  181. package/src/model/table-sorting.ts +0 -216
  182. package/src/types/schema.ts +0 -16
  183. package/src/util/table.ts +0 -53
package/package.json CHANGED
@@ -1,20 +1,21 @@
1
1
  {
2
2
  "name": "@dxos/react-ui-table",
3
- "version": "0.8.4-main.fd6878d",
3
+ "version": "0.9.0",
4
4
  "description": "A table component.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
7
- "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/dxos/dxos"
10
+ },
11
+ "license": "FSL-1.1-Apache-2.0",
8
12
  "author": "DXOS.org",
9
- "sideEffects": true,
13
+ "sideEffects": false,
10
14
  "type": "module",
15
+ "imports": {
16
+ "#translations": "./src/translations.ts"
17
+ },
11
18
  "exports": {
12
- "./deprecated": {
13
- "source": "./src/deprecated/index.ts",
14
- "types": "./dist/types/src/deprecated/index.d.ts",
15
- "browser": "./dist/lib/browser/deprecated/index.mjs",
16
- "node": "./dist/lib/node-esm/deprecated/index.mjs"
17
- },
18
19
  ".": {
19
20
  "source": "./src/index.ts",
20
21
  "types": "./dist/types/src/index.d.ts",
@@ -27,6 +28,12 @@
27
28
  "browser": "./dist/lib/browser/testing/index.mjs",
28
29
  "node": "./dist/lib/node-esm/testing/index.mjs"
29
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
+ },
30
37
  "./types": {
31
38
  "source": "./src/types/index.ts",
32
39
  "types": "./dist/types/src/types/index.d.ts",
@@ -35,90 +42,74 @@
35
42
  }
36
43
  },
37
44
  "types": "dist/types/src/index.d.ts",
38
- "typesVersions": {
39
- "*": {
40
- "deprecated": [
41
- "dist/types/src/deprecated/index.d.ts"
42
- ],
43
- "testing": [
44
- "dist/types/src/testing/index.d.ts"
45
- ],
46
- "types": [
47
- "dist/types/src/types/index.d.ts"
48
- ]
49
- }
50
- },
51
45
  "files": [
52
46
  "dist",
53
47
  "src"
54
48
  ],
55
49
  "dependencies": {
56
- "@codemirror/autocomplete": "^6.18.1",
57
- "@codemirror/state": "^6.4.1",
58
- "@codemirror/view": "^6.34.1",
59
- "@fluentui/react-tabster": "^9.24.2",
60
- "@preact-signals/safe-react": "^0.9.0",
61
- "@preact/signals-core": "^1.9.0",
50
+ "@codemirror/autocomplete": "^6.20.2",
51
+ "@codemirror/state": "^6.6.0",
52
+ "@codemirror/view": "^6.43.0",
53
+ "@effect-atom/atom-react": "^0.5.0",
54
+ "@fluentui/react-tabster": "9.26.11",
62
55
  "@radix-ui/react-context": "1.1.1",
63
56
  "@radix-ui/react-primitive": "2.0.2",
64
57
  "@radix-ui/react-slot": "1.1.2",
65
58
  "@radix-ui/react-use-controllable-state": "1.1.0",
66
- "date-fns": "^3.3.1",
59
+ "date-fns": "^3.6.0",
67
60
  "lodash.orderby": "^4.6.0",
68
- "@dxos/context": "0.8.4-main.fd6878d",
69
- "@dxos/debug": "0.8.4-main.fd6878d",
70
- "@dxos/echo": "0.8.4-main.fd6878d",
71
- "@dxos/echo-db": "0.8.4-main.fd6878d",
72
- "@dxos/echo-schema": "0.8.4-main.fd6878d",
73
- "@dxos/invariant": "0.8.4-main.fd6878d",
74
- "@dxos/effect": "0.8.4-main.fd6878d",
75
- "@dxos/keys": "0.8.4-main.fd6878d",
76
- "@dxos/lit-grid": "0.8.4-main.fd6878d",
77
- "@dxos/live-object": "0.8.4-main.fd6878d",
78
- "@dxos/log": "0.8.4-main.fd6878d",
79
- "@dxos/plugin-search": "0.8.4-main.fd6878d",
80
- "@dxos/random": "0.8.4-main.fd6878d",
81
- "@dxos/react-client": "0.8.4-main.fd6878d",
82
- "@dxos/react-ui-editor": "0.8.4-main.fd6878d",
83
- "@dxos/react-ui-grid": "0.8.4-main.fd6878d",
84
- "@dxos/react-ui-attention": "0.8.4-main.fd6878d",
85
- "@dxos/react-ui-form": "0.8.4-main.fd6878d",
86
- "@dxos/react-ui-stack": "0.8.4-main.fd6878d",
87
- "@dxos/react-ui-searchlist": "0.8.4-main.fd6878d",
88
- "@dxos/react-ui-syntax-highlighter": "0.8.4-main.fd6878d",
89
- "@dxos/react-ui-tag-picker": "0.8.4-main.fd6878d",
90
- "@dxos/react-ui-types": "0.8.4-main.fd6878d",
91
- "@dxos/schema": "0.8.4-main.fd6878d",
92
- "@dxos/react-ui-menu": "0.8.4-main.fd6878d",
93
- "@dxos/util": "0.8.4-main.fd6878d"
61
+ "@dxos/debug": "0.9.0",
62
+ "@dxos/async": "0.9.0",
63
+ "@dxos/context": "0.9.0",
64
+ "@dxos/echo": "0.9.0",
65
+ "@dxos/effect": "0.9.0",
66
+ "@dxos/invariant": "0.9.0",
67
+ "@dxos/keys": "0.9.0",
68
+ "@dxos/random": "0.9.0",
69
+ "@dxos/react-ui-attention": "0.9.0",
70
+ "@dxos/log": "0.9.0",
71
+ "@dxos/react-client": "0.9.0",
72
+ "@dxos/react-ui-components": "0.9.0",
73
+ "@dxos/react-ui-editor": "0.9.0",
74
+ "@dxos/lit-grid": "0.9.0",
75
+ "@dxos/react-ui-form": "0.9.0",
76
+ "@dxos/react-ui-grid": "0.9.0",
77
+ "@dxos/react-ui-list": "0.9.0",
78
+ "@dxos/react-ui-menu": "0.9.0",
79
+ "@dxos/react-ui-search": "0.9.0",
80
+ "@dxos/react-ui-stack": "0.9.0",
81
+ "@dxos/react-ui-syntax-highlighter": "0.9.0",
82
+ "@dxos/types": "0.9.0",
83
+ "@dxos/schema": "0.9.0",
84
+ "@dxos/ui-types": "0.9.0",
85
+ "@dxos/util": "0.9.0"
94
86
  },
95
87
  "devDependencies": {
96
- "@effect-rx/rx-react": "0.38.0",
97
- "@effect/platform": "0.90.2",
88
+ "@effect/platform": "0.96.1",
98
89
  "@types/lodash.orderby": "^4.6.9",
99
- "@types/react": "~18.2.0",
100
- "@types/react-dom": "~18.2.0",
101
- "effect": "3.17.7",
90
+ "@types/react": "~19.2.7",
91
+ "@types/react-dom": "~19.2.3",
92
+ "effect": "3.21.3",
102
93
  "fast-check": "^3.19.0",
103
- "react": "~18.2.0",
104
- "react-dom": "~18.2.0",
105
- "vite": "5.4.7",
106
- "@dxos/echo-signals": "0.8.4-main.fd6878d",
107
- "@dxos/plugin-search": "0.8.4-main.fd6878d",
108
- "@dxos/random": "0.8.4-main.fd6878d",
109
- "@dxos/react-ui-theme": "0.8.4-main.fd6878d",
110
- "@dxos/test-utils": "0.8.4-main.fd6878d",
111
- "@dxos/react-ui": "0.8.4-main.fd6878d",
112
- "@dxos/storybook-utils": "0.8.4-main.fd6878d"
94
+ "react": "~19.2.3",
95
+ "react-dom": "~19.2.3",
96
+ "vite": "^8.0.16",
97
+ "@dxos/lit-ui": "0.9.0",
98
+ "@dxos/react-client": "0.9.0",
99
+ "@dxos/react-ui": "0.9.0",
100
+ "@dxos/storybook-utils": "0.9.0",
101
+ "@dxos/ui-theme": "0.9.0",
102
+ "@dxos/random": "0.9.0",
103
+ "@dxos/test-utils": "0.9.0"
113
104
  },
114
105
  "peerDependencies": {
115
- "@effect-rx/rx-react": "^0.34.1",
116
- "@effect/platform": "^0.80.12",
117
- "effect": "^3.13.3",
118
- "react": "~18.2.0",
119
- "react-dom": "~18.2.0",
120
- "@dxos/react-ui-theme": "0.8.4-main.fd6878d",
121
- "@dxos/react-ui": "0.8.4-main.fd6878d"
106
+ "@effect-atom/atom-react": "^0.5.0",
107
+ "@effect/platform": "0.96.1",
108
+ "effect": "3.21.3",
109
+ "react": "~19.2.3",
110
+ "react-dom": "~19.2.3",
111
+ "@dxos/react-ui": "0.9.0",
112
+ "@dxos/ui-theme": "0.9.0"
122
113
  },
123
114
  "publishConfig": {
124
115
  "access": "public"
@@ -2,23 +2,28 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
+ import { useAtomValue } from '@effect-atom/atom-react';
5
6
  import React from 'react';
6
7
 
7
8
  import { DropdownMenu, useTranslation } from '@dxos/react-ui';
8
9
 
10
+ import { translationKey } from '#translations';
11
+
9
12
  import { type ModalController, type TableModel } from '../../model';
10
- import { translationKey } from '../../translations';
11
13
 
12
- type ColumnActionsMenuProps = { model: TableModel; modals: ModalController };
14
+ export type ColumnActionsMenuProps = {
15
+ model: TableModel;
16
+ modals: ModalController;
17
+ };
13
18
 
14
19
  export const ColumnActionsMenu = ({ model, modals }: ColumnActionsMenuProps) => {
15
20
  const { t } = useTranslation(translationKey);
16
- const state = modals.state.value;
21
+ const state = useAtomValue(modals.state);
17
22
  if (state?.type !== 'column') {
18
23
  return null;
19
24
  }
20
25
 
21
- const currentSort = model.sorting?.sorting;
26
+ const currentSort = model.getSorting();
22
27
  const isCurrentColumnSorted = currentSort?.fieldId === state.fieldId;
23
28
 
24
29
  return (
@@ -30,32 +35,32 @@ export const ColumnActionsMenu = ({ model, modals }: ColumnActionsMenuProps) =>
30
35
  {(!isCurrentColumnSorted || currentSort?.direction === 'asc') && (
31
36
  <DropdownMenu.Item
32
37
  data-testid='column-sort-descending'
33
- onClick={() => model.sorting?.setSort(state.fieldId, 'desc')}
38
+ onClick={() => model.setSort(state.fieldId, 'desc')}
34
39
  >
35
- {t('column action sort descending')}
40
+ {t('column-action-sort-descending.menu')}
36
41
  </DropdownMenu.Item>
37
42
  )}
38
43
  {(!isCurrentColumnSorted || currentSort?.direction === 'desc') && (
39
44
  <DropdownMenu.Item
40
45
  data-testid='column-sort-ascending'
41
- onClick={() => model.sorting?.setSort(state.fieldId, 'asc')}
46
+ onClick={() => model.setSort(state.fieldId, 'asc')}
42
47
  >
43
- {t('column action sort ascending')}
48
+ {t('column-action-sort-ascending.menu')}
44
49
  </DropdownMenu.Item>
45
50
  )}
46
51
  {isCurrentColumnSorted && (
47
- <DropdownMenu.Item data-testid='column-clear-sort' onClick={() => model.sorting?.clearSort()}>
48
- {t('column action clear sorting')}
52
+ <DropdownMenu.Item data-testid='column-clear-sort' onClick={() => model.clearSort()}>
53
+ {t('column-action-clear-sorting.menu')}
49
54
  </DropdownMenu.Item>
50
55
  )}
51
56
  {model.getColumnCount() > 1 && model.features.schemaEditable && (
52
57
  <DropdownMenu.Item data-testid='column-delete' onClick={() => model.deleteColumn(state.fieldId)}>
53
- {t('column action delete')}
58
+ {t('column-action-delete.menu')}
54
59
  </DropdownMenu.Item>
55
60
  )}
56
61
  {model.features.schemaEditable && (
57
62
  <DropdownMenu.Item data-testid='column-settings' onClick={() => modals.openColumnSettings()}>
58
- {t('column action settings')}
63
+ {t('column-action-settings.menu')}
59
64
  </DropdownMenu.Item>
60
65
  )}
61
66
  </DropdownMenu.Viewport>
@@ -2,26 +2,25 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
+ import { useAtomValue } from '@effect-atom/atom-react';
5
6
  import React, { useCallback, useEffect, useMemo, useState } from 'react';
6
7
 
7
- // TODO(burdon): Remove dependency on echo-db.
8
- import { type SchemaRegistry } from '@dxos/echo-db';
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
- import { type FieldType } from '@dxos/schema';
12
11
 
13
12
  import { type ModalController, type TableModel } from '../../model';
14
13
 
15
14
  type ColumnSettingsProps = {
16
- registry?: SchemaRegistry;
15
+ registry?: Registry.Registry;
17
16
  model?: TableModel;
18
17
  modals: ModalController;
19
18
  onNewColumn: () => void;
20
19
  };
21
20
 
22
21
  export const ColumnSettings = ({ registry, model, modals, onNewColumn }: ColumnSettingsProps) => {
23
- const [newField, setNewField] = useState<FieldType>();
24
- const state = modals.state.value;
22
+ const [newField, setNewField] = useState<View.FieldType>();
23
+ const state = useAtomValue(modals.state);
25
24
 
26
25
  useEffect(() => {
27
26
  if (state?.type === 'columnSettings' && state.mode.type === 'create' && model?.projection) {
@@ -38,11 +37,11 @@ export const ColumnSettings = ({ registry, model, modals, onNewColumn }: ColumnS
38
37
  if (state?.type === 'columnSettings') {
39
38
  const { mode } = state;
40
39
  if (mode.type === 'edit') {
41
- return model?.projection?.fields.find((f) => f.id === mode.fieldId);
40
+ return model?.projection?.getFields().find((f) => f.id === mode.fieldId);
42
41
  }
43
42
  }
44
43
  return undefined;
45
- }, [model?.projection?.fields, state]);
44
+ }, [model?.projection, state]);
46
45
 
47
46
  const field = existingField ?? newField;
48
47
 
@@ -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}
@@ -2,42 +2,41 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
6
-
7
5
  import { type Meta, type StoryObj } from '@storybook/react-vite';
6
+ import type * as Types from 'effect/Types';
8
7
  import React, { useMemo, useState } from 'react';
9
8
 
10
- import { Obj } from '@dxos/echo';
11
- import { FormatEnum, type JsonSchemaType } from '@dxos/echo-schema';
12
- import { faker } from '@dxos/random';
13
- import { useClient } from '@dxos/react-client';
14
- import { Filter, useQuery, useSchema } from '@dxos/react-client/echo';
15
- import { useClientProvider, withClientProvider } from '@dxos/react-client/testing';
9
+ import { Filter, type JsonSchema, Obj, Type } from '@dxos/echo';
10
+ import { Format } from '@dxos/echo/Format';
11
+ import { random } from '@dxos/random';
12
+ import { useQuery, useType } from '@dxos/react-client/echo';
13
+ import { useClientStory, withClientProvider } from '@dxos/react-client/testing';
14
+ import { withLayout, withTheme } from '@dxos/react-ui/testing';
16
15
  import { type SchemaPropertyDefinition } from '@dxos/schema';
17
- import { Testing } from '@dxos/schema/testing';
18
- import { withLayout, withTheme } from '@dxos/storybook-utils';
16
+ import { TestSchema } from '@dxos/schema/testing';
17
+ import { withRegistry } from '@dxos/storybook-utils';
19
18
 
20
- import { type TableFeatures } from '../../model';
21
- import { translations } from '../../translations';
19
+ import { translations } from '#translations';
22
20
 
21
+ import { type TableFeatures } from '../../model';
23
22
  import { DynamicTable } from './DynamicTable';
24
23
 
25
- faker.seed(0);
24
+ random.seed(0);
26
25
 
27
26
  const useTestPropertiesAndObjects = () => {
28
27
  const properties = useMemo<SchemaPropertyDefinition[]>(
29
28
  () => [
30
- { name: 'name', format: FormatEnum.String },
31
- { name: 'age', format: FormatEnum.Number },
29
+ { name: 'name', format: Format.TypeFormat.String },
30
+ { name: 'age', format: Format.TypeFormat.Number },
32
31
  ],
33
32
  [],
34
33
  );
35
34
 
36
35
  const [rows] = useState<any[]>(
37
36
  Array.from({ length: 10 }, () => ({
38
- id: faker.string.uuid(),
39
- name: faker.person.fullName(),
40
- age: faker.number.int({ min: 18, max: 80 }),
37
+ id: random.string.uuid(),
38
+ name: random.person.fullName(),
39
+ age: random.number.int({ min: 18, max: 80 }),
41
40
  })),
42
41
  );
43
42
 
@@ -57,15 +56,20 @@ const DynamicTableStory = () => {
57
56
  // Story definitions.
58
57
  //
59
58
 
60
- const meta: Meta = {
59
+ const meta = {
61
60
  title: 'ui/react-ui-table/DynamicTable',
62
61
  component: DynamicTable,
63
- parameters: { translations },
64
- decorators: [withLayout({ fullscreen: true }), withTheme],
65
- };
62
+ decorators: [withTheme(), withLayout({ layout: 'fullscreen' }), withRegistry],
63
+ parameters: {
64
+ layout: 'fullscreen',
65
+ translations,
66
+ },
67
+ } satisfies Meta<typeof DynamicTable>;
66
68
 
67
69
  export default meta;
68
70
 
71
+ type Story = StoryObj<typeof meta>;
72
+
69
73
  export const Default: StoryObj = {
70
74
  render: DynamicTableStory,
71
75
  };
@@ -98,7 +102,7 @@ export const WithClickToSelect: StoryObj = {
98
102
 
99
103
  export const WithJsonSchema: StoryObj = {
100
104
  render: () => {
101
- const schema = useMemo<JsonSchemaType>(
105
+ const schema = useMemo<Types.DeepMutable<JsonSchema.JsonSchema>>(
102
106
  () => ({
103
107
  type: 'object',
104
108
  properties: {
@@ -114,10 +118,10 @@ export const WithJsonSchema: StoryObj = {
114
118
 
115
119
  const [rows] = useState<any[]>(
116
120
  Array.from({ length: 15 }, () => ({
117
- name: faker.person.fullName(),
118
- age: faker.number.int({ min: 18, max: 80 }),
119
- email: faker.internet.email(),
120
- active: faker.datatype.boolean(),
121
+ name: random.person.fullName(),
122
+ age: random.number.int({ min: 18, max: 80 }),
123
+ email: random.internet.email(),
124
+ active: random.datatype.boolean(),
121
125
  })),
122
126
  );
123
127
 
@@ -127,27 +131,26 @@ export const WithJsonSchema: StoryObj = {
127
131
 
128
132
  export const WithEchoSchema: StoryObj = {
129
133
  render: () => {
130
- const client = useClient();
131
- const { space } = useClientProvider();
132
- const schema = useSchema(client, space, Testing.Contact.typename);
133
- const objects = useQuery(space, schema ? Filter.type(schema) : Filter.nothing());
134
- if (!schema) {
134
+ const { space } = useClientStory();
135
+ const type = useType(space?.db, Type.getURI(TestSchema.Person));
136
+ const objects = useQuery(space?.db, type ? Filter.type(type) : Filter.nothing());
137
+ if (!type) {
135
138
  return <div>Loading schema...</div>;
136
139
  }
137
140
 
138
- return <DynamicTable schema={schema} rows={objects} />;
141
+ return <DynamicTable type={type} rows={objects} />;
139
142
  },
140
143
  decorators: [
141
144
  withClientProvider({
142
- types: [Testing.Contact],
145
+ types: [TestSchema.Person],
143
146
  createIdentity: true,
144
147
  createSpace: true,
145
- onSpaceCreated: async ({ space }) => {
148
+ onCreateSpace: async ({ space }) => {
146
149
  Array.from({ length: 10 }).forEach(() => {
147
150
  space.db.add(
148
- Obj.make(Testing.Contact, {
149
- name: faker.person.fullName(),
150
- email: faker.internet.email(),
151
+ Obj.make(TestSchema.Person, {
152
+ name: random.person.fullName(),
153
+ email: random.internet.email(),
151
154
  }),
152
155
  );
153
156
  });
@@ -2,25 +2,27 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { type Schema } from 'effect';
6
- import React, { useCallback, useMemo, useRef } from 'react';
5
+ import { RegistryContext } from '@effect-atom/atom-react';
6
+ import type * as Types from 'effect/Types';
7
+ import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
7
8
 
8
- import { type JsonSchemaType } from '@dxos/echo-schema';
9
+ import { type JsonSchema, type Type } from '@dxos/echo';
9
10
  import { type ThemedClassName, useDefaultValue } from '@dxos/react-ui';
10
- import { mx } from '@dxos/react-ui-theme';
11
+ import { type ProjectionModel } from '@dxos/schema';
12
+ import { mx } from '@dxos/ui-theme';
11
13
 
12
14
  import { useTableModel } from '../../hooks';
13
15
  import { type TableFeatures, TablePresentation, type TableRowAction } from '../../model';
16
+ import { type Table as TableType } from '../../types';
14
17
  import { type TablePropertyDefinition, getBaseSchema, makeDynamicTable } from '../../util';
15
-
16
18
  import { Table, type TableController } from './Table';
17
19
 
18
- type DynamicTableProps = ThemedClassName<{
20
+ export type DynamicTableProps<T extends Type.AnyEntity = Type.AnyEntity> = ThemedClassName<{
21
+ type?: T;
19
22
  name?: string; // TODO(burdon): Remove?
20
23
  rows: any[];
21
24
  properties?: TablePropertyDefinition[];
22
- jsonSchema?: JsonSchemaType;
23
- schema?: Schema.Schema.AnyNoContext;
25
+ jsonSchema?: Types.DeepMutable<JsonSchema.JsonSchema>;
24
26
  features?: Partial<TableFeatures>;
25
27
  rowActions?: TableRowAction[];
26
28
  onRowClick?: (row: any) => void;
@@ -32,28 +34,30 @@ type DynamicTableProps = ThemedClassName<{
32
34
  */
33
35
  // TODO(burdon): Instead of creating component variants, create helpers/hooks that normalize the props.
34
36
  // TODO(burdon): Warning: Cannot update a component (`DynamicTable`) while rendering a different component (`DynamicTable`).
35
- export const DynamicTable = ({
37
+ export const DynamicTable = <T extends Type.AnyEntity = Type.AnyEntity>({
36
38
  classNames,
37
- name = 'example.com/dynamic-table', // Rmove default or make random; this will lead to type collisions.
39
+ type: typeProp,
40
+ name = 'com.example.dynamicTable', // Remove default or make random; this will lead to type collisions.
38
41
  rows,
39
42
  properties,
40
- jsonSchema: _jsonSchema,
41
- schema,
43
+ jsonSchema: jsonSchemaProp,
42
44
  rowActions,
43
45
  onRowClick,
44
46
  onRowAction,
45
47
  ...props
46
- }: DynamicTableProps) => {
48
+ }: DynamicTableProps<T>) => {
49
+ const registry = useContext(RegistryContext);
50
+ const [dynamicTable, setDynamicTable] = useState<{ object: TableType.Table; projection: ProjectionModel }>();
51
+
47
52
  // TODO(burdon): Remove variance from the props (should be normalized externally; possibly via hooks).
48
- const { typename, jsonSchema } = useMemo(
49
- () => getBaseSchema({ typename: name, properties, jsonSchema: _jsonSchema, schema }),
50
- [name, properties, _jsonSchema, schema],
53
+ const { type } = useMemo(
54
+ () => getBaseSchema({ typename: name, properties, jsonSchema: jsonSchemaProp, type: typeProp }),
55
+ [name, properties, jsonSchemaProp, typeProp],
51
56
  );
52
57
 
53
- const { projection, view } = useMemo(
54
- () => makeDynamicTable({ typename, jsonSchema, properties }),
55
- [typename, jsonSchema, properties],
56
- );
58
+ useEffect(() => {
59
+ setDynamicTable(makeDynamicTable({ registry, type, properties }));
60
+ }, [registry, type, properties]);
57
61
 
58
62
  const tableRef = useRef<TableController>(null);
59
63
  const handleCellUpdate = useCallback((cell: any) => {
@@ -75,9 +79,8 @@ export const DynamicTable = ({
75
79
 
76
80
  const model = useTableModel({
77
81
  rows,
78
- view,
79
- schema: jsonSchema,
80
- projection,
82
+ object: dynamicTable?.object,
83
+ projection: dynamicTable?.projection,
81
84
  features,
82
85
  rowActions,
83
86
  onCellUpdate: handleCellUpdate,
@@ -87,22 +90,15 @@ export const DynamicTable = ({
87
90
 
88
91
  const presentation = useMemo(() => {
89
92
  if (model) {
90
- return new TablePresentation(model);
93
+ return new TablePresentation(registry, model);
91
94
  }
92
- }, [model]);
95
+ }, [registry, model]);
93
96
 
94
- // TODO(burdon): Do we need the outer divs?
95
97
  return (
96
- <div role='none' className={mx('is-full bs-full grow grid', classNames)}>
97
- <div role='none' className='grid min-bs-0 overflow-hidden'>
98
- <Table.Root>
99
- <Table.Main
100
- ref={tableRef}
101
- model={model}
102
- presentation={presentation}
103
- ignoreAttention
104
- onRowClick={onRowClick}
105
- />
98
+ <div className={mx('dx-expander grid', classNames)}>
99
+ <div className='grid min-h-0 overflow-hidden'>
100
+ <Table.Root ref={tableRef}>
101
+ <Table.Content model={model} presentation={presentation} ignoreAttention onRowClick={onRowClick} />
106
102
  </Table.Root>
107
103
  </div>
108
104
  </div>