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

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-BBXDTWCX.mjs} +537 -466
  4. package/dist/lib/browser/chunk-BBXDTWCX.mjs.map +7 -0
  5. package/dist/lib/browser/index.mjs +730 -669
  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-RNQDU7IQ.mjs} +537 -466
  14. package/dist/lib/node-esm/chunk-RNQDU7IQ.mjs.map +7 -0
  15. package/dist/lib/node-esm/index.mjs +730 -669
  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 +47 -42
  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 +138 -112
  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 +9 -5
  93. package/src/model/table-model.ts +35 -24
  94. package/src/model/table-presentation.test.ts +10 -5
  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 +10 -9
  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,12 +1,12 @@
1
1
  import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
2
  import {
3
- TableView
4
- } from "./chunk-NXZ4CJYX.mjs";
3
+ schema_exports
4
+ } from "./chunk-K734DJB7.mjs";
5
5
 
6
6
  // src/util/dynamic-table.ts
7
- import { Obj } from "@dxos/echo";
7
+ import { Filter, Obj, Query } from "@dxos/echo";
8
8
  import { getTypename, toJsonSchema } from "@dxos/echo-schema";
9
- import { createView, getSchemaFromPropertyDefinitions, ProjectionModel } from "@dxos/schema";
9
+ import { ProjectionModel, createView, getSchemaFromPropertyDefinitions } from "@dxos/schema";
10
10
  var getBaseSchema = ({ typename, properties, jsonSchema, schema }) => {
11
11
  if (typename && properties) {
12
12
  const schema2 = getSchemaFromPropertyDefinitions(typename, properties);
@@ -29,11 +29,11 @@ var getBaseSchema = ({ typename, properties, jsonSchema, schema }) => {
29
29
  }
30
30
  };
31
31
  var makeDynamicTable = ({ typename, jsonSchema, properties }) => {
32
- const table = Obj.make(TableView, {
32
+ const table = Obj.make(schema_exports.Table, {
33
33
  sizes: {}
34
34
  });
35
35
  const view = createView({
36
- typename,
36
+ query: Query.select(Filter.typename(typename)),
37
37
  jsonSchema,
38
38
  presentation: table,
39
39
  ...properties && {
@@ -68,7 +68,7 @@ var setProperties = (view, projection, table, properties) => {
68
68
  }
69
69
  if (property.sort) {
70
70
  const fieldId = field.id;
71
- view.query.sort = [
71
+ view.sort = [
72
72
  {
73
73
  fieldId,
74
74
  direction: property.sort
@@ -82,40 +82,6 @@ var setProperties = (view, projection, table, properties) => {
82
82
  // src/util/signals.ts
83
83
  var touch = (value) => value;
84
84
 
85
- // src/util/table.ts
86
- import { Match } from "effect";
87
- import { Obj as Obj2 } from "@dxos/echo";
88
- import { toEffectSchema } from "@dxos/echo-schema";
89
- import { createViewFromSpace, getSchemaProperties } from "@dxos/schema";
90
- var createTable = async ({ sizes, ...props }) => {
91
- const table = Obj2.make(TableView, {
92
- sizes: {}
93
- });
94
- const { jsonSchema, view } = await createViewFromSpace({
95
- ...props,
96
- presentation: table
97
- });
98
- const schema = toEffectSchema(jsonSchema);
99
- const shouldIncludeId = props.fields?.find((field) => field === "id") !== void 0;
100
- const properties = getSchemaProperties(schema.ast, {}, shouldIncludeId);
101
- for (const property of properties) {
102
- if (sizes?.[property.name]) {
103
- table.sizes[property.name] = sizes[property.name];
104
- continue;
105
- }
106
- Match.type().pipe(Match.when("boolean", () => {
107
- table.sizes[property.name] = 100;
108
- }), Match.when("number", () => {
109
- table.sizes[property.name] = 100;
110
- }), Match.orElse(() => {
111
- }))(property.type);
112
- }
113
- return {
114
- jsonSchema,
115
- view
116
- };
117
- };
118
-
119
85
  // src/util/table-buttons.ts
120
86
  var BUTTON_IDENTIFIERS = {
121
87
  columnSettings: "data-table-column-settings-button",
@@ -125,10 +91,9 @@ var BUTTON_IDENTIFIERS = {
125
91
  saveDraftRow: "data-table-save-draft-row-button",
126
92
  sort: "data-table-sort-button"
127
93
  };
128
- var createButton = ({ attr, data, disabled = false, icon, testId, type = "primary" }) => {
94
+ var createButton = ({ attr, data, disabled = false, icon, testId, type: _type = "primary" }) => {
129
95
  const dataAttrs = Object.entries(data).map(([k, v]) => `${k}="${v}"`).join(" ");
130
- const positionClass = type === "primary" ? "inline-end-2" : "inline-end-9";
131
- return `<button ${attr} data-testid="${testId}" class="dx-button is-6 pli-0.5 min-bs-0 absolute inset-block-1 ${positionClass}" ${dataAttrs} ${disabled ? "disabled" : ""}><svg data-size="4"><use href="/icons.svg#${icon}"/></svg></button>`;
96
+ return `<button ${attr} data-testid="${testId}" class="dx-button is-6 aspect-square pli-0.5 min-bs-0" ${dataAttrs} ${disabled ? "disabled" : ""} data-dx-grid-action="accessory"><svg data-size="4"><use href="/icons.svg#${icon}"/></svg></button>`;
132
97
  };
133
98
  var addColumnButton = {
134
99
  attr: BUTTON_IDENTIFIERS.newColumn,
@@ -154,7 +119,8 @@ var columnSettingsButton = {
154
119
  attr: BUTTON_IDENTIFIERS.columnSettings,
155
120
  icon: columnSettingsButton.icon,
156
121
  data: {
157
- "data-field-id": fieldId
122
+ "data-field-id": fieldId,
123
+ "data-variant": "ghost"
158
124
  },
159
125
  testId: "table-column-settings-button"
160
126
  });
@@ -214,7 +180,8 @@ var saveDraftRowButton = {
214
180
  icon: saveDraftRowButton.icon,
215
181
  disabled,
216
182
  data: {
217
- "data-row-index": rowIndex.toString()
183
+ "data-row-index": rowIndex.toString(),
184
+ "data-variant": "primary"
218
185
  },
219
186
  testId: "table-save-draft-row-button"
220
187
  });
@@ -233,6 +200,7 @@ var tableButtons = {
233
200
  };
234
201
 
235
202
  // src/util/table-controls.ts
203
+ import { accessoryHandlesPointerdownAttrs } from "@dxos/lit-grid";
236
204
  var CONTROL_IDENTIFIERS = {
237
205
  checkbox: "data-table-checkbox",
238
206
  switch: "data-table-switch"
@@ -245,7 +213,7 @@ var renderAttributes = (data) => {
245
213
  return Object.entries(data).map(([k, v]) => `${k}="${v}"`).join(" ");
246
214
  };
247
215
  var renderInput = (baseClass, attrs, checked = false, disabled = false, preventToggle = false, testId) => {
248
- return `<input type="checkbox" class="${baseClass}" ${renderAttributes(attrs)} ${checked ? "checked" : ""} ${preventToggle ? 'onclick="return false"' : ""} ${disabled ? "disabled" : ""} data-testid="${testId}"/>`;
216
+ return `<input type="checkbox" class="${baseClass}" ${renderAttributes(attrs)} ${checked ? "checked" : ""} ${preventToggle ? 'onclick="return false"' : ""} ${disabled ? "disabled" : ""} data-testid="${testId}" data-dx-grid-action="accessory"/>`;
249
217
  };
250
218
  var CheckboxStory = ({ rowIndex, header = false, checked = false, disabled = false }) => {
251
219
  const attrs = {
@@ -261,7 +229,8 @@ var SwitchStory = ({ colIndex, rowIndex, checked = false, disabled = false }) =>
261
229
  const attrs = {
262
230
  [CONTROL_IDENTIFIERS.switch]: "",
263
231
  "data-row-index": rowIndex.toString(),
264
- "data-col-index": colIndex.toString()
232
+ "data-col-index": colIndex.toString(),
233
+ ...accessoryHandlesPointerdownAttrs
265
234
  };
266
235
  return renderInput(BASE_CLASSES.switch, attrs, checked, disabled, true, "table-switch");
267
236
  };
@@ -288,7 +257,7 @@ var tableControls = {
288
257
 
289
258
  // src/util/schema.ts
290
259
  import { Schema } from "effect";
291
- import { isTypeLiteral, TypeLiteral } from "effect/SchemaAST";
260
+ import { TypeLiteral, isTypeLiteral } from "effect/SchemaAST";
292
261
  var narrowSchema = (schema, paths) => {
293
262
  const ast = schema?.ast;
294
263
  if (isTypeLiteral(ast)) {
@@ -304,21 +273,75 @@ var narrowSchema = (schema, paths) => {
304
273
  // src/model/table-model.ts
305
274
  import { computed as computed3, effect as effect2, signal as signal3 } from "@preact/signals-core";
306
275
  import { Resource as Resource2 } from "@dxos/context";
307
- import { Obj as Obj3, Ref } from "@dxos/echo";
308
- import { FormatEnum as FormatEnum2, getValue as getValue2, setValue, getSnapshot, getSchema, toEffectSchema as toEffectSchema2 } from "@dxos/echo-schema";
276
+ import { Obj as Obj2, Ref } from "@dxos/echo";
277
+ import { FormatEnum as FormatEnum2, getSchema, getValue as getValue2, setValue, toEffectSchema } from "@dxos/echo-schema";
309
278
  import { invariant } from "@dxos/invariant";
310
279
  import { ObjectId } from "@dxos/keys";
311
- import { isLiveObject } from "@dxos/live-object";
280
+ import { getSnapshot, isLiveObject } from "@dxos/live-object";
312
281
  import { fullyQualifiedId } from "@dxos/react-client/echo";
313
282
  import { formatForEditing, parseValue } from "@dxos/react-ui-form";
314
283
  import { ProjectionModel as ProjectionModel2, validateSchema } from "@dxos/schema";
315
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
+
316
301
  // src/model/selection-model.ts
317
302
  import { computed, effect, signal } from "@preact/signals-core";
318
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
+ }
319
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
+ }
320
340
  constructor(_rows, _selectionMode, _initialSelection, _onSelectionChanged) {
321
- 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(() => {
322
345
  const rows = this._rows.value;
323
346
  if (!rows) {
324
347
  return /* @__PURE__ */ new Set();
@@ -367,58 +390,27 @@ var SelectionModel = class extends Resource {
367
390
  };
368
391
  this._selection = signal(new Set(this._initialSelection));
369
392
  }
370
- async _open() {
371
- const selectionWatcher = effect(() => {
372
- touch(this._selection.value);
373
- this._onSelectionChanged?.();
374
- });
375
- this._ctx.onDispose(selectionWatcher);
376
- }
377
- //
378
- // Getters
379
- //
380
- get selection() {
381
- return this._selection;
382
- }
383
- get hasSelection() {
384
- return this._hasSelection;
385
- }
386
- get allRowsSeleted() {
387
- return this._allSelected;
388
- }
389
- get selectionMode() {
390
- return this._selectionMode;
391
- }
392
393
  };
393
394
 
394
395
  // src/model/table-sorting.ts
395
396
  import { computed as computed2, signal as signal2 } from "@preact/signals-core";
396
397
  import orderBy from "lodash.orderby";
397
- import { getValue, FormatEnum, TypeEnum } from "@dxos/echo-schema";
398
+ import { FormatEnum, TypeEnum, getValue } from "@dxos/echo-schema";
398
399
  import { formatForDisplay } from "@dxos/react-ui-form";
399
- var TableSorting = class {
400
- constructor(rows, _view, _projection) {
401
- this._view = _view;
402
- this._projection = _projection;
403
- this._displayToDataIndex = /* @__PURE__ */ new Map();
404
- this._localSort = signal2(void 0);
405
- this._rows = rows;
406
- this._isDirty = computed2(() => {
407
- const local = this._localSort.value;
408
- const viewSort = this._view.query.sort?.[0];
409
- if (local?.type === "cleared") {
410
- return viewSort !== void 0;
411
- }
412
- if (local?.type === "active") {
413
- if (!viewSort) {
414
- return true;
415
- }
416
- return local.sort.fieldId !== viewSort.fieldId || local.sort.direction !== viewSort.direction;
417
- }
418
- 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
419
407
  });
420
- this.sortedRows = this.initialiseSortedRows();
408
+ } else {
409
+ obj[key] = value;
421
410
  }
411
+ return obj;
412
+ }
413
+ var TableSorting = class {
422
414
  /**
423
415
  * @reactive
424
416
  * @returns Local sort if present, falls back to view sort.
@@ -431,7 +423,7 @@ var TableSorting = class {
431
423
  if (local?.type === "active") {
432
424
  return local.sort;
433
425
  }
434
- return this._view.query.sort?.[0];
426
+ return this._view.sort?.[0];
435
427
  }
436
428
  /**
437
429
  * @reactive
@@ -475,11 +467,11 @@ var TableSorting = class {
475
467
  save() {
476
468
  if (this._localSort.value !== void 0) {
477
469
  if (this._localSort.value.type === "active") {
478
- this._view.query.sort = [
470
+ this._view.sort = [
479
471
  this._localSort.value.sort
480
472
  ];
481
473
  } else {
482
- this._view.query.sort = [];
474
+ this._view.sort = [];
483
475
  }
484
476
  this._localSort.value = void 0;
485
477
  }
@@ -554,25 +546,51 @@ var TableSorting = class {
554
546
  value
555
547
  });
556
548
  }
557
- };
558
-
559
- // src/util/tag.ts
560
- var TAG_PATTERN_REGEX = /\[([^\]]+)\]\(([^)]+)\)/g;
561
- var extractTagIds = (value) => {
562
- if (typeof value !== "string") {
563
- return void 0;
564
- }
565
- const ids = [];
566
- let match;
567
- while ((match = TAG_PATTERN_REGEX.exec(value)) !== null) {
568
- if (match[2]) {
569
- ids.push(match[2]);
570
- }
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();
571
577
  }
572
- return ids.length > 0 ? ids : void 0;
573
578
  };
574
579
 
575
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
+ }
576
594
  var __dxlog_file = "/__w/dxos/dxos/packages/ui/react-ui-table/src/model/table-model.ts";
577
595
  var defaultFeatures = {
578
596
  selection: {
@@ -583,252 +601,6 @@ var defaultFeatures = {
583
601
  schemaEditable: false
584
602
  };
585
603
  var TableModel = class extends Resource2 {
586
- constructor({ view, schema, projection, features = {}, sorting = [], initialSelection = [], pinnedRows = {
587
- top: [],
588
- bottom: []
589
- }, rowActions = [], onCellUpdate, onDeleteColumn, onDeleteRows, onInsertRow, onRowOrderChange, onRowAction }) {
590
- super();
591
- this._visibleRange = signal3({
592
- start: {
593
- row: 0,
594
- col: 0
595
- },
596
- end: {
597
- row: 0,
598
- col: 0
599
- }
600
- });
601
- this._rows = signal3([]);
602
- this._draftRows = signal3([]);
603
- //
604
- // Data
605
- //
606
- this.setRows = (obj) => {
607
- this._rows.value = obj;
608
- };
609
- this.getRowCount = () => this._rows.value.length;
610
- /**
611
- * @reactive
612
- */
613
- this.getDraftRowCount = () => this._draftRows.value.length;
614
- this.getColumnCount = () => this._projection?.fields.length ?? 0;
615
- this.insertRow = () => {
616
- const result = this._onInsertRow?.();
617
- if (result === false && this._draftRows.value.length === 0) {
618
- this.createDraftRow();
619
- }
620
- };
621
- this.commitDraftRow = (draftRowIndex) => {
622
- if (draftRowIndex < 0 || draftRowIndex >= this._draftRows.value.length) {
623
- return false;
624
- }
625
- const draftRow = this._draftRows.value[draftRowIndex];
626
- if (!draftRow.valid) {
627
- return false;
628
- }
629
- const success = this._onInsertRow?.(draftRow.data);
630
- if (success) {
631
- const newDraftRows = this._draftRows.value.filter((_, index) => index !== draftRowIndex);
632
- this._draftRows.value = newDraftRows;
633
- }
634
- return success ?? false;
635
- };
636
- this.deleteRow = (rowIndex) => {
637
- const row = this._sorting.getDataIndex(rowIndex);
638
- const obj = this._rows.value[row];
639
- const objectsToDelete = [];
640
- if (this.features.selection.enabled && this._selection.hasSelection.value) {
641
- const selectedRows = this._selection.getSelectedRows();
642
- objectsToDelete.push(...selectedRows);
643
- } else {
644
- objectsToDelete.push(obj);
645
- }
646
- this._onDeleteRows?.(row, objectsToDelete);
647
- };
648
- this.handleRowAction = (actionId, rowIndex) => {
649
- if (!this._onRowAction) {
650
- return;
651
- }
652
- const row = this._sorting.getDataIndex(rowIndex);
653
- const data = this._rows.value[row];
654
- if (data) {
655
- this._onRowAction(actionId, data);
656
- }
657
- };
658
- this.getCellData = (cell) => {
659
- const { col, row, plane } = cell;
660
- const fields = this._projection?.fields ?? [];
661
- if (col < 0 || col >= fields.length) {
662
- return void 0;
663
- }
664
- const field = fields[col];
665
- let value;
666
- if (plane === "frozenRowsEnd") {
667
- if (row >= 0 && row < this._draftRows.value.length) {
668
- value = getValue2(this._draftRows.value[row].data, field.path);
669
- } else {
670
- return void 0;
671
- }
672
- } else {
673
- const dataIndex = this._sorting.getDataIndex(row);
674
- value = getValue2(this._rows.value[dataIndex], field.path);
675
- }
676
- if (value == null) {
677
- return "";
678
- }
679
- const { props } = this._projection.getFieldProjection(field.id);
680
- switch (props.format) {
681
- case FormatEnum2.Ref: {
682
- if (!field.referencePath) {
683
- return "";
684
- }
685
- return getValue2(value.target, field.referencePath);
686
- }
687
- default: {
688
- return formatForEditing({
689
- type: props.type,
690
- format: props.format,
691
- value
692
- });
693
- }
694
- }
695
- };
696
- this.validateCellData = async ({ col, row, plane }, value) => {
697
- const fields = this._projection?.fields ?? [];
698
- if (col < 0 || col >= fields.length) {
699
- return {
700
- valid: false,
701
- error: "Invalid column index"
702
- };
703
- }
704
- const field = fields[col];
705
- const { props } = this._projection.getFieldProjection(field.id);
706
- const transformedValue = editorTextToCellValue(props, value);
707
- const isDraftRow = plane === "frozenRowsEnd";
708
- if (isDraftRow) {
709
- const isInvalidDraftRowIndex = row < 0 || row >= this._draftRows.value.length;
710
- if (isInvalidDraftRowIndex) {
711
- return {
712
- valid: false,
713
- error: "Invalid draft row index"
714
- };
715
- }
716
- const draftRow = this._draftRows.value[row];
717
- const snapshot = {
718
- ...draftRow.data
719
- };
720
- setValue(snapshot, field.path, transformedValue);
721
- const validationErrors = this.validateDraftRowData(snapshot);
722
- if (validationErrors.length > 0) {
723
- const error = validationErrors.find((err) => err.path === field.path);
724
- if (error) {
725
- return {
726
- valid: false,
727
- error: error.message
728
- };
729
- }
730
- }
731
- return {
732
- valid: true
733
- };
734
- } else {
735
- const rowIdx = this._sorting.getDataIndex(row);
736
- const currentRow = this._rows.value[rowIdx];
737
- invariant(currentRow, "Invalid row index", {
738
- F: __dxlog_file,
739
- L: 510,
740
- S: this,
741
- A: [
742
- "currentRow",
743
- "'Invalid row index'"
744
- ]
745
- });
746
- const snapshot = getSnapshot(currentRow);
747
- setValue(snapshot, field.path, transformedValue);
748
- const schema = getSchema(currentRow);
749
- invariant(schema, void 0, {
750
- F: __dxlog_file,
751
- L: 516,
752
- S: this,
753
- A: [
754
- "schema",
755
- ""
756
- ]
757
- });
758
- const validationResult = validateSchema(schema, snapshot);
759
- if (validationResult && validationResult.length > 0) {
760
- const error = validationResult[0];
761
- invariant(error.path === field.path, void 0, {
762
- F: __dxlog_file,
763
- L: 521,
764
- S: this,
765
- A: [
766
- "error.path === field.path",
767
- ""
768
- ]
769
- });
770
- return {
771
- valid: false,
772
- error: error.message
773
- };
774
- }
775
- return {
776
- valid: true
777
- };
778
- }
779
- };
780
- this.setCellData = (cell, value) => {
781
- const { col, row, plane } = cell;
782
- const fields = this._projection?.fields ?? [];
783
- if (col < 0 || col >= fields.length) {
784
- return;
785
- }
786
- const field = fields[col];
787
- const { props } = this._projection.getFieldProjection(field.id);
788
- const transformedValue = editorTextToCellValue(props, value);
789
- if (props.format === FormatEnum2.Ref && !isLiveObject(value)) {
790
- return;
791
- }
792
- if (plane === "frozenRowsEnd") {
793
- if (row >= 0 && row < this._draftRows.value.length) {
794
- setValue(this._draftRows.value[row].data, field.path, transformedValue);
795
- this.validateDraftRow(row);
796
- }
797
- } else {
798
- const rowIdx = this._sorting.getDataIndex(row);
799
- setValue(this._rows.value[rowIdx], field.path, transformedValue);
800
- }
801
- };
802
- this._view = view;
803
- this._projection = projection ?? new ProjectionModel2(schema, view.projection);
804
- this._features = {
805
- ...defaultFeatures,
806
- ...features
807
- };
808
- invariant(!(this._features.dataEditable && this._features.selection.enabled && this._features.selection.mode === "single"), "Single selection is not compatible with editable tables.", {
809
- F: __dxlog_file,
810
- L: 139,
811
- S: this,
812
- A: [
813
- "!(this._features.dataEditable && this._features.selection.enabled && this._features.selection.mode === 'single')",
814
- "'Single selection is not compatible with editable tables.'"
815
- ]
816
- });
817
- this._sorting = new TableSorting(this._rows, this._view, this._projection);
818
- if (sorting.length > 0) {
819
- const [sort] = sorting;
820
- this._sorting.setSort(sort.fieldId, sort.direction);
821
- }
822
- this._selection = new SelectionModel(this._sorting.sortedRows, this._features.selection.mode ?? "multiple", initialSelection, () => this._onRowOrderChange?.());
823
- this._pinnedRows = pinnedRows;
824
- this._rowActions = rowActions;
825
- this._onInsertRow = onInsertRow;
826
- this._onDeleteRows = onDeleteRows;
827
- this._onDeleteColumn = onDeleteColumn;
828
- this._onCellUpdate = onCellUpdate;
829
- this._onRowOrderChange = onRowOrderChange;
830
- this._onRowAction = onRowAction;
831
- }
832
604
  get id() {
833
605
  return fullyQualifiedId(this._view);
834
606
  }
@@ -838,7 +610,7 @@ var TableModel = class extends Resource2 {
838
610
  get table() {
839
611
  invariant(this._table, "Model not initialized", {
840
612
  F: __dxlog_file,
841
- L: 177,
613
+ L: 186,
842
614
  S: this,
843
615
  A: [
844
616
  "this._table",
@@ -877,7 +649,7 @@ var TableModel = class extends Resource2 {
877
649
  get columnMeta() {
878
650
  invariant(this._columnMeta, void 0, {
879
651
  F: __dxlog_file,
880
- L: 216,
652
+ L: 225,
881
653
  S: this,
882
654
  A: [
883
655
  "this._columnMeta",
@@ -901,12 +673,12 @@ var TableModel = class extends Resource2 {
901
673
  //
902
674
  async _open() {
903
675
  const presentation = this._view.presentation.target ?? await this._view.presentation.load();
904
- invariant(Obj3.instanceOf(TableView, presentation), void 0, {
676
+ invariant(Obj2.instanceOf(schema_exports.Table, presentation), void 0, {
905
677
  F: __dxlog_file,
906
- L: 239,
678
+ L: 248,
907
679
  S: this,
908
680
  A: [
909
- "Obj.instanceOf(TableView, presentation)",
681
+ "Obj.instanceOf(Table.Table, presentation)",
910
682
  ""
911
683
  ]
912
684
  });
@@ -935,7 +707,7 @@ var TableModel = class extends Resource2 {
935
707
  },
936
708
  frozenColsEnd: {
937
709
  0: {
938
- size: 40,
710
+ size: 32,
939
711
  resizeable: false
940
712
  }
941
713
  }
@@ -1025,7 +797,7 @@ var TableModel = class extends Resource2 {
1025
797
  this._draftRows.value = newDraftRows;
1026
798
  }
1027
799
  validateDraftRowData(data) {
1028
- const schema = toEffectSchema2(this._projection.baseSchema);
800
+ const schema = toEffectSchema(this._projection.baseSchema);
1029
801
  return validateSchema(schema, data) || [];
1030
802
  }
1031
803
  /**
@@ -1090,23 +862,256 @@ var TableModel = class extends Resource2 {
1090
862
  this.table.sizes[field.path] = newWidth;
1091
863
  }
1092
864
  }
1093
- }
1094
- //
1095
- // Pinning
1096
- //
1097
- // TODO(burdon): Change to setPinned(on/off).
1098
- pinRow(rowIndex, side) {
1099
- this._pinnedRows[side].push(rowIndex);
1100
- }
1101
- unpinRow(rowIndex) {
1102
- this._pinnedRows.top = this._pinnedRows.top.filter((index) => index !== rowIndex);
1103
- this._pinnedRows.bottom = this._pinnedRows.bottom.filter((index) => index !== rowIndex);
1104
- }
1105
- //
1106
- // View operations
1107
- //
1108
- saveView() {
1109
- 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: 521,
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: 527,
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: 532,
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._features = {
1089
+ ...defaultFeatures,
1090
+ ...features
1091
+ };
1092
+ invariant(!(this._features.dataEditable && this._features.selection.enabled && this._features.selection.mode === "single"), "Single selection is not compatible with editable tables.", {
1093
+ F: __dxlog_file,
1094
+ L: 148,
1095
+ S: this,
1096
+ A: [
1097
+ "!(this._features.dataEditable && this._features.selection.enabled && this._features.selection.mode === 'single')",
1098
+ "'Single selection is not compatible with editable tables.'"
1099
+ ]
1100
+ });
1101
+ this._sorting = new TableSorting(this._rows, this._view, this._projection);
1102
+ if (sorting.length > 0) {
1103
+ const [sort] = sorting;
1104
+ this._sorting.setSort(sort.fieldId, sort.direction);
1105
+ }
1106
+ this._selection = new SelectionModel(this._sorting.sortedRows, this._features.selection.mode ?? "multiple", initialSelection, () => this._onRowOrderChange?.());
1107
+ this._pinnedRows = pinnedRows;
1108
+ this._rowActions = rowActions;
1109
+ this._onInsertRow = onInsertRow;
1110
+ this._onDeleteRows = onDeleteRows;
1111
+ this._onDeleteColumn = onDeleteColumn;
1112
+ this._onCellUpdate = onCellUpdate;
1113
+ this._onRowOrderChange = onRowOrderChange;
1114
+ this._onRowAction = onRowAction;
1110
1115
  }
1111
1116
  };
1112
1117
  var editorTextToCellValue = (props, value) => {
@@ -1143,46 +1148,65 @@ var editorTextToCellValue = (props, value) => {
1143
1148
  // src/model/modal-controller.ts
1144
1149
  import { signal as signal4 } from "@preact/signals-core";
1145
1150
  import { log } from "@dxos/log";
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 __dxlog_file2 = "/__w/dxos/dxos/packages/ui/react-ui-table/src/model/modal-controller.ts";
1147
1165
  var ModalController = class {
1166
+ get state() {
1167
+ return this._state;
1168
+ }
1169
+ get trigger() {
1170
+ return this._triggerRef;
1171
+ }
1148
1172
  constructor() {
1149
- this._state = signal4({
1173
+ _define_property4(this, "_state", signal4({
1150
1174
  type: "closed"
1151
- });
1152
- this._triggerRef = {
1175
+ }));
1176
+ _define_property4(this, "_triggerRef", {
1153
1177
  current: null
1154
- };
1155
- this.setTrigger = (trigger) => {
1178
+ });
1179
+ _define_property4(this, "setTrigger", (trigger) => {
1156
1180
  this._triggerRef.current = trigger;
1157
- };
1158
- this.showRowMenu = (rowIndex) => {
1181
+ });
1182
+ _define_property4(this, "showRowMenu", (rowIndex) => {
1159
1183
  this._state.value = {
1160
1184
  type: "row",
1161
1185
  rowIndex
1162
1186
  };
1163
- };
1164
- this.showColumnMenu = (fieldId) => {
1187
+ });
1188
+ _define_property4(this, "showColumnMenu", (fieldId) => {
1165
1189
  this._state.value = {
1166
1190
  type: "column",
1167
1191
  fieldId
1168
1192
  };
1169
- };
1170
- this.showColumnCreator = () => {
1193
+ });
1194
+ _define_property4(this, "showColumnCreator", () => {
1171
1195
  this._state.value = {
1172
1196
  type: "columnSettings",
1173
1197
  mode: {
1174
1198
  type: "create"
1175
1199
  }
1176
1200
  };
1177
- };
1178
- this.showReferencePanel = (targetId, schemaId) => {
1201
+ });
1202
+ _define_property4(this, "showReferencePanel", (targetId, schemaId) => {
1179
1203
  this._state.value = {
1180
1204
  type: "refPanel",
1181
1205
  targetId,
1182
1206
  typename: schemaId
1183
1207
  };
1184
- };
1185
- this.openColumnSettings = () => {
1208
+ });
1209
+ _define_property4(this, "openColumnSettings", () => {
1186
1210
  if (this._state.value.type === "column") {
1187
1211
  const fieldId = this._state.value.fieldId;
1188
1212
  requestAnimationFrame(() => {
@@ -1195,8 +1219,8 @@ var ModalController = class {
1195
1219
  };
1196
1220
  });
1197
1221
  }
1198
- };
1199
- this.openCreateRef = (typename, anchorCell, initialValues, onCreate) => {
1222
+ });
1223
+ _define_property4(this, "openCreateRef", (typename, anchorCell, initialValues, onCreate) => {
1200
1224
  if (anchorCell) {
1201
1225
  this._triggerRef.current = anchorCell;
1202
1226
  this._state.value = {
@@ -1213,45 +1237,38 @@ var ModalController = class {
1213
1237
  C: (f, a) => f(...a)
1214
1238
  });
1215
1239
  }
1216
- };
1217
- this.close = () => {
1240
+ });
1241
+ _define_property4(this, "close", () => {
1218
1242
  this._state.value = {
1219
1243
  type: "closed"
1220
1244
  };
1221
- };
1222
- }
1223
- get state() {
1224
- return this._state;
1225
- }
1226
- get trigger() {
1227
- return this._triggerRef;
1245
+ });
1228
1246
  }
1229
1247
  };
1230
1248
 
1231
1249
  // src/model/table-presentation.ts
1232
1250
  import { signal as signal5 } from "@preact/signals-core";
1233
1251
  import { isNotNullable } from "effect/Predicate";
1234
- import { Obj as Obj4 } from "@dxos/echo";
1235
- import { FormatEnum as FormatEnum3, getValue as getValue3, TypeEnum as TypeEnum2 } from "@dxos/echo-schema";
1252
+ import { Obj as Obj3 } from "@dxos/echo";
1253
+ import { FormatEnum as FormatEnum3, TypeEnum as TypeEnum2, getValue as getValue3 } from "@dxos/echo-schema";
1236
1254
  import { cellClassesForFieldType, formatForDisplay as formatForDisplay2 } from "@dxos/react-ui-form";
1237
1255
  import { toPlaneCellIndex } from "@dxos/react-ui-grid";
1238
1256
  import { mx } from "@dxos/react-ui-theme";
1239
1257
  import { VIEW_FIELD_LIMIT } from "@dxos/schema";
1240
- var TablePresentation = class {
1241
- constructor(model, _visibleRange = signal5({
1242
- start: {
1243
- row: 0,
1244
- col: 0
1245
- },
1246
- end: {
1247
- row: 0,
1248
- col: 0
1249
- }
1250
- })) {
1251
- this.model = model;
1252
- this._visibleRange = _visibleRange;
1253
- this.fieldProjectionCache = /* @__PURE__ */ new Map();
1258
+ function _define_property5(obj, key, value) {
1259
+ if (key in obj) {
1260
+ Object.defineProperty(obj, key, {
1261
+ value,
1262
+ enumerable: true,
1263
+ configurable: true,
1264
+ writable: true
1265
+ });
1266
+ } else {
1267
+ obj[key] = value;
1254
1268
  }
1269
+ return obj;
1270
+ }
1271
+ var TablePresentation = class {
1255
1272
  getCells(range, plane) {
1256
1273
  this.fieldProjectionCache.clear();
1257
1274
  let cells;
@@ -1278,6 +1295,9 @@ var TablePresentation = class {
1278
1295
  case "frozenRowsEnd":
1279
1296
  cells = this.getDraftRowCells(range);
1280
1297
  break;
1298
+ case "fixedEndStart":
1299
+ cells = this.getDraftIconCells(range);
1300
+ break;
1281
1301
  case "fixedEndEnd":
1282
1302
  cells = this.getDraftActionCells(range);
1283
1303
  break;
@@ -1336,10 +1356,7 @@ var TablePresentation = class {
1336
1356
  }
1337
1357
  };
1338
1358
  const classes = [];
1339
- const formatClasses = cellClassesForFieldType({
1340
- type: props.type,
1341
- format: props.format
1342
- });
1359
+ const formatClasses = cellClassesForFieldType(props);
1343
1360
  if (formatClasses) {
1344
1361
  classes.push(formatClasses);
1345
1362
  }
@@ -1347,9 +1364,7 @@ var TablePresentation = class {
1347
1364
  if (rowSelectionClasses) {
1348
1365
  classes.push(rowSelectionClasses);
1349
1366
  }
1350
- if (classes.length > 0) {
1351
- cell.className = mx(classes.flat());
1352
- }
1367
+ cell.className = mx(classes);
1353
1368
  if (props.type === TypeEnum2.Array) {
1354
1369
  const targetArray = getValue3(obj, field.path);
1355
1370
  if (targetArray && Array.isArray(targetArray)) {
@@ -1380,8 +1395,8 @@ var TablePresentation = class {
1380
1395
  if (props.format === FormatEnum3.Ref && props.referenceSchema) {
1381
1396
  const targetObj = getValue3(obj, field.path)?.target;
1382
1397
  if (targetObj) {
1383
- const dxn = Obj4.getDXN(targetObj)?.toString();
1384
- cell.accessoryHtml = `<dx-ref-tag refId=${dxn} class="dx-button is-6 pli-[3px] pbe-[2px] min-bs-0 absolute inline-end-1"><dx-icon icon="ph--link-simple--regular"/></dx-ref-tag>`;
1398
+ const dxn = Obj3.getDXN(targetObj)?.toString();
1399
+ 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>`;
1385
1400
  }
1386
1401
  }
1387
1402
  if (props.format === FormatEnum3.Boolean) {
@@ -1443,24 +1458,37 @@ var TablePresentation = class {
1443
1458
  const cells = {};
1444
1459
  const fields = this.model.projection?.fields ?? [];
1445
1460
  const draftRows = this.model.draftRows.value;
1446
- for (let row = range.start.row; row <= range.end.row && row < draftRows.length; row++) {
1447
- const draftRow = draftRows[row];
1461
+ if (draftRows.length === 0) {
1448
1462
  for (let col = range.start.col; col <= range.end.col && col < fields.length; col++) {
1449
- const field = fields[col];
1450
- if (!field) {
1451
- continue;
1452
- }
1453
- this.createDataCell(cells, draftRow.data, field, col, row);
1454
- if (this.model.hasDraftRowValidationError(row, field.path)) {
1463
+ cells[toPlaneCellIndex({
1464
+ col,
1465
+ row: 0
1466
+ })] = {
1467
+ value: "",
1468
+ readonly: true,
1469
+ className: "dx-grid__row--cta__cell"
1470
+ };
1471
+ }
1472
+ } else {
1473
+ for (let row = range.start.row; row <= range.end.row && row < draftRows.length; row++) {
1474
+ const draftRow = draftRows[row];
1475
+ for (let col = range.start.col; col <= range.end.col && col < fields.length; col++) {
1455
1476
  const cellIndex = toPlaneCellIndex({
1456
1477
  col,
1457
1478
  row
1458
1479
  });
1459
- const cellValue = cells[cellIndex];
1460
- if (cellValue) {
1461
- const existingClasses = cellValue.className || "";
1462
- const draftClasses = "dx-grid__cell--flagged";
1463
- cellValue.className = existingClasses ? `${existingClasses} ${draftClasses}` : draftClasses;
1480
+ const field = fields[col];
1481
+ if (!field) {
1482
+ continue;
1483
+ }
1484
+ this.createDataCell(cells, draftRow.data, field, col, row);
1485
+ if (this.model.hasDraftRowValidationError(row, field.path)) {
1486
+ const cellValue = cells[cellIndex];
1487
+ if (cellValue) {
1488
+ const existingClasses = cellValue.className || "";
1489
+ const draftClasses = "dx-grid__cell--flagged";
1490
+ cellValue.className = existingClasses ? `${existingClasses} ${draftClasses}` : draftClasses;
1491
+ }
1464
1492
  }
1465
1493
  }
1466
1494
  }
@@ -1479,10 +1507,10 @@ var TablePresentation = class {
1479
1507
  row: 0
1480
1508
  })] = {
1481
1509
  // TODO(burdon): Use same logic as form for fallback title.
1482
- value: props.title ?? field.path,
1483
- readonly: true,
1510
+ value: "",
1484
1511
  resizeHandle: "col",
1485
1512
  accessoryHtml: `
1513
+ <span class="grow min-is-0 truncate">${props.title ?? field.path}</span>
1486
1514
  ${direction !== void 0 ? tableButtons.sort.render({
1487
1515
  fieldId: field.id,
1488
1516
  direction
@@ -1491,7 +1519,7 @@ var TablePresentation = class {
1491
1519
  fieldId: field.id
1492
1520
  })}
1493
1521
  `,
1494
- className: "!bg-toolbarSurface"
1522
+ className: "!bg-toolbarSurface !text-description [&>div]:flex [&>div]:items-stretch"
1495
1523
  };
1496
1524
  }
1497
1525
  return cells;
@@ -1582,23 +1610,67 @@ var TablePresentation = class {
1582
1610
  getDraftActionCells(range) {
1583
1611
  const cells = {};
1584
1612
  const draftRows = this.model.draftRows.value;
1585
- for (let row = range.start.row; row <= range.end.row && row < draftRows.length; row++) {
1586
- const draftRow = draftRows[row];
1587
- const disabled = !draftRow.valid;
1613
+ if (draftRows.length === 0) {
1614
+ cells[toPlaneCellIndex({
1615
+ col: 0,
1616
+ row: 0
1617
+ })] = {
1618
+ value: "",
1619
+ className: "dx-grid__row--cta__cell",
1620
+ readonly: true
1621
+ };
1622
+ } else {
1623
+ for (let row = range.start.row; row <= range.end.row && row < draftRows.length; row++) {
1624
+ const draftRow = draftRows[row];
1625
+ const disabled = !draftRow.valid;
1626
+ cells[toPlaneCellIndex({
1627
+ col: 0,
1628
+ row
1629
+ })] = {
1630
+ value: "",
1631
+ readonly: true,
1632
+ accessoryHtml: tableButtons.saveDraftRow.render({
1633
+ rowIndex: row,
1634
+ disabled
1635
+ })
1636
+ };
1637
+ }
1638
+ }
1639
+ return cells;
1640
+ }
1641
+ getDraftIconCells(range) {
1642
+ const cells = {};
1643
+ const draftRows = this.model.draftRows.value;
1644
+ for (let row = range.start.row; row <= range.end.row; row++) {
1588
1645
  cells[toPlaneCellIndex({
1589
1646
  col: 0,
1590
1647
  row
1591
1648
  })] = {
1592
1649
  value: "",
1593
1650
  readonly: true,
1594
- accessoryHtml: tableButtons.saveDraftRow.render({
1595
- rowIndex: row,
1596
- disabled
1597
- })
1651
+ accessoryHtml: '<dx-icon icon="ph--plus--regular" class="contents"></dx-icon>',
1652
+ className: mx("[&>div]:grid [&>div]:place-content-center", draftRows.length < 1 && "dx-grid__row--cta__cell")
1598
1653
  };
1599
1654
  }
1600
1655
  return cells;
1601
1656
  }
1657
+ constructor(model, _visibleRange = signal5({
1658
+ start: {
1659
+ row: 0,
1660
+ col: 0
1661
+ },
1662
+ end: {
1663
+ row: 0,
1664
+ col: 0
1665
+ }
1666
+ })) {
1667
+ _define_property5(this, "model", void 0);
1668
+ _define_property5(this, "_visibleRange", void 0);
1669
+ _define_property5(this, "fieldProjectionCache", void 0);
1670
+ this.model = model;
1671
+ this._visibleRange = _visibleRange;
1672
+ this.fieldProjectionCache = /* @__PURE__ */ new Map();
1673
+ }
1602
1674
  };
1603
1675
  var cellClassesForRowSelection = (selected, selectionMode) => {
1604
1676
  if (!selected) {
@@ -1712,18 +1784,18 @@ var useTableModel = ({ view, schema, projection, rows, rowActions, features, onS
1712
1784
 
1713
1785
  // src/hooks/useAddRow.ts
1714
1786
  import { useCallback } from "react";
1715
- import { Obj as Obj5 } from "@dxos/echo";
1787
+ import { Obj as Obj4 } from "@dxos/echo";
1716
1788
  var useAddRow = ({ space, schema }) => {
1717
1789
  return useCallback((data) => {
1718
1790
  if (space && schema) {
1719
1791
  try {
1720
- space.db.add(Obj5.make(schema, data ?? {}));
1721
- return true;
1792
+ space.db.add(Obj4.make(schema, data ?? {}));
1793
+ return "final";
1722
1794
  } catch (error) {
1723
- return false;
1795
+ return "draft";
1724
1796
  }
1725
1797
  }
1726
- return false;
1798
+ return "final";
1727
1799
  }, [
1728
1800
  space,
1729
1801
  schema
@@ -1734,7 +1806,6 @@ export {
1734
1806
  getBaseSchema,
1735
1807
  makeDynamicTable,
1736
1808
  touch,
1737
- createTable,
1738
1809
  BUTTON_IDENTIFIERS,
1739
1810
  tableButtons,
1740
1811
  CONTROL_IDENTIFIERS,
@@ -1749,4 +1820,4 @@ export {
1749
1820
  useTableModel,
1750
1821
  useAddRow
1751
1822
  };
1752
- //# sourceMappingURL=chunk-Y66YLSTC.mjs.map
1823
+ //# sourceMappingURL=chunk-RNQDU7IQ.mjs.map