@dxos/react-ui-table 0.8.4-main.67995b8 → 0.8.4-main.dedc0f3

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 (120) hide show
  1. package/dist/lib/browser/chunk-63UUF4IG.mjs +66 -0
  2. package/dist/lib/browser/chunk-63UUF4IG.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-5XLSHLOG.mjs → chunk-GPZSXPSA.mjs} +535 -464
  4. package/dist/lib/browser/chunk-GPZSXPSA.mjs.map +7 -0
  5. package/dist/lib/browser/index.mjs +724 -667
  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 +9 -6
  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-K734DJB7.mjs +67 -0
  12. package/dist/lib/node-esm/chunk-K734DJB7.mjs.map +7 -0
  13. package/dist/lib/node-esm/{chunk-Y66YLSTC.mjs → chunk-XUD6W42C.mjs} +535 -464
  14. package/dist/lib/node-esm/chunk-XUD6W42C.mjs.map +7 -0
  15. package/dist/lib/node-esm/index.mjs +724 -667
  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 +9 -6
  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/CreateRefPanel.d.ts +1 -1
  26. package/dist/types/src/components/Table/CreateRefPanel.d.ts.map +1 -1
  27. package/dist/types/src/components/Table/DynamicTable.d.ts.map +1 -1
  28. package/dist/types/src/components/Table/DynamicTable.stories.d.ts +50 -2
  29. package/dist/types/src/components/Table/DynamicTable.stories.d.ts.map +1 -1
  30. package/dist/types/src/components/Table/Relations.stories.d.ts +44 -0
  31. package/dist/types/src/components/Table/Relations.stories.d.ts.map +1 -0
  32. package/dist/types/src/components/Table/RowActionsMenu.d.ts +1 -1
  33. package/dist/types/src/components/Table/RowActionsMenu.d.ts.map +1 -1
  34. package/dist/types/src/components/Table/Table.d.ts +3 -2
  35. package/dist/types/src/components/Table/Table.d.ts.map +1 -1
  36. package/dist/types/src/components/Table/Table.stories.d.ts +42 -3
  37. package/dist/types/src/components/Table/Table.stories.d.ts.map +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 +7 -3
  40. package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts.map +1 -1
  41. package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts +8 -15
  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 -3
  44. package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts.map +1 -1
  45. package/dist/types/src/components/TableToolbar/TableToolbar.d.ts.map +1 -1
  46. package/dist/types/src/hooks/useAddRow.d.ts +2 -1
  47. package/dist/types/src/hooks/useAddRow.d.ts.map +1 -1
  48. package/dist/types/src/hooks/useTableModel.d.ts +1 -1
  49. package/dist/types/src/hooks/useTableModel.d.ts.map +1 -1
  50. package/dist/types/src/model/modal-controller.d.ts.map +1 -1
  51. package/dist/types/src/model/selection-model.d.ts.map +1 -1
  52. package/dist/types/src/model/table-model.d.ts +9 -7
  53. package/dist/types/src/model/table-model.d.ts.map +1 -1
  54. package/dist/types/src/model/table-presentation.d.ts +2 -1
  55. package/dist/types/src/model/table-presentation.d.ts.map +1 -1
  56. package/dist/types/src/model/table-sorting.d.ts +2 -3
  57. package/dist/types/src/model/table-sorting.d.ts.map +1 -1
  58. package/dist/types/src/testing/useTestTableModel.d.ts +2 -21
  59. package/dist/types/src/testing/useTestTableModel.d.ts.map +1 -1
  60. package/dist/types/src/translations.d.ts +2 -2
  61. package/dist/types/src/types/index.d.ts +1 -1
  62. package/dist/types/src/types/index.d.ts.map +1 -1
  63. package/dist/types/src/types/schema.d.ts +24 -4
  64. package/dist/types/src/types/schema.d.ts.map +1 -1
  65. package/dist/types/src/util/dynamic-table.d.ts +2 -2
  66. package/dist/types/src/util/dynamic-table.d.ts.map +1 -1
  67. package/dist/types/src/util/index.d.ts +0 -1
  68. package/dist/types/src/util/index.d.ts.map +1 -1
  69. package/dist/types/src/util/table-buttons.d.ts.map +1 -1
  70. package/dist/types/src/util/table-controls.d.ts.map +1 -1
  71. package/dist/types/tsconfig.tsbuildinfo +1 -1
  72. package/package.json +51 -50
  73. package/src/components/Table/ColumnActionsMenu.tsx +1 -1
  74. package/src/components/Table/ColumnSettings.tsx +1 -1
  75. package/src/components/Table/CreateRefPanel.tsx +25 -8
  76. package/src/components/Table/DynamicTable.stories.tsx +7 -4
  77. package/src/components/Table/DynamicTable.tsx +4 -3
  78. package/src/components/Table/{relations.stories.tsx → Relations.stories.tsx} +40 -23
  79. package/src/components/Table/RowActionsMenu.tsx +3 -3
  80. package/src/components/Table/Table.stories.tsx +39 -28
  81. package/src/components/Table/Table.tsx +131 -110
  82. package/src/components/TableCellEditor/CellValidationMessage.tsx +1 -1
  83. package/src/components/TableCellEditor/FormCellEditor.tsx +143 -42
  84. package/src/components/TableCellEditor/TableCellEditor.stories.tsx +12 -24
  85. package/src/components/TableCellEditor/TableCellEditor.tsx +74 -137
  86. package/src/components/TableToolbar/TableToolbar.tsx +2 -2
  87. package/src/components/testing.ts +1 -1
  88. package/src/hooks/useAddRow.ts +6 -4
  89. package/src/hooks/useTableModel.ts +1 -1
  90. package/src/model/modal-controller.ts +1 -1
  91. package/src/model/selection-model.ts +3 -2
  92. package/src/model/table-model.test.ts +3 -4
  93. package/src/model/table-model.ts +35 -24
  94. package/src/model/table-presentation.test.ts +4 -4
  95. package/src/model/table-presentation.ts +72 -30
  96. package/src/model/table-sorting.ts +16 -7
  97. package/src/playwright/smoke.spec.ts +129 -37
  98. package/src/testing/useTestTableModel.ts +7 -5
  99. package/src/translations.ts +2 -2
  100. package/src/types/index.ts +1 -1
  101. package/src/types/schema.ts +62 -5
  102. package/src/util/dynamic-table.ts +8 -7
  103. package/src/util/index.ts +0 -1
  104. package/src/util/schema.ts +1 -1
  105. package/src/util/table-buttons.ts +4 -3
  106. package/src/util/table-controls.ts +4 -1
  107. package/dist/lib/browser/chunk-5XLSHLOG.mjs.map +0 -7
  108. package/dist/lib/browser/chunk-L2LSB6KV.mjs +0 -18
  109. package/dist/lib/browser/chunk-L2LSB6KV.mjs.map +0 -7
  110. package/dist/lib/node-esm/chunk-NXZ4CJYX.mjs +0 -20
  111. package/dist/lib/node-esm/chunk-NXZ4CJYX.mjs.map +0 -7
  112. package/dist/lib/node-esm/chunk-Y66YLSTC.mjs.map +0 -7
  113. package/dist/types/src/components/Table/relations.stories.d.ts +0 -9
  114. package/dist/types/src/components/Table/relations.stories.d.ts.map +0 -1
  115. package/dist/types/src/components/TableCellEditor/extension.d.ts +0 -13
  116. package/dist/types/src/components/TableCellEditor/extension.d.ts.map +0 -1
  117. package/dist/types/src/util/table.d.ts +0 -11
  118. package/dist/types/src/util/table.d.ts.map +0 -1
  119. package/src/components/TableCellEditor/extension.ts +0 -61
  120. 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-63UUF4IG.mjs";
