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