@dxos/react-ui-table 0.8.1-main.ba2dec9 → 0.8.1-staging.5be625a

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 (203) hide show
  1. package/dist/lib/browser/{chunk-3FR6NHPD.mjs → chunk-5MKYB7NF.mjs} +5 -7
  2. package/dist/lib/browser/chunk-5MKYB7NF.mjs.map +7 -0
  3. package/dist/lib/browser/{_deprecated → deprecated}/index.mjs +26 -26
  4. package/dist/lib/{node-esm/_deprecated → browser/deprecated}/index.mjs.map +4 -4
  5. package/dist/lib/browser/index.mjs +394 -192
  6. package/dist/lib/browser/index.mjs.map +4 -4
  7. package/dist/lib/browser/meta.json +1 -1
  8. package/dist/lib/browser/types/index.mjs +1 -1
  9. package/dist/lib/node/{chunk-NB3SFHGA.cjs → chunk-NRFKBRPV.cjs} +7 -9
  10. package/dist/lib/node/chunk-NRFKBRPV.cjs.map +7 -0
  11. package/dist/lib/node/{_deprecated → deprecated}/index.cjs +5 -5
  12. package/dist/lib/node/{_deprecated → deprecated}/index.cjs.map +4 -4
  13. package/dist/lib/node/index.cjs +386 -188
  14. package/dist/lib/node/index.cjs.map +4 -4
  15. package/dist/lib/node/meta.json +1 -1
  16. package/dist/lib/node/types/index.cjs +3 -3
  17. package/dist/lib/node/types/index.cjs.map +1 -1
  18. package/dist/lib/node-esm/{chunk-RLVVOZW5.mjs → chunk-SU4D55KI.mjs} +5 -7
  19. package/dist/lib/node-esm/chunk-SU4D55KI.mjs.map +7 -0
  20. package/dist/lib/node-esm/{_deprecated → deprecated}/index.mjs +26 -26
  21. package/dist/lib/node-esm/deprecated/index.mjs.map +7 -0
  22. package/dist/lib/node-esm/index.mjs +394 -192
  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/types/index.mjs +1 -1
  26. package/dist/types/src/components/Table/ColumnActionsMenu.d.ts.map +1 -1
  27. package/dist/types/src/components/Table/ColumnSettings.d.ts.map +1 -1
  28. package/dist/types/src/components/Table/DynamicTable.d.ts +19 -0
  29. package/dist/types/src/components/Table/DynamicTable.d.ts.map +1 -0
  30. package/dist/types/src/components/Table/RowActionsMenu.d.ts.map +1 -1
  31. package/dist/types/src/components/Table/Table.d.ts +1 -0
  32. package/dist/types/src/components/Table/Table.d.ts.map +1 -1
  33. package/dist/types/src/components/Table/Table.stories.d.ts +3 -1
  34. package/dist/types/src/components/Table/Table.stories.d.ts.map +1 -1
  35. package/dist/types/src/components/Table/index.d.ts +1 -0
  36. package/dist/types/src/components/Table/index.d.ts.map +1 -1
  37. package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts.map +1 -1
  38. package/dist/types/src/components/testing.d.ts +7 -7
  39. package/dist/types/src/components/testing.d.ts.map +1 -1
  40. package/dist/types/src/deprecated/components/Cell/Cell.d.ts.map +1 -0
  41. package/dist/types/src/deprecated/components/Cell/CellCombobox.d.ts.map +1 -0
  42. package/dist/types/src/deprecated/components/Cell/index.d.ts.map +1 -0
  43. package/dist/types/src/deprecated/components/ColumnMenu/ColumnMenu.d.ts.map +1 -0
  44. package/dist/types/src/deprecated/components/ColumnMenu/ColumnMenu.stories.d.ts.map +1 -0
  45. package/dist/types/src/deprecated/components/ColumnMenu/ColumnSettings.d.ts.map +1 -0
  46. package/dist/types/src/deprecated/components/ColumnMenu/ColumnSettings.stories.d.ts.map +1 -0
  47. package/dist/types/src/deprecated/components/ColumnMenu/index.d.ts.map +1 -0
  48. package/dist/types/src/deprecated/components/Table/Table.d.ts.map +1 -0
  49. package/dist/types/src/deprecated/components/Table/Table.stories.d.ts.map +1 -0
  50. package/dist/types/src/deprecated/components/Table/TableBody.d.ts.map +1 -0
  51. package/dist/types/src/deprecated/components/Table/TableContext.d.ts.map +1 -0
  52. package/dist/types/src/deprecated/components/Table/TableHead.d.ts.map +1 -0
  53. package/dist/types/src/deprecated/components/Table/TableRootContext.d.ts.map +1 -0
  54. package/dist/types/src/deprecated/components/Table/index.d.ts.map +1 -0
  55. package/dist/types/src/deprecated/components/Table/props.d.ts.map +1 -0
  56. package/dist/types/src/deprecated/components/index.d.ts.map +1 -0
  57. package/dist/types/src/deprecated/helpers.d.ts.map +1 -0
  58. package/dist/types/src/deprecated/hooks/index.d.ts.map +1 -0
  59. package/dist/types/src/deprecated/hooks/useColumnSizing.d.ts.map +1 -0
  60. package/dist/types/src/deprecated/hooks/useColumnSorting.d.ts.map +1 -0
  61. package/dist/types/src/deprecated/hooks/usePinLastRow.d.ts.map +1 -0
  62. package/dist/types/src/deprecated/hooks/useRowSelection.d.ts.map +1 -0
  63. package/dist/types/src/deprecated/index.d.ts.map +1 -0
  64. package/dist/types/src/deprecated/schema/Schema.stories.d.ts.map +1 -0
  65. package/dist/types/src/deprecated/schema/column-utils.d.ts.map +1 -0
  66. package/dist/types/src/deprecated/schema/index.d.ts.map +1 -0
  67. package/dist/types/src/deprecated/schema/types.d.ts.map +1 -0
  68. package/dist/types/src/deprecated/theme.d.ts.map +1 -0
  69. package/dist/types/src/deprecated/translations.d.ts.map +1 -0
  70. package/dist/types/src/deprecated/types.d.ts.map +1 -0
  71. package/dist/types/src/hooks/useTableModel.d.ts +6 -3
  72. package/dist/types/src/hooks/useTableModel.d.ts.map +1 -1
  73. package/dist/types/src/model/table-model.d.ts +34 -7
  74. package/dist/types/src/model/table-model.d.ts.map +1 -1
  75. package/dist/types/src/model/table-presentation.d.ts.map +1 -1
  76. package/dist/types/src/model/table-sorting.d.ts.map +1 -1
  77. package/dist/types/src/types/table.d.ts +7 -33
  78. package/dist/types/src/types/table.d.ts.map +1 -1
  79. package/dist/types/src/util/dynamic-table.d.ts +40 -0
  80. package/dist/types/src/util/dynamic-table.d.ts.map +1 -0
  81. package/dist/types/src/util/index.d.ts +1 -0
  82. package/dist/types/src/util/index.d.ts.map +1 -1
  83. package/dist/types/src/util/table.d.ts +5 -3
  84. package/dist/types/src/util/table.d.ts.map +1 -1
  85. package/package.json +35 -35
  86. package/src/components/Table/ColumnActionsMenu.tsx +6 -4
  87. package/src/components/Table/ColumnSettings.tsx +5 -6
  88. package/src/components/Table/CreateRefPanel.tsx +3 -3
  89. package/src/components/Table/DynamicTable.tsx +86 -0
  90. package/src/components/Table/RefPanel.tsx +3 -3
  91. package/src/components/Table/RowActionsMenu.tsx +18 -3
  92. package/src/components/Table/Table.stories.tsx +71 -20
  93. package/src/components/Table/Table.tsx +30 -10
  94. package/src/components/Table/index.ts +1 -0
  95. package/src/components/TableCellEditor/TableCellEditor.stories.tsx +9 -4
  96. package/src/components/testing.ts +1 -0
  97. package/src/{_deprecated → deprecated}/components/Cell/Cell.tsx +2 -2
  98. package/src/{_deprecated → deprecated}/components/Table/TableBody.tsx +2 -2
  99. package/src/{_deprecated → deprecated}/helpers.tsx +2 -2
  100. package/src/hooks/useTableModel.ts +28 -7
  101. package/src/model/table-model.test.ts +1 -1
  102. package/src/model/table-model.ts +97 -21
  103. package/src/model/table-presentation.test.ts +1 -1
  104. package/src/model/table-presentation.ts +30 -12
  105. package/src/model/table-sorting.ts +1 -0
  106. package/src/types/table.ts +5 -7
  107. package/src/util/dynamic-table.ts +71 -0
  108. package/src/util/index.ts +1 -0
  109. package/src/util/table.ts +67 -65
  110. package/dist/lib/browser/_deprecated/index.mjs.map +0 -7
  111. package/dist/lib/browser/chunk-3FR6NHPD.mjs.map +0 -7
  112. package/dist/lib/node/chunk-NB3SFHGA.cjs.map +0 -7
  113. package/dist/lib/node-esm/chunk-RLVVOZW5.mjs.map +0 -7
  114. package/dist/types/src/_deprecated/components/Cell/Cell.d.ts.map +0 -1
  115. package/dist/types/src/_deprecated/components/Cell/CellCombobox.d.ts.map +0 -1
  116. package/dist/types/src/_deprecated/components/Cell/index.d.ts.map +0 -1
  117. package/dist/types/src/_deprecated/components/ColumnMenu/ColumnMenu.d.ts.map +0 -1
  118. package/dist/types/src/_deprecated/components/ColumnMenu/ColumnMenu.stories.d.ts.map +0 -1
  119. package/dist/types/src/_deprecated/components/ColumnMenu/ColumnSettings.d.ts.map +0 -1
  120. package/dist/types/src/_deprecated/components/ColumnMenu/ColumnSettings.stories.d.ts.map +0 -1
  121. package/dist/types/src/_deprecated/components/ColumnMenu/index.d.ts.map +0 -1
  122. package/dist/types/src/_deprecated/components/Table/Table.d.ts.map +0 -1
  123. package/dist/types/src/_deprecated/components/Table/Table.stories.d.ts.map +0 -1
  124. package/dist/types/src/_deprecated/components/Table/TableBody.d.ts.map +0 -1
  125. package/dist/types/src/_deprecated/components/Table/TableContext.d.ts.map +0 -1
  126. package/dist/types/src/_deprecated/components/Table/TableHead.d.ts.map +0 -1
  127. package/dist/types/src/_deprecated/components/Table/TableRootContext.d.ts.map +0 -1
  128. package/dist/types/src/_deprecated/components/Table/index.d.ts.map +0 -1
  129. package/dist/types/src/_deprecated/components/Table/props.d.ts.map +0 -1
  130. package/dist/types/src/_deprecated/components/index.d.ts.map +0 -1
  131. package/dist/types/src/_deprecated/helpers.d.ts.map +0 -1
  132. package/dist/types/src/_deprecated/hooks/index.d.ts.map +0 -1
  133. package/dist/types/src/_deprecated/hooks/useColumnSizing.d.ts.map +0 -1
  134. package/dist/types/src/_deprecated/hooks/useColumnSorting.d.ts.map +0 -1
  135. package/dist/types/src/_deprecated/hooks/usePinLastRow.d.ts.map +0 -1
  136. package/dist/types/src/_deprecated/hooks/useRowSelection.d.ts.map +0 -1
  137. package/dist/types/src/_deprecated/index.d.ts.map +0 -1
  138. package/dist/types/src/_deprecated/schema/Schema.stories.d.ts.map +0 -1
  139. package/dist/types/src/_deprecated/schema/column-utils.d.ts.map +0 -1
  140. package/dist/types/src/_deprecated/schema/index.d.ts.map +0 -1
  141. package/dist/types/src/_deprecated/schema/types.d.ts.map +0 -1
  142. package/dist/types/src/_deprecated/theme.d.ts.map +0 -1
  143. package/dist/types/src/_deprecated/translations.d.ts.map +0 -1
  144. package/dist/types/src/_deprecated/types.d.ts.map +0 -1
  145. /package/dist/types/src/{_deprecated → deprecated}/components/Cell/Cell.d.ts +0 -0
  146. /package/dist/types/src/{_deprecated → deprecated}/components/Cell/CellCombobox.d.ts +0 -0
  147. /package/dist/types/src/{_deprecated → deprecated}/components/Cell/index.d.ts +0 -0
  148. /package/dist/types/src/{_deprecated → deprecated}/components/ColumnMenu/ColumnMenu.d.ts +0 -0
  149. /package/dist/types/src/{_deprecated → deprecated}/components/ColumnMenu/ColumnMenu.stories.d.ts +0 -0
  150. /package/dist/types/src/{_deprecated → deprecated}/components/ColumnMenu/ColumnSettings.d.ts +0 -0
  151. /package/dist/types/src/{_deprecated → deprecated}/components/ColumnMenu/ColumnSettings.stories.d.ts +0 -0
  152. /package/dist/types/src/{_deprecated → deprecated}/components/ColumnMenu/index.d.ts +0 -0
  153. /package/dist/types/src/{_deprecated → deprecated}/components/Table/Table.d.ts +0 -0
  154. /package/dist/types/src/{_deprecated → deprecated}/components/Table/Table.stories.d.ts +0 -0
  155. /package/dist/types/src/{_deprecated → deprecated}/components/Table/TableBody.d.ts +0 -0
  156. /package/dist/types/src/{_deprecated → deprecated}/components/Table/TableContext.d.ts +0 -0
  157. /package/dist/types/src/{_deprecated → deprecated}/components/Table/TableHead.d.ts +0 -0
  158. /package/dist/types/src/{_deprecated → deprecated}/components/Table/TableRootContext.d.ts +0 -0
  159. /package/dist/types/src/{_deprecated → deprecated}/components/Table/index.d.ts +0 -0
  160. /package/dist/types/src/{_deprecated → deprecated}/components/Table/props.d.ts +0 -0
  161. /package/dist/types/src/{_deprecated → deprecated}/components/index.d.ts +0 -0
  162. /package/dist/types/src/{_deprecated → deprecated}/helpers.d.ts +0 -0
  163. /package/dist/types/src/{_deprecated → deprecated}/hooks/index.d.ts +0 -0
  164. /package/dist/types/src/{_deprecated → deprecated}/hooks/useColumnSizing.d.ts +0 -0
  165. /package/dist/types/src/{_deprecated → deprecated}/hooks/useColumnSorting.d.ts +0 -0
  166. /package/dist/types/src/{_deprecated → deprecated}/hooks/usePinLastRow.d.ts +0 -0
  167. /package/dist/types/src/{_deprecated → deprecated}/hooks/useRowSelection.d.ts +0 -0
  168. /package/dist/types/src/{_deprecated → deprecated}/index.d.ts +0 -0
  169. /package/dist/types/src/{_deprecated → deprecated}/schema/Schema.stories.d.ts +0 -0
  170. /package/dist/types/src/{_deprecated → deprecated}/schema/column-utils.d.ts +0 -0
  171. /package/dist/types/src/{_deprecated → deprecated}/schema/index.d.ts +0 -0
  172. /package/dist/types/src/{_deprecated → deprecated}/schema/types.d.ts +0 -0
  173. /package/dist/types/src/{_deprecated → deprecated}/theme.d.ts +0 -0
  174. /package/dist/types/src/{_deprecated → deprecated}/translations.d.ts +0 -0
  175. /package/dist/types/src/{_deprecated → deprecated}/types.d.ts +0 -0
  176. /package/src/{_deprecated → deprecated}/components/Cell/CellCombobox.tsx +0 -0
  177. /package/src/{_deprecated → deprecated}/components/Cell/index.ts +0 -0
  178. /package/src/{_deprecated → deprecated}/components/ColumnMenu/ColumnMenu.stories.tsx +0 -0
  179. /package/src/{_deprecated → deprecated}/components/ColumnMenu/ColumnMenu.tsx +0 -0
  180. /package/src/{_deprecated → deprecated}/components/ColumnMenu/ColumnSettings.stories.tsx +0 -0
  181. /package/src/{_deprecated → deprecated}/components/ColumnMenu/ColumnSettings.tsx +0 -0
  182. /package/src/{_deprecated → deprecated}/components/ColumnMenu/index.ts +0 -0
  183. /package/src/{_deprecated → deprecated}/components/Table/Table.stories.tsx +0 -0
  184. /package/src/{_deprecated → deprecated}/components/Table/Table.tsx +0 -0
  185. /package/src/{_deprecated → deprecated}/components/Table/TableContext.tsx +0 -0
  186. /package/src/{_deprecated → deprecated}/components/Table/TableHead.tsx +0 -0
  187. /package/src/{_deprecated → deprecated}/components/Table/TableRootContext.ts +0 -0
  188. /package/src/{_deprecated → deprecated}/components/Table/index.ts +0 -0
  189. /package/src/{_deprecated → deprecated}/components/Table/props.ts +0 -0
  190. /package/src/{_deprecated → deprecated}/components/index.ts +0 -0
  191. /package/src/{_deprecated → deprecated}/hooks/index.ts +0 -0
  192. /package/src/{_deprecated → deprecated}/hooks/useColumnSizing.ts +0 -0
  193. /package/src/{_deprecated → deprecated}/hooks/useColumnSorting.ts +0 -0
  194. /package/src/{_deprecated → deprecated}/hooks/usePinLastRow.ts +0 -0
  195. /package/src/{_deprecated → deprecated}/hooks/useRowSelection.ts +0 -0
  196. /package/src/{_deprecated → deprecated}/index.ts +0 -0
  197. /package/src/{_deprecated → deprecated}/schema/Schema.stories.tsx +0 -0
  198. /package/src/{_deprecated → deprecated}/schema/column-utils.ts +0 -0
  199. /package/src/{_deprecated → deprecated}/schema/index.ts +0 -0
  200. /package/src/{_deprecated → deprecated}/schema/types.ts +0 -0
  201. /package/src/{_deprecated → deprecated}/theme.ts +0 -0
  202. /package/src/{_deprecated → deprecated}/translations.ts +0 -0
  203. /package/src/{_deprecated → deprecated}/types.ts +0 -0
