@dxos/react-ui-table 0.8.2-staging.7ac8446 → 0.8.2

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 (97) hide show
  1. package/dist/lib/browser/chunk-U6LL2AVU.mjs +26 -0
  2. package/dist/lib/browser/chunk-U6LL2AVU.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +1115 -905
  4. package/dist/lib/browser/index.mjs.map +4 -4
  5. package/dist/lib/browser/meta.json +1 -1
  6. package/dist/lib/browser/types/index.mjs +1 -1
  7. package/dist/lib/node/{chunk-TGG6OZ54.cjs → chunk-CXDGXPM6.cjs} +12 -12
  8. package/dist/lib/node/chunk-CXDGXPM6.cjs.map +7 -0
  9. package/dist/lib/node/index.cjs +1113 -906
  10. package/dist/lib/node/index.cjs.map +4 -4
  11. package/dist/lib/node/meta.json +1 -1
  12. package/dist/lib/node/types/index.cjs +3 -3
  13. package/dist/lib/node/types/index.cjs.map +1 -1
  14. package/dist/lib/node-esm/{chunk-KKLP54L3.mjs → chunk-EFSM52KQ.mjs} +10 -10
  15. package/dist/lib/node-esm/chunk-EFSM52KQ.mjs.map +7 -0
  16. package/dist/lib/node-esm/index.mjs +1115 -905
  17. package/dist/lib/node-esm/index.mjs.map +4 -4
  18. package/dist/lib/node-esm/meta.json +1 -1
  19. package/dist/lib/node-esm/types/index.mjs +1 -1
  20. package/dist/types/src/components/Table/ColumnActionsMenu.d.ts.map +1 -1
  21. package/dist/types/src/components/Table/ColumnSettings.d.ts.map +1 -1
  22. package/dist/types/src/components/Table/CreateRefPanel.d.ts.map +1 -1
  23. package/dist/types/src/components/Table/DynamicTable.d.ts +3 -4
  24. package/dist/types/src/components/Table/DynamicTable.d.ts.map +1 -1
  25. package/dist/types/src/components/Table/RowActionsMenu.d.ts.map +1 -1
  26. package/dist/types/src/components/Table/Table.d.ts +2 -0
  27. package/dist/types/src/components/Table/Table.d.ts.map +1 -1
  28. package/dist/types/src/components/Table/Table.stories.d.ts +1 -0
  29. package/dist/types/src/components/Table/Table.stories.d.ts.map +1 -1
  30. package/dist/types/src/components/Table/relations.stories.d.ts.map +1 -1
  31. package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts +13 -0
  32. package/dist/types/src/components/TableCellEditor/FormCellEditor.d.ts.map +1 -0
  33. package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts +3 -0
  34. package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts.map +1 -1
  35. package/dist/types/src/components/TableCellEditor/TableCellEditor.stories.d.ts.map +1 -1
  36. package/dist/types/src/components/TableCellEditor/extension.d.ts.map +1 -1
  37. package/dist/types/src/components/TableToolbar/TableToolbar.d.ts +6 -3
  38. package/dist/types/src/components/TableToolbar/TableToolbar.d.ts.map +1 -1
  39. package/dist/types/src/components/testing.d.ts +40 -40
  40. package/dist/types/src/components/testing.d.ts.map +1 -1
  41. package/dist/types/src/hooks/useTableModel.d.ts +2 -2
  42. package/dist/types/src/hooks/useTableModel.d.ts.map +1 -1
  43. package/dist/types/src/model/modal-controller.d.ts +3 -3
  44. package/dist/types/src/model/modal-controller.d.ts.map +1 -1
  45. package/dist/types/src/model/selection-model.d.ts.map +1 -1
  46. package/dist/types/src/model/table-model.d.ts.map +1 -1
  47. package/dist/types/src/model/table-presentation.d.ts.map +1 -1
  48. package/dist/types/src/types/table.d.ts +46 -45
  49. package/dist/types/src/types/table.d.ts.map +1 -1
  50. package/dist/types/src/util/dynamic-table.d.ts +4 -3
  51. package/dist/types/src/util/dynamic-table.d.ts.map +1 -1
  52. package/dist/types/src/util/index.d.ts +1 -0
  53. package/dist/types/src/util/index.d.ts.map +1 -1
  54. package/dist/types/src/util/schema.d.ts +12 -0
  55. package/dist/types/src/util/schema.d.ts.map +1 -0
  56. package/dist/types/src/util/signals.d.ts.map +1 -1
  57. package/dist/types/src/util/table-buttons.d.ts +0 -14
  58. package/dist/types/src/util/table-buttons.d.ts.map +1 -1
  59. package/dist/types/src/util/table-controls.d.ts.map +1 -1
  60. package/dist/types/src/util/table.d.ts +2 -2
  61. package/dist/types/src/util/table.d.ts.map +1 -1
  62. package/dist/types/src/util/tag.d.ts +11 -0
  63. package/dist/types/src/util/tag.d.ts.map +1 -0
  64. package/dist/types/tsconfig.tsbuildinfo +1 -1
  65. package/package.json +41 -34
  66. package/src/components/Table/CreateRefPanel.tsx +5 -5
  67. package/src/components/Table/DynamicTable.stories.tsx +4 -4
  68. package/src/components/Table/DynamicTable.tsx +4 -5
  69. package/src/components/Table/Table.stories.tsx +84 -50
  70. package/src/components/Table/Table.tsx +25 -28
  71. package/src/components/Table/relations.stories.tsx +38 -32
  72. package/src/components/TableCellEditor/FormCellEditor.tsx +94 -0
  73. package/src/components/TableCellEditor/TableCellEditor.stories.tsx +13 -11
  74. package/src/components/TableCellEditor/TableCellEditor.tsx +45 -4
  75. package/src/components/TableToolbar/TableToolbar.tsx +65 -35
  76. package/src/components/testing.ts +10 -9
  77. package/src/hooks/useTableModel.ts +6 -4
  78. package/src/model/modal-controller.ts +3 -3
  79. package/src/model/selection-model.ts +1 -1
  80. package/src/model/table-model.test.ts +7 -6
  81. package/src/model/table-model.ts +20 -3
  82. package/src/model/table-presentation.test.ts +7 -6
  83. package/src/model/table-presentation.ts +54 -10
  84. package/src/types/table.ts +16 -11
  85. package/src/util/dynamic-table.ts +9 -6
  86. package/src/util/index.ts +1 -0
  87. package/src/util/schema.ts +36 -0
  88. package/src/util/table-buttons.ts +1 -24
  89. package/src/util/table.ts +13 -16
  90. package/src/util/tag.ts +33 -0
  91. package/dist/lib/browser/chunk-YWNRUF4J.mjs +0 -26
  92. package/dist/lib/browser/chunk-YWNRUF4J.mjs.map +0 -7
  93. package/dist/lib/node/chunk-TGG6OZ54.cjs.map +0 -7
  94. package/dist/lib/node-esm/chunk-KKLP54L3.mjs.map +0 -7
  95. package/dist/types/src/components/Table/RefPanel.d.ts +0 -9
  96. package/dist/types/src/components/Table/RefPanel.d.ts.map +0 -1
  97. package/src/components/Table/RefPanel.tsx +0 -52
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  TableSchema,
3
3
  TableType
4
- } from "./chunk-YWNRUF4J.mjs";
4
+ } from "./chunk-U6LL2AVU.mjs";
5
5
 
6
6
  // packages/ui/react-ui-table/src/translations.ts
7
7
  var translationKey = "table";
@@ -36,258 +36,245 @@ var translations_default = [
36
36
  ];
37
37
 
38
38
  // packages/ui/react-ui-table/src/components/Table/Table.tsx
39
- import React7, { forwardRef, useCallback as useCallback4, useImperativeHandle, useState as useState2, useMemo as useMemo4, useEffect as useEffect2 } from "react";
39
+ import { useSignals as _useSignals7 } from "@preact-signals/safe-react/tracking";
40
+ import React7, { forwardRef, useCallback as useCallback5, useImperativeHandle, useState as useState2, useMemo as useMemo5, useEffect as useEffect3 } from "react";
40
41
  import { getValue as getValue4 } from "@dxos/echo-schema";
41
- import { invariant as invariant3 } from "@dxos/invariant";
42
+ import { invariant as invariant4 } from "@dxos/invariant";
42
43
  import { Filter } from "@dxos/react-client/echo";
43
44
  import { useTranslation as useTranslation3 } from "@dxos/react-ui";
44
45
  import { useAttention } from "@dxos/react-ui-attention";
45
- import { closestCell, Grid } from "@dxos/react-ui-grid";
46
+ import { closestCell, Grid, gridSeparatorInlineEnd, gridSeparatorBlockEnd } from "@dxos/react-ui-grid";
46
47
  import { mx as mx2 } from "@dxos/react-ui-theme";
47
48
  import { isNotFalsy, safeParseInt } from "@dxos/util";
48
49
 
49
50
  // packages/ui/react-ui-table/src/components/Table/ColumnActionsMenu.tsx
51
+ import { useSignals as _useSignals } from "@preact-signals/safe-react/tracking";
50
52
  import React from "react";
51
53
  import { DropdownMenu, useTranslation } from "@dxos/react-ui";
52
54
  var ColumnActionsMenu = ({ model, modals }) => {
53
- const { t } = useTranslation(translationKey);
54
- const state = modals.state.value;
55
- if (state?.type !== "column") {
56
- return null;
57
- }
58
- const currentSort = model.sorting?.sorting;
59
- const isCurrentColumnSorted = currentSort?.fieldId === state.fieldId;
60
- return /* @__PURE__ */ React.createElement(DropdownMenu.Root, {
61
- modal: false,
62
- open: true,
63
- onOpenChange: modals.close
64
- }, /* @__PURE__ */ React.createElement(DropdownMenu.VirtualTrigger, {
65
- virtualRef: modals.trigger
66
- }), /* @__PURE__ */ React.createElement(DropdownMenu.Portal, null, /* @__PURE__ */ React.createElement(DropdownMenu.Content, null, /* @__PURE__ */ React.createElement(DropdownMenu.Viewport, null, (!isCurrentColumnSorted || currentSort?.direction === "asc") && /* @__PURE__ */ React.createElement(DropdownMenu.Item, {
67
- "data-testid": "column-sort-descending",
68
- onClick: () => model.sorting?.setSort(state.fieldId, "desc")
69
- }, t("column action sort descending")), (!isCurrentColumnSorted || currentSort?.direction === "desc") && /* @__PURE__ */ React.createElement(DropdownMenu.Item, {
70
- "data-testid": "column-sort-ascending",
71
- onClick: () => model.sorting?.setSort(state.fieldId, "asc")
72
- }, t("column action sort ascending")), isCurrentColumnSorted && /* @__PURE__ */ React.createElement(DropdownMenu.Item, {
73
- "data-testid": "column-clear-sort",
74
- onClick: () => model.sorting?.clearSort()
75
- }, t("column action clear sorting")), model.getColumnCount() > 1 && model.features.schemaEditable && /* @__PURE__ */ React.createElement(DropdownMenu.Item, {
76
- "data-testid": "column-delete",
77
- onClick: () => model.deleteColumn(state.fieldId)
78
- }, t("column action delete")), model.features.schemaEditable && /* @__PURE__ */ React.createElement(DropdownMenu.Item, {
79
- "data-testid": "column-settings",
80
- onClick: () => modals.openColumnSettings()
81
- }, t("column action settings"))), /* @__PURE__ */ React.createElement(DropdownMenu.Arrow, null))));
55
+ var _effect = _useSignals();
56
+ try {
57
+ const { t } = useTranslation(translationKey);
58
+ const state = modals.state.value;
59
+ if (state?.type !== "column") {
60
+ return null;
61
+ }
62
+ const currentSort = model.sorting?.sorting;
63
+ const isCurrentColumnSorted = currentSort?.fieldId === state.fieldId;
64
+ return /* @__PURE__ */ React.createElement(DropdownMenu.Root, {
65
+ modal: false,
66
+ open: true,
67
+ onOpenChange: modals.close
68
+ }, /* @__PURE__ */ React.createElement(DropdownMenu.VirtualTrigger, {
69
+ virtualRef: modals.trigger
70
+ }), /* @__PURE__ */ React.createElement(DropdownMenu.Portal, null, /* @__PURE__ */ React.createElement(DropdownMenu.Content, null, /* @__PURE__ */ React.createElement(DropdownMenu.Viewport, null, (!isCurrentColumnSorted || currentSort?.direction === "asc") && /* @__PURE__ */ React.createElement(DropdownMenu.Item, {
71
+ "data-testid": "column-sort-descending",
72
+ onClick: () => model.sorting?.setSort(state.fieldId, "desc")
73
+ }, t("column action sort descending")), (!isCurrentColumnSorted || currentSort?.direction === "desc") && /* @__PURE__ */ React.createElement(DropdownMenu.Item, {
74
+ "data-testid": "column-sort-ascending",
75
+ onClick: () => model.sorting?.setSort(state.fieldId, "asc")
76
+ }, t("column action sort ascending")), isCurrentColumnSorted && /* @__PURE__ */ React.createElement(DropdownMenu.Item, {
77
+ "data-testid": "column-clear-sort",
78
+ onClick: () => model.sorting?.clearSort()
79
+ }, t("column action clear sorting")), model.getColumnCount() > 1 && model.features.schemaEditable && /* @__PURE__ */ React.createElement(DropdownMenu.Item, {
80
+ "data-testid": "column-delete",
81
+ onClick: () => model.deleteColumn(state.fieldId)
82
+ }, t("column action delete")), model.features.schemaEditable && /* @__PURE__ */ React.createElement(DropdownMenu.Item, {
83
+ "data-testid": "column-settings",
84
+ onClick: () => modals.openColumnSettings()
85
+ }, t("column action settings"))), /* @__PURE__ */ React.createElement(DropdownMenu.Arrow, null))));
86
+ } finally {
87
+ _effect.f();
88
+ }
82
89
  };
