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