@dxos/react-ui-table 0.8.4-main.2e9d522 → 0.8.4-main.3c1ae3b

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 (144) hide show
  1. package/dist/lib/browser/chunk-CJQ6T4LL.mjs +77 -0
  2. package/dist/lib/browser/chunk-CJQ6T4LL.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-5XLSHLOG.mjs → chunk-V7A7ZA5E.mjs} +576 -544
  4. package/dist/lib/browser/chunk-V7A7ZA5E.mjs.map +7 -0
  5. package/dist/lib/browser/index.mjs +694 -760
  6. package/dist/lib/browser/index.mjs.map +4 -4
  7. package/dist/lib/browser/meta.json +1 -1
  8. package/dist/lib/browser/testing/index.mjs +16 -27
  9. package/dist/lib/browser/testing/index.mjs.map +3 -3
  10. package/dist/lib/browser/types/index.mjs +3 -3
  11. package/dist/lib/node-esm/{chunk-Y66YLSTC.mjs → chunk-P73ALX3N.mjs} +576 -544
  12. package/dist/lib/node-esm/chunk-P73ALX3N.mjs.map +7 -0
  13. package/dist/lib/node-esm/chunk-T6PXZQ6W.mjs +78 -0
  14. package/dist/lib/node-esm/chunk-T6PXZQ6W.mjs.map +7 -0
  15. package/dist/lib/node-esm/index.mjs +694 -760
  16. package/dist/lib/node-esm/index.mjs.map +4 -4
  17. package/dist/lib/node-esm/meta.json +1 -1
  18. package/dist/lib/node-esm/testing/index.mjs +16 -27
  19. package/dist/lib/node-esm/testing/index.mjs.map +3 -3
  20. package/dist/lib/node-esm/types/index.mjs +3 -3
  21. package/dist/types/src/components/Table/ColumnActionsMenu.d.ts +2 -3
  22. package/dist/types/src/components/Table/ColumnActionsMenu.d.ts.map +1 -1
  23. package/dist/types/src/components/Table/ColumnSettings.d.ts +3 -3
  24. package/dist/types/src/components/Table/ColumnSettings.d.ts.map +1 -1
  25. package/dist/types/src/components/Table/DynamicTable.d.ts +5 -6
  26. package/dist/types/src/components/Table/DynamicTable.d.ts.map +1 -1
  27. package/dist/types/src/components/Table/DynamicTable.stories.d.ts +37 -3
  28. package/dist/types/src/components/Table/DynamicTable.stories.d.ts.map +1 -1
  29. package/dist/types/src/components/Table/Relations.stories.d.ts +111 -0
  30. package/dist/types/src/components/Table/Relations.stories.d.ts.map +1 -0
  31. package/dist/types/src/components/Table/RowActionsMenu.d.ts +1 -1
  32. package/dist/types/src/components/Table/RowActionsMenu.d.ts.map +1 -1
  33. package/dist/types/src/components/Table/Table.d.ts +13 -9
  34. package/dist/types/src/components/Table/Table.d.ts.map +1 -1
  35. package/dist/types/src/components/Table/Table.stories.d.ts +108 -4
  36. package/dist/types/src/components/Table/Table.stories.d.ts.map +1 -1
  37. package/dist/types/src/components/TableCellEditor/CellValidationMessage.d.ts +1 -1
  38. package/dist/types/src/components/TableCellEditor/CellValidationMessage.d.ts.map +1 -1
  39. package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts +14 -9
  40. package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts.map +1 -1
  41. package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts +11 -18
  42. package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts.map +1 -1
  43. package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts +39 -4
  44. package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts.map +1 -1
  45. package/dist/types/src/components/TableCellEditor/index.d.ts +1 -0
  46. package/dist/types/src/components/TableCellEditor/index.d.ts.map +1 -1
  47. package/dist/types/src/components/TableToolbar/TableToolbar.d.ts +2 -2
  48. package/dist/types/src/components/TableToolbar/TableToolbar.d.ts.map +1 -1
  49. package/dist/types/src/components/testing.d.ts +3 -5
  50. package/dist/types/src/components/testing.d.ts.map +1 -1
  51. package/dist/types/src/hooks/index.d.ts +2 -1
  52. package/dist/types/src/hooks/index.d.ts.map +1 -1
  53. package/dist/types/src/hooks/useAddRow.d.ts +3 -2
  54. package/dist/types/src/hooks/useAddRow.d.ts.map +1 -1
  55. package/dist/types/src/hooks/useProjectionModel.d.ts +5 -0
  56. package/dist/types/src/hooks/useProjectionModel.d.ts.map +1 -0
  57. package/dist/types/src/hooks/useTableModel.d.ts +5 -6
  58. package/dist/types/src/hooks/useTableModel.d.ts.map +1 -1
  59. package/dist/types/src/model/modal-controller.d.ts +0 -7
  60. package/dist/types/src/model/modal-controller.d.ts.map +1 -1
  61. package/dist/types/src/model/selection-model.d.ts.map +1 -1
  62. package/dist/types/src/model/table-model.d.ts +14 -14
  63. package/dist/types/src/model/table-model.d.ts.map +1 -1
  64. package/dist/types/src/model/table-presentation.d.ts +2 -1
  65. package/dist/types/src/model/table-presentation.d.ts.map +1 -1
  66. package/dist/types/src/model/table-sorting.d.ts +9 -6
  67. package/dist/types/src/model/table-sorting.d.ts.map +1 -1
  68. package/dist/types/src/playwright/TableManager.d.ts +1 -1
  69. package/dist/types/src/playwright/TableManager.d.ts.map +1 -1
  70. package/dist/types/src/testing/useTestTableModel.d.ts +19 -34
  71. package/dist/types/src/testing/useTestTableModel.d.ts.map +1 -1
  72. package/dist/types/src/translations.d.ts +2 -2
  73. package/dist/types/src/types/Table.d.ts +28 -0
  74. package/dist/types/src/types/Table.d.ts.map +1 -0
  75. package/dist/types/src/types/index.d.ts +1 -1
  76. package/dist/types/src/types/index.d.ts.map +1 -1
  77. package/dist/types/src/util/dynamic-table.d.ts +10 -11
  78. package/dist/types/src/util/dynamic-table.d.ts.map +1 -1
  79. package/dist/types/src/util/index.d.ts +0 -1
  80. package/dist/types/src/util/index.d.ts.map +1 -1
  81. package/dist/types/src/util/schema.d.ts +1 -1
  82. package/dist/types/src/util/schema.d.ts.map +1 -1
  83. package/dist/types/src/util/table-buttons.d.ts.map +1 -1
  84. package/dist/types/src/util/table-controls.d.ts.map +1 -1
  85. package/dist/types/tsconfig.tsbuildinfo +1 -1
  86. package/package.json +57 -51
  87. package/src/components/Table/ColumnActionsMenu.tsx +5 -2
  88. package/src/components/Table/ColumnSettings.tsx +3 -4
  89. package/src/components/Table/DynamicTable.stories.tsx +21 -19
  90. package/src/components/Table/DynamicTable.tsx +24 -18
  91. package/src/components/Table/Relations.stories.tsx +233 -0
  92. package/src/components/Table/RowActionsMenu.tsx +23 -15
  93. package/src/components/Table/Table.stories.tsx +104 -99
  94. package/src/components/Table/Table.tsx +338 -295
  95. package/src/components/TableCellEditor/CellValidationMessage.tsx +2 -2
  96. package/src/components/TableCellEditor/FormCellEditor.tsx +143 -39
  97. package/src/components/TableCellEditor/TableCellEditor.stories.tsx +30 -66
  98. package/src/components/TableCellEditor/TableCellEditor.tsx +86 -236
  99. package/src/components/TableCellEditor/index.ts +1 -0
  100. package/src/components/TableToolbar/TableToolbar.tsx +34 -24
  101. package/src/components/testing.ts +4 -4
  102. package/src/hooks/index.ts +2 -1
  103. package/src/hooks/useAddRow.ts +7 -5
  104. package/src/hooks/useProjectionModel.ts +19 -0
  105. package/src/hooks/useTableModel.ts +13 -15
  106. package/src/model/modal-controller.ts +1 -29
  107. package/src/model/selection-model.ts +3 -2
  108. package/src/model/table-model.test.ts +21 -12
  109. package/src/model/table-model.ts +64 -58
  110. package/src/model/table-presentation.test.ts +25 -23
  111. package/src/model/table-presentation.ts +82 -41
  112. package/src/model/table-sorting.ts +32 -14
  113. package/src/playwright/TableManager.ts +5 -5
  114. package/src/playwright/smoke.spec.ts +132 -38
  115. package/src/testing/useTestTableModel.ts +32 -24
  116. package/src/translations.ts +2 -2
  117. package/src/types/Table.ts +90 -0
  118. package/src/types/index.ts +1 -1
  119. package/src/util/dynamic-table.ts +21 -27
  120. package/src/util/index.ts +0 -1
  121. package/src/util/schema.ts +4 -4
  122. package/src/util/table-buttons.ts +4 -3
  123. package/src/util/table-controls.ts +4 -1
  124. package/dist/lib/browser/chunk-5XLSHLOG.mjs.map +0 -7
  125. package/dist/lib/browser/chunk-L2LSB6KV.mjs +0 -18
  126. package/dist/lib/browser/chunk-L2LSB6KV.mjs.map +0 -7
  127. package/dist/lib/node-esm/chunk-NXZ4CJYX.mjs +0 -20
  128. package/dist/lib/node-esm/chunk-NXZ4CJYX.mjs.map +0 -7
  129. package/dist/lib/node-esm/chunk-Y66YLSTC.mjs.map +0 -7
  130. package/dist/types/src/components/Table/CreateRefPanel.d.ts +0 -9
  131. package/dist/types/src/components/Table/CreateRefPanel.d.ts.map +0 -1
  132. package/dist/types/src/components/Table/relations.stories.d.ts +0 -9
  133. package/dist/types/src/components/Table/relations.stories.d.ts.map +0 -1
  134. package/dist/types/src/components/TableCellEditor/extension.d.ts +0 -13
  135. package/dist/types/src/components/TableCellEditor/extension.d.ts.map +0 -1
  136. package/dist/types/src/types/schema.d.ts +0 -8
  137. package/dist/types/src/types/schema.d.ts.map +0 -1
  138. package/dist/types/src/util/table.d.ts +0 -11
  139. package/dist/types/src/util/table.d.ts.map +0 -1
  140. package/src/components/Table/CreateRefPanel.tsx +0 -86
  141. package/src/components/Table/relations.stories.tsx +0 -116
  142. package/src/components/TableCellEditor/extension.ts +0 -61
  143. package/src/types/schema.ts +0 -16
  144. package/src/util/table.ts +0 -49