83
90
 
84
91
  // packages/ui/react-ui-table/src/components/Table/ColumnSettings.tsx
92
+ import { useSignals as _useSignals2 } from "@preact-signals/safe-react/tracking";
85
93
  import React2, { useCallback, useEffect, useMemo, useState } from "react";
86
94
  import { DropdownMenu as DropdownMenu2 } from "@dxos/react-ui";
87
95
  import { FieldEditor } from "@dxos/react-ui-form";
88
96
  var ColumnSettings = ({ model, modals, onNewColumn }) => {
89
- const [newField, setNewField] = useState();
90
- const state = modals.state.value;
91
- const space = model?.space;
92
- useEffect(() => {
93
- if (state?.type === "columnSettings" && state.mode.type === "create" && model?.projection) {
94
- setNewField(model.projection.createFieldProjection());
95
- requestAnimationFrame(() => {
96
- onNewColumn();
97
- });
98
- } else {
99
- setNewField(void 0);
100
- }
101
- }, [
102
- model?.projection,
103
- state
104
- ]);
105
- const existingField = useMemo(() => {
106
- if (state?.type === "columnSettings") {
107
- const { mode } = state;
108
- if (mode.type === "edit") {
109
- return model?.view?.fields.find((f) => f.id === mode.fieldId);
97
+ var _effect = _useSignals2();
98
+ try {
99
+ const [newField, setNewField] = useState();
100
+ const state = modals.state.value;
101
+ const space = model?.space;
102
+ useEffect(() => {
103
+ if (state?.type === "columnSettings" && state.mode.type === "create" && model?.projection) {
104
+ setNewField(model.projection.createFieldProjection());
105
+ requestAnimationFrame(() => {
106
+ onNewColumn();
107
+ });
108
+ } else {
109
+ setNewField(void 0);
110
110
  }
111
- }
112
- return void 0;
113
- }, [
114
- model?.view?.fields,
115
- state
116
- ]);
117
- const field = existingField ?? newField;
118
- const handleSave = useCallback(() => {
119
- modals.close();
120
- }, [
121
- modals
122
- ]);
123
- const handleCancel = useCallback(() => {
124
- if (state?.type === "columnSettings" && state.mode.type === "create" && newField) {
125
- model?.projection?.deleteFieldProjection(newField.id);
126
- }
127
- }, [
128
- model?.projection,
129
- state,
130
- newField
131
- ]);
132
- if (!model?.view || !model.projection || !field) {
133
- return null;
134
- }
135
- return /* @__PURE__ */ React2.createElement(DropdownMenu2.Root, {
136
- modal: false,
137
- open: state?.type === "columnSettings"
138
- }, /* @__PURE__ */ React2.createElement(DropdownMenu2.VirtualTrigger, {
139
- virtualRef: modals.trigger
140
- }), /* @__PURE__ */ React2.createElement(DropdownMenu2.Portal, null, /* @__PURE__ */ React2.createElement(DropdownMenu2.Content, {
141
- classNames: "md:is-64"
142
- }, /* @__PURE__ */ React2.createElement(DropdownMenu2.Viewport, null, /* @__PURE__ */ React2.createElement(FieldEditor, {
143
- view: model.view,
144
- projection: model.projection,
145
- field,
146
- registry: space?.db.schemaRegistry,
147
- onSave: handleSave,
148
- onCancel: handleCancel
149
- })), /* @__PURE__ */ React2.createElement(DropdownMenu2.Arrow, null))));
111
+ }, [
112
+ model?.projection,
113
+ state
114
+ ]);
115
+ const existingField = useMemo(() => {
116
+ if (state?.type === "columnSettings") {
117
+ const { mode } = state;
118
+ if (mode.type === "edit") {
119
+ return model?.view?.fields.find((f) => f.id === mode.fieldId);
120
+ }
121
+ }
122
+ return void 0;
123
+ }, [
124
+ model?.view?.fields,
125
+ state
126
+ ]);
127
+ const field = existingField ?? newField;
128
+ const handleSave = useCallback(() => {
129
+ modals.close();
130
+ }, [
131
+ modals
132
+ ]);
133
+ const handleCancel = useCallback(() => {
134
+ if (state?.type === "columnSettings" && state.mode.type === "create" && newField) {
135
+ model?.projection?.deleteFieldProjection(newField.id);
136
+ }
137
+ }, [
138
+ model?.projection,
139
+ state,
140
+ newField
141
+ ]);
142
+ if (!model?.view || !model.projection || !field) {
143
+ return null;
144
+ }
145
+ return /* @__PURE__ */ React2.createElement(DropdownMenu2.Root, {
146
+ modal: false,
147
+ open: state?.type === "columnSettings"
148
+ }, /* @__PURE__ */ React2.createElement(DropdownMenu2.VirtualTrigger, {
149
+ virtualRef: modals.trigger
150
+ }), /* @__PURE__ */ React2.createElement(DropdownMenu2.Portal, null, /* @__PURE__ */ React2.createElement(DropdownMenu2.Content, {
151
+ classNames: "md:is-64"
152
+ }, /* @__PURE__ */ React2.createElement(DropdownMenu2.Viewport, null, /* @__PURE__ */ React2.createElement(FieldEditor, {
153
+ view: model.view,
154
+ projection: model.projection,
155
+ field,
156
+ registry: space?.db.schemaRegistry,
157
+ onSave: handleSave,
158
+ onCancel: handleCancel
159
+ })), /* @__PURE__ */ React2.createElement(DropdownMenu2.Arrow, null))));
160
+ } finally {
161
+ _effect.f();
162
+ }
150
163
  };
151
164
 
152
165
  // packages/ui/react-ui-table/src/components/Table/CreateRefPanel.tsx
166
+ import { useSignals as _useSignals3 } from "@preact-signals/safe-react/tracking";
167
+ import { Schema } from "effect";
153
168
  import React3, { useCallback as useCallback2, useMemo as useMemo2 } from "react";
154
- import { S } from "@dxos/echo-schema";
155
- import { create } from "@dxos/react-client/echo";
169
+ import { live } from "@dxos/react-client/echo";
156
170
  import { Popover } from "@dxos/react-ui";
157
171
  import { Form } from "@dxos/react-ui-form";
158
172
  import { useGridContext } from "@dxos/react-ui-grid";
159
173
  var CreateRefPanel = ({ model, modals, __gridScope }) => {
160
- const { id: gridId } = useGridContext("TableCellEditor", __gridScope);
161
- const space = model?.space;
162
- const state = modals.state.value;
163
- const schema = useMemo2(() => {
164
- if (!space || state?.type !== "createRefPanel") {
165
- return;
166
- }
167
- const [schema2] = space.db.schemaRegistry.query({
168
- typename: state.typename
169
- }).runSync();
170
- if (schema2) {
171
- const omit = S.omit("id");
172
- return omit(schema2);
173
- }
174
- }, [
175
- space,
176
- state
177
- ]);
178
- const handleSave = useCallback2((values) => {
179
- if (!model || !space || state?.type !== "createRefPanel") {
180
- return;
181
- }
182
- const [schema2] = space.db.schemaRegistry.query({
183
- typename: state.typename
184
- }).runSync();
185
- if (schema2) {
186
- const obj = space.db.add(create(schema2, values));
187
- state.onCreate?.(obj);
188
- }
189
- void modals.close();
190
- }, [
191
- modals,
192
- space,
193
- state
194
- ]);
195
- const handleCancel = useCallback2(() => {
196
- if (model) {
197
- modals.close();
198
- }
199
- }, [
200
- modals
201
- ]);
202
- if (!model?.view || !model.projection) {
203
- return null;
204
- }
205
- return /* @__PURE__ */ React3.createElement(Popover.Root, {
206
- modal: false,
207
- open: state?.type === "createRefPanel" && !!schema,
208
- onOpenChange: (nextOpen) => {
209
- if (model && !nextOpen) {
210
- return modals.close();
174
+ var _effect = _useSignals3();
175
+ try {
176
+ const { id: gridId } = useGridContext("TableCellEditor", __gridScope);
177
+ const space = model?.space;
178
+ const state = modals.state.value;
179
+ const schema = useMemo2(() => {
180
+ if (!space || state?.type !== "createRefPanel") {
181
+ return;
211
182
  }
212
- }
213
- }, /* @__PURE__ */ React3.createElement(Popover.VirtualTrigger, {
214
- virtualRef: modals.trigger
215
- }), /* @__PURE__ */ React3.createElement(Popover.Portal, null, /* @__PURE__ */ React3.createElement(Popover.Content, {
216
- classNames: "md:is-64",
217
- "data-grid": gridId
218
- }, state?.type === "createRefPanel" && schema && /* @__PURE__ */ React3.createElement(Form, {
219
- schema,
220
- values: state.initialValues ?? {},
221
- onSave: handleSave,
222
- onCancel: handleCancel
223
- }), /* @__PURE__ */ React3.createElement(Popover.Arrow, null))));
224
- };
225
-
226
- // packages/ui/react-ui-table/src/components/Table/RefPanel.tsx
227
- import React4 from "react";
228
- import { Popover as Popover2 } from "@dxos/react-ui";
229
- import { Form as Form2 } from "@dxos/react-ui-form";
230
- var getRefTargetObj = (space, id) => {
231
- if (space && id) {
232
- return space?.db.getObjectById(id);
233
- } else {
234
- return void 0;
235
- }
236
- };
237
- var RefPanel = ({ model, modals }) => {
238
- const state = modals.state.value;
239
- const space = model?.space;
240
- const targetObj = getRefTargetObj(space, state?.type === "refPanel" ? state.targetId : void 0);
241
- const schema = space && state?.type === "refPanel" ? space.db.schemaRegistry.getSchema(state.typename) : void 0;
242
- if (!model.view || !model.projection) {
243
- return null;
244
- }
245
- return /* @__PURE__ */ React4.createElement(Popover2.Root, {
246
- modal: false,
247
- open: state?.type === "refPanel" && !!targetObj && !!schema,
248
- onOpenChange: (nextOpen) => {
249
- if (!nextOpen) {
250
- return modals.close();
183
+ const [schema2] = space.db.schemaRegistry.query({
184
+ typename: state.typename
185
+ }).runSync();
186
+ if (schema2) {
187
+ const omit = Schema.omit("id");
188
+ return omit(schema2);
251
189
  }
252
- }
253
- }, /* @__PURE__ */ React4.createElement(Popover2.VirtualTrigger, {
254
- virtualRef: modals.trigger
255
- }), /* @__PURE__ */ React4.createElement(Popover2.Portal, null, /* @__PURE__ */ React4.createElement(Popover2.Content, {
256
- classNames: "md:is-64"
257
- }, targetObj && schema && /* @__PURE__ */ React4.createElement(Form2, {
258
- readonly: true,
259
- values: targetObj,
260
- schema
261
- }), /* @__PURE__ */ React4.createElement(Popover2.Arrow, null))));
190
+ }, [
191
+ space,
192
+ state
193
+ ]);
194
+ const handleSave = useCallback2((values) => {
195
+ if (!model || !space || state?.type !== "createRefPanel") {
196
+ return;
197
+ }
198
+ const [schema2] = space.db.schemaRegistry.query({
199
+ typename: state.typename
200
+ }).runSync();
201
+ if (schema2) {
202
+ const obj = space.db.add(live(schema2, values));
203
+ state.onCreate?.(obj);
204
+ }
205
+ void modals.close();
206
+ }, [
207
+ modals,
208
+ space,
209
+ state
210
+ ]);
211
+ const handleCancel = useCallback2(() => {
212
+ if (model) {
213
+ modals.close();
214
+ }
215
+ }, [
216
+ modals
217
+ ]);
218
+ if (!model?.view || !model.projection) {
219
+ return null;
220
+ }
221
+ return /* @__PURE__ */ React3.createElement(Popover.Root, {
222
+ modal: false,
223
+ open: state?.type === "createRefPanel" && !!schema,
224
+ onOpenChange: (nextOpen) => {
225
+ if (model && !nextOpen) {
226
+ return modals.close();
227
+ }
228
+ }
229
+ }, /* @__PURE__ */ React3.createElement(Popover.VirtualTrigger, {
230
+ virtualRef: modals.trigger
231
+ }), /* @__PURE__ */ React3.createElement(Popover.Portal, null, /* @__PURE__ */ React3.createElement(Popover.Content, {
232
+ classNames: "md:is-64",
233
+ "data-grid": gridId
234
+ }, state?.type === "createRefPanel" && schema && /* @__PURE__ */ React3.createElement(Form, {
235
+ schema,
236
+ values: state.initialValues ?? {},
237
+ onSave: handleSave,
238
+ onCancel: handleCancel
239
+ }), /* @__PURE__ */ React3.createElement(Popover.Arrow, null))));
240
+ } finally {
241
+ _effect.f();
242
+ }
262
243
  };
263
244
 
264
245
  // packages/ui/react-ui-table/src/components/Table/RowActionsMenu.tsx
265
- import React5 from "react";
246
+ import { useSignals as _useSignals4 } from "@preact-signals/safe-react/tracking";
247
+ import React4 from "react";
266
248
  import { DropdownMenu as DropdownMenu3, useTranslation as useTranslation2 } from "@dxos/react-ui";
267
249
  var RowActionsMenu = ({ model, modals }) => {
268
- const { t } = useTranslation2(translationKey);
269
- const hasSelection = model.selection.hasSelection.value;
270
- const state = modals.state.value;
271
- if (state?.type !== "row") {
272
- return null;
273
- }
274
- return /* @__PURE__ */ React5.createElement(DropdownMenu3.Root, {
275
- modal: false,
276
- open: true,
277
- onOpenChange: modals.close
278
- }, /* @__PURE__ */ React5.createElement(DropdownMenu3.VirtualTrigger, {
279
- virtualRef: modals.trigger
280
- }), /* @__PURE__ */ React5.createElement(DropdownMenu3.Content, null, /* @__PURE__ */ React5.createElement(DropdownMenu3.Viewport, null, model.features.dataEditable !== false && /* @__PURE__ */ React5.createElement(DropdownMenu3.Item, {
281
- "data-testid": "row-menu-delete",
282
- onClick: () => model.deleteRow(state.rowIndex)
283
- }, t(hasSelection ? "bulk delete row label" : "delete row label")), model.rowActions?.map((action) => /* @__PURE__ */ React5.createElement(DropdownMenu3.Item, {
284
- key: action.id,
285
- "data-testid": `row-action-${action.id}`,
286
- onClick: () => {
287
- modals.close();
288
- model.handleRowAction(action.id, state.rowIndex);
289
- }
290
- }, t(action.translationKey)))), /* @__PURE__ */ React5.createElement(DropdownMenu3.Arrow, null)));
250
+ var _effect = _useSignals4();
251
+ try {
252
+ const { t } = useTranslation2(translationKey);
253
+ const hasSelection = model.selection.hasSelection.value;
254
+ const state = modals.state.value;
255
+ if (state?.type !== "row") {
256
+ return null;
257
+ }
258
+ return /* @__PURE__ */ React4.createElement(DropdownMenu3.Root, {
259
+ modal: false,
260
+ open: true,
261
+ onOpenChange: modals.close
262
+ }, /* @__PURE__ */ React4.createElement(DropdownMenu3.VirtualTrigger, {
263
+ virtualRef: modals.trigger
264
+ }), /* @__PURE__ */ React4.createElement(DropdownMenu3.Content, null, /* @__PURE__ */ React4.createElement(DropdownMenu3.Viewport, null, model.features.dataEditable !== false && /* @__PURE__ */ React4.createElement(DropdownMenu3.Item, {
265
+ "data-testid": "row-menu-delete",
266
+ onClick: () => model.deleteRow(state.rowIndex)
267
+ }, t(hasSelection ? "bulk delete row label" : "delete row label")), model.rowActions?.map((action) => /* @__PURE__ */ React4.createElement(DropdownMenu3.Item, {
268
+ key: action.id,
269
+ "data-testid": `row-action-${action.id}`,
270
+ onClick: () => {
271
+ modals.close();
272
+ model.handleRowAction(action.id, state.rowIndex);
273
+ }
274
+ }, t(action.translationKey)))), /* @__PURE__ */ React4.createElement(DropdownMenu3.Arrow, null)));
275
+ } finally {
276
+ _effect.f();
277
+ }
291
278
  };
292
279
 
293
280
  // packages/ui/react-ui-table/src/model/table-model.ts
@@ -295,7 +282,7 @@ import { computed as computed3, effect as effect2, signal as signal3 } from "@pr
295
282
  import { Resource as Resource2 } from "@dxos/context";
296
283
  import { FormatEnum as FormatEnum3, getValue as getValue2, setValue } from "@dxos/echo-schema";
297
284
  import { invariant } from "@dxos/invariant";
298
- import { isReactiveObject, makeRef as makeRef3 } from "@dxos/live-object";
285
+ import { isLiveObject, makeRef as makeRef2 } from "@dxos/live-object";
299
286
  import { formatForEditing, parseValue } from "@dxos/react-ui-form";
300
287
 
301
288
  // packages/ui/react-ui-table/src/model/selection-model.ts
@@ -303,9 +290,10 @@ import { computed, effect, signal } from "@preact/signals-core";
303
290
  import { Resource } from "@dxos/context";
304
291
 
305
292
  // packages/ui/react-ui-table/src/util/dynamic-table.ts
306
- import { create as create2, makeRef } from "@dxos/live-object";
293
+ import { getTypename, toJsonSchema } from "@dxos/echo-schema";
294
+ import { live as live2, makeRef } from "@dxos/live-object";
307
295
  import { createView, getSchemaFromPropertyDefinitions, ViewProjection } from "@dxos/schema";
308
- var getBaseSchems = ({ typename, properties, jsonSchema, schema }) => {
296
+ var getBaseSchema = ({ typename, properties, jsonSchema, schema }) => {
309
297
  if (typename && properties) {
310
298
  const schema2 = getSchemaFromPropertyDefinitions(typename, properties);
311
299
  return {
@@ -314,8 +302,8 @@ var getBaseSchems = ({ typename, properties, jsonSchema, schema }) => {
314
302
  };
315
303
  } else if (schema) {
316
304
  return {
317
- typename: schema.typename,
318
- jsonSchema: schema.jsonSchema
305
+ typename: getTypename(schema),
306
+ jsonSchema: toJsonSchema(schema)
319
307
  };
320
308
  } else if (typename && jsonSchema) {
321
309
  return {
@@ -335,7 +323,7 @@ var makeDynamicTable = ({ typename, jsonSchema, properties }) => {
335
323
  fields: properties.map((property) => property.name)
336
324
  }
337
325
  });
338
- const table = create2(TableType, {
326
+ const table = live2(TableType, {
339
327
  name: "dynamic-table",
340
328
  view: makeRef(view)
341
329
  });
@@ -382,9 +370,10 @@ var setProperties = (view, projection, properties) => {
382
370
  var touch = (value) => value;
383
371
 
384
372
  // packages/ui/react-ui-table/src/util/table.ts
385
- import { AST, Format, FormatEnum, S as S2, TypedObject, TypeEnum } from "@dxos/echo-schema";
373
+ import { Schema as Schema2 } from "effect";
374
+ import { Format, FormatEnum, Ref, TypedObject, TypeEnum } from "@dxos/echo-schema";
386
375
  import { PublicKey } from "@dxos/react-client";
387
- import { create as create3, makeRef as makeRef2 } from "@dxos/react-client/echo";
376
+ import { live as live3 } from "@dxos/react-client/echo";
388
377
  import { createFieldId, createView as createView2, getSchemaProperties, ViewProjection as ViewProjection2 } from "@dxos/schema";
389
378
  var initializeTable = async ({ client, space, table, typename, initialRow = true }) => {
390
379
  if (typename) {
@@ -392,8 +381,8 @@ var initializeTable = async ({ client, space, table, typename, initialRow = true
392
381
  if (!schema) {
393
382
  throw new Error(`Schema not found: ${typename}`);
394
383
  }
395
- const fields = getSchemaProperties(schema.ast).filter((prop) => prop.format !== FormatEnum.Ref).map((prop) => prop.name);
396
- table.view = makeRef2(createView2({
384
+ const fields = getSchemaProperties(schema.ast).map((prop) => prop.name);
385
+ table.view = Ref.make(createView2({
397
386
  // TODO(ZaymonFC): Don't hardcode name?
398
387
  name: "View",
399
388
  typename: schema.typename,
@@ -406,7 +395,7 @@ var initializeTable = async ({ client, space, table, typename, initialRow = true
406
395
  ContactSchema
407
396
  ]);
408
397
  const fields = ContactFields;
409
- table.view = makeRef2(createView2({
398
+ table.view = Ref.make(createView2({
410
399
  name: "View",
411
400
  typename: schema.typename,
412
401
  jsonSchema: schema.jsonSchema,
@@ -414,7 +403,7 @@ var initializeTable = async ({ client, space, table, typename, initialRow = true
414
403
  }));
415
404
  createProjection(schema, table.view.target);
416
405
  if (initialRow) {
417
- space.db.add(create3(schema, {}));
406
+ space.db.add(live3(schema, {}));
418
407
  }
419
408
  return schema;
420
409
  }
@@ -423,13 +412,13 @@ var ContactSchema = TypedObject({
423
412
  typename: `example.com/type/${PublicKey.random().truncate()}`,
424
413
  version: "0.1.0"
425
414
  })({
426
- name: S2.optional(S2.String).annotations({
427
- [AST.TitleAnnotationId]: "Name"
415
+ name: Schema2.optional(Schema2.String).annotations({
416
+ title: "Name"
428
417
  }),
429
- active: S2.optional(S2.Boolean),
430
- email: S2.optional(Format.Email),
431
- salary: S2.optional(Format.Currency()).annotations({
432
- [AST.TitleAnnotationId]: "Salary"
418
+ active: Schema2.optional(Schema2.Boolean),
419
+ email: Schema2.optional(Format.Email),
420
+ salary: Schema2.optional(Format.Currency()).annotations({
421
+ title: "Salary"
433
422
  })
434
423
  });
435
424
  var ContactFields = [
@@ -482,7 +471,7 @@ var BUTTON_IDENTIFIERS = {
482
471
  var createButton = ({ attr, data, disabled = false, icon, testId, type = "primary" }) => {
483
472
  const dataAttrs = Object.entries(data).map(([k, v]) => `${k}="${v}"`).join(" ");
484
473
  const positionClass = type === "primary" ? "inline-end-2" : "inline-end-9";
485
- return `<button ${attr} data-testid="${testId}" class="dx-button is-6 pli-0.5 min-bs-0 absolute inset-block-1 ${positionClass}" ${dataAttrs} ${disabled ? "disabled" : ""}><svg><use href="/icons.svg#${icon}"/></svg></button>`;
474
+ return `<button ${attr} data-testid="${testId}" class="dx-button is-6 pli-0.5 min-bs-0 absolute inset-block-1 ${positionClass}" ${dataAttrs} ${disabled ? "disabled" : ""}><svg data-size="4"><use href="/icons.svg#${icon}"/></svg></button>`;
486
475
  };
487
476
  var addColumnButton = {
488
477
  attr: BUTTON_IDENTIFIERS.newColumn,
@@ -518,26 +507,6 @@ var columnSettingsButton = {
518
507
  fieldId: el.getAttribute("data-field-id")
519
508
  })
520
509
  };
521
- var referencedCellButton = {
522
- attr: BUTTON_IDENTIFIERS.referencedCell,
523
- icon: "ph--link-simple-horizontal--regular",
524
- render: ({ targetId, schemaId }) => {
525
- return createButton({
526
- attr: BUTTON_IDENTIFIERS.referencedCell,
527
- icon: referencedCellButton.icon,
528
- data: {
529
- "data-target-id": targetId,
530
- "data-schema-id": schemaId
531
- },
532
- testId: "table-ref-cell-button"
533
- });
534
- },
535
- getData: (el) => ({
536
- type: "referencedCell",
537
- targetId: el.getAttribute("data-target-id"),
538
- schemaId: el.getAttribute("data-schema-id")
539
- })
540
- };
541
510
  var rowMenuButton = {
542
511
  attr: BUTTON_IDENTIFIERS.rowMenu,
543
512
  icon: "ph--dots-three--regular",
@@ -582,7 +551,6 @@ var sortButton = {
582
551
  var tableButtons = {
583
552
  addColumn: addColumnButton,
584
553
  columnSettings: columnSettingsButton,
585
- referencedCell: referencedCellButton,
586
554
  rowMenu: rowMenuButton,
587
555
  sort: sortButton
588
556
  };
@@ -641,15 +609,25 @@ var tableControls = {
641
609
  }
642
610
  };
643
611
 
612
+ // packages/ui/react-ui-table/src/util/schema.ts
613
+ import { Schema as Schema3 } from "effect";
614
+ import { isTypeLiteral, TypeLiteral } from "effect/SchemaAST";
615
+ var narrowSchema = (schema, paths) => {
616
+ const ast = schema?.ast;
617
+ if (isTypeLiteral(ast)) {
618
+ const propertySignatures = ast.propertySignatures.filter((signature) => paths.includes(signature.name.toString()));
619
+ if (propertySignatures.length > 0) {
620
+ const narrowType = new TypeLiteral(propertySignatures, []);
621
+ return Schema3.make(narrowType);
622
+ }
623
+ }
624
+ return void 0;
625
+ };
626
+
644
627
  // packages/ui/react-ui-table/src/model/selection-model.ts
645
628
  var SelectionModel = class extends Resource {
646
629
  constructor(_rows, _selectionMode, _onSelectionChanged) {
647
- super();
648
- this._rows = _rows;
649
- this._selectionMode = _selectionMode;
650
- this._onSelectionChanged = _onSelectionChanged;
651
- this._selection = signal(/* @__PURE__ */ new Set());
652
- this._validSelectedIds = computed(() => {
630
+ super(), this._rows = _rows, this._selectionMode = _selectionMode, this._onSelectionChanged = _onSelectionChanged, this._selection = signal(/* @__PURE__ */ new Set()), this._validSelectedIds = computed(() => {
653
631
  const rows = this._rows.value;
654
632
  if (!rows) {
655
633
  return /* @__PURE__ */ new Set();
@@ -658,27 +636,21 @@ var SelectionModel = class extends Resource {
658
636
  return new Set([
659
637
  ...this._selection.value
660
638
  ].filter((id) => validIds.has(id)));
661
- });
662
- this._hasSelection = computed(() => this._validSelectedIds.value.size > 0);
663
- this._allSelected = computed(() => {
639
+ }), this._hasSelection = computed(() => this._validSelectedIds.value.size > 0), this._allSelected = computed(() => {
664
640
  const rows = this._rows.value;
665
641
  if (rows.length === 0) {
666
642
  return false;
667
643
  }
668
644
  return rows.every((row) => this._selection.value.has(row.id));
669
- });
670
- this.getSelectedRows = () => {
645
+ }), this.getSelectedRows = () => {
671
646
  const selectedIds = this._validSelectedIds.value;
672
647
  return this._rows.value.filter((row) => selectedIds.has(row.id));
673
- };
674
- this.isRowIndexSelected = (rowIndex) => {
648
+ }, this.isRowIndexSelected = (rowIndex) => {
675
649
  const row = this._rows.value[rowIndex];
676
650
  return this._selection.value.has(row.id);
677
- };
678
- this.isObjectSelected = (object) => {
651
+ }, this.isObjectSelected = (object) => {
679
652
  return this._selection.value.has(object.id);
680
- };
681
- this.toggleSelectionForRowIndex = (rowIndex) => {
653
+ }, this.toggleSelectionForRowIndex = (rowIndex) => {
682
654
  const row = this._rows.value[rowIndex];
683
655
  const newSelection = new Set(this._selection.value);
684
656
  if (newSelection.has(row.id)) {
@@ -690,8 +662,7 @@ var SelectionModel = class extends Resource {
690
662
  newSelection.add(row.id);
691
663
  }
692
664
  this._selection.value = newSelection;
693
- };
694
- this.setSelection = (mode) => {
665
+ }, this.setSelection = (mode) => {
695
666
  switch (mode) {
696
667
  case "all": {
697
668
  this._selection.value = new Set(this._rows.value.map((row) => row.id));
@@ -893,6 +864,22 @@ var TableSorting = class {
893
864
  }
894
865
  };
895
866
 
867
+ // packages/ui/react-ui-table/src/util/tag.ts
868
+ var TAG_PATTERN_REGEX = /\[([^\]]+)\]\(([^)]+)\)/g;
869
+ var extractTagIds = (value) => {
870
+ if (typeof value !== "string") {
871
+ return void 0;
872
+ }
873
+ const ids = [];
874
+ let match;
875
+ while ((match = TAG_PATTERN_REGEX.exec(value)) !== null) {
876
+ if (match[2]) {
877
+ ids.push(match[2]);
878
+ }
879
+ }
880
+ return ids.length > 0 ? ids : void 0;
881
+ };
882
+
896
883
  // packages/ui/react-ui-table/src/model/table-model.ts
897
884
  var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-table/src/model/table-model.ts";
898
885
  var defaultFeatures = {
@@ -992,8 +979,22 @@ var TableModel = class extends Resource2 {
992
979
  const { props } = this._projection.getFieldProjection(field.id);
993
980
  switch (props.format) {
994
981
  case FormatEnum3.Ref: {
995
- if (isReactiveObject(value)) {
996
- setValue(this._rows.value[rowIdx], field.path, makeRef3(value));
982
+ if (isLiveObject(value)) {
983
+ setValue(this._rows.value[rowIdx], field.path, makeRef2(value));
984
+ }
985
+ break;
986
+ }
987
+ case FormatEnum3.SingleSelect: {
988
+ const ids = extractTagIds(value);
989
+ if (ids && ids.length > 0) {
990
+ setValue(this._rows.value[rowIdx], field.path, ids[0]);
991
+ }
992
+ break;
993
+ }
994
+ case FormatEnum3.MultiSelect: {
995
+ const ids = extractTagIds(value);
996
+ if (ids) {
997
+ setValue(this._rows.value[rowIdx], field.path, ids);
997
998
  }
998
999
  break;
999
1000
  }
@@ -1017,7 +1018,7 @@ var TableModel = class extends Resource2 {
1017
1018
  };
1018
1019
  invariant(!(this._features.dataEditable && this._features.selection.enabled && this._features.selection.mode === "single"), "Single selection is not compatible with editable tables.", {
1019
1020
  F: __dxlog_file,
1020
- L: 114,
1021
+ L: 115,
1021
1022
  S: this,
1022
1023
  A: [
1023
1024
  "!(this._features.dataEditable && this._features.selection.enabled && this._features.selection.mode === 'single')",
@@ -1077,7 +1078,7 @@ var TableModel = class extends Resource2 {
1077
1078
  get columnMeta() {
1078
1079
  invariant(this._columnMeta, void 0, {
1079
1080
  F: __dxlog_file,
1080
- L: 183,
1081
+ L: 184,
1081
1082
  S: this,
1082
1083
  A: [
1083
1084
  "this._columnMeta",
@@ -1303,7 +1304,8 @@ var ModalController = class {
1303
1304
 
1304
1305
  // packages/ui/react-ui-table/src/model/table-presentation.ts
1305
1306
  import { signal as signal5 } from "@preact/signals-core";
1306
- import { FormatEnum as FormatEnum4, getValue as getValue3 } from "@dxos/echo-schema";
1307
+ import { isNotNullable } from "effect/Predicate";
1308
+ import { FormatEnum as FormatEnum4, getDXN, getValue as getValue3, TypeEnum as TypeEnum3 } from "@dxos/echo-schema";
1307
1309
  import { cellClassesForFieldType, formatForDisplay as formatForDisplay2 } from "@dxos/react-ui-form";
1308
1310
  import { toPlaneCellIndex } from "@dxos/react-ui-grid";
1309
1311
  import { mx } from "@dxos/react-ui-theme";
@@ -1365,6 +1367,9 @@ var TablePresentation = class {
1365
1367
  if (value == null) {
1366
1368
  return "";
1367
1369
  }
1370
+ if (props.type === "array") {
1371
+ return "";
1372
+ }
1368
1373
  switch (props.format) {
1369
1374
  case FormatEnum4.Boolean:
1370
1375
  case FormatEnum4.SingleSelect:
@@ -1402,13 +1407,38 @@ var TablePresentation = class {
1402
1407
  if (classes.length > 0) {
1403
1408
  cell.className = mx(classes.flat());
1404
1409
  }
1410
+ if (props.type === TypeEnum3.Array) {
1411
+ const targetArray = getValue3(obj, field.path);
1412
+ if (targetArray && Array.isArray(targetArray)) {
1413
+ const getLabel = (value) => {
1414
+ if (!value) {
1415
+ return void 0;
1416
+ }
1417
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
1418
+ return String(value);
1419
+ }
1420
+ if (Array.isArray(value)) {
1421
+ return "Array";
1422
+ }
1423
+ if (typeof value === "object" && value.name) {
1424
+ return value.name;
1425
+ }
1426
+ if (typeof value === "object" && value.value) {
1427
+ return `${value.value}`;
1428
+ }
1429
+ return "Object";
1430
+ };
1431
+ const tags = targetArray.map(getLabel).filter(isNotNullable).map((title) => {
1432
+ return `<span class="dx-tag rounded-xl" data-hue="neutral">${title}</span>`;
1433
+ }).join("");
1434
+ cell.accessoryHtml = `<div role='none' class="flex flex-row gap-1 overflow-x-auto">${tags}</div>`;
1435
+ }
1436
+ }
1405
1437
  if (props.format === FormatEnum4.Ref && props.referenceSchema) {
1406
1438
  const targetObj = getValue3(obj, field.path)?.target;
1407
1439
  if (targetObj) {
1408
- cell.accessoryHtml = tableButtons.referencedCell.render({
1409
- targetId: targetObj.id,
1410
- schemaId: props.referenceSchema
1411
- });
1440
+ const dxn = getDXN(targetObj)?.toString();
1441
+ cell.accessoryHtml = `<dx-ref-tag refId=${dxn} class="dx-button block is-6 pli-[3px] plb-[3px] pbe-[2px] min-bs-0 absolute inline-end-1"><dx-icon icon="ph--link-simple--regular"/></dx-ref-tag>`;
1412
1442
  }
1413
1443
  }
1414
1444
  if (props.format === FormatEnum4.Boolean) {
@@ -1442,7 +1472,7 @@ var TablePresentation = class {
1442
1472
  return null;
1443
1473
  }).filter(Boolean).join(" ");
1444
1474
  if (tags) {
1445
- cell.accessoryHtml = tags;
1475
+ cell.accessoryHtml = `<div role='none' class="flex flex-row gap-1">${tags}</div>`;
1446
1476
  }
1447
1477
  }
1448
1478
  }
@@ -1487,7 +1517,7 @@ var TablePresentation = class {
1487
1517
  fieldId: field.id
1488
1518
  })}
1489
1519
  `,
1490
- className: "!bg-gridHeader"
1520
+ className: "!bg-toolbarSurface"
1491
1521
  };
1492
1522
  }
1493
1523
  return cells;
@@ -1538,7 +1568,7 @@ var TablePresentation = class {
1538
1568
  col: 0,
1539
1569
  row: 0
1540
1570
  })]: {
1541
- className: "!bg-gridHeader",
1571
+ className: "!bg-toolbarSurface",
1542
1572
  readonly: true,
1543
1573
  value: ""
1544
1574
  }
@@ -1554,7 +1584,7 @@ var TablePresentation = class {
1554
1584
  header: true,
1555
1585
  checked: this.model.selection.allRowsSeleted.value
1556
1586
  }),
1557
- className: "!bg-gridHeader",
1587
+ className: "!bg-toolbarSurface",
1558
1588
  readonly: true,
1559
1589
  value: ""
1560
1590
  }
@@ -1569,7 +1599,7 @@ var TablePresentation = class {
1569
1599
  accessoryHtml: this.model.features.schemaEditable ? tableButtons.addColumn.render({
1570
1600
  disabled: (this.model.view?.fields?.length ?? 0) >= VIEW_FIELD_LIMIT
1571
1601
  }) : void 0,
1572
- className: "!bg-gridHeader",
1602
+ className: "!bg-toolbarSurface",
1573
1603
  readonly: true,
1574
1604
  value: ""
1575
1605
  }
@@ -1600,14 +1630,116 @@ var cellClassesForRowSelection = (selected, selectionMode) => {
1600
1630
  };
1601
1631
 
1602
1632
  // packages/ui/react-ui-table/src/components/TableCellEditor/TableCellEditor.tsx
1603
- import React6, { useCallback as useCallback3, useMemo as useMemo3, useRef } from "react";
1604
- import { FormatEnum as FormatEnum5 } from "@dxos/echo-schema";
1605
- import { invariant as invariant2 } from "@dxos/invariant";
1633
+ import { useSignals as _useSignals6 } from "@preact-signals/safe-react/tracking";
1634
+ import React6, { useCallback as useCallback4, useMemo as useMemo4, useRef as useRef2 } from "react";
1635
+ import { FormatEnum as FormatEnum5, TypeEnum as TypeEnum4 } from "@dxos/echo-schema";
1636
+ import { invariant as invariant3 } from "@dxos/invariant";
1606
1637
  import { useThemeContext } from "@dxos/react-ui";
1607
1638
  import { createMarkdownExtensions } from "@dxos/react-ui-editor";
1608
- import { cellQuery, editorKeys, parseCellIndex, useGridContext as useGridContext2, GridCellEditor } from "@dxos/react-ui-grid";
1639
+ import { cellQuery, editorKeys, parseCellIndex as parseCellIndex2, useGridContext as useGridContext3, GridCellEditor } from "@dxos/react-ui-grid";
1609
1640
  import { tagPickerExtension, createLinks } from "@dxos/react-ui-tag-picker";
1610
1641
 
1642
+ // packages/ui/react-ui-table/src/components/TableCellEditor/FormCellEditor.tsx
1643
+ import { useSignals as _useSignals5 } from "@preact-signals/safe-react/tracking";
1644
+ import React5, { useCallback as useCallback3, useEffect as useEffect2, useMemo as useMemo3, useRef } from "react";
1645
+ import { getSnapshot } from "@dxos/echo-schema";
1646
+ import { invariant as invariant2 } from "@dxos/invariant";
1647
+ import { Popover as Popover2 } from "@dxos/react-ui";
1648
+ import { Form as Form2 } from "@dxos/react-ui-form";
1649
+ import { parseCellIndex, useGridContext as useGridContext2 } from "@dxos/react-ui-grid";
1650
+ import { getDeep, setDeep } from "@dxos/util";
1651
+ var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-table/src/components/TableCellEditor/FormCellEditor.tsx";
1652
+ var FormCellEditor = ({ fieldProjection, model, schema, __gridScope }) => {
1653
+ var _effect = _useSignals5();
1654
+ try {
1655
+ const { editing, setEditing } = useGridContext2("ArrayEditor", __gridScope);
1656
+ const cellRef = useRef(null);
1657
+ useEffect2(() => {
1658
+ if (editing && editing.cellElement) {
1659
+ cellRef.current = editing.cellElement;
1660
+ }
1661
+ }, [
1662
+ editing?.cellElement
1663
+ ]);
1664
+ const narrowedSchema = useMemo3(() => {
1665
+ if (!schema) {
1666
+ return void 0;
1667
+ }
1668
+ return narrowSchema(schema, [
1669
+ fieldProjection.field.path
1670
+ ]);
1671
+ }, [
1672
+ JSON.stringify(schema),
1673
+ fieldProjection.field.path
1674
+ ]);
1675
+ const originalRow = useMemo3(() => {
1676
+ if (model && editing) {
1677
+ const cell = parseCellIndex(editing.index);
1678
+ const row = model.getRowAt(cell.row);
1679
+ invariant2(row, void 0, {
1680
+ F: __dxlog_file3,
1681
+ L: 47,
1682
+ S: void 0,
1683
+ A: [
1684
+ "row",
1685
+ ""
1686
+ ]
1687
+ });
1688
+ return row;
1689
+ }
1690
+ return void 0;
1691
+ }, [
1692
+ model,
1693
+ editing
1694
+ ]);
1695
+ const formValues = useMemo3(() => {
1696
+ if (originalRow) {
1697
+ return getSnapshot(originalRow);
1698
+ }
1699
+ }, [
1700
+ originalRow
1701
+ ]);
1702
+ const handleSave = useCallback3((values) => {
1703
+ const path = fieldProjection.field.path;
1704
+ const value = getDeep(values, [
1705
+ path
1706
+ ]);
1707
+ setDeep(originalRow, [
1708
+ path
1709
+ ], value);
1710
+ setEditing(null);
1711
+ }, [
1712
+ fieldProjection.field.path,
1713
+ originalRow
1714
+ ]);
1715
+ const handleOpenChange = useCallback3((nextOpen) => {
1716
+ if (nextOpen === false) {
1717
+ setEditing(null);
1718
+ }
1719
+ }, [
1720
+ setEditing
1721
+ ]);
1722
+ if (!editing) {
1723
+ return null;
1724
+ }
1725
+ return /* @__PURE__ */ React5.createElement(Popover2.Root, {
1726
+ open: editing !== null,
1727
+ onOpenChange: handleOpenChange
1728
+ }, /* @__PURE__ */ React5.createElement(Popover2.VirtualTrigger, {
1729
+ virtualRef: cellRef
1730
+ }), /* @__PURE__ */ React5.createElement(Popover2.Content, {
1731
+ tabIndex: -1,
1732
+ classNames: "popover-card-width"
1733
+ }, /* @__PURE__ */ React5.createElement(Popover2.Arrow, null), /* @__PURE__ */ React5.createElement(Form2, {
1734
+ values: formValues,
1735
+ schema: narrowedSchema,
1736
+ onSave: handleSave
1737
+ })));
1738
+ } finally {
1739
+ _effect.f();
1740
+ }
1741
+ };
1742
+
1611
1743
  // packages/ui/react-ui-table/src/components/TableCellEditor/extension.ts
1612
1744
  import { autocompletion, pickedCompletion } from "@codemirror/autocomplete";
1613
1745
  import { EditorView } from "@codemirror/view";
@@ -1648,218 +1780,268 @@ var completion = ({ debug, onQuery, onMatch }) => {
1648
1780
  };
1649
1781
 
1650
1782
  // packages/ui/react-ui-table/src/components/TableCellEditor/TableCellEditor.tsx
1651
- var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-table/src/components/TableCellEditor/TableCellEditor.tsx";
1783
+ var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-table/src/components/TableCellEditor/TableCellEditor.tsx";
1652
1784
  var newValue = Symbol.for("newValue");
1653
1785
  var createOption = (text) => ({
1654
1786
  [newValue]: true,
1655
1787
  text
1656
1788
  });
1657
1789
  var isCreateOption = (data) => typeof data === "object" && data[newValue];
1658
- var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, __gridScope }) => {
1659
- const { id: gridId, editing, setEditing } = useGridContext2("TableCellEditor", __gridScope);
1660
- const suppressNextBlur = useRef(false);
1661
- const { themeMode } = useThemeContext();
1662
- const fieldProjection = useMemo3(() => {
1663
- if (!model || !editing) {
1664
- return;
1790
+ var TableValueEditor = ({ model, modals, schema, onEnter, onFocus, onQuery, __gridScope }) => {
1791
+ var _effect = _useSignals6();
1792
+ try {
1793
+ const { editing } = useGridContext3("TableValueEditor", __gridScope);
1794
+ const fieldProjection = useMemo4(() => {
1795
+ if (!model || !editing) {
1796
+ return;
1797
+ }
1798
+ const { col } = parseCellIndex2(editing.index);
1799
+ const field = model.projection.view.fields[col];
1800
+ const fieldProjection2 = model.projection.getFieldProjection(field.id);
1801
+ invariant3(fieldProjection2, void 0, {
1802
+ F: __dxlog_file4,
1803
+ L: 73,
1804
+ S: void 0,
1805
+ A: [
1806
+ "fieldProjection",
1807
+ ""
1808
+ ]
1809
+ });
1810
+ return fieldProjection2;
1811
+ }, [
1812
+ model,
1813
+ editing
1814
+ ]);
1815
+ if (fieldProjection?.props.type === TypeEnum4.Array) {
1816
+ return /* @__PURE__ */ React6.createElement(FormCellEditor, {
1817
+ fieldProjection,
1818
+ model,
1819
+ schema,
1820
+ __gridScope
1821
+ });
1665
1822
  }
1666
- const { col } = parseCellIndex(editing.index);
1667
- const field = model.projection.view.fields[col];
1668
- const fieldProjection2 = model.projection.getFieldProjection(field.id);
1669
- invariant2(fieldProjection2, void 0, {
1670
- F: __dxlog_file3,
1671
- L: 71,
1672
- S: void 0,
1673
- A: [
1674
- "fieldProjection",
1675
- ""
1676
- ]
1823
+ return /* @__PURE__ */ React6.createElement(TableCellEditor, {
1824
+ model,
1825
+ modals,
1826
+ onEnter,
1827
+ onFocus,
1828
+ onQuery,
1829
+ __gridScope
1677
1830
  });
1678
- return fieldProjection2;
1679
- }, [
1680
- model,
1681
- editing
1682
- ]);
1683
- const handleEnter = useCallback3((value) => {
1684
- if (!model || !editing) {
1685
- return;
1686
- }
1687
- const cell = parseCellIndex(editing.index);
1688
- model.setCellData(cell, value);
1689
- onEnter?.(cell);
1690
- onFocus?.();
1691
- setEditing(null);
1692
- }, [
1693
- model,
1694
- editing,
1695
- onEnter,
1696
- onFocus,
1697
- setEditing
1698
- ]);
1699
- const handleBlur = useCallback3((value) => {
1700
- if (!model || !editing) {
1701
- return;
1702
- }
1703
- if (suppressNextBlur.current) {
1704
- suppressNextBlur.current = false;
1705
- return;
1706
- }
1707
- const cell = parseCellIndex(editing.index);
1708
- if (value !== void 0) {
1831
+ } finally {
1832
+ _effect.f();
1833
+ }
1834
+ };
1835
+ var TableCellEditor = ({ model, modals, onEnter, onFocus, onQuery, __gridScope }) => {
1836
+ var _effect = _useSignals6();
1837
+ try {
1838
+ const { id: gridId, editing, setEditing } = useGridContext3("TableCellEditor", __gridScope);
1839
+ const suppressNextBlur = useRef2(false);
1840
+ const { themeMode } = useThemeContext();
1841
+ const fieldProjection = useMemo4(() => {
1842
+ if (!model || !editing) {
1843
+ return;
1844
+ }
1845
+ const { col } = parseCellIndex2(editing.index);
1846
+ const field = model.projection.view.fields[col];
1847
+ const fieldProjection2 = model.projection.getFieldProjection(field.id);
1848
+ invariant3(fieldProjection2, void 0, {
1849
+ F: __dxlog_file4,
1850
+ L: 114,
1851
+ S: void 0,
1852
+ A: [
1853
+ "fieldProjection",
1854
+ ""
1855
+ ]
1856
+ });
1857
+ return fieldProjection2;
1858
+ }, [
1859
+ model,
1860
+ editing
1861
+ ]);
1862
+ const handleEnter = useCallback4((value) => {
1863
+ if (!model || !editing) {
1864
+ return;
1865
+ }
1866
+ const cell = parseCellIndex2(editing.index);
1709
1867
  model.setCellData(cell, value);
1710
- }
1711
- }, [
1712
- model,
1713
- editing
1714
- ]);
1715
- const handleClose = useCallback3((value, event) => {
1716
- if (!model || !editing || !fieldProjection) {
1717
- return;
1718
- }
1719
- const cell = parseCellIndex(editing.index);
1720
- onEnter?.(cell);
1721
- if (event && onFocus) {
1722
- onFocus(determineNavigationAxis(event), determineNavigationDelta(event));
1723
- }
1724
- }, [
1725
- model,
1726
- editing,
1727
- onFocus,
1728
- onEnter,
1729
- fieldProjection
1730
- ]);
1731
- const extension = useMemo3(() => {
1732
- if (!fieldProjection) {
1733
- return [];
1734
- }
1735
- const extension2 = [
1736
- editorKeys({
1737
- onClose: handleClose,
1738
- ...editing?.initialContent && {
1739
- onNav: handleClose
1740
- }
1741
- })
1742
- ];
1743
- const format = fieldProjection.props.format;
1744
- if (format === FormatEnum5.SingleSelect || format === FormatEnum5.MultiSelect) {
1745
- extension2.push(createMarkdownExtensions({
1746
- themeMode
1747
- }));
1748
- const options = fieldProjection.props.options || [];
1749
- const mode = format === FormatEnum5.SingleSelect ? "single-select" : "multi-select";
1750
- extension2.push(tagPickerExtension({
1751
- mode,
1752
- inGrid: true,
1753
- onSearch: (text, selectedIds) => {
1754
- return options.filter((option) => selectedIds.indexOf(option.id) === -1 && (text.length === 0 || option.title.toLowerCase().includes(text.toLowerCase()))).map((option) => ({
1755
- id: option.id,
1756
- label: option.title,
1757
- hue: option.color
1758
- }));
1759
- },
1760
- onUpdate: (ids) => {
1761
- if (model && editing) {
1762
- if (ids.length === 0) {
1763
- return;
1764
- }
1765
- if (mode === "single-select") {
1766
- handleEnter(ids[0]);
1767
- } else {
1768
- handleEnter(ids);
1868
+ onEnter?.(cell);
1869
+ onFocus?.();
1870
+ setEditing(null);
1871
+ }, [
1872
+ model,
1873
+ editing,
1874
+ onEnter,
1875
+ onFocus,
1876
+ setEditing
1877
+ ]);
1878
+ const handleBlur = useCallback4((value) => {
1879
+ if (!model || !editing) {
1880
+ return;
1881
+ }
1882
+ if (suppressNextBlur.current) {
1883
+ suppressNextBlur.current = false;
1884
+ return;
1885
+ }
1886
+ const cell = parseCellIndex2(editing.index);
1887
+ if (value !== void 0) {
1888
+ model.setCellData(cell, value);
1889
+ }
1890
+ }, [
1891
+ model,
1892
+ editing
1893
+ ]);
1894
+ const handleClose = useCallback4((value, event) => {
1895
+ if (!model || !editing || !fieldProjection) {
1896
+ return;
1897
+ }
1898
+ const cell = parseCellIndex2(editing.index);
1899
+ onEnter?.(cell);
1900
+ if (event && onFocus) {
1901
+ onFocus(determineNavigationAxis(event), determineNavigationDelta(event));
1902
+ }
1903
+ }, [
1904
+ model,
1905
+ editing,
1906
+ onFocus,
1907
+ onEnter,
1908
+ fieldProjection
1909
+ ]);
1910
+ const extension = useMemo4(() => {
1911
+ if (!fieldProjection) {
1912
+ return [];
1913
+ }
1914
+ const extension2 = [
1915
+ editorKeys({
1916
+ onClose: handleClose,
1917
+ ...editing?.initialContent && {
1918
+ onNav: handleClose
1919
+ }
1920
+ })
1921
+ ];
1922
+ const format = fieldProjection.props.format;
1923
+ if (format === FormatEnum5.SingleSelect || format === FormatEnum5.MultiSelect) {
1924
+ extension2.push(createMarkdownExtensions({
1925
+ themeMode
1926
+ }));
1927
+ const options = fieldProjection.props.options || [];
1928
+ const mode = format === FormatEnum5.SingleSelect ? "single-select" : "multi-select";
1929
+ extension2.push(tagPickerExtension({
1930
+ mode,
1931
+ inGrid: true,
1932
+ onSearch: (text, selectedIds) => {
1933
+ return options.filter((option) => selectedIds.indexOf(option.id) === -1 && (text.length === 0 || option.title.toLowerCase().includes(text.toLowerCase()))).map((option) => ({
1934
+ id: option.id,
1935
+ label: option.title,
1936
+ hue: option.color
1937
+ }));
1938
+ },
1939
+ onUpdate: (ids) => {
1940
+ if (model && editing) {
1941
+ if (ids.length === 0) {
1942
+ return;
1943
+ }
1944
+ if (mode === "single-select") {
1945
+ handleEnter(ids[0]);
1946
+ } else {
1947
+ handleEnter(ids);
1948
+ }
1769
1949
  }
1770
1950
  }
1771
- }
1772
- }));
1773
- }
1774
- if (onQuery) {
1775
- switch (fieldProjection.props.format) {
1776
- case FormatEnum5.Ref: {
1777
- extension2.push([
1778
- completion({
1779
- onQuery: (text) => onQuery(fieldProjection, text),
1780
- onMatch: (data) => {
1781
- if (model && editing && modals) {
1782
- if (isCreateOption(data)) {
1783
- const { field, props } = fieldProjection;
1784
- if (props.referenceSchema) {
1785
- suppressNextBlur.current = true;
1786
- modals.openCreateRef(props.referenceSchema, document.querySelector(cellQuery(editing.index, gridId)), {
1787
- [field.referencePath]: data.text
1788
- }, (data2) => {
1789
- handleEnter(data2);
1790
- });
1951
+ }));
1952
+ }
1953
+ if (onQuery) {
1954
+ switch (fieldProjection.props.format) {
1955
+ case FormatEnum5.Ref: {
1956
+ extension2.push([
1957
+ completion({
1958
+ onQuery: (text) => onQuery(fieldProjection, text),
1959
+ onMatch: (data) => {
1960
+ if (model && editing && modals) {
1961
+ if (isCreateOption(data)) {
1962
+ const { field, props } = fieldProjection;
1963
+ if (props.referenceSchema) {
1964
+ suppressNextBlur.current = true;
1965
+ modals.openCreateRef(props.referenceSchema, document.querySelector(cellQuery(editing.index, gridId)), {
1966
+ [field.referencePath]: data.text
1967
+ }, (data2) => {
1968
+ handleEnter(data2);
1969
+ });
1970
+ }
1971
+ } else {
1972
+ handleEnter(data);
1791
1973
  }
1792
- } else {
1793
- handleEnter(data);
1794
1974
  }
1795
1975
  }
1796
- }
1797
- })
1798
- ]);
1799
- break;
1976
+ })
1977
+ ]);
1978
+ break;
1979
+ }
1800
1980
  }
1801
1981
  }
1802
- }
1803
- return extension2;
1804
- }, [
1805
- model,
1806
- modals,
1807
- editing,
1808
- fieldProjection,
1809
- handleClose,
1810
- themeMode
1811
- ]);
1812
- const getCellContent = useCallback3(() => {
1813
- if (model && editing) {
1814
- const cell = parseCellIndex(editing.index);
1815
- const { col } = cell;
1816
- const field = model.projection.view.fields[col];
1817
- const fieldProjection2 = model.projection.getFieldProjection(field.id);
1818
- if (fieldProjection2?.props.format === FormatEnum5.SingleSelect || fieldProjection2?.props.format === FormatEnum5.MultiSelect) {
1819
- const value2 = model.getCellData(cell);
1820
- if (value2 !== void 0) {
1821
- const options = fieldProjection2.props.options || [];
1822
- if (fieldProjection2.props.format === FormatEnum5.MultiSelect && Array.isArray(value2)) {
1823
- const tagItems = value2.map((id) => {
1824
- const option = options.find((o) => o.id === id);
1982
+ return extension2;
1983
+ }, [
1984
+ model,
1985
+ modals,
1986
+ editing,
1987
+ fieldProjection,
1988
+ handleClose,
1989
+ themeMode
1990
+ ]);
1991
+ const getCellContent = useCallback4(() => {
1992
+ if (model && editing) {
1993
+ const cell = parseCellIndex2(editing.index);
1994
+ const { col } = cell;
1995
+ const field = model.projection.view.fields[col];
1996
+ const fieldProjection2 = model.projection.getFieldProjection(field.id);
1997
+ if (fieldProjection2?.props.format === FormatEnum5.SingleSelect || fieldProjection2?.props.format === FormatEnum5.MultiSelect) {
1998
+ const value2 = model.getCellData(cell);
1999
+ if (value2 !== void 0) {
2000
+ const options = fieldProjection2.props.options || [];
2001
+ if (fieldProjection2.props.format === FormatEnum5.MultiSelect && Array.isArray(value2)) {
2002
+ const tagItems = value2.map((id) => {
2003
+ const option = options.find((o) => o.id === id);
2004
+ if (option) {
2005
+ return {
2006
+ id,
2007
+ label: option.title,
2008
+ hue: option.color
2009
+ };
2010
+ }
2011
+ return void 0;
2012
+ }).filter((item) => item !== void 0);
2013
+ return createLinks(tagItems);
2014
+ } else {
2015
+ const option = options.find((o) => o.id === value2);
1825
2016
  if (option) {
1826
- return {
1827
- id,
2017
+ const tagItem = {
2018
+ id: value2,
1828
2019
  label: option.title,
1829
2020
  hue: option.color
1830
2021
  };
2022
+ return createLinks([
2023
+ tagItem
2024
+ ]);
1831
2025
  }
1832
- return void 0;
1833
- }).filter((item) => item !== void 0);
1834
- return createLinks(tagItems);
1835
- } else {
1836
- const option = options.find((o) => o.id === value2);
1837
- if (option) {
1838
- const tagItem = {
1839
- id: value2,
1840
- label: option.title,
1841
- hue: option.color
1842
- };
1843
- return createLinks([
1844
- tagItem
1845
- ]);
1846
2026
  }
1847
2027
  }
2028
+ return "";
1848
2029
  }
1849
- return "";
2030
+ const value = model.getCellData(cell);
2031
+ return value !== void 0 ? String(value) : "";
1850
2032
  }
1851
- const value = model.getCellData(cell);
1852
- return value !== void 0 ? String(value) : "";
1853
- }
1854
- }, [
1855
- model,
1856
- editing
1857
- ]);
1858
- return /* @__PURE__ */ React6.createElement(GridCellEditor, {
1859
- extension,
1860
- getCellContent,
1861
- onBlur: handleBlur
1862
- });
2033
+ }, [
2034
+ model,
2035
+ editing
2036
+ ]);
2037
+ return /* @__PURE__ */ React6.createElement(GridCellEditor, {
2038
+ extension,
2039
+ getCellContent,
2040
+ onBlur: handleBlur
2041
+ });
2042
+ } finally {
2043
+ _effect.f();
2044
+ }
1863
2045
  };
1864
2046
  var determineNavigationAxis = ({ key }) => {
1865
2047
  switch (key) {
@@ -1887,288 +2069,294 @@ var determineNavigationDelta = ({ key, shift }) => {
1887
2069
  };
1888
2070
 
1889
2071
  // packages/ui/react-ui-table/src/components/Table/Table.tsx
1890
- var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-table/src/components/Table/Table.tsx";
1891
- var inlineEndLine = "[&>.dx-grid]:relative [&>.dx-grid]:after:absolute [&>.dx-grid]:after:inset-block-0 [&>.dx-grid]:after:-inline-end-px [&>.dx-grid]:after:is-px [&>.dx-grid]:after:bg-separator";
1892
- var blockEndLine = "[&>.dx-grid]:before:absolute [&>.dx-grid]:before:inset-inline-0 [&>.dx-grid]:before:-block-end-px [&>.dx-grid]:before:bs-px [&>.dx-grid]:before:bg-separator";
2072
+ var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-table/src/components/Table/Table.tsx";
1893
2073
  var TableRoot = ({ children, role }) => {
1894
- return /* @__PURE__ */ React7.createElement("div", {
1895
- role: "none",
1896
- className: mx2("relative !border-separator", role === "section" ? "attention-surface overflow-hidden [&_.dx-grid]:max-is-[--dx-grid-content-inline-size]" : "flex flex-col [&_.dx-grid]:grow [&_.dx-grid]:max-is-[--dx-grid-content-inline-size] [&_.dx-grid]:bs-0 [&_.dx-grid]:max-bs-[--dx-grid-content-block-size]")
1897
- }, children);
2074
+ var _effect = _useSignals7();
2075
+ try {
2076
+ return /* @__PURE__ */ React7.createElement("div", {
2077
+ role: "none",
2078
+ className: mx2("relative !border-separator", role === "section" ? "attention-surface overflow-hidden [&_.dx-grid]:max-is-[--dx-grid-content-inline-size]" : "flex flex-col [&_.dx-grid]:grow [&_.dx-grid]:max-is-[--dx-grid-content-inline-size] [&_.dx-grid]:bs-0 [&_.dx-grid]:max-bs-[--dx-grid-content-block-size]")
2079
+ }, children);
2080
+ } finally {
2081
+ _effect.f();
2082
+ }
1898
2083
  };
1899
- var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttention, onRowClick }, forwardedRef) => {
1900
- const [dxGrid, setDxGrid] = useState2(null);
1901
- const { hasAttention } = useAttention(model?.id ?? "table");
1902
- const { t } = useTranslation3(translationKey);
1903
- const modals = useMemo4(() => new ModalController(), []);
1904
- const frozen = useMemo4(() => {
1905
- const noActionColumn = model?.features.dataEditable === false && model?.features.schemaEditable === false && model.rowActions.length === 0;
1906
- return {
1907
- frozenRowsStart: 1,
1908
- frozenColsStart: model?.features.selection.enabled ? 1 : 0,
1909
- frozenColsEnd: noActionColumn ? 0 : 1
1910
- };
1911
- }, [
1912
- model
1913
- ]);
1914
- useEffect2(() => {
1915
- if (!presentation || !dxGrid) {
1916
- return;
1917
- }
1918
- dxGrid.getCells = (range, plane) => presentation.getCells(range, plane);
1919
- }, [
1920
- presentation,
1921
- dxGrid
1922
- ]);
1923
- useImperativeHandle(forwardedRef, () => {
1924
- if (!presentation || !dxGrid) {
1925
- return {};
1926
- }
1927
- return {
1928
- update: (cell) => {
1929
- if (cell) {
1930
- dxGrid.updateIfWithinBounds(cell);
1931
- } else {
1932
- dxGrid.updateCells(true);
1933
- dxGrid.requestUpdate();
1934
- }
2084
+ var TableMain = /* @__PURE__ */ forwardRef(({ model, presentation, ignoreAttention, schema, onRowClick }, forwardedRef) => {
2085
+ var _effect = _useSignals7();
2086
+ try {
2087
+ const [dxGrid, setDxGrid] = useState2(null);
2088
+ const { hasAttention } = useAttention(model?.id ?? "table");
2089
+ const { t } = useTranslation3(translationKey);
2090
+ const modals = useMemo5(() => new ModalController(), []);
2091
+ const frozen = useMemo5(() => {
2092
+ const noActionColumn = model?.features.dataEditable === false && model?.features.schemaEditable === false && model.rowActions.length === 0;
2093
+ return {
2094
+ frozenRowsStart: 1,
2095
+ frozenColsStart: model?.features.selection.enabled ? 1 : 0,
2096
+ frozenColsEnd: noActionColumn ? 0 : 1
2097
+ };
2098
+ }, [
2099
+ model
2100
+ ]);
2101
+ const getCells = useCallback5((range, plane) => presentation?.getCells(range, plane) ?? {}, [
2102
+ presentation
2103
+ ]);
2104
+ useEffect3(() => {
2105
+ if (!presentation || !dxGrid) {
2106
+ return;
1935
2107
  }
1936
- };
1937
- }, [
1938
- presentation,
1939
- dxGrid
1940
- ]);
1941
- const handleGridClick = useCallback4((event) => {
1942
- const rowIndex = safeParseInt(event.target.ariaRowIndex ?? "");
1943
- if (rowIndex != null) {
1944
- if (onRowClick) {
1945
- const row = model?.getRowAt(rowIndex);
1946
- row && onRowClick(row);
1947
- }
1948
- if (model?.features.selection.enabled && model?.selection.selectionMode === "single") {
1949
- model.selection.toggleSelectionForRowIndex(rowIndex);
2108
+ dxGrid.getCells = getCells;
2109
+ }, [
2110
+ presentation,
2111
+ dxGrid,
2112
+ getCells
2113
+ ]);
2114
+ useImperativeHandle(forwardedRef, () => {
2115
+ if (!presentation || !dxGrid) {
2116
+ return {};
1950
2117
  }
1951
- }
1952
- if (!modals) {
1953
- return;
1954
- }
1955
- const buttonSelector = Object.values(tableButtons).map((button) => `button[${button.attr}]`).join(",");
1956
- const tableButtonElement = event.target.closest(buttonSelector);
1957
- if (tableButtonElement) {
1958
- const button = Object.values(tableButtons).find((btn) => tableButtonElement.hasAttribute(btn.attr));
1959
- if (!button) {
2118
+ return {
2119
+ update: (cell) => {
2120
+ if (cell) {
2121
+ dxGrid.updateIfWithinBounds(cell);
2122
+ } else {
2123
+ dxGrid.updateCells(true);
2124
+ dxGrid.requestUpdate();
2125
+ }
2126
+ }
2127
+ };
2128
+ }, [
2129
+ presentation,
2130
+ dxGrid
2131
+ ]);
2132
+ const handleGridClick = useCallback5((event) => {
2133
+ const rowIndex = safeParseInt(event.target.ariaRowIndex ?? "");
2134
+ if (rowIndex != null) {
2135
+ if (onRowClick) {
2136
+ const row = model?.getRowAt(rowIndex);
2137
+ row && onRowClick(row);
2138
+ }
2139
+ if (model?.features.selection.enabled && model?.selection.selectionMode === "single") {
2140
+ model.selection.toggleSelectionForRowIndex(rowIndex);
2141
+ }
2142
+ }
2143
+ if (!modals) {
1960
2144
  return;
1961
2145
  }
1962
- modals.setTrigger(tableButtonElement);
1963
- const data = button.getData(tableButtonElement);
1964
- switch (data.type) {
1965
- case "rowMenu": {
1966
- modals.showRowMenu(data.rowIndex);
1967
- break;
2146
+ const buttonSelector = Object.values(tableButtons).map((button) => `button[${button.attr}]`).join(",");
2147
+ const tableButtonElement = event.target.closest(buttonSelector);
2148
+ if (tableButtonElement) {
2149
+ const button = Object.values(tableButtons).find((btn) => tableButtonElement.hasAttribute(btn.attr));
2150
+ if (!button) {
2151
+ return;
1968
2152
  }
1969
- case "columnSettings": {
1970
- modals.showColumnMenu(data.fieldId);
1971
- break;
1972
- }
1973
- case "newColumn": {
1974
- modals.showColumnCreator();
1975
- break;
2153
+ modals.setTrigger(tableButtonElement);
2154
+ const data = button.getData(tableButtonElement);
2155
+ switch (data.type) {
2156
+ case "rowMenu": {
2157
+ modals.showRowMenu(data.rowIndex);
2158
+ break;
2159
+ }
2160
+ case "columnSettings": {
2161
+ modals.showColumnMenu(data.fieldId);
2162
+ break;
2163
+ }
2164
+ case "newColumn": {
2165
+ modals.showColumnCreator();
2166
+ break;
2167
+ }
2168
+ case "sort": {
2169
+ model?.sorting?.toggleSort(data.fieldId);
2170
+ break;
2171
+ }
1976
2172
  }
1977
- case "referencedCell": {
1978
- modals.showReferencePanel(data.targetId, data.schemaId);
1979
- break;
2173
+ return;
2174
+ }
2175
+ const controlSelector = Object.values(tableControls).map((control) => `input[${control.attr}]`).join(",");
2176
+ const controlElement = event.target.closest(controlSelector);
2177
+ if (controlElement) {
2178
+ const control = Object.values(tableControls).find((ctrl) => controlElement.hasAttribute(ctrl.attr));
2179
+ if (!control) {
2180
+ return;
1980
2181
  }
1981
- case "sort": {
1982
- model?.sorting?.toggleSort(data.fieldId);
1983
- break;
2182
+ const data = control.getData(controlElement);
2183
+ switch (data.type) {
2184
+ case "checkbox": {
2185
+ if (data.header) {
2186
+ model?.selection.setSelection(model.selection.allRowsSeleted.value ? "none" : "all");
2187
+ } else {
2188
+ model?.selection.toggleSelectionForRowIndex(data.rowIndex);
2189
+ }
2190
+ break;
2191
+ }
2192
+ case "switch": {
2193
+ if (model) {
2194
+ model.updateCellData({
2195
+ row: data.rowIndex,
2196
+ col: data.colIndex
2197
+ }, (value) => !value);
2198
+ }
2199
+ break;
2200
+ }
1984
2201
  }
1985
2202
  }
1986
- return;
1987
- }
1988
- const controlSelector = Object.values(tableControls).map((control) => `input[${control.attr}]`).join(",");
1989
- const controlElement = event.target.closest(controlSelector);
1990
- if (controlElement) {
1991
- const control = Object.values(tableControls).find((ctrl) => controlElement.hasAttribute(ctrl.attr));
1992
- if (!control) {
2203
+ }, [
2204
+ model,
2205
+ modals
2206
+ ]);
2207
+ const handleFocus = useCallback5((increment, delta) => {
2208
+ if (dxGrid) {
2209
+ dxGrid.refocus(increment, delta);
2210
+ }
2211
+ }, [
2212
+ dxGrid
2213
+ ]);
2214
+ const handleEnter = useCallback5((cell) => {
2215
+ if (!model?.features.dataEditable) {
1993
2216
  return;
1994
2217
  }
1995
- const data = control.getData(controlElement);
1996
- switch (data.type) {
1997
- case "checkbox": {
1998
- if (data.header) {
1999
- model?.selection.setSelection(model.selection.allRowsSeleted.value ? "none" : "all");
2000
- } else {
2001
- model?.selection.toggleSelectionForRowIndex(data.rowIndex);
2002
- }
2003
- break;
2218
+ if (model && cell.row === model.getRowCount() - 1) {
2219
+ model.insertRow(cell.row);
2220
+ if (dxGrid) {
2221
+ requestAnimationFrame(() => {
2222
+ dxGrid?.scrollToRow(cell.row + 1);
2223
+ dxGrid?.refocus("row", 1);
2224
+ });
2004
2225
  }
2005
- case "switch": {
2006
- if (model) {
2007
- model.updateCellData({
2008
- row: data.rowIndex,
2009
- col: data.colIndex
2010
- }, (value) => !value);
2011
- }
2226
+ }
2227
+ }, [
2228
+ model,
2229
+ dxGrid
2230
+ ]);
2231
+ const handleKeyDown = useCallback5((event) => {
2232
+ if (!model?.features.dataEditable) {
2233
+ return;
2234
+ }
2235
+ const cell = closestCell(event.target);
2236
+ if (!model || !cell) {
2237
+ return;
2238
+ }
2239
+ switch (event.key) {
2240
+ case "Backspace":
2241
+ case "Delete": {
2242
+ model.setCellData(cell, void 0);
2012
2243
  break;
2013
2244
  }
2014
2245
  }
2015
- }
2016
- }, [
2017
- model,
2018
- modals
2019
- ]);
2020
- const handleFocus = useCallback4((increment, delta) => {
2021
- if (dxGrid) {
2022
- dxGrid.refocus(increment, delta);
2023
- }
2024
- }, [
2025
- dxGrid
2026
- ]);
2027
- const handleEnter = useCallback4((cell) => {
2028
- if (!model?.features.dataEditable) {
2029
- return;
2030
- }
2031
- if (model && cell.row === model.getRowCount() - 1) {
2032
- model.insertRow(cell.row);
2033
- if (dxGrid) {
2034
- requestAnimationFrame(() => {
2035
- dxGrid?.scrollToRow(cell.row + 1);
2036
- dxGrid?.refocus("row", 1);
2037
- });
2246
+ }, [
2247
+ model
2248
+ ]);
2249
+ const handleAxisResize = useCallback5((event) => {
2250
+ if (event.axis === "col") {
2251
+ const columnIndex = parseInt(event.index, 10);
2252
+ model?.setColumnWidth(columnIndex, event.size);
2038
2253
  }
2039
- }
2040
- }, [
2041
- model,
2042
- dxGrid
2043
- ]);
2044
- const handleKeyDown = useCallback4((event) => {
2045
- if (!model?.features.dataEditable) {
2046
- return;
2047
- }
2048
- const cell = closestCell(event.target);
2049
- if (!model || !cell) {
2050
- return;
2051
- }
2052
- switch (event.key) {
2053
- case "Backspace":
2054
- case "Delete": {
2055
- model.setCellData(cell, void 0);
2056
- break;
2254
+ }, [
2255
+ model
2256
+ ]);
2257
+ const handleWheel = useCallback5((event) => {
2258
+ if (!ignoreAttention && !hasAttention) {
2259
+ event.stopPropagation();
2057
2260
  }
2058
- }
2059
- }, [
2060
- model
2061
- ]);
2062
- const handleAxisResize = useCallback4((event) => {
2063
- if (event.axis === "col") {
2064
- const columnIndex = parseInt(event.index, 10);
2065
- model?.setColumnWidth(columnIndex, event.size);
2066
- }
2067
- }, [
2068
- model
2069
- ]);
2070
- const handleWheel = useCallback4((event) => {
2071
- if (!ignoreAttention && !hasAttention) {
2072
- event.stopPropagation();
2073
- }
2074
- }, [
2075
- hasAttention,
2076
- ignoreAttention
2077
- ]);
2078
- const handleNewColumn = useCallback4(() => {
2079
- const columns = model?.getColumnCount();
2080
- if (dxGrid && columns) {
2081
- dxGrid.scrollToColumn(columns - 1);
2082
- }
2083
- }, [
2084
- model,
2085
- dxGrid
2086
- ]);
2087
- const handleQuery = useCallback4(async ({ field, props }, text) => {
2088
- if (model && props.referenceSchema && field.referencePath) {
2089
- const space = model.space;
2090
- invariant3(space, void 0, {
2091
- F: __dxlog_file4,
2092
- L: 312,
2093
- S: void 0,
2094
- A: [
2095
- "space",
2096
- ""
2097
- ]
2098
- });
2099
- const schema = space.db.schemaRegistry.getSchema(props.referenceSchema);
2100
- if (schema) {
2101
- const { objects } = await space.db.query(Filter.schema(schema)).run();
2102
- const options = objects.map((obj) => {
2103
- const value = getValue4(obj, field.referencePath);
2104
- if (!value || typeof value !== "string") {
2105
- return void 0;
2106
- }
2107
- return {
2108
- label: value,
2109
- data: obj
2110
- };
2111
- }).filter(isNotFalsy);
2112
- return [
2113
- ...options,
2114
- {
2115
- label: t("create new object label", {
2116
- text
2117
- }),
2118
- data: createOption(text)
2119
- }
2120
- ];
2261
+ }, [
2262
+ hasAttention,
2263
+ ignoreAttention
2264
+ ]);
2265
+ const handleNewColumn = useCallback5(() => {
2266
+ const columns = model?.getColumnCount();
2267
+ if (dxGrid && columns) {
2268
+ dxGrid.scrollToColumn(columns - 1);
2121
2269
  }
2270
+ }, [
2271
+ model,
2272
+ dxGrid
2273
+ ]);
2274
+ const handleQuery = useCallback5(async ({ field, props }, text) => {
2275
+ if (model && props.referenceSchema && field.referencePath) {
2276
+ const space = model.space;
2277
+ invariant4(space, void 0, {
2278
+ F: __dxlog_file5,
2279
+ L: 309,
2280
+ S: void 0,
2281
+ A: [
2282
+ "space",
2283
+ ""
2284
+ ]
2285
+ });
2286
+ const schema2 = space.db.schemaRegistry.getSchema(props.referenceSchema);
2287
+ if (schema2) {
2288
+ const { objects } = await space.db.query(Filter.type(schema2)).run();
2289
+ const options = objects.map((obj) => {
2290
+ const value = getValue4(obj, field.referencePath);
2291
+ if (!value || typeof value !== "string") {
2292
+ return void 0;
2293
+ }
2294
+ return {
2295
+ label: value,
2296
+ data: obj
2297
+ };
2298
+ }).filter(isNotFalsy);
2299
+ return [
2300
+ ...options,
2301
+ {
2302
+ label: t("create new object label", {
2303
+ text
2304
+ }),
2305
+ data: createOption(text)
2306
+ }
2307
+ ];
2308
+ }
2309
+ }
2310
+ return [];
2311
+ }, [
2312
+ model,
2313
+ t
2314
+ ]);
2315
+ if (!model || !modals) {
2316
+ return /* @__PURE__ */ React7.createElement("span", {
2317
+ role: "none",
2318
+ className: "attention-surface"
2319
+ });
2122
2320
  }
2123
- return [];
2124
- }, [
2125
- model,
2126
- t
2127
- ]);
2128
- if (!model || !modals) {
2129
- return /* @__PURE__ */ React7.createElement("span", {
2130
- role: "none",
2131
- className: "attention-surface"
2132
- });
2321
+ return /* @__PURE__ */ React7.createElement(Grid.Root, {
2322
+ id: model.id ?? "table-grid"
2323
+ }, /* @__PURE__ */ React7.createElement(TableValueEditor, {
2324
+ model,
2325
+ modals,
2326
+ schema,
2327
+ onEnter: handleEnter,
2328
+ onFocus: handleFocus,
2329
+ onQuery: handleQuery
2330
+ }), /* @__PURE__ */ React7.createElement(Grid.Content, {
2331
+ className: mx2("[--dx-grid-base:var(--baseSurface)]", gridSeparatorInlineEnd, gridSeparatorBlockEnd),
2332
+ frozen,
2333
+ // getCells={getCells}
2334
+ columns: model.columnMeta.value,
2335
+ limitRows: model.getRowCount() ?? 0,
2336
+ limitColumns: model.view?.fields?.length ?? 0,
2337
+ overscroll: "trap",
2338
+ onAxisResize: handleAxisResize,
2339
+ onClick: handleGridClick,
2340
+ onKeyDown: handleKeyDown,
2341
+ onWheelCapture: handleWheel,
2342
+ ref: setDxGrid
2343
+ }), /* @__PURE__ */ React7.createElement(RowActionsMenu, {
2344
+ model,
2345
+ modals
2346
+ }), /* @__PURE__ */ React7.createElement(ColumnActionsMenu, {
2347
+ model,
2348
+ modals
2349
+ }), /* @__PURE__ */ React7.createElement(ColumnSettings, {
2350
+ model,
2351
+ modals,
2352
+ onNewColumn: handleNewColumn
2353
+ }), /* @__PURE__ */ React7.createElement(CreateRefPanel, {
2354
+ model,
2355
+ modals
2356
+ }));
2357
+ } finally {
2358
+ _effect.f();
2133
2359
  }
2134
- return /* @__PURE__ */ React7.createElement(Grid.Root, {
2135
- id: model.id ?? "table-grid"
2136
- }, /* @__PURE__ */ React7.createElement(TableCellEditor, {
2137
- model,
2138
- modals,
2139
- onEnter: handleEnter,
2140
- onFocus: handleFocus,
2141
- onQuery: handleQuery
2142
- }), /* @__PURE__ */ React7.createElement(Grid.Content, {
2143
- className: mx2("[--dx-grid-base:var(--surface-bg)]", inlineEndLine, blockEndLine),
2144
- frozen,
2145
- // getCells={getCells}
2146
- columns: model.columnMeta.value,
2147
- limitRows: model.getRowCount() ?? 0,
2148
- limitColumns: model.view?.fields?.length ?? 0,
2149
- overscroll: "trap",
2150
- onAxisResize: handleAxisResize,
2151
- onClick: handleGridClick,
2152
- onKeyDown: handleKeyDown,
2153
- onWheelCapture: handleWheel,
2154
- ref: setDxGrid
2155
- }), /* @__PURE__ */ React7.createElement(RowActionsMenu, {
2156
- model,
2157
- modals
2158
- }), /* @__PURE__ */ React7.createElement(ColumnActionsMenu, {
2159
- model,
2160
- modals
2161
- }), /* @__PURE__ */ React7.createElement(ColumnSettings, {
2162
- model,
2163
- modals,
2164
- onNewColumn: handleNewColumn
2165
- }), /* @__PURE__ */ React7.createElement(CreateRefPanel, {
2166
- model,
2167
- modals
2168
- }), /* @__PURE__ */ React7.createElement(RefPanel, {
2169
- model,
2170
- modals
2171
- }));
2172
2360
  });
2173
2361
  var Table = {
2174
2362
  Root: TableRoot,
@@ -2176,152 +2364,167 @@ var Table = {
2176
2364
  };
2177
2365
 
2178
2366
  // packages/ui/react-ui-table/src/components/Table/DynamicTable.tsx
2179
- import React8, { useRef as useRef2, useMemo as useMemo5, useCallback as useCallback5 } from "react";
2367
+ import { useSignals as _useSignals9 } from "@preact-signals/safe-react/tracking";
2368
+ import React8, { useRef as useRef3, useMemo as useMemo6, useCallback as useCallback6 } from "react";
2180
2369
  import { useDefaultValue } from "@dxos/react-ui";
2181
2370
  import { mx as mx3 } from "@dxos/react-ui-theme";
2182
2371
 
2183
2372
  // packages/ui/react-ui-table/src/hooks/useTableModel.ts
2373
+ import { useSignals as _useSignals8 } from "@preact-signals/safe-react/tracking";
2184
2374
  import { effect as effect3 } from "@preact/signals-core";
2185
- import { useEffect as useEffect3, useState as useState3 } from "react";
2375
+ import { useEffect as useEffect4, useState as useState3 } from "react";
2186
2376
  import { fullyQualifiedId, getSpace } from "@dxos/react-client/echo";
2187
2377
  import { useSelectionActions } from "@dxos/react-ui-attention";
2188
2378
  import { isNonNullable } from "@dxos/util";
2189
2379
  var useTableModel = ({ table, projection, rows, rowActions, features, onSelectionChanged, onRowAction, ...props }) => {
2190
- const [model, setModel] = useState3();
2191
- useEffect3(() => {
2192
- if (!table || !projection) {
2193
- return;
2194
- }
2195
- let model2;
2196
- const t = setTimeout(async () => {
2197
- model2 = new TableModel({
2198
- id: fullyQualifiedId(table),
2199
- space: getSpace(table),
2200
- view: table.view?.target,
2201
- projection,
2202
- features,
2203
- rowActions,
2204
- onRowAction,
2205
- ...props
2380
+ var _effect = _useSignals8();
2381
+ try {
2382
+ const [model, setModel] = useState3();
2383
+ useEffect4(() => {
2384
+ if (!table || !projection) {
2385
+ return;
2386
+ }
2387
+ let model2;
2388
+ const t = setTimeout(async () => {
2389
+ model2 = new TableModel({
2390
+ id: fullyQualifiedId(table),
2391
+ space: getSpace(table),
2392
+ view: table.view?.target,
2393
+ projection,
2394
+ features,
2395
+ rowActions,
2396
+ onRowAction,
2397
+ ...props
2398
+ });
2399
+ await model2.open();
2400
+ setModel(model2);
2206
2401
  });
2207
- await model2.open();
2208
- setModel(model2);
2209
- });
2210
- return () => {
2211
- clearTimeout(t);
2212
- void model2?.close();
2213
- };
2214
- }, [
2215
- table,
2216
- projection,
2217
- table?.view?.target,
2218
- features,
2219
- rowActions
2220
- ]);
2221
- useEffect3(() => {
2222
- if (rows) {
2223
- model?.setRows(rows);
2224
- }
2225
- }, [
2226
- model,
2227
- rows
2228
- ]);
2229
- const { select, clear } = useSelectionActions([
2230
- table?.id,
2231
- table?.view?.target?.query.typename
2232
- ].filter(isNonNullable));
2233
- useEffect3(() => {
2234
- if (!model) {
2235
- return;
2236
- }
2237
- const unsubscribe = effect3(() => {
2238
- const selectedItems = [
2239
- ...model.selection.selection.value
2240
- ];
2241
- select(selectedItems);
2242
- onSelectionChanged?.(selectedItems);
2243
- });
2244
- return () => {
2245
- clear();
2246
- unsubscribe();
2247
- };
2248
- }, [
2249
- model,
2250
- onSelectionChanged
2251
- ]);
2252
- return model;
2402
+ return () => {
2403
+ clearTimeout(t);
2404
+ void model2?.close();
2405
+ };
2406
+ }, [
2407
+ table,
2408
+ projection,
2409
+ table?.view?.target,
2410
+ features,
2411
+ rowActions
2412
+ ]);
2413
+ useEffect4(() => {
2414
+ if (rows) {
2415
+ model?.setRows(rows);
2416
+ }
2417
+ }, [
2418
+ model,
2419
+ rows
2420
+ ]);
2421
+ const { multiSelect, clear } = useSelectionActions([
2422
+ table?.id,
2423
+ table?.view?.target?.query.typename
2424
+ ].filter(isNonNullable));
2425
+ useEffect4(() => {
2426
+ if (!model) {
2427
+ return;
2428
+ }
2429
+ const unsubscribe = effect3(() => {
2430
+ const selectedItems = [
2431
+ ...model.selection.selection.value
2432
+ ];
2433
+ multiSelect(selectedItems);
2434
+ onSelectionChanged?.(selectedItems);
2435
+ });
2436
+ return () => {
2437
+ clear();
2438
+ unsubscribe();
2439
+ };
2440
+ }, [
2441
+ model,
2442
+ onSelectionChanged
2443
+ ]);
2444
+ return model;
2445
+ } finally {
2446
+ _effect.f();
2447
+ }
2253
2448
  };
2254
2449
 
2255
2450
  // packages/ui/react-ui-table/src/components/Table/DynamicTable.tsx
2256
2451
  var DynamicTable = ({ classNames, name = "example.com/dynamic-table", rows, properties, jsonSchema, schema, rowActions, onRowClick, onRowAction, ...props }) => {
2257
- const { table, projection } = useMemo5(() => {
2258
- const props2 = getBaseSchems({
2259
- typename: name,
2452
+ var _effect = _useSignals9();
2453
+ try {
2454
+ const { table, projection } = useMemo6(() => {
2455
+ const props2 = getBaseSchema({
2456
+ typename: name,
2457
+ properties,
2458
+ jsonSchema,
2459
+ schema
2460
+ });
2461
+ return makeDynamicTable({
2462
+ ...props2,
2463
+ properties
2464
+ });
2465
+ }, [
2466
+ name,
2260
2467
  properties,
2261
- jsonSchema,
2262
- schema
2263
- });
2264
- return makeDynamicTable({
2265
- ...props2,
2266
- properties
2468
+ schema,
2469
+ jsonSchema
2470
+ ]);
2471
+ const tableRef = useRef3(null);
2472
+ const handleCellUpdate = useCallback6((cell) => {
2473
+ tableRef.current?.update?.(cell);
2474
+ }, []);
2475
+ const handleRowOrderChange = useCallback6(() => {
2476
+ tableRef.current?.update?.();
2477
+ }, []);
2478
+ const features = useDefaultValue(props.features, () => ({
2479
+ selection: {
2480
+ enabled: false
2481
+ },
2482
+ dataEditable: false
2483
+ }));
2484
+ const model = useTableModel({
2485
+ table,
2486
+ rows,
2487
+ projection,
2488
+ features,
2489
+ rowActions,
2490
+ onCellUpdate: handleCellUpdate,
2491
+ onRowOrderChange: handleRowOrderChange,
2492
+ onRowAction
2267
2493
  });
2268
- }, [
2269
- name,
2270
- properties,
2271
- schema,
2272
- jsonSchema
2273
- ]);
2274
- const tableRef = useRef2(null);
2275
- const handleCellUpdate = useCallback5((cell) => {
2276
- tableRef.current?.update?.(cell);
2277
- }, []);
2278
- const handleRowOrderChange = useCallback5(() => {
2279
- tableRef.current?.update?.();
2280
- }, []);
2281
- const features = useDefaultValue(props.features, () => ({
2282
- selection: {
2283
- enabled: false
2284
- },
2285
- dataEditable: false
2286
- }));
2287
- const model = useTableModel({
2288
- table,
2289
- rows,
2290
- projection,
2291
- features,
2292
- rowActions,
2293
- onCellUpdate: handleCellUpdate,
2294
- onRowOrderChange: handleRowOrderChange,
2295
- onRowAction
2296
- });
2297
- const presentation = useMemo5(() => {
2298
- if (model) {
2299
- return new TablePresentation(model);
2300
- }
2301
- }, [
2302
- model
2303
- ]);
2304
- return /* @__PURE__ */ React8.createElement("div", {
2305
- role: "none",
2306
- className: mx3("is-full bs-full grow grid", classNames)
2307
- }, /* @__PURE__ */ React8.createElement("div", {
2308
- role: "none",
2309
- className: "grid min-bs-0 overflow-hidden"
2310
- }, /* @__PURE__ */ React8.createElement(Table.Root, null, /* @__PURE__ */ React8.createElement(Table.Main, {
2311
- ref: tableRef,
2312
- model,
2313
- presentation,
2314
- ignoreAttention: true,
2315
- onRowClick
2316
- }))));
2494
+ const presentation = useMemo6(() => {
2495
+ if (model) {
2496
+ return new TablePresentation(model);
2497
+ }
2498
+ }, [
2499
+ model
2500
+ ]);
2501
+ return /* @__PURE__ */ React8.createElement("div", {
2502
+ role: "none",
2503
+ className: mx3("is-full bs-full grow grid", classNames)
2504
+ }, /* @__PURE__ */ React8.createElement("div", {
2505
+ role: "none",
2506
+ className: "grid min-bs-0 overflow-hidden"
2507
+ }, /* @__PURE__ */ React8.createElement(Table.Root, null, /* @__PURE__ */ React8.createElement(Table.Main, {
2508
+ ref: tableRef,
2509
+ model,
2510
+ presentation,
2511
+ ignoreAttention: true,
2512
+ onRowClick
2513
+ }))));
2514
+ } finally {
2515
+ _effect.f();
2516
+ }
2317
2517
  };
2318
2518
 
2319
2519
  // packages/ui/react-ui-table/src/components/TableToolbar/TableToolbar.tsx
2320
- import React9, { useCallback as useCallback6, useMemo as useMemo6 } from "react";
2321
- import { create as create4 } from "@dxos/live-object";
2520
+ import { useSignals as _useSignals10 } from "@preact-signals/safe-react/tracking";
2521
+ import { Rx } from "@effect-rx/rx-react";
2522
+ import React9, { useMemo as useMemo7 } from "react";
2523
+ import { live as live4 } from "@dxos/live-object";
2322
2524
  import { createGapSeparator, createMenuAction, MenuProvider, ToolbarMenu, useMenuActions } from "@dxos/react-ui-menu";
2323
- var createTableToolbarActions = (state) => {
2324
- const add = createMenuAction("add-row", {
2525
+ import { rxFromSignal } from "@dxos/react-ui-menu";
2526
+ var createTableToolbarActions = ({ state, onAdd, onSave, customActions }) => Rx.make((get) => {
2527
+ const add = createMenuAction("add-row", onAdd, {
2325
2528
  type: "add-row",
2326
2529
  icon: "ph--plus--regular",
2327
2530
  label: [
@@ -2332,7 +2535,7 @@ var createTableToolbarActions = (state) => {
2332
2535
  ],
2333
2536
  testId: "table.toolbar.add-row"
2334
2537
  });
2335
- const save = createMenuAction("save-view", {
2538
+ const save = createMenuAction("save-view", onSave, {
2336
2539
  type: "save-view",
2337
2540
  icon: "ph--floppy-disk--regular",
2338
2541
  label: [
@@ -2343,49 +2546,55 @@ var createTableToolbarActions = (state) => {
2343
2546
  ],
2344
2547
  testId: "table.toolbar.save-view",
2345
2548
  iconOnly: false,
2346
- hidden: !state.viewDirty
2549
+ hidden: get(rxFromSignal(() => !state.viewDirty))
2347
2550
  });
2348
2551
  const gap = createGapSeparator();
2349
- const comment = createMenuAction("comment", {
2350
- type: "comment",
2351
- icon: "ph--chat-text--regular",
2352
- label: [
2353
- "create comment",
2354
- {
2355
- ns: translationKey
2356
- }
2357
- ],
2358
- testId: "table.toolbar.comment"
2359
- });
2360
2552
  const nodes = [
2361
2553
  add,
2362
2554
  save,
2363
- ...gap.nodes,
2364
- comment
2555
+ ...gap.nodes
2365
2556
  ];
2557
+ const edges = nodes.map(({ id: target }) => ({
2558
+ source: "root",
2559
+ target
2560
+ }));
2561
+ if (customActions) {
2562
+ const custom = get(customActions);
2563
+ nodes.push(...custom.nodes);
2564
+ edges.push(...custom.edges);
2565
+ }
2366
2566
  return {
2367
2567
  nodes,
2368
- edges: nodes.map(({ id: target }) => ({
2369
- source: "root",
2370
- target
2371
- }))
2568
+ edges
2372
2569
  };
2373
- };
2374
- var TableToolbar = ({ classNames, viewDirty, attendableId, onAction }) => {
2375
- const state = useMemo6(() => create4({
2376
- viewDirty
2377
- }), []);
2378
- const actionsCreator = useCallback6(() => createTableToolbarActions(state), [
2379
- state
2380
- ]);
2381
- const menu = useMenuActions(actionsCreator);
2382
- return /* @__PURE__ */ React9.createElement(MenuProvider, {
2383
- ...menu,
2384
- attendableId,
2385
- onAction
2386
- }, /* @__PURE__ */ React9.createElement(ToolbarMenu, {
2387
- classNames
2388
- }));
2570
+ });
2571
+ var TableToolbar = ({ classNames, viewDirty, attendableId, onAdd, onSave, customActions }) => {
2572
+ var _effect = _useSignals10();
2573
+ try {
2574
+ const state = useMemo7(() => live4({
2575
+ viewDirty
2576
+ }), []);
2577
+ const actionsCreator = useMemo7(() => createTableToolbarActions({
2578
+ state,
2579
+ onAdd,
2580
+ onSave,
2581
+ customActions
2582
+ }), [
2583
+ state,
2584
+ onAdd,
2585
+ onSave,
2586
+ customActions
2587
+ ]);
2588
+ const menu = useMenuActions(actionsCreator);
2589
+ return /* @__PURE__ */ React9.createElement(MenuProvider, {
2590
+ ...menu,
2591
+ attendableId
2592
+ }, /* @__PURE__ */ React9.createElement(ToolbarMenu, {
2593
+ classNames
2594
+ }));
2595
+ } finally {
2596
+ _effect.f();
2597
+ }
2389
2598
  };
2390
2599
  export {
2391
2600
  BUTTON_IDENTIFIERS,
@@ -2401,9 +2610,10 @@ export {
2401
2610
  TableToolbar,
2402
2611
  TableType,
2403
2612
  cellClassesForRowSelection,
2404
- getBaseSchems,
2613
+ getBaseSchema,
2405
2614
  initializeTable,
2406
2615
  makeDynamicTable,
2616
+ narrowSchema,
2407
2617
  tableButtons,
2408
2618
  tableControls,
2409
2619
  touch,