@dxos/react-ui-table 0.8.4-main.72ec0f3 → 0.8.4-main.8360d9e660

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