@@ -2,7 +2,7 @@ import { createRequire } from 'node:module';const require = createRequire(import
2
2
  import {
3
3
  TableSchema,
4
4
  TableType
5
- } from "./chunk-RLVVOZW5.mjs";
5
+ } from "./chunk-SU4D55KI.mjs";
6
6
 
7
7
  // packages/ui/react-ui-table/src/translations.ts
8
8
  var translationKey = "table";
@@ -40,12 +40,12 @@ var translations_default = [
40
40
  import React7, { forwardRef, useCallback as useCallback4, useImperativeHandle, useState as useState2, useMemo as useMemo4 } from "react";
41
41
  import { getValue as getValue4 } from "@dxos/echo-schema";
42
42
  import { invariant as invariant3 } from "@dxos/invariant";
43
- import { Filter, getSpace as getSpace4, fullyQualifiedId } from "@dxos/react-client/echo";
43
+ import { Filter } from "@dxos/react-client/echo";
44
44
  import { useTranslation as useTranslation3 } from "@dxos/react-ui";
45
45
  import { useAttention } from "@dxos/react-ui-attention";
46
46
  import { Grid, closestCell } from "@dxos/react-ui-grid";
47
47
  import { mx as mx2 } from "@dxos/react-ui-theme";
48
- import { isNotFalsy } from "@dxos/util";
48
+ import { isNotFalsy, safeParseInt } from "@dxos/util";
49
49
 
50
50
  // packages/ui/react-ui-table/src/components/Table/ColumnActionsMenu.tsx
51
51
  import React from "react";
@@ -73,10 +73,10 @@ var ColumnActionsMenu = ({ model, modals }) => {
73
73
  }, t("column action sort ascending")), isCurrentColumnSorted && /* @__PURE__ */ React.createElement(DropdownMenu.Item, {
74
74
  "data-testid": "column-clear-sort",
75
75
  onClick: () => model.sorting?.clearSort()
76
- }, t("column action clear sorting")), model.getColumnCount() > 1 && /* @__PURE__ */ React.createElement(DropdownMenu.Item, {
76
+ }, t("column action clear sorting")), model.getColumnCount() > 1 && model.features.schemaEditable && /* @__PURE__ */ React.createElement(DropdownMenu.Item, {
77
77
  "data-testid": "column-delete",
78
78
  onClick: () => model.deleteColumn(state.fieldId)
79
- }, t("column action delete")), /* @__PURE__ */ React.createElement(DropdownMenu.Item, {
79
+ }, t("column action delete")), model.features.schemaEditable && /* @__PURE__ */ React.createElement(DropdownMenu.Item, {
80
80
  "data-testid": "column-settings",
81
81
  onClick: () => modals.openColumnSettings()
82
82
  }, t("column action settings"))), /* @__PURE__ */ React.createElement(DropdownMenu.Arrow, null))));
