@dxos/react-ui-table 0.8.4-main.5ea62a8 → 0.8.4-main.72ec0f3

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 (97) hide show
  1. package/dist/lib/browser/{chunk-63UUF4IG.mjs → chunk-2PFAPQL4.mjs} +7 -7
  2. package/dist/lib/browser/chunk-2PFAPQL4.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-RQYXNWWN.mjs → chunk-GS2UNGJK.mjs} +451 -498
  4. package/dist/lib/browser/chunk-GS2UNGJK.mjs.map +7 -0
  5. package/dist/lib/browser/index.mjs +170 -317
  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 +10 -7
  9. package/dist/lib/browser/testing/index.mjs.map +3 -3
  10. package/dist/lib/browser/types/index.mjs +1 -1
  11. package/dist/lib/node-esm/{chunk-K734DJB7.mjs → chunk-6POOFFYF.mjs} +7 -7
  12. package/dist/lib/node-esm/chunk-6POOFFYF.mjs.map +7 -0
  13. package/dist/lib/node-esm/{chunk-QNDUGIS7.mjs → chunk-TRR3C5NX.mjs} +451 -498
  14. package/dist/lib/node-esm/chunk-TRR3C5NX.mjs.map +7 -0
  15. package/dist/lib/node-esm/index.mjs +170 -317
  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 +10 -7
  19. package/dist/lib/node-esm/testing/index.mjs.map +3 -3
  20. package/dist/lib/node-esm/types/index.mjs +1 -1
  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 +3 -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 +70 -7
  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 +5 -2
  29. package/dist/types/src/components/Table/Table.d.ts.map +1 -1
  30. package/dist/types/src/components/Table/Table.stories.d.ts +5 -6
  31. package/dist/types/src/components/Table/Table.stories.d.ts.map +1 -1
  32. package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts +7 -5
  33. package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts.map +1 -1
  34. package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts +5 -3
  35. package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts.map +1 -1
  36. package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts +1 -2
  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 +1 -1
  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 +4 -4
  51. package/dist/types/src/model/table-model.d.ts.map +1 -1
  52. package/dist/types/src/model/table-presentation.d.ts.map +1 -1
  53. package/dist/types/src/model/table-sorting.d.ts +2 -3
  54. package/dist/types/src/model/table-sorting.d.ts.map +1 -1
  55. package/dist/types/src/testing/useTestTableModel.d.ts +3 -17
  56. package/dist/types/src/testing/useTestTableModel.d.ts.map +1 -1
  57. package/dist/types/src/types/schema.d.ts +6 -6
  58. package/dist/types/src/types/schema.d.ts.map +1 -1
  59. package/dist/types/src/util/dynamic-table.d.ts +5 -6
  60. package/dist/types/src/util/dynamic-table.d.ts.map +1 -1
  61. package/dist/types/src/util/schema.d.ts +1 -1
  62. package/dist/types/src/util/schema.d.ts.map +1 -1
  63. package/dist/types/tsconfig.tsbuildinfo +1 -1
  64. package/package.json +53 -52
  65. package/src/components/Table/DynamicTable.stories.tsx +11 -10
  66. package/src/components/Table/DynamicTable.tsx +4 -7
  67. package/src/components/Table/Relations.stories.tsx +127 -18
  68. package/src/components/Table/RowActionsMenu.tsx +21 -13
  69. package/src/components/Table/Table.stories.tsx +47 -46
  70. package/src/components/Table/Table.tsx +13 -9
  71. package/src/components/TableCellEditor/FormCellEditor.tsx +51 -41
  72. package/src/components/TableCellEditor/TableCellEditor.stories.tsx +19 -46
  73. package/src/components/TableCellEditor/TableCellEditor.tsx +17 -112
  74. package/src/components/TableCellEditor/index.ts +1 -0
  75. package/src/components/TableToolbar/TableToolbar.tsx +32 -22
  76. package/src/components/testing.ts +2 -2
  77. package/src/hooks/useAddRow.ts +1 -1
  78. package/src/hooks/useTableModel.ts +5 -5
  79. package/src/model/modal-controller.ts +0 -28
  80. package/src/model/table-model.test.ts +17 -7
  81. package/src/model/table-model.ts +19 -9
  82. package/src/model/table-presentation.test.ts +20 -18
  83. package/src/model/table-presentation.ts +4 -5
  84. package/src/model/table-sorting.ts +16 -7
  85. package/src/playwright/TableManager.ts +1 -1
  86. package/src/playwright/smoke.spec.ts +7 -5
  87. package/src/testing/useTestTableModel.ts +8 -5
  88. package/src/types/schema.ts +8 -8
  89. package/src/util/dynamic-table.ts +12 -13
  90. package/src/util/schema.ts +4 -4
  91. package/dist/lib/browser/chunk-63UUF4IG.mjs.map +0 -7
  92. package/dist/lib/browser/chunk-RQYXNWWN.mjs.map +0 -7
  93. package/dist/lib/node-esm/chunk-K734DJB7.mjs.map +0 -7
  94. package/dist/lib/node-esm/chunk-QNDUGIS7.mjs.map +0 -7
  95. package/dist/types/src/components/Table/CreateRefPanel.d.ts +0 -9
  96. package/dist/types/src/components/Table/CreateRefPanel.d.ts.map +0 -1
  97. package/src/components/Table/CreateRefPanel.tsx +0 -103
@@ -16,8 +16,8 @@ import {
16
16
  touch,
17
17
  useAddRow,
18
18
  useTableModel
19
- } from "./chunk-QNDUGIS7.mjs";
20
- import "./chunk-K734DJB7.mjs";
19
+ } from "./chunk-TRR3C5NX.mjs";
20
+ import "./chunk-6POOFFYF.mjs";
21
21
 
22
22
  // src/translations.ts
23
23
  var translationKey = "react-ui-table";
@@ -52,8 +52,9 @@ var translations = [
52
52
  ];
53
53
 
54
54
  // src/components/Table/Table.tsx
