@dxos/react-ui-table 0.8.4-main.70d3990 → 0.8.4-main.7996785055

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