@dxos/react-ui-table 0.8.4-main.28f8d3d → 0.8.4-main.2c6827d

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 (114) hide show
  1. package/dist/lib/browser/chunk-2PFAPQL4.mjs +66 -0
  2. package/dist/lib/browser/chunk-2PFAPQL4.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-ZAOSIG3L.mjs → chunk-GS2UNGJK.mjs} +174 -213
  4. package/dist/lib/browser/chunk-GS2UNGJK.mjs.map +7 -0
  5. package/dist/lib/browser/index.mjs +411 -515
  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 +12 -9
  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-6POOFFYF.mjs +67 -0
  12. package/dist/lib/node-esm/chunk-6POOFFYF.mjs.map +7 -0
  13. package/dist/lib/node-esm/{chunk-ZOFFI3JJ.mjs → chunk-TRR3C5NX.mjs} +174 -213
  14. package/dist/lib/node-esm/chunk-TRR3C5NX.mjs.map +7 -0
  15. package/dist/lib/node-esm/index.mjs +411 -515
  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 +12 -9
  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/DynamicTable.d.ts +2 -2
  22. package/dist/types/src/components/Table/DynamicTable.d.ts.map +1 -1
  23. package/dist/types/src/components/Table/DynamicTable.stories.d.ts +51 -3
  24. package/dist/types/src/components/Table/DynamicTable.stories.d.ts.map +1 -1
  25. package/dist/types/src/components/Table/Relations.stories.d.ts +103 -5
  26. package/dist/types/src/components/Table/Relations.stories.d.ts.map +1 -1
  27. package/dist/types/src/components/Table/RowActionsMenu.d.ts.map +1 -1
  28. package/dist/types/src/components/Table/Table.d.ts +8 -5
  29. package/dist/types/src/components/Table/Table.d.ts.map +1 -1
  30. package/dist/types/src/components/Table/Table.stories.d.ts +41 -3
  31. package/dist/types/src/components/Table/Table.stories.d.ts.map +1 -1
  32. package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts +12 -6
  33. package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts.map +1 -1
  34. package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts +8 -13
  35. package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts.map +1 -1
  36. package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts +39 -4
  37. package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts.map +1 -1
  38. package/dist/types/src/components/TableCellEditor/index.d.ts +1 -0
  39. package/dist/types/src/components/TableCellEditor/index.d.ts.map +1 -1
  40. package/dist/types/src/components/TableToolbar/TableToolbar.d.ts +2 -2
  41. package/dist/types/src/components/TableToolbar/TableToolbar.d.ts.map +1 -1
  42. package/dist/types/src/components/testing.d.ts +3 -3
  43. package/dist/types/src/components/testing.d.ts.map +1 -1
  44. package/dist/types/src/hooks/useAddRow.d.ts +3 -2
  45. package/dist/types/src/hooks/useAddRow.d.ts.map +1 -1
  46. package/dist/types/src/hooks/useTableModel.d.ts +3 -3
  47. package/dist/types/src/hooks/useTableModel.d.ts.map +1 -1
  48. package/dist/types/src/model/modal-controller.d.ts +0 -7
  49. package/dist/types/src/model/modal-controller.d.ts.map +1 -1
  50. package/dist/types/src/model/table-model.d.ts +9 -8
  51. package/dist/types/src/model/table-model.d.ts.map +1 -1
  52. package/dist/types/src/model/table-presentation.d.ts +1 -1
  53. package/dist/types/src/model/table-presentation.d.ts.map +1 -1
  54. package/dist/types/src/model/table-sorting.d.ts +2 -3
  55. package/dist/types/src/model/table-sorting.d.ts.map +1 -1
  56. package/dist/types/src/testing/useTestTableModel.d.ts +3 -22
  57. package/dist/types/src/testing/useTestTableModel.d.ts.map +1 -1
  58. package/dist/types/src/types/index.d.ts +1 -1
  59. package/dist/types/src/types/index.d.ts.map +1 -1
  60. package/dist/types/src/types/schema.d.ts +25 -5
  61. package/dist/types/src/types/schema.d.ts.map +1 -1
  62. package/dist/types/src/util/dynamic-table.d.ts +5 -6
  63. package/dist/types/src/util/dynamic-table.d.ts.map +1 -1
  64. package/dist/types/src/util/index.d.ts +0 -1
  65. package/dist/types/src/util/index.d.ts.map +1 -1
  66. package/dist/types/src/util/schema.d.ts +1 -1
  67. package/dist/types/src/util/schema.d.ts.map +1 -1
  68. package/dist/types/src/util/table-buttons.d.ts.map +1 -1
  69. package/dist/types/tsconfig.tsbuildinfo +1 -1
  70. package/package.json +53 -51
  71. package/src/components/Table/DynamicTable.stories.tsx +15 -12
  72. package/src/components/Table/DynamicTable.tsx +4 -7
  73. package/src/components/Table/Relations.stories.tsx +160 -42
  74. package/src/components/Table/RowActionsMenu.tsx +21 -13
  75. package/src/components/Table/Table.stories.tsx +63 -56
  76. package/src/components/Table/Table.tsx +109 -90
  77. package/src/components/TableCellEditor/FormCellEditor.tsx +153 -42
  78. package/src/components/TableCellEditor/TableCellEditor.stories.tsx +24 -64
  79. package/src/components/TableCellEditor/TableCellEditor.tsx +62 -208
  80. package/src/components/TableCellEditor/index.ts +1 -0
  81. package/src/components/TableToolbar/TableToolbar.tsx +32 -22
  82. package/src/components/testing.ts +2 -2
  83. package/src/hooks/useAddRow.ts +7 -5
  84. package/src/hooks/useTableModel.ts +5 -5
  85. package/src/model/modal-controller.ts +0 -28
  86. package/src/model/table-model.test.ts +19 -11
  87. package/src/model/table-model.ts +36 -24
  88. package/src/model/table-presentation.test.ts +22 -21
  89. package/src/model/table-presentation.ts +58 -39
  90. package/src/model/table-sorting.ts +16 -7
  91. package/src/playwright/TableManager.ts +1 -1
  92. package/src/playwright/smoke.spec.ts +51 -49
  93. package/src/testing/useTestTableModel.ts +10 -7
  94. package/src/types/index.ts +1 -1
  95. package/src/types/schema.ts +63 -6
  96. package/src/util/dynamic-table.ts +15 -16
  97. package/src/util/index.ts +0 -1
  98. package/src/util/schema.ts +4 -4
  99. package/src/util/table-buttons.ts +3 -3
  100. package/dist/lib/browser/chunk-L2LSB6KV.mjs +0 -18
  101. package/dist/lib/browser/chunk-L2LSB6KV.mjs.map +0 -7
  102. package/dist/lib/browser/chunk-ZAOSIG3L.mjs.map +0 -7
  103. package/dist/lib/node-esm/chunk-NXZ4CJYX.mjs +0 -20
  104. package/dist/lib/node-esm/chunk-NXZ4CJYX.mjs.map +0 -7
  105. package/dist/lib/node-esm/chunk-ZOFFI3JJ.mjs.map +0 -7
  106. package/dist/types/src/components/Table/CreateRefPanel.d.ts +0 -9
  107. package/dist/types/src/components/Table/CreateRefPanel.d.ts.map +0 -1
  108. package/dist/types/src/components/TableCellEditor/extension.d.ts +0 -13
  109. package/dist/types/src/components/TableCellEditor/extension.d.ts.map +0 -1
  110. package/dist/types/src/util/table.d.ts +0 -12
  111. package/dist/types/src/util/table.d.ts.map +0 -1
  112. package/src/components/Table/CreateRefPanel.tsx +0 -86
  113. package/src/components/TableCellEditor/extension.ts +0 -61
  114. package/src/util/table.ts +0 -53
