@dxos/react-ui-table 0.8.4-main.72ec0f3 → 0.8.4-main.937b3ca

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 (129) hide show
  1. package/dist/lib/browser/{chunk-GS2UNGJK.mjs → chunk-MNZKOFMA.mjs} +633 -662
  2. package/dist/lib/browser/chunk-MNZKOFMA.mjs.map +7 -0
  3. package/dist/lib/browser/chunk-OZBLY7XM.mjs +76 -0
  4. package/dist/lib/browser/chunk-OZBLY7XM.mjs.map +7 -0
  5. package/dist/lib/browser/index.mjs +1101 -973
  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 +29 -41
  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-TRR3C5NX.mjs → chunk-2ATAIIAO.mjs} +633 -661
  12. package/dist/lib/node-esm/chunk-2ATAIIAO.mjs.map +7 -0
  13. package/dist/lib/node-esm/chunk-WNZSKIRF.mjs +77 -0
  14. package/dist/lib/node-esm/chunk-WNZSKIRF.mjs.map +7 -0
  15. package/dist/lib/node-esm/index.mjs +1101 -973
  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 +29 -41
  19. package/dist/lib/node-esm/testing/index.mjs.map +3 -3
  20. package/dist/lib/node-esm/types/index.mjs +3 -3
  21. package/dist/types/src/components/Table/ColumnActionsMenu.d.ts +1 -2
  22. package/dist/types/src/components/Table/ColumnActionsMenu.d.ts.map +1 -1
  23. package/dist/types/src/components/Table/ColumnSettings.d.ts +2 -2
  24. package/dist/types/src/components/Table/ColumnSettings.d.ts.map +1 -1
  25. package/dist/types/src/components/Table/DynamicTable.d.ts +4 -5
  26. package/dist/types/src/components/Table/DynamicTable.d.ts.map +1 -1
  27. package/dist/types/src/components/Table/DynamicTable.stories.d.ts +4 -18
  28. package/dist/types/src/components/Table/DynamicTable.stories.d.ts.map +1 -1
  29. package/dist/types/src/components/Table/Relations.stories.d.ts +12 -8
  30. package/dist/types/src/components/Table/Relations.stories.d.ts.map +1 -1
  31. package/dist/types/src/components/Table/RowActionsMenu.d.ts.map +1 -1
  32. package/dist/types/src/components/Table/Table.d.ts +8 -8
  33. package/dist/types/src/components/Table/Table.d.ts.map +1 -1
  34. package/dist/types/src/components/Table/Table.stories.d.ts +71 -5
  35. package/dist/types/src/components/Table/Table.stories.d.ts.map +1 -1
  36. package/dist/types/src/components/TableCellEditor/CellValidationMessage.d.ts +1 -1
  37. package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts +10 -12
  38. package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts.map +1 -1
  39. package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts +5 -7
  40. package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts.map +1 -1
  41. package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts +4 -4
  42. package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts.map +1 -1
  43. package/dist/types/src/components/TableToolbar/TableToolbar.d.ts +2 -2
  44. package/dist/types/src/components/TableToolbar/TableToolbar.d.ts.map +1 -1
  45. package/dist/types/src/components/testing.d.ts +22 -15
  46. package/dist/types/src/components/testing.d.ts.map +1 -1
  47. package/dist/types/src/hooks/index.d.ts +2 -1
  48. package/dist/types/src/hooks/index.d.ts.map +1 -1
  49. package/dist/types/src/hooks/useAddRow.d.ts +5 -6
  50. package/dist/types/src/hooks/useAddRow.d.ts.map +1 -1
  51. package/dist/types/src/hooks/useProjectionModel.d.ts +6 -0
  52. package/dist/types/src/hooks/useProjectionModel.d.ts.map +1 -0
  53. package/dist/types/src/hooks/useTableModel.d.ts +8 -8
  54. package/dist/types/src/hooks/useTableModel.d.ts.map +1 -1
  55. package/dist/types/src/model/modal-controller.d.ts +5 -1
  56. package/dist/types/src/model/modal-controller.d.ts.map +1 -1
  57. package/dist/types/src/model/selection-model.d.ts +17 -8
  58. package/dist/types/src/model/selection-model.d.ts.map +1 -1
  59. package/dist/types/src/model/table-model.d.ts +101 -22
  60. package/dist/types/src/model/table-model.d.ts.map +1 -1
  61. package/dist/types/src/model/table-presentation.d.ts +3 -1
  62. package/dist/types/src/model/table-presentation.d.ts.map +1 -1
  63. package/dist/types/src/playwright/TableManager.d.ts +1 -1
  64. package/dist/types/src/playwright/TableManager.d.ts.map +1 -1
  65. package/dist/types/src/testing/useTestTableModel.d.ts +18 -15
  66. package/dist/types/src/testing/useTestTableModel.d.ts.map +1 -1
  67. package/dist/types/src/translations.d.ts +4 -4
  68. package/dist/types/src/translations.d.ts.map +1 -1
  69. package/dist/types/src/types/Table.d.ts +31 -0
  70. package/dist/types/src/types/Table.d.ts.map +1 -0
  71. package/dist/types/src/types/index.d.ts +1 -1
  72. package/dist/types/src/types/index.d.ts.map +1 -1
  73. package/dist/types/src/util/dynamic-table.d.ts +13 -11
  74. package/dist/types/src/util/dynamic-table.d.ts.map +1 -1
  75. package/dist/types/src/util/index.d.ts +2 -0
  76. package/dist/types/src/util/index.d.ts.map +1 -1
  77. package/dist/types/src/util/query-ast.d.ts +7 -0
  78. package/dist/types/src/util/query-ast.d.ts.map +1 -0
  79. package/dist/types/src/util/sort.d.ts +12 -0
  80. package/dist/types/src/util/sort.d.ts.map +1 -0
  81. package/dist/types/tsconfig.tsbuildinfo +1 -1
  82. package/package.json +53 -54
  83. package/src/components/Table/ColumnActionsMenu.tsx +10 -6
  84. package/src/components/Table/ColumnSettings.tsx +6 -6
  85. package/src/components/Table/DynamicTable.stories.tsx +12 -13
  86. package/src/components/Table/DynamicTable.tsx +21 -14
  87. package/src/components/Table/Relations.stories.tsx +28 -33
  88. package/src/components/Table/RowActionsMenu.tsx +3 -2
  89. package/src/components/Table/Table.stories.tsx +65 -69
  90. package/src/components/Table/Table.tsx +335 -305
  91. package/src/components/TableCellEditor/CellValidationMessage.tsx +1 -1
  92. package/src/components/TableCellEditor/FormCellEditor.tsx +111 -134
  93. package/src/components/TableCellEditor/TableCellEditor.stories.tsx +11 -8
  94. package/src/components/TableCellEditor/TableCellEditor.tsx +31 -31
  95. package/src/components/TableToolbar/TableToolbar.tsx +19 -13
  96. package/src/components/testing.ts +38 -12
  97. package/src/hooks/index.ts +2 -1
  98. package/src/hooks/useAddRow.ts +8 -10
  99. package/src/hooks/useProjectionModel.ts +40 -0
  100. package/src/hooks/useTableModel.ts +35 -33
  101. package/src/model/modal-controller.ts +23 -12
  102. package/src/model/selection-model.ts +75 -44
  103. package/src/model/table-model.test.ts +81 -53
  104. package/src/model/table-model.ts +422 -160
  105. package/src/model/table-presentation.test.ts +58 -48
  106. package/src/model/table-presentation.ts +31 -26
  107. package/src/playwright/TableManager.ts +5 -5
  108. package/src/playwright/playwright.config.ts +1 -1
  109. package/src/playwright/smoke.spec.ts +4 -3
  110. package/src/testing/useTestTableModel.ts +44 -37
  111. package/src/translations.ts +3 -3
  112. package/src/types/Table.ts +90 -0
  113. package/src/types/index.ts +1 -1
  114. package/src/util/dynamic-table.ts +36 -23
  115. package/src/util/index.ts +2 -0
  116. package/src/util/query-ast.ts +19 -0
  117. package/src/util/sort.ts +90 -0
  118. package/dist/lib/browser/chunk-2PFAPQL4.mjs +0 -66
  119. package/dist/lib/browser/chunk-2PFAPQL4.mjs.map +0 -7
  120. package/dist/lib/browser/chunk-GS2UNGJK.mjs.map +0 -7
  121. package/dist/lib/node-esm/chunk-6POOFFYF.mjs +0 -67
  122. package/dist/lib/node-esm/chunk-6POOFFYF.mjs.map +0 -7
  123. package/dist/lib/node-esm/chunk-TRR3C5NX.mjs.map +0 -7
  124. package/dist/types/src/model/table-sorting.d.ts +0 -52
  125. package/dist/types/src/model/table-sorting.d.ts.map +0 -1
  126. package/dist/types/src/types/schema.d.ts +0 -28
  127. package/dist/types/src/types/schema.d.ts.map +0 -1
  128. package/src/model/table-sorting.ts +0 -225
  129. package/src/types/schema.ts +0 -73
@@ -2,24 +2,27 @@ import {
2
2
  BUTTON_IDENTIFIERS,
3
3
  CONTROL_IDENTIFIERS,
4
4
  CheckboxStory,
5
- ModalController,
6
5
  SwitchStory,
7
6
  TableModel,
8
7
  TablePresentation,
9
8
  cellClassesForRowSelection,
10
- getBaseSchema,
11
- makeDynamicTable,
12
- narrowSchema,
9
+ compareValues,
10
+ createDirectChangeCallback,
11
+ createEchoChangeCallback,
12
+ extractOrder,
13
+ getSortValue,
13
14
  tableButtons,
14
15
  tableControls,
15
- touch,
16
16
  useAddRow,
17
+ useProjectionModel,
17
18
  useTableModel
18
- } from "./chunk-GS2UNGJK.mjs";
19
- import "./chunk-2PFAPQL4.mjs";
19
+ } from "./chunk-MNZKOFMA.mjs";
20
+ import {
21
+ Table_exports
22
+ } from "./chunk-OZBLY7XM.mjs";
20
23
 
21
24
  // src/translations.ts
