@dxos/react-ui-table 0.8.4-main.ae835ea → 0.8.4-main.bc674ce

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