@@ -1,11 +1,11 @@
1
1
  import {
2
- TableView
3
- } from "./chunk-L2LSB6KV.mjs";
2
+ schema_exports
3
+ } from "./chunk-2PFAPQL4.mjs";
4
4
 
5
5
  // src/util/dynamic-table.ts
6
- import { Obj } from "@dxos/echo";
7
- import { getTypename, toJsonSchema } from "@dxos/echo-schema";
8
- import { ProjectionModel, createView, getSchemaFromPropertyDefinitions } from "@dxos/schema";
6
+ import { Filter, Obj, Query } from "@dxos/echo";
7
+ import { getTypename, toJsonSchema } from "@dxos/echo/internal";
8
+ import { ProjectionModel, View, getSchemaFromPropertyDefinitions } from "@dxos/schema";
9
9
  var getBaseSchema = ({ typename, properties, jsonSchema, schema }) => {
10
10
  if (typename && properties) {
11
11
  const schema2 = getSchemaFromPropertyDefinitions(typename, properties);
@@ -27,12 +27,12 @@ var getBaseSchema = ({ typename, properties, jsonSchema, schema }) => {
27
27
  throw new Error("invalid properties");
28
28
  }
29
29
  };
30
- var makeDynamicTable = ({ typename, jsonSchema, properties }) => {
31
- const table = Obj.make(TableView, {
30
+ var makeDynamicTable = ({ jsonSchema, properties }) => {
31
+ const table = Obj.make(schema_exports.Table, {
32
32
  sizes: {}
33
33
  });
34
- const view = createView({
35
- typename,
34
+ const view = View.make({
35
+ query: Query.select(Filter.everything()),
36
36
  jsonSchema,
37
37
  presentation: table,
38
38
  ...properties && {
@@ -40,6 +40,7 @@ var makeDynamicTable = ({ typename, jsonSchema, properties }) => {
40
40
  }
41
41
  });
42
42
  const projection = new ProjectionModel(jsonSchema, view.projection);
43
+ projection.normalizeView();
43
44
  if (properties && projection.fields) {
44
45
  setProperties(view, projection, table, properties);
45
46
  }
@@ -67,7 +68,7 @@ var setProperties = (view, projection, table, properties) => {
67
68
  }
68
69
  if (property.sort) {
69
70
  const fieldId = field.id;
70
- view.query.sort = [
71
+ view.sort = [
71
72
  {
72
73
  fieldId,
73
74
  direction: property.sort
@@ -81,41 +82,6 @@ var setProperties = (view, projection, table, properties) => {
81
82
  // src/util/signals.ts
82
83
  var touch = (value) => value;
83
84
 
84
- // src/util/table.ts
85
- import { Match } from "effect";
86
- import { Obj as Obj2 } from "@dxos/echo";
87
- import { toEffectSchema } from "@dxos/echo-schema";
88
- import { createViewFromSpace, getSchemaProperties } from "@dxos/schema";
89
- var createTable = async ({ sizes, ...props }) => {
90
- const table = Obj2.make(TableView, {
91
- sizes: {}
92
- });
93
- const { jsonSchema, view } = await createViewFromSpace({
94
- ...props,
95
- presentation: table
96
- });
97
- const schema = toEffectSchema(jsonSchema);
98
- const shouldIncludeId = props.fields?.find((field) => field === "id") !== void 0;
99
- const properties = getSchemaProperties(schema.ast, {}, shouldIncludeId);
100
- for (const property of properties) {
101
- if (sizes?.[property.name]) {
102
- table.sizes[property.name] = sizes[property.name];
103
- continue;
104
- }
105
- Match.type().pipe(Match.when("boolean", () => {
106
- table.sizes[property.name] = 100;
107
- }), Match.when("number", () => {
108
- table.sizes[property.name] = 100;
109
- }), Match.orElse(() => {
110
- }))(property.type);
111
- }
112
- return {
113
- jsonSchema,
114
- schema,
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" : ""} data-dx-grid-action="accessory"><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
  });
@@ -290,14 +256,14 @@ var tableControls = {
290
256
  };
291
257
 
292
258
  // src/util/schema.ts
293
- import { Schema } from "effect";
294
- import { TypeLiteral, isTypeLiteral } from "effect/SchemaAST";
259
+ import * as Schema from "effect/Schema";
260
+ import * as SchemaAST from "effect/SchemaAST";
295
261
  var narrowSchema = (schema, paths) => {
296
262
  const ast = schema?.ast;
297
- if (isTypeLiteral(ast)) {
263
+ if (SchemaAST.isTypeLiteral(ast)) {
298
264
  const propertySignatures = ast.propertySignatures.filter((signature) => paths.includes(signature.name.toString()));
299
265
  if (propertySignatures.length > 0) {
300
- const narrowType = new TypeLiteral(propertySignatures, []);
266
+ const narrowType = new SchemaAST.TypeLiteral(propertySignatures, []);
301
267
  return Schema.make(narrowType);
302
268
  }
303
269
  }
@@ -307,12 +273,11 @@ var narrowSchema = (schema, paths) => {
307
273
  // src/model/table-model.ts
308
274
  import { computed as computed3, effect as effect2, signal as signal3 } from "@preact/signals-core";
309
275
  import { Resource as Resource2 } from "@dxos/context";
310
- import { Obj as Obj3, Ref } from "@dxos/echo";
311
- import { FormatEnum as FormatEnum2, getSchema, getSnapshot, getValue as getValue2, setValue, toEffectSchema as toEffectSchema2 } from "@dxos/echo-schema";
276
+ import { Obj as Obj2, Ref } from "@dxos/echo";
277
+ import { FormatEnum as FormatEnum2, getSchema, getValue as getValue2, setValue, toEffectSchema } from "@dxos/echo/internal";
312
278
  import { invariant } from "@dxos/invariant";
313
279
  import { ObjectId } from "@dxos/keys";
314
- import { isLiveObject } from "@dxos/live-object";
315
- import { fullyQualifiedId } from "@dxos/react-client/echo";
280
+ import { getSnapshot, isLiveObject } from "@dxos/live-object";
316
281
  import { formatForEditing, parseValue } from "@dxos/react-ui-form";
317
282
  import { ProjectionModel as ProjectionModel2, validateSchema } from "@dxos/schema";
318
283
 
@@ -341,57 +306,26 @@ var SelectionModel = class extends Resource {
341
306
  _initialSelection;
342
307
  _onSelectionChanged;
343
308
  _selection;
344
- _validSelectedIds;
345
- _hasSelection;
346
- _allSelected;
309
+ _validSelectedIds = computed(() => {
310
+ const rows = this._rows.value;
311
+ if (!rows) {
312
+ return /* @__PURE__ */ new Set();
313
+ }
314
+ const validIds = new Set(rows.map((row) => row.id));
315
+ return new Set([
316
+ ...this._selection.value
317
+ ].filter((id) => validIds.has(id)));
318
+ });
319
+ _hasSelection = computed(() => this._validSelectedIds.value.size > 0);
320
+ _allSelected = computed(() => {
321
+ const rows = this._rows.value;
322
+ if (rows.length === 0) {
323
+ return false;
324
+ }
325
+ return rows.every((row) => this._selection.value.has(row.id));
326
+ });
347
327
  constructor(_rows, _selectionMode, _initialSelection, _onSelectionChanged) {
348
- super(), this._rows = _rows, this._selectionMode = _selectionMode, this._initialSelection = _initialSelection, this._onSelectionChanged = _onSelectionChanged, this._validSelectedIds = computed(() => {
349
- const rows = this._rows.value;
350
- if (!rows) {
351
- return /* @__PURE__ */ new Set();
352
- }
353
- const validIds = new Set(rows.map((row) => row.id));
354
- return new Set([
355
- ...this._selection.value
356
- ].filter((id) => validIds.has(id)));
357
- }), this._hasSelection = computed(() => this._validSelectedIds.value.size > 0), this._allSelected = computed(() => {
358
- const rows = this._rows.value;
359
- if (rows.length === 0) {
360
- return false;
361
- }
362
- return rows.every((row) => this._selection.value.has(row.id));
363
- }), this.getSelectedRows = () => {
364
- const selectedIds = this._validSelectedIds.value;
365
- return this._rows.value.filter((row) => selectedIds.has(row.id));
366
- }, this.isRowIndexSelected = (rowIndex) => {
367
- const row = this._rows.value[rowIndex];
368
- return this._selection.value.has(row.id);
369
- }, this.isObjectSelected = (object) => {
370
- return this._selection.value.has(object.id);
371
- }, this.toggleSelectionForRowIndex = (rowIndex) => {
372
- const row = this._rows.value[rowIndex];
373
- const newSelection = new Set(this._selection.value);
374
- if (newSelection.has(row.id)) {
375
- newSelection.delete(row.id);
376
- } else {
377
- if (this._selectionMode === "single") {
378
- newSelection.clear();
379
- }
380
- newSelection.add(row.id);
381
- }
382
- this._selection.value = newSelection;
383
- }, this.setSelection = (mode) => {
384
- switch (mode) {
385
- case "all": {
386
- this._selection.value = new Set(this._rows.value.map((row) => row.id));
387
- break;
388
- }
389
- case "none": {
390
- this._selection.value = /* @__PURE__ */ new Set();
391
- break;
392
- }
393
- }
394
- };
328
+ super(), this._rows = _rows, this._selectionMode = _selectionMode, this._initialSelection = _initialSelection, this._onSelectionChanged = _onSelectionChanged;
395
329
  this._selection = signal(new Set(this._initialSelection));
396
330
  }
397
331
  async _open() {
@@ -416,38 +350,67 @@ var SelectionModel = class extends Resource {
416
350
  get selectionMode() {
417
351
  return this._selectionMode;
418
352
  }
419
- getSelectedRows;
420
- isRowIndexSelected;
421
- isObjectSelected;
353
+ getSelectedRows = () => {
354
+ const selectedIds = this._validSelectedIds.value;
355
+ return this._rows.value.filter((row) => selectedIds.has(row.id));
356
+ };
357
+ isRowIndexSelected = (rowIndex) => {
358
+ const row = this._rows.value[rowIndex];
359
+ return this._selection.value.has(row.id);
360
+ };
361
+ isObjectSelected = (object) => {
362
+ return this._selection.value.has(object.id);
363
+ };
422
364
  //
423
365
  // Manipulation
424
366
  //
425
- toggleSelectionForRowIndex;
426
- setSelection;
367
+ toggleSelectionForRowIndex = (rowIndex) => {
368
+ const row = this._rows.value[rowIndex];
369
+ const newSelection = new Set(this._selection.value);
370
+ if (newSelection.has(row.id)) {
371
+ newSelection.delete(row.id);
372
+ } else {
373
+ if (this._selectionMode === "single") {
374
+ newSelection.clear();
375
+ }
376
+ newSelection.add(row.id);
377
+ }
378
+ this._selection.value = newSelection;
379
+ };
380
+ setSelection = (mode) => {
381
+ switch (mode) {
382
+ case "all": {
383
+ this._selection.value = new Set(this._rows.value.map((row) => row.id));
384
+ break;
385
+ }
386
+ case "none": {
387
+ this._selection.value = /* @__PURE__ */ new Set();
388
+ break;
389
+ }
390
+ }
391
+ };
427
392
  };
428
393
 
429
394
  // src/model/table-sorting.ts
430
395
  import { computed as computed2, signal as signal2 } from "@preact/signals-core";
431
396
  import orderBy from "lodash.orderby";
432
- import { FormatEnum, TypeEnum, getValue } from "@dxos/echo-schema";
397
+ import { FormatEnum, TypeEnum, getValue } from "@dxos/echo/internal";
433
398
  import { formatForDisplay } from "@dxos/react-ui-form";
434
399
  var TableSorting = class {
435
400
  _view;
436
401
  _projection;
437
- _displayToDataIndex;
402
+ _displayToDataIndex = /* @__PURE__ */ new Map();
438
403
  _rows;
439
- _localSort;
404
+ _localSort = signal2(void 0);
440
405
  _isDirty;
441
406
  sortedRows;
442
407
  constructor(rows, _view, _projection) {
443
408
  this._view = _view;
444
409
  this._projection = _projection;
445
- this._displayToDataIndex = /* @__PURE__ */ new Map();
446
- this._localSort = signal2(void 0);
447
410
  this._rows = rows;
448
411
  this._isDirty = computed2(() => {
449
412
  const local = this._localSort.value;
450
- const viewSort = this._view.query.sort?.[0];
413
+ const viewSort = this._view.sort?.[0];
451
414
  if (local?.type === "cleared") {
452
415
  return viewSort !== void 0;
453
416
  }
@@ -473,7 +436,7 @@ var TableSorting = class {
473
436
  if (local?.type === "active") {
474
437
  return local.sort;
475
438
  }
476
- return this._view.query.sort?.[0];
439
+ return this._view.sort?.[0];
477
440
  }
478
441
  /**
479
442
  * @reactive
@@ -517,11 +480,11 @@ var TableSorting = class {
517
480
  save() {
518
481
  if (this._localSort.value !== void 0) {
519
482
  if (this._localSort.value.type === "active") {
520
- this._view.query.sort = [
483
+ this._view.sort = [
521
484
  this._localSort.value.sort
522
485
  ];
523
486
  } else {
524
- this._view.query.sort = [];
487
+ this._view.sort = [];
525
488
  }
526
489
  this._localSort.value = void 0;
527
490
  }
@@ -643,13 +606,14 @@ var TableModel = class extends Resource2 {
643
606
  super();
644
607
  this._view = view;
645
608
  this._projection = projection ?? new ProjectionModel2(schema, view.projection);
609
+ this._projection.normalizeView();
646
610
  this._features = {
647
611
  ...defaultFeatures,
648
612
  ...features
649
613
  };
650
614
  invariant(!(this._features.dataEditable && this._features.selection.enabled && this._features.selection.mode === "single"), "Single selection is not compatible with editable tables.", {
651
615
  F: __dxlog_file,
652
- L: 141,
616
+ L: 148,
653
617
  S: this,
654
618
  A: [
655
619
  "!(this._features.dataEditable && this._features.selection.enabled && this._features.selection.mode === 'single')",
@@ -672,7 +636,7 @@ var TableModel = class extends Resource2 {
672
636
  this._onRowAction = onRowAction;
673
637
  }
674
638
  get id() {
675
- return fullyQualifiedId(this._view);
639
+ return Obj2.getDXN(this._view).toString();
676
640
  }
677
641
  get view() {
678
642
  return this._view;
@@ -680,7 +644,7 @@ var TableModel = class extends Resource2 {
680
644
  get table() {
681
645
  invariant(this._table, "Model not initialized", {
682
646
  F: __dxlog_file,
683
- L: 179,
647
+ L: 186,
684
648
  S: this,
685
649
  A: [
686
650
  "this._table",
@@ -719,7 +683,7 @@ var TableModel = class extends Resource2 {
719
683
  get columnMeta() {
720
684
  invariant(this._columnMeta, void 0, {
721
685
  F: __dxlog_file,
722
- L: 218,
686
+ L: 225,
723
687
  S: this,
724
688
  A: [
725
689
  "this._columnMeta",
@@ -743,12 +707,12 @@ var TableModel = class extends Resource2 {
743
707
  //
744
708
  async _open() {
745
709
  const presentation = this._view.presentation.target ?? await this._view.presentation.load();
746
- invariant(Obj3.instanceOf(TableView, presentation), void 0, {
710
+ invariant(Obj2.instanceOf(schema_exports.Table, presentation), void 0, {
747
711
  F: __dxlog_file,
748
- L: 241,
712
+ L: 248,
749
713
  S: this,
750
714
  A: [
751
- "Obj.instanceOf(TableView, presentation)",
715
+ "Obj.instanceOf(Table.Table, presentation)",
752
716
  ""
753
717
  ]
754
718
  });
@@ -777,7 +741,7 @@ var TableModel = class extends Resource2 {
777
741
  },
778
742
  frozenColsEnd: {
779
743
  0: {
780
- size: 40,
744
+ size: 32,
781
745
  resizeable: false
782
746
  }
783
747
  }
@@ -845,9 +809,10 @@ var TableModel = class extends Resource2 {
845
809
  getColumnCount = () => this._projection?.fields.length ?? 0;
846
810
  insertRow = () => {
847
811
  const result = this._onInsertRow?.();
848
- if (result === false && this._draftRows.value.length === 0) {
812
+ if (result === "draft" && this._draftRows.value.length === 0) {
849
813
  this.createDraftRow();
850
814
  }
815
+ return result ?? "final";
851
816
  };
852
817
  createDraftRow() {
853
818
  if (!this._projection) {
@@ -885,7 +850,7 @@ var TableModel = class extends Resource2 {
885
850
  this._draftRows.value = newDraftRows;
886
851
  }
887
852
  validateDraftRowData(data) {
888
- const schema = toEffectSchema2(this._projection.baseSchema);
853
+ const schema = toEffectSchema(this._projection.baseSchema);
889
854
  return validateSchema(schema, data) || [];
890
855
  }
891
856
  commitDraftRow = (draftRowIndex) => {
@@ -896,12 +861,12 @@ var TableModel = class extends Resource2 {
896
861
  if (!draftRow.valid) {
897
862
  return false;
898
863
  }
899
- const success = this._onInsertRow?.(draftRow.data);
900
- if (success) {
864
+ const insertRowResult = this._onInsertRow?.(draftRow.data);
865
+ if (insertRowResult === "final") {
901
866
  const newDraftRows = this._draftRows.value.filter((_, index) => index !== draftRowIndex);
902
867
  this._draftRows.value = newDraftRows;
903
868
  }
904
- return success ?? false;
869
+ return insertRowResult === "final";
905
870
  };
906
871
  deleteRow = (rowIndex) => {
907
872
  const row = this._sorting.getDataIndex(rowIndex);
@@ -1006,7 +971,7 @@ var TableModel = class extends Resource2 {
1006
971
  const currentRow = this._rows.value[rowIdx];
1007
972
  invariant(currentRow, "Invalid row index", {
1008
973
  F: __dxlog_file,
1009
- L: 513,
974
+ L: 525,
1010
975
  S: this,
1011
976
  A: [
1012
977
  "currentRow",
@@ -1018,7 +983,7 @@ var TableModel = class extends Resource2 {
1018
983
  const schema = getSchema(currentRow);
1019
984
  invariant(schema, void 0, {
1020
985
  F: __dxlog_file,
1021
- L: 519,
986
+ L: 531,
1022
987
  S: this,
1023
988
  A: [
1024
989
  "schema",
@@ -1030,7 +995,7 @@ var TableModel = class extends Resource2 {
1030
995
  const error = validationResult[0];
1031
996
  invariant(error.path === field.path, void 0, {
1032
997
  F: __dxlog_file,
1033
- L: 524,
998
+ L: 536,
1034
999
  S: this,
1035
1000
  A: [
1036
1001
  "error.path === field.path",
@@ -1183,8 +1148,6 @@ var editorTextToCellValue = (props, value) => {
1183
1148
 
1184
1149
  // src/model/modal-controller.ts
1185
1150
  import { signal as signal4 } from "@preact/signals-core";
1186
- import { log } from "@dxos/log";
1187
- var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/react-ui-table/src/model/modal-controller.ts";
1188
1151
  var ModalController = class {
1189
1152
  _state = signal4({
1190
1153
  type: "closed"
@@ -1242,24 +1205,6 @@ var ModalController = class {
1242
1205
  });
1243
1206
  }
1244
1207
  };
1245
- openCreateRef = (typename, anchorCell, initialValues, onCreate) => {
1246
- if (anchorCell) {
1247
- this._triggerRef.current = anchorCell;
1248
- this._state.value = {
1249
- type: "createRefPanel",
1250
- typename,
1251
- initialValues,
1252
- onCreate
1253
- };
1254
- } else {
1255
- log.warn("anchor cell not found while creating new ref", void 0, {
1256
- F: __dxlog_file2,
1257
- L: 86,
1258
- S: this,
1259
- C: (f, a) => f(...a)
1260
- });
1261
- }
1262
- };
1263
1208
  close = () => {
1264
1209
  this._state.value = {
1265
1210
  type: "closed"
@@ -1269,9 +1214,9 @@ var ModalController = class {
1269
1214
 
1270
1215
  // src/model/table-presentation.ts
1271
1216
  import { signal as signal5 } from "@preact/signals-core";
1272
- import { isNotNullable } from "effect/Predicate";
1273
- import { Obj as Obj4 } from "@dxos/echo";
1274
- import { FormatEnum as FormatEnum3, TypeEnum as TypeEnum2, getValue as getValue3 } from "@dxos/echo-schema";
1217
+ import * as Predicate from "effect/Predicate";
1218
+ import { Obj as Obj3 } from "@dxos/echo";
1219
+ import { FormatEnum as FormatEnum3, TypeEnum as TypeEnum2, getValue as getValue3 } from "@dxos/echo/internal";
1275
1220
  import { cellClassesForFieldType, formatForDisplay as formatForDisplay2 } from "@dxos/react-ui-form";
1276
1221
  import { toPlaneCellIndex } from "@dxos/react-ui-grid";
1277
1222
  import { mx } from "@dxos/react-ui-theme";
@@ -1279,7 +1224,7 @@ import { VIEW_FIELD_LIMIT } from "@dxos/schema";
1279
1224
  var TablePresentation = class {
1280
1225
  model;
1281
1226
  _visibleRange;
1282
- fieldProjectionCache;
1227
+ fieldProjectionCache = /* @__PURE__ */ new Map();
1283
1228
  constructor(model, _visibleRange = signal5({
1284
1229
  start: {
1285
1230
  row: 0,
@@ -1292,7 +1237,6 @@ var TablePresentation = class {
1292
1237
  })) {
1293
1238
  this.model = model;
1294
1239
  this._visibleRange = _visibleRange;
1295
- this.fieldProjectionCache = /* @__PURE__ */ new Map();
1296
1240
  }
1297
1241
  getCells(range, plane) {
1298
1242
  this.fieldProjectionCache.clear();
@@ -1321,7 +1265,7 @@ var TablePresentation = class {
1321
1265
  cells = this.getDraftRowCells(range);
1322
1266
  break;
1323
1267
  case "fixedEndStart":
1324
- cells = this.getDraftSelectCells(range);
1268
+ cells = this.getDraftIconCells(range);
1325
1269
  break;
1326
1270
  case "fixedEndEnd":
1327
1271
  cells = this.getDraftActionCells(range);
@@ -1381,10 +1325,7 @@ var TablePresentation = class {
1381
1325
  }
1382
1326
  };
1383
1327
  const classes = [];
1384
- const formatClasses = cellClassesForFieldType({
1385
- type: props.type,
1386
- format: props.format
1387
- });
1328
+ const formatClasses = cellClassesForFieldType(props);
1388
1329
  if (formatClasses) {
1389
1330
  classes.push(formatClasses);
1390
1331
  }
@@ -1392,9 +1333,7 @@ var TablePresentation = class {
1392
1333
  if (rowSelectionClasses) {
1393
1334
  classes.push(rowSelectionClasses);
1394
1335
  }
1395
- if (classes.length > 0) {
1396
- cell.className = mx(classes.flat());
1397
- }
1336
+ cell.className = mx(classes);
1398
1337
  if (props.type === TypeEnum2.Array) {
1399
1338
  const targetArray = getValue3(obj, field.path);
1400
1339
  if (targetArray && Array.isArray(targetArray)) {
@@ -1416,7 +1355,7 @@ var TablePresentation = class {
1416
1355
  }
1417
1356
  return "Object";
1418
1357
  };
1419
- const tags = targetArray.map(getLabel).filter(isNotNullable).map((title) => {
1358
+ const tags = targetArray.map(getLabel).filter(Predicate.isNotNullable).map((title) => {
1420
1359
  return `<span class="dx-tag" data-hue="neutral">${title}</span>`;
1421
1360
  }).join("");
1422
1361
  cell.accessoryHtml = `<div role='none' class="flex flex-row gap-1 overflow-x-auto">${tags}</div>`;
@@ -1425,8 +1364,8 @@ var TablePresentation = class {
1425
1364
  if (props.format === FormatEnum3.Ref && props.referenceSchema) {
1426
1365
  const targetObj = getValue3(obj, field.path)?.target;
1427
1366
  if (targetObj) {
1428
- const dxn = Obj4.getDXN(targetObj)?.toString();
1429
- cell.accessoryHtml = `<dx-ref-tag 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-ref-tag>`;
1367
+ const dxn = Obj3.getDXN(targetObj)?.toString();
1368
+ cell.accessoryHtml = `<div role="none" class="absolute inline-end-0 inset-block-0 p-[--dx-grid-cell-content-padding-block]"><dx-anchor refId=${dxn} class="dx-button is-6 aspect-square min-bs-0" data-dx-grid-action="accessory"><dx-icon icon="ph--link-simple--regular"/></dx-anchor></div>`;
1430
1369
  }
1431
1370
  }
1432
1371
  if (props.format === FormatEnum3.Boolean) {
@@ -1488,27 +1427,39 @@ var TablePresentation = class {
1488
1427
  const cells = {};
1489
1428
  const fields = this.model.projection?.fields ?? [];
1490
1429
  const draftRows = this.model.draftRows.value;
1491
- for (let row = range.start.row; row <= range.end.row && row < draftRows.length; row++) {
1492
- const draftRow = draftRows[row];
1430
+ if (draftRows.length === 0) {
1493
1431
  for (let col = range.start.col; col <= range.end.col && col < fields.length; col++) {
1494
- const cellIndex = toPlaneCellIndex({
1432
+ cells[toPlaneCellIndex({
1495
1433
  col,
1496
- row
1497
- });
1498
- const field = fields[col];
1499
- if (!field) {
1500
- continue;
1501
- }
1502
- this.createDataCell(cells, draftRow.data, field, col, row);
1503
- if (this.model.hasDraftRowValidationError(row, field.path)) {
1504
- const cellValue = cells[cellIndex];
1505
- if (cellValue) {
1506
- const existingClasses = cellValue.className || "";
1507
- const draftClasses = "dx-grid__cell--flagged";
1508
- cellValue.className = existingClasses ? `${existingClasses} ${draftClasses}` : draftClasses;
1434
+ row: 0
1435
+ })] = {
1436
+ value: "",
1437
+ readonly: true,
1438
+ className: "dx-grid__row--cta__cell"
1439
+ };
1440
+ }
1441
+ } else {
1442
+ for (let row = range.start.row; row <= range.end.row && row < draftRows.length; row++) {
1443
+ const draftRow = draftRows[row];
1444
+ for (let col = range.start.col; col <= range.end.col && col < fields.length; col++) {
1445
+ const cellIndex = toPlaneCellIndex({
1446
+ col,
1447
+ row
1448
+ });
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)) {
1455
+ const cellValue = cells[cellIndex];
1456
+ if (cellValue) {
1457
+ const existingClasses = cellValue.className || "";
1458
+ const draftClasses = "dx-grid__cell--flagged";
1459
+ cellValue.className = existingClasses ? `${existingClasses} ${draftClasses}` : draftClasses;
1460
+ }
1509
1461
  }
1510
1462
  }
1511
- cells[cellIndex].className += " !bg-toolbarSurface";
1512
1463
  }
1513
1464
  }
1514
1465
  return cells;
@@ -1525,10 +1476,10 @@ var TablePresentation = class {
1525
1476
  row: 0
1526
1477
  })] = {
1527
1478
  // TODO(burdon): Use same logic as form for fallback title.
1528
- value: props.title ?? field.path,
1529
- readonly: true,
1479
+ value: "",
1530
1480
  resizeHandle: "col",
1531
1481
  accessoryHtml: `
1482
+ <span class="grow min-is-0 truncate">${props.title ?? field.path}</span>
1532
1483
  ${direction !== void 0 ? tableButtons.sort.render({
1533
1484
  fieldId: field.id,
1534
1485
  direction
@@ -1537,7 +1488,7 @@ var TablePresentation = class {
1537
1488
  fieldId: field.id
1538
1489
  })}
1539
1490
  `,
1540
- className: "!bg-toolbarSurface"
1491
+ className: "!bg-toolbarSurface !text-description [&>div]:flex [&>div]:items-stretch"
1541
1492
  };
1542
1493
  }
1543
1494
  return cells;
@@ -1628,35 +1579,46 @@ var TablePresentation = class {
1628
1579
  getDraftActionCells(range) {
1629
1580
  const cells = {};
1630
1581
  const draftRows = this.model.draftRows.value;
1631
- for (let row = range.start.row; row <= range.end.row && row < draftRows.length; row++) {
1632
- const draftRow = draftRows[row];
1633
- const disabled = !draftRow.valid;
1582
+ if (draftRows.length === 0) {
1634
1583
  cells[toPlaneCellIndex({
1635
1584
  col: 0,
1636
- row
1585
+ row: 0
1637
1586
  })] = {
1638
1587
  value: "",
1639
- readonly: true,
1640
- accessoryHtml: tableButtons.saveDraftRow.render({
1641
- rowIndex: row,
1642
- disabled
1643
- }),
1644
- className: "!bg-toolbarSurface"
1588
+ className: "dx-grid__row--cta__cell",
1589
+ readonly: true
1645
1590
  };
1591
+ } else {
1592
+ for (let row = range.start.row; row <= range.end.row && row < draftRows.length; row++) {
1593
+ const draftRow = draftRows[row];
1594
+ const disabled = !draftRow.valid;
1595
+ cells[toPlaneCellIndex({
1596
+ col: 0,
1597
+ row
1598
+ })] = {
1599
+ value: "",
1600
+ readonly: true,
1601
+ accessoryHtml: tableButtons.saveDraftRow.render({
1602
+ rowIndex: row,
1603
+ disabled
1604
+ })
1605
+ };
1606
+ }
1646
1607
  }
1647
1608
  return cells;
1648
1609
  }
1649
- getDraftSelectCells(range) {
1610
+ getDraftIconCells(range) {
1650
1611
  const cells = {};
1651
1612
  const draftRows = this.model.draftRows.value;
1652
- for (let row = range.start.row; row <= range.end.row && row < draftRows.length; row++) {
1613
+ for (let row = range.start.row; row <= range.end.row; row++) {
1653
1614
  cells[toPlaneCellIndex({
1654
1615
  col: 0,
1655
1616
  row
1656
1617
  })] = {
1657
1618
  value: "",
1658
1619
  readonly: true,
1659
- className: "!bg-toolbarSurface"
1620
+ accessoryHtml: '<dx-icon icon="ph--plus--regular" class="contents"></dx-icon>',
1621
+ className: mx("[&>div]:grid [&>div]:place-content-center", draftRows.length < 1 && "dx-grid__row--cta__cell")
1660
1622
  };
1661
1623
  }
1662
1624
  return cells;
@@ -1689,13 +1651,13 @@ import { useSignals as _useSignals } from "@preact-signals/safe-react/tracking";
1689
1651
  import { effect as effect3 } from "@preact/signals-core";
1690
1652
  import orderBy2 from "lodash.orderby";
1691
1653
  import { useEffect, useMemo, useState } from "react";
1692
- import { fullyQualifiedId as fullyQualifiedId2 } from "@dxos/react-client/echo";
1654
+ import { Obj as Obj4 } from "@dxos/echo";
1693
1655
  import { useSelected, useSelectionActions } from "@dxos/react-ui-attention";
1694
1656
  import { isNonNullable } from "@dxos/util";
1695
1657
  var useTableModel = ({ view, schema, projection, rows, rowActions, features, onSelectionChanged, onRowAction, ...props }) => {
1696
1658
  var _effect = _useSignals();
1697
1659
  try {
1698
- const selected = useSelected(view && fullyQualifiedId2(view), "multi");
1660
+ const selected = useSelected(view && Obj4.getDXN(view).toString(), "multi");
1699
1661
  const initialSelection = useMemo(() => selected, [
1700
1662
  view
1701
1663
  ]);
@@ -1780,12 +1742,12 @@ var useAddRow = ({ space, schema }) => {
1780
1742
  if (space && schema) {
1781
1743
  try {
1782
1744
  space.db.add(Obj5.make(schema, data ?? {}));
1783
- return true;
1745
+ return "final";
1784
1746
  } catch (error) {
1785
- return false;
1747
+ return "draft";
1786
1748
  }
1787
1749
  }
1788
- return false;
1750
+ return "final";
1789
1751
  }, [
1790
1752
  space,
1791
1753
  schema
@@ -1796,7 +1758,6 @@ export {
1796
1758
  getBaseSchema,
1797
1759
  makeDynamicTable,
1798
1760
  touch,
1799
- createTable,
1800
1761
  BUTTON_IDENTIFIERS,
1801
1762
  tableButtons,
1802
1763
  CONTROL_IDENTIFIERS,
@@ -1811,4 +1772,4 @@ export {
1811
1772
  useTableModel,
1812
1773
  useAddRow
1813
1774
  };
1814
- //# sourceMappingURL=chunk-ZAOSIG3L.mjs.map
1775
+ //# sourceMappingURL=chunk-GS2UNGJK.mjs.map