22
- var translationKey = "react-ui-table";
25
+ var translationKey = "@dxos/react-ui-table";
23
26
  var translations = [
24
27
  {
25
28
  "en-US": {
@@ -28,8 +31,8 @@ var translations = [
28
31
  "create object label": "Create table",
29
32
  "table name placeholder": "Table name",
30
33
  "settings title": "Table settings",
31
- "table schema label": "Record type",
32
- "new schema": "New record type",
34
+ "table schema label": "Type",
35
+ "new schema": "New type",
33
36
  "continue label": "Continue",
34
37
  "create stack section label": "Create table",
35
38
  "add row label": "Add row",
@@ -51,63 +54,227 @@ var translations = [
51
54
  ];
52
55
 
53
56
  // src/components/Table/Table.tsx
54
- import { useSignals as _useSignals7 } from "@preact-signals/safe-react/tracking";
57
+ import { Atom as Atom2, RegistryContext, useAtomValue as useAtomValue4 } from "@effect-atom/atom-react";
55
58
  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";
59
+ import React7, { forwardRef, useCallback as useCallback4, useContext, useEffect as useEffect3, useImperativeHandle, useMemo as useMemo4, useState as useState4 } from "react";
60
+ import { log } from "@dxos/log";
57
61
  import { useAttention } from "@dxos/react-ui-attention";
58
62
  import { Grid, closestCell, gridSeparatorBlockEnd, gridSeparatorInlineEnd } from "@dxos/react-ui-grid";
59
63
  import { DxEditRequest } from "@dxos/react-ui-grid";
60
- import { mx } from "@dxos/react-ui-theme";
64
+ import { mx } from "@dxos/ui-theme";
65
+
66
+ // src/util/dynamic-table.ts
67
+ import { Filter, Obj, Order, Query, Ref, Type } from "@dxos/echo";
68
+ import { ProjectionModel, View, createDirectChangeCallback as createDirectChangeCallback2, getSchemaFromPropertyDefinitions } from "@dxos/schema";
69
+ var getBaseSchema = ({ schema, typename, properties, jsonSchema }) => {
70
+ if (typename && properties) {
71
+ const schema2 = getSchemaFromPropertyDefinitions(typename, properties);
72
+ return {
73
+ typename: schema2.typename,
74
+ jsonSchema: schema2.jsonSchema
75
+ };
76
+ } else if (schema) {
77
+ return {
78
+ typename: Type.getTypename(schema),
79
+ jsonSchema: Type.toJsonSchema(schema)
80
+ };
81
+ } else if (typename && jsonSchema) {
82
+ return {
83
+ typename,
84
+ jsonSchema
85
+ };
86
+ } else {
87
+ throw new Error("invalid properties");
88
+ }
89
+ };
90
+ var makeDynamicTable = ({ registry, jsonSchema, properties }) => {
91
+ const view = View.make({
92
+ query: Query.select(Filter.everything()),
93
+ jsonSchema,
94
+ ...properties && {
95
+ fields: properties.map((property) => property.name)
96
+ }
97
+ });
98
+ const object = Obj.make(Table_exports.Table, {
99
+ view: Ref.make(view),
100
+ sizes: {}
101
+ });
102
+ const projection = new ProjectionModel({
103
+ registry,
104
+ view,
105
+ baseSchema: jsonSchema,
106
+ change: createDirectChangeCallback2(view.projection, jsonSchema)
107
+ });
108
+ projection.normalizeView();
109
+ if (properties && projection.getFields()) {
110
+ setProperties(view, projection, object, properties);
111
+ }
112
+ return {
113
+ projection,
114
+ object
115
+ };
116
+ };
117
+ var setProperties = (view, projection, table, properties) => {
118
+ for (const property of properties) {
119
+ const field = projection.getFields().find((field2) => field2.path === property.name);
120
+ if (field) {
121
+ if (property.size !== void 0) {
122
+ Obj.change(table, (t) => {
123
+ t.sizes[field.path] = property.size;
124
+ });
125
+ }
126
+ if (property.title !== void 0) {
127
+ const fieldProjection = projection.getFieldProjection(field.id);
128
+ projection.setFieldProjection({
129
+ ...fieldProjection,
130
+ props: {
131
+ ...fieldProjection.props,
132
+ title: property.title
133
+ }
134
+ });
135
+ }
136
+ if (property.sort) {
137
+ const currentQuery = Query.fromAst(Obj.getSnapshot(view).query.ast);
138
+ const newQuery = currentQuery.orderBy(Order.property(field.path, property.sort));
139
+ Obj.change(view, (v) => {
140
+ v.query.ast = newQuery.ast;
141
+ });
142
+ }
143
+ }
144
+ }
145
+ };
146
+
147
+ // src/util/signals.ts
148
+ var touch = (value) => value;
149
+
150
+ // src/util/schema.ts
151
+ import * as Schema from "effect/Schema";
152
+ import * as SchemaAST from "effect/SchemaAST";
153
+ var narrowSchema = (schema, paths) => {
154
+ const ast = schema?.ast;
155
+ if (SchemaAST.isTypeLiteral(ast)) {
156
+ const propertySignatures = ast.propertySignatures.filter((signature) => paths.includes(signature.name.toString()));
157
+ if (propertySignatures.length > 0) {
158
+ const narrowType = new SchemaAST.TypeLiteral(propertySignatures, []);
159
+ return Schema.make(narrowType);
160
+ }
161
+ }
162
+ return void 0;
163
+ };
164
+
165
+ // src/model/modal-controller.ts
166
+ import { Atom } from "@effect-atom/atom-react";
167
+ var ModalController = class {
168
+ _registry;
169
+ _state;
170
+ _triggerRef = {
171
+ current: null
172
+ };
173
+ constructor(registry) {
174
+ this._registry = registry;
175
+ this._state = Atom.make({
176
+ type: "closed"
177
+ });
178
+ }
179
+ get state() {
180
+ return this._state;
181
+ }
182
+ get stateValue() {
183
+ return this._registry.get(this._state);
184
+ }
185
+ get trigger() {
186
+ return this._triggerRef;
187
+ }
188
+ setTrigger = (trigger) => {
189
+ this._triggerRef.current = trigger;
190
+ };
191
+ showRowMenu = (rowIndex) => {
192
+ this._registry.set(this._state, {
193
+ type: "row",
194
+ rowIndex
195
+ });
196
+ };
197
+ showColumnMenu = (fieldId) => {
198
+ this._registry.set(this._state, {
199
+ type: "column",
200
+ fieldId
201
+ });
202
+ };
203
+ showColumnCreator = () => {
204
+ this._registry.set(this._state, {
205
+ type: "columnSettings",
206
+ mode: {
207
+ type: "create"
208
+ }
209
+ });
210
+ };
211
+ showReferencePanel = (targetId, schemaId) => {
212
+ this._registry.set(this._state, {
213
+ type: "refPanel",
214
+ targetId,
215
+ typename: schemaId
216
+ });
217
+ };
218
+ openColumnSettings = () => {
219
+ const currentState = this._registry.get(this._state);
220
+ if (currentState.type === "column") {
221
+ const fieldId = currentState.fieldId;
222
+ requestAnimationFrame(() => {
223
+ this._registry.set(this._state, {
224
+ type: "columnSettings",
225
+ mode: {
226
+ type: "edit",
227
+ fieldId
228
+ }
229
+ });
230
+ });
231
+ }
232
+ };
233
+ close = () => {
234
+ this._registry.set(this._state, {
235
+ type: "closed"
236
+ });
237
+ };
238
+ };
61
239
 
62
240
  // src/components/TableCellEditor/TableCellEditor.tsx
63
- import { useSignals as _useSignals3 } from "@preact-signals/safe-react/tracking";
64
241
  import { EditorView } from "@codemirror/view";
65
242
  import React3, { useCallback as useCallback2, useMemo as useMemo2, useRef as useRef2, useState as useState2 } from "react";
66
243
  import { debounce } from "@dxos/async";
67
- import { FormatEnum as FormatEnum2, TypeEnum } from "@dxos/echo/internal";
244
+ import { Format, TypeEnum } from "@dxos/echo/internal";
68
245
  import { invariant as invariant2 } from "@dxos/invariant";
69
246
  import { GridCellEditor, editorKeys, parseCellIndex as parseCellIndex2, useGridContext as useGridContext3 } from "@dxos/react-ui-grid";
70
247
 
71
248
  // src/components/TableCellEditor/CellValidationMessage.tsx
72
- import { useSignals as _useSignals } from "@preact-signals/safe-react/tracking";
73
249
  import React from "react";
74
250
  import { useGridContext } from "@dxos/react-ui-grid";
75
- var CellValidationMessage = ({ validationError, variant = "error", __gridScope }) => {
76
- var _effect = _useSignals();
77
- try {
78
- const { editing, editBox: box } = useGridContext("GridSheetCellEditor", __gridScope);
79
- if (!editing || !validationError) {
80
- return null;
81
- }
82
- const bgClass = variant === "error" ? "bg-errorSurface" : "bg-warningSurface";
83
- const textClass = variant === "error" ? "text-errorSurfaceText" : "text-warningSurfaceText";
84
- return /* @__PURE__ */ React.createElement("div", {
85
- role: "none",
86
- className: `absolute ${bgClass} ${textClass} rounded-bs-sm text-xs p-1`,
87
- style: {
88
- ...{
89
- "--dx-gridCellWidth": `${box?.inlineSize ?? 200}px`
90
- },
91
- zIndex: 10,
92
- insetBlockEnd: `calc(100% - ${box.insetBlockStart}px)`,
93
- insetInlineStart: box.insetInlineStart,
94
- inlineSize: box.inlineSize
95
- }
96
- }, validationError);
97
- } finally {
98
- _effect.f();
251
+ var CellValidationMessage = ({ __gridScope, validationError, variant = "error" }) => {
252
+ const { editing, editBox: box } = useGridContext("GridSheetCellEditor", __gridScope);
253
+ if (!editing || !validationError) {
254
+ return null;
99
255
  }
256
+ const bgClass = variant === "error" ? "bg-errorSurface" : "bg-warningSurface";
257
+ const textClass = variant === "error" ? "text-errorSurfaceText" : "text-warningSurfaceText";
258
+ return /* @__PURE__ */ React.createElement("div", {
259
+ role: "none",
260
+ className: `absolute ${bgClass} ${textClass} rounded-bs-sm text-xs p-1`,
261
+ style: {
262
+ ...{
263
+ "--dx-gridCellWidth": `${box?.inlineSize ?? 200}px`
264
+ },
265
+ zIndex: 10,
266
+ insetBlockEnd: `calc(100% - ${box.insetBlockStart}px)`,
267
+ insetInlineStart: box.insetInlineStart,
268
+ inlineSize: box.inlineSize
269
+ }
270
+ }, validationError);
100
271
  };
101
272
 
102
273
  // src/components/TableCellEditor/FormCellEditor.tsx
103
- import { useSignals as _useSignals2 } from "@preact-signals/safe-react/tracking";
104
- import * as Schema from "effect/Schema";
105
274
  import React2, { useCallback, useEffect, useMemo, useRef, useState } from "react";
106
- import { Filter, Obj } from "@dxos/echo";
107
- import { FormatEnum, Ref, getValue } from "@dxos/echo/internal";
275
+ import { Entity } from "@dxos/echo";
276
+ import { Ref as Ref2, getValue } from "@dxos/echo/internal";
108
277
  import { invariant } from "@dxos/invariant";
109
- import { getSnapshot } from "@dxos/live-object";
110
- import { getSpace } from "@dxos/react-client/echo";
111
278
  import { Popover } from "@dxos/react-ui";
112
279
  import { Form } from "@dxos/react-ui-form";
113
280
  import { parseCellIndex, useGridContext as useGridContext2 } from "@dxos/react-ui-grid";
@@ -119,429 +286,376 @@ var createOptionLabel = [
119
286
  ns: translationKey
120
287
  }
121
288
  ];
122
- var FormCellEditor = ({ fieldProjection, model, schema, onSave, client, modals, onCreate, __gridScope, ...formProps }) => {
123
- var _effect = _useSignals2();
124
- try {
125
- const { editing: contextEditing, setEditing, id: gridId } = useGridContext2("ArrayEditor", __gridScope);
126
- const [editing, setLocalEditing] = useState(false);
127
- const anchorRef = useRef(null);
128
- const getSchema = useCallback((typeAnnotation) => {
129
- const space = getSpace(model.view);
130
- invariant(space, void 0, {
131
- F: __dxlog_file,
132
- L: 57,
133
- S: void 0,
134
- A: [
135
- "space",
136
- ""
137
- ]
138
- });
139
- let schema2;
140
- if (client) {
141
- schema2 = client.graph.schemaRegistry.getSchema(typeAnnotation.typename);
142
- }
143
- if (!schema2) {
144
- schema2 = space.db.schemaRegistry.getSchema(typeAnnotation.typename);
145
- }
146
- return {
147
- space,
148
- schema: schema2
149
- };
150
- }, [
151
- client,
152
- model
153
- ]);
154
- const handleQueryRefOptions = useCallback(async (typeAnnotation) => {
155
- const { schema: schema2, space } = getSchema(typeAnnotation);
156
- if (model && schema2 && space) {
157
- const { objects } = await space.db.query(Filter.type(schema2)).run();
158
- return objects.map((obj) => {
159
- return {
160
- dxn: Obj.getDXN(obj),
161
- label: getValue(obj, fieldProjection.field.referencePath) || obj.id.toString()
162
- };
163
- }).filter(isTruthy);
164
- }
165
- return [];
166
- }, [
167
- client,
168
- model
169
- ]);
170
- const originalRow = useMemo(() => {
171
- if (model && contextEditing) {
172
- const cell = parseCellIndex(contextEditing.index);
173
- if (model.isDraftCell(cell)) {
174
- const draftRow = model.draftRows.value[cell.row];
175
- invariant(draftRow, void 0, {
176
- F: __dxlog_file,
177
- L: 98,
178
- S: void 0,
179
- A: [
180
- "draftRow",
181
- ""
182
- ]
183
- });
184
- return draftRow.data;
185
- } else {
186
- const row = model.getRowAt(cell.row);
187
- invariant(row, void 0, {
188
- F: __dxlog_file,
189
- L: 102,
190
- S: void 0,
191
- A: [
192
- "row",
193
- ""
194
- ]
195
- });
196
- return row;
197
- }
198
- }
199
- return void 0;
200
- }, [
201
- model,
202
- contextEditing
203
- ]);
204
- const handleSave = useCallback((values) => {
205
- const path = fieldProjection.field.path;
206
- const value = getDeep(values, [
207
- path
208
- ]);
209
- setDeep(originalRow, [
210
- path
211
- ], value);
212
- contextEditing?.cellElement?.focus();
213
- setEditing(null);
289
+ var FormCellEditor = ({ __gridScope, schema, model, fieldProjection, onSave, onCreate, ...formProps }) => {
290
+ const anchorRef = useRef(null);
291
+ const { id: _gridId, editing: contextEditing, setEditing } = useGridContext2("ArrayEditor", __gridScope);
292
+ const [editing, setLocalEditing] = useState(false);
293
+ useEffect(() => {
294
+ if (contextEditing && contextEditing.cellElement) {
295
+ anchorRef.current = contextEditing.cellElement.querySelector(".dx-grid__cell__content");
296
+ setLocalEditing(true);
297
+ } else {
298
+ anchorRef.current = null;
214
299
  setLocalEditing(false);
215
- onSave?.();
216
- }, [
217
- fieldProjection.field.path,
218
- onSave,
219
- contextEditing,
220
- originalRow
221
- ]);
222
- useEffect(() => {
223
- if (contextEditing && contextEditing.cellElement) {
224
- anchorRef.current = contextEditing.cellElement.querySelector(".dx-grid__cell__content");
225
- setLocalEditing(true);
226
- } else {
227
- anchorRef.current = null;
228
- setLocalEditing(false);
229
- }
230
- }, [
231
- contextEditing
232
- ]);
233
- const narrowedSchema = useMemo(() => {
234
- if (!schema) {
235
- return void 0;
236
- }
237
- return narrowSchema(schema, [
238
- fieldProjection.field.path
239
- ]);
240
- }, [
241
- JSON.stringify(schema),
300
+ }
301
+ }, [
302
+ contextEditing
303
+ ]);
304
+ const narrowedSchema = useMemo(() => {
305
+ if (!schema) {
306
+ return void 0;
307
+ }
308
+ return narrowSchema(schema, [
242
309
  fieldProjection.field.path
243
310
  ]);
244
- const formValues = useMemo(() => originalRow ? getSnapshot(originalRow) : {}, [
245
- originalRow
246
- ]);
247
- const handleOpenChange = useCallback((nextOpen) => {
248
- if (nextOpen === false) {
249
- setEditing(null);
250
- onSave?.();
251
- }
252
- setLocalEditing(nextOpen);
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
311
+ }, [
312
+ JSON.stringify(schema),
313
+ fieldProjection.field.path
314
+ ]);
315
+ const originalRow = useMemo(() => {
316
+ if (model && contextEditing) {
317
+ const cell = parseCellIndex(contextEditing.index);
318
+ if (model.isDraftCell(cell)) {
319
+ const draftRow = model.getDraftRows()[cell.row];
320
+ invariant(draftRow, void 0, {
321
+ F: __dxlog_file,
322
+ L: 74,
323
+ S: void 0,
324
+ A: [
325
+ "draftRow",
326
+ ""
327
+ ]
258
328
  });
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
- }
329
+ return draftRow.data;
330
+ } else {
331
+ const row = model.getRowAt(cell.row);
332
+ invariant(row, void 0, {
333
+ F: __dxlog_file,
334
+ L: 78,
335
+ S: void 0,
336
+ A: [
337
+ "row",
338
+ ""
339
+ ]
340
+ });
341
+ return row;
282
342
  }
283
- contextEditing?.cellElement?.focus();
343
+ }
344
+ return void 0;
345
+ }, [
346
+ model,
347
+ contextEditing
348
+ ]);
349
+ const formValues = useMemo(() => originalRow ? JSON.parse(JSON.stringify(originalRow)) : {}, [
350
+ originalRow
351
+ ]);
352
+ const handleOpenChange = useCallback((nextOpen) => {
353
+ if (nextOpen === false) {
284
354
  setEditing(null);
285
- setLocalEditing(false);
286
355
  onSave?.();
287
- }, [
288
- fieldProjection.field.path,
289
- onSave,
290
- contextEditing,
291
- originalRow,
292
- refSchema,
293
- onCreate
356
+ }
357
+ setLocalEditing(nextOpen);
358
+ }, []);
359
+ const handleSave = useCallback((values) => {
360
+ if (!originalRow) {
361
+ return;
362
+ }
363
+ const path = fieldProjection.field.path;
364
+ const value = getDeep(values, [
365
+ path
294
366
  ]);
295
- if (!editing) {
296
- return null;
367
+ if (model) {
368
+ model.changeRow(originalRow, (mutableRow) => {
369
+ setDeep(mutableRow, [
370
+ path
371
+ ], value);
372
+ });
373
+ } else {
374
+ setDeep(originalRow, [
375
+ path
376
+ ], value);
297
377
  }
298
- return /* @__PURE__ */ React2.createElement(Popover.Root, {
299
- open: editing,
300
- onOpenChange: handleOpenChange
301
- }, /* @__PURE__ */ React2.createElement(Popover.VirtualTrigger, {
302
- virtualRef: anchorRef
303
- }), /* @__PURE__ */ React2.createElement(Popover.Portal, null, /* @__PURE__ */ React2.createElement(Popover.Content, {
304
- tabIndex: -1,
305
- classNames: "popover-card-width density-fine"
306
- }, /* @__PURE__ */ React2.createElement(Popover.Arrow, null), /* @__PURE__ */ React2.createElement(Popover.Viewport, null, /* @__PURE__ */ React2.createElement(Form, {
307
- autoFocus: true,
308
- values: formValues,
309
- schema: narrowedSchema,
310
- onSave: handleSave,
311
- ...formProps,
312
- onQueryRefOptions: handleQueryRefOptions,
313
- ...createSchema && {
314
- onCreate: handleCreate,
315
- createSchema,
316
- createInitialValuePath: fieldProjection.field.referencePath,
317
- createOptionIcon: "ph--plus--regular",
318
- createOptionLabel
378
+ contextEditing?.cellElement?.focus();
379
+ setEditing(null);
380
+ setLocalEditing(false);
381
+ onSave?.();
382
+ }, [
383
+ fieldProjection.field.path,
384
+ onSave,
385
+ contextEditing,
386
+ originalRow,
387
+ model
388
+ ]);
389
+ const handleCreate = useCallback((schema2, values) => {
390
+ const objectWithId = onCreate?.(schema2, values);
391
+ if (objectWithId && originalRow) {
392
+ const ref = Ref2.make(objectWithId);
393
+ const path = fieldProjection.field.path;
394
+ if (model) {
395
+ model.changeRow(originalRow, (mutableRow) => {
396
+ setDeep(mutableRow, [
397
+ path
398
+ ], ref);
399
+ });
400
+ } else {
401
+ setDeep(originalRow, [
402
+ path
403
+ ], ref);
319
404
  }
320
- })))));
321
- } finally {
322
- _effect.f();
405
+ }
406
+ contextEditing?.cellElement?.focus();
407
+ setEditing(null);
408
+ setLocalEditing(false);
409
+ onSave?.();
410
+ }, [
411
+ fieldProjection.field.path,
412
+ onSave,
413
+ contextEditing,
414
+ originalRow,
415
+ onCreate,
416
+ model
417
+ ]);
418
+ const getOptions = useCallback((results) => results.map((obj) => {
419
+ return {
420
+ id: Entity.getDXN(obj).toString(),
421
+ label: getValue(obj, fieldProjection.field.referencePath) || obj.id.toString()
422
+ };
423
+ }).filter(isTruthy), [
424
+ fieldProjection
425
+ ]);
426
+ if (!editing) {
427
+ return null;
323
428
  }
429
+ return /* @__PURE__ */ React2.createElement(Popover.Root, {
430
+ open: editing,
431
+ onOpenChange: handleOpenChange
432
+ }, /* @__PURE__ */ React2.createElement(Popover.VirtualTrigger, {
433
+ virtualRef: anchorRef
434
+ }), /* @__PURE__ */ React2.createElement(Popover.Portal, null, /* @__PURE__ */ React2.createElement(Popover.Content, {
435
+ tabIndex: -1,
436
+ classNames: "popover-card-width density-fine"
437
+ }, /* @__PURE__ */ React2.createElement(Popover.Arrow, null), /* @__PURE__ */ React2.createElement(Popover.Viewport, null, /* @__PURE__ */ React2.createElement(Form.Root, {
438
+ ...formProps,
439
+ autoFocus: true,
440
+ schema: narrowedSchema,
441
+ values: formValues,
442
+ createInitialValuePath: fieldProjection.field.referencePath,
443
+ createOptionIcon: "ph--plus--regular",
444
+ createOptionLabel,
445
+ db: model?.db,
446
+ getOptions,
447
+ onCreate: handleCreate,
448
+ onSave: handleSave
449
+ }, /* @__PURE__ */ React2.createElement(Form.Viewport, null, /* @__PURE__ */ React2.createElement(Form.Content, null, /* @__PURE__ */ React2.createElement(Form.FieldSet, null), /* @__PURE__ */ React2.createElement(Form.Actions, null))))))));
324
450
  };
325
451
 
326
452
  // src/components/TableCellEditor/TableCellEditor.tsx
327
453
  var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/react-ui-table/src/components/TableCellEditor/TableCellEditor.tsx";
328
- var adaptValidationMessage = (message) => message ? message.endsWith("is missing") ? "Can\u2019t be blank" : message : null;
329
- var TableValueEditor = ({ model, modals, schema, onFocus, onSave, onCreate, client, __gridScope }) => {
330
- var _effect = _useSignals3();
331
- try {
332
- const { editing } = useGridContext3("TableValueEditor", __gridScope);
333
- const fieldProjection = useMemo2(() => {
334
- if (!model || !editing) {
335
- return;
336
- }
337
- const { col } = parseCellIndex2(editing.index);
338
- const field = model.projection.fields[col];
339
- const fieldProjection2 = model.projection.getFieldProjection(field.id);
340
- invariant2(fieldProjection2, void 0, {
341
- F: __dxlog_file2,
342
- L: 71,
343
- S: void 0,
344
- A: [
345
- "fieldProjection",
346
- ""
347
- ]
348
- });
349
- return fieldProjection2;
350
- }, [
351
- model,
352
- editing
353
- ]);
354
- if (fieldProjection?.props.type === TypeEnum.Array || fieldProjection?.props.format === FormatEnum2.SingleSelect || fieldProjection?.props.format === FormatEnum2.Ref) {
355
- return /* @__PURE__ */ React3.createElement(FormCellEditor, {
356
- fieldProjection,
357
- model,
358
- schema,
359
- __gridScope,
360
- onSave,
361
- onCreate,
362
- client,
363
- modals
364
- });
454
+ var editorSlots = {
455
+ scroll: {
456
+ className: "!plb-[--dx-grid-cell-editor-padding-block]"
457
+ }
458
+ };
459
+ var TableValueEditor = ({ __gridScope, schema, model, modals, onFocus, onSave, onCreate }) => {
460
+ const { editing } = useGridContext3("TableValueEditor", __gridScope);
461
+ const fieldProjection = useMemo2(() => {
462
+ if (!model || !editing) {
463
+ return;
365
464
  }
366
- return /* @__PURE__ */ React3.createElement(TableCellEditor, {
465
+ const { col } = parseCellIndex2(editing.index);
466
+ const field = model.projection.getFields()[col];
467
+ const fieldProjection2 = model.projection.getFieldProjection(field.id);
468
+ invariant2(fieldProjection2, void 0, {
469
+ F: __dxlog_file2,
470
+ L: 73,
471
+ S: void 0,
472
+ A: [
473
+ "fieldProjection",
474
+ ""
475
+ ]
476
+ });
477
+ return fieldProjection2;
478
+ }, [
479
+ model,
480
+ editing
481
+ ]);
482
+ if (fieldProjection?.props.type === TypeEnum.Array || fieldProjection?.props.format === Format.TypeFormat.SingleSelect || fieldProjection?.props.format === Format.TypeFormat.Ref) {
483
+ return /* @__PURE__ */ React3.createElement(FormCellEditor, {
484
+ __gridScope,
485
+ schema,
367
486
  model,
487
+ fieldProjection,
368
488
  modals,
369
- onFocus,
370
489
  onSave,
371
- __gridScope
490
+ onCreate
372
491
  });
373
- } finally {
374
- _effect.f();
375
492
  }
493
+ return /* @__PURE__ */ React3.createElement(TableCellEditor, {
494
+ model,
495
+ modals,
496
+ onFocus,
497
+ onSave,
498
+ __gridScope
499
+ });
376
500
  };
377
- var editorSlots = {
378
- scroll: {
379
- className: "!plb-[--dx-grid-cell-editor-padding-block]"
380
- }
381
- };
382
- var TableCellEditor = ({ model, modals, onFocus, onSave, __gridScope }) => {
383
- var _effect = _useSignals3();
384
- try {
385
- const { editing, setEditing } = useGridContext3("TableCellEditor", __gridScope);
386
- const suppressNextBlur = useRef2(false);
387
- const [validationError, setValidationError] = useState2(null);
388
- const [validationVariant, setValidationVariant] = useState2("error");
389
- const fieldProjection = useMemo2(() => {
390
- if (!model || !editing) {
391
- return;
392
- }
393
- const { col } = parseCellIndex2(editing.index);
394
- const field = model.projection.fields[col];
395
- const fieldProjection2 = model.projection.getFieldProjection(field.id);
396
- invariant2(fieldProjection2, void 0, {
397
- F: __dxlog_file2,
398
- L: 121,
399
- S: void 0,
400
- A: [
401
- "fieldProjection",
402
- ""
403
- ]
404
- });
405
- return fieldProjection2;
406
- }, [
407
- model,
408
- editing
409
- ]);
410
- const handleEnter = useCallback2(async (value) => {
411
- if (!model || !editing) {
412
- return;
413
- }
414
- const cell = parseCellIndex2(editing.index);
415
- const validationResult = await model.validateCellData(cell, value);
416
- if (validationResult.valid) {
417
- setValidationError(null);
418
- model.setCellData(cell, value);
419
- onFocus?.();
420
- setEditing(null);
421
- onSave?.();
422
- } else {
423
- setValidationError(adaptValidationMessage(validationResult.error));
424
- setValidationVariant("error");
425
- }
426
- }, [
427
- model,
428
- editing,
429
- onFocus,
430
- setEditing
431
- ]);
432
- const handleBlur = useCallback2(async (value) => {
433
- if (suppressNextBlur.current) {
434
- suppressNextBlur.current = false;
435
- } else if (model && editing) {
436
- const cell = parseCellIndex2(editing.index);
437
- if (value !== void 0) {
438
- const result = await model.validateCellData(cell, value);
439
- if (result.valid) {
440
- setValidationError(null);
441
- model.setCellData(cell, value);
442
- setEditing(null);
443
- onSave?.();
444
- }
445
- }
446
- }
447
- }, [
448
- model,
449
- editing
450
- ]);
451
- const handleClose = useCallback2(async (value, event) => {
452
- if (!model || !editing || !fieldProjection) {
453
- return;
454
- }
501
+ var TableCellEditor = ({ __gridScope, model, modals, onFocus, onSave }) => {
502
+ const { editing, setEditing } = useGridContext3("TableCellEditor", __gridScope);
503
+ const suppressNextBlur = useRef2(false);
504
+ const [validationError, setValidationError] = useState2(null);
505
+ const [validationVariant, setValidationVariant] = useState2("error");
506
+ const fieldProjection = useMemo2(() => {
507
+ if (!model || !editing) {
508
+ return;
509
+ }
510
+ const { col } = parseCellIndex2(editing.index);
511
+ const field = model.projection.getFields()[col];
512
+ const fieldProjection2 = model.projection.getFieldProjection(field.id);
513
+ invariant2(fieldProjection2, void 0, {
514
+ F: __dxlog_file2,
515
+ L: 120,
516
+ S: void 0,
517
+ A: [
518
+ "fieldProjection",
519
+ ""
520
+ ]
521
+ });
522
+ return fieldProjection2;
523
+ }, [
524
+ model,
525
+ editing
526
+ ]);
527
+ const handleEnter = useCallback2(async (value) => {
528
+ if (!model || !editing) {
529
+ return;
530
+ }
531
+ const cell = parseCellIndex2(editing.index);
532
+ const validationResult = await model.validateCellData(cell, value);
533
+ if (validationResult.valid) {
534
+ setValidationError(null);
535
+ model.setCellData(cell, value);
536
+ onFocus?.();
537
+ setEditing(null);
538
+ onSave?.();
539
+ } else {
540
+ setValidationError(validationResult.error);
541
+ setValidationVariant("error");
542
+ }
543
+ }, [
544
+ model,
545
+ editing,
546
+ onFocus,
547
+ setEditing
548
+ ]);
549
+ const handleBlur = useCallback2(async (value) => {
550
+ if (suppressNextBlur.current) {
551
+ suppressNextBlur.current = false;
552
+ } else if (model && editing) {
455
553
  const cell = parseCellIndex2(editing.index);
456
554
  if (value !== void 0) {
457
555
  const result = await model.validateCellData(cell, value);
458
556
  if (result.valid) {
459
- suppressNextBlur.current = true;
460
557
  setValidationError(null);
461
558
  model.setCellData(cell, value);
462
559
  setEditing(null);
463
560
  onSave?.();
464
- if (event && onFocus) {
465
- onFocus(determineNavigationAxis(event), determineNavigationDelta(event), cell);
466
- }
467
- } else {
468
- setValidationError(result.error);
469
- setValidationVariant("error");
470
561
  }
471
- } else {
562
+ }
563
+ }
564
+ }, [
565
+ model,
566
+ editing
567
+ ]);
568
+ const handleClose = useCallback2(async (value, event) => {
569
+ if (!model || !editing || !fieldProjection) {
570
+ return;
571
+ }
572
+ const cell = parseCellIndex2(editing.index);
573
+ if (value !== void 0) {
574
+ const result = await model.validateCellData(cell, value);
575
+ if (result.valid) {
472
576
  suppressNextBlur.current = true;
473
577
  setValidationError(null);
578
+ model.setCellData(cell, value);
474
579
  setEditing(null);
475
580
  onSave?.();
476
581
  if (event && onFocus) {
477
- onFocus(determineNavigationAxis(event), determineNavigationDelta(event));
582
+ onFocus(determineNavigationAxis(event), determineNavigationDelta(event), cell);
478
583
  }
584
+ } else {
585
+ setValidationError(result.error);
586
+ setValidationVariant("error");
479
587
  }
480
- }, [
481
- model,
482
- editing,
483
- onFocus,
484
- fieldProjection,
485
- setEditing,
486
- onSave
487
- ]);
488
- const extensions = useMemo2(() => {
489
- if (!fieldProjection) {
490
- return [];
491
- }
492
- const extensions2 = [
493
- editorKeys({
494
- onClose: handleClose,
495
- ...editing?.initialContent && {
496
- onNav: handleClose
497
- }
498
- })
499
- ];
500
- if (model && editing) {
501
- extensions2.push(EditorView.updateListener.of(debounce((update) => {
502
- const content = update.state.doc.toString();
503
- const cell = parseCellIndex2(editing.index);
504
- void model.validateCellData(cell, content).then((result) => {
505
- if (result.valid) {
506
- setValidationError(null);
507
- } else {
508
- setValidationError(result.error);
509
- setValidationVariant("error");
510
- }
511
- });
512
- }, 10)));
588
+ } else {
589
+ suppressNextBlur.current = true;
590
+ setValidationError(null);
591
+ setEditing(null);
592
+ onSave?.();
593
+ if (event && onFocus) {
594
+ onFocus(determineNavigationAxis(event), determineNavigationDelta(event));
513
595
  }
514
- return extensions2;
515
- }, [
516
- model,
517
- modals,
518
- editing,
519
- fieldProjection,
520
- handleClose
521
- ]);
522
- const getCellContent = useCallback2(() => {
523
- if (model && editing) {
596
+ }
597
+ }, [
598
+ model,
599
+ editing,
600
+ onFocus,
601
+ fieldProjection,
602
+ setEditing,
603
+ onSave
604
+ ]);
605
+ const extensions = useMemo2(() => {
606
+ if (!fieldProjection) {
607
+ return [];
608
+ }
609
+ const extensions2 = [
610
+ editorKeys({
611
+ onClose: handleClose,
612
+ ...editing?.initialContent && {
613
+ onNav: handleClose
614
+ }
615
+ })
616
+ ];
617
+ if (model && editing) {
618
+ extensions2.push(EditorView.updateListener.of(debounce((update) => {
619
+ const content = update.state.doc.toString();
524
620
  const cell = parseCellIndex2(editing.index);
525
- const value = model.getCellData(cell);
526
- return value !== void 0 ? String(value) : "";
527
- }
528
- }, [
529
- model,
530
- editing
531
- ]);
532
- return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(CellValidationMessage, {
533
- validationError,
534
- variant: validationVariant,
535
- __gridScope
536
- }), /* @__PURE__ */ React3.createElement(GridCellEditor, {
537
- extensions,
538
- getCellContent,
539
- onBlur: handleBlur,
540
- slots: editorSlots
541
- }));
542
- } finally {
543
- _effect.f();
544
- }
621
+ void model.validateCellData(cell, content).then((result) => {
622
+ if (result.valid) {
623
+ setValidationError(null);
624
+ } else {
625
+ setValidationError(result.error);
626
+ setValidationVariant("error");
627
+ }
628
+ });
629
+ }, 10)));
630
+ }
631
+ return extensions2;
632
+ }, [
633
+ model,
634
+ modals,
635
+ editing,
636
+ fieldProjection,
637
+ handleClose
638
+ ]);
639
+ const getCellContent = useCallback2(() => {
640
+ if (model && editing) {
641
+ const cell = parseCellIndex2(editing.index);
642
+ const value = model.getCellData(cell);
643
+ return value !== void 0 ? String(value) : "";
644
+ }
645
+ }, [
646
+ model,
647
+ editing
648
+ ]);
649
+ return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(CellValidationMessage, {
650
+ validationError,
651
+ variant: validationVariant,
652
+ __gridScope
653
+ }), /* @__PURE__ */ React3.createElement(GridCellEditor, {
654
+ extensions,
655
+ getCellContent,
656
+ onBlur: handleBlur,
657
+ slots: editorSlots
658
+ }));
545
659
  };
546
660
  var determineNavigationAxis = ({ key }) => {
547
661
  switch (key) {
@@ -569,154 +683,140 @@ var determineNavigationDelta = ({ key, shift }) => {
569
683
  };
570
684
 
571
685
  // src/components/Table/ColumnActionsMenu.tsx
572
- import { useSignals as _useSignals4 } from "@preact-signals/safe-react/tracking";
686
+ import { useAtomValue } from "@effect-atom/atom-react";
573
687
  import React4 from "react";
574
688
  import { DropdownMenu, useTranslation } from "@dxos/react-ui";
575
689
  var ColumnActionsMenu = ({ model, modals }) => {
576
- var _effect = _useSignals4();
577
- try {
578
- const { t } = useTranslation(translationKey);
579
- const state = modals.state.value;
580
- if (state?.type !== "column") {
581
- return null;
582
- }
583
- const currentSort = model.sorting?.sorting;
584
- const isCurrentColumnSorted = currentSort?.fieldId === state.fieldId;
585
- return /* @__PURE__ */ React4.createElement(DropdownMenu.Root, {
586
- modal: false,
587
- open: true,
588
- onOpenChange: modals.close
589
- }, /* @__PURE__ */ React4.createElement(DropdownMenu.VirtualTrigger, {
590
- virtualRef: modals.trigger
591
- }), /* @__PURE__ */ React4.createElement(DropdownMenu.Portal, null, /* @__PURE__ */ React4.createElement(DropdownMenu.Content, null, /* @__PURE__ */ React4.createElement(DropdownMenu.Viewport, null, (!isCurrentColumnSorted || currentSort?.direction === "asc") && /* @__PURE__ */ React4.createElement(DropdownMenu.Item, {
592
- "data-testid": "column-sort-descending",
593
- onClick: () => model.sorting?.setSort(state.fieldId, "desc")
594
- }, t("column action sort descending")), (!isCurrentColumnSorted || currentSort?.direction === "desc") && /* @__PURE__ */ React4.createElement(DropdownMenu.Item, {
595
- "data-testid": "column-sort-ascending",
596
- onClick: () => model.sorting?.setSort(state.fieldId, "asc")
597
- }, t("column action sort ascending")), isCurrentColumnSorted && /* @__PURE__ */ React4.createElement(DropdownMenu.Item, {
598
- "data-testid": "column-clear-sort",
599
- onClick: () => model.sorting?.clearSort()
600
- }, t("column action clear sorting")), model.getColumnCount() > 1 && model.features.schemaEditable && /* @__PURE__ */ React4.createElement(DropdownMenu.Item, {
601
- "data-testid": "column-delete",
602
- onClick: () => model.deleteColumn(state.fieldId)
603
- }, t("column action delete")), model.features.schemaEditable && /* @__PURE__ */ React4.createElement(DropdownMenu.Item, {
604
- "data-testid": "column-settings",
605
- onClick: () => modals.openColumnSettings()
606
- }, t("column action settings"))), /* @__PURE__ */ React4.createElement(DropdownMenu.Arrow, null))));
607
- } finally {
608
- _effect.f();
690
+ const { t } = useTranslation(translationKey);
691
+ const state = useAtomValue(modals.state);
692
+ if (state?.type !== "column") {
693
+ return null;
609
694
  }
695
+ const currentSort = model.getSorting();
696
+ const isCurrentColumnSorted = currentSort?.fieldId === state.fieldId;
697
+ return /* @__PURE__ */ React4.createElement(DropdownMenu.Root, {
698
+ modal: false,
699
+ open: true,
700
+ onOpenChange: modals.close
701
+ }, /* @__PURE__ */ React4.createElement(DropdownMenu.VirtualTrigger, {
702
+ virtualRef: modals.trigger
703
+ }), /* @__PURE__ */ React4.createElement(DropdownMenu.Portal, null, /* @__PURE__ */ React4.createElement(DropdownMenu.Content, null, /* @__PURE__ */ React4.createElement(DropdownMenu.Viewport, null, (!isCurrentColumnSorted || currentSort?.direction === "asc") && /* @__PURE__ */ React4.createElement(DropdownMenu.Item, {
704
+ "data-testid": "column-sort-descending",
705
+ onClick: () => model.setSort(state.fieldId, "desc")
706
+ }, t("column action sort descending")), (!isCurrentColumnSorted || currentSort?.direction === "desc") && /* @__PURE__ */ React4.createElement(DropdownMenu.Item, {
707
+ "data-testid": "column-sort-ascending",
708
+ onClick: () => model.setSort(state.fieldId, "asc")
709
+ }, t("column action sort ascending")), isCurrentColumnSorted && /* @__PURE__ */ React4.createElement(DropdownMenu.Item, {
710
+ "data-testid": "column-clear-sort",
711
+ onClick: () => model.clearSort()
712
+ }, t("column action clear sorting")), model.getColumnCount() > 1 && model.features.schemaEditable && /* @__PURE__ */ React4.createElement(DropdownMenu.Item, {
713
+ "data-testid": "column-delete",
714
+ onClick: () => model.deleteColumn(state.fieldId)
715
+ }, t("column action delete")), model.features.schemaEditable && /* @__PURE__ */ React4.createElement(DropdownMenu.Item, {
716
+ "data-testid": "column-settings",
717
+ onClick: () => modals.openColumnSettings()
718
+ }, t("column action settings"))), /* @__PURE__ */ React4.createElement(DropdownMenu.Arrow, null))));
610
719
  };
611
720
 
612
721
  // src/components/Table/ColumnSettings.tsx
613
- import { useSignals as _useSignals5 } from "@preact-signals/safe-react/tracking";
722
+ import { useAtomValue as useAtomValue2 } from "@effect-atom/atom-react";
614
723
  import React5, { useCallback as useCallback3, useEffect as useEffect2, useMemo as useMemo3, useState as useState3 } from "react";
615
724
  import { Popover as Popover2 } from "@dxos/react-ui";
616
725
  import { FieldEditor } from "@dxos/react-ui-form";
617
726
  var ColumnSettings = ({ registry, model, modals, onNewColumn }) => {
618
- var _effect = _useSignals5();
619
- try {
620
- const [newField, setNewField] = useState3();
621
- const state = modals.state.value;
622
- useEffect2(() => {
623
- if (state?.type === "columnSettings" && state.mode.type === "create" && model?.projection) {
624
- setNewField(model.projection.createFieldProjection());
625
- requestAnimationFrame(() => {
626
- onNewColumn();
627
- });
628
- } else {
629
- setNewField(void 0);
630
- }
631
- }, [
632
- model?.projection,
633
- state
634
- ]);
635
- const existingField = useMemo3(() => {
636
- if (state?.type === "columnSettings") {
637
- const { mode } = state;
638
- if (mode.type === "edit") {
639
- return model?.projection?.fields.find((f) => f.id === mode.fieldId);
640
- }
641
- }
642
- return void 0;
643
- }, [
644
- model?.projection?.fields,
645
- state
646
- ]);
647
- const field = existingField ?? newField;
648
- const handleSave = useCallback3(() => {
649
- modals.close();
650
- }, [
651
- modals
652
- ]);
653
- const handleCancel = useCallback3(() => {
654
- if (state?.type === "columnSettings" && state.mode.type === "create" && newField) {
655
- model?.projection.deleteFieldProjection(newField.id);
727
+ const [newField, setNewField] = useState3();
728
+ const state = useAtomValue2(modals.state);
729
+ useEffect2(() => {
730
+ if (state?.type === "columnSettings" && state.mode.type === "create" && model?.projection) {
731
+ setNewField(model.projection.createFieldProjection());
732
+ requestAnimationFrame(() => {
733
+ onNewColumn();
734
+ });
735
+ } else {
736
+ setNewField(void 0);
737
+ }
738
+ }, [
739
+ model?.projection,
740
+ state
741
+ ]);
742
+ const existingField = useMemo3(() => {
743
+ if (state?.type === "columnSettings") {
744
+ const { mode } = state;
745
+ if (mode.type === "edit") {
746
+ return model?.projection?.getFields().find((f) => f.id === mode.fieldId);
656
747
  }
657
- }, [
658
- model?.projection,
659
- state,
660
- newField
661
- ]);
662
- if (!model?.projection || !field) {
663
- return null;
664
748
  }
665
- return /* @__PURE__ */ React5.createElement(Popover2.Root, {
666
- modal: false,
667
- open: state?.type === "columnSettings"
668
- }, /* @__PURE__ */ React5.createElement(Popover2.VirtualTrigger, {
669
- virtualRef: modals.trigger
670
- }), /* @__PURE__ */ React5.createElement(Popover2.Portal, null, /* @__PURE__ */ React5.createElement(Popover2.Content, {
671
- classNames: "md:is-64"
672
- }, /* @__PURE__ */ React5.createElement(Popover2.Viewport, null, /* @__PURE__ */ React5.createElement(FieldEditor, {
673
- projection: model.projection,
674
- field,
675
- registry,
676
- onSave: handleSave,
677
- onCancel: handleCancel
678
- })), /* @__PURE__ */ React5.createElement(Popover2.Arrow, null))));
679
- } finally {
680
- _effect.f();
749
+ return void 0;
750
+ }, [
751
+ model?.projection,
752
+ state
753
+ ]);
754
+ const field = existingField ?? newField;
755
+ const handleSave = useCallback3(() => {
756
+ modals.close();
757
+ }, [
758
+ modals
759
+ ]);
760
+ const handleCancel = useCallback3(() => {
761
+ if (state?.type === "columnSettings" && state.mode.type === "create" && newField) {
762
+ model?.projection.deleteFieldProjection(newField.id);
763
+ }
764
+ }, [
765
+ model?.projection,
766
+ state,
767
+ newField
768
+ ]);
769
+ if (!model?.projection || !field) {
770
+ return null;
681
771
  }
772
+ return /* @__PURE__ */ React5.createElement(Popover2.Root, {
773
+ modal: false,
774
+ open: state?.type === "columnSettings"
775
+ }, /* @__PURE__ */ React5.createElement(Popover2.VirtualTrigger, {
776
+ virtualRef: modals.trigger
777
+ }), /* @__PURE__ */ React5.createElement(Popover2.Portal, null, /* @__PURE__ */ React5.createElement(Popover2.Content, {
778
+ classNames: "md:is-64"
779
+ }, /* @__PURE__ */ React5.createElement(Popover2.Viewport, null, /* @__PURE__ */ React5.createElement(FieldEditor, {
780
+ projection: model.projection,
781
+ field,
782
+ registry,
783
+ onSave: handleSave,
784
+ onCancel: handleCancel
785
+ })), /* @__PURE__ */ React5.createElement(Popover2.Arrow, null))));
682
786
  };
683
787
 
684
788
  // src/components/Table/RowActionsMenu.tsx
685
- import { useSignals as _useSignals6 } from "@preact-signals/safe-react/tracking";
789
+ import { useAtomValue as useAtomValue3 } from "@effect-atom/atom-react";
686
790
  import React6 from "react";
687
791
  import { DropdownMenu as DropdownMenu2, toLocalizedString, useTranslation as useTranslation2 } from "@dxos/react-ui";
688
792
  var RowActionsMenu = ({ model, modals }) => {
689
- var _effect = _useSignals6();
690
- try {
691
- const { t } = useTranslation2(translationKey);
692
- const hasSelection = model.selection.hasSelection.value;
693
- const state = modals.state.value;
694
- if (state?.type !== "row") {
695
- return null;
696
- }
697
- return /* @__PURE__ */ React6.createElement(DropdownMenu2.Root, {
698
- modal: false,
699
- open: true,
700
- onOpenChange: modals.close
701
- }, /* @__PURE__ */ React6.createElement(DropdownMenu2.VirtualTrigger, {
702
- virtualRef: modals.trigger
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, {
704
- key: action.id,
705
- "data-testid": `row-action-${action.id}`,
706
- onClick: () => {
707
- modals.close();
708
- model.handleRowAction(action.id, state.rowIndex);
709
- }
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)));
714
- } finally {
715
- _effect.f();
793
+ const { t } = useTranslation2(translationKey);
794
+ const hasSelection = model.selection.hasSelection;
795
+ const state = useAtomValue3(modals.state);
796
+ if (state?.type !== "row") {
797
+ return null;
716
798
  }
799
+ return /* @__PURE__ */ React6.createElement(DropdownMenu2.Root, {
800
+ modal: false,
801
+ open: true,
802
+ onOpenChange: modals.close
803
+ }, /* @__PURE__ */ React6.createElement(DropdownMenu2.VirtualTrigger, {
804
+ virtualRef: modals.trigger
805
+ }), /* @__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, {
806
+ key: action.id,
807
+ "data-testid": `row-action-${action.id}`,
808
+ onClick: () => {
809
+ modals.close();
810
+ model.handleRowAction(action.id, state.rowIndex);
811
+ }
812
+ }, toLocalizedString(action.label, t)))), /* @__PURE__ */ React6.createElement(DropdownMenu2.Separator, null)), model.features.dataEditable !== false && /* @__PURE__ */ React6.createElement(DropdownMenu2.Item, {
813
+ "data-testid": "row-menu-delete",
814
+ onClick: () => model.deleteRow(state.rowIndex)
815
+ }, t(hasSelection ? "bulk delete row label" : "delete row label"))), /* @__PURE__ */ React6.createElement(DropdownMenu2.Arrow, null)));
717
816
  };
718
817
 
719
818
  // src/components/Table/Table.tsx
819
+ var __dxlog_file3 = "/__w/dxos/dxos/packages/ui/react-ui-table/src/components/Table/Table.tsx";
720
820
  var columnDefault = {
721
821
  grid: {
722
822
  minSize: 80,
@@ -729,454 +829,470 @@ var rowDefault = {
729
829
  focusUnfurl: false
730
830
  }
731
831
  };
832
+ var emptyColumnMeta = Atom2.make({
833
+ grid: {}
834
+ });
732
835
  var TableRoot = ({ children, role = "article" }) => {
733
- var _effect = _useSignals7();
734
- try {
735
- return /* @__PURE__ */ React7.createElement("div", {
736
- role: "none",
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]", [
738
- "card--popover",
739
- "section",
740
- "card--extrinsic"
741
- ].includes(role) && "overflow-hidden", [
742
- "article",
743
- "slide"
744
- ].includes(role) && "flex flex-col [&_.dx-grid]:grow [&_.dx-grid]:bs-0")
745
- }, children);
746
- } finally {
747
- _effect.f();
748
- }
836
+ return /* @__PURE__ */ React7.createElement("div", {
837
+ role: "none",
838
+ 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]", [
839
+ "card--popover",
840
+ "section",
841
+ "card--extrinsic"
842
+ ].includes(role) && "overflow-hidden", [
843
+ "article",
844
+ "slide"
845
+ ].includes(role) && "flex flex-col [&_.dx-grid]:grow [&_.dx-grid]:bs-0")
846
+ }, children);
749
847
  };
750
- var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttention, schema, client, onCreate, onRowClick, testId }, forwardedRef) => {
751
- var _effect = _useSignals7();
752
- try {
753
- const [dxGrid, setDxGrid] = useState4(null);
754
- const { hasAttention } = useAttention(model?.id ?? "table");
755
- const modals = useMemo4(() => new ModalController(), []);
756
- const draftRowCount = model?.getDraftRowCount() ?? 0;
757
- const handleSave = useCallback4(() => {
758
- dxGrid?.updateCells(true);
759
- dxGrid?.requestUpdate();
760
- }, [
761
- dxGrid
762
- ]);
763
- const frozen = useMemo4(() => {
764
- const noActionColumn = model?.features.dataEditable === false && model?.features.schemaEditable === false && model.rowActions.length === 0;
765
- return {
766
- frozenRowsStart: 1,
767
- frozenRowsEnd: Math.max(1, draftRowCount),
768
- frozenColsStart: model?.features.selection.enabled ? 1 : 0,
769
- frozenColsEnd: noActionColumn ? 0 : 1
770
- };
771
- }, [
772
- model,
773
- draftRowCount
774
- ]);
775
- const getCells = useCallback4((range, plane) => presentation?.getCells(range, plane) ?? {}, [
776
- presentation
777
- ]);
778
- useEffect3(() => {
779
- if (!presentation || !dxGrid) {
780
- return;
781
- }
782
- dxGrid.getCells = getCells;
783
- }, [
784
- presentation,
785
- dxGrid,
786
- getCells
787
- ]);
788
- const handleInsertRowResult = useCallback4((insertResult) => {
789
- if (insertResult === "draft") {
790
- requestAnimationFrame(() => {
791
- dxGrid?.setFocus({
792
- plane: "frozenRowsEnd",
793
- col: 0,
794
- row: 0
795
- });
796
- dxGrid?.refocus();
848
+ var emptyRowsAtom = Atom2.make([]);
849
+ var emptyCellUpdateAtom = Atom2.make(0);
850
+ var TableMainInner = ({ schema, model, presentation, ignoreAttention, onCreate, onRowClick, testId }, forwardedRef) => {
851
+ const registry = useContext(RegistryContext);
852
+ const [dxGrid, setDxGrid] = useState4(null);
853
+ const { hasAttention } = useAttention(model?.id ?? "table");
854
+ const modals = useMemo4(() => new ModalController(registry), [
855
+ registry
856
+ ]);
857
+ const columnMeta = useAtomValue4(model?.columnMeta ?? emptyColumnMeta);
858
+ const rows = useAtomValue4(model?.rows ?? emptyRowsAtom);
859
+ const cellUpdateCounter = useAtomValue4(model?.cellUpdate ?? emptyCellUpdateAtom);
860
+ const columnCount = Object.keys(columnMeta.grid).length || model?.projection.getFields().length || 0;
861
+ const draftRowCount = model?.getDraftRowCount() ?? 0;
862
+ const frozen = useMemo4(() => {
863
+ const noActionColumn = model?.features.dataEditable === false && model?.features.schemaEditable === false && model.rowActions.length === 0;
864
+ return {
865
+ frozenRowsStart: 1,
866
+ frozenRowsEnd: Math.max(1, draftRowCount),
867
+ frozenColsStart: model?.features.selection.enabled ? 1 : 0,
868
+ frozenColsEnd: noActionColumn ? 0 : 1
869
+ };
870
+ }, [
871
+ model,
872
+ draftRowCount
873
+ ]);
874
+ const getCells = useCallback4((range, plane) => presentation?.getCells(range, plane) ?? {}, [
875
+ presentation
876
+ ]);
877
+ useEffect3(() => {
878
+ if (!dxGrid || !presentation) {
879
+ return;
880
+ }
881
+ dxGrid.getCells = getCells;
882
+ }, [
883
+ dxGrid,
884
+ presentation,
885
+ getCells
886
+ ]);
887
+ useEffect3(() => {
888
+ if (!dxGrid) {
889
+ return;
890
+ }
891
+ dxGrid.updateCells(true);
892
+ dxGrid.requestUpdate();
893
+ }, [
894
+ dxGrid,
895
+ rows,
896
+ cellUpdateCounter
897
+ ]);
898
+ const handleInsertRowResult = useCallback4((insertResult) => {
899
+ if (insertResult === "draft") {
900
+ requestAnimationFrame(() => {
901
+ dxGrid?.setFocus({
902
+ plane: "frozenRowsEnd",
903
+ col: 0,
904
+ row: 0
797
905
  });
798
- } else {
906
+ dxGrid?.refocus();
907
+ });
908
+ } else {
909
+ requestAnimationFrame(() => {
910
+ dxGrid?.setFocus({
911
+ plane: "grid",
912
+ col: 0,
913
+ row: model ? model.getRowCount() - 1 : 0
914
+ });
915
+ dxGrid?.refocus();
916
+ });
917
+ }
918
+ }, [
919
+ model,
920
+ dxGrid
921
+ ]);
922
+ const handleSave = useCallback4(() => {
923
+ dxGrid?.updateCells(true);
924
+ dxGrid?.requestUpdate();
925
+ }, [
926
+ dxGrid
927
+ ]);
928
+ const handleSaveDraftRow = useCallback4((rowIndex = 0) => {
929
+ if (model && dxGrid) {
930
+ const didCommitSuccessfully = model.commitDraftRow(rowIndex);
931
+ if (didCommitSuccessfully) {
799
932
  requestAnimationFrame(() => {
800
- dxGrid?.setFocus({
801
- plane: "grid",
802
- col: 0,
803
- row: model ? model.getRowCount() - 1 : 0
804
- });
805
- dxGrid?.refocus();
933
+ dxGrid.scrollToEndRow();
806
934
  });
807
935
  }
808
- }, [
809
- model,
810
- dxGrid
811
- ]);
812
- useImperativeHandle(forwardedRef, () => {
813
- if (!presentation || !dxGrid) {
814
- return {};
815
- }
816
- return {
817
- update: (cell) => {
818
- if (cell) {
819
- dxGrid.updateIfWithinBounds(cell, true);
820
- } else {
821
- dxGrid.updateCells(true);
822
- dxGrid.requestUpdate();
823
- }
824
- },
825
- handleInsertRowResult
826
- };
827
- }, [
828
- presentation,
829
- dxGrid,
830
- model
831
- ]);
832
- const handleSaveDraftRow = useCallback4((rowIndex = 0) => {
833
- if (model && dxGrid) {
834
- const didCommitSuccessfully = model.commitDraftRow(rowIndex);
835
- if (didCommitSuccessfully) {
836
- requestAnimationFrame(() => {
837
- dxGrid.scrollToEndRow();
838
- });
936
+ }
937
+ }, [
938
+ model,
939
+ dxGrid
940
+ ]);
941
+ const handleGridClick = useCallback4((event) => {
942
+ const cell = closestCell(event.target);
943
+ if (cell) {
944
+ const { row: rowIndex, plane } = cell;
945
+ if (onRowClick) {
946
+ if (plane === "grid") {
947
+ const row = model?.getRowAt(rowIndex);
948
+ row && onRowClick(row);
949
+ } else {
950
+ onRowClick(cell);
839
951
  }
840
952
  }
841
- }, [
842
- model,
843
- dxGrid
844
- ]);
845
- const handleGridClick = useCallback4((event) => {
846
- const cell = closestCell(event.target);
847
- if (cell) {
848
- const { row: rowIndex, plane } = cell;
849
- if (onRowClick) {
850
- if (plane === "grid") {
851
- const row = model?.getRowAt(rowIndex);
852
- row && onRowClick(row);
853
- } else {
854
- onRowClick(cell);
855
- }
856
- }
857
- if (model?.features.selection.enabled && model?.selection.selectionMode === "single") {
858
- model.selection.toggleSelectionForRowIndex(rowIndex);
859
- }
953
+ if (model?.features.selection.enabled && model?.selection.selectionMode === "single") {
954
+ model.selection.toggleSelectionForRowIndex(rowIndex);
860
955
  }
861
- if (!modals) {
956
+ }
957
+ if (!modals) {
958
+ return;
959
+ }
960
+ const buttonSelector = Object.values(tableButtons).map((button) => `button[${button.attr}]`).join(",");
961
+ const tableButtonElement = event.target.closest(buttonSelector);
962
+ if (tableButtonElement) {
963
+ const button = Object.values(tableButtons).find((btn) => tableButtonElement.hasAttribute(btn.attr));
964
+ if (!button) {
862
965
  return;
863
966
  }
864
- const buttonSelector = Object.values(tableButtons).map((button) => `button[${button.attr}]`).join(",");
865
- const tableButtonElement = event.target.closest(buttonSelector);
866
- if (tableButtonElement) {
867
- const button = Object.values(tableButtons).find((btn) => tableButtonElement.hasAttribute(btn.attr));
868
- if (!button) {
869
- return;
967
+ modals.setTrigger(tableButtonElement);
968
+ const data = button.getData(tableButtonElement);
969
+ switch (data.type) {
970
+ case "rowMenu": {
971
+ modals.showRowMenu(data.rowIndex);
972
+ break;
870
973
  }
871
- modals.setTrigger(tableButtonElement);
872
- const data = button.getData(tableButtonElement);
873
- switch (data.type) {
874
- case "rowMenu": {
875
- modals.showRowMenu(data.rowIndex);
876
- break;
877
- }
878
- case "columnSettings": {
879
- modals.showColumnMenu(data.fieldId);
880
- break;
881
- }
882
- case "newColumn": {
883
- modals.showColumnCreator();
884
- break;
885
- }
886
- case "sort": {
887
- model?.sorting?.toggleSort(data.fieldId);
888
- break;
889
- }
890
- case "saveDraftRow": {
891
- handleSaveDraftRow();
892
- break;
893
- }
974
+ case "columnSettings": {
975
+ modals.showColumnMenu(data.fieldId);
976
+ break;
894
977
  }
895
- return;
896
- }
897
- const controlSelector = Object.values(tableControls).map((control) => `input[${control.attr}]`).join(",");
898
- const controlElement = event.target.closest(controlSelector);
899
- if (controlElement) {
900
- const control = Object.values(tableControls).find((ctrl) => controlElement.hasAttribute(ctrl.attr));
901
- if (!control) {
902
- return;
978
+ case "newColumn": {
979
+ modals.showColumnCreator();
980
+ break;
903
981
  }
904
- const data = control.getData(controlElement);
905
- switch (data.type) {
906
- case "checkbox": {
907
- if (data.header) {
908
- model?.selection.setSelection(model.selection.allRowsSeleted.value ? "none" : "all");
909
- } else {
910
- model?.selection.toggleSelectionForRowIndex(data.rowIndex);
911
- }
912
- break;
913
- }
914
- case "switch": {
915
- if (model) {
916
- model.updateCellData({
917
- row: data.rowIndex,
918
- col: data.colIndex
919
- }, (value) => !value);
920
- }
921
- break;
922
- }
982
+ case "sort": {
983
+ model?.toggleSort(data.fieldId);
984
+ break;
923
985
  }
924
- }
925
- }, [
926
- model,
927
- modals,
928
- dxGrid
929
- ]);
930
- const handleFocus = useCallback4((increment, delta, cell) => {
931
- if (dxGrid && model) {
932
- if (cell?.plane === "grid" && cell?.row >= model.getRowCount() - 1 && increment !== "col") {
933
- handleInsertRowResult(draftRowCount < 1 ? model.insertRow() : "final");
934
- } else if (cell?.plane === "frozenRowsEnd" && increment === "row") {
935
- handleSaveDraftRow(cell.row);
936
- handleInsertRowResult(model.insertRow());
937
- } else {
938
- dxGrid.refocus(increment, delta);
986
+ case "saveDraftRow": {
987
+ handleSaveDraftRow();
988
+ break;
939
989
  }
940
990
  }
941
- }, [
942
- dxGrid,
943
- model
944
- ]);
945
- const handleKeyDown = useCallback4((event) => {
946
- if (!model?.features.dataEditable) {
947
- return;
948
- }
949
- const cell = closestCell(event.target);
950
- if (!model || !cell) {
991
+ return;
992
+ }
993
+ const controlSelector = Object.values(tableControls).map((control) => `input[${control.attr}]`).join(",");
994
+ const controlElement = event.target.closest(controlSelector);
995
+ if (controlElement) {
996
+ const control = Object.values(tableControls).find((ctrl) => controlElement.hasAttribute(ctrl.attr));
997
+ if (!control) {
951
998
  return;
952
999
  }
953
- if (event.metaKey || event.ctrlKey) {
954
- switch (event.key) {
955
- case "c": {
956
- try {
957
- const cellData = model.getCellData(cell);
958
- const textContent = cellData?.toString() ?? "";
959
- void navigator.clipboard.writeText(textContent);
960
- event.preventDefault();
961
- } catch (error) {
962
- console.warn("Failed to copy cell content:", error);
963
- }
964
- break;
1000
+ const data = control.getData(controlElement);
1001
+ switch (data.type) {
1002
+ case "checkbox": {
1003
+ if (data.header) {
1004
+ model?.selection.setSelection(model.selection.allRowsSelected ? "none" : "all");
1005
+ } else {
1006
+ model?.selection.toggleSelectionForRowIndex(data.rowIndex);
965
1007
  }
966
- case "v": {
967
- event.preventDefault();
968
- void navigator.clipboard.readText().then((clipboardText) => {
969
- try {
970
- model.setCellData(cell, String2.trim(clipboardText).replace(/[\n\r]+/, " "));
971
- handleSave();
972
- } catch {
973
- const cellElement = event.target.closest('[data-dx-grid-action="cell"]');
974
- if (cellElement) {
975
- const rect = cellElement.getBoundingClientRect();
976
- const editRequest = new DxEditRequest({
977
- cellIndex: `${cell.plane},${cell.col},${cell.row}`,
978
- cellBox: {
979
- insetInlineStart: rect.left,
980
- insetBlockStart: rect.top,
981
- inlineSize: rect.width,
982
- blockSize: rect.height
983
- },
984
- cellElement,
985
- initialContent: clipboardText
986
- });
987
- cellElement.dispatchEvent(editRequest);
988
- }
989
- }
990
- });
991
- break;
1008
+ break;
1009
+ }
1010
+ case "switch": {
1011
+ if (model) {
1012
+ model.updateCellData({
1013
+ row: data.rowIndex,
1014
+ col: data.colIndex
1015
+ }, (value) => !value);
992
1016
  }
1017
+ break;
993
1018
  }
994
1019
  }
1020
+ }
1021
+ }, [
1022
+ model,
1023
+ modals,
1024
+ dxGrid
1025
+ ]);
1026
+ const handleFocus = useCallback4((increment, delta, cell) => {
1027
+ if (dxGrid && model) {
1028
+ if (cell?.plane === "grid" && cell?.row >= model.getRowCount() - 1 && increment !== "col") {
1029
+ handleInsertRowResult(draftRowCount < 1 ? model.insertRow() : "final");
1030
+ } else if (cell?.plane === "frozenRowsEnd" && increment === "row") {
1031
+ handleSaveDraftRow(cell.row);
1032
+ handleInsertRowResult(model.insertRow());
1033
+ } else {
1034
+ dxGrid.refocus(increment, delta);
1035
+ }
1036
+ }
1037
+ }, [
1038
+ dxGrid,
1039
+ model
1040
+ ]);
1041
+ const handleKeyDown = useCallback4((event) => {
1042
+ if (!model?.features.dataEditable) {
1043
+ return;
1044
+ }
1045
+ const cell = closestCell(event.target);
1046
+ if (!model || !cell) {
1047
+ return;
1048
+ }
1049
+ if (event.metaKey || event.ctrlKey) {
995
1050
  switch (event.key) {
996
- case "Backspace":
997
- case "Delete": {
1051
+ case "c": {
998
1052
  try {
999
- model.setCellData(cell, void 0);
1053
+ const cellData = model.getCellData(cell);
1054
+ const textContent = cellData?.toString() ?? "";
1055
+ void navigator.clipboard.writeText(textContent);
1000
1056
  event.preventDefault();
1001
- handleSave();
1002
- } catch {
1057
+ } catch (error) {
1058
+ log.catch(error, void 0, {
1059
+ F: __dxlog_file3,
1060
+ L: 322,
1061
+ S: void 0,
1062
+ C: (f, a) => f(...a)
1063
+ });
1003
1064
  }
1004
1065
  break;
1005
1066
  }
1067
+ case "v": {
1068
+ event.preventDefault();
1069
+ void navigator.clipboard.readText().then((clipboardText) => {
1070
+ try {
1071
+ model.setCellData(cell, String2.trim(clipboardText).replace(/[\n\r]+/, " "));
1072
+ handleSave();
1073
+ } catch {
1074
+ const cellElement = event.target.closest('[data-dx-grid-action="cell"]');
1075
+ if (cellElement) {
1076
+ const rect = cellElement.getBoundingClientRect();
1077
+ const editRequest = new DxEditRequest({
1078
+ cellIndex: `${cell.plane},${cell.col},${cell.row}`,
1079
+ cellBox: {
1080
+ insetInlineStart: rect.left,
1081
+ insetBlockStart: rect.top,
1082
+ inlineSize: rect.width,
1083
+ blockSize: rect.height
1084
+ },
1085
+ cellElement,
1086
+ initialContent: clipboardText
1087
+ });
1088
+ cellElement.dispatchEvent(editRequest);
1089
+ }
1090
+ }
1091
+ });
1092
+ break;
1093
+ }
1006
1094
  }
1007
- }, [
1008
- model,
1009
- dxGrid,
1010
- handleSave
1011
- ]);
1012
- const handleAxisResize = useCallback4((event) => {
1013
- if (event.axis === "col") {
1014
- const columnIndex = parseInt(event.index, 10);
1015
- model?.setColumnWidth(columnIndex, event.size);
1016
- }
1017
- }, [
1018
- model
1019
- ]);
1020
- const handleWheel = useCallback4((event) => {
1021
- if (!ignoreAttention && !hasAttention) {
1022
- event.stopPropagation();
1023
- }
1024
- }, [
1025
- hasAttention,
1026
- ignoreAttention
1027
- ]);
1028
- const handleNewColumn = useCallback4(() => {
1029
- const columns = model?.getColumnCount();
1030
- if (dxGrid && columns) {
1031
- dxGrid.scrollToColumn(columns - 1);
1095
+ }
1096
+ switch (event.key) {
1097
+ case "Backspace":
1098
+ case "Delete": {
1099
+ try {
1100
+ model.setCellData(cell, void 0);
1101
+ event.preventDefault();
1102
+ handleSave();
1103
+ } catch {
1104
+ }
1105
+ break;
1032
1106
  }
1033
- }, [
1034
- model,
1035
- dxGrid
1036
- ]);
1037
- if (!model || !modals) {
1038
- return /* @__PURE__ */ React7.createElement("span", {
1039
- role: "none",
1040
- className: "attention-surface"
1041
- });
1042
1107
  }
1043
- return /* @__PURE__ */ React7.createElement(Grid.Root, {
1044
- id: model.id ?? "table-grid"
1045
- }, /* @__PURE__ */ React7.createElement(TableValueEditor, {
1046
- model,
1047
- modals,
1048
- schema,
1049
- onFocus: handleFocus,
1050
- onSave: handleSave,
1051
- onCreate,
1052
- client
1053
- }), /* @__PURE__ */ React7.createElement(Grid.Content, {
1054
- className: mx("[--dx-grid-base:var(--baseSurface)]", gridSeparatorInlineEnd, gridSeparatorBlockEnd),
1055
- frozen,
1056
- columns: model.columnMeta.value,
1057
- columnDefault,
1058
- rowDefault,
1059
- limitRows: model.getRowCount() ?? 0,
1060
- limitColumns: model.projection.fields.length,
1061
- overscroll: "trap",
1062
- onAxisResize: handleAxisResize,
1063
- onClick: handleGridClick,
1064
- onKeyDownCapture: handleKeyDown,
1065
- onWheelCapture: handleWheel,
1066
- ...testId && {
1067
- "data-testid": testId
1108
+ }, [
1109
+ model,
1110
+ dxGrid,
1111
+ handleSave
1112
+ ]);
1113
+ const handleAxisResize = useCallback4((event) => {
1114
+ if (event.axis === "col") {
1115
+ const columnIndex = parseInt(event.index, 10);
1116
+ model?.setColumnWidth(columnIndex, event.size);
1117
+ }
1118
+ }, [
1119
+ model
1120
+ ]);
1121
+ const handleWheel = useCallback4((event) => {
1122
+ if (!ignoreAttention && !hasAttention) {
1123
+ event.stopPropagation();
1124
+ }
1125
+ }, [
1126
+ hasAttention,
1127
+ ignoreAttention
1128
+ ]);
1129
+ const handleNewColumn = useCallback4(() => {
1130
+ const columns = model?.getColumnCount();
1131
+ if (dxGrid && columns) {
1132
+ dxGrid.scrollToColumn(columns - 1);
1133
+ }
1134
+ }, [
1135
+ model,
1136
+ dxGrid
1137
+ ]);
1138
+ useImperativeHandle(forwardedRef, () => {
1139
+ if (!dxGrid || !presentation) {
1140
+ return {};
1141
+ }
1142
+ return {
1143
+ update: (cell) => {
1144
+ if (cell) {
1145
+ dxGrid.updateIfWithinBounds(cell, true);
1146
+ } else {
1147
+ dxGrid.updateCells(true);
1148
+ dxGrid.requestUpdate();
1149
+ }
1068
1150
  },
1069
- ref: setDxGrid
1070
- }), /* @__PURE__ */ React7.createElement(RowActionsMenu, {
1071
- model,
1072
- modals
1073
- }), /* @__PURE__ */ React7.createElement(ColumnActionsMenu, {
1074
- model,
1075
- modals
1076
- }), /* @__PURE__ */ React7.createElement(ColumnSettings, {
1077
- model,
1078
- modals,
1079
- onNewColumn: handleNewColumn
1080
- }));
1081
- } finally {
1082
- _effect.f();
1151
+ handleInsertRowResult
1152
+ };
1153
+ }, [
1154
+ dxGrid,
1155
+ model,
1156
+ presentation
1157
+ ]);
1158
+ if (!model || !modals) {
1159
+ return /* @__PURE__ */ React7.createElement("span", {
1160
+ role: "none",
1161
+ className: "attention-surface"
1162
+ });
1083
1163
  }
1084
- });
1164
+ return /* @__PURE__ */ React7.createElement(Grid.Root, {
1165
+ id: model.id ?? "table-grid"
1166
+ }, /* @__PURE__ */ React7.createElement(TableValueEditor, {
1167
+ model,
1168
+ modals,
1169
+ schema,
1170
+ onFocus: handleFocus,
1171
+ onSave: handleSave,
1172
+ onCreate
1173
+ }), /* @__PURE__ */ React7.createElement(Grid.Content, {
1174
+ className: mx("[--dx-grid-base:var(--baseSurface)]", gridSeparatorInlineEnd, gridSeparatorBlockEnd),
1175
+ frozen,
1176
+ columns: columnMeta,
1177
+ columnDefault,
1178
+ rowDefault,
1179
+ limitRows: rows.length,
1180
+ limitColumns: columnCount,
1181
+ overscroll: "trap",
1182
+ onAxisResize: handleAxisResize,
1183
+ onClick: handleGridClick,
1184
+ onKeyDownCapture: handleKeyDown,
1185
+ onWheelCapture: handleWheel,
1186
+ ...testId && {
1187
+ "data-testid": testId
1188
+ },
1189
+ ref: setDxGrid
1190
+ }), /* @__PURE__ */ React7.createElement(RowActionsMenu, {
1191
+ model,
1192
+ modals
1193
+ }), /* @__PURE__ */ React7.createElement(ColumnActionsMenu, {
1194
+ model,
1195
+ modals
1196
+ }), /* @__PURE__ */ React7.createElement(ColumnSettings, {
1197
+ model,
1198
+ modals,
1199
+ onNewColumn: handleNewColumn
1200
+ }));
1201
+ };
1202
+ var TableMain = /* @__PURE__ */ forwardRef(TableMainInner);
1085
1203
  var Table = {
1086
1204
  Root: TableRoot,
1087
1205
  Main: TableMain
1088
1206
  };
1089
1207
 
1090
1208
  // src/components/Table/DynamicTable.tsx
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";
1209
+ import { RegistryContext as RegistryContext2 } from "@effect-atom/atom-react";
1210
+ import React8, { useCallback as useCallback5, useContext as useContext2, useEffect as useEffect4, useMemo as useMemo5, useRef as useRef3, useState as useState5 } from "react";
1093
1211
  import { useDefaultValue } from "@dxos/react-ui";
1094
- import { mx as mx2 } from "@dxos/react-ui-theme";
1095
- var DynamicTable = ({ classNames, name = "example.com/dynamic-table", rows, properties, jsonSchema: _jsonSchema, schema, rowActions, onRowClick, onRowAction, ...props }) => {
1096
- var _effect = _useSignals8();
1097
- try {
1098
- const { jsonSchema } = useMemo5(() => getBaseSchema({
1099
- typename: name,
1100
- properties,
1101
- jsonSchema: _jsonSchema,
1102
- schema
1103
- }), [
1104
- name,
1105
- properties,
1106
- _jsonSchema,
1107
- schema
1108
- ]);
1109
- const { projection, view } = useMemo5(() => makeDynamicTable({
1110
- jsonSchema,
1111
- properties
1112
- }), [
1212
+ import { mx as mx2 } from "@dxos/ui-theme";
1213
+ var DynamicTable = ({ classNames, schema, name = "example.com/dynamic-table", rows, properties, jsonSchema: _jsonSchema, rowActions, onRowClick, onRowAction, ...props }) => {
1214
+ const registry = useContext2(RegistryContext2);
1215
+ const [dynamicTable, setDynamicTable] = useState5();
1216
+ const { jsonSchema } = useMemo5(() => getBaseSchema({
1217
+ typename: name,
1218
+ properties,
1219
+ jsonSchema: _jsonSchema,
1220
+ schema
1221
+ }), [
1222
+ name,
1223
+ properties,
1224
+ _jsonSchema,
1225
+ schema
1226
+ ]);
1227
+ useEffect4(() => {
1228
+ setDynamicTable(makeDynamicTable({
1229
+ registry,
1113
1230
  jsonSchema,
1114
1231
  properties
1115
- ]);
1116
- const tableRef = useRef3(null);
1117
- const handleCellUpdate = useCallback5((cell) => {
1118
- tableRef.current?.update?.(cell);
1119
- }, []);
1120
- const handleRowOrderChange = useCallback5(() => {
1121
- tableRef.current?.update?.();
1122
- }, []);
1123
- const features = useDefaultValue(props.features, () => ({
1124
- selection: {
1125
- enabled: false
1126
- },
1127
- dataEditable: false
1128
1232
  }));
1129
- const model = useTableModel({
1130
- rows,
1131
- view,
1132
- schema: jsonSchema,
1133
- projection,
1134
- features,
1135
- rowActions,
1136
- onCellUpdate: handleCellUpdate,
1137
- onRowOrderChange: handleRowOrderChange,
1138
- onRowAction
1139
- });
1140
- const presentation = useMemo5(() => {
1141
- if (model) {
1142
- return new TablePresentation(model);
1143
- }
1144
- }, [
1145
- model
1146
- ]);
1147
- return /* @__PURE__ */ React8.createElement("div", {
1148
- role: "none",
1149
- className: mx2("is-full bs-full grow grid", classNames)
1150
- }, /* @__PURE__ */ React8.createElement("div", {
1151
- role: "none",
1152
- className: "grid min-bs-0 overflow-hidden"
1153
- }, /* @__PURE__ */ React8.createElement(Table.Root, null, /* @__PURE__ */ React8.createElement(Table.Main, {
1154
- ref: tableRef,
1155
- model,
1156
- presentation,
1157
- ignoreAttention: true,
1158
- onRowClick
1159
- }))));
1160
- } finally {
1161
- _effect.f();
1162
- }
1233
+ }, [
1234
+ registry,
1235
+ jsonSchema,
1236
+ properties
1237
+ ]);
1238
+ const tableRef = useRef3(null);
1239
+ const handleCellUpdate = useCallback5((cell) => {
1240
+ tableRef.current?.update?.(cell);
1241
+ }, []);
1242
+ const handleRowOrderChange = useCallback5(() => {
1243
+ tableRef.current?.update?.();
1244
+ }, []);
1245
+ const features = useDefaultValue(props.features, () => ({
1246
+ selection: {
1247
+ enabled: false
1248
+ },
1249
+ dataEditable: false
1250
+ }));
1251
+ const model = useTableModel({
1252
+ rows,
1253
+ object: dynamicTable?.object,
1254
+ projection: dynamicTable?.projection,
1255
+ features,
1256
+ rowActions,
1257
+ onCellUpdate: handleCellUpdate,
1258
+ onRowOrderChange: handleRowOrderChange,
1259
+ onRowAction
1260
+ });
1261
+ const presentation = useMemo5(() => {
1262
+ if (model) {
1263
+ return new TablePresentation(registry, model);
1264
+ }
1265
+ }, [
1266
+ registry,
1267
+ model
1268
+ ]);
1269
+ return /* @__PURE__ */ React8.createElement("div", {
1270
+ role: "none",
1271
+ className: mx2("is-full bs-full grow grid", classNames)
1272
+ }, /* @__PURE__ */ React8.createElement("div", {
1273
+ role: "none",
1274
+ className: "grid min-bs-0 overflow-hidden"
1275
+ }, /* @__PURE__ */ React8.createElement(Table.Root, null, /* @__PURE__ */ React8.createElement(Table.Main, {
1276
+ ref: tableRef,
1277
+ model,
1278
+ presentation,
1279
+ ignoreAttention: true,
1280
+ onRowClick
1281
+ }))));
1163
1282
  };
1164
1283
 
1165
1284
  // src/components/TableToolbar/TableToolbar.tsx
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";
1285
+ import { Atom as Atom3, RegistryContext as RegistryContext3 } from "@effect-atom/atom-react";
1286
+ import React9, { useContext as useContext3, useEffect as useEffect5, useMemo as useMemo6 } from "react";
1170
1287
  import { MenuProvider, ToolbarMenu, createGapSeparator, createMenuAction, useMenuActions } from "@dxos/react-ui-menu";
1171
- import { atomFromSignal } from "@dxos/react-ui-menu";
1172
- var createTableToolbarActions = ({ state, onAdd, onSave, customActions }) => Atom.make((get) => {
1288
+ var createTableToolbarActions = ({ stateAtom, onAdd, onSave, customActions }) => Atom3.make((get) => {
1173
1289
  const nodes = [];
1174
1290
  if (onAdd) {
1175
1291
  const add = createMenuAction("add-row", onAdd, {
1176
1292
  type: "add-row",
1177
1293
  icon: "ph--plus--regular",
1178
1294
  label: [
1179
- "add row",
1295
+ "add row label",
1180
1296
  {
1181
1297
  ns: translationKey
1182
1298
  }
@@ -1186,6 +1302,7 @@ var createTableToolbarActions = ({ state, onAdd, onSave, customActions }) => Ato
1186
1302
  nodes.push(add);
1187
1303
  }
1188
1304
  if (onSave) {
1305
+ const state = get(stateAtom);
1189
1306
  const save = createMenuAction("save-view", onSave, {
1190
1307
  type: "save-view",
1191
1308
  icon: "ph--floppy-disk--regular",
@@ -1197,7 +1314,7 @@ var createTableToolbarActions = ({ state, onAdd, onSave, customActions }) => Ato
1197
1314
  ],
1198
1315
  testId: "table.toolbar.save-view",
1199
1316
  iconOnly: false,
1200
- hidden: get(atomFromSignal(() => !state.viewDirty))
1317
+ hidden: !state.viewDirty
1201
1318
  });
1202
1319
  nodes.push(save);
1203
1320
  }
@@ -1218,32 +1335,37 @@ var createTableToolbarActions = ({ state, onAdd, onSave, customActions }) => Ato
1218
1335
  };
1219
1336
  });
1220
1337
  var TableToolbar = ({ classNames, viewDirty, attendableId, onAdd, onSave, customActions }) => {
1221
- var _effect = _useSignals9();
1222
- try {
1223
- const state = useMemo6(() => live({
1338
+ const registry = useContext3(RegistryContext3);
1339
+ const stateAtom = useMemo6(() => Atom3.make({
1340
+ viewDirty
1341
+ }), []);
1342
+ useEffect5(() => {
1343
+ registry.set(stateAtom, {
1224
1344
  viewDirty
1225
- }), []);
1226
- const actionsCreator = useMemo6(() => createTableToolbarActions({
1227
- state,
1228
- onAdd,
1229
- onSave,
1230
- customActions
1231
- }), [
1232
- state,
1233
- onAdd,
1234
- onSave,
1235
- customActions
1236
- ]);
1237
- const menu = useMenuActions(actionsCreator);
1238
- return /* @__PURE__ */ React9.createElement(MenuProvider, {
1239
- ...menu,
1240
- attendableId
1241
- }, /* @__PURE__ */ React9.createElement(ToolbarMenu, {
1242
- classNames
1243
- }));
1244
- } finally {
1245
- _effect.f();
1246
- }
1345
+ });
1346
+ }, [
1347
+ registry,
1348
+ stateAtom,
1349
+ viewDirty
1350
+ ]);
1351
+ const actionsCreator = useMemo6(() => createTableToolbarActions({
1352
+ stateAtom,
1353
+ onAdd,
1354
+ onSave,
1355
+ customActions
1356
+ }), [
1357
+ stateAtom,
1358
+ onAdd,
1359
+ onSave,
1360
+ customActions
1361
+ ]);
1362
+ const menu = useMenuActions(actionsCreator);
1363
+ return /* @__PURE__ */ React9.createElement(MenuProvider, {
1364
+ ...menu,
1365
+ attendableId
1366
+ }, /* @__PURE__ */ React9.createElement(ToolbarMenu, {
1367
+ classNames
1368
+ }));
1247
1369
  };
1248
1370
  export {
1249
1371
  BUTTON_IDENTIFIERS,
@@ -1257,7 +1379,12 @@ export {
1257
1379
  TablePresentation,
1258
1380
  TableToolbar,
1259
1381
  cellClassesForRowSelection,
1382
+ compareValues,
1383
+ createDirectChangeCallback,
1384
+ createEchoChangeCallback,
1385
+ extractOrder,
1260
1386
  getBaseSchema,
1387
+ getSortValue,
1261
1388
  makeDynamicTable,
1262
1389
  narrowSchema,
1263
1390
  tableButtons,
@@ -1265,6 +1392,7 @@ export {
1265
1392
  touch,
1266
1393
  translations,
1267
1394
  useAddRow,
1395
+ useProjectionModel,
1268
1396
  useTableModel
1269
1397
  };
1270
1398
  //# sourceMappingURL=index.mjs.map