4
4
 
5
5
  // src/util/dynamic-table.ts
6
6
  import { Obj } from "@dxos/echo";
7
7
  import { getTypename, toJsonSchema } from "@dxos/echo-schema";
8
- import { createView, getSchemaFromPropertyDefinitions, ProjectionModel } from "@dxos/schema";
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);
@@ -28,7 +28,7 @@ var getBaseSchema = ({ typename, properties, jsonSchema, schema }) => {
28
28
  }
29
29
  };
30
30
  var makeDynamicTable = ({ typename, jsonSchema, properties }) => {
31
- const table = Obj.make(TableView, {
31
+ const table = Obj.make(schema_exports.Table, {
32
32
  sizes: {}
33
33
  });
34
34
  const view = createView({
@@ -67,7 +67,7 @@ var setProperties = (view, projection, table, properties) => {
67
67
  }
68
68
  if (property.sort) {
69
69
  const fieldId = field.id;
70
- view.query.sort = [
70
+ view.sort = [
71
71
  {
72
72
  fieldId,
73
73
  direction: property.sort
@@ -81,40 +81,6 @@ var setProperties = (view, projection, table, properties) => {
81
81
  // src/util/signals.ts
82
82
  var touch = (value) => value;
83
83
 
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
84
  // src/util/table-buttons.ts
119
85
  var BUTTON_IDENTIFIERS = {
120
86
  columnSettings: "data-table-column-settings-button",
@@ -124,10 +90,9 @@ var BUTTON_IDENTIFIERS = {
124
90
  saveDraftRow: "data-table-save-draft-row-button",
125
91
  sort: "data-table-sort-button"
126
92
  };
127
- var createButton = ({ attr, data, disabled = false, icon, testId, type = "primary" }) => {
93
+ var createButton = ({ attr, data, disabled = false, icon, testId, type: _type = "primary" }) => {
128
94
  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>`;
95
+ 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
96
  };
132
97
  var addColumnButton = {
133
98
  attr: BUTTON_IDENTIFIERS.newColumn,
@@ -153,7 +118,8 @@ var columnSettingsButton = {
153
118
  attr: BUTTON_IDENTIFIERS.columnSettings,
154
119
  icon: columnSettingsButton.icon,
155
120
  data: {
156
- "data-field-id": fieldId
121
+ "data-field-id": fieldId,
122
+ "data-variant": "ghost"
157
123
  },
158
124
  testId: "table-column-settings-button"
159
125
  });
@@ -213,7 +179,8 @@ var saveDraftRowButton = {
213
179
  icon: saveDraftRowButton.icon,
214
180
  disabled,
215
181
  data: {
216
- "data-row-index": rowIndex.toString()
182
+ "data-row-index": rowIndex.toString(),
183
+ "data-variant": "primary"
217
184
  },
218
185
  testId: "table-save-draft-row-button"
219
186
  });
@@ -232,6 +199,7 @@ var tableButtons = {
232
199
  };
233
200
 
234
201
  // src/util/table-controls.ts
202
+ import { accessoryHandlesPointerdownAttrs } from "@dxos/lit-grid";
235
203
  var CONTROL_IDENTIFIERS = {
236
204
  checkbox: "data-table-checkbox",
237
205
  switch: "data-table-switch"
@@ -244,7 +212,7 @@ var renderAttributes = (data) => {
244
212
  return Object.entries(data).map(([k, v]) => `${k}="${v}"`).join(" ");
245
213
  };
246
214
  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}"/>`;
215
+ 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
216
  };
249
217
  var CheckboxStory = ({ rowIndex, header = false, checked = false, disabled = false }) => {
250
218
  const attrs = {
@@ -260,7 +228,8 @@ var SwitchStory = ({ colIndex, rowIndex, checked = false, disabled = false }) =>
260
228
  const attrs = {
261
229
  [CONTROL_IDENTIFIERS.switch]: "",
262
230
  "data-row-index": rowIndex.toString(),
263
- "data-col-index": colIndex.toString()
231
+ "data-col-index": colIndex.toString(),
232
+ ...accessoryHandlesPointerdownAttrs
264
233
  };
265
234
  return renderInput(BASE_CLASSES.switch, attrs, checked, disabled, true, "table-switch");
266
235
  };
@@ -287,7 +256,7 @@ var tableControls = {
287
256
 
288
257
  // src/util/schema.ts
289
258
  import { Schema } from "effect";
290
- import { isTypeLiteral, TypeLiteral } from "effect/SchemaAST";
259
+ import { TypeLiteral, isTypeLiteral } from "effect/SchemaAST";
291
260
  var narrowSchema = (schema, paths) => {
292
261
  const ast = schema?.ast;
293
262
  if (isTypeLiteral(ast)) {
@@ -303,21 +272,75 @@ var narrowSchema = (schema, paths) => {
303
272
  // src/model/table-model.ts
304
273
  import { computed as computed3, effect as effect2, signal as signal3 } from "@preact/signals-core";
305
274
  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";
275
+ import { Obj as Obj2, Ref } from "@dxos/echo";
276
+ import { FormatEnum as FormatEnum2, getSchema, getValue as getValue2, setValue, toEffectSchema } from "@dxos/echo-schema";
308
277
  import { invariant } from "@dxos/invariant";
309
278
  import { ObjectId } from "@dxos/keys";
310
- import { isLiveObject } from "@dxos/live-object";
279
+ import { getSnapshot, isLiveObject } from "@dxos/live-object";
311
280
  import { fullyQualifiedId } from "@dxos/react-client/echo";
312
281
  import { formatForEditing, parseValue } from "@dxos/react-ui-form";
313
282
  import { ProjectionModel as ProjectionModel2, validateSchema } from "@dxos/schema";
314
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
+ };
299
+
315
300
  // src/model/selection-model.ts
316
301
  import { computed, effect, signal } from "@preact/signals-core";
317
302
  import { Resource } from "@dxos/context";
303
+ function _define_property(obj, key, value) {
304
+ if (key in obj) {
305
+ Object.defineProperty(obj, key, {
306
+ value,
307
+ enumerable: true,
308
+ configurable: true,
309
+ writable: true
310
+ });
311
+ } else {
312
+ obj[key] = value;
313
+ }
314
+ return obj;
315
+ }
318
316
  var SelectionModel = class extends Resource {
317
+ async _open() {
318
+ const selectionWatcher = effect(() => {
319
+ touch(this._selection.value);
320
+ this._onSelectionChanged?.();
321
+ });
322
+ this._ctx.onDispose(selectionWatcher);
323
+ }
324
+ //
325
+ // Getters
326
+ //
327
+ get selection() {
328
+ return this._selection;
329
+ }
330
+ get hasSelection() {
331
+ return this._hasSelection;
332
+ }
333
+ get allRowsSeleted() {
334
+ return this._allSelected;
335
+ }
336
+ get selectionMode() {
337
+ return this._selectionMode;
338
+ }
319
339
  constructor(_rows, _selectionMode, _initialSelection, _onSelectionChanged) {
320
- super(), this._rows = _rows, this._selectionMode = _selectionMode, this._initialSelection = _initialSelection, this._onSelectionChanged = _onSelectionChanged, this._validSelectedIds = computed(() => {
340
+ 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), //
341
+ // Manipulation
342
+ //
343
+ _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
344
  const rows = this._rows.value;
322
345
  if (!rows) {
323
346
  return /* @__PURE__ */ new Set();
@@ -366,58 +389,27 @@ var SelectionModel = class extends Resource {
366
389
  };
367
390
  this._selection = signal(new Set(this._initialSelection));
368
391
  }
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
392
  };
392
393
 
393
394
  // src/model/table-sorting.ts
394
395
  import { computed as computed2, signal as signal2 } from "@preact/signals-core";
395
396
  import orderBy from "lodash.orderby";
396
- import { getValue, FormatEnum, TypeEnum } from "@dxos/echo-schema";
397
+ import { FormatEnum, TypeEnum, getValue } from "@dxos/echo-schema";
397
398
  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;
399
+ function _define_property2(obj, key, value) {
400
+ if (key in obj) {
401
+ Object.defineProperty(obj, key, {
402
+ value,
403
+ enumerable: true,
404
+ configurable: true,
405
+ writable: true
418
406
  });
419
- this.sortedRows = this.initialiseSortedRows();
407
+ } else {
408
+ obj[key] = value;
420
409
  }
410
+ return obj;
411
+ }
412
+ var TableSorting = class {
421
413
  /**
422
414
  * @reactive
423
415
  * @returns Local sort if present, falls back to view sort.
@@ -430,7 +422,7 @@ var TableSorting = class {
430
422
  if (local?.type === "active") {
431
423
  return local.sort;
432
424
  }
433
- return this._view.query.sort?.[0];
425
+ return this._view.sort?.[0];
434
426
  }
435
427
  /**
436
428
  * @reactive
@@ -474,11 +466,11 @@ var TableSorting = class {
474
466
  save() {
475
467
  if (this._localSort.value !== void 0) {
476
468
  if (this._localSort.value.type === "active") {
477
- this._view.query.sort = [
469
+ this._view.sort = [
478
470
  this._localSort.value.sort
479
471
  ];
480
472
  } else {
481
- this._view.query.sort = [];
473
+ this._view.sort = [];
482
474
  }
483
475
  this._localSort.value = void 0;
484
476
  }
@@ -553,25 +545,51 @@ var TableSorting = class {
553
545
  value
554
546
  });
555
547
  }
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
- }
548
+ constructor(rows, _view, _projection) {
549
+ _define_property2(this, "_view", void 0);
550
+ _define_property2(this, "_projection", void 0);
551
+ _define_property2(this, "_displayToDataIndex", void 0);
552
+ _define_property2(this, "_rows", void 0);
553
+ _define_property2(this, "_localSort", void 0);
554
+ _define_property2(this, "_isDirty", void 0);
555
+ _define_property2(this, "sortedRows", void 0);
556
+ this._view = _view;
557
+ this._projection = _projection;
558
+ this._displayToDataIndex = /* @__PURE__ */ new Map();
559
+ this._localSort = signal2(void 0);
560
+ this._rows = rows;
561
+ this._isDirty = computed2(() => {
562
+ const local = this._localSort.value;
563
+ const viewSort = this._view.sort?.[0];
564
+ if (local?.type === "cleared") {
565
+ return viewSort !== void 0;
566
+ }
567
+ if (local?.type === "active") {
568
+ if (!viewSort) {
569
+ return true;
570
+ }
571
+ return local.sort.fieldId !== viewSort.fieldId || local.sort.direction !== viewSort.direction;
572
+ }
573
+ return false;
574
+ });
575
+ this.sortedRows = this.initialiseSortedRows();
570
576
  }
571
- return ids.length > 0 ? ids : void 0;
572
577
  };
573
578
 
574
579
  // src/model/table-model.ts
580
+ function _define_property3(obj, key, value) {
581
+ if (key in obj) {
582
+ Object.defineProperty(obj, key, {
583
+ value,
584
+ enumerable: true,
585
+ configurable: true,
586
+ writable: true
587
+ });
588
+ } else {
589
+ obj[key] = value;
590
+ }
591
+ return obj;
592
+ }
575
593
  var __dxlog_file = "/__w/dxos/dxos/packages/ui/react-ui-table/src/model/table-model.ts";
576
594
  var defaultFeatures = {
577
595
  selection: {
@@ -582,252 +600,6 @@ var defaultFeatures = {
582
600
  schemaEditable: false
583
601
  };
584
602
  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
603
  get id() {
832
604
  return fullyQualifiedId(this._view);
833
605
  }
@@ -837,7 +609,7 @@ var TableModel = class extends Resource2 {
837
609
  get table() {
838
610
  invariant(this._table, "Model not initialized", {
839
611
  F: __dxlog_file,
840
- L: 177,
612
+ L: 186,
841
613
  S: this,
842
614
  A: [
843
615
  "this._table",
@@ -876,7 +648,7 @@ var TableModel = class extends Resource2 {
876
648
  get columnMeta() {
877
649
  invariant(this._columnMeta, void 0, {
878
650
  F: __dxlog_file,
879
- L: 216,
651
+ L: 225,
880
652
  S: this,
881
653
  A: [
882
654
  "this._columnMeta",
@@ -900,12 +672,12 @@ var TableModel = class extends Resource2 {
900
672
  //
901
673
  async _open() {
902
674
  const presentation = this._view.presentation.target ?? await this._view.presentation.load();
903
- invariant(Obj3.instanceOf(TableView, presentation), void 0, {
675
+ invariant(Obj2.instanceOf(schema_exports.Table, presentation), void 0, {
904
676
  F: __dxlog_file,
905
- L: 239,
677
+ L: 248,
906
678
  S: this,
907
679
  A: [
908
- "Obj.instanceOf(TableView, presentation)",
680
+ "Obj.instanceOf(Table.Table, presentation)",
909
681
  ""
910
682
  ]
911
683
  });
@@ -934,7 +706,7 @@ var TableModel = class extends Resource2 {
934
706
  },
935
707
  frozenColsEnd: {
936
708
  0: {
937
- size: 40,
709
+ size: 32,
938
710
  resizeable: false
939
711
  }
940
712
  }
@@ -1024,7 +796,7 @@ var TableModel = class extends Resource2 {
1024
796
  this._draftRows.value = newDraftRows;
1025
797
  }
1026
798
  validateDraftRowData(data) {
1027
- const schema = toEffectSchema2(this._projection.baseSchema);
799
+ const schema = toEffectSchema(this._projection.baseSchema);
1028
800
  return validateSchema(schema, data) || [];
1029
801
  }
1030
802
  /**
@@ -1089,23 +861,256 @@ var TableModel = class extends Resource2 {
1089
861
  this.table.sizes[field.path] = newWidth;
1090
862
  }
1091
863
  }
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();
864
+ }
865
+ //
866
+ // Pinning
867
+ //
868
+ // TODO(burdon): Change to setPinned(on/off).
869
+ pinRow(rowIndex, side) {
870
+ this._pinnedRows[side].push(rowIndex);
871
+ }
872
+ unpinRow(rowIndex) {
873
+ this._pinnedRows.top = this._pinnedRows.top.filter((index) => index !== rowIndex);
874
+ this._pinnedRows.bottom = this._pinnedRows.bottom.filter((index) => index !== rowIndex);
875
+ }
876
+ //
877
+ // View operations
878
+ //
879
+ saveView() {
880
+ this._sorting.save();
881
+ }
882
+ constructor({ view, schema, projection, features = {}, sorting = [], initialSelection = [], pinnedRows = {
883
+ top: [],
884
+ bottom: []
885
+ }, rowActions = [], onCellUpdate, onDeleteColumn, onDeleteRows, onInsertRow, onRowOrderChange, onRowAction }) {
886
+ super(), _define_property3(this, "_view", void 0), _define_property3(this, "_projection", void 0), _define_property3(this, "_table", void 0), _define_property3(this, "_visibleRange", signal3({
887
+ start: {
888
+ row: 0,
889
+ col: 0
890
+ },
891
+ end: {
892
+ row: 0,
893
+ col: 0
894
+ }
895
+ })), _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), //
896
+ // Data
897
+ //
898
+ _define_property3(this, "setRows", (obj) => {
899
+ this._rows.value = obj;
900
+ }), _define_property3(this, "getRowCount", () => this._rows.value.length), /**
901
+ * @reactive
902
+ */
903
+ _define_property3(this, "getDraftRowCount", () => this._draftRows.value.length), _define_property3(this, "getColumnCount", () => this._projection?.fields.length ?? 0), _define_property3(this, "insertRow", () => {
904
+ const result = this._onInsertRow?.();
905
+ if (result === "draft" && this._draftRows.value.length === 0) {
906
+ this.createDraftRow();
907
+ }
908
+ return result ?? "final";
909
+ }), _define_property3(this, "commitDraftRow", (draftRowIndex) => {
910
+ if (draftRowIndex < 0 || draftRowIndex >= this._draftRows.value.length) {
911
+ return false;
912
+ }
913
+ const draftRow = this._draftRows.value[draftRowIndex];
914
+ if (!draftRow.valid) {
915
+ return false;
916
+ }
917
+ const insertRowResult = this._onInsertRow?.(draftRow.data);
918
+ if (insertRowResult === "final") {
919
+ const newDraftRows = this._draftRows.value.filter((_, index) => index !== draftRowIndex);
920
+ this._draftRows.value = newDraftRows;
921
+ }
922
+ return insertRowResult === "final";
923
+ }), _define_property3(this, "deleteRow", (rowIndex) => {
924
+ const row = this._sorting.getDataIndex(rowIndex);
925
+ const obj = this._rows.value[row];
926
+ const objectsToDelete = [];
927
+ if (this.features.selection.enabled && this._selection.hasSelection.value) {
928
+ const selectedRows = this._selection.getSelectedRows();
929
+ objectsToDelete.push(...selectedRows);
930
+ } else {
931
+ objectsToDelete.push(obj);
932
+ }
933
+ this._onDeleteRows?.(row, objectsToDelete);
934
+ }), _define_property3(this, "handleRowAction", (actionId, rowIndex) => {
935
+ if (!this._onRowAction) {
936
+ return;
937
+ }
938
+ const row = this._sorting.getDataIndex(rowIndex);
939
+ const data = this._rows.value[row];
940
+ if (data) {
941
+ this._onRowAction(actionId, data);
942
+ }
943
+ }), _define_property3(this, "getCellData", (cell) => {
944
+ const { col, row, plane } = cell;
945
+ const fields = this._projection?.fields ?? [];
946
+ if (col < 0 || col >= fields.length) {
947
+ return void 0;
948
+ }
949
+ const field = fields[col];
950
+ let value;
951
+ if (plane === "frozenRowsEnd") {
952
+ if (row >= 0 && row < this._draftRows.value.length) {
953
+ value = getValue2(this._draftRows.value[row].data, field.path);
954
+ } else {
955
+ return void 0;
956
+ }
957
+ } else {
958
+ const dataIndex = this._sorting.getDataIndex(row);
959
+ value = getValue2(this._rows.value[dataIndex], field.path);
960
+ }
961
+ if (value == null) {
962
+ return "";
963
+ }
964
+ const { props } = this._projection.getFieldProjection(field.id);
965
+ switch (props.format) {
966
+ case FormatEnum2.Ref: {
967
+ if (!field.referencePath) {
968
+ return "";
969
+ }
970
+ return getValue2(value.target, field.referencePath);
971
+ }
972
+ default: {
973
+ return formatForEditing({
974
+ type: props.type,
975
+ format: props.format,
976
+ value
977
+ });
978
+ }
979
+ }
980
+ }), _define_property3(this, "validateCellData", async ({ col, row, plane }, value) => {
981
+ const fields = this._projection?.fields ?? [];
982
+ if (col < 0 || col >= fields.length) {
983
+ return {
984
+ valid: false,
985
+ error: "Invalid column index"
986
+ };
987
+ }
988
+ const field = fields[col];
989
+ const { props } = this._projection.getFieldProjection(field.id);
990
+ const transformedValue = editorTextToCellValue(props, value);
991
+ const isDraftRow = plane === "frozenRowsEnd";
992
+ if (isDraftRow) {
993
+ const isInvalidDraftRowIndex = row < 0 || row >= this._draftRows.value.length;
994
+ if (isInvalidDraftRowIndex) {
995
+ return {
996
+ valid: false,
997
+ error: "Invalid draft row index"
998
+ };
999
+ }
1000
+ const draftRow = this._draftRows.value[row];
1001
+ const snapshot = {
1002
+ ...draftRow.data
1003
+ };
1004
+ setValue(snapshot, field.path, transformedValue);
1005
+ const validationErrors = this.validateDraftRowData(snapshot);
1006
+ if (validationErrors.length > 0) {
1007
+ const error = validationErrors.find((err) => err.path === field.path);
1008
+ if (error) {
1009
+ return {
1010
+ valid: false,
1011
+ error: error.message
1012
+ };
1013
+ }
1014
+ }
1015
+ return {
1016
+ valid: true
1017
+ };
1018
+ } else {
1019
+ const rowIdx = this._sorting.getDataIndex(row);
1020
+ const currentRow = this._rows.value[rowIdx];
1021
+ invariant(currentRow, "Invalid row index", {
1022
+ F: __dxlog_file,
1023
+ L: 521,
1024
+ S: this,
1025
+ A: [
1026
+ "currentRow",
1027
+ "'Invalid row index'"
1028
+ ]
1029
+ });
1030
+ const snapshot = getSnapshot(currentRow);
1031
+ setValue(snapshot, field.path, transformedValue);
1032
+ const schema2 = getSchema(currentRow);
1033
+ invariant(schema2, void 0, {
1034
+ F: __dxlog_file,
1035
+ L: 527,
1036
+ S: this,
1037
+ A: [
1038
+ "schema",
1039
+ ""
1040
+ ]
1041
+ });
1042
+ const validationResult = validateSchema(schema2, snapshot);
1043
+ if (validationResult && validationResult.length > 0) {
1044
+ const error = validationResult[0];
1045
+ invariant(error.path === field.path, void 0, {
1046
+ F: __dxlog_file,
1047
+ L: 532,
1048
+ S: this,
1049
+ A: [
1050
+ "error.path === field.path",
1051
+ ""
1052
+ ]
1053
+ });
1054
+ return {
1055
+ valid: false,
1056
+ error: error.message
1057
+ };
1058
+ }
1059
+ return {
1060
+ valid: true
1061
+ };
1062
+ }
1063
+ }), _define_property3(this, "setCellData", (cell, value) => {
1064
+ const { col, row, plane } = cell;
1065
+ const fields = this._projection?.fields ?? [];
1066
+ if (col < 0 || col >= fields.length) {
1067
+ return;
1068
+ }
1069
+ const field = fields[col];
1070
+ const { props } = this._projection.getFieldProjection(field.id);
1071
+ const transformedValue = editorTextToCellValue(props, value);
1072
+ if (props.format === FormatEnum2.Ref && !isLiveObject(value)) {
1073
+ return;
1074
+ }
1075
+ if (plane === "frozenRowsEnd") {
1076
+ if (row >= 0 && row < this._draftRows.value.length) {
1077
+ setValue(this._draftRows.value[row].data, field.path, transformedValue);
1078
+ this.validateDraftRow(row);
1079
+ }
1080
+ } else {
1081
+ const rowIdx = this._sorting.getDataIndex(row);
1082
+ setValue(this._rows.value[rowIdx], field.path, transformedValue);
1083
+ }
1084
+ });
1085
+ this._view = view;
1086
+ this._projection = projection ?? new ProjectionModel2(schema, view.projection);
1087
+ this._features = {
1088
+ ...defaultFeatures,
1089
+ ...features
1090
+ };
1091
+ invariant(!(this._features.dataEditable && this._features.selection.enabled && this._features.selection.mode === "single"), "Single selection is not compatible with editable tables.", {
1092
+ F: __dxlog_file,
1093
+ L: 148,
1094
+ S: this,
1095
+ A: [
1096
+ "!(this._features.dataEditable && this._features.selection.enabled && this._features.selection.mode === 'single')",
1097
+ "'Single selection is not compatible with editable tables.'"
1098
+ ]
1099
+ });
1100
+ this._sorting = new TableSorting(this._rows, this._view, this._projection);
1101
+ if (sorting.length > 0) {
1102
+ const [sort] = sorting;
1103
+ this._sorting.setSort(sort.fieldId, sort.direction);
1104
+ }
1105
+ this._selection = new SelectionModel(this._sorting.sortedRows, this._features.selection.mode ?? "multiple", initialSelection, () => this._onRowOrderChange?.());
1106
+ this._pinnedRows = pinnedRows;
1107
+ this._rowActions = rowActions;
1108
+ this._onInsertRow = onInsertRow;
1109
+ this._onDeleteRows = onDeleteRows;
1110
+ this._onDeleteColumn = onDeleteColumn;
1111
+ this._onCellUpdate = onCellUpdate;
1112
+ this._onRowOrderChange = onRowOrderChange;
1113
+ this._onRowAction = onRowAction;
1109
1114
  }
1110
1115
  };
1111
1116
  var editorTextToCellValue = (props, value) => {
@@ -1142,46 +1147,65 @@ var editorTextToCellValue = (props, value) => {
1142
1147
  // src/model/modal-controller.ts
1143
1148
  import { signal as signal4 } from "@preact/signals-core";
1144
1149
  import { log } from "@dxos/log";
1150
+ function _define_property4(obj, key, value) {
1151
+ if (key in obj) {
1152
+ Object.defineProperty(obj, key, {
1153
+ value,
1154
+ enumerable: true,
1155
+ configurable: true,
1156
+ writable: true
1157
+ });
1158
+ } else {
1159
+ obj[key] = value;
1160
+ }
1161
+ return obj;
1162
+ }
1145
1163
  var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/react-ui-table/src/model/modal-controller.ts";
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,8 +1218,8 @@ var ModalController = class {
1194
1218
  };
1195
1219
  });
1196
1220
  }
1197
- };
1198
- this.openCreateRef = (typename, anchorCell, initialValues, onCreate) => {
1221
+ });
1222
+ _define_property4(this, "openCreateRef", (typename, anchorCell, initialValues, onCreate) => {
1199
1223
  if (anchorCell) {
1200
1224
  this._triggerRef.current = anchorCell;
1201
1225
  this._state.value = {
@@ -1212,45 +1236,38 @@ var ModalController = class {
1212
1236
  C: (f, a) => f(...a)
1213
1237
  });
1214
1238
  }
1215
- };
1216
- this.close = () => {
1239
+ });
1240
+ _define_property4(this, "close", () => {
1217
1241
  this._state.value = {
1218
1242
  type: "closed"
1219
1243
  };
1220
- };
1221
- }
1222
- get state() {
1223
- return this._state;
1224
- }
1225
- get trigger() {
1226
- return this._triggerRef;
1244
+ });
1227
1245
  }
1228
1246
  };
1229
1247
 
1230
1248
  // src/model/table-presentation.ts
1231
1249
  import { signal as signal5 } from "@preact/signals-core";
1232
1250
  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";
1251
+ import { Obj as Obj3 } from "@dxos/echo";
1252
+ import { FormatEnum as FormatEnum3, TypeEnum as TypeEnum2, getValue as getValue3 } from "@dxos/echo-schema";
1235
1253
  import { cellClassesForFieldType, formatForDisplay as formatForDisplay2 } from "@dxos/react-ui-form";
1236
1254
  import { toPlaneCellIndex } from "@dxos/react-ui-grid";
1237
1255
  import { mx } from "@dxos/react-ui-theme";
1238
1256
  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();
1257
+ function _define_property5(obj, key, value) {
1258
+ if (key in obj) {
1259
+ Object.defineProperty(obj, key, {
1260
+ value,
1261
+ enumerable: true,
1262
+ configurable: true,
1263
+ writable: true
1264
+ });
1265
+ } else {
1266
+ obj[key] = value;
1253
1267
  }
1268
+ return obj;
1269
+ }
1270
+ var TablePresentation = class {
1254
1271
  getCells(range, plane) {
1255
1272
  this.fieldProjectionCache.clear();
1256
1273
  let cells;
@@ -1277,6 +1294,9 @@ var TablePresentation = class {
1277
1294
  case "frozenRowsEnd":
1278
1295
  cells = this.getDraftRowCells(range);
1279
1296
  break;
1297
+ case "fixedEndStart":
1298
+ cells = this.getDraftIconCells(range);
1299
+ break;
1280
1300
  case "fixedEndEnd":
1281
1301
  cells = this.getDraftActionCells(range);
1282
1302
  break;
@@ -1335,10 +1355,7 @@ var TablePresentation = class {
1335
1355
  }
1336
1356
  };
1337
1357
  const classes = [];
1338
- const formatClasses = cellClassesForFieldType({
1339
- type: props.type,
1340
- format: props.format
1341
- });
1358
+ const formatClasses = cellClassesForFieldType(props);
1342
1359
  if (formatClasses) {
1343
1360
  classes.push(formatClasses);
1344
1361
  }
@@ -1346,9 +1363,7 @@ var TablePresentation = class {
1346
1363
  if (rowSelectionClasses) {
1347
1364
  classes.push(rowSelectionClasses);
1348
1365
  }
1349
- if (classes.length > 0) {
1350
- cell.className = mx(classes.flat());
1351
- }
1366
+ cell.className = mx(classes);
1352
1367
  if (props.type === TypeEnum2.Array) {
1353
1368
  const targetArray = getValue3(obj, field.path);
1354
1369
  if (targetArray && Array.isArray(targetArray)) {
@@ -1379,8 +1394,8 @@ var TablePresentation = class {
1379
1394
  if (props.format === FormatEnum3.Ref && props.referenceSchema) {
1380
1395
  const targetObj = getValue3(obj, field.path)?.target;
1381
1396
  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>`;
1397
+ const dxn = Obj3.getDXN(targetObj)?.toString();
1398
+ cell.accessoryHtml = `<dx-anchor refId=${dxn} class="dx-button is-6 pli-[3px] pbe-[2px] min-bs-0 absolute inline-end-2 block-start-[.2rem]" data-dx-grid-action="accessory"><dx-icon icon="ph--link-simple--regular"/></dx-anchor>`;
1384
1399
  }
1385
1400
  }
1386
1401
  if (props.format === FormatEnum3.Boolean) {
@@ -1442,24 +1457,37 @@ var TablePresentation = class {
1442
1457
  const cells = {};
1443
1458
  const fields = this.model.projection?.fields ?? [];
1444
1459
  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];
1460
+ if (draftRows.length === 0) {
1447
1461
  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)) {
1462
+ cells[toPlaneCellIndex({
1463
+ col,
1464
+ row: 0
1465
+ })] = {
1466
+ value: "",
1467
+ readonly: true,
1468
+ className: "dx-grid__row--cta__cell"
1469
+ };
1470
+ }
1471
+ } else {
1472
+ for (let row = range.start.row; row <= range.end.row && row < draftRows.length; row++) {
1473
+ const draftRow = draftRows[row];
1474
+ for (let col = range.start.col; col <= range.end.col && col < fields.length; col++) {
1454
1475
  const cellIndex = toPlaneCellIndex({
1455
1476
  col,
1456
1477
  row
1457
1478
  });
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;
1479
+ const field = fields[col];
1480
+ if (!field) {
1481
+ continue;
1482
+ }
1483
+ this.createDataCell(cells, draftRow.data, field, col, row);
1484
+ if (this.model.hasDraftRowValidationError(row, field.path)) {
1485
+ const cellValue = cells[cellIndex];
1486
+ if (cellValue) {
1487
+ const existingClasses = cellValue.className || "";
1488
+ const draftClasses = "dx-grid__cell--flagged";
1489
+ cellValue.className = existingClasses ? `${existingClasses} ${draftClasses}` : draftClasses;
1490
+ }
1463
1491
  }
1464
1492
  }
1465
1493
  }
@@ -1478,10 +1506,10 @@ var TablePresentation = class {
1478
1506
  row: 0
1479
1507
  })] = {
1480
1508
  // TODO(burdon): Use same logic as form for fallback title.
1481
- value: props.title ?? field.path,
1482
- readonly: true,
1509
+ value: "",
1483
1510
  resizeHandle: "col",
1484
1511
  accessoryHtml: `
1512
+ <span class="grow min-is-0 truncate">${props.title ?? field.path}</span>
1485
1513
  ${direction !== void 0 ? tableButtons.sort.render({
1486
1514
  fieldId: field.id,
1487
1515
  direction
@@ -1490,7 +1518,7 @@ var TablePresentation = class {
1490
1518
  fieldId: field.id
1491
1519
  })}
1492
1520
  `,
1493
- className: "!bg-toolbarSurface"
1521
+ className: "!bg-toolbarSurface !text-description [&>div]:flex [&>div]:items-stretch"
1494
1522
  };
1495
1523
  }
1496
1524
  return cells;
@@ -1581,23 +1609,67 @@ var TablePresentation = class {
1581
1609
  getDraftActionCells(range) {
1582
1610
  const cells = {};
1583
1611
  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;
1612
+ if (draftRows.length === 0) {
1613
+ cells[toPlaneCellIndex({
1614
+ col: 0,
1615
+ row: 0
1616
+ })] = {
1617
+ value: "",
1618
+ className: "dx-grid__row--cta__cell",
1619
+ readonly: true
1620
+ };
1621
+ } else {
1622
+ for (let row = range.start.row; row <= range.end.row && row < draftRows.length; row++) {
1623
+ const draftRow = draftRows[row];
1624
+ const disabled = !draftRow.valid;
1625
+ cells[toPlaneCellIndex({
1626
+ col: 0,
1627
+ row
1628
+ })] = {
1629
+ value: "",
1630
+ readonly: true,
1631
+ accessoryHtml: tableButtons.saveDraftRow.render({
1632
+ rowIndex: row,
1633
+ disabled
1634
+ })
1635
+ };
1636
+ }
1637
+ }
1638
+ return cells;
1639
+ }
1640
+ getDraftIconCells(range) {
1641
+ const cells = {};
1642
+ const draftRows = this.model.draftRows.value;
1643
+ for (let row = range.start.row; row <= range.end.row; row++) {
1587
1644
  cells[toPlaneCellIndex({
1588
1645
  col: 0,
1589
1646
  row
1590
1647
  })] = {
1591
1648
  value: "",
1592
1649
  readonly: true,
1593
- accessoryHtml: tableButtons.saveDraftRow.render({
1594
- rowIndex: row,
1595
- disabled
1596
- })
1650
+ accessoryHtml: '<dx-icon icon="ph--plus--regular" class="contents"></dx-icon>',
1651
+ className: mx("[&>div]:grid [&>div]:place-content-center", draftRows.length < 1 && "dx-grid__row--cta__cell")
1597
1652
  };
1598
1653
  }
1599
1654
  return cells;
1600
1655
  }
1656
+ constructor(model, _visibleRange = signal5({
1657
+ start: {
1658
+ row: 0,
1659
+ col: 0
1660
+ },
1661
+ end: {
1662
+ row: 0,
1663
+ col: 0
1664
+ }
1665
+ })) {
1666
+ _define_property5(this, "model", void 0);
1667
+ _define_property5(this, "_visibleRange", void 0);
1668
+ _define_property5(this, "fieldProjectionCache", void 0);
1669
+ this.model = model;
1670
+ this._visibleRange = _visibleRange;
1671
+ this.fieldProjectionCache = /* @__PURE__ */ new Map();
1672
+ }
1601
1673
  };
1602
1674
  var cellClassesForRowSelection = (selected, selectionMode) => {
1603
1675
  if (!selected) {
@@ -1711,18 +1783,18 @@ var useTableModel = ({ view, schema, projection, rows, rowActions, features, onS
1711
1783
 
1712
1784
  // src/hooks/useAddRow.ts
1713
1785
  import { useCallback } from "react";
1714
- import { Obj as Obj5 } from "@dxos/echo";
1786
+ import { Obj as Obj4 } from "@dxos/echo";
1715
1787
  var useAddRow = ({ space, schema }) => {
1716
1788
  return useCallback((data) => {
1717
1789
  if (space && schema) {
1718
1790
  try {
1719
- space.db.add(Obj5.make(schema, data ?? {}));
1720
- return true;
1791
+ space.db.add(Obj4.make(schema, data ?? {}));
1792
+ return "final";
1721
1793
  } catch (error) {
1722
- return false;
1794
+ return "draft";
1723
1795
  }
1724
1796
  }
1725
- return false;
1797
+ return "final";
1726
1798
  }, [
1727
1799
  space,
1728
1800
  schema
@@ -1733,7 +1805,6 @@ export {
1733
1805
  getBaseSchema,
1734
1806
  makeDynamicTable,
1735
1807
  touch,
1736
- createTable,
1737
1808
  BUTTON_IDENTIFIERS,
1738
1809
  tableButtons,
1739
1810
  CONTROL_IDENTIFIERS,
@@ -1748,4 +1819,4 @@ export {
1748
1819
  useTableModel,
1749
1820
  useAddRow
1750
1821
  };
1751
- //# sourceMappingURL=chunk-5XLSHLOG.mjs.map
1822
+ //# sourceMappingURL=chunk-GPZSXPSA.mjs.map