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