55
- import { useSignals as _useSignals8 } from "@preact-signals/safe-react/tracking";
56
- import React8, { forwardRef, useCallback as useCallback5, useEffect as useEffect3, useImperativeHandle, useMemo as useMemo5, useState as useState4 } from "react";
55
+ import { useSignals as _useSignals7 } from "@preact-signals/safe-react/tracking";
56
+ import * as String2 from "effect/String";
57
+ import React7, { forwardRef, useCallback as useCallback4, useEffect as useEffect3, useImperativeHandle, useMemo as useMemo4, useState as useState4 } from "react";
57
58
  import { useAttention } from "@dxos/react-ui-attention";
58
59
  import { Grid, closestCell, gridSeparatorBlockEnd, gridSeparatorInlineEnd } from "@dxos/react-ui-grid";
59
60
  import { DxEditRequest } from "@dxos/react-ui-grid";
@@ -64,12 +65,9 @@ import { useSignals as _useSignals3 } from "@preact-signals/safe-react/tracking"
64
65
  import { EditorView } from "@codemirror/view";
65
66
  import React3, { useCallback as useCallback2, useMemo as useMemo2, useRef as useRef2, useState as useState2 } from "react";
66
67
  import { debounce } from "@dxos/async";
67
- import { FormatEnum, TypeEnum } from "@dxos/echo-schema";
68
+ import { FormatEnum as FormatEnum2, TypeEnum } from "@dxos/echo/internal";
68
69
  import { invariant as invariant2 } from "@dxos/invariant";
69
- import { useThemeContext } from "@dxos/react-ui";
70
- import { createMarkdownExtensions } from "@dxos/react-ui-editor";
71
70
  import { GridCellEditor, editorKeys, parseCellIndex as parseCellIndex2, useGridContext as useGridContext3 } from "@dxos/react-ui-grid";
72
- import { createLinks, tagPicker } from "@dxos/react-ui-tag-picker";
73
71
 
74
72
  // src/components/TableCellEditor/CellValidationMessage.tsx
75
73
  import { useSignals as _useSignals } from "@preact-signals/safe-react/tracking";
