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