@dxos/react-ui-table 0.8.4-main.c1de068 → 0.8.4-main.c4373fc

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 (130) hide show
  1. package/dist/lib/browser/chunk-4K7JPALT.mjs +66 -0
  2. package/dist/lib/browser/chunk-4K7JPALT.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-5XLSHLOG.mjs → chunk-OZTXLZGM.mjs} +544 -491
  4. package/dist/lib/browser/chunk-OZTXLZGM.mjs.map +7 -0
  5. package/dist/lib/browser/index.mjs +590 -675
  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 +13 -8
  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-MK6OVUF6.mjs +67 -0
  12. package/dist/lib/node-esm/chunk-MK6OVUF6.mjs.map +7 -0
  13. package/dist/lib/node-esm/{chunk-Y66YLSTC.mjs → chunk-S56Z4V4X.mjs} +544 -491
  14. package/dist/lib/node-esm/chunk-S56Z4V4X.mjs.map +7 -0
  15. package/dist/lib/node-esm/index.mjs +590 -675
  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 +13 -8
  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 +1 -1
  22. package/dist/types/src/components/Table/ColumnActionsMenu.d.ts.map +1 -1
  23. package/dist/types/src/components/Table/ColumnSettings.d.ts +1 -1
  24. package/dist/types/src/components/Table/ColumnSettings.d.ts.map +1 -1
  25. package/dist/types/src/components/Table/DynamicTable.d.ts +2 -2
  26. package/dist/types/src/components/Table/DynamicTable.d.ts.map +1 -1
  27. package/dist/types/src/components/Table/DynamicTable.stories.d.ts +51 -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 +108 -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 +8 -4
  34. package/dist/types/src/components/Table/Table.d.ts.map +1 -1
  35. package/dist/types/src/components/Table/Table.stories.d.ts +42 -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.map +1 -1
  38. package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts +12 -6
  39. package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts.map +1 -1
  40. package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts +12 -17
  41. package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts.map +1 -1
  42. package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts +39 -4
  43. package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts.map +1 -1
  44. package/dist/types/src/components/TableCellEditor/index.d.ts +1 -0
  45. package/dist/types/src/components/TableCellEditor/index.d.ts.map +1 -1
  46. package/dist/types/src/components/TableToolbar/TableToolbar.d.ts.map +1 -1
  47. package/dist/types/src/components/testing.d.ts +3 -3
  48. package/dist/types/src/components/testing.d.ts.map +1 -1
  49. package/dist/types/src/hooks/useAddRow.d.ts +3 -2
  50. package/dist/types/src/hooks/useAddRow.d.ts.map +1 -1
  51. package/dist/types/src/hooks/useTableModel.d.ts +2 -2
  52. package/dist/types/src/hooks/useTableModel.d.ts.map +1 -1
  53. package/dist/types/src/model/modal-controller.d.ts +0 -7
  54. package/dist/types/src/model/modal-controller.d.ts.map +1 -1
  55. package/dist/types/src/model/selection-model.d.ts.map +1 -1
  56. package/dist/types/src/model/table-model.d.ts +9 -7
  57. package/dist/types/src/model/table-model.d.ts.map +1 -1
  58. package/dist/types/src/model/table-presentation.d.ts +2 -1
  59. package/dist/types/src/model/table-presentation.d.ts.map +1 -1
  60. package/dist/types/src/model/table-sorting.d.ts +2 -3
  61. package/dist/types/src/model/table-sorting.d.ts.map +1 -1
  62. package/dist/types/src/testing/useTestTableModel.d.ts +3 -22
  63. package/dist/types/src/testing/useTestTableModel.d.ts.map +1 -1
  64. package/dist/types/src/translations.d.ts +2 -2
  65. package/dist/types/src/types/index.d.ts +1 -1
  66. package/dist/types/src/types/index.d.ts.map +1 -1
  67. package/dist/types/src/types/schema.d.ts +25 -5
  68. package/dist/types/src/types/schema.d.ts.map +1 -1
  69. package/dist/types/src/util/dynamic-table.d.ts +4 -5
  70. package/dist/types/src/util/dynamic-table.d.ts.map +1 -1
  71. package/dist/types/src/util/index.d.ts +0 -1
  72. package/dist/types/src/util/index.d.ts.map +1 -1
  73. package/dist/types/src/util/schema.d.ts +1 -1
  74. package/dist/types/src/util/schema.d.ts.map +1 -1
  75. package/dist/types/src/util/table-buttons.d.ts.map +1 -1
  76. package/dist/types/src/util/table-controls.d.ts.map +1 -1
  77. package/dist/types/tsconfig.tsbuildinfo +1 -1
  78. package/package.json +55 -50
  79. package/src/components/Table/ColumnActionsMenu.tsx +1 -1
  80. package/src/components/Table/ColumnSettings.tsx +1 -1
  81. package/src/components/Table/DynamicTable.stories.tsx +15 -11
  82. package/src/components/Table/DynamicTable.tsx +8 -10
  83. package/src/components/Table/Relations.stories.tsx +248 -0
  84. package/src/components/Table/RowActionsMenu.tsx +3 -3
  85. package/src/components/Table/Table.stories.tsx +66 -54
  86. package/src/components/Table/Table.tsx +147 -117
  87. package/src/components/TableCellEditor/CellValidationMessage.tsx +1 -1
  88. package/src/components/TableCellEditor/FormCellEditor.tsx +153 -42
  89. package/src/components/TableCellEditor/TableCellEditor.stories.tsx +24 -64
  90. package/src/components/TableCellEditor/TableCellEditor.tsx +74 -224
  91. package/src/components/TableCellEditor/index.ts +1 -0
  92. package/src/components/TableToolbar/TableToolbar.tsx +2 -2
  93. package/src/components/testing.ts +2 -2
  94. package/src/hooks/useAddRow.ts +7 -5
  95. package/src/hooks/useTableModel.ts +2 -2
  96. package/src/model/modal-controller.ts +1 -29
  97. package/src/model/selection-model.ts +3 -2
  98. package/src/model/table-model.test.ts +19 -10
  99. package/src/model/table-model.ts +37 -25
  100. package/src/model/table-presentation.test.ts +23 -21
  101. package/src/model/table-presentation.ts +74 -33
  102. package/src/model/table-sorting.ts +16 -7
  103. package/src/playwright/smoke.spec.ts +129 -37
  104. package/src/testing/useTestTableModel.ts +11 -7
  105. package/src/translations.ts +2 -2
  106. package/src/types/index.ts +1 -1
  107. package/src/types/schema.ts +63 -6
  108. package/src/util/dynamic-table.ts +13 -13
  109. package/src/util/index.ts +0 -1
  110. package/src/util/schema.ts +4 -4
  111. package/src/util/table-buttons.ts +4 -3
  112. package/src/util/table-controls.ts +4 -1
  113. package/dist/lib/browser/chunk-5XLSHLOG.mjs.map +0 -7
  114. package/dist/lib/browser/chunk-L2LSB6KV.mjs +0 -18
  115. package/dist/lib/browser/chunk-L2LSB6KV.mjs.map +0 -7
  116. package/dist/lib/node-esm/chunk-NXZ4CJYX.mjs +0 -20
  117. package/dist/lib/node-esm/chunk-NXZ4CJYX.mjs.map +0 -7
  118. package/dist/lib/node-esm/chunk-Y66YLSTC.mjs.map +0 -7
  119. package/dist/types/src/components/Table/CreateRefPanel.d.ts +0 -9
  120. package/dist/types/src/components/Table/CreateRefPanel.d.ts.map +0 -1
  121. package/dist/types/src/components/Table/relations.stories.d.ts +0 -9
  122. package/dist/types/src/components/Table/relations.stories.d.ts.map +0 -1
  123. package/dist/types/src/components/TableCellEditor/extension.d.ts +0 -13
  124. package/dist/types/src/components/TableCellEditor/extension.d.ts.map +0 -1
  125. package/dist/types/src/util/table.d.ts +0 -11
  126. package/dist/types/src/util/table.d.ts.map +0 -1
  127. package/src/components/Table/CreateRefPanel.tsx +0 -86
  128. package/src/components/Table/relations.stories.tsx +0 -116
  129. package/src/components/TableCellEditor/extension.ts +0 -61
  130. package/src/util/table.ts +0 -49