@@ -104,16 +102,17 @@ var CellValidationMessage = ({ validationError, variant = "error", __gridScope }
104
102
 
105
103
  // src/components/TableCellEditor/FormCellEditor.tsx
106
104
  import { useSignals as _useSignals2 } from "@preact-signals/safe-react/tracking";
105
+ import * as Schema from "effect/Schema";
107
106
  import React2, { useCallback, useEffect, useMemo, useRef, useState } from "react";
108
107
  import { Filter, Obj } from "@dxos/echo";
109
- import { Ref, getValue } from "@dxos/echo-schema";
108
+ import { FormatEnum, Ref, getValue } from "@dxos/echo/internal";
110
109
  import { invariant } from "@dxos/invariant";
111
110
  import { getSnapshot } from "@dxos/live-object";
112
111
  import { getSpace } from "@dxos/react-client/echo";
113
112
  import { Popover } from "@dxos/react-ui";
114
113
  import { Form } from "@dxos/react-ui-form";
115
- import { cellQuery, parseCellIndex, useGridContext as useGridContext2 } from "@dxos/react-ui-grid";
116
- import { getDeep, isNotFalsy, setDeep } from "@dxos/util";
114
+ import { parseCellIndex, useGridContext as useGridContext2 } from "@dxos/react-ui-grid";
115
+ import { getDeep, isTruthy, setDeep } from "@dxos/util";
117
116
  var __dxlog_file = "/__w/dxos/dxos/packages/ui/react-ui-table/src/components/TableCellEditor/FormCellEditor.tsx";
118
117
  var createOptionLabel = [
119
118
  "create new object label",
@@ -121,7 +120,7 @@ var createOptionLabel = [
121
120
  ns: translationKey
122
121
  }
123
122
  ];
124
- var FormCellEditor = ({ fieldProjection, model, schema, onSave, client, modals, __gridScope, ...formProps }) => {
123
+ var FormCellEditor = ({ fieldProjection, model, schema, onSave, client, modals, onCreate, __gridScope, ...formProps }) => {
125
124
  var _effect = _useSignals2();
126
125
  try {
127
126
  const { editing: contextEditing, setEditing, id: gridId } = useGridContext2("ArrayEditor", __gridScope);
@@ -131,7 +130,7 @@ var FormCellEditor = ({ fieldProjection, model, schema, onSave, client, modals,
131
130
  const space = getSpace(model.view);
132
131
  invariant(space, void 0, {
133
132
  F: __dxlog_file,
134
- L: 53,
133
+ L: 57,
135
134
  S: void 0,
136
135
  A: [
137
136
  "space",
@@ -162,7 +161,7 @@ var FormCellEditor = ({ fieldProjection, model, schema, onSave, client, modals,
162
161
  dxn: Obj.getDXN(obj),
163
162
  label: getValue(obj, fieldProjection.field.referencePath) || obj.id.toString()
164
163
  };
165
- }).filter(isNotFalsy);
164
+ }).filter(isTruthy);
166
165
  }
167
166
  return [];
168
167
  }, [
@@ -176,7 +175,7 @@ var FormCellEditor = ({ fieldProjection, model, schema, onSave, client, modals,
176
175
  const draftRow = model.draftRows.value[cell.row];
177
176
  invariant(draftRow, void 0, {
178
177
  F: __dxlog_file,
179
- L: 94,
178
+ L: 98,
180
179
  S: void 0,
181
180
  A: [
182
181
  "draftRow",
@@ -188,7 +187,7 @@ var FormCellEditor = ({ fieldProjection, model, schema, onSave, client, modals,
188
187
  const row = model.getRowAt(cell.row);
189
188
  invariant(row, void 0, {
190
189
  F: __dxlog_file,
191
- L: 98,
190
+ L: 102,
192
191
  S: void 0,
193
192
  A: [
194
193
  "row",
@@ -221,38 +220,6 @@ var FormCellEditor = ({ fieldProjection, model, schema, onSave, client, modals,
221
220
  contextEditing,
222
221
  originalRow
223
222
  ]);
224
- const handleCreate = useCallback((object) => {
225
- const ref = Ref.make(object);
226
- const path = fieldProjection.field.path;
227
- setDeep(originalRow, [
228
- path
229
- ], ref);
230
- contextEditing?.cellElement?.focus();
231
- setEditing(null);
232
- setLocalEditing(false);
233
- onSave?.();
234
- }, [
235
- fieldProjection.field.path,
236
- onSave,
237
- contextEditing,
238
- originalRow
239
- ]);
240
- const handleCreateFromQuery = useCallback(async (typeAnnotation, query) => {
241
- if (model && modals && contextEditing?.index) {
242
- setLocalEditing(false);
243
- modals.openCreateRef(typeAnnotation.typename, document.querySelector(cellQuery(contextEditing.index, gridId)), {
244
- [fieldProjection.field.referencePath]: query
245
- }, handleCreate);
246
- }
247
- }, [
248
- model,
249
- modals,
250
- client,
251
- contextEditing?.index,
252
- gridId,
253
- fieldProjection,
254
- handleSave
255
- ]);
256
223
  useEffect(() => {
257
224
  if (contextEditing && contextEditing.cellElement) {
258
225
  anchorRef.current = contextEditing.cellElement.querySelector(".dx-grid__cell__content");
@@ -285,6 +252,47 @@ var FormCellEditor = ({ fieldProjection, model, schema, onSave, client, modals,
285
252
  }
286
253
  setLocalEditing(nextOpen);
287
254
  }, []);
255
+ const refSchema = useMemo(() => {
256
+ if (fieldProjection.props.format === FormatEnum.Ref && fieldProjection.props.referenceSchema) {
257
+ const { schema: refSchema2 } = getSchema({
258
+ typename: fieldProjection.props.referenceSchema
259
+ });
260
+ return refSchema2;
261
+ }
262
+ return null;
263
+ }, [
264
+ fieldProjection.props.format,
265
+ fieldProjection.props.referenceSchema,
266
+ getSchema
267
+ ]);
268
+ const createSchema = useMemo(() => {
269
+ return refSchema ? Schema.omit("id")(refSchema) : null;
270
+ }, [
271
+ refSchema
272
+ ]);
273
+ const handleCreate = useCallback((values) => {
274
+ if (refSchema && onCreate) {
275
+ const objectWithId = onCreate(refSchema, values);
276
+ if (objectWithId) {
277
+ const ref = Ref.make(objectWithId);
278
+ const path = fieldProjection.field.path;
279
+ setDeep(originalRow, [
280
+ path
281
+ ], ref);
282
+ }
283
+ }
284
+ contextEditing?.cellElement?.focus();
285
+ setEditing(null);
286
+ setLocalEditing(false);
287
+ onSave?.();
288
+ }, [
289
+ fieldProjection.field.path,
290
+ onSave,
291
+ contextEditing,
292
+ originalRow,
293
+ refSchema,
294
+ onCreate
295
+ ]);
288
296
  if (!editing) {
289
297
  return null;
290
298
  }
@@ -303,9 +311,13 @@ var FormCellEditor = ({ fieldProjection, model, schema, onSave, client, modals,
303
311
  onSave: handleSave,
304
312
  ...formProps,
305
313
  onQueryRefOptions: handleQueryRefOptions,
306
- onCreateFromQuery: handleCreateFromQuery,
307
- createOptionIcon: "ph--plus--regular",
308
- createOptionLabel
314
+ ...createSchema && {
315
+ onCreate: handleCreate,
316
+ createSchema,
317
+ createInitialValuePath: fieldProjection.field.referencePath,
318
+ createOptionIcon: "ph--plus--regular",
319
+ createOptionLabel
320
+ }
309
321
  })))));
310
322
  } finally {
311
323
  _effect.f();
@@ -315,7 +327,7 @@ var FormCellEditor = ({ fieldProjection, model, schema, onSave, client, modals,
315
327
  // src/components/TableCellEditor/TableCellEditor.tsx
316
328
  var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/react-ui-table/src/components/TableCellEditor/TableCellEditor.tsx";
317
329
  var adaptValidationMessage = (message) => message ? message.endsWith("is missing") ? "Can\u2019t be blank" : message : null;
318
- var TableValueEditor = ({ model, modals, schema, onFocus, onSave, client, __gridScope }) => {
330
+ var TableValueEditor = ({ model, modals, schema, onFocus, onSave, onCreate, client, __gridScope }) => {
319
331
  var _effect = _useSignals3();
320
332
  try {
321
333
  const { editing } = useGridContext3("TableValueEditor", __gridScope);
@@ -328,7 +340,7 @@ var TableValueEditor = ({ model, modals, schema, onFocus, onSave, client, __grid
328
340
  const fieldProjection2 = model.projection.getFieldProjection(field.id);
329
341
  invariant2(fieldProjection2, void 0, {
330
342
  F: __dxlog_file2,
331
- L: 72,
343
+ L: 71,
332
344
  S: void 0,
333
345
  A: [
334
346
  "fieldProjection",
@@ -340,13 +352,14 @@ var TableValueEditor = ({ model, modals, schema, onFocus, onSave, client, __grid
340
352
  model,
341
353
  editing
342
354
  ]);
343
- if (fieldProjection?.props.type === TypeEnum.Array || fieldProjection?.props.format === FormatEnum.SingleSelect || fieldProjection?.props.format === FormatEnum.Ref) {
355
+ if (fieldProjection?.props.type === TypeEnum.Array || fieldProjection?.props.format === FormatEnum2.SingleSelect || fieldProjection?.props.format === FormatEnum2.Ref) {
344
356
  return /* @__PURE__ */ React3.createElement(FormCellEditor, {
345
357
  fieldProjection,
346
358
  model,
347
359
  schema,
348
360
  __gridScope,
349
361
  onSave,
362
+ onCreate,
350
363
  client,
351
364
  modals
352
365
  });
@@ -363,16 +376,15 @@ var TableValueEditor = ({ model, modals, schema, onFocus, onSave, client, __grid
363
376
  }
364
377
  };
365
378
  var editorSlots = {
366
- scroller: {
379
+ scroll: {
367
380
  className: "!plb-[--dx-grid-cell-editor-padding-block]"
368
381
  }
369
382
  };
370
383
  var TableCellEditor = ({ model, modals, onFocus, onSave, __gridScope }) => {
371
384
  var _effect = _useSignals3();
372
385
  try {
373
- const { id: gridId, editing, setEditing } = useGridContext3("TableCellEditor", __gridScope);
386
+ const { editing, setEditing } = useGridContext3("TableCellEditor", __gridScope);
374
387
  const suppressNextBlur = useRef2(false);
375
- const { themeMode } = useThemeContext();
376
388
  const [validationError, setValidationError] = useState2(null);
377
389
  const [validationVariant, setValidationVariant] = useState2("error");
378
390
  const fieldProjection = useMemo2(() => {
@@ -384,7 +396,7 @@ var TableCellEditor = ({ model, modals, onFocus, onSave, __gridScope }) => {
384
396
  const fieldProjection2 = model.projection.getFieldProjection(field.id);
385
397
  invariant2(fieldProjection2, void 0, {
386
398
  F: __dxlog_file2,
387
- L: 122,
399
+ L: 121,
388
400
  S: void 0,
389
401
  A: [
390
402
  "fieldProjection",
@@ -474,11 +486,11 @@ var TableCellEditor = ({ model, modals, onFocus, onSave, __gridScope }) => {
474
486
  setEditing,
475
487
  onSave
476
488
  ]);
477
- const extension = useMemo2(() => {
489
+ const extensions = useMemo2(() => {
478
490
  if (!fieldProjection) {
479
491
  return [];
480
492
  }
481
- const extension2 = [
493
+ const extensions2 = [
482
494
  editorKeys({
483
495
  onClose: handleClose,
484
496
  ...editing?.initialContent && {
@@ -486,39 +498,8 @@ var TableCellEditor = ({ model, modals, onFocus, onSave, __gridScope }) => {
486
498
  }
487
499
  })
488
500
  ];
489
- const format = fieldProjection.props.format;
490
- if (format === FormatEnum.SingleSelect || format === FormatEnum.MultiSelect) {
491
- extension2.push(createMarkdownExtensions({
492
- themeMode
493
- }));
494
- const options = fieldProjection.props.options || [];
495
- const mode = format === FormatEnum.SingleSelect ? "single-select" : "multi-select";
496
- extension2.push(tagPicker({
497
- mode,
498
- keymap: false,
499
- onSearch: (text, selectedIds) => {
500
- return options.filter((option) => selectedIds.indexOf(option.id) === -1 && (text.length === 0 || option.title.toLowerCase().includes(text.toLowerCase()))).map((option) => ({
501
- id: option.id,
502
- label: option.title,
503
- hue: option.color
504
- }));
505
- },
506
- onUpdate: (ids) => {
507
- if (model && editing) {
508
- if (ids.length === 0) {
509
- return;
510
- }
511
- if (mode === "single-select") {
512
- void handleEnter(ids[0]);
513
- } else {
514
- void handleEnter(ids);
515
- }
516
- }
517
- }
518
- }));
519
- }
520
501
  if (model && editing) {
521
- extension2.push(EditorView.updateListener.of(debounce((update) => {
502
+ extensions2.push(EditorView.updateListener.of(debounce((update) => {
522
503
  const content = update.state.doc.toString();
523
504
  const cell = parseCellIndex2(editing.index);
524
505
  void model.validateCellData(cell, content).then((result) => {
@@ -531,54 +512,17 @@ var TableCellEditor = ({ model, modals, onFocus, onSave, __gridScope }) => {
531
512
  });
532
513
  }, 10)));
533
514
  }
534
- return extension2;
515
+ return extensions2;
535
516
  }, [
536
517
  model,
537
518
  modals,
538
519
  editing,
539
520
  fieldProjection,
540
- handleClose,
541
- themeMode
521
+ handleClose
542
522
  ]);
543
523
  const getCellContent = useCallback2(() => {
544
524
  if (model && editing) {
545
525
  const cell = parseCellIndex2(editing.index);
546
- const { col } = cell;
547
- const field = model.projection.fields[col];
548
- const fieldProjection2 = model.projection.getFieldProjection(field.id);
549
- if (fieldProjection2?.props.format === FormatEnum.SingleSelect || fieldProjection2?.props.format === FormatEnum.MultiSelect) {
550
- const value2 = model.getCellData(cell);
551
- if (value2 !== void 0) {
552
- const options = fieldProjection2.props.options || [];
553
- if (fieldProjection2.props.format === FormatEnum.MultiSelect) {
554
- const tagItems = value2.split(",").map((id) => {
555
- const option = options.find((o) => o.id === id);
556
- if (option) {
557
- return {
558
- id,
559
- label: option.title,
560
- hue: option.color
561
- };
562
- }
563
- return void 0;
564
- }).filter((item) => item !== void 0);
565
- return createLinks(tagItems);
566
- } else {
567
- const option = options.find((o) => o.id === value2);
568
- if (option) {
569
- const tagItem = {
570
- id: value2,
571
- label: option.title,
572
- hue: option.color
573
- };
574
- return createLinks([
575
- tagItem
576
- ]);
577
- }
578
- }
579
- }
580
- return "";
581
- }
582
526
  const value = model.getCellData(cell);
583
527
  return value !== void 0 ? String(value) : "";
584
528
  }
@@ -591,7 +535,7 @@ var TableCellEditor = ({ model, modals, onFocus, onSave, __gridScope }) => {
591
535
  variant: validationVariant,
592
536
  __gridScope
593
537
  }), /* @__PURE__ */ React3.createElement(GridCellEditor, {
594
- extension,
538
+ extensions,
595
539
  getCellContent,
596
540
  onBlur: handleBlur,
597
541
  slots: editorSlots
@@ -738,106 +682,12 @@ var ColumnSettings = ({ registry, model, modals, onNewColumn }) => {
738
682
  }
739
683
  };
740
684
 
741
- // src/components/Table/CreateRefPanel.tsx
742
- import { useSignals as _useSignals6 } from "@preact-signals/safe-react/tracking";
743
- import { Schema } from "effect";
744
- import React6, { useCallback as useCallback4, useMemo as useMemo4 } from "react";
745
- import { Type } from "@dxos/echo";
746
- import { live } from "@dxos/live-object";
747
- import { useClient } from "@dxos/react-client";
748
- import { getSpace as getSpace2 } from "@dxos/react-client/echo";
749
- import { Popover as Popover3 } from "@dxos/react-ui";
750
- import { Form as Form2 } from "@dxos/react-ui-form";
751
- import { useGridContext as useGridContext4 } from "@dxos/react-ui-grid";
752
- var CreateRefPanel = ({ model, modals, __gridScope }) => {
753
- var _effect = _useSignals6();
754
- try {
755
- const { id: gridId } = useGridContext4("TableCellEditor", __gridScope);
756
- const client = useClient();
757
- const space = model && getSpace2(model?.view);
758
- const state = modals.state.value;
759
- const getSchema = useCallback4(() => {
760
- if (!space || state?.type !== "createRefPanel") {
761
- return;
762
- }
763
- const staticSchema = client.graph.schemaRegistry.schemas.find((schema3) => Type.getTypename(schema3) === state.typename);
764
- if (staticSchema) {
765
- return staticSchema;
766
- }
767
- const [schema2] = space.db.schemaRegistry.query({
768
- typename: state.typename
769
- }).runSync();
770
- return schema2;
771
- }, [
772
- space,
773
- state
774
- ]);
775
- const schema = useMemo4(() => {
776
- const schema2 = getSchema();
777
- if (!schema2) {
778
- return;
779
- }
780
- const omit = Schema.omit("id");
781
- return omit(schema2);
782
- }, [
783
- getSchema
784
- ]);
785
- const handleSave = useCallback4((values) => {
786
- if (!model || !space || state?.type !== "createRefPanel") {
787
- return;
788
- }
789
- const schema2 = getSchema();
790
- if (schema2) {
791
- const obj = space.db.add(live(schema2, values));
792
- state.onCreate?.(obj);
793
- }
794
- void modals.close();
795
- }, [
796
- model,
797
- modals,
798
- space,
799
- state
800
- ]);
801
- const handleCancel = useCallback4(() => {
802
- if (model) {
803
- modals.close();
804
- }
805
- }, [
806
- modals
807
- ]);
808
- if (!model?.projection) {
809
- return null;
810
- }
811
- return /* @__PURE__ */ React6.createElement(Popover3.Root, {
812
- modal: false,
813
- open: state?.type === "createRefPanel" && !!schema,
814
- onOpenChange: (nextOpen) => {
815
- if (model && !nextOpen) {
816
- return modals.close();
817
- }
818
- }
819
- }, /* @__PURE__ */ React6.createElement(Popover3.VirtualTrigger, {
820
- virtualRef: modals.trigger
821
- }), /* @__PURE__ */ React6.createElement(Popover3.Portal, null, /* @__PURE__ */ React6.createElement(Popover3.Content, {
822
- classNames: "md:is-64",
823
- "data-grid": gridId
824
- }, /* @__PURE__ */ React6.createElement(Popover3.Viewport, null, state?.type === "createRefPanel" && schema && /* @__PURE__ */ React6.createElement(Form2, {
825
- schema,
826
- values: state.initialValues ?? {},
827
- onSave: handleSave,
828
- onCancel: handleCancel
829
- })), /* @__PURE__ */ React6.createElement(Popover3.Arrow, null))));
830
- } finally {
831
- _effect.f();
832
- }
833
- };
834
-
835
685
  // src/components/Table/RowActionsMenu.tsx
836
- import { useSignals as _useSignals7 } from "@preact-signals/safe-react/tracking";
837
- import React7 from "react";
686
+ import { useSignals as _useSignals6 } from "@preact-signals/safe-react/tracking";
687
+ import React6 from "react";
838
688
  import { DropdownMenu as DropdownMenu2, toLocalizedString, useTranslation as useTranslation2 } from "@dxos/react-ui";
839
689
  var RowActionsMenu = ({ model, modals }) => {
840
- var _effect = _useSignals7();
690
+ var _effect = _useSignals6();
841
691
  try {
842
692
  const { t } = useTranslation2(translationKey);
843
693
  const hasSelection = model.selection.hasSelection.value;
@@ -845,23 +695,23 @@ var RowActionsMenu = ({ model, modals }) => {
845
695
  if (state?.type !== "row") {
846
696
  return null;
847
697
  }
848
- return /* @__PURE__ */ React7.createElement(DropdownMenu2.Root, {
698
+ return /* @__PURE__ */ React6.createElement(DropdownMenu2.Root, {
849
699
  modal: false,
850
700
  open: true,
851
701
  onOpenChange: modals.close
852
- }, /* @__PURE__ */ React7.createElement(DropdownMenu2.VirtualTrigger, {
702
+ }, /* @__PURE__ */ React6.createElement(DropdownMenu2.VirtualTrigger, {
853
703
  virtualRef: modals.trigger
854
- }), /* @__PURE__ */ React7.createElement(DropdownMenu2.Content, null, /* @__PURE__ */ React7.createElement(DropdownMenu2.Viewport, null, model.features.dataEditable !== false && /* @__PURE__ */ React7.createElement(DropdownMenu2.Item, {
855
- "data-testid": "row-menu-delete",
856
- onClick: () => model.deleteRow(state.rowIndex)
857
- }, t(hasSelection ? "bulk delete row label" : "delete row label")), model.rowActions?.map((action) => /* @__PURE__ */ React7.createElement(DropdownMenu2.Item, {
704
+ }), /* @__PURE__ */ React6.createElement(DropdownMenu2.Content, null, /* @__PURE__ */ React6.createElement(DropdownMenu2.Viewport, null, model.rowActions?.length > 0 && /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(DropdownMenu2.Group, null, model.rowActions?.map((action) => /* @__PURE__ */ React6.createElement(DropdownMenu2.Item, {
858
705
  key: action.id,
859
706
  "data-testid": `row-action-${action.id}`,
860
707
  onClick: () => {
861
708
  modals.close();
862
709
  model.handleRowAction(action.id, state.rowIndex);
863
710
  }
864
- }, toLocalizedString(action.label, t)))), /* @__PURE__ */ React7.createElement(DropdownMenu2.Arrow, null)));
711
+ }, toLocalizedString(action.label, t)))), /* @__PURE__ */ React6.createElement(DropdownMenu2.Separator, null)), model.features.dataEditable !== false && /* @__PURE__ */ React6.createElement(DropdownMenu2.Item, {
712
+ "data-testid": "row-menu-delete",
713
+ onClick: () => model.deleteRow(state.rowIndex)
714
+ }, t(hasSelection ? "bulk delete row label" : "delete row label"))), /* @__PURE__ */ React6.createElement(DropdownMenu2.Arrow, null)));
865
715
  } finally {
866
716
  _effect.f();
867
717
  }
@@ -881,9 +731,9 @@ var rowDefault = {
881
731
  }
882
732
  };
883
733
  var TableRoot = ({ children, role = "article" }) => {
884
- var _effect = _useSignals8();
734
+ var _effect = _useSignals7();
885
735
  try {
886
- return /* @__PURE__ */ React8.createElement("div", {
736
+ return /* @__PURE__ */ React7.createElement("div", {
887
737
  role: "none",
888
738
  className: mx("relative !border-separator [&_.dx-grid]:max-is-[--dx-grid-content-inline-size] [&_.dx-grid]:max-bs-[--dx-grid-content-block-size]", role === "card--popover" && "popover-card-height", role === "section" && "attention-surface", role === "card--intrinsic" && "[&_.dx-grid]:bs-[--dx-grid-content-block-size]", [
889
739
  "card--popover",
@@ -898,20 +748,20 @@ var TableRoot = ({ children, role = "article" }) => {
898
748
  _effect.f();
899
749
  }
900
750
  };
901
- var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttention, schema, client, onRowClick }, forwardedRef) => {
902
- var _effect = _useSignals8();
751
+ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttention, schema, client, onCreate, onRowClick, testId }, forwardedRef) => {
752
+ var _effect = _useSignals7();
903
753
  try {
904
754
  const [dxGrid, setDxGrid] = useState4(null);
905
755
  const { hasAttention } = useAttention(model?.id ?? "table");
906
- const modals = useMemo5(() => new ModalController(), []);
756
+ const modals = useMemo4(() => new ModalController(), []);
907
757
  const draftRowCount = model?.getDraftRowCount() ?? 0;
908
- const handleSave = useCallback5(() => {
758
+ const handleSave = useCallback4(() => {
909
759
  dxGrid?.updateCells(true);
910
760
  dxGrid?.requestUpdate();
911
761
  }, [
912
762
  dxGrid
913
763
  ]);
914
- const frozen = useMemo5(() => {
764
+ const frozen = useMemo4(() => {
915
765
  const noActionColumn = model?.features.dataEditable === false && model?.features.schemaEditable === false && model.rowActions.length === 0;
916
766
  return {
917
767
  frozenRowsStart: 1,
@@ -923,7 +773,7 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
923
773
  model,
924
774
  draftRowCount
925
775
  ]);
926
- const getCells = useCallback5((range, plane) => presentation?.getCells(range, plane) ?? {}, [
776
+ const getCells = useCallback4((range, plane) => presentation?.getCells(range, plane) ?? {}, [
927
777
  presentation
928
778
  ]);
929
779
  useEffect3(() => {
@@ -936,7 +786,7 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
936
786
  dxGrid,
937
787
  getCells
938
788
  ]);
939
- const handleInsertRowResult = useCallback5((insertResult) => {
789
+ const handleInsertRowResult = useCallback4((insertResult) => {
940
790
  if (insertResult === "draft") {
941
791
  requestAnimationFrame(() => {
942
792
  dxGrid?.setFocus({
@@ -980,7 +830,7 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
980
830
  dxGrid,
981
831
  model
982
832
  ]);
983
- const handleSaveDraftRow = useCallback5((rowIndex = 0) => {
833
+ const handleSaveDraftRow = useCallback4((rowIndex = 0) => {
984
834
  if (model && dxGrid) {
985
835
  const didCommitSuccessfully = model.commitDraftRow(rowIndex);
986
836
  if (didCommitSuccessfully) {
@@ -993,7 +843,7 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
993
843
  model,
994
844
  dxGrid
995
845
  ]);
996
- const handleGridClick = useCallback5((event) => {
846
+ const handleGridClick = useCallback4((event) => {
997
847
  const cell = closestCell(event.target);
998
848
  if (cell) {
999
849
  const { row: rowIndex, plane } = cell;
@@ -1078,9 +928,9 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
1078
928
  modals,
1079
929
  dxGrid
1080
930
  ]);
1081
- const handleFocus = useCallback5((increment, delta, cell) => {
931
+ const handleFocus = useCallback4((increment, delta, cell) => {
1082
932
  if (dxGrid && model) {
1083
- if (cell?.plane === "grid" && cell?.row >= model.getRowCount() - 1) {
933
+ if (cell?.plane === "grid" && cell?.row >= model.getRowCount() - 1 && increment !== "col") {
1084
934
  handleInsertRowResult(draftRowCount < 1 ? model.insertRow() : "final");
1085
935
  } else if (cell?.plane === "frozenRowsEnd" && increment === "row") {
1086
936
  handleSaveDraftRow(cell.row);
@@ -1093,7 +943,7 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
1093
943
  dxGrid,
1094
944
  model
1095
945
  ]);
1096
- const handleKeyDown = useCallback5((event) => {
946
+ const handleKeyDown = useCallback4((event) => {
1097
947
  if (!model?.features.dataEditable) {
1098
948
  return;
1099
949
  }
@@ -1118,7 +968,7 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
1118
968
  event.preventDefault();
1119
969
  void navigator.clipboard.readText().then((clipboardText) => {
1120
970
  try {
1121
- model.setCellData(cell, clipboardText);
971
+ model.setCellData(cell, String2.trim(clipboardText).replace(/[\n\r]+/, " "));
1122
972
  handleSave();
1123
973
  } catch {
1124
974
  const cellElement = event.target.closest('[data-dx-grid-action="cell"]');
@@ -1149,6 +999,7 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
1149
999
  try {
1150
1000
  model.setCellData(cell, void 0);
1151
1001
  event.preventDefault();
1002
+ handleSave();
1152
1003
  } catch {
1153
1004
  }
1154
1005
  break;
@@ -1159,7 +1010,7 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
1159
1010
  dxGrid,
1160
1011
  handleSave
1161
1012
  ]);
1162
- const handleAxisResize = useCallback5((event) => {
1013
+ const handleAxisResize = useCallback4((event) => {
1163
1014
  if (event.axis === "col") {
1164
1015
  const columnIndex = parseInt(event.index, 10);
1165
1016
  model?.setColumnWidth(columnIndex, event.size);
@@ -1167,7 +1018,7 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
1167
1018
  }, [
1168
1019
  model
1169
1020
  ]);
1170
- const handleWheel = useCallback5((event) => {
1021
+ const handleWheel = useCallback4((event) => {
1171
1022
  if (!ignoreAttention && !hasAttention) {
1172
1023
  event.stopPropagation();
1173
1024
  }
@@ -1175,7 +1026,7 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
1175
1026
  hasAttention,
1176
1027
  ignoreAttention
1177
1028
  ]);
1178
- const handleNewColumn = useCallback5(() => {
1029
+ const handleNewColumn = useCallback4(() => {
1179
1030
  const columns = model?.getColumnCount();
1180
1031
  if (dxGrid && columns) {
1181
1032
  dxGrid.scrollToColumn(columns - 1);
@@ -1185,21 +1036,22 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
1185
1036
  dxGrid
1186
1037
  ]);
1187
1038
  if (!model || !modals) {
1188
- return /* @__PURE__ */ React8.createElement("span", {
1039
+ return /* @__PURE__ */ React7.createElement("span", {
1189
1040
  role: "none",
1190
1041
  className: "attention-surface"
1191
1042
  });
1192
1043
  }
1193
- return /* @__PURE__ */ React8.createElement(Grid.Root, {
1044
+ return /* @__PURE__ */ React7.createElement(Grid.Root, {
1194
1045
  id: model.id ?? "table-grid"
1195
- }, /* @__PURE__ */ React8.createElement(TableValueEditor, {
1046
+ }, /* @__PURE__ */ React7.createElement(TableValueEditor, {
1196
1047
  model,
1197
1048
  modals,
1198
1049
  schema,
1199
1050
  onFocus: handleFocus,
1200
1051
  onSave: handleSave,
1052
+ onCreate,
1201
1053
  client
1202
- }), /* @__PURE__ */ React8.createElement(Grid.Content, {
1054
+ }), /* @__PURE__ */ React7.createElement(Grid.Content, {
1203
1055
  className: mx("[--dx-grid-base:var(--baseSurface)]", gridSeparatorInlineEnd, gridSeparatorBlockEnd),
1204
1056
  frozen,
1205
1057
  columns: model.columnMeta.value,
@@ -1212,20 +1064,20 @@ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttenti
1212
1064
  onClick: handleGridClick,
1213
1065
  onKeyDownCapture: handleKeyDown,
1214
1066
  onWheelCapture: handleWheel,
1067
+ ...testId && {
1068
+ "data-testid": testId
1069
+ },
1215
1070
  ref: setDxGrid
1216
- }), /* @__PURE__ */ React8.createElement(RowActionsMenu, {
1071
+ }), /* @__PURE__ */ React7.createElement(RowActionsMenu, {
1217
1072
  model,
1218
1073
  modals
1219
- }), /* @__PURE__ */ React8.createElement(ColumnActionsMenu, {
1074
+ }), /* @__PURE__ */ React7.createElement(ColumnActionsMenu, {
1220
1075
  model,
1221
1076
  modals
1222
- }), /* @__PURE__ */ React8.createElement(ColumnSettings, {
1077
+ }), /* @__PURE__ */ React7.createElement(ColumnSettings, {
1223
1078
  model,
1224
1079
  modals,
1225
1080
  onNewColumn: handleNewColumn
1226
- }), /* @__PURE__ */ React8.createElement(CreateRefPanel, {
1227
- model,
1228
- modals
1229
1081
  }));
1230
1082
  } finally {
1231
1083
  _effect.f();
@@ -1237,14 +1089,14 @@ var Table = {
1237
1089
  };
1238
1090
 
1239
1091
  // src/components/Table/DynamicTable.tsx
1240
- import { useSignals as _useSignals9 } from "@preact-signals/safe-react/tracking";
1241
- import React9, { useCallback as useCallback6, useMemo as useMemo6, useRef as useRef3 } from "react";
1092
+ import { useSignals as _useSignals8 } from "@preact-signals/safe-react/tracking";
1093
+ import React8, { useCallback as useCallback5, useMemo as useMemo5, useRef as useRef3 } from "react";
1242
1094
  import { useDefaultValue } from "@dxos/react-ui";
1243
1095
  import { mx as mx2 } from "@dxos/react-ui-theme";
1244
1096
  var DynamicTable = ({ classNames, name = "example.com/dynamic-table", rows, properties, jsonSchema: _jsonSchema, schema, rowActions, onRowClick, onRowAction, ...props }) => {
1245
- var _effect = _useSignals9();
1097
+ var _effect = _useSignals8();
1246
1098
  try {
1247
- const { typename, jsonSchema } = useMemo6(() => getBaseSchema({
1099
+ const { jsonSchema } = useMemo5(() => getBaseSchema({
1248
1100
  typename: name,
1249
1101
  properties,
1250
1102
  jsonSchema: _jsonSchema,
@@ -1255,20 +1107,18 @@ var DynamicTable = ({ classNames, name = "example.com/dynamic-table", rows, prop
1255
1107
  _jsonSchema,
1256
1108
  schema
1257
1109
  ]);
1258
- const { projection, view } = useMemo6(() => makeDynamicTable({
1259
- typename,
1110
+ const { projection, view } = useMemo5(() => makeDynamicTable({
1260
1111
  jsonSchema,
1261
1112
  properties
1262
1113
  }), [
1263
- typename,
1264
1114
  jsonSchema,
1265
1115
  properties
1266
1116
  ]);
1267
1117
  const tableRef = useRef3(null);
1268
- const handleCellUpdate = useCallback6((cell) => {
1118
+ const handleCellUpdate = useCallback5((cell) => {
1269
1119
  tableRef.current?.update?.(cell);
1270
1120
  }, []);
1271
- const handleRowOrderChange = useCallback6(() => {
1121
+ const handleRowOrderChange = useCallback5(() => {
1272
1122
  tableRef.current?.update?.();
1273
1123
  }, []);
1274
1124
  const features = useDefaultValue(props.features, () => ({
@@ -1288,20 +1138,20 @@ var DynamicTable = ({ classNames, name = "example.com/dynamic-table", rows, prop
1288
1138
  onRowOrderChange: handleRowOrderChange,
1289
1139
  onRowAction
1290
1140
  });
1291
- const presentation = useMemo6(() => {
1141
+ const presentation = useMemo5(() => {
1292
1142
  if (model) {
1293
1143
  return new TablePresentation(model);
1294
1144
  }
1295
1145
  }, [
1296
1146
  model
1297
1147
  ]);
1298
- return /* @__PURE__ */ React9.createElement("div", {
1148
+ return /* @__PURE__ */ React8.createElement("div", {
1299
1149
  role: "none",
1300
1150
  className: mx2("is-full bs-full grow grid", classNames)
1301
- }, /* @__PURE__ */ React9.createElement("div", {
1151
+ }, /* @__PURE__ */ React8.createElement("div", {
1302
1152
  role: "none",
1303
1153
  className: "grid min-bs-0 overflow-hidden"
1304
- }, /* @__PURE__ */ React9.createElement(Table.Root, null, /* @__PURE__ */ React9.createElement(Table.Main, {
1154
+ }, /* @__PURE__ */ React8.createElement(Table.Root, null, /* @__PURE__ */ React8.createElement(Table.Main, {
1305
1155
  ref: tableRef,
1306
1156
  model,
1307
1157
  presentation,
@@ -1314,43 +1164,46 @@ var DynamicTable = ({ classNames, name = "example.com/dynamic-table", rows, prop
1314
1164
  };
1315
1165
 
1316
1166
  // src/components/TableToolbar/TableToolbar.tsx
1317
- import { useSignals as _useSignals10 } from "@preact-signals/safe-react/tracking";
1318
- import { Rx } from "@effect-rx/rx-react";
1319
- import React10, { useMemo as useMemo7 } from "react";
1320
- import { live as live2 } from "@dxos/live-object";
1167
+ import { useSignals as _useSignals9 } from "@preact-signals/safe-react/tracking";
1168
+ import { Atom } from "@effect-atom/atom-react";
1169
+ import React9, { useMemo as useMemo6 } from "react";
1170
+ import { live } from "@dxos/live-object";
1321
1171
  import { MenuProvider, ToolbarMenu, createGapSeparator, createMenuAction, useMenuActions } from "@dxos/react-ui-menu";
1322
- import { rxFromSignal } from "@dxos/react-ui-menu";
1323
- var createTableToolbarActions = ({ state, onAdd, onSave, customActions }) => Rx.make((get) => {
1324
- const add = createMenuAction("add-row", onAdd, {
1325
- type: "add-row",
1326
- icon: "ph--plus--regular",
1327
- label: [
1328
- "add row",
1329
- {
1330
- ns: translationKey
1331
- }
1332
- ],
1333
- testId: "table.toolbar.add-row"
1334
- });
1335
- const save = createMenuAction("save-view", onSave, {
1336
- type: "save-view",
1337
- icon: "ph--floppy-disk--regular",
1338
- label: [
1339
- "save view label",
1340
- {
1341
- ns: translationKey
1342
- }
1343
- ],
1344
- testId: "table.toolbar.save-view",
1345
- iconOnly: false,
1346
- hidden: get(rxFromSignal(() => !state.viewDirty))
1347
- });
1172
+ import { atomFromSignal } from "@dxos/react-ui-menu";
1173
+ var createTableToolbarActions = ({ state, onAdd, onSave, customActions }) => Atom.make((get) => {
1174
+ const nodes = [];
1175
+ if (onAdd) {
1176
+ const add = createMenuAction("add-row", onAdd, {
1177
+ type: "add-row",
1178
+ icon: "ph--plus--regular",
1179
+ label: [
1180
+ "add row",
1181
+ {
1182
+ ns: translationKey
1183
+ }
1184
+ ],
1185
+ testId: "table.toolbar.add-row"
1186
+ });
1187
+ nodes.push(add);
1188
+ }
1189
+ if (onSave) {
1190
+ const save = createMenuAction("save-view", onSave, {
1191
+ type: "save-view",
1192
+ icon: "ph--floppy-disk--regular",
1193
+ label: [
1194
+ "save view label",
1195
+ {
1196
+ ns: translationKey
1197
+ }
1198
+ ],
1199
+ testId: "table.toolbar.save-view",
1200
+ iconOnly: false,
1201
+ hidden: get(atomFromSignal(() => !state.viewDirty))
1202
+ });
1203
+ nodes.push(save);
1204
+ }
1348
1205
  const gap = createGapSeparator();
1349
- const nodes = [
1350
- add,
1351
- save,
1352
- ...gap.nodes
1353
- ];
1206
+ nodes.push(...gap.nodes);
1354
1207
  const edges = nodes.map(({ id: target }) => ({
1355
1208
  source: "root",
1356
1209
  target
@@ -1366,12 +1219,12 @@ var createTableToolbarActions = ({ state, onAdd, onSave, customActions }) => Rx.
1366
1219
  };
1367
1220
  });
1368
1221
  var TableToolbar = ({ classNames, viewDirty, attendableId, onAdd, onSave, customActions }) => {
1369
- var _effect = _useSignals10();
1222
+ var _effect = _useSignals9();
1370
1223
  try {
1371
- const state = useMemo7(() => live2({
1224
+ const state = useMemo6(() => live({
1372
1225
  viewDirty
1373
1226
  }), []);
1374
- const actionsCreator = useMemo7(() => createTableToolbarActions({
1227
+ const actionsCreator = useMemo6(() => createTableToolbarActions({
1375
1228
  state,
1376
1229
  onAdd,
1377
1230
  onSave,
@@ -1383,10 +1236,10 @@ var TableToolbar = ({ classNames, viewDirty, attendableId, onAdd, onSave, custom
1383
1236
  customActions
1384
1237
  ]);
1385
1238
  const menu = useMenuActions(actionsCreator);
1386
- return /* @__PURE__ */ React10.createElement(MenuProvider, {
1239
+ return /* @__PURE__ */ React9.createElement(MenuProvider, {
1387
1240
  ...menu,
1388
1241
  attendableId
1389
- }, /* @__PURE__ */ React10.createElement(ToolbarMenu, {
1242
+ }, /* @__PURE__ */ React9.createElement(ToolbarMenu, {
1390
1243
  classNames
1391
1244
  }));
1392
1245
  } finally {