@@ -1,13 +1,12 @@
1
1
  import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
2
  import {
3
- TableView
4
- } from "./chunk-NXZ4CJYX.mjs";
3
+ Table_exports
4
+ } from "./chunk-T6PXZQ6W.mjs";
5
5
 
6
6
  // src/util/dynamic-table.ts
7
- import { Obj } from "@dxos/echo";
8
- import { getTypename, toJsonSchema } from "@dxos/echo-schema";
9
- import { createView, getSchemaFromPropertyDefinitions, ProjectionModel } from "@dxos/schema";
10
- var getBaseSchema = ({ typename, properties, jsonSchema, schema }) => {
7
+ import { Filter, Obj, Query, Ref, Type } from "@dxos/echo";
8
+ import { ProjectionModel, View, getSchemaFromPropertyDefinitions } from "@dxos/schema";
9
+ var getBaseSchema = ({ schema, typename, properties, jsonSchema }) => {
11
10
  if (typename && properties) {
12
11
  const schema2 = getSchemaFromPropertyDefinitions(typename, properties);
13
12
  return {
@@ -16,8 +15,8 @@ var getBaseSchema = ({ typename, properties, jsonSchema, schema }) => {
16
15
  };
17
16
  } else if (schema) {
18
17
  return {
19
- typename: getTypename(schema),
20
- jsonSchema: toJsonSchema(schema)
18
+ typename: Type.getTypename(schema),
19
+ jsonSchema: Type.toJsonSchema(schema)
21
20
  };
22
21
  } else if (typename && jsonSchema) {
23
22
  return {
@@ -28,25 +27,26 @@ var getBaseSchema = ({ typename, properties, jsonSchema, schema }) => {
28
27
  throw new Error("invalid properties");
29
28
  }
30
29
  };
31
- var makeDynamicTable = ({ typename, jsonSchema, properties }) => {
32
- const table = Obj.make(TableView, {
33
- sizes: {}
34
- });
35
- const view = createView({
36
- typename,
30
+ var makeDynamicTable = ({ jsonSchema, properties }) => {
31
+ const view = View.make({
32
+ query: Query.select(Filter.everything()),
37
33
  jsonSchema,
38
- presentation: table,
39
34
  ...properties && {
40
35
  fields: properties.map((property) => property.name)
41
36
  }
42
37
  });
38
+ const object = Obj.make(Table_exports.Table, {
39
+ view: Ref.make(view),
40
+ sizes: {}
41
+ });
43
42
  const projection = new ProjectionModel(jsonSchema, view.projection);
43
+ projection.normalizeView();
44
44
  if (properties && projection.fields) {
45
- setProperties(view, projection, table, properties);
45
+ setProperties(view, projection, object, properties);
46
46
  }
47
47
  return {
48
48
  projection,
49
- view
49
+ object
50
50
  };
51
51
  };
52
52
  var setProperties = (view, projection, table, properties) => {
@@ -68,7 +68,7 @@ var setProperties = (view, projection, table, properties) => {
68
68
  }
69
69
  if (property.sort) {
70
70
  const fieldId = field.id;
71
- view.query.sort = [
71
+ view.sort = [
72
72
  {
73
73
  fieldId,
74
74
  direction: property.sort
@@ -82,40 +82,6 @@ var setProperties = (view, projection, table, properties) => {
82
82
  // src/util/signals.ts
83
83
  var touch = (value) => value;
84
84
 
85
- // src/util/table.ts
86
- import { Match } from "effect";
87
- import { Obj as Obj2 } from "@dxos/echo";
88
- import { toEffectSchema } from "@dxos/echo-schema";
89
- import { createViewFromSpace, getSchemaProperties } from "@dxos/schema";
90
- var createTable = async ({ sizes, ...props }) => {
91
- const table = Obj2.make(TableView, {
92
- sizes: {}
93
- });
94
- const { jsonSchema, view } = await createViewFromSpace({
95
- ...props,
96
- presentation: table
97
- });
98
- const schema = toEffectSchema(jsonSchema);
99
- const shouldIncludeId = props.fields?.find((field) => field === "id") !== void 0;
100
- const properties = getSchemaProperties(schema.ast, {}, shouldIncludeId);
101
- for (const property of properties) {
102
- if (sizes?.[property.name]) {
103
- table.sizes[property.name] = sizes[property.name];
104
- continue;
105
- }
106
- Match.type().pipe(Match.when("boolean", () => {
107
- table.sizes[property.name] = 100;
108
- }), Match.when("number", () => {
109
- table.sizes[property.name] = 100;
110
- }), Match.orElse(() => {
111
- }))(property.type);
112
- }
113
- return {
114
- jsonSchema,
115
- view
116
- };
117
- };
118
-
119
85
  // src/util/table-buttons.ts
120
86
  var BUTTON_IDENTIFIERS = {
121
87
  columnSettings: "data-table-column-settings-button",
@@ -125,10 +91,9 @@ var BUTTON_IDENTIFIERS = {
125
91
  saveDraftRow: "data-table-save-draft-row-button",
126
92
  sort: "data-table-sort-button"
127
93
  };
128
- var createButton = ({ attr, data, disabled = false, icon, testId, type = "primary" }) => {
94
+ var createButton = ({ attr, data, disabled = false, icon, testId, type: _type = "primary" }) => {
129
95
  const dataAttrs = Object.entries(data).map(([k, v]) => `${k}="${v}"`).join(" ");
130
- const positionClass = type === "primary" ? "inline-end-2" : "inline-end-9";
131
- return `<button ${attr} data-testid="${testId}" class="dx-button is-6 pli-0.5 min-bs-0 absolute inset-block-1 ${positionClass}" ${dataAttrs} ${disabled ? "disabled" : ""}><svg data-size="4"><use href="/icons.svg#${icon}"/></svg></button>`;
96
+ return `<button ${attr} data-testid="${testId}" class="dx-button is-6 aspect-square pli-0.5 min-bs-0" ${dataAttrs} ${disabled ? "disabled" : ""} data-dx-grid-action="accessory"><svg data-size="4"><use href="/icons.svg#${icon}"/></svg></button>`;
132
97
  };
133
98
  var addColumnButton = {
134
99
  attr: BUTTON_IDENTIFIERS.newColumn,
@@ -154,7 +119,8 @@ var columnSettingsButton = {
154
119
  attr: BUTTON_IDENTIFIERS.columnSettings,
155
120
  icon: columnSettingsButton.icon,
156
121
  data: {
157
- "data-field-id": fieldId
122
+ "data-field-id": fieldId,
123
+ "data-variant": "ghost"
158
124
  },
159
125
  testId: "table-column-settings-button"
160
126
  });
@@ -214,7 +180,8 @@ var saveDraftRowButton = {
214
180
  icon: saveDraftRowButton.icon,
215
181
  disabled,
216
182
  data: {
217
- "data-row-index": rowIndex.toString()
183
+ "data-row-index": rowIndex.toString(),
184
+ "data-variant": "primary"
218
185
  },
219
186
  testId: "table-save-draft-row-button"
220
187
  });
@@ -233,6 +200,7 @@ var tableButtons = {
233
200
  };
234
201
 
235
202
  // src/util/table-controls.ts
203
+ import { accessoryHandlesPointerdownAttrs } from "@dxos/lit-grid";
236
204
  var CONTROL_IDENTIFIERS = {
237
205
  checkbox: "data-table-checkbox",
238
206
  switch: "data-table-switch"
@@ -245,7 +213,7 @@ var renderAttributes = (data) => {
245
213
  return Object.entries(data).map(([k, v]) => `${k}="${v}"`).join(" ");
246
214
  };
247
215
  var renderInput = (baseClass, attrs, checked = false, disabled = false, preventToggle = false, testId) => {
248
- return `<input type="checkbox" class="${baseClass}" ${renderAttributes(attrs)} ${checked ? "checked" : ""} ${preventToggle ? 'onclick="return false"' : ""} ${disabled ? "disabled" : ""} data-testid="${testId}"/>`;
216
+ return `<input type="checkbox" class="${baseClass}" ${renderAttributes(attrs)} ${checked ? "checked" : ""} ${preventToggle ? 'onclick="return false"' : ""} ${disabled ? "disabled" : ""} data-testid="${testId}" data-dx-grid-action="accessory"/>`;
249
217
  };
250
218
  var CheckboxStory = ({ rowIndex, header = false, checked = false, disabled = false }) => {
251
219
  const attrs = {
@@ -261,7 +229,8 @@ var SwitchStory = ({ colIndex, rowIndex, checked = false, disabled = false }) =>
261
229
  const attrs = {
262
230
  [CONTROL_IDENTIFIERS.switch]: "",
263
231
  "data-row-index": rowIndex.toString(),
264
- "data-col-index": colIndex.toString()
232
+ "data-col-index": colIndex.toString(),
233
+ ...accessoryHandlesPointerdownAttrs
265
234
  };
266
235
  return renderInput(BASE_CLASSES.switch, attrs, checked, disabled, true, "table-switch");
267
236
  };
@@ -287,14 +256,14 @@ var tableControls = {
287
256
  };
288
257
 
289
258
  // src/util/schema.ts
290
- import { Schema } from "effect";
291
- import { isTypeLiteral, TypeLiteral } from "effect/SchemaAST";
259
+ import * as Schema from "effect/Schema";
260
+ import * as SchemaAST from "effect/SchemaAST";
292
261
  var narrowSchema = (schema, paths) => {
293
262
  const ast = schema?.ast;
294
- if (isTypeLiteral(ast)) {
263
+ if (SchemaAST.isTypeLiteral(ast)) {
295
264
  const propertySignatures = ast.propertySignatures.filter((signature) => paths.includes(signature.name.toString()));
296
265
  if (propertySignatures.length > 0) {
297
- const narrowType = new TypeLiteral(propertySignatures, []);
266
+ const narrowType = new SchemaAST.TypeLiteral(propertySignatures, []);
298
267
  return Schema.make(narrowType);
299
268
  }
300
269
  }
@@ -304,67 +273,59 @@ var narrowSchema = (schema, paths) => {
304
273
  // src/model/table-model.ts
305
274
  import { computed as computed3, effect as effect2, signal as signal3 } from "@preact/signals-core";
306
275
  import { Resource as Resource2 } from "@dxos/context";
307
- import { Obj as Obj3, Ref } from "@dxos/echo";
308
- import { FormatEnum as FormatEnum2, getValue as getValue2, setValue, getSnapshot, getSchema, toEffectSchema as toEffectSchema2 } from "@dxos/echo-schema";
276
+ import { Format as Format2, Obj as Obj2, Ref as Ref2 } from "@dxos/echo";
277
+ import { getValue as getValue2, setValue, toEffectSchema } from "@dxos/echo/internal";
309
278
  import { invariant } from "@dxos/invariant";
310
279
  import { ObjectId } from "@dxos/keys";
311
- import { isLiveObject } from "@dxos/live-object";
312
- import { fullyQualifiedId } from "@dxos/react-client/echo";
280
+ import { getSnapshot, isLiveObject } from "@dxos/live-object";
313
281
  import { formatForEditing, parseValue } from "@dxos/react-ui-form";
314
- import { ProjectionModel as ProjectionModel2, validateSchema } from "@dxos/schema";
282
+ import { validateSchema } from "@dxos/schema";
283
+
284
+ // src/util/tag.ts
285
+ var TAG_PATTERN_REGEX = /\[([^\]]+)\]\(([^)]+)\)/g;
286
+ var extractTagIds = (value) => {
287
+ if (typeof value !== "string") {
288
+ return void 0;
289
+ }
290
+ const ids = [];
291
+ let match;
292
+ while ((match = TAG_PATTERN_REGEX.exec(value)) !== null) {
293
+ if (match[2]) {
294
+ ids.push(match[2]);
295
+ }
296
+ }
297
+ return ids.length > 0 ? ids : void 0;
298
+ };
315
299
 
316
300
  // src/model/selection-model.ts
317
301
  import { computed, effect, signal } from "@preact/signals-core";
318
302
  import { Resource } from "@dxos/context";
319
303
  var SelectionModel = class extends Resource {
304
+ _rows;
305
+ _selectionMode;
306
+ _initialSelection;
307
+ _onSelectionChanged;
308
+ _selection;
309
+ _validSelectedIds = computed(() => {
310
+ const rows = this._rows.value;
311
+ if (!rows) {
312
+ return /* @__PURE__ */ new Set();
313
+ }
314
+ const validIds = new Set(rows.map((row) => row.id));
315
+ return new Set([
316
+ ...this._selection.value
317
+ ].filter((id) => validIds.has(id)));
318
+ });
319
+ _hasSelection = computed(() => this._validSelectedIds.value.size > 0);
320
+ _allSelected = computed(() => {
321
+ const rows = this._rows.value;
322
+ if (rows.length === 0) {
323
+ return false;
324
+ }
325
+ return rows.every((row) => this._selection.value.has(row.id));
326
+ });
320
327
  constructor(_rows, _selectionMode, _initialSelection, _onSelectionChanged) {
321
- super(), this._rows = _rows, this._selectionMode = _selectionMode, this._initialSelection = _initialSelection, this._onSelectionChanged = _onSelectionChanged, this._validSelectedIds = computed(() => {
322
- const rows = this._rows.value;
323
- if (!rows) {
324
- return /* @__PURE__ */ new Set();
325
- }
326
- const validIds = new Set(rows.map((row) => row.id));
327
- return new Set([
328
- ...this._selection.value
329
- ].filter((id) => validIds.has(id)));
330
- }), this._hasSelection = computed(() => this._validSelectedIds.value.size > 0), this._allSelected = computed(() => {
331
- const rows = this._rows.value;
332
- if (rows.length === 0) {
333
- return false;
334
- }
335
- return rows.every((row) => this._selection.value.has(row.id));
336
- }), this.getSelectedRows = () => {
337
- const selectedIds = this._validSelectedIds.value;
338
- return this._rows.value.filter((row) => selectedIds.has(row.id));
339
- }, this.isRowIndexSelected = (rowIndex) => {
340
- const row = this._rows.value[rowIndex];
341
- return this._selection.value.has(row.id);
342
- }, this.isObjectSelected = (object) => {
343
- return this._selection.value.has(object.id);
344
- }, this.toggleSelectionForRowIndex = (rowIndex) => {
345
- const row = this._rows.value[rowIndex];
346
- const newSelection = new Set(this._selection.value);
347
- if (newSelection.has(row.id)) {
348
- newSelection.delete(row.id);
349
- } else {
350
- if (this._selectionMode === "single") {
351
- newSelection.clear();
352
- }
353
- newSelection.add(row.id);
354
- }
355
- this._selection.value = newSelection;
356
- }, this.setSelection = (mode) => {
357
- switch (mode) {
358
- case "all": {
359
- this._selection.value = new Set(this._rows.value.map((row) => row.id));
360
- break;
361
- }
362
- case "none": {
363
- this._selection.value = /* @__PURE__ */ new Set();
364
- break;
365
- }
366
- }
367
- };
328
+ super(), this._rows = _rows, this._selectionMode = _selectionMode, this._initialSelection = _initialSelection, this._onSelectionChanged = _onSelectionChanged;
368
329
  this._selection = signal(new Set(this._initialSelection));
369
330
  }
370
331
  async _open() {
@@ -389,23 +350,67 @@ var SelectionModel = class extends Resource {
389
350
  get selectionMode() {
390
351
  return this._selectionMode;
391
352
  }
353
+ getSelectedRows = () => {
354
+ const selectedIds = this._validSelectedIds.value;
355
+ return this._rows.value.filter((row) => selectedIds.has(row.id));
356
+ };
357
+ isRowIndexSelected = (rowIndex) => {
358
+ const row = this._rows.value[rowIndex];
359
+ return this._selection.value.has(row.id);
360
+ };
361
+ isObjectSelected = (object) => {
362
+ return this._selection.value.has(object.id);
363
+ };
364
+ //
365
+ // Manipulation
366
+ //
367
+ toggleSelectionForRowIndex = (rowIndex) => {
368
+ const row = this._rows.value[rowIndex];
369
+ const newSelection = new Set(this._selection.value);
370
+ if (newSelection.has(row.id)) {
371
+ newSelection.delete(row.id);
372
+ } else {
373
+ if (this._selectionMode === "single") {
374
+ newSelection.clear();
375
+ }
376
+ newSelection.add(row.id);
377
+ }
378
+ this._selection.value = newSelection;
379
+ };
380
+ setSelection = (mode) => {
381
+ switch (mode) {
382
+ case "all": {
383
+ this._selection.value = new Set(this._rows.value.map((row) => row.id));
384
+ break;
385
+ }
386
+ case "none": {
387
+ this._selection.value = /* @__PURE__ */ new Set();
388
+ break;
389
+ }
390
+ }
391
+ };
392
392
  };
393
393
 
394
394
  // src/model/table-sorting.ts
395
395
  import { computed as computed2, signal as signal2 } from "@preact/signals-core";
396
396
  import orderBy from "lodash.orderby";
397
- import { getValue, FormatEnum, TypeEnum } from "@dxos/echo-schema";
397
+ import { Format, TypeEnum, getValue } from "@dxos/echo/internal";
398
398
  import { formatForDisplay } from "@dxos/react-ui-form";
399
399
  var TableSorting = class {
400
- constructor(rows, _view, _projection) {
401
- this._view = _view;
402
- this._projection = _projection;
403
- this._displayToDataIndex = /* @__PURE__ */ new Map();
404
- this._localSort = signal2(void 0);
400
+ _displayToDataIndex = /* @__PURE__ */ new Map();
401
+ _rows;
402
+ _getView;
403
+ _projection;
404
+ _localSort = signal2(void 0);
405
+ _isDirty;
406
+ sortedRows;
407
+ constructor({ rows, projection, getView }) {
405
408
  this._rows = rows;
409
+ this._getView = getView;
410
+ this._projection = projection;
406
411
  this._isDirty = computed2(() => {
407
412
  const local = this._localSort.value;
408
- const viewSort = this._view.query.sort?.[0];
413
+ const viewSort = this._getView().sort?.[0];
409
414
  if (local?.type === "cleared") {
410
415
  return viewSort !== void 0;
411
416
  }
@@ -431,7 +436,7 @@ var TableSorting = class {
431
436
  if (local?.type === "active") {
432
437
  return local.sort;
433
438
  }
434
- return this._view.query.sort?.[0];
439
+ return this._getView().sort?.[0];
435
440
  }
436
441
  /**
437
442
  * @reactive
@@ -474,12 +479,13 @@ var TableSorting = class {
474
479
  }
475
480
  save() {
476
481
  if (this._localSort.value !== void 0) {
482
+ const view = this._getView();
477
483
  if (this._localSort.value.type === "active") {
478
- this._view.query.sort = [
484
+ view.sort = [
479
485
  this._localSort.value.sort
480
486
  ];
481
487
  } else {
482
- this._view.query.sort = [];
488
+ view.sort = [];
483
489
  }
484
490
  this._localSort.value = void 0;
485
491
  }
@@ -536,7 +542,7 @@ var TableSorting = class {
536
542
  if (value == null) {
537
543
  return value;
538
544
  }
539
- if (format === FormatEnum.SingleSelect) {
545
+ if (format === Format.TypeFormat.SingleSelect) {
540
546
  const options = props.options;
541
547
  if (!options) {
542
548
  return void 0;
@@ -544,7 +550,7 @@ var TableSorting = class {
544
550
  const option = options.find((option2) => option2.id === value);
545
551
  return option ? options.indexOf(option) : void 0;
546
552
  }
547
- if (format === FormatEnum.Ref && field.referencePath) {
553
+ if (format === Format.TypeFormat.Ref && field.referencePath) {
548
554
  const refValue = getValue(value.target, field.referencePath);
549
555
  return refValue;
550
556
  }
@@ -556,22 +562,6 @@ var TableSorting = class {
556
562
  }
557
563
  };
558
564
 
559
- // src/util/tag.ts
560
- var TAG_PATTERN_REGEX = /\[([^\]]+)\]\(([^)]+)\)/g;
561
- var extractTagIds = (value) => {
562
- if (typeof value !== "string") {
563
- return void 0;
564
- }
565
- const ids = [];
566
- let match;
567
- while ((match = TAG_PATTERN_REGEX.exec(value)) !== null) {
568
- if (match[2]) {
569
- ids.push(match[2]);
570
- }
571
- }
572
- return ids.length > 0 ? ids : void 0;
573
- };
574
-
575
565
  // src/model/table-model.ts
576
566
  var __dxlog_file = "/__w/dxos/dxos/packages/ui/react-ui-table/src/model/table-model.ts";
577
567
  var defaultFeatures = {
@@ -583,241 +573,61 @@ var defaultFeatures = {
583
573
  schemaEditable: false
584
574
  };
585
575
  var TableModel = class extends Resource2 {
586
- constructor({ view, schema, projection, features = {}, sorting = [], initialSelection = [], pinnedRows = {
576
+ _object;
577
+ _projection;
578
+ _visibleRange = signal3({
579
+ start: {
580
+ row: 0,
581
+ col: 0
582
+ },
583
+ end: {
584
+ row: 0,
585
+ col: 0
586
+ }
587
+ });
588
+ _onInsertRow;
589
+ _onDeleteRows;
590
+ _onDeleteColumn;
591
+ _onCellUpdate;
592
+ _onRowOrderChange;
593
+ _onRowAction;
594
+ _rowActions;
595
+ _features;
596
+ _rows = signal3([]);
597
+ _draftRows = signal3([]);
598
+ _sorting;
599
+ _pinnedRows;
600
+ _selection;
601
+ _columnMeta;
602
+ constructor({ object, projection, features = {}, sorting = [], initialSelection = [], pinnedRows = {
587
603
  top: [],
588
604
  bottom: []
589
605
  }, rowActions = [], onCellUpdate, onDeleteColumn, onDeleteRows, onInsertRow, onRowOrderChange, onRowAction }) {
590
606
  super();
591
- this._visibleRange = signal3({
592
- start: {
593
- row: 0,
594
- col: 0
595
- },
596
- end: {
597
- row: 0,
598
- col: 0
599
- }
600
- });
601
- this._rows = signal3([]);
602
- this._draftRows = signal3([]);
603
- //
604
- // Data
605
- //
606
- this.setRows = (obj) => {
607
- this._rows.value = obj;
608
- };
609
- this.getRowCount = () => this._rows.value.length;
610
- /**
611
- * @reactive
612
- */
613
- this.getDraftRowCount = () => this._draftRows.value.length;
614
- this.getColumnCount = () => this._projection?.fields.length ?? 0;
615
- this.insertRow = () => {
616
- const result = this._onInsertRow?.();
617
- if (result === false && this._draftRows.value.length === 0) {
618
- this.createDraftRow();
619
- }
620
- };
621
- this.commitDraftRow = (draftRowIndex) => {
622
- if (draftRowIndex < 0 || draftRowIndex >= this._draftRows.value.length) {
623
- return false;
624
- }
625
- const draftRow = this._draftRows.value[draftRowIndex];
626
- if (!draftRow.valid) {
627
- return false;
628
- }
629
- const success = this._onInsertRow?.(draftRow.data);
630
- if (success) {
631
- const newDraftRows = this._draftRows.value.filter((_, index) => index !== draftRowIndex);
632
- this._draftRows.value = newDraftRows;
633
- }
634
- return success ?? false;
635
- };
636
- this.deleteRow = (rowIndex) => {
637
- const row = this._sorting.getDataIndex(rowIndex);
638
- const obj = this._rows.value[row];
639
- const objectsToDelete = [];
640
- if (this.features.selection.enabled && this._selection.hasSelection.value) {
641
- const selectedRows = this._selection.getSelectedRows();
642
- objectsToDelete.push(...selectedRows);
643
- } else {
644
- objectsToDelete.push(obj);
645
- }
646
- this._onDeleteRows?.(row, objectsToDelete);
647
- };
648
- this.handleRowAction = (actionId, rowIndex) => {
649
- if (!this._onRowAction) {
650
- return;
651
- }
652
- const row = this._sorting.getDataIndex(rowIndex);
653
- const data = this._rows.value[row];
654
- if (data) {
655
- this._onRowAction(actionId, data);
656
- }
657
- };
658
- this.getCellData = (cell) => {
659
- const { col, row, plane } = cell;
660
- const fields = this._projection?.fields ?? [];
661
- if (col < 0 || col >= fields.length) {
662
- return void 0;
663
- }
664
- const field = fields[col];
665
- let value;
666
- if (plane === "frozenRowsEnd") {
667
- if (row >= 0 && row < this._draftRows.value.length) {
668
- value = getValue2(this._draftRows.value[row].data, field.path);
669
- } else {
670
- return void 0;
671
- }
672
- } else {
673
- const dataIndex = this._sorting.getDataIndex(row);
674
- value = getValue2(this._rows.value[dataIndex], field.path);
675
- }
676
- if (value == null) {
677
- return "";
678
- }
679
- const { props } = this._projection.getFieldProjection(field.id);
680
- switch (props.format) {
681
- case FormatEnum2.Ref: {
682
- if (!field.referencePath) {
683
- return "";
684
- }
685
- return getValue2(value.target, field.referencePath);
686
- }
687
- default: {
688
- return formatForEditing({
689
- type: props.type,
690
- format: props.format,
691
- value
692
- });
693
- }
694
- }
695
- };
696
- this.validateCellData = async ({ col, row, plane }, value) => {
697
- const fields = this._projection?.fields ?? [];
698
- if (col < 0 || col >= fields.length) {
699
- return {
700
- valid: false,
701
- error: "Invalid column index"
702
- };
703
- }
704
- const field = fields[col];
705
- const { props } = this._projection.getFieldProjection(field.id);
706
- const transformedValue = editorTextToCellValue(props, value);
707
- const isDraftRow = plane === "frozenRowsEnd";
708
- if (isDraftRow) {
709
- const isInvalidDraftRowIndex = row < 0 || row >= this._draftRows.value.length;
710
- if (isInvalidDraftRowIndex) {
711
- return {
712
- valid: false,
713
- error: "Invalid draft row index"
714
- };
715
- }
716
- const draftRow = this._draftRows.value[row];
717
- const snapshot = {
718
- ...draftRow.data
719
- };
720
- setValue(snapshot, field.path, transformedValue);
721
- const validationErrors = this.validateDraftRowData(snapshot);
722
- if (validationErrors.length > 0) {
723
- const error = validationErrors.find((err) => err.path === field.path);
724
- if (error) {
725
- return {
726
- valid: false,
727
- error: error.message
728
- };
729
- }
730
- }
731
- return {
732
- valid: true
733
- };
734
- } else {
735
- const rowIdx = this._sorting.getDataIndex(row);
736
- const currentRow = this._rows.value[rowIdx];
737
- invariant(currentRow, "Invalid row index", {
738
- F: __dxlog_file,
739
- L: 510,
740
- S: this,
741
- A: [
742
- "currentRow",
743
- "'Invalid row index'"
744
- ]
745
- });
746
- const snapshot = getSnapshot(currentRow);
747
- setValue(snapshot, field.path, transformedValue);
748
- const schema = getSchema(currentRow);
749
- invariant(schema, void 0, {
750
- F: __dxlog_file,
751
- L: 516,
752
- S: this,
753
- A: [
754
- "schema",
755
- ""
756
- ]
757
- });
758
- const validationResult = validateSchema(schema, snapshot);
759
- if (validationResult && validationResult.length > 0) {
760
- const error = validationResult[0];
761
- invariant(error.path === field.path, void 0, {
762
- F: __dxlog_file,
763
- L: 521,
764
- S: this,
765
- A: [
766
- "error.path === field.path",
767
- ""
768
- ]
769
- });
770
- return {
771
- valid: false,
772
- error: error.message
773
- };
774
- }
775
- return {
776
- valid: true
777
- };
778
- }
779
- };
780
- this.setCellData = (cell, value) => {
781
- const { col, row, plane } = cell;
782
- const fields = this._projection?.fields ?? [];
783
- if (col < 0 || col >= fields.length) {
784
- return;
785
- }
786
- const field = fields[col];
787
- const { props } = this._projection.getFieldProjection(field.id);
788
- const transformedValue = editorTextToCellValue(props, value);
789
- if (props.format === FormatEnum2.Ref && !isLiveObject(value)) {
790
- return;
791
- }
792
- if (plane === "frozenRowsEnd") {
793
- if (row >= 0 && row < this._draftRows.value.length) {
794
- setValue(this._draftRows.value[row].data, field.path, transformedValue);
795
- this.validateDraftRow(row);
796
- }
797
- } else {
798
- const rowIdx = this._sorting.getDataIndex(row);
799
- setValue(this._rows.value[rowIdx], field.path, transformedValue);
800
- }
801
- };
802
- this._view = view;
803
- this._projection = projection ?? new ProjectionModel2(schema, view.projection);
607
+ this._object = object;
608
+ this._projection = projection;
609
+ this._projection.normalizeView();
804
610
  this._features = {
805
611
  ...defaultFeatures,
806
612
  ...features
807
613
  };
808
614
  invariant(!(this._features.dataEditable && this._features.selection.enabled && this._features.selection.mode === "single"), "Single selection is not compatible with editable tables.", {
809
615
  F: __dxlog_file,
810
- L: 139,
616
+ L: 137,
811
617
  S: this,
812
618
  A: [
813
619
  "!(this._features.dataEditable && this._features.selection.enabled && this._features.selection.mode === 'single')",
814
620
  "'Single selection is not compatible with editable tables.'"
815
621
  ]
816
622
  });
817
- this._sorting = new TableSorting(this._rows, this._view, this._projection);
623
+ this._sorting = new TableSorting({
624
+ rows: this._rows,
625
+ getView: () => this.view,
626
+ projection: this._projection
627
+ });
818
628
  if (sorting.length > 0) {
819
- const [sort] = sorting;
820
- this._sorting.setSort(sort.fieldId, sort.direction);
629
+ const { fieldId, direction } = sorting[0];
630
+ this._sorting.setSort(fieldId, direction);
821
631
  }
822
632
  this._selection = new SelectionModel(this._sorting.sortedRows, this._features.selection.mode ?? "multiple", initialSelection, () => this._onRowOrderChange?.());
823
633
  this._pinnedRows = pinnedRows;
@@ -830,22 +640,23 @@ var TableModel = class extends Resource2 {
830
640
  this._onRowAction = onRowAction;
831
641
  }
832
642
  get id() {
833
- return fullyQualifiedId(this._view);
643
+ return Obj2.getDXN(this._object).toString();
834
644
  }
835
645
  get view() {
836
- return this._view;
837
- }
838
- get table() {
839
- invariant(this._table, "Model not initialized", {
646
+ const view = this._object.view.target;
647
+ invariant(view, "Table model not initialized", {
840
648
  F: __dxlog_file,
841
- L: 177,
649
+ L: 176,
842
650
  S: this,
843
651
  A: [
844
- "this._table",
845
- "'Model not initialized'"
652
+ "view",
653
+ "'Table model not initialized'"
846
654
  ]
847
655
  });
848
- return this._table;
656
+ return view;
657
+ }
658
+ get table() {
659
+ return this._object;
849
660
  }
850
661
  get projection() {
851
662
  return this._projection;
@@ -877,7 +688,7 @@ var TableModel = class extends Resource2 {
877
688
  get columnMeta() {
878
689
  invariant(this._columnMeta, void 0, {
879
690
  F: __dxlog_file,
880
- L: 216,
691
+ L: 219,
881
692
  S: this,
882
693
  A: [
883
694
  "this._columnMeta",
@@ -900,17 +711,7 @@ var TableModel = class extends Resource2 {
900
711
  // Initialisation
901
712
  //
902
713
  async _open() {
903
- const presentation = this._view.presentation.target ?? await this._view.presentation.load();
904
- invariant(Obj3.instanceOf(TableView, presentation), void 0, {
905
- F: __dxlog_file,
906
- L: 239,
907
- S: this,
908
- A: [
909
- "Obj.instanceOf(TableView, presentation)",
910
- ""
911
- ]
912
- });
913
- this._table = presentation;
714
+ await this._object.view.load();
914
715
  this.initializeColumnMeta();
915
716
  this.initializeEffects();
916
717
  await this._selection.open(this._ctx);
@@ -935,7 +736,7 @@ var TableModel = class extends Resource2 {
935
736
  },
936
737
  frozenColsEnd: {
937
738
  0: {
938
- size: 40,
739
+ size: 32,
939
740
  resizeable: false
940
741
  }
941
742
  }
@@ -971,6 +772,17 @@ var TableModel = class extends Resource2 {
971
772
  });
972
773
  this._ctx.onDispose(draftRowsWatcher);
973
774
  }
775
+ //
776
+ // Data
777
+ //
778
+ setRows = (obj) => {
779
+ this._rows.value = obj;
780
+ };
781
+ getRowCount = () => this._rows.value.length;
782
+ /**
783
+ * @reactive
784
+ */
785
+ getDraftRowCount = () => this._draftRows.value.length;
974
786
  // TODO(ZaymonFC): Return .value instead of exposing the signal.
975
787
  get draftRows() {
976
788
  return this._draftRows;
@@ -989,6 +801,14 @@ var TableModel = class extends Resource2 {
989
801
  const validationErrors = draftRow.validationErrors || [];
990
802
  return validationErrors.some((error) => error.path === fieldPath);
991
803
  }
804
+ getColumnCount = () => this._projection?.fields.length ?? 0;
805
+ insertRow = () => {
806
+ const result = this._onInsertRow?.();
807
+ if (result === "draft" && this._draftRows.value.length === 0) {
808
+ this.createDraftRow();
809
+ }
810
+ return result ?? "final";
811
+ };
992
812
  createDraftRow() {
993
813
  if (!this._projection) {
994
814
  return;
@@ -1025,9 +845,190 @@ var TableModel = class extends Resource2 {
1025
845
  this._draftRows.value = newDraftRows;
1026
846
  }
1027
847
  validateDraftRowData(data) {
1028
- const schema = toEffectSchema2(this._projection.baseSchema);
848
+ const schema = toEffectSchema(this._projection.baseSchema);
1029
849
  return validateSchema(schema, data) || [];
1030
850
  }
851
+ commitDraftRow = (draftRowIndex) => {
852
+ if (draftRowIndex < 0 || draftRowIndex >= this._draftRows.value.length) {
853
+ return false;
854
+ }
855
+ const draftRow = this._draftRows.value[draftRowIndex];
856
+ if (!draftRow.valid) {
857
+ return false;
858
+ }
859
+ const insertRowResult = this._onInsertRow?.(draftRow.data);
860
+ if (insertRowResult === "final") {
861
+ const newDraftRows = this._draftRows.value.filter((_, index) => index !== draftRowIndex);
862
+ this._draftRows.value = newDraftRows;
863
+ }
864
+ return insertRowResult === "final";
865
+ };
866
+ deleteRow = (rowIndex) => {
867
+ const row = this._sorting.getDataIndex(rowIndex);
868
+ const obj = this._rows.value[row];
869
+ const objectsToDelete = [];
870
+ if (this.features.selection.enabled && this._selection.hasSelection.value) {
871
+ const selectedRows = this._selection.getSelectedRows();
872
+ objectsToDelete.push(...selectedRows);
873
+ } else {
874
+ objectsToDelete.push(obj);
875
+ }
876
+ this._onDeleteRows?.(row, objectsToDelete);
877
+ };
878
+ handleRowAction = (actionId, rowIndex) => {
879
+ if (!this._onRowAction) {
880
+ return;
881
+ }
882
+ const row = this._sorting.getDataIndex(rowIndex);
883
+ const data = this._rows.value[row];
884
+ if (data) {
885
+ this._onRowAction(actionId, data);
886
+ }
887
+ };
888
+ getCellData = (cell) => {
889
+ const { col, row, plane } = cell;
890
+ const fields = this._projection?.fields ?? [];
891
+ if (col < 0 || col >= fields.length) {
892
+ return void 0;
893
+ }
894
+ const field = fields[col];
895
+ let value;
896
+ if (plane === "frozenRowsEnd") {
897
+ if (row >= 0 && row < this._draftRows.value.length) {
898
+ value = getValue2(this._draftRows.value[row].data, field.path);
899
+ } else {
900
+ return void 0;
901
+ }
902
+ } else {
903
+ const dataIndex = this._sorting.getDataIndex(row);
904
+ value = getValue2(this._rows.value[dataIndex], field.path);
905
+ }
906
+ if (value == null) {
907
+ return "";
908
+ }
909
+ const { props } = this._projection.getFieldProjection(field.id);
910
+ switch (props.format) {
911
+ case Format2.TypeFormat.Ref: {
912
+ if (!field.referencePath) {
913
+ return "";
914
+ }
915
+ return getValue2(value.target, field.referencePath);
916
+ }
917
+ default: {
918
+ return formatForEditing({
919
+ type: props.type,
920
+ format: props.format,
921
+ value
922
+ });
923
+ }
924
+ }
925
+ };
926
+ validateCellData = async ({ col, row, plane }, value) => {
927
+ const fields = this._projection?.fields ?? [];
928
+ if (col < 0 || col >= fields.length) {
929
+ return {
930
+ valid: false,
931
+ error: "Invalid column index"
932
+ };
933
+ }
934
+ const field = fields[col];
935
+ const { props } = this._projection.getFieldProjection(field.id);
936
+ const transformedValue = editorTextToCellValue(props, value);
937
+ const isDraftRow = plane === "frozenRowsEnd";
938
+ if (isDraftRow) {
939
+ const isInvalidDraftRowIndex = row < 0 || row >= this._draftRows.value.length;
940
+ if (isInvalidDraftRowIndex) {
941
+ return {
942
+ valid: false,
943
+ error: "Invalid draft row index"
944
+ };
945
+ }
946
+ const draftRow = this._draftRows.value[row];
947
+ const snapshot = {
948
+ ...draftRow.data
949
+ };
950
+ setValue(snapshot, field.path, transformedValue);
951
+ const validationErrors = this.validateDraftRowData(snapshot);
952
+ if (validationErrors.length > 0) {
953
+ const error = validationErrors.find((err) => err.path === field.path);
954
+ if (error) {
955
+ return {
956
+ valid: false,
957
+ error: error.message
958
+ };
959
+ }
960
+ }
961
+ return {
962
+ valid: true
963
+ };
964
+ } else {
965
+ const rowIdx = this._sorting.getDataIndex(row);
966
+ const currentRow = this._rows.value[rowIdx];
967
+ invariant(currentRow, "Invalid row index", {
968
+ F: __dxlog_file,
969
+ L: 516,
970
+ S: this,
971
+ A: [
972
+ "currentRow",
973
+ "'Invalid row index'"
974
+ ]
975
+ });
976
+ const snapshot = getSnapshot(currentRow);
977
+ setValue(snapshot, field.path, transformedValue);
978
+ const schema = Obj2.getSchema(currentRow);
979
+ invariant(schema, void 0, {
980
+ F: __dxlog_file,
981
+ L: 522,
982
+ S: this,
983
+ A: [
984
+ "schema",
985
+ ""
986
+ ]
987
+ });
988
+ const validationResult = validateSchema(schema, snapshot);
989
+ if (validationResult && validationResult.length > 0) {
990
+ const error = validationResult[0];
991
+ invariant(error.path === field.path, void 0, {
992
+ F: __dxlog_file,
993
+ L: 527,
994
+ S: this,
995
+ A: [
996
+ "error.path === field.path",
997
+ ""
998
+ ]
999
+ });
1000
+ return {
1001
+ valid: false,
1002
+ error: error.message
1003
+ };
1004
+ }
1005
+ return {
1006
+ valid: true
1007
+ };
1008
+ }
1009
+ };
1010
+ setCellData = (cell, value) => {
1011
+ const { col, row, plane } = cell;
1012
+ const fields = this._projection?.fields ?? [];
1013
+ if (col < 0 || col >= fields.length) {
1014
+ return;
1015
+ }
1016
+ const field = fields[col];
1017
+ const { props } = this._projection.getFieldProjection(field.id);
1018
+ const transformedValue = editorTextToCellValue(props, value);
1019
+ if (props.format === Format2.TypeFormat.Ref && !isLiveObject(value)) {
1020
+ return;
1021
+ }
1022
+ if (plane === "frozenRowsEnd") {
1023
+ if (row >= 0 && row < this._draftRows.value.length) {
1024
+ setValue(this._draftRows.value[row].data, field.path, transformedValue);
1025
+ this.validateDraftRow(row);
1026
+ }
1027
+ } else {
1028
+ const rowIdx = this._sorting.getDataIndex(row);
1029
+ setValue(this._rows.value[rowIdx], field.path, transformedValue);
1030
+ }
1031
+ };
1031
1032
  /**
1032
1033
  * Updates a cell's value using a transform function.
1033
1034
  * @param {DxGridPlanePosition} position - The position of the cell to update.
@@ -1111,14 +1112,14 @@ var TableModel = class extends Resource2 {
1111
1112
  };
1112
1113
  var editorTextToCellValue = (props, value) => {
1113
1114
  switch (props.format) {
1114
- case FormatEnum2.Ref: {
1115
+ case Format2.TypeFormat.Ref: {
1115
1116
  if (isLiveObject(value)) {
1116
- return Ref.make(value);
1117
+ return Ref2.make(value);
1117
1118
  } else {
1118
1119
  return value;
1119
1120
  }
1120
1121
  }
1121
- case FormatEnum2.SingleSelect: {
1122
+ case Format2.TypeFormat.SingleSelect: {
1122
1123
  const ids = extractTagIds(value);
1123
1124
  if (ids && ids.length > 0) {
1124
1125
  return ids[0];
@@ -1126,7 +1127,7 @@ var editorTextToCellValue = (props, value) => {
1126
1127
  return value;
1127
1128
  }
1128
1129
  }
1129
- case FormatEnum2.MultiSelect: {
1130
+ case Format2.TypeFormat.MultiSelect: {
1130
1131
  const ids = extractTagIds(value);
1131
1132
  return ids || value;
1132
1133
  }
@@ -1142,102 +1143,83 @@ var editorTextToCellValue = (props, value) => {
1142
1143
 
1143
1144
  // src/model/modal-controller.ts
1144
1145
  import { signal as signal4 } from "@preact/signals-core";
1145
- import { log } from "@dxos/log";
1146
- var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/react-ui-table/src/model/modal-controller.ts";
1147
1146
  var ModalController = class {
1148
- constructor() {
1149
- this._state = signal4({
1150
- type: "closed"
1151
- });
1152
- this._triggerRef = {
1153
- current: null
1154
- };
1155
- this.setTrigger = (trigger) => {
1156
- this._triggerRef.current = trigger;
1157
- };
1158
- this.showRowMenu = (rowIndex) => {
1159
- this._state.value = {
1160
- type: "row",
1161
- rowIndex
1162
- };
1163
- };
1164
- this.showColumnMenu = (fieldId) => {
1165
- this._state.value = {
1166
- type: "column",
1167
- fieldId
1168
- };
1169
- };
1170
- this.showColumnCreator = () => {
1171
- this._state.value = {
1172
- type: "columnSettings",
1173
- mode: {
1174
- type: "create"
1175
- }
1176
- };
1147
+ _state = signal4({
1148
+ type: "closed"
1149
+ });
1150
+ _triggerRef = {
1151
+ current: null
1152
+ };
1153
+ get state() {
1154
+ return this._state;
1155
+ }
1156
+ get trigger() {
1157
+ return this._triggerRef;
1158
+ }
1159
+ setTrigger = (trigger) => {
1160
+ this._triggerRef.current = trigger;
1161
+ };
1162
+ showRowMenu = (rowIndex) => {
1163
+ this._state.value = {
1164
+ type: "row",
1165
+ rowIndex
1177
1166
  };
1178
- this.showReferencePanel = (targetId, schemaId) => {
1179
- this._state.value = {
1180
- type: "refPanel",
1181
- targetId,
1182
- typename: schemaId
1183
- };
1167
+ };
1168
+ showColumnMenu = (fieldId) => {
1169
+ this._state.value = {
1170
+ type: "column",
1171
+ fieldId
1184
1172
  };
1185
- this.openColumnSettings = () => {
1186
- if (this._state.value.type === "column") {
1187
- const fieldId = this._state.value.fieldId;
1188
- requestAnimationFrame(() => {
1189
- this._state.value = {
1190
- type: "columnSettings",
1191
- mode: {
1192
- type: "edit",
1193
- fieldId
1194
- }
1195
- };
1196
- });
1173
+ };
1174
+ showColumnCreator = () => {
1175
+ this._state.value = {
1176
+ type: "columnSettings",
1177
+ mode: {
1178
+ type: "create"
1197
1179
  }
1198
1180
  };
1199
- this.openCreateRef = (typename, anchorCell, initialValues, onCreate) => {
1200
- if (anchorCell) {
1201
- this._triggerRef.current = anchorCell;
1181
+ };
1182
+ showReferencePanel = (targetId, schemaId) => {
1183
+ this._state.value = {
1184
+ type: "refPanel",
1185
+ targetId,
1186
+ typename: schemaId
1187
+ };
1188
+ };
1189
+ openColumnSettings = () => {
1190
+ if (this._state.value.type === "column") {
1191
+ const fieldId = this._state.value.fieldId;
1192
+ requestAnimationFrame(() => {
1202
1193
  this._state.value = {
1203
- type: "createRefPanel",
1204
- typename,
1205
- initialValues,
1206
- onCreate
1194
+ type: "columnSettings",
1195
+ mode: {
1196
+ type: "edit",
1197
+ fieldId
1198
+ }
1207
1199
  };
1208
- } else {
1209
- log.warn("anchor cell not found while creating new ref", void 0, {
1210
- F: __dxlog_file2,
1211
- L: 86,
1212
- S: this,
1213
- C: (f, a) => f(...a)
1214
- });
1215
- }
1216
- };
1217
- this.close = () => {
1218
- this._state.value = {
1219
- type: "closed"
1220
- };
1200
+ });
1201
+ }
1202
+ };
1203
+ close = () => {
1204
+ this._state.value = {
1205
+ type: "closed"
1221
1206
  };
1222
- }
1223
- get state() {
1224
- return this._state;
1225
- }
1226
- get trigger() {
1227
- return this._triggerRef;
1228
- }
1207
+ };
1229
1208
  };
1230
1209
 
1231
1210
  // src/model/table-presentation.ts
1232
1211
  import { signal as signal5 } from "@preact/signals-core";
1233
- import { isNotNullable } from "effect/Predicate";
1234
- import { Obj as Obj4 } from "@dxos/echo";
1235
- import { FormatEnum as FormatEnum3, getValue as getValue3, TypeEnum as TypeEnum2 } from "@dxos/echo-schema";
1212
+ import * as Predicate from "effect/Predicate";
1213
+ import { Obj as Obj3 } from "@dxos/echo";
1214
+ import { Format as Format3, TypeEnum as TypeEnum2, getValue as getValue3 } from "@dxos/echo/internal";
1236
1215
  import { cellClassesForFieldType, formatForDisplay as formatForDisplay2 } from "@dxos/react-ui-form";
1237
1216
  import { toPlaneCellIndex } from "@dxos/react-ui-grid";
1238
1217
  import { mx } from "@dxos/react-ui-theme";
1239
1218
  import { VIEW_FIELD_LIMIT } from "@dxos/schema";
1240
1219
  var TablePresentation = class {
1220
+ model;
1221
+ _visibleRange;
1222
+ fieldProjectionCache = /* @__PURE__ */ new Map();
1241
1223
  constructor(model, _visibleRange = signal5({
1242
1224
  start: {
1243
1225
  row: 0,
@@ -1250,7 +1232,6 @@ var TablePresentation = class {
1250
1232
  })) {
1251
1233
  this.model = model;
1252
1234
  this._visibleRange = _visibleRange;
1253
- this.fieldProjectionCache = /* @__PURE__ */ new Map();
1254
1235
  }
1255
1236
  getCells(range, plane) {
1256
1237
  this.fieldProjectionCache.clear();
@@ -1278,6 +1259,9 @@ var TablePresentation = class {
1278
1259
  case "frozenRowsEnd":
1279
1260
  cells = this.getDraftRowCells(range);
1280
1261
  break;
1262
+ case "fixedEndStart":
1263
+ cells = this.getDraftIconCells(range);
1264
+ break;
1281
1265
  case "fixedEndEnd":
1282
1266
  cells = this.getDraftActionCells(range);
1283
1267
  break;
@@ -1314,12 +1298,12 @@ var TablePresentation = class {
1314
1298
  return "";
1315
1299
  }
1316
1300
  switch (props.format) {
1317
- case FormatEnum3.Boolean:
1318
- case FormatEnum3.SingleSelect:
1319
- case FormatEnum3.MultiSelect: {
1301
+ case Format3.TypeFormat.Boolean:
1302
+ case Format3.TypeFormat.SingleSelect:
1303
+ case Format3.TypeFormat.MultiSelect: {
1320
1304
  return "";
1321
1305
  }
1322
- case FormatEnum3.Ref: {
1306
+ case Format3.TypeFormat.Ref: {
1323
1307
  if (!field.referencePath) {
1324
1308
  return "";
1325
1309
  }
@@ -1336,10 +1320,7 @@ var TablePresentation = class {
1336
1320
  }
1337
1321
  };
1338
1322
  const classes = [];
1339
- const formatClasses = cellClassesForFieldType({
1340
- type: props.type,
1341
- format: props.format
1342
- });
1323
+ const formatClasses = cellClassesForFieldType(props);
1343
1324
  if (formatClasses) {
1344
1325
  classes.push(formatClasses);
1345
1326
  }
@@ -1347,9 +1328,7 @@ var TablePresentation = class {
1347
1328
  if (rowSelectionClasses) {
1348
1329
  classes.push(rowSelectionClasses);
1349
1330
  }
1350
- if (classes.length > 0) {
1351
- cell.className = mx(classes.flat());
1352
- }
1331
+ cell.className = mx(classes);
1353
1332
  if (props.type === TypeEnum2.Array) {
1354
1333
  const targetArray = getValue3(obj, field.path);
1355
1334
  if (targetArray && Array.isArray(targetArray)) {
@@ -1371,20 +1350,20 @@ var TablePresentation = class {
1371
1350
  }
1372
1351
  return "Object";
1373
1352
  };
1374
- const tags = targetArray.map(getLabel).filter(isNotNullable).map((title) => {
1353
+ const tags = targetArray.map(getLabel).filter(Predicate.isNotNullable).map((title) => {
1375
1354
  return `<span class="dx-tag" data-hue="neutral">${title}</span>`;
1376
1355
  }).join("");
1377
1356
  cell.accessoryHtml = `<div role='none' class="flex flex-row gap-1 overflow-x-auto">${tags}</div>`;
1378
1357
  }
1379
1358
  }
1380
- if (props.format === FormatEnum3.Ref && props.referenceSchema) {
1359
+ if (props.format === Format3.TypeFormat.Ref && props.referenceSchema) {
1381
1360
  const targetObj = getValue3(obj, field.path)?.target;
1382
1361
  if (targetObj) {
1383
- const dxn = Obj4.getDXN(targetObj)?.toString();
1384
- cell.accessoryHtml = `<dx-ref-tag refId=${dxn} class="dx-button is-6 pli-[3px] pbe-[2px] min-bs-0 absolute inline-end-1"><dx-icon icon="ph--link-simple--regular"/></dx-ref-tag>`;
1362
+ const dxn = Obj3.getDXN(targetObj)?.toString();
1363
+ cell.accessoryHtml = `<div role="none" class="absolute inline-end-0 inset-block-0 p-[--dx-grid-cell-content-padding-block]"><dx-anchor refId=${dxn} class="dx-button is-6 aspect-square min-bs-0" data-dx-grid-action="accessory"><dx-icon icon="ph--link-simple--regular"/></dx-anchor></div>`;
1385
1364
  }
1386
1365
  }
1387
- if (props.format === FormatEnum3.Boolean) {
1366
+ if (props.format === Format3.TypeFormat.Boolean) {
1388
1367
  const value = getValue3(obj, field.path);
1389
1368
  cell.accessoryHtml = tableControls.switch.render({
1390
1369
  colIndex,
@@ -1393,7 +1372,7 @@ var TablePresentation = class {
1393
1372
  });
1394
1373
  cell.readonly = "no-text-select";
1395
1374
  }
1396
- if (props.format === FormatEnum3.SingleSelect) {
1375
+ if (props.format === Format3.TypeFormat.SingleSelect) {
1397
1376
  const value = getValue3(obj, field.path);
1398
1377
  const options = this.model.projection.getFieldProjection(field.id).props.options;
1399
1378
  if (options) {
@@ -1403,7 +1382,7 @@ var TablePresentation = class {
1403
1382
  }
1404
1383
  }
1405
1384
  }
1406
- if (props.format === FormatEnum3.MultiSelect) {
1385
+ if (props.format === Format3.TypeFormat.MultiSelect) {
1407
1386
  const values = getValue3(obj, field.path);
1408
1387
  const options = this.model.projection.getFieldProjection(field.id).props.options;
1409
1388
  if (options && values && values.length > 0) {
@@ -1443,24 +1422,37 @@ var TablePresentation = class {
1443
1422
  const cells = {};
1444
1423
  const fields = this.model.projection?.fields ?? [];
1445
1424
  const draftRows = this.model.draftRows.value;
1446
- for (let row = range.start.row; row <= range.end.row && row < draftRows.length; row++) {
1447
- const draftRow = draftRows[row];
1425
+ if (draftRows.length === 0) {
1448
1426
  for (let col = range.start.col; col <= range.end.col && col < fields.length; col++) {
1449
- const field = fields[col];
1450
- if (!field) {
1451
- continue;
1452
- }
1453
- this.createDataCell(cells, draftRow.data, field, col, row);
1454
- if (this.model.hasDraftRowValidationError(row, field.path)) {
1427
+ cells[toPlaneCellIndex({
1428
+ col,
1429
+ row: 0
1430
+ })] = {
1431
+ value: "",
1432
+ readonly: true,
1433
+ className: "dx-grid__row--cta__cell"
1434
+ };
1435
+ }
1436
+ } else {
1437
+ for (let row = range.start.row; row <= range.end.row && row < draftRows.length; row++) {
1438
+ const draftRow = draftRows[row];
1439
+ for (let col = range.start.col; col <= range.end.col && col < fields.length; col++) {
1455
1440
  const cellIndex = toPlaneCellIndex({
1456
1441
  col,
1457
1442
  row
1458
1443
  });
1459
- const cellValue = cells[cellIndex];
1460
- if (cellValue) {
1461
- const existingClasses = cellValue.className || "";
1462
- const draftClasses = "dx-grid__cell--flagged";
1463
- cellValue.className = existingClasses ? `${existingClasses} ${draftClasses}` : draftClasses;
1444
+ const field = fields[col];
1445
+ if (!field) {
1446
+ continue;
1447
+ }
1448
+ this.createDataCell(cells, draftRow.data, field, col, row);
1449
+ if (this.model.hasDraftRowValidationError(row, field.path)) {
1450
+ const cellValue = cells[cellIndex];
1451
+ if (cellValue) {
1452
+ const existingClasses = cellValue.className || "";
1453
+ const draftClasses = "dx-grid__cell--flagged";
1454
+ cellValue.className = existingClasses ? `${existingClasses} ${draftClasses}` : draftClasses;
1455
+ }
1464
1456
  }
1465
1457
  }
1466
1458
  }
@@ -1479,10 +1471,10 @@ var TablePresentation = class {
1479
1471
  row: 0
1480
1472
  })] = {
1481
1473
  // TODO(burdon): Use same logic as form for fallback title.
1482
- value: props.title ?? field.path,
1483
- readonly: true,
1474
+ value: "",
1484
1475
  resizeHandle: "col",
1485
1476
  accessoryHtml: `
1477
+ <span class="grow min-is-0 truncate">${props.title ?? field.path}</span>
1486
1478
  ${direction !== void 0 ? tableButtons.sort.render({
1487
1479
  fieldId: field.id,
1488
1480
  direction
@@ -1491,7 +1483,7 @@ var TablePresentation = class {
1491
1483
  fieldId: field.id
1492
1484
  })}
1493
1485
  `,
1494
- className: "!bg-toolbarSurface"
1486
+ className: "!bg-toolbarSurface !text-description [&>div]:flex [&>div]:items-stretch"
1495
1487
  };
1496
1488
  }
1497
1489
  return cells;
@@ -1582,19 +1574,46 @@ var TablePresentation = class {
1582
1574
  getDraftActionCells(range) {
1583
1575
  const cells = {};
1584
1576
  const draftRows = this.model.draftRows.value;
1585
- for (let row = range.start.row; row <= range.end.row && row < draftRows.length; row++) {
1586
- const draftRow = draftRows[row];
1587
- const disabled = !draftRow.valid;
1577
+ if (draftRows.length === 0) {
1578
+ cells[toPlaneCellIndex({
1579
+ col: 0,
1580
+ row: 0
1581
+ })] = {
1582
+ value: "",
1583
+ className: "dx-grid__row--cta__cell",
1584
+ readonly: true
1585
+ };
1586
+ } else {
1587
+ for (let row = range.start.row; row <= range.end.row && row < draftRows.length; row++) {
1588
+ const draftRow = draftRows[row];
1589
+ const disabled = !draftRow.valid;
1590
+ cells[toPlaneCellIndex({
1591
+ col: 0,
1592
+ row
1593
+ })] = {
1594
+ value: "",
1595
+ readonly: true,
1596
+ accessoryHtml: tableButtons.saveDraftRow.render({
1597
+ rowIndex: row,
1598
+ disabled
1599
+ })
1600
+ };
1601
+ }
1602
+ }
1603
+ return cells;
1604
+ }
1605
+ getDraftIconCells(range) {
1606
+ const cells = {};
1607
+ const draftRows = this.model.draftRows.value;
1608
+ for (let row = range.start.row; row <= range.end.row; row++) {
1588
1609
  cells[toPlaneCellIndex({
1589
1610
  col: 0,
1590
1611
  row
1591
1612
  })] = {
1592
1613
  value: "",
1593
1614
  readonly: true,
1594
- accessoryHtml: tableButtons.saveDraftRow.render({
1595
- rowIndex: row,
1596
- disabled
1597
- })
1615
+ accessoryHtml: '<dx-icon icon="ph--plus--regular" class="contents"></dx-icon>',
1616
+ className: mx("[&>div]:grid [&>div]:place-content-center", draftRows.length < 1 && "dx-grid__row--cta__cell")
1598
1617
  };
1599
1618
  }
1600
1619
  return cells;
@@ -1622,31 +1641,65 @@ var cellClassesForRowSelection = (selected, selectionMode) => {
1622
1641
  }
1623
1642
  };
1624
1643
 
1644
+ // src/hooks/useAddRow.ts
1645
+ import { useCallback } from "react";
1646
+ import { Obj as Obj4 } from "@dxos/echo";
1647
+ var useAddRow = ({ space, schema }) => {
1648
+ return useCallback((data) => {
1649
+ if (space && schema) {
1650
+ try {
1651
+ space.db.add(Obj4.make(schema, data ?? {}));
1652
+ return "final";
1653
+ } catch (error) {
1654
+ return "draft";
1655
+ }
1656
+ }
1657
+ return "final";
1658
+ }, [
1659
+ space,
1660
+ schema
1661
+ ]);
1662
+ };
1663
+
1664
+ // src/hooks/useProjectionModel.ts
1665
+ import { useMemo } from "react";
1666
+ import { Type as Type2 } from "@dxos/echo";
1667
+ import { ProjectionModel as ProjectionModel2 } from "@dxos/schema";
1668
+ var useProjectionModel = (schema, table) => useMemo(() => {
1669
+ if (schema && table?.view.target?.projection) {
1670
+ const projection = new ProjectionModel2(Type2.toJsonSchema(schema), table.view.target.projection);
1671
+ projection.normalizeView();
1672
+ return projection;
1673
+ }
1674
+ }, [
1675
+ schema,
1676
+ table?.view.target?.projection
1677
+ ]);
1678
+
1625
1679
  // src/hooks/useTableModel.ts
1626
1680
  import { useSignals as _useSignals } from "@preact-signals/safe-react/tracking";
1627
1681
  import { effect as effect3 } from "@preact/signals-core";
1628
1682
  import orderBy2 from "lodash.orderby";
1629
- import { useEffect, useMemo, useState } from "react";
1630
- import { fullyQualifiedId as fullyQualifiedId2 } from "@dxos/react-client/echo";
1683
+ import { useEffect, useMemo as useMemo2, useState } from "react";
1684
+ import { Obj as Obj5 } from "@dxos/echo";
1631
1685
  import { useSelected, useSelectionActions } from "@dxos/react-ui-attention";
1632
1686
  import { isNonNullable } from "@dxos/util";
1633
- var useTableModel = ({ view, schema, projection, rows, rowActions, features, onSelectionChanged, onRowAction, ...props }) => {
1687
+ var useTableModel = ({ object, projection, rows, rowActions, features, onSelectionChanged, onRowAction, ...props }) => {
1634
1688
  var _effect = _useSignals();
1635
1689
  try {
1636
- const selected = useSelected(view && fullyQualifiedId2(view), "multi");
1637
- const initialSelection = useMemo(() => selected, [
1638
- view
1690
+ const selected = useSelected(object && Obj5.getDXN(object).toString(), "multi");
1691
+ const initialSelection = useMemo2(() => selected, [
1692
+ object
1639
1693
  ]);
1640
1694
  const [model, setModel] = useState();
1641
1695
  useEffect(() => {
1642
- if (!view || !schema) {
1696
+ if (!object || !projection) {
1643
1697
  return;
1644
1698
  }
1645
1699
  let model2;
1646
1700
  const t = setTimeout(async () => {
1647
1701
  model2 = new TableModel({
1648
- view,
1649
- schema,
1702
+ object,
1650
1703
  projection,
1651
1704
  features,
1652
1705
  rowActions,
@@ -1662,8 +1715,7 @@ var useTableModel = ({ view, schema, projection, rows, rowActions, features, onS
1662
1715
  void model2?.close();
1663
1716
  };
1664
1717
  }, [
1665
- view,
1666
- schema,
1718
+ object,
1667
1719
  projection,
1668
1720
  features,
1669
1721
  rowActions,
@@ -1710,31 +1762,10 @@ var useTableModel = ({ view, schema, projection, rows, rowActions, features, onS
1710
1762
  }
1711
1763
  };
1712
1764
 
1713
- // src/hooks/useAddRow.ts
1714
- import { useCallback } from "react";
1715
- import { Obj as Obj5 } from "@dxos/echo";
1716
- var useAddRow = ({ space, schema }) => {
1717
- return useCallback((data) => {
1718
- if (space && schema) {
1719
- try {
1720
- space.db.add(Obj5.make(schema, data ?? {}));
1721
- return true;
1722
- } catch (error) {
1723
- return false;
1724
- }
1725
- }
1726
- return false;
1727
- }, [
1728
- space,
1729
- schema
1730
- ]);
1731
- };
1732
-
1733
1765
  export {
1734
1766
  getBaseSchema,
1735
1767
  makeDynamicTable,
1736
1768
  touch,
1737
- createTable,
1738
1769
  BUTTON_IDENTIFIERS,
1739
1770
  tableButtons,
1740
1771
  CONTROL_IDENTIFIERS,
@@ -1746,7 +1777,8 @@ export {
1746
1777
  ModalController,
1747
1778
  TablePresentation,
1748
1779
  cellClassesForRowSelection,
1749
- useTableModel,
1750
- useAddRow
1780
+ useAddRow,
1781
+ useProjectionModel,
1782
+ useTableModel
1751
1783
  };
1752
- //# sourceMappingURL=chunk-Y66YLSTC.mjs.map
1784
+ //# sourceMappingURL=chunk-P73ALX3N.mjs.map