@@ -1,11 +1,11 @@
1
1
  import {
2
- TableView
3
- } from "./chunk-L2LSB6KV.mjs";
2
+ schema_exports
3
+ } from "./chunk-4K7JPALT.mjs";
4
4
 
5
5
  // src/util/dynamic-table.ts
6
- import { Obj } from "@dxos/echo";
7
- import { getTypename, toJsonSchema } from "@dxos/echo-schema";
8
- import { createView, getSchemaFromPropertyDefinitions, ProjectionModel } from "@dxos/schema";
6
+ import { Filter, Obj, Query } from "@dxos/echo";
7
+ import { getTypename, toJsonSchema } from "@dxos/echo/internal";
8
+ import { ProjectionModel, createView, getSchemaFromPropertyDefinitions } from "@dxos/schema";
9
9
  var getBaseSchema = ({ typename, properties, jsonSchema, schema }) => {
10
10
  if (typename && properties) {
11
11
  const schema2 = getSchemaFromPropertyDefinitions(typename, properties);
@@ -27,12 +27,12 @@ var getBaseSchema = ({ typename, properties, jsonSchema, schema }) => {
27
27
  throw new Error("invalid properties");
28
28
  }
29
29
  };
30
- var makeDynamicTable = ({ typename, jsonSchema, properties }) => {
31
- const table = Obj.make(TableView, {
30
+ var makeDynamicTable = ({ jsonSchema, properties }) => {
31
+ const table = Obj.make(schema_exports.Table, {
32
32
  sizes: {}
33
33
  });
34
34
  const view = createView({
35
- typename,
35
+ query: Query.select(Filter.everything()),
36
36
  jsonSchema,
37
37
  presentation: table,
38
38
  ...properties && {
@@ -40,6 +40,7 @@ var makeDynamicTable = ({ typename, jsonSchema, properties }) => {
40
40
  }
41
41
  });
42
42
  const projection = new ProjectionModel(jsonSchema, view.projection);
43
+ projection.normalizeView();
43
44
  if (properties && projection.fields) {
44
45
  setProperties(view, projection, table, properties);
45
46
  }
@@ -67,7 +68,7 @@ var setProperties = (view, projection, table, properties) => {
67
68
  }
68
69
  if (property.sort) {
69
70
  const fieldId = field.id;
70
- view.query.sort = [
71
+ view.sort = [
71
72
  {
72
73
  fieldId,
73
74
  direction: property.sort
@@ -81,40 +82,6 @@ var setProperties = (view, projection, table, properties) => {
81
82
  // src/util/signals.ts
82
83
  var touch = (value) => value;
83
84
 
84
- // src/util/table.ts
85
- import { Match } from "effect";
86
- import { Obj as Obj2 } from "@dxos/echo";
87
- import { toEffectSchema } from "@dxos/echo-schema";
88
- import { createViewFromSpace, getSchemaProperties } from "@dxos/schema";
89
- var createTable = async ({ sizes, ...props }) => {
90
- const table = Obj2.make(TableView, {
91
- sizes: {}
92
- });
93
- const { jsonSchema, view } = await createViewFromSpace({
94
- ...props,
95
- presentation: table
96
- });
97
- const schema = toEffectSchema(jsonSchema);
98
- const shouldIncludeId = props.fields?.find((field) => field === "id") !== void 0;
99
- const properties = getSchemaProperties(schema.ast, {}, shouldIncludeId);
100
- for (const property of properties) {
101
- if (sizes?.[property.name]) {
102
- table.sizes[property.name] = sizes[property.name];
103
- continue;
104
- }
105
- Match.type().pipe(Match.when("boolean", () => {
106
- table.sizes[property.name] = 100;
107
- }), Match.when("number", () => {
108
- table.sizes[property.name] = 100;
109
- }), Match.orElse(() => {
110
- }))(property.type);
111
- }
112
- return {
113
- jsonSchema,
114
- view
115
- };
116
- };
117
-
118
85
  // src/util/table-buttons.ts
119
86
  var BUTTON_IDENTIFIERS = {
120
87
  columnSettings: "data-table-column-settings-button",
@@ -124,10 +91,9 @@ var BUTTON_IDENTIFIERS = {
124
91
  saveDraftRow: "data-table-save-draft-row-button",
125
92
  sort: "data-table-sort-button"
126
93
  };
127
- var createButton = ({ attr, data, disabled = false, icon, testId, type = "primary" }) => {
94
+ var createButton = ({ attr, data, disabled = false, icon, testId, type: _type = "primary" }) => {
128
95
  const dataAttrs = Object.entries(data).map(([k, v]) => `${k}="${v}"`).join(" ");
129
- const positionClass = type === "primary" ? "inline-end-2" : "inline-end-9";
130
- 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>`;
131
97
  };
132
98
  var addColumnButton = {
133
99
  attr: BUTTON_IDENTIFIERS.newColumn,
@@ -153,7 +119,8 @@ var columnSettingsButton = {
153
119
  attr: BUTTON_IDENTIFIERS.columnSettings,
154
120
  icon: columnSettingsButton.icon,
155
121
  data: {
156
- "data-field-id": fieldId
122
+ "data-field-id": fieldId,
123
+ "data-variant": "ghost"
157
124
  },
158
125
  testId: "table-column-settings-button"
159
126
  });
@@ -213,7 +180,8 @@ var saveDraftRowButton = {
213
180
  icon: saveDraftRowButton.icon,
214
181
  disabled,
215
182
  data: {
216
- "data-row-index": rowIndex.toString()
183
+ "data-row-index": rowIndex.toString(),
184
+ "data-variant": "primary"
217
185
  },
218
186
  testId: "table-save-draft-row-button"
219
187
  });
@@ -232,6 +200,7 @@ var tableButtons = {
232
200
  };
233
201
 
234
202
  // src/util/table-controls.ts
203
+ import { accessoryHandlesPointerdownAttrs } from "@dxos/lit-grid";
235
204
  var CONTROL_IDENTIFIERS = {
236
205
  checkbox: "data-table-checkbox",
237
206
  switch: "data-table-switch"
@@ -244,7 +213,7 @@ var renderAttributes = (data) => {
244
213
  return Object.entries(data).map(([k, v]) => `${k}="${v}"`).join(" ");
245
214
  };
246
215
  var renderInput = (baseClass, attrs, checked = false, disabled = false, preventToggle = false, testId) => {
247
- 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"/>`;
248
217
  };
249
218
  var CheckboxStory = ({ rowIndex, header = false, checked = false, disabled = false }) => {
250
219
  const attrs = {
@@ -260,7 +229,8 @@ var SwitchStory = ({ colIndex, rowIndex, checked = false, disabled = false }) =>
260
229
  const attrs = {
261
230
  [CONTROL_IDENTIFIERS.switch]: "",
262
231
  "data-row-index": rowIndex.toString(),
263
- "data-col-index": colIndex.toString()
232
+ "data-col-index": colIndex.toString(),
233
+ ...accessoryHandlesPointerdownAttrs
264
234
  };
265
235
  return renderInput(BASE_CLASSES.switch, attrs, checked, disabled, true, "table-switch");
266
236
  };
@@ -286,14 +256,14 @@ var tableControls = {
286
256
  };
287
257
 
288
258
  // src/util/schema.ts
289
- import { Schema } from "effect";
290
- import { isTypeLiteral, TypeLiteral } from "effect/SchemaAST";
259
+ import * as Schema from "effect/Schema";
260
+ import * as SchemaAST from "effect/SchemaAST";
291
261
  var narrowSchema = (schema, paths) => {
292
262
  const ast = schema?.ast;
293
- if (isTypeLiteral(ast)) {
263
+ if (SchemaAST.isTypeLiteral(ast)) {
294
264
  const propertySignatures = ast.propertySignatures.filter((signature) => paths.includes(signature.name.toString()));
295
265
  if (propertySignatures.length > 0) {
296
- const narrowType = new TypeLiteral(propertySignatures, []);
266
+ const narrowType = new SchemaAST.TypeLiteral(propertySignatures, []);
297
267
  return Schema.make(narrowType);
298
268
  }
299
269
  }
@@ -303,21 +273,75 @@ var narrowSchema = (schema, paths) => {
303
273
  // src/model/table-model.ts
304
274
  import { computed as computed3, effect as effect2, signal as signal3 } from "@preact/signals-core";
305
275
  import { Resource as Resource2 } from "@dxos/context";
306
- import { Obj as Obj3, Ref } from "@dxos/echo";
307
- import { FormatEnum as FormatEnum2, getValue as getValue2, setValue, getSnapshot, getSchema, toEffectSchema as toEffectSchema2 } from "@dxos/echo-schema";
276
+ import { Obj as Obj2, Ref } from "@dxos/echo";
277
+ import { FormatEnum as FormatEnum2, getSchema, getValue as getValue2, setValue, toEffectSchema } from "@dxos/echo/internal";
308
278
  import { invariant } from "@dxos/invariant";
309
279
  import { ObjectId } from "@dxos/keys";
310
- import { isLiveObject } from "@dxos/live-object";
280
+ import { getSnapshot, isLiveObject } from "@dxos/live-object";
311
281
  import { fullyQualifiedId } from "@dxos/react-client/echo";
312
282
  import { formatForEditing, parseValue } from "@dxos/react-ui-form";
313
283
  import { ProjectionModel as ProjectionModel2, validateSchema } from "@dxos/schema";
314
284
 
285
+ // src/util/tag.ts
286
+ var TAG_PATTERN_REGEX = /\[([^\]]+)\]\(([^)]+)\)/g;
287
+ var extractTagIds = (value) => {
288
+ if (typeof value !== "string") {
289
+ return void 0;
290
+ }
291
+ const ids = [];
292
+ let match;
293
+ while ((match = TAG_PATTERN_REGEX.exec(value)) !== null) {
294
+ if (match[2]) {
295
+ ids.push(match[2]);
296
+ }
297
+ }
298
+ return ids.length > 0 ? ids : void 0;
299
+ };
300
+
315
301
  // src/model/selection-model.ts
316
302
  import { computed, effect, signal } from "@preact/signals-core";
317
303
  import { Resource } from "@dxos/context";
304
+ function _define_property(obj, key, value) {
305
+ if (key in obj) {
306
+ Object.defineProperty(obj, key, {
307
+ value,
308
+ enumerable: true,
309
+ configurable: true,
310
+ writable: true
311
+ });
312
+ } else {
313
+ obj[key] = value;
314
+ }
315
+ return obj;
316
+ }
318
317
  var SelectionModel = class extends Resource {
318
+ async _open() {
319
+ const selectionWatcher = effect(() => {
320
+ touch(this._selection.value);
321
+ this._onSelectionChanged?.();
322
+ });
323
+ this._ctx.onDispose(selectionWatcher);
324
+ }
325
+ //
326
+ // Getters
327
+ //
328
+ get selection() {
329
+ return this._selection;
330
+ }
331
+ get hasSelection() {
332
+ return this._hasSelection;
333
+ }
334
+ get allRowsSeleted() {
335
+ return this._allSelected;
336
+ }
337
+ get selectionMode() {
338
+ return this._selectionMode;
339
+ }
319
340
  constructor(_rows, _selectionMode, _initialSelection, _onSelectionChanged) {
320
- super(), this._rows = _rows, this._selectionMode = _selectionMode, this._initialSelection = _initialSelection, this._onSelectionChanged = _onSelectionChanged, this._validSelectedIds = computed(() => {
341
+ super(), _define_property(this, "_rows", void 0), _define_property(this, "_selectionMode", void 0), _define_property(this, "_initialSelection", void 0), _define_property(this, "_onSelectionChanged", void 0), _define_property(this, "_selection", void 0), _define_property(this, "_validSelectedIds", void 0), _define_property(this, "_hasSelection", void 0), _define_property(this, "_allSelected", void 0), _define_property(this, "getSelectedRows", void 0), _define_property(this, "isRowIndexSelected", void 0), _define_property(this, "isObjectSelected", void 0), //
342
+ // Manipulation
343
+ //
344
+ _define_property(this, "toggleSelectionForRowIndex", void 0), _define_property(this, "setSelection", void 0), this._rows = _rows, this._selectionMode = _selectionMode, this._initialSelection = _initialSelection, this._onSelectionChanged = _onSelectionChanged, this._validSelectedIds = computed(() => {
321
345
  const rows = this._rows.value;
322
346
  if (!rows) {
323
347
  return /* @__PURE__ */ new Set();
@@ -366,58 +390,27 @@ var SelectionModel = class extends Resource {
366
390
  };
367
391
  this._selection = signal(new Set(this._initialSelection));
368
392
  }
369
- async _open() {
370
- const selectionWatcher = effect(() => {
371
- touch(this._selection.value);
372
- this._onSelectionChanged?.();
373
- });
374
- this._ctx.onDispose(selectionWatcher);
375
- }
376
- //
377
- // Getters
378
- //
379
- get selection() {
380
- return this._selection;
381
- }
382
- get hasSelection() {
383
- return this._hasSelection;
384
- }
385
- get allRowsSeleted() {
386
- return this._allSelected;
387
- }
388
- get selectionMode() {
389
- return this._selectionMode;
390
- }
391
393
  };
392
394
 
393
395
  // src/model/table-sorting.ts
394
396
  import { computed as computed2, signal as signal2 } from "@preact/signals-core";
395
397
  import orderBy from "lodash.orderby";
396
- import { getValue, FormatEnum, TypeEnum } from "@dxos/echo-schema";
398
+ import { FormatEnum, TypeEnum, getValue } from "@dxos/echo/internal";
397
399
  import { formatForDisplay } from "@dxos/react-ui-form";
398
- var TableSorting = class {
399
- constructor(rows, _view, _projection) {
400
- this._view = _view;
401
- this._projection = _projection;
402
- this._displayToDataIndex = /* @__PURE__ */ new Map();
403
- this._localSort = signal2(void 0);
404
- this._rows = rows;
405
- this._isDirty = computed2(() => {
406
- const local = this._localSort.value;
407
- const viewSort = this._view.query.sort?.[0];
408
- if (local?.type === "cleared") {
409
- return viewSort !== void 0;
410
- }
411
- if (local?.type === "active") {
412
- if (!viewSort) {
413
- return true;
414
- }
415
- return local.sort.fieldId !== viewSort.fieldId || local.sort.direction !== viewSort.direction;
416
- }
417
- return false;
400
+ function _define_property2(obj, key, value) {
401
+ if (key in obj) {
402
+ Object.defineProperty(obj, key, {
403
+ value,
404
+ enumerable: true,
405
+ configurable: true,
406
+ writable: true
418
407
  });
419
- this.sortedRows = this.initialiseSortedRows();
408
+ } else {
409
+ obj[key] = value;
420
410
  }
411
+ return obj;
412
+ }
413
+ var TableSorting = class {
421
414
  /**
422
415
  * @reactive
423
416
  * @returns Local sort if present, falls back to view sort.
@@ -430,7 +423,7 @@ var TableSorting = class {
430
423
  if (local?.type === "active") {
431
424
  return local.sort;
432
425
  }
433
- return this._view.query.sort?.[0];
426
+ return this._view.sort?.[0];
434
427
  }
435
428
  /**
436
429
  * @reactive
@@ -474,11 +467,11 @@ var TableSorting = class {
474
467
  save() {
475
468
  if (this._localSort.value !== void 0) {
476
469
  if (this._localSort.value.type === "active") {
477
- this._view.query.sort = [
470
+ this._view.sort = [
478
471
  this._localSort.value.sort
479
472
  ];
480
473
  } else {
481
- this._view.query.sort = [];
474
+ this._view.sort = [];
482
475
  }
483
476
  this._localSort.value = void 0;
484
477
  }
@@ -553,25 +546,51 @@ var TableSorting = class {
553
546
  value
554
547
  });
555
548
  }
556
- };
557
-
558
- // src/util/tag.ts
559
- var TAG_PATTERN_REGEX = /\[([^\]]+)\]\(([^)]+)\)/g;
560
- var extractTagIds = (value) => {
561
- if (typeof value !== "string") {
562
- return void 0;
563
- }
564
- const ids = [];
565
- let match;
566
- while ((match = TAG_PATTERN_REGEX.exec(value)) !== null) {
567
- if (match[2]) {
568
- ids.push(match[2]);
569
- }
549
+ constructor(rows, _view, _projection) {
550
+ _define_property2(this, "_view", void 0);
551
+ _define_property2(this, "_projection", void 0);
552
+ _define_property2(this, "_displayToDataIndex", void 0);
553
+ _define_property2(this, "_rows", void 0);
554
+ _define_property2(this, "_localSort", void 0);
555
+ _define_property2(this, "_isDirty", void 0);
556
+ _define_property2(this, "sortedRows", void 0);
557
+ this._view = _view;
558
+ this._projection = _projection;
559
+ this._displayToDataIndex = /* @__PURE__ */ new Map();
560
+ this._localSort = signal2(void 0);
561
+ this._rows = rows;
562
+ this._isDirty = computed2(() => {
563
+ const local = this._localSort.value;
564
+ const viewSort = this._view.sort?.[0];
565
+ if (local?.type === "cleared") {
566
+ return viewSort !== void 0;
567
+ }
568
+ if (local?.type === "active") {
569
+ if (!viewSort) {
570
+ return true;
571
+ }
572
+ return local.sort.fieldId !== viewSort.fieldId || local.sort.direction !== viewSort.direction;
573
+ }
574
+ return false;
575
+ });
576
+ this.sortedRows = this.initialiseSortedRows();
570
577
  }
571
- return ids.length > 0 ? ids : void 0;
572
578
  };
573
579
 
574
580
  // src/model/table-model.ts
581
+ function _define_property3(obj, key, value) {
582
+ if (key in obj) {
583
+ Object.defineProperty(obj, key, {
584
+ value,
585
+ enumerable: true,
586
+ configurable: true,
587
+ writable: true
588
+ });
589
+ } else {
590
+ obj[key] = value;
591
+ }
592
+ return obj;
593
+ }
575
594
  var __dxlog_file = "/__w/dxos/dxos/packages/ui/react-ui-table/src/model/table-model.ts";
576
595
  var defaultFeatures = {
577
596
  selection: {
@@ -582,252 +601,6 @@ var defaultFeatures = {
582
601
  schemaEditable: false
583
602
  };
584
603
  var TableModel = class extends Resource2 {
585
- constructor({ view, schema, projection, features = {}, sorting = [], initialSelection = [], pinnedRows = {
586
- top: [],
587
- bottom: []
588
- }, rowActions = [], onCellUpdate, onDeleteColumn, onDeleteRows, onInsertRow, onRowOrderChange, onRowAction }) {
589
- super();
590
- this._visibleRange = signal3({
591
- start: {
592
- row: 0,
593
- col: 0
594
- },
595
- end: {
596
- row: 0,
597
- col: 0
598
- }
599
- });
600
- this._rows = signal3([]);
601
- this._draftRows = signal3([]);
602
- //
603
- // Data
604
- //
605
- this.setRows = (obj) => {
606
- this._rows.value = obj;
607
- };
608
- this.getRowCount = () => this._rows.value.length;
609
- /**
610
- * @reactive
611
- */
612
- this.getDraftRowCount = () => this._draftRows.value.length;
613
- this.getColumnCount = () => this._projection?.fields.length ?? 0;
614
- this.insertRow = () => {
615
- const result = this._onInsertRow?.();
616
- if (result === false && this._draftRows.value.length === 0) {
617
- this.createDraftRow();
618
- }
619
- };
620
- this.commitDraftRow = (draftRowIndex) => {
621
- if (draftRowIndex < 0 || draftRowIndex >= this._draftRows.value.length) {
622
- return false;
623
- }
624
- const draftRow = this._draftRows.value[draftRowIndex];
625
- if (!draftRow.valid) {
626
- return false;
627
- }
628
- const success = this._onInsertRow?.(draftRow.data);
629
- if (success) {
630
- const newDraftRows = this._draftRows.value.filter((_, index) => index !== draftRowIndex);
631
- this._draftRows.value = newDraftRows;
632
- }
633
- return success ?? false;
634
- };
635
- this.deleteRow = (rowIndex) => {
636
- const row = this._sorting.getDataIndex(rowIndex);
637
- const obj = this._rows.value[row];
638
- const objectsToDelete = [];
639
- if (this.features.selection.enabled && this._selection.hasSelection.value) {
640
- const selectedRows = this._selection.getSelectedRows();
641
- objectsToDelete.push(...selectedRows);
642
- } else {
643
- objectsToDelete.push(obj);
644
- }
645
- this._onDeleteRows?.(row, objectsToDelete);
646
- };
647
- this.handleRowAction = (actionId, rowIndex) => {
648
- if (!this._onRowAction) {
649
- return;
650
- }
651
- const row = this._sorting.getDataIndex(rowIndex);
652
- const data = this._rows.value[row];
653
- if (data) {
654
- this._onRowAction(actionId, data);
655
- }
656
- };
657
- this.getCellData = (cell) => {
658
- const { col, row, plane } = cell;
659
- const fields = this._projection?.fields ?? [];
660
- if (col < 0 || col >= fields.length) {
661
- return void 0;
662
- }
663
- const field = fields[col];
664
- let value;
665
- if (plane === "frozenRowsEnd") {
666
- if (row >= 0 && row < this._draftRows.value.length) {
667
- value = getValue2(this._draftRows.value[row].data, field.path);
668
- } else {
669
- return void 0;
670
- }
671
- } else {
672
- const dataIndex = this._sorting.getDataIndex(row);
673
- value = getValue2(this._rows.value[dataIndex], field.path);
674
- }
675
- if (value == null) {
676
- return "";
677
- }
678
- const { props } = this._projection.getFieldProjection(field.id);
679
- switch (props.format) {
680
- case FormatEnum2.Ref: {
681
- if (!field.referencePath) {
682
- return "";
683
- }
684
- return getValue2(value.target, field.referencePath);
685
- }
686
- default: {
687
- return formatForEditing({
688
- type: props.type,
689
- format: props.format,
690
- value
691
- });
692
- }
693
- }
694
- };
695
- this.validateCellData = async ({ col, row, plane }, value) => {
696
- const fields = this._projection?.fields ?? [];
697
- if (col < 0 || col >= fields.length) {
698
- return {
699
- valid: false,
700
- error: "Invalid column index"
701
- };
702
- }
703
- const field = fields[col];
704
- const { props } = this._projection.getFieldProjection(field.id);
705
- const transformedValue = editorTextToCellValue(props, value);
706
- const isDraftRow = plane === "frozenRowsEnd";
707
- if (isDraftRow) {
708
- const isInvalidDraftRowIndex = row < 0 || row >= this._draftRows.value.length;
709
- if (isInvalidDraftRowIndex) {
710
- return {
711
- valid: false,
712
- error: "Invalid draft row index"
713
- };
714
- }
715
- const draftRow = this._draftRows.value[row];
716
- const snapshot = {
717
- ...draftRow.data
718
- };
719
- setValue(snapshot, field.path, transformedValue);
720
- const validationErrors = this.validateDraftRowData(snapshot);
721
- if (validationErrors.length > 0) {
722
- const error = validationErrors.find((err) => err.path === field.path);
723
- if (error) {
724
- return {
725
- valid: false,
726
- error: error.message
727
- };
728
- }
729
- }
730
- return {
731
- valid: true
732
- };
733
- } else {
734
- const rowIdx = this._sorting.getDataIndex(row);
735
- const currentRow = this._rows.value[rowIdx];
736
- invariant(currentRow, "Invalid row index", {
737
- F: __dxlog_file,
738
- L: 510,
739
- S: this,
740
- A: [
741
- "currentRow",
742
- "'Invalid row index'"
743
- ]
744
- });
745
- const snapshot = getSnapshot(currentRow);
746
- setValue(snapshot, field.path, transformedValue);
747
- const schema = getSchema(currentRow);
748
- invariant(schema, void 0, {
749
- F: __dxlog_file,
750
- L: 516,
751
- S: this,
752
- A: [
753
- "schema",
754
- ""
755
- ]
756
- });
757
- const validationResult = validateSchema(schema, snapshot);
758
- if (validationResult && validationResult.length > 0) {
759
- const error = validationResult[0];
760
- invariant(error.path === field.path, void 0, {
761
- F: __dxlog_file,
762
- L: 521,
763
- S: this,
764
- A: [
765
- "error.path === field.path",
766
- ""
767
- ]
768
- });
769
- return {
770
- valid: false,
771
- error: error.message
772
- };
773
- }
774
- return {
775
- valid: true
776
- };
777
- }
778
- };
779
- this.setCellData = (cell, value) => {
780
- const { col, row, plane } = cell;
781
- const fields = this._projection?.fields ?? [];
782
- if (col < 0 || col >= fields.length) {
783
- return;
784
- }
785
- const field = fields[col];
786
- const { props } = this._projection.getFieldProjection(field.id);
787
- const transformedValue = editorTextToCellValue(props, value);
788
- if (props.format === FormatEnum2.Ref && !isLiveObject(value)) {
789
- return;
790
- }
791
- if (plane === "frozenRowsEnd") {
792
- if (row >= 0 && row < this._draftRows.value.length) {
793
- setValue(this._draftRows.value[row].data, field.path, transformedValue);
794
- this.validateDraftRow(row);
795
- }
796
- } else {
797
- const rowIdx = this._sorting.getDataIndex(row);
798
- setValue(this._rows.value[rowIdx], field.path, transformedValue);
799
- }
800
- };
801
- this._view = view;
802
- this._projection = projection ?? new ProjectionModel2(schema, view.projection);
803
- this._features = {
804
- ...defaultFeatures,
805
- ...features
806
- };
807
- invariant(!(this._features.dataEditable && this._features.selection.enabled && this._features.selection.mode === "single"), "Single selection is not compatible with editable tables.", {
808
- F: __dxlog_file,
809
- L: 139,
810
- S: this,
811
- A: [
812
- "!(this._features.dataEditable && this._features.selection.enabled && this._features.selection.mode === 'single')",
813
- "'Single selection is not compatible with editable tables.'"
814
- ]
815
- });
816
- this._sorting = new TableSorting(this._rows, this._view, this._projection);
817
- if (sorting.length > 0) {
818
- const [sort] = sorting;
819
- this._sorting.setSort(sort.fieldId, sort.direction);
820
- }
821
- this._selection = new SelectionModel(this._sorting.sortedRows, this._features.selection.mode ?? "multiple", initialSelection, () => this._onRowOrderChange?.());
822
- this._pinnedRows = pinnedRows;
823
- this._rowActions = rowActions;
824
- this._onInsertRow = onInsertRow;
825
- this._onDeleteRows = onDeleteRows;
826
- this._onDeleteColumn = onDeleteColumn;
827
- this._onCellUpdate = onCellUpdate;
828
- this._onRowOrderChange = onRowOrderChange;
829
- this._onRowAction = onRowAction;
830
- }
831
604
  get id() {
832
605
  return fullyQualifiedId(this._view);
833
606
  }
@@ -837,7 +610,7 @@ var TableModel = class extends Resource2 {
837
610
  get table() {
838
611
  invariant(this._table, "Model not initialized", {
839
612
  F: __dxlog_file,
840
- L: 177,
613
+ L: 187,
841
614
  S: this,
842
615
  A: [
843
616
  "this._table",
@@ -876,7 +649,7 @@ var TableModel = class extends Resource2 {
876
649
  get columnMeta() {
877
650
  invariant(this._columnMeta, void 0, {
878
651
  F: __dxlog_file,
879
- L: 216,
652
+ L: 226,
880
653
  S: this,
881
654
  A: [
882
655
  "this._columnMeta",
@@ -900,12 +673,12 @@ var TableModel = class extends Resource2 {
900
673
  //
901
674
  async _open() {
902
675
  const presentation = this._view.presentation.target ?? await this._view.presentation.load();
903
- invariant(Obj3.instanceOf(TableView, presentation), void 0, {
676
+ invariant(Obj2.instanceOf(schema_exports.Table, presentation), void 0, {
904
677
  F: __dxlog_file,
905
- L: 239,
678
+ L: 249,
906
679
  S: this,
907
680
  A: [
908
- "Obj.instanceOf(TableView, presentation)",
681
+ "Obj.instanceOf(Table.Table, presentation)",
909
682
  ""
910
683
  ]
911
684
  });
@@ -934,7 +707,7 @@ var TableModel = class extends Resource2 {
934
707
  },
935
708
  frozenColsEnd: {
936
709
  0: {
937
- size: 40,
710
+ size: 32,
938
711
  resizeable: false
939
712
  }
940
713
  }
@@ -1024,7 +797,7 @@ var TableModel = class extends Resource2 {
1024
797
  this._draftRows.value = newDraftRows;
1025
798
  }
1026
799
  validateDraftRowData(data) {
1027
- const schema = toEffectSchema2(this._projection.baseSchema);
800
+ const schema = toEffectSchema(this._projection.baseSchema);
1028
801
  return validateSchema(schema, data) || [];
1029
802
  }
1030
803
  /**
@@ -1089,23 +862,257 @@ var TableModel = class extends Resource2 {
1089
862
  this.table.sizes[field.path] = newWidth;
1090
863
  }
1091
864
  }
1092
- }
1093
- //
1094
- // Pinning
1095
- //
1096
- // TODO(burdon): Change to setPinned(on/off).
1097
- pinRow(rowIndex, side) {
1098
- this._pinnedRows[side].push(rowIndex);
1099
- }
1100
- unpinRow(rowIndex) {
1101
- this._pinnedRows.top = this._pinnedRows.top.filter((index) => index !== rowIndex);
1102
- this._pinnedRows.bottom = this._pinnedRows.bottom.filter((index) => index !== rowIndex);
1103
- }
1104
- //
1105
- // View operations
1106
- //
1107
- saveView() {
1108
- this._sorting.save();
865
+ }
866
+ //
867
+ // Pinning
868
+ //
869
+ // TODO(burdon): Change to setPinned(on/off).
870
+ pinRow(rowIndex, side) {
871
+ this._pinnedRows[side].push(rowIndex);
872
+ }
873
+ unpinRow(rowIndex) {
874
+ this._pinnedRows.top = this._pinnedRows.top.filter((index) => index !== rowIndex);
875
+ this._pinnedRows.bottom = this._pinnedRows.bottom.filter((index) => index !== rowIndex);
876
+ }
877
+ //
878
+ // View operations
879
+ //
880
+ saveView() {
881
+ this._sorting.save();
882
+ }
883
+ constructor({ view, schema, projection, features = {}, sorting = [], initialSelection = [], pinnedRows = {
884
+ top: [],
885
+ bottom: []
886
+ }, rowActions = [], onCellUpdate, onDeleteColumn, onDeleteRows, onInsertRow, onRowOrderChange, onRowAction }) {
887
+ super(), _define_property3(this, "_view", void 0), _define_property3(this, "_projection", void 0), _define_property3(this, "_table", void 0), _define_property3(this, "_visibleRange", signal3({
888
+ start: {
889
+ row: 0,
890
+ col: 0
891
+ },
892
+ end: {
893
+ row: 0,
894
+ col: 0
895
+ }
896
+ })), _define_property3(this, "_onInsertRow", void 0), _define_property3(this, "_onDeleteRows", void 0), _define_property3(this, "_onDeleteColumn", void 0), _define_property3(this, "_onCellUpdate", void 0), _define_property3(this, "_onRowOrderChange", void 0), _define_property3(this, "_onRowAction", void 0), _define_property3(this, "_rowActions", void 0), _define_property3(this, "_features", void 0), _define_property3(this, "_rows", signal3([])), _define_property3(this, "_draftRows", signal3([])), _define_property3(this, "_sorting", void 0), _define_property3(this, "_pinnedRows", void 0), _define_property3(this, "_selection", void 0), _define_property3(this, "_columnMeta", void 0), //
897
+ // Data
898
+ //
899
+ _define_property3(this, "setRows", (obj) => {
900
+ this._rows.value = obj;
901
+ }), _define_property3(this, "getRowCount", () => this._rows.value.length), /**
902
+ * @reactive
903
+ */
904
+ _define_property3(this, "getDraftRowCount", () => this._draftRows.value.length), _define_property3(this, "getColumnCount", () => this._projection?.fields.length ?? 0), _define_property3(this, "insertRow", () => {
905
+ const result = this._onInsertRow?.();
906
+ if (result === "draft" && this._draftRows.value.length === 0) {
907
+ this.createDraftRow();
908
+ }
909
+ return result ?? "final";
910
+ }), _define_property3(this, "commitDraftRow", (draftRowIndex) => {
911
+ if (draftRowIndex < 0 || draftRowIndex >= this._draftRows.value.length) {
912
+ return false;
913
+ }
914
+ const draftRow = this._draftRows.value[draftRowIndex];
915
+ if (!draftRow.valid) {
916
+ return false;
917
+ }
918
+ const insertRowResult = this._onInsertRow?.(draftRow.data);
919
+ if (insertRowResult === "final") {
920
+ const newDraftRows = this._draftRows.value.filter((_, index) => index !== draftRowIndex);
921
+ this._draftRows.value = newDraftRows;
922
+ }
923
+ return insertRowResult === "final";
924
+ }), _define_property3(this, "deleteRow", (rowIndex) => {
925
+ const row = this._sorting.getDataIndex(rowIndex);
926
+ const obj = this._rows.value[row];
927
+ const objectsToDelete = [];
928
+ if (this.features.selection.enabled && this._selection.hasSelection.value) {
929
+ const selectedRows = this._selection.getSelectedRows();
930
+ objectsToDelete.push(...selectedRows);
931
+ } else {
932
+ objectsToDelete.push(obj);
933
+ }
934
+ this._onDeleteRows?.(row, objectsToDelete);
935
+ }), _define_property3(this, "handleRowAction", (actionId, rowIndex) => {
936
+ if (!this._onRowAction) {
937
+ return;
938
+ }
939
+ const row = this._sorting.getDataIndex(rowIndex);
940
+ const data = this._rows.value[row];
941
+ if (data) {
942
+ this._onRowAction(actionId, data);
943
+ }
944
+ }), _define_property3(this, "getCellData", (cell) => {
945
+ const { col, row, plane } = cell;
946
+ const fields = this._projection?.fields ?? [];
947
+ if (col < 0 || col >= fields.length) {
948
+ return void 0;
949
+ }
950
+ const field = fields[col];
951
+ let value;
952
+ if (plane === "frozenRowsEnd") {
953
+ if (row >= 0 && row < this._draftRows.value.length) {
954
+ value = getValue2(this._draftRows.value[row].data, field.path);
955
+ } else {
956
+ return void 0;
957
+ }
958
+ } else {
959
+ const dataIndex = this._sorting.getDataIndex(row);
960
+ value = getValue2(this._rows.value[dataIndex], field.path);
961
+ }
962
+ if (value == null) {
963
+ return "";
964
+ }
965
+ const { props } = this._projection.getFieldProjection(field.id);
966
+ switch (props.format) {
967
+ case FormatEnum2.Ref: {
968
+ if (!field.referencePath) {
969
+ return "";
970
+ }
971
+ return getValue2(value.target, field.referencePath);
972
+ }
973
+ default: {
974
+ return formatForEditing({
975
+ type: props.type,
976
+ format: props.format,
977
+ value
978
+ });
979
+ }
980
+ }
981
+ }), _define_property3(this, "validateCellData", async ({ col, row, plane }, value) => {
982
+ const fields = this._projection?.fields ?? [];
983
+ if (col < 0 || col >= fields.length) {
984
+ return {
985
+ valid: false,
986
+ error: "Invalid column index"
987
+ };
988
+ }
989
+ const field = fields[col];
990
+ const { props } = this._projection.getFieldProjection(field.id);
991
+ const transformedValue = editorTextToCellValue(props, value);
992
+ const isDraftRow = plane === "frozenRowsEnd";
993
+ if (isDraftRow) {
994
+ const isInvalidDraftRowIndex = row < 0 || row >= this._draftRows.value.length;
995
+ if (isInvalidDraftRowIndex) {
996
+ return {
997
+ valid: false,
998
+ error: "Invalid draft row index"
999
+ };
1000
+ }
1001
+ const draftRow = this._draftRows.value[row];
1002
+ const snapshot = {
1003
+ ...draftRow.data
1004
+ };
1005
+ setValue(snapshot, field.path, transformedValue);
1006
+ const validationErrors = this.validateDraftRowData(snapshot);
1007
+ if (validationErrors.length > 0) {
1008
+ const error = validationErrors.find((err) => err.path === field.path);
1009
+ if (error) {
1010
+ return {
1011
+ valid: false,
1012
+ error: error.message
1013
+ };
1014
+ }
1015
+ }
1016
+ return {
1017
+ valid: true
1018
+ };
1019
+ } else {
1020
+ const rowIdx = this._sorting.getDataIndex(row);
1021
+ const currentRow = this._rows.value[rowIdx];
1022
+ invariant(currentRow, "Invalid row index", {
1023
+ F: __dxlog_file,
1024
+ L: 522,
1025
+ S: this,
1026
+ A: [
1027
+ "currentRow",
1028
+ "'Invalid row index'"
1029
+ ]
1030
+ });
1031
+ const snapshot = getSnapshot(currentRow);
1032
+ setValue(snapshot, field.path, transformedValue);
1033
+ const schema2 = getSchema(currentRow);
1034
+ invariant(schema2, void 0, {
1035
+ F: __dxlog_file,
1036
+ L: 528,
1037
+ S: this,
1038
+ A: [
1039
+ "schema",
1040
+ ""
1041
+ ]
1042
+ });
1043
+ const validationResult = validateSchema(schema2, snapshot);
1044
+ if (validationResult && validationResult.length > 0) {
1045
+ const error = validationResult[0];
1046
+ invariant(error.path === field.path, void 0, {
1047
+ F: __dxlog_file,
1048
+ L: 533,
1049
+ S: this,
1050
+ A: [
1051
+ "error.path === field.path",
1052
+ ""
1053
+ ]
1054
+ });
1055
+ return {
1056
+ valid: false,
1057
+ error: error.message
1058
+ };
1059
+ }
1060
+ return {
1061
+ valid: true
1062
+ };
1063
+ }
1064
+ }), _define_property3(this, "setCellData", (cell, value) => {
1065
+ const { col, row, plane } = cell;
1066
+ const fields = this._projection?.fields ?? [];
1067
+ if (col < 0 || col >= fields.length) {
1068
+ return;
1069
+ }
1070
+ const field = fields[col];
1071
+ const { props } = this._projection.getFieldProjection(field.id);
1072
+ const transformedValue = editorTextToCellValue(props, value);
1073
+ if (props.format === FormatEnum2.Ref && !isLiveObject(value)) {
1074
+ return;
1075
+ }
1076
+ if (plane === "frozenRowsEnd") {
1077
+ if (row >= 0 && row < this._draftRows.value.length) {
1078
+ setValue(this._draftRows.value[row].data, field.path, transformedValue);
1079
+ this.validateDraftRow(row);
1080
+ }
1081
+ } else {
1082
+ const rowIdx = this._sorting.getDataIndex(row);
1083
+ setValue(this._rows.value[rowIdx], field.path, transformedValue);
1084
+ }
1085
+ });
1086
+ this._view = view;
1087
+ this._projection = projection ?? new ProjectionModel2(schema, view.projection);
1088
+ this._projection.normalizeView();
1089
+ this._features = {
1090
+ ...defaultFeatures,
1091
+ ...features
1092
+ };
1093
+ invariant(!(this._features.dataEditable && this._features.selection.enabled && this._features.selection.mode === "single"), "Single selection is not compatible with editable tables.", {
1094
+ F: __dxlog_file,
1095
+ L: 149,
1096
+ S: this,
1097
+ A: [
1098
+ "!(this._features.dataEditable && this._features.selection.enabled && this._features.selection.mode === 'single')",
1099
+ "'Single selection is not compatible with editable tables.'"
1100
+ ]
1101
+ });
1102
+ this._sorting = new TableSorting(this._rows, this._view, this._projection);
1103
+ if (sorting.length > 0) {
1104
+ const [sort] = sorting;
1105
+ this._sorting.setSort(sort.fieldId, sort.direction);
1106
+ }
1107
+ this._selection = new SelectionModel(this._sorting.sortedRows, this._features.selection.mode ?? "multiple", initialSelection, () => this._onRowOrderChange?.());
1108
+ this._pinnedRows = pinnedRows;
1109
+ this._rowActions = rowActions;
1110
+ this._onInsertRow = onInsertRow;
1111
+ this._onDeleteRows = onDeleteRows;
1112
+ this._onDeleteColumn = onDeleteColumn;
1113
+ this._onCellUpdate = onCellUpdate;
1114
+ this._onRowOrderChange = onRowOrderChange;
1115
+ this._onRowAction = onRowAction;
1109
1116
  }
1110
1117
  };
1111
1118
  var editorTextToCellValue = (props, value) => {
@@ -1141,47 +1148,64 @@ var editorTextToCellValue = (props, value) => {
1141
1148
 
1142
1149
  // src/model/modal-controller.ts
1143
1150
  import { signal as signal4 } from "@preact/signals-core";
1144
- import { log } from "@dxos/log";
1145
- var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/react-ui-table/src/model/modal-controller.ts";
1151
+ function _define_property4(obj, key, value) {
1152
+ if (key in obj) {
1153
+ Object.defineProperty(obj, key, {
1154
+ value,
1155
+ enumerable: true,
1156
+ configurable: true,
1157
+ writable: true
1158
+ });
1159
+ } else {
1160
+ obj[key] = value;
1161
+ }
1162
+ return obj;
1163
+ }
1146
1164
  var ModalController = class {
1165
+ get state() {
1166
+ return this._state;
1167
+ }
1168
+ get trigger() {
1169
+ return this._triggerRef;
1170
+ }
1147
1171
  constructor() {
1148
- this._state = signal4({
1172
+ _define_property4(this, "_state", signal4({
1149
1173
  type: "closed"
1150
- });
1151
- this._triggerRef = {
1174
+ }));
1175
+ _define_property4(this, "_triggerRef", {
1152
1176
  current: null
1153
- };
1154
- this.setTrigger = (trigger) => {
1177
+ });
1178
+ _define_property4(this, "setTrigger", (trigger) => {
1155
1179
  this._triggerRef.current = trigger;
1156
- };
1157
- this.showRowMenu = (rowIndex) => {
1180
+ });
1181
+ _define_property4(this, "showRowMenu", (rowIndex) => {
1158
1182
  this._state.value = {
1159
1183
  type: "row",
1160
1184
  rowIndex
1161
1185
  };
1162
- };
1163
- this.showColumnMenu = (fieldId) => {
1186
+ });
1187
+ _define_property4(this, "showColumnMenu", (fieldId) => {
1164
1188
  this._state.value = {
1165
1189
  type: "column",
1166
1190
  fieldId
1167
1191
  };
1168
- };
1169
- this.showColumnCreator = () => {
1192
+ });
1193
+ _define_property4(this, "showColumnCreator", () => {
1170
1194
  this._state.value = {
1171
1195
  type: "columnSettings",
1172
1196
  mode: {
1173
1197
  type: "create"
1174
1198
  }
1175
1199
  };
1176
- };
1177
- this.showReferencePanel = (targetId, schemaId) => {
1200
+ });
1201
+ _define_property4(this, "showReferencePanel", (targetId, schemaId) => {
1178
1202
  this._state.value = {
1179
1203
  type: "refPanel",
1180
1204
  targetId,
1181
1205
  typename: schemaId
1182
1206
  };
1183
- };
1184
- this.openColumnSettings = () => {
1207
+ });
1208
+ _define_property4(this, "openColumnSettings", () => {
1185
1209
  if (this._state.value.type === "column") {
1186
1210
  const fieldId = this._state.value.fieldId;
1187
1211
  requestAnimationFrame(() => {
@@ -1194,63 +1218,38 @@ var ModalController = class {
1194
1218
  };
1195
1219
  });
1196
1220
  }
1197
- };
1198
- this.openCreateRef = (typename, anchorCell, initialValues, onCreate) => {
1199
- if (anchorCell) {
1200
- this._triggerRef.current = anchorCell;
1201
- this._state.value = {
1202
- type: "createRefPanel",
1203
- typename,
1204
- initialValues,
1205
- onCreate
1206
- };
1207
- } else {
1208
- log.warn("anchor cell not found while creating new ref", void 0, {
1209
- F: __dxlog_file2,
1210
- L: 86,
1211
- S: this,
1212
- C: (f, a) => f(...a)
1213
- });
1214
- }
1215
- };
1216
- this.close = () => {
1221
+ });
1222
+ _define_property4(this, "close", () => {
1217
1223
  this._state.value = {
1218
1224
  type: "closed"
1219
1225
  };
1220
- };
1221
- }
1222
- get state() {
1223
- return this._state;
1224
- }
1225
- get trigger() {
1226
- return this._triggerRef;
1226
+ });
1227
1227
  }
1228
1228
  };
1229
1229
 
1230
1230
  // src/model/table-presentation.ts
1231
1231
  import { signal as signal5 } from "@preact/signals-core";
1232
- import { isNotNullable } from "effect/Predicate";
1233
- import { Obj as Obj4 } from "@dxos/echo";
1234
- import { FormatEnum as FormatEnum3, getValue as getValue3, TypeEnum as TypeEnum2 } from "@dxos/echo-schema";
1232
+ import * as Predicate from "effect/Predicate";
1233
+ import { Obj as Obj3 } from "@dxos/echo";
1234
+ import { FormatEnum as FormatEnum3, TypeEnum as TypeEnum2, getValue as getValue3 } from "@dxos/echo/internal";
1235
1235
  import { cellClassesForFieldType, formatForDisplay as formatForDisplay2 } from "@dxos/react-ui-form";
1236
1236
  import { toPlaneCellIndex } from "@dxos/react-ui-grid";
1237
1237
  import { mx } from "@dxos/react-ui-theme";
1238
1238
  import { VIEW_FIELD_LIMIT } from "@dxos/schema";
1239
- var TablePresentation = class {
1240
- constructor(model, _visibleRange = signal5({
1241
- start: {
1242
- row: 0,
1243
- col: 0
1244
- },
1245
- end: {
1246
- row: 0,
1247
- col: 0
1248
- }
1249
- })) {
1250
- this.model = model;
1251
- this._visibleRange = _visibleRange;
1252
- this.fieldProjectionCache = /* @__PURE__ */ new Map();
1239
+ function _define_property5(obj, key, value) {
1240
+ if (key in obj) {
1241
+ Object.defineProperty(obj, key, {
1242
+ value,
1243
+ enumerable: true,
1244
+ configurable: true,
1245
+ writable: true
1246
+ });
1247
+ } else {
1248
+ obj[key] = value;
1253
1249
  }
1250
+ return obj;
1251
+ }
1252
+ var TablePresentation = class {
1254
1253
  getCells(range, plane) {
1255
1254
  this.fieldProjectionCache.clear();
1256
1255
  let cells;
@@ -1277,6 +1276,9 @@ var TablePresentation = class {
1277
1276
  case "frozenRowsEnd":
1278
1277
  cells = this.getDraftRowCells(range);
1279
1278
  break;
1279
+ case "fixedEndStart":
1280
+ cells = this.getDraftIconCells(range);
1281
+ break;
1280
1282
  case "fixedEndEnd":
1281
1283
  cells = this.getDraftActionCells(range);
1282
1284
  break;
@@ -1335,10 +1337,7 @@ var TablePresentation = class {
1335
1337
  }
1336
1338
  };
1337
1339
  const classes = [];
1338
- const formatClasses = cellClassesForFieldType({
1339
- type: props.type,
1340
- format: props.format
1341
- });
1340
+ const formatClasses = cellClassesForFieldType(props);
1342
1341
  if (formatClasses) {
1343
1342
  classes.push(formatClasses);
1344
1343
  }
@@ -1346,9 +1345,7 @@ var TablePresentation = class {
1346
1345
  if (rowSelectionClasses) {
1347
1346
  classes.push(rowSelectionClasses);
1348
1347
  }
1349
- if (classes.length > 0) {
1350
- cell.className = mx(classes.flat());
1351
- }
1348
+ cell.className = mx(classes);
1352
1349
  if (props.type === TypeEnum2.Array) {
1353
1350
  const targetArray = getValue3(obj, field.path);
1354
1351
  if (targetArray && Array.isArray(targetArray)) {
@@ -1370,7 +1367,7 @@ var TablePresentation = class {
1370
1367
  }
1371
1368
  return "Object";
1372
1369
  };
1373
- const tags = targetArray.map(getLabel).filter(isNotNullable).map((title) => {
1370
+ const tags = targetArray.map(getLabel).filter(Predicate.isNotNullable).map((title) => {
1374
1371
  return `<span class="dx-tag" data-hue="neutral">${title}</span>`;
1375
1372
  }).join("");
1376
1373
  cell.accessoryHtml = `<div role='none' class="flex flex-row gap-1 overflow-x-auto">${tags}</div>`;
@@ -1379,8 +1376,8 @@ var TablePresentation = class {
1379
1376
  if (props.format === FormatEnum3.Ref && props.referenceSchema) {
1380
1377
  const targetObj = getValue3(obj, field.path)?.target;
1381
1378
  if (targetObj) {
1382
- const dxn = Obj4.getDXN(targetObj)?.toString();
1383
- 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>`;
1379
+ const dxn = Obj3.getDXN(targetObj)?.toString();
1380
+ 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>`;
1384
1381
  }
1385
1382
  }
1386
1383
  if (props.format === FormatEnum3.Boolean) {
@@ -1442,24 +1439,37 @@ var TablePresentation = class {
1442
1439
  const cells = {};
1443
1440
  const fields = this.model.projection?.fields ?? [];
1444
1441
  const draftRows = this.model.draftRows.value;
1445
- for (let row = range.start.row; row <= range.end.row && row < draftRows.length; row++) {
1446
- const draftRow = draftRows[row];
1442
+ if (draftRows.length === 0) {
1447
1443
  for (let col = range.start.col; col <= range.end.col && col < fields.length; col++) {
1448
- const field = fields[col];
1449
- if (!field) {
1450
- continue;
1451
- }
1452
- this.createDataCell(cells, draftRow.data, field, col, row);
1453
- if (this.model.hasDraftRowValidationError(row, field.path)) {
1444
+ cells[toPlaneCellIndex({
1445
+ col,
1446
+ row: 0
1447
+ })] = {
1448
+ value: "",
1449
+ readonly: true,
1450
+ className: "dx-grid__row--cta__cell"
1451
+ };
1452
+ }
1453
+ } else {
1454
+ for (let row = range.start.row; row <= range.end.row && row < draftRows.length; row++) {
1455
+ const draftRow = draftRows[row];
1456
+ for (let col = range.start.col; col <= range.end.col && col < fields.length; col++) {
1454
1457
  const cellIndex = toPlaneCellIndex({
1455
1458
  col,
1456
1459
  row
1457
1460
  });
1458
- const cellValue = cells[cellIndex];
1459
- if (cellValue) {
1460
- const existingClasses = cellValue.className || "";
1461
- const draftClasses = "dx-grid__cell--flagged";
1462
- cellValue.className = existingClasses ? `${existingClasses} ${draftClasses}` : draftClasses;
1461
+ const field = fields[col];
1462
+ if (!field) {
1463
+ continue;
1464
+ }
1465
+ this.createDataCell(cells, draftRow.data, field, col, row);
1466
+ if (this.model.hasDraftRowValidationError(row, field.path)) {
1467
+ const cellValue = cells[cellIndex];
1468
+ if (cellValue) {
1469
+ const existingClasses = cellValue.className || "";
1470
+ const draftClasses = "dx-grid__cell--flagged";
1471
+ cellValue.className = existingClasses ? `${existingClasses} ${draftClasses}` : draftClasses;
1472
+ }
1463
1473
  }
1464
1474
  }
1465
1475
  }
@@ -1478,10 +1488,10 @@ var TablePresentation = class {
1478
1488
  row: 0
1479
1489
  })] = {
1480
1490
  // TODO(burdon): Use same logic as form for fallback title.
1481
- value: props.title ?? field.path,
1482
- readonly: true,
1491
+ value: "",
1483
1492
  resizeHandle: "col",
1484
1493
  accessoryHtml: `
1494
+ <span class="grow min-is-0 truncate">${props.title ?? field.path}</span>
1485
1495
  ${direction !== void 0 ? tableButtons.sort.render({
1486
1496
  fieldId: field.id,
1487
1497
  direction
@@ -1490,7 +1500,7 @@ var TablePresentation = class {
1490
1500
  fieldId: field.id
1491
1501
  })}
1492
1502
  `,
1493
- className: "!bg-toolbarSurface"
1503
+ className: "!bg-toolbarSurface !text-description [&>div]:flex [&>div]:items-stretch"
1494
1504
  };
1495
1505
  }
1496
1506
  return cells;
@@ -1581,23 +1591,67 @@ var TablePresentation = class {
1581
1591
  getDraftActionCells(range) {
1582
1592
  const cells = {};
1583
1593
  const draftRows = this.model.draftRows.value;
1584
- for (let row = range.start.row; row <= range.end.row && row < draftRows.length; row++) {
1585
- const draftRow = draftRows[row];
1586
- const disabled = !draftRow.valid;
1594
+ if (draftRows.length === 0) {
1595
+ cells[toPlaneCellIndex({
1596
+ col: 0,
1597
+ row: 0
1598
+ })] = {
1599
+ value: "",
1600
+ className: "dx-grid__row--cta__cell",
1601
+ readonly: true
1602
+ };
1603
+ } else {
1604
+ for (let row = range.start.row; row <= range.end.row && row < draftRows.length; row++) {
1605
+ const draftRow = draftRows[row];
1606
+ const disabled = !draftRow.valid;
1607
+ cells[toPlaneCellIndex({
1608
+ col: 0,
1609
+ row
1610
+ })] = {
1611
+ value: "",
1612
+ readonly: true,
1613
+ accessoryHtml: tableButtons.saveDraftRow.render({
1614
+ rowIndex: row,
1615
+ disabled
1616
+ })
1617
+ };
1618
+ }
1619
+ }
1620
+ return cells;
1621
+ }
1622
+ getDraftIconCells(range) {
1623
+ const cells = {};
1624
+ const draftRows = this.model.draftRows.value;
1625
+ for (let row = range.start.row; row <= range.end.row; row++) {
1587
1626
  cells[toPlaneCellIndex({
1588
1627
  col: 0,
1589
1628
  row
1590
1629
  })] = {
1591
1630
  value: "",
1592
1631
  readonly: true,
1593
- accessoryHtml: tableButtons.saveDraftRow.render({
1594
- rowIndex: row,
1595
- disabled
1596
- })
1632
+ accessoryHtml: '<dx-icon icon="ph--plus--regular" class="contents"></dx-icon>',
1633
+ className: mx("[&>div]:grid [&>div]:place-content-center", draftRows.length < 1 && "dx-grid__row--cta__cell")
1597
1634
  };
1598
1635
  }
1599
1636
  return cells;
1600
1637
  }
1638
+ constructor(model, _visibleRange = signal5({
1639
+ start: {
1640
+ row: 0,
1641
+ col: 0
1642
+ },
1643
+ end: {
1644
+ row: 0,
1645
+ col: 0
1646
+ }
1647
+ })) {
1648
+ _define_property5(this, "model", void 0);
1649
+ _define_property5(this, "_visibleRange", void 0);
1650
+ _define_property5(this, "fieldProjectionCache", void 0);
1651
+ this.model = model;
1652
+ this._visibleRange = _visibleRange;
1653
+ this.fieldProjectionCache = /* @__PURE__ */ new Map();
1654
+ }
1601
1655
  };
1602
1656
  var cellClassesForRowSelection = (selected, selectionMode) => {
1603
1657
  if (!selected) {
@@ -1711,18 +1765,18 @@ var useTableModel = ({ view, schema, projection, rows, rowActions, features, onS
1711
1765
 
1712
1766
  // src/hooks/useAddRow.ts
1713
1767
  import { useCallback } from "react";
1714
- import { Obj as Obj5 } from "@dxos/echo";
1768
+ import { Obj as Obj4 } from "@dxos/echo";
1715
1769
  var useAddRow = ({ space, schema }) => {
1716
1770
  return useCallback((data) => {
1717
1771
  if (space && schema) {
1718
1772
  try {
1719
- space.db.add(Obj5.make(schema, data ?? {}));
1720
- return true;
1773
+ space.db.add(Obj4.make(schema, data ?? {}));
1774
+ return "final";
1721
1775
  } catch (error) {
1722
- return false;
1776
+ return "draft";
1723
1777
  }
1724
1778
  }
1725
- return false;
1779
+ return "final";
1726
1780
  }, [
1727
1781
  space,
1728
1782
  schema
@@ -1733,7 +1787,6 @@ export {
1733
1787
  getBaseSchema,
1734
1788
  makeDynamicTable,
1735
1789
  touch,
1736
- createTable,
1737
1790
  BUTTON_IDENTIFIERS,
1738
1791
  tableButtons,
1739
1792
  CONTROL_IDENTIFIERS,
@@ -1748,4 +1801,4 @@ export {
1748
1801
  useTableModel,
1749
1802
  useAddRow
1750
1803
  };
1751
- //# sourceMappingURL=chunk-5XLSHLOG.mjs.map
1804
+ //# sourceMappingURL=chunk-OZTXLZGM.mjs.map