@@ -84,13 +84,12 @@ var ColumnActionsMenu = ({ model, modals }) => {
84
84
 
85
85
  // packages/ui/react-ui-table/src/components/Table/ColumnSettings.tsx
86
86
  import React2, { useCallback, useEffect, useMemo, useState } from "react";
87
- import { getSpace } from "@dxos/react-client/echo";
88
87
  import { DropdownMenu as DropdownMenu2 } from "@dxos/react-ui";
89
88
  import { FieldEditor } from "@dxos/react-ui-form";
90
89
  var ColumnSettings = ({ model, modals, onNewColumn }) => {
91
90
  const [newField, setNewField] = useState();
92
91
  const state = modals.state.value;
93
- const space = getSpace(model?.table);
92
+ const space = model?.space;
94
93
  useEffect(() => {
95
94
  if (state?.type === "columnSettings" && state.mode.type === "create" && model?.projection) {
96
95
  setNewField(model.projection.createFieldProjection());
@@ -108,12 +107,12 @@ var ColumnSettings = ({ model, modals, onNewColumn }) => {
108
107
  if (state?.type === "columnSettings") {
109
108
  const { mode } = state;
110
109
  if (mode.type === "edit") {
111
- return model?.table?.view?.target?.fields.find((f) => f.id === mode.fieldId);
110
+ return model?.view?.fields.find((f) => f.id === mode.fieldId);
112
111
  }
113
112
  }
114
113
  return void 0;
115
114
  }, [
116
- model?.table?.view?.target?.fields,
115
+ model?.view?.fields,
117
116
  state
118
117
  ]);
119
118
  const field = existingField ?? newField;
@@ -131,7 +130,7 @@ var ColumnSettings = ({ model, modals, onNewColumn }) => {
131
130
  state,
132
131
  newField
133
132
  ]);
134
- if (!model?.table?.view?.target || !model.projection || !field) {
133
+ if (!model?.view || !model.projection || !field) {
135
134
  return null;
136
135
  }
137
136
  return /* @__PURE__ */ React2.createElement(DropdownMenu2.Root, {
@@ -142,7 +141,7 @@ var ColumnSettings = ({ model, modals, onNewColumn }) => {
142
141
  }), /* @__PURE__ */ React2.createElement(DropdownMenu2.Portal, null, /* @__PURE__ */ React2.createElement(DropdownMenu2.Content, {
143
142
  classNames: "md:is-64"
144
143
  }, /* @__PURE__ */ React2.createElement(DropdownMenu2.Viewport, null, /* @__PURE__ */ React2.createElement(FieldEditor, {
145
- view: model.table.view.target,
144
+ view: model.view,
146
145
  projection: model.projection,
147
146
  field,
148
147
  registry: space?.db.schemaRegistry,
@@ -154,13 +153,13 @@ var ColumnSettings = ({ model, modals, onNewColumn }) => {
154
153
  // packages/ui/react-ui-table/src/components/Table/CreateRefPanel.tsx
155
154
  import React3, { useCallback as useCallback2, useMemo as useMemo2 } from "react";
156
155
  import { S } from "@dxos/echo-schema";
157
- import { create, getSpace as getSpace2 } from "@dxos/react-client/echo";
156
+ import { create } from "@dxos/react-client/echo";
158
157
  import { Popover } from "@dxos/react-ui";
159
158
  import { Form } from "@dxos/react-ui-form";
160
159
  import { useGridContext } from "@dxos/react-ui-grid";
161
160
  var CreateRefPanel = ({ model, modals, __gridScope }) => {
162
161
  const { id: gridId } = useGridContext("TableCellEditor", __gridScope);
163
- const space = getSpace2(model?.table);
162
+ const space = model?.space;
164
163
  const state = modals.state.value;
165
164
  const schema = useMemo2(() => {
166
165
  if (!space || state?.type !== "createRefPanel") {
@@ -201,7 +200,7 @@ var CreateRefPanel = ({ model, modals, __gridScope }) => {
201
200
  }, [
202
201
  modals
203
202
  ]);
204
- if (!model?.table?.view || !model.projection) {
203
+ if (!model?.view || !model.projection) {
205
204
  return null;
206
205
  }
207
206
  return /* @__PURE__ */ React3.createElement(Popover.Root, {
@@ -227,7 +226,6 @@ var CreateRefPanel = ({ model, modals, __gridScope }) => {
227
226
 
228
227
  // packages/ui/react-ui-table/src/components/Table/RefPanel.tsx
229
228
  import React4 from "react";
230
- import { getSpace as getSpace3 } from "@dxos/react-client/echo";
231
229
  import { Popover as Popover2 } from "@dxos/react-ui";
232
230
  import { Form as Form2 } from "@dxos/react-ui-form";
233
231
  var getRefTargetObj = (space, id) => {
@@ -239,10 +237,10 @@ var getRefTargetObj = (space, id) => {
239
237
  };
240
238
  var RefPanel = ({ model, modals }) => {
241
239
  const state = modals.state.value;
242
- const space = getSpace3(model.table);
240
+ const space = model?.space;
243
241
  const targetObj = getRefTargetObj(space, state?.type === "refPanel" ? state.targetId : void 0);
244
242
  const schema = space && state?.type === "refPanel" ? space.db.schemaRegistry.getSchema(state.typename) : void 0;
245
- if (!model.table?.view || !model.projection) {
243
+ if (!model.view || !model.projection) {
246
244
  return null;
247
245
  }
248
246
  return /* @__PURE__ */ React4.createElement(Popover2.Root, {
@@ -280,10 +278,17 @@ var RowActionsMenu = ({ model, modals }) => {
280
278
  onOpenChange: modals.close
281
279
  }, /* @__PURE__ */ React5.createElement(DropdownMenu3.VirtualTrigger, {
282
280
  virtualRef: modals.trigger
283
- }), /* @__PURE__ */ React5.createElement(DropdownMenu3.Content, null, /* @__PURE__ */ React5.createElement(DropdownMenu3.Viewport, null, /* @__PURE__ */ React5.createElement(DropdownMenu3.Item, {
281
+ }), /* @__PURE__ */ React5.createElement(DropdownMenu3.Content, null, /* @__PURE__ */ React5.createElement(DropdownMenu3.Viewport, null, model.features.dataEditable !== false && /* @__PURE__ */ React5.createElement(DropdownMenu3.Item, {
284
282
  "data-testid": "row-menu-delete",
285
283
  onClick: () => model.deleteRow(state.rowIndex)
286
- }, t(hasSelection ? "bulk delete row label" : "delete row label"))), /* @__PURE__ */ React5.createElement(DropdownMenu3.Arrow, null)));
284
+ }, t(hasSelection ? "bulk delete row label" : "delete row label")), model.rowActions?.map((action) => /* @__PURE__ */ React5.createElement(DropdownMenu3.Item, {
285
+ key: action.id,
286
+ "data-testid": `row-action-${action.id}`,
287
+ onClick: () => {
288
+ modals.close();
289
+ model.handleRowAction(action.id, state.rowIndex);
290
+ }
291
+ }, t(action.translationKey)))), /* @__PURE__ */ React5.createElement(DropdownMenu3.Arrow, null)));
287
292
  };
288
293
 
289
294
  // packages/ui/react-ui-table/src/model/table-model.ts
@@ -291,32 +296,84 @@ import { computed as computed3, effect as effect2, signal as signal3 } from "@pr
291
296
  import { Resource as Resource2 } from "@dxos/context";
292
297
  import { FormatEnum as FormatEnum3, getValue as getValue2, setValue } from "@dxos/echo-schema";
293
298
  import { invariant } from "@dxos/invariant";
294
- import { isReactiveObject, makeRef as makeRef2 } from "@dxos/live-object";
295
- import { PublicKey as PublicKey2 } from "@dxos/react-client";
299
+ import { isReactiveObject, makeRef as makeRef3 } from "@dxos/live-object";
296
300
  import { formatForEditing, parseValue } from "@dxos/react-ui-form";
297
301
 
298
302
  // packages/ui/react-ui-table/src/model/selection-model.ts
299
303
  import { computed, effect, signal } from "@preact/signals-core";
300
304
  import { Resource } from "@dxos/context";
301
305
 
306
+ // packages/ui/react-ui-table/src/util/dynamic-table.ts
307
+ import { create as create2, makeRef } from "@dxos/live-object";
308
+ import { createView, echoSchemaFromPropertyDefinitions, ViewProjection } from "@dxos/schema";
309
+ var makeDynamicTable = (typename, properties) => {
310
+ const table = create2(TableType, {
311
+ name: "dynamic-table"
312
+ });
313
+ const echoSchema = echoSchemaFromPropertyDefinitions(typename, properties);
314
+ const propertyNames = properties.map((property) => property.name);
315
+ const view = createView({
316
+ name: "dynamic-table",
317
+ typename: echoSchema.typename,
318
+ jsonSchema: echoSchema.jsonSchema,
319
+ fields: propertyNames
320
+ });
321
+ table.view = makeRef(view);
322
+ const viewProjection = new ViewProjection(echoSchema, view);
323
+ for (const property of properties) {
324
+ if (!view.fields) {
325
+ continue;
326
+ }
327
+ const field = view.fields.find((field2) => field2.path === property.name);
328
+ if (field) {
329
+ if (property.size !== void 0) {
330
+ field.size = property.size;
331
+ }
332
+ if (property.title !== void 0) {
333
+ const fieldProjection = viewProjection.getFieldProjection(field.id);
334
+ viewProjection.setFieldProjection({
335
+ ...fieldProjection,
336
+ props: {
337
+ ...fieldProjection.props,
338
+ title: property.title
339
+ }
340
+ });
341
+ }
342
+ if (property.sort) {
343
+ const fieldId = field.id;
344
+ view.query.sort = [
345
+ {
346
+ fieldId,
347
+ direction: property.sort
348
+ }
349
+ ];
350
+ }
351
+ }
352
+ }
353
+ return {
354
+ table,
355
+ schema: echoSchema,
356
+ view,
357
+ viewProjection
358
+ };
359
+ };
360
+
302
361
  // packages/ui/react-ui-table/src/util/signals.ts
303
362
  var touch = (value) => value;
304
363
 
305
364
  // packages/ui/react-ui-table/src/util/table.ts
306
365
  import { AST, Format, FormatEnum, S as S2, TypedObject, TypeEnum } from "@dxos/echo-schema";
307
366
  import { PublicKey } from "@dxos/react-client";
308
- import { create as create2, makeRef } from "@dxos/react-client/echo";
309
- import { createFieldId, createView, getSchemaProperties, ViewProjection } from "@dxos/schema";
310
- var initializeTable = async ({ space, table, initialRow = true, initialSchema }) => {
311
- if (initialSchema) {
312
- const schema = await space.db.schemaRegistry.query({
313
- typename: initialSchema
314
- }).firstOrUndefined();
367
+ import { create as create3, makeRef as makeRef2 } from "@dxos/react-client/echo";
368
+ import { createFieldId, createView as createView2, getSchemaProperties, ViewProjection as ViewProjection2 } from "@dxos/schema";
369
+ var initializeTable = async ({ client, space, table, typename, initialRow = true }) => {
370
+ if (typename) {
371
+ const schema = await space.db.graph.getSchemaByTypename(typename, space.db);
315
372
  if (!schema) {
316
- throw new Error(`Schema not found: ${initialSchema}`);
373
+ throw new Error(`Schema not found: ${typename}`);
317
374
  }
318
375
  const fields = getSchemaProperties(schema.ast).filter((prop) => prop.format !== FormatEnum.Ref).map((prop) => prop.name);
319
- table.view = makeRef(createView({
376
+ table.view = makeRef2(createView2({
320
377
  // TODO(ZaymonFC): Don't hardcode name?
321
378
  name: "View",
322
379
  typename: schema.typename,
@@ -325,68 +382,74 @@ var initializeTable = async ({ space, table, initialRow = true, initialSchema })
325
382
  }));
326
383
  return schema;
327
384
  } else {
328
- const ContactSchema = TypedObject({
329
- typename: `example.com/type/${PublicKey.random().truncate()}`,
330
- version: "0.1.0"
331
- })({
332
- name: S2.optional(S2.String).annotations({
333
- [AST.TitleAnnotationId]: "Name"
334
- }),
335
- active: S2.optional(S2.Boolean),
336
- email: S2.optional(Format.Email),
337
- salary: S2.optional(Format.Currency()).annotations({
338
- [AST.TitleAnnotationId]: "Salary"
339
- })
340
- });
341
- const [contactSchema] = await space.db.schemaRegistry.register([
385
+ const [schema] = await space.db.schemaRegistry.register([
342
386
  ContactSchema
343
387
  ]);
344
- table.view = makeRef(createView({
388
+ const fields = ContactFields;
389
+ table.view = makeRef2(createView2({
345
390
  name: "View",
346
- typename: contactSchema.typename,
347
- jsonSchema: contactSchema.jsonSchema,
348
- fields: [
349
- "name",
350
- "email",
351
- "salary",
352
- "active"
353
- ]
391
+ typename: schema.typename,
392
+ jsonSchema: schema.jsonSchema,
393
+ fields
354
394
  }));
355
- const projection = new ViewProjection(contactSchema, table.view.target);
356
- projection.setFieldProjection({
357
- field: {
358
- id: table.view.target.fields.find((f) => f.path === "salary").id,
359
- path: "salary",
360
- size: 150
361
- }
362
- });
363
- projection.setFieldProjection({
364
- field: {
365
- id: table.view.target.fields.find((f) => f.path === "active").id,
366
- path: "active",
367
- size: 100
368
- }
369
- });
370
- projection.setFieldProjection({
371
- field: {
372
- id: createFieldId(),
373
- path: "manager",
374
- referencePath: "name"
375
- },
376
- props: {
377
- property: "manager",
378
- type: TypeEnum.Ref,
379
- format: FormatEnum.Ref,
380
- referenceSchema: contactSchema.typename,
381
- title: "Manager"
382
- }
383
- });
395
+ createProjection(schema, table.view.target);
384
396
  if (initialRow) {
385
- space.db.add(create2(contactSchema, {}));
397
+ space.db.add(create3(schema, {}));
386
398
  }
387
- return contactSchema;
399
+ return schema;
388
400
  }
389
401
  };
402
+ var ContactSchema = TypedObject({
403
+ typename: `example.com/type/${PublicKey.random().truncate()}`,
404
+ version: "0.1.0"
405
+ })({
406
+ name: S2.optional(S2.String).annotations({
407
+ [AST.TitleAnnotationId]: "Name"
408
+ }),
409
+ active: S2.optional(S2.Boolean),
410
+ email: S2.optional(Format.Email),
411
+ salary: S2.optional(Format.Currency()).annotations({
412
+ [AST.TitleAnnotationId]: "Salary"
413
+ })
414
+ });
415
+ var ContactFields = [
416
+ "name",
417
+ "email",
418
+ "salary",
419
+ "active"
420
+ ];
421
+ var createProjection = (schema, view) => {
422
+ const projection = new ViewProjection2(schema, view);
423
+ projection.setFieldProjection({
424
+ field: {
425
+ id: view.fields.find((f) => f.path === "salary").id,
426
+ path: "salary",
427
+ size: 150
428
+ }
429
+ });
430
+ projection.setFieldProjection({
431
+ field: {
432
+ id: view.fields.find((f) => f.path === "active").id,
433
+ path: "active",
434
+ size: 100
435
+ }
436
+ });
437
+ projection.setFieldProjection({
438
+ field: {
439
+ id: createFieldId(),
440
+ path: "manager",
441
+ referencePath: "name"
442
+ },
443
+ props: {
444
+ property: "manager",
445
+ type: TypeEnum.Ref,
446
+ format: FormatEnum.Ref,
447
+ referenceSchema: schema.typename,
448
+ title: "Manager"
449
+ }
450
+ });
451
+ return projection;
452
+ };
390
453
 
391
454
  // packages/ui/react-ui-table/src/util/table-buttons.ts
392
455
  var BUTTON_IDENTIFIERS = {
@@ -805,13 +868,17 @@ var TableSorting = class {
805
868
 
806
869
  // packages/ui/react-ui-table/src/model/table-model.ts
807
870
  var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-table/src/model/table-model.ts";
871
+ var defaultFeatures = {
872
+ selection: true,
873
+ dataEditable: false,
874
+ schemaEditable: false
875
+ };
808
876
  var TableModel = class extends Resource2 {
809
- constructor({ table, projection, sorting = [], pinnedRows = {
877
+ constructor({ id, space, view, projection, features = {}, sorting = [], pinnedRows = {
810
878
  top: [],
811
879
  bottom: []
812
- }, onCellUpdate, onDeleteColumn, onDeleteRows, onInsertRow, onRowOrderChanged }) {
880
+ }, onCellUpdate, onDeleteColumn, onDeleteRows, onInsertRow, onRowOrderChanged, rowActions = [], onRowAction }) {
813
881
  super();
814
- this.id = `table-model-${PublicKey2.random().truncate()}`;
815
882
  this._visibleRange = signal3({
816
883
  start: {
817
884
  row: 0,
@@ -830,7 +897,7 @@ var TableModel = class extends Resource2 {
830
897
  this._rows.value = obj;
831
898
  };
832
899
  this.getRowCount = () => this._rows.value.length;
833
- this.getColumnCount = () => this.table.view?.target?.fields.length ?? 0;
900
+ this.getColumnCount = () => this._view?.fields.length ?? 0;
834
901
  this.insertRow = (rowIndex) => {
835
902
  const row = rowIndex !== void 0 ? this._sorting.getDataIndex(rowIndex) : this._rows.value.length;
836
903
  this._onInsertRow?.(row);
@@ -847,8 +914,18 @@ var TableModel = class extends Resource2 {
847
914
  }
848
915
  this._onDeleteRows?.(row, objectsToDelete);
849
916
  };
917
+ this.handleRowAction = (actionId, rowIndex) => {
918
+ if (!this._onRowAction) {
919
+ return;
920
+ }
921
+ const row = this._sorting.getDataIndex(rowIndex);
922
+ const data = this._rows.value[row];
923
+ if (data) {
924
+ this._onRowAction(actionId, data);
925
+ }
926
+ };
850
927
  this.getCellData = ({ col, row }) => {
851
- const fields = this.table.view?.target?.fields ?? [];
928
+ const fields = this._view?.fields ?? [];
852
929
  if (col < 0 || col >= fields.length) {
853
930
  return void 0;
854
931
  }
@@ -877,7 +954,7 @@ var TableModel = class extends Resource2 {
877
954
  };
878
955
  this.setCellData = ({ col, row }, value) => {
879
956
  const rowIdx = this._sorting.getDataIndex(row);
880
- const fields = this.table.view?.target?.fields ?? [];
957
+ const fields = this._view?.fields ?? [];
881
958
  if (col < 0 || col >= fields.length) {
882
959
  return;
883
960
  }
@@ -886,7 +963,7 @@ var TableModel = class extends Resource2 {
886
963
  switch (props.format) {
887
964
  case FormatEnum3.Ref: {
888
965
  if (isReactiveObject(value)) {
889
- setValue(this._rows.value[rowIdx], field.path, makeRef2(value));
966
+ setValue(this._rows.value[rowIdx], field.path, makeRef3(value));
890
967
  }
891
968
  break;
892
969
  }
@@ -900,9 +977,15 @@ var TableModel = class extends Resource2 {
900
977
  }
901
978
  }
902
979
  };
903
- this._table = table;
980
+ this._id = id;
981
+ this._space = space;
982
+ this._view = view;
904
983
  this._projection = projection;
905
- this._sorting = new TableSorting(this._rows, table.view?.target, projection);
984
+ this._features = {
985
+ ...defaultFeatures,
986
+ ...features
987
+ };
988
+ this._sorting = new TableSorting(this._rows, this._view, projection);
906
989
  if (sorting.length > 0) {
907
990
  const [sort] = sorting;
908
991
  this._sorting.setSort(sort.fieldId, sort.direction);
@@ -913,9 +996,17 @@ var TableModel = class extends Resource2 {
913
996
  this._onDeleteColumn = onDeleteColumn;
914
997
  this._onCellUpdate = onCellUpdate;
915
998
  this._onRowOrderChanged = onRowOrderChanged;
999
+ this._rowActions = rowActions;
1000
+ this._onRowAction = onRowAction;
1001
+ }
1002
+ get id() {
1003
+ return this._id;
916
1004
  }
917
- get table() {
918
- return this._table;
1005
+ get space() {
1006
+ return this._space;
1007
+ }
1008
+ get view() {
1009
+ return this._view;
919
1010
  }
920
1011
  get projection() {
921
1012
  return this._projection;
@@ -923,19 +1014,31 @@ var TableModel = class extends Resource2 {
923
1014
  get rows() {
924
1015
  return this._sorting.sortedRows;
925
1016
  }
1017
+ get features() {
1018
+ return this._features;
1019
+ }
926
1020
  /**
927
1021
  * @reactive
928
1022
  */
929
1023
  get sorting() {
930
1024
  return this._sorting;
931
1025
  }
1026
+ /**
1027
+ * Gets the row data at the specified display index.
1028
+ */
1029
+ getRowAt(displayIndex) {
1030
+ if (displayIndex < 0 || displayIndex >= this._sorting.sortedRows.value.length) {
1031
+ return void 0;
1032
+ }
1033
+ return this._sorting.sortedRows.value[displayIndex];
1034
+ }
932
1035
  get pinnedRows() {
933
1036
  return this._pinnedRows;
934
1037
  }
935
1038
  get columnMeta() {
936
1039
  invariant(this._columnMeta, void 0, {
937
1040
  F: __dxlog_file,
938
- L: 117,
1041
+ L: 176,
939
1042
  S: this,
940
1043
  A: [
941
1044
  "this._columnMeta",
@@ -951,6 +1054,9 @@ var TableModel = class extends Resource2 {
951
1054
  get isViewDirty() {
952
1055
  return this._sorting.isDirty;
953
1056
  }
1057
+ get rowActions() {
1058
+ return this._rowActions;
1059
+ }
954
1060
  //
955
1061
  // Initialisation
956
1062
  //
@@ -962,7 +1068,7 @@ var TableModel = class extends Resource2 {
962
1068
  }
963
1069
  initializeColumnMeta() {
964
1070
  this._columnMeta = computed3(() => {
965
- const fields = this._table.view?.target?.fields ?? [];
1071
+ const fields = this._view?.fields ?? [];
966
1072
  const meta = Object.fromEntries(fields.map((field, index) => [
967
1073
  index,
968
1074
  {
@@ -999,7 +1105,7 @@ var TableModel = class extends Resource2 {
999
1105
  for (let row = start.row; row <= end.row; row++) {
1000
1106
  rowEffects.push(effect2(() => {
1001
1107
  const obj = this._sorting.sortedRows.value[row];
1002
- this?._table?.view?.target?.fields.forEach((field) => touch(getValue2(obj, field.path)));
1108
+ this._view?.fields.forEach((field) => touch(getValue2(obj, field.path)));
1003
1109
  this._onCellUpdate?.({
1004
1110
  row,
1005
1111
  col: start.col,
@@ -1018,7 +1124,7 @@ var TableModel = class extends Resource2 {
1018
1124
  */
1019
1125
  updateCellData({ col, row }, update) {
1020
1126
  const dataRow = this._sorting.getDataIndex(row);
1021
- const fields = this.table.view?.target?.fields ?? [];
1127
+ const fields = this._view?.fields ?? [];
1022
1128
  const field = fields[col];
1023
1129
  const value = getValue2(this._rows.value[dataRow], field.path);
1024
1130
  const updatedValue = update(value);
@@ -1028,10 +1134,10 @@ var TableModel = class extends Resource2 {
1028
1134
  // Column Operations
1029
1135
  //
1030
1136
  deleteColumn(fieldId) {
1031
- if (!this.table.view) {
1137
+ if (!this._view) {
1032
1138
  return;
1033
1139
  }
1034
- const field = this.table.view.target?.fields.find((field2) => field2.id === fieldId);
1140
+ const field = this._view?.fields.find((field2) => field2.id === fieldId);
1035
1141
  if (field && this._onDeleteColumn) {
1036
1142
  this._onDeleteColumn(field.id);
1037
1143
  }
@@ -1040,7 +1146,7 @@ var TableModel = class extends Resource2 {
1040
1146
  // Resize
1041
1147
  //
1042
1148
  setColumnWidth(columnIndex, width) {
1043
- const fields = this.table.view?.target?.fields ?? [];
1149
+ const fields = this._view?.fields ?? [];
1044
1150
  if (columnIndex < fields.length) {
1045
1151
  const newWidth = Math.max(0, width);
1046
1152
  const field = fields[columnIndex];
@@ -1178,27 +1284,40 @@ var TablePresentation = class {
1178
1284
  this._visibleRange = _visibleRange;
1179
1285
  }
1180
1286
  getCells(range, plane) {
1287
+ let cells;
1181
1288
  switch (plane) {
1182
1289
  case "grid":
1183
1290
  this._visibleRange.value = range;
1184
- return this.getMainGridCells(range);
1291
+ cells = this.getMainGridCells(range);
1292
+ break;
1185
1293
  case "frozenRowsStart":
1186
- return this.getHeaderCells(range);
1294
+ cells = this.getHeaderCells(range);
1295
+ break;
1187
1296
  case "frozenColsStart":
1188
- return this.getSelectionColumnCells(range);
1297
+ cells = this.getSelectionColumnCells(range);
1298
+ break;
1189
1299
  case "frozenColsEnd":
1190
- return this.getActionColumnCells(range);
1300
+ cells = this.getActionColumnCells(range);
1301
+ break;
1191
1302
  case "fixedStartStart":
1192
- return this.getSelectAllCell();
1303
+ cells = this.getSelectAllCell();
1304
+ break;
1193
1305
  case "fixedStartEnd":
1194
- return this.getNewColumnCell();
1306
+ cells = this.getNewColumnCell();
1307
+ break;
1195
1308
  default:
1196
- return {};
1309
+ cells = {};
1310
+ }
1311
+ if (plane === "grid" && this.model.features.dataEditable === false) {
1312
+ Object.values(cells).forEach((cell) => {
1313
+ cell.readonly = true;
1314
+ });
1197
1315
  }
1316
+ return cells;
1198
1317
  }
1199
1318
  getMainGridCells(range) {
1200
1319
  const cells = {};
1201
- const fields = this.model.table.view?.target?.fields ?? [];
1320
+ const fields = this.model.view?.fields ?? [];
1202
1321
  const addCell = (obj, field, colIndex, displayIndex) => {
1203
1322
  const { props } = this.model.projection.getFieldProjection(field.id);
1204
1323
  const cell = {
@@ -1290,7 +1409,7 @@ var TablePresentation = class {
1290
1409
  }
1291
1410
  getHeaderCells(range) {
1292
1411
  const cells = {};
1293
- const fields = this.model.table.view?.target?.fields ?? [];
1412
+ const fields = this.model.view?.fields ?? [];
1294
1413
  for (let col = range.start.col; col <= range.end.col && col < fields.length; col++) {
1295
1414
  const { field, props } = this.model.projection.getFieldProjection(fields[col].id);
1296
1415
  const sorting = this.model.sorting?.sorting;
@@ -1379,9 +1498,9 @@ var TablePresentation = class {
1379
1498
  col: 0,
1380
1499
  row: 0
1381
1500
  })]: {
1382
- accessoryHtml: tableButtons.addColumn.render({
1383
- disabled: (this.model.table.view?.target?.fields?.length ?? 0) >= VIEW_FIELD_LIMIT
1384
- }),
1501
+ accessoryHtml: this.model.features.schemaEditable ? tableButtons.addColumn.render({
1502
+ disabled: (this.model.view?.fields?.length ?? 0) >= VIEW_FIELD_LIMIT
1503
+ }) : void 0,
1385
1504
  className: "!bg-gridHeader",
1386
1505
  readonly: true,
1387
1506
  value: ""
@@ -1607,22 +1726,24 @@ var determineNavigationDelta = ({ key, shift }) => {
1607
1726
  var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-table/src/components/Table/Table.tsx";
1608
1727
  var inlineEndLine = "[&>.dx-grid]:relative [&>.dx-grid]:after:absolute [&>.dx-grid]:after:inset-block-0 [&>.dx-grid]:after:-inline-end-px [&>.dx-grid]:after:is-px [&>.dx-grid]:after:bg-separator";
1609
1728
  var blockEndLine = "[&>.dx-grid]:before:absolute [&>.dx-grid]:before:inset-inline-0 [&>.dx-grid]:before:-block-end-px [&>.dx-grid]:before:bs-px [&>.dx-grid]:before:bg-separator";
1610
- var frozen = {
1611
- frozenRowsStart: 1,
1612
- frozenColsStart: 1,
1613
- frozenColsEnd: 1
1614
- };
1615
1729
  var TableRoot = ({ children, role }) => {
1616
1730
  return /* @__PURE__ */ React7.createElement("div", {
1617
1731
  role: "none",
1618
1732
  className: mx2("relative border-bs !border-separator", role === "section" ? "attention-surface overflow-hidden [&_.dx-grid]:max-is-[--dx-grid-content-inline-size]" : "flex flex-col [&_.dx-grid]:grow [&_.dx-grid]:max-is-[--dx-grid-content-inline-size] [&_.dx-grid]:bs-0 [&_.dx-grid]:max-bs-[--dx-grid-content-block-size]")
1619
1733
  }, children);
1620
1734
  };
1621
- var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttention }, forwardedRef) => {
1735
+ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttention, onRowClicked }, forwardedRef) => {
1622
1736
  const [dxGrid, setDxGrid] = useState2(null);
1623
- const { hasAttention } = useAttention(model?.table ? fullyQualifiedId(model.table) : "table");
1737
+ const { hasAttention } = useAttention(model?.id ?? "table");
1624
1738
  const { t } = useTranslation3(translationKey);
1625
1739
  const modals = useMemo4(() => new ModalController(), []);
1740
+ const frozen = useMemo4(() => ({
1741
+ frozenRowsStart: 1,
1742
+ frozenColsStart: model?.features.selection ? 1 : 0,
1743
+ frozenColsEnd: 1
1744
+ }), [
1745
+ model
1746
+ ]);
1626
1747
  useImperativeHandle(forwardedRef, () => {
1627
1748
  if (!presentation || !dxGrid) {
1628
1749
  return {};
@@ -1643,6 +1764,13 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
1643
1764
  dxGrid
1644
1765
  ]);
1645
1766
  const handleGridClick = useCallback4((event) => {
1767
+ if (onRowClicked) {
1768
+ const rowIndex = safeParseInt(event.target.ariaRowIndex ?? "");
1769
+ if (rowIndex != null) {
1770
+ const row = model?.getRowAt(rowIndex);
1771
+ row && onRowClicked(row);
1772
+ }
1773
+ }
1646
1774
  if (!modals) {
1647
1775
  return;
1648
1776
  }
@@ -1719,6 +1847,9 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
1719
1847
  dxGrid
1720
1848
  ]);
1721
1849
  const handleEnter = useCallback4((cell) => {
1850
+ if (!model?.features.dataEditable) {
1851
+ return;
1852
+ }
1722
1853
  if (model && cell.row === model.getRowCount() - 1) {
1723
1854
  model.insertRow(cell.row);
1724
1855
  if (dxGrid) {
@@ -1733,6 +1864,9 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
1733
1864
  dxGrid
1734
1865
  ]);
1735
1866
  const handleKeyDown = useCallback4((event) => {
1867
+ if (!model?.features.dataEditable) {
1868
+ return;
1869
+ }
1736
1870
  const cell = closestCell(event.target);
1737
1871
  if (!model || !cell) {
1738
1872
  return;
@@ -1774,10 +1908,10 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
1774
1908
  ]);
1775
1909
  const handleQuery = useCallback4(async ({ field, props }, text) => {
1776
1910
  if (model && props.referenceSchema && field.referencePath) {
1777
- const space = getSpace4(model.table);
1911
+ const space = model.space;
1778
1912
  invariant3(space, void 0, {
1779
1913
  F: __dxlog_file4,
1780
- L: 264,
1914
+ L: 284,
1781
1915
  S: void 0,
1782
1916
  A: [
1783
1917
  "space",
@@ -1810,7 +1944,8 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
1810
1944
  }
1811
1945
  return [];
1812
1946
  }, [
1813
- model
1947
+ model,
1948
+ t
1814
1949
  ]);
1815
1950
  if (!model || !modals) {
1816
1951
  return /* @__PURE__ */ React7.createElement("span", {
@@ -1819,7 +1954,7 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
1819
1954
  });
1820
1955
  }
1821
1956
  return /* @__PURE__ */ React7.createElement(Grid.Root, {
1822
- id: model.table.id ?? "table-grid"
1957
+ id: model.id ?? "table-grid"
1823
1958
  }, /* @__PURE__ */ React7.createElement(TableCellEditor, {
1824
1959
  model,
1825
1960
  modals,
@@ -1832,7 +1967,7 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
1832
1967
  frozen,
1833
1968
  columns: model.columnMeta.value,
1834
1969
  limitRows: model.getRowCount() ?? 0,
1835
- limitColumns: model.table.view?.target?.fields?.length ?? 0,
1970
+ limitColumns: model.view?.fields?.length ?? 0,
1836
1971
  onAxisResize: handleAxisResize,
1837
1972
  onClick: handleGridClick,
1838
1973
  onKeyDown: handleKeyDown,
@@ -1861,9 +1996,134 @@ var Table = {
1861
1996
  Main: TableMain
1862
1997
  };
1863
1998
 
1999
+ // packages/ui/react-ui-table/src/components/Table/DynamicTable.tsx
2000
+ import React8, { useRef as useRef2, useMemo as useMemo5, useCallback as useCallback5 } from "react";
2001
+ import { mx as mx3 } from "@dxos/react-ui-theme";
2002
+
2003
+ // packages/ui/react-ui-table/src/hooks/useTableModel.ts
2004
+ import { effect as effect3 } from "@preact/signals-core";
2005
+ import { useEffect as useEffect2, useState as useState3 } from "react";
2006
+ import { fullyQualifiedId, getSpace } from "@dxos/react-client/echo";
2007
+ import { useSelectionActions } from "@dxos/react-ui-attention";
2008
+ import { isNonNullable } from "@dxos/util";
2009
+ var useTableModel = ({ objects, table, projection, features, onSelectionChanged, rowActions, onRowAction, ...props }) => {
2010
+ const [model, setModel] = useState3();
2011
+ useEffect2(() => {
2012
+ if (!table || !projection) {
2013
+ return;
2014
+ }
2015
+ let model2;
2016
+ const t = setTimeout(async () => {
2017
+ model2 = new TableModel({
2018
+ id: fullyQualifiedId(table),
2019
+ space: getSpace(table),
2020
+ view: table.view?.target,
2021
+ projection,
2022
+ features,
2023
+ rowActions,
2024
+ onRowAction,
2025
+ ...props
2026
+ });
2027
+ await model2.open();
2028
+ setModel(model2);
2029
+ });
2030
+ return () => {
2031
+ clearTimeout(t);
2032
+ void model2?.close();
2033
+ };
2034
+ }, [
2035
+ table,
2036
+ projection,
2037
+ table?.view?.target,
2038
+ features,
2039
+ rowActions
2040
+ ]);
2041
+ useEffect2(() => {
2042
+ if (objects) {
2043
+ model?.setRows(objects);
2044
+ }
2045
+ }, [
2046
+ model,
2047
+ objects
2048
+ ]);
2049
+ const { select, clear } = useSelectionActions([
2050
+ table?.id,
2051
+ table?.view?.target?.query.typename
2052
+ ].filter(isNonNullable));
2053
+ useEffect2(() => {
2054
+ if (!model) {
2055
+ return;
2056
+ }
2057
+ const unsubscribe = effect3(() => {
2058
+ const selectedItems = [
2059
+ ...model.selection.selection.value
2060
+ ];
2061
+ select(selectedItems);
2062
+ onSelectionChanged?.(selectedItems);
2063
+ });
2064
+ return () => {
2065
+ clear();
2066
+ unsubscribe();
2067
+ };
2068
+ }, [
2069
+ model,
2070
+ onSelectionChanged
2071
+ ]);
2072
+ return model;
2073
+ };
2074
+
2075
+ // packages/ui/react-ui-table/src/components/Table/DynamicTable.tsx
2076
+ var DynamicTable = ({ data, properties, classNames, tableName = "com.example/dynamic_table", onRowClicked, rowActions, onRowAction }) => {
2077
+ const { table, viewProjection } = useMemo5(() => {
2078
+ return makeDynamicTable(tableName, properties);
2079
+ }, [
2080
+ tableName,
2081
+ properties
2082
+ ]);
2083
+ const tableRef = useRef2(null);
2084
+ const handleCellUpdate = useCallback5((cell) => {
2085
+ tableRef.current?.update?.(cell);
2086
+ }, []);
2087
+ const handleRowOrderChanged = useCallback5(() => {
2088
+ tableRef.current?.update?.();
2089
+ }, []);
2090
+ const features = useMemo5(() => ({
2091
+ selection: false,
2092
+ dataEditable: false
2093
+ }), []);
2094
+ const model = useTableModel({
2095
+ table,
2096
+ objects: data,
2097
+ projection: viewProjection,
2098
+ features,
2099
+ onCellUpdate: handleCellUpdate,
2100
+ onRowOrderChanged: handleRowOrderChanged,
2101
+ rowActions,
2102
+ onRowAction
2103
+ });
2104
+ const presentation = useMemo5(() => {
2105
+ if (model) {
2106
+ return new TablePresentation(model);
2107
+ }
2108
+ }, [
2109
+ model
2110
+ ]);
2111
+ return /* @__PURE__ */ React8.createElement("div", {
2112
+ className: mx3("is-full bs-full grow grid", classNames)
2113
+ }, /* @__PURE__ */ React8.createElement("div", {
2114
+ className: "grid min-bs-0 overflow-hidden"
2115
+ }, /* @__PURE__ */ React8.createElement(Table.Root, null, /* @__PURE__ */ React8.createElement(Table.Main, {
2116
+ ref: tableRef,
2117
+ model,
2118
+ presentation,
2119
+ onRowClicked,
2120
+ ignoreAttention: true
2121
+ }))));
2122
+ };
2123
+
1864
2124
  // packages/ui/react-ui-table/src/components/TableToolbar/TableToolbar.tsx
1865
- import React8, { useCallback as useCallback5, useMemo as useMemo5 } from "react";
1866
- import { create as create3 } from "@dxos/live-object";
2125
+ import React9, { useCallback as useCallback6, useMemo as useMemo6 } from "react";
2126
+ import { create as create4 } from "@dxos/live-object";
1867
2127
  import { createGapSeparator, createMenuAction, MenuProvider, ToolbarMenu, useMenuActions } from "@dxos/react-ui-menu";
1868
2128
  var createTableToolbarActions = (state) => {
1869
2129
  const add = createMenuAction("add-row", {
@@ -1917,84 +2177,25 @@ var createTableToolbarActions = (state) => {
1917
2177
  };
1918
2178
  };
1919
2179
  var TableToolbar = ({ classNames, viewDirty, attendableId, onAction }) => {
1920
- const state = useMemo5(() => create3({
2180
+ const state = useMemo6(() => create4({
1921
2181
  viewDirty
1922
2182
  }), []);
1923
- const actionsCreator = useCallback5(() => createTableToolbarActions(state), [
2183
+ const actionsCreator = useCallback6(() => createTableToolbarActions(state), [
1924
2184
  state
1925
2185
  ]);
1926
2186
  const menu = useMenuActions(actionsCreator);
1927
- return /* @__PURE__ */ React8.createElement(MenuProvider, {
2187
+ return /* @__PURE__ */ React9.createElement(MenuProvider, {
1928
2188
  ...menu,
1929
2189
  attendableId,
1930
2190
  onAction
1931
- }, /* @__PURE__ */ React8.createElement(ToolbarMenu, {
2191
+ }, /* @__PURE__ */ React9.createElement(ToolbarMenu, {
1932
2192
  classNames
1933
2193
  }));
1934
2194
  };
1935
-
1936
- // packages/ui/react-ui-table/src/hooks/useTableModel.ts
1937
- import { effect as effect3 } from "@preact/signals-core";
1938
- import { useEffect as useEffect2, useState as useState3 } from "react";
1939
- import { useSelectionActions } from "@dxos/react-ui-attention";
1940
- import { isNonNullable } from "@dxos/util";
1941
- var useTableModel = ({ objects, table, projection, ...props }) => {
1942
- const [model, setModel] = useState3();
1943
- useEffect2(() => {
1944
- if (!table || !projection) {
1945
- return;
1946
- }
1947
- let model2;
1948
- const t = setTimeout(async () => {
1949
- model2 = new TableModel({
1950
- table,
1951
- projection,
1952
- ...props
1953
- });
1954
- await model2.open();
1955
- setModel(model2);
1956
- });
1957
- return () => {
1958
- clearTimeout(t);
1959
- void model2?.close();
1960
- };
1961
- }, [
1962
- table,
1963
- projection
1964
- ]);
1965
- useEffect2(() => {
1966
- if (objects) {
1967
- model?.setRows(objects);
1968
- }
1969
- }, [
1970
- model,
1971
- objects
1972
- ]);
1973
- const { select, clear } = useSelectionActions([
1974
- table?.id,
1975
- table?.view?.target?.query.typename
1976
- ].filter(isNonNullable));
1977
- useEffect2(() => {
1978
- if (!model) {
1979
- return;
1980
- }
1981
- const unsubscribe = effect3(() => {
1982
- select([
1983
- ...model.selection.selection.value
1984
- ]);
1985
- });
1986
- return () => {
1987
- clear();
1988
- unsubscribe();
1989
- };
1990
- }, [
1991
- model
1992
- ]);
1993
- return model;
1994
- };
1995
2195
  export {
1996
2196
  BUTTON_IDENTIFIERS,
1997
2197
  CONTROL_IDENTIFIERS,
2198
+ DynamicTable,
1998
2199
  ModalController,
1999
2200
  Table,
2000
2201
  TableModel,
@@ -2003,6 +2204,7 @@ export {
2003
2204
  TableToolbar,
2004
2205
  TableType,
2005
2206
  initializeTable,
2207
+ makeDynamicTable,
2006
2208
  renderCheckbox,
2007
2209
  renderSwitch,
2008
2210
  tableButtons,