@dxos/react-ui-table 0.7.2 → 0.7.3-staging.0905f03

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 (75) hide show
  1. package/dist/lib/browser/{chunk-EWGUNGJC.mjs → chunk-IYCSJDMB.mjs} +5 -3
  2. package/dist/lib/browser/chunk-IYCSJDMB.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +461 -237
  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 +3 -1
  7. package/dist/lib/node/{chunk-A2N7XWW6.cjs → chunk-MHBMVCFZ.cjs} +8 -5
  8. package/dist/lib/node/chunk-MHBMVCFZ.cjs.map +7 -0
  9. package/dist/lib/node/index.cjs +471 -253
  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 +4 -2
  13. package/dist/lib/node/types/index.cjs.map +2 -2
  14. package/dist/lib/node-esm/{chunk-SABDOZ6I.mjs → chunk-BMWGPXPL.mjs} +5 -3
  15. package/dist/lib/node-esm/chunk-BMWGPXPL.mjs.map +7 -0
  16. package/dist/lib/node-esm/index.mjs +461 -237
  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 +3 -1
  20. package/dist/types/src/_deprecated/components/Table/Table.stories.d.ts.map +1 -1
  21. package/dist/types/src/components/Table/ColumnActionsMenu.d.ts.map +1 -1
  22. package/dist/types/src/components/Table/ColumnSettings.d.ts +2 -1
  23. package/dist/types/src/components/Table/ColumnSettings.d.ts.map +1 -1
  24. package/dist/types/src/components/Table/CreateRefPanel.d.ts +8 -0
  25. package/dist/types/src/components/Table/CreateRefPanel.d.ts.map +1 -0
  26. package/dist/types/src/components/Table/RefPanel.d.ts +8 -0
  27. package/dist/types/src/components/Table/RefPanel.d.ts.map +1 -0
  28. package/dist/types/src/components/Table/RowActionsMenu.d.ts.map +1 -1
  29. package/dist/types/src/components/Table/Table.d.ts +2 -2
  30. package/dist/types/src/components/Table/Table.d.ts.map +1 -1
  31. package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts +16 -7
  32. package/dist/types/src/components/TableCellEditor/TableCellEditor.d.ts.map +1 -1
  33. package/dist/types/src/components/TableCellEditor/extension.d.ts +2 -1
  34. package/dist/types/src/components/TableCellEditor/extension.d.ts.map +1 -1
  35. package/dist/types/src/components/testing.d.ts +1 -1
  36. package/dist/types/src/components/testing.d.ts.map +1 -1
  37. package/dist/types/src/model/modal-controller.d.ts +11 -0
  38. package/dist/types/src/model/modal-controller.d.ts.map +1 -1
  39. package/dist/types/src/model/table-model.d.ts +4 -5
  40. package/dist/types/src/model/table-model.d.ts.map +1 -1
  41. package/dist/types/src/translations.d.ts +1 -0
  42. package/dist/types/src/translations.d.ts.map +1 -1
  43. package/dist/types/src/types/table.d.ts +57 -2
  44. package/dist/types/src/types/table.d.ts.map +1 -1
  45. package/dist/types/src/util/index.d.ts +0 -1
  46. package/dist/types/src/util/index.d.ts.map +1 -1
  47. package/dist/types/src/util/table-buttons.d.ts +8 -0
  48. package/dist/types/src/util/table-buttons.d.ts.map +1 -1
  49. package/package.json +29 -28
  50. package/src/_deprecated/components/Table/Table.stories.tsx +1 -1
  51. package/src/components/Table/ColumnActionsMenu.tsx +0 -1
  52. package/src/components/Table/ColumnSettings.tsx +7 -4
  53. package/src/components/Table/CreateRefPanel.tsx +83 -0
  54. package/src/components/Table/RefPanel.tsx +52 -0
  55. package/src/components/Table/RowActionsMenu.tsx +1 -2
  56. package/src/components/Table/Table.stories.tsx +1 -1
  57. package/src/components/Table/Table.tsx +60 -33
  58. package/src/components/TableCellEditor/TableCellEditor.stories.tsx +1 -1
  59. package/src/components/TableCellEditor/TableCellEditor.tsx +72 -23
  60. package/src/components/TableCellEditor/extension.ts +3 -4
  61. package/src/components/testing.ts +2 -1
  62. package/src/model/modal-controller.ts +43 -0
  63. package/src/model/table-model.test.ts +5 -3
  64. package/src/model/table-model.ts +34 -22
  65. package/src/playwright/smoke.spec.ts +0 -4
  66. package/src/translations.ts +1 -0
  67. package/src/types/table.ts +5 -5
  68. package/src/util/index.ts +0 -1
  69. package/src/util/table-buttons.ts +18 -1
  70. package/dist/lib/browser/chunk-EWGUNGJC.mjs.map +0 -7
  71. package/dist/lib/node/chunk-A2N7XWW6.cjs.map +0 -7
  72. package/dist/lib/node-esm/chunk-SABDOZ6I.mjs.map +0 -7
  73. package/dist/types/src/util/grid.d.ts +0 -14
  74. package/dist/types/src/util/grid.d.ts.map +0 -1
  75. package/src/util/grid.ts +0 -23
@@ -29,62 +29,74 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
29
29
  var node_exports = {};
30
30
  __export(node_exports, {
31
31
  Table: () => Table,
32
- TableType: () => import_chunk_A2N7XWW6.TableType,
32
+ TableSchema: () => import_chunk_MHBMVCFZ.TableSchema,
33
+ TableType: () => import_chunk_MHBMVCFZ.TableType,
33
34
  Toolbar: () => Toolbar,
34
- fromGridCell: () => fromGridCell,
35
35
  initializeTable: () => initializeTable,
36
36
  tableButtons: () => tableButtons,
37
- toGridCell: () => toGridCell,
38
37
  touch: () => touch,
39
38
  translations: () => translations_default,
40
39
  useTableModel: () => useTableModel,
41
40
  useToolbarContext: () => useToolbarContext
42
41
  });
43
42
  module.exports = __toCommonJS(node_exports);
44
- var import_chunk_A2N7XWW6 = require("./chunk-A2N7XWW6.cjs");
43
+ var import_chunk_MHBMVCFZ = require("./chunk-MHBMVCFZ.cjs");
45
44
  var import_react = __toESM(require("react"));
46
45
  var import_echo_schema = require("@dxos/echo-schema");
47
46
  var import_invariant = require("@dxos/invariant");
48
47
  var import_echo = require("@dxos/react-client/echo");
48
+ var import_react_ui = require("@dxos/react-ui");
49
49
  var import_react_ui_attention = require("@dxos/react-ui-attention");
50
50
  var import_react_ui_grid = require("@dxos/react-ui-grid");
51
51
  var import_react_ui_theme = require("@dxos/react-ui-theme");
52
52
  var import_util = require("@dxos/util");
53
53
  var import_react2 = __toESM(require("react"));
54
- var import_react_ui = require("@dxos/react-ui");
54
+ var import_react_ui2 = require("@dxos/react-ui");
55
55
  var import_react3 = __toESM(require("react"));
56
56
  var import_echo2 = require("@dxos/react-client/echo");
57
- var import_react_ui2 = require("@dxos/react-ui");
57
+ var import_react_ui3 = require("@dxos/react-ui");
58
58
  var import_react_ui_form = require("@dxos/react-ui-form");
59
59
  var import_react4 = __toESM(require("react"));
60
- var import_react_ui3 = require("@dxos/react-ui");
61
- var import_react5 = __toESM(require("react"));
62
60
  var import_echo_schema2 = require("@dxos/echo-schema");
63
- var import_invariant2 = require("@dxos/invariant");
61
+ var import_echo3 = require("@dxos/react-client/echo");
62
+ var import_react_ui4 = require("@dxos/react-ui");
63
+ var import_react_ui_form2 = require("@dxos/react-ui-form");
64
64
  var import_react_ui_grid2 = require("@dxos/react-ui-grid");
65
+ var import_react5 = __toESM(require("react"));
66
+ var import_echo4 = require("@dxos/react-client/echo");
67
+ var import_react_ui5 = require("@dxos/react-ui");
68
+ var import_react_ui_form3 = require("@dxos/react-ui-form");
69
+ var import_react6 = __toESM(require("react"));
70
+ var import_react_ui6 = require("@dxos/react-ui");
71
+ var import_react7 = __toESM(require("react"));
72
+ var import_echo_schema3 = require("@dxos/echo-schema");
73
+ var import_invariant2 = require("@dxos/invariant");
74
+ var import_react_ui_grid3 = require("@dxos/react-ui-grid");
65
75
  var import_autocomplete = require("@codemirror/autocomplete");
66
76
  var import_view = require("@codemirror/view");
67
- var import_echo_schema3 = require("@dxos/echo-schema");
68
- var import_log = require("@dxos/log");
69
- var import_react_client = require("@dxos/react-client");
70
- var import_echo3 = require("@dxos/react-client/echo");
71
- var import_schema = require("@dxos/schema");
72
77
  var import_react_context = require("@radix-ui/react-context");
73
- var import_react6 = __toESM(require("react"));
74
- var import_react_ui4 = require("@dxos/react-ui");
75
- var import_react7 = __toESM(require("react"));
76
- var import_react_ui5 = require("@dxos/react-ui");
77
- var import_react8 = require("react");
78
+ var import_react8 = __toESM(require("react"));
79
+ var import_react_ui7 = require("@dxos/react-ui");
80
+ var import_react9 = __toESM(require("react"));
81
+ var import_react_ui8 = require("@dxos/react-ui");
82
+ var import_react10 = require("react");
78
83
  var import_signals_core = require("@preact/signals-core");
79
84
  var import_lodash = __toESM(require("lodash.orderby"));
80
85
  var import_context = require("@dxos/context");
81
86
  var import_echo_schema4 = require("@dxos/echo-schema");
82
87
  var import_invariant3 = require("@dxos/invariant");
83
- var import_react_client2 = require("@dxos/react-client");
84
- var import_react_ui_form2 = require("@dxos/react-ui-form");
88
+ var import_react_client = require("@dxos/react-client");
89
+ var import_react_ui_form4 = require("@dxos/react-ui-form");
90
+ var import_react_ui_grid4 = require("@dxos/react-ui-grid");
85
91
  var import_react_ui_theme2 = require("@dxos/react-ui-theme");
86
- var import_schema2 = require("@dxos/schema");
92
+ var import_schema = require("@dxos/schema");
87
93
  var import_signals_core2 = require("@preact/signals-core");
94
+ var import_log = require("@dxos/log");
95
+ var import_echo_schema5 = require("@dxos/echo-schema");
96
+ var import_log2 = require("@dxos/log");
97
+ var import_react_client2 = require("@dxos/react-client");
98
+ var import_echo5 = require("@dxos/react-client/echo");
99
+ var import_schema2 = require("@dxos/schema");
88
100
  var import_signals_core3 = require("@preact/signals-core");
89
101
  var import_context2 = require("@dxos/context");
90
102
  var translationKey = "table";
@@ -110,49 +122,53 @@ var translations_default = [
110
122
  "delete row label": "Delete row",
111
123
  "bulk delete row label": "Delete selected rows",
112
124
  "column deleted label": "Column deleted",
113
- "new column button label": "Create column"
125
+ "new column button label": "Create column",
126
+ "create new object label": "Create new object \u201C{{text}}\u201D"
114
127
  }
115
128
  }
116
129
  }
117
130
  ];
118
131
  var ColumnActionsMenu = ({ model }) => {
119
- const { t } = (0, import_react_ui.useTranslation)(translationKey);
132
+ const { t } = (0, import_react_ui2.useTranslation)(translationKey);
120
133
  const state = model?.modalController.state.value;
121
134
  if (!model || state?.type !== "column") {
122
135
  return null;
123
136
  }
124
137
  const currentSort = model.sorting;
125
138
  const isCurrentColumnSorted = currentSort?.fieldId === state.fieldId;
126
- return /* @__PURE__ */ import_react2.default.createElement(import_react_ui.DropdownMenu.Root, {
139
+ return /* @__PURE__ */ import_react2.default.createElement(import_react_ui2.DropdownMenu.Root, {
127
140
  modal: false,
128
141
  open: state?.type === "column",
129
142
  onOpenChange: model.modalController.close
130
- }, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.DropdownMenu.VirtualTrigger, {
143
+ }, /* @__PURE__ */ import_react2.default.createElement(import_react_ui2.DropdownMenu.VirtualTrigger, {
131
144
  virtualRef: model.modalController.trigger
132
- }), /* @__PURE__ */ import_react2.default.createElement(import_react_ui.DropdownMenu.Portal, null, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.DropdownMenu.Content, null, /* @__PURE__ */ import_react2.default.createElement(import_react_ui.DropdownMenu.Viewport, null, (!isCurrentColumnSorted || currentSort?.direction === "asc") && /* @__PURE__ */ import_react2.default.createElement(import_react_ui.DropdownMenu.Item, {
145
+ }), /* @__PURE__ */ import_react2.default.createElement(import_react_ui2.DropdownMenu.Portal, null, /* @__PURE__ */ import_react2.default.createElement(import_react_ui2.DropdownMenu.Content, null, /* @__PURE__ */ import_react2.default.createElement(import_react_ui2.DropdownMenu.Viewport, null, (!isCurrentColumnSorted || currentSort?.direction === "asc") && /* @__PURE__ */ import_react2.default.createElement(import_react_ui2.DropdownMenu.Item, {
133
146
  "data-testid": "column-sort-descending",
134
147
  onClick: () => model.setSort(state.fieldId, "desc")
135
- }, t("column action sort descending")), (!isCurrentColumnSorted || currentSort?.direction === "desc") && /* @__PURE__ */ import_react2.default.createElement(import_react_ui.DropdownMenu.Item, {
148
+ }, t("column action sort descending")), (!isCurrentColumnSorted || currentSort?.direction === "desc") && /* @__PURE__ */ import_react2.default.createElement(import_react_ui2.DropdownMenu.Item, {
136
149
  "data-testid": "column-sort-ascending",
137
150
  onClick: () => model.setSort(state.fieldId, "asc")
138
- }, t("column action sort ascending")), isCurrentColumnSorted && /* @__PURE__ */ import_react2.default.createElement(import_react_ui.DropdownMenu.Item, {
151
+ }, t("column action sort ascending")), isCurrentColumnSorted && /* @__PURE__ */ import_react2.default.createElement(import_react_ui2.DropdownMenu.Item, {
139
152
  "data-testid": "column-clear-sort",
140
153
  onClick: () => model.clearSort()
141
- }, t("column action clear sorting")), model.getColumnCount() > 1 && /* @__PURE__ */ import_react2.default.createElement(import_react_ui.DropdownMenu.Item, {
154
+ }, t("column action clear sorting")), model.getColumnCount() > 1 && /* @__PURE__ */ import_react2.default.createElement(import_react_ui2.DropdownMenu.Item, {
142
155
  "data-testid": "column-delete",
143
156
  onClick: () => model.deleteColumn(state.fieldId)
144
- }, t("column action delete")), /* @__PURE__ */ import_react2.default.createElement(import_react_ui.DropdownMenu.Item, {
157
+ }, t("column action delete")), /* @__PURE__ */ import_react2.default.createElement(import_react_ui2.DropdownMenu.Item, {
145
158
  "data-testid": "column-settings",
146
159
  onClick: () => model.modalController.openColumnSettings()
147
- }, t("column action settings"))), /* @__PURE__ */ import_react2.default.createElement(import_react_ui.DropdownMenu.Arrow, null))));
160
+ }, t("column action settings"))), /* @__PURE__ */ import_react2.default.createElement(import_react_ui2.DropdownMenu.Arrow, null))));
148
161
  };
149
- var ColumnSettings = ({ model }) => {
162
+ var ColumnSettings = ({ model, onNewColumn }) => {
150
163
  const [newField, setNewField] = (0, import_react3.useState)();
151
164
  const state = model?.modalController.state.value;
152
165
  const space = (0, import_echo2.getSpace)(model?.table);
153
166
  (0, import_react3.useEffect)(() => {
154
167
  if (state?.type === "columnSettings" && state.mode.type === "create" && model?.projection) {
155
168
  setNewField(model.projection.createFieldProjection());
169
+ requestAnimationFrame(() => {
170
+ onNewColumn();
171
+ });
156
172
  } else {
157
173
  setNewField(void 0);
158
174
  }
@@ -173,7 +189,7 @@ var ColumnSettings = ({ model }) => {
173
189
  state
174
190
  ]);
175
191
  const field = existingField ?? newField;
176
- const handleClose = (0, import_react3.useCallback)(() => {
192
+ const handleSave = (0, import_react3.useCallback)(() => {
177
193
  model?.modalController.close();
178
194
  }, [
179
195
  model?.modalController
@@ -190,41 +206,136 @@ var ColumnSettings = ({ model }) => {
190
206
  if (!model?.table?.view || !model.projection || !field) {
191
207
  return null;
192
208
  }
193
- return /* @__PURE__ */ import_react3.default.createElement(import_react_ui2.DropdownMenu.Root, {
209
+ return /* @__PURE__ */ import_react3.default.createElement(import_react_ui3.DropdownMenu.Root, {
194
210
  modal: false,
195
211
  open: state?.type === "columnSettings"
196
- }, /* @__PURE__ */ import_react3.default.createElement(import_react_ui2.DropdownMenu.VirtualTrigger, {
212
+ }, /* @__PURE__ */ import_react3.default.createElement(import_react_ui3.DropdownMenu.VirtualTrigger, {
197
213
  virtualRef: model.modalController.trigger
198
- }), /* @__PURE__ */ import_react3.default.createElement(import_react_ui2.DropdownMenu.Portal, null, /* @__PURE__ */ import_react3.default.createElement(import_react_ui2.DropdownMenu.Content, {
214
+ }), /* @__PURE__ */ import_react3.default.createElement(import_react_ui3.DropdownMenu.Portal, null, /* @__PURE__ */ import_react3.default.createElement(import_react_ui3.DropdownMenu.Content, {
199
215
  classNames: "md:is-64"
200
- }, /* @__PURE__ */ import_react3.default.createElement(import_react_ui2.DropdownMenu.Viewport, null, /* @__PURE__ */ import_react3.default.createElement(import_react_ui_form.FieldEditor, {
216
+ }, /* @__PURE__ */ import_react3.default.createElement(import_react_ui3.DropdownMenu.Viewport, null, /* @__PURE__ */ import_react3.default.createElement(import_react_ui_form.FieldEditor, {
201
217
  view: model.table.view,
202
218
  projection: model.projection,
203
219
  field,
204
220
  registry: space?.db.schemaRegistry,
205
- onClose: handleClose,
221
+ onSave: handleSave,
206
222
  onCancel: handleCancel
207
- })), /* @__PURE__ */ import_react3.default.createElement(import_react_ui2.DropdownMenu.Arrow, null))));
223
+ })), /* @__PURE__ */ import_react3.default.createElement(import_react_ui3.DropdownMenu.Arrow, null))));
224
+ };
225
+ var CreateRefPanel = ({ model, __gridScope }) => {
226
+ const { id: gridId } = (0, import_react_ui_grid2.useGridContext)("TableCellEditor", __gridScope);
227
+ const space = (0, import_echo3.getSpace)(model?.table);
228
+ const state = model?.modalController.state.value;
229
+ const schema = (0, import_react4.useMemo)(() => {
230
+ if (!space || state?.type !== "createRefPanel") {
231
+ return;
232
+ }
233
+ const schema2 = space.db.schemaRegistry.getSchema(state.typename)?.schema;
234
+ if (schema2) {
235
+ const omit = import_echo_schema2.S.omit("id");
236
+ return omit(schema2);
237
+ }
238
+ }, [
239
+ space,
240
+ state
241
+ ]);
242
+ const handleSave = (0, import_react4.useCallback)((values) => {
243
+ if (!model || !space || state?.type !== "createRefPanel") {
244
+ return;
245
+ }
246
+ const schema2 = space.db.schemaRegistry.getSchema(state.typename)?.schema;
247
+ if (schema2) {
248
+ const obj = space.db.add((0, import_echo3.create)(schema2, values));
249
+ state.onCreate?.(obj);
250
+ }
251
+ void model.modalController.close();
252
+ }, [
253
+ model?.modalController,
254
+ space,
255
+ state
256
+ ]);
257
+ const handleCancel = (0, import_react4.useCallback)(() => {
258
+ if (model) {
259
+ model.modalController.close();
260
+ }
261
+ }, [
262
+ model?.modalController
263
+ ]);
264
+ if (!model?.table?.view || !model.projection) {
265
+ return null;
266
+ }
267
+ return /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Popover.Root, {
268
+ modal: false,
269
+ open: state?.type === "createRefPanel" && !!schema,
270
+ onOpenChange: (nextOpen) => {
271
+ if (model && !nextOpen) {
272
+ return model.modalController.close();
273
+ }
274
+ }
275
+ }, /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Popover.VirtualTrigger, {
276
+ virtualRef: model.modalController.trigger
277
+ }), /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Popover.Portal, null, /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Popover.Content, {
278
+ classNames: "md:is-64",
279
+ "data-grid": gridId
280
+ }, state?.type === "createRefPanel" && schema && /* @__PURE__ */ import_react4.default.createElement(import_react_ui_form2.Form, {
281
+ schema,
282
+ values: state.initialValues ?? {},
283
+ onSave: handleSave,
284
+ onCancel: handleCancel
285
+ }), /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Popover.Arrow, null))));
286
+ };
287
+ var getRefTargetObj = (space, id) => {
288
+ if (space && id) {
289
+ return space?.db.getObjectById(id);
290
+ } else {
291
+ return void 0;
292
+ }
293
+ };
294
+ var RefPanel = ({ model }) => {
295
+ const state = model?.modalController.state.value;
296
+ const space = (0, import_echo4.getSpace)(model?.table);
297
+ const targetObj = getRefTargetObj(space, state?.type === "refPanel" ? state.targetId : void 0);
298
+ const schema = space && state?.type === "refPanel" ? space.db.schemaRegistry.getSchema(state.typename) : void 0;
299
+ if (!model?.table?.view || !model.projection) {
300
+ return null;
301
+ }
302
+ return /* @__PURE__ */ import_react5.default.createElement(import_react_ui5.Popover.Root, {
303
+ modal: false,
304
+ open: state?.type === "refPanel" && !!targetObj && !!schema,
305
+ onOpenChange: (nextOpen) => {
306
+ if (model && !nextOpen) {
307
+ return model.modalController.close();
308
+ }
309
+ }
310
+ }, /* @__PURE__ */ import_react5.default.createElement(import_react_ui5.Popover.VirtualTrigger, {
311
+ virtualRef: model.modalController.trigger
312
+ }), /* @__PURE__ */ import_react5.default.createElement(import_react_ui5.Popover.Portal, null, /* @__PURE__ */ import_react5.default.createElement(import_react_ui5.Popover.Content, {
313
+ classNames: "md:is-64"
314
+ }, targetObj && schema && /* @__PURE__ */ import_react5.default.createElement(import_react_ui_form3.Form, {
315
+ readonly: true,
316
+ values: targetObj,
317
+ schema
318
+ }), /* @__PURE__ */ import_react5.default.createElement(import_react_ui5.Popover.Arrow, null))));
208
319
  };
209
320
  var RowActionsMenu = ({ model }) => {
210
- const { t } = (0, import_react_ui3.useTranslation)(translationKey);
211
- const state = model.modalController.state.value;
321
+ const { t } = (0, import_react_ui6.useTranslation)(translationKey);
212
322
  const hasSelection = model.selection.hasSelection.value;
323
+ const state = model.modalController.state.value;
213
324
  if (state?.type !== "row") {
214
325
  return null;
215
326
  }
216
- return /* @__PURE__ */ import_react4.default.createElement(import_react_ui3.DropdownMenu.Root, {
327
+ return /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.DropdownMenu.Root, {
217
328
  modal: false,
218
329
  open: true,
219
330
  onOpenChange: model.modalController.close
220
- }, /* @__PURE__ */ import_react4.default.createElement(import_react_ui3.DropdownMenu.VirtualTrigger, {
331
+ }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.DropdownMenu.VirtualTrigger, {
221
332
  virtualRef: model.modalController.trigger
222
- }), /* @__PURE__ */ import_react4.default.createElement(import_react_ui3.DropdownMenu.Content, null, /* @__PURE__ */ import_react4.default.createElement(import_react_ui3.DropdownMenu.Viewport, null, /* @__PURE__ */ import_react4.default.createElement(import_react_ui3.DropdownMenu.Item, {
333
+ }), /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.DropdownMenu.Content, null, /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.DropdownMenu.Viewport, null, /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.DropdownMenu.Item, {
223
334
  "data-testid": "row-menu-delete",
224
335
  onClick: () => model.deleteRow(state.rowIndex)
225
- }, t(hasSelection ? "bulk delete row label" : "delete row label"))), /* @__PURE__ */ import_react4.default.createElement(import_react_ui3.DropdownMenu.Arrow, null)));
336
+ }, t(hasSelection ? "bulk delete row label" : "delete row label"))), /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.DropdownMenu.Arrow, null)));
226
337
  };
227
- var completion = ({ onQuery, onMatch }) => {
338
+ var completion = ({ debug, onQuery, onMatch }) => {
228
339
  return [
229
340
  import_view.EditorView.theme({
230
341
  ".cm-completionDialog": {
@@ -234,6 +345,7 @@ var completion = ({ onQuery, onMatch }) => {
234
345
  (0, import_autocomplete.autocompletion)({
235
346
  icons: false,
236
347
  activateOnTyping: true,
348
+ closeOnBlur: !debug,
237
349
  override: [
238
350
  async (context) => {
239
351
  const text = context.state.doc.toString();
@@ -258,133 +370,26 @@ var completion = ({ onQuery, onMatch }) => {
258
370
  })
259
371
  ];
260
372
  };
261
- var fromGridCell = ({ col, row }) => {
262
- return `${col},${row}`;
263
- };
264
- var toGridCell = (cell) => {
265
- const [col, row] = cell.split(",").map(Number);
266
- return {
267
- row,
268
- col
269
- };
270
- };
271
- var touch = (value) => value;
272
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-table/src/util/table.ts";
273
- var initializeTable = ({ space, table, initialRow = true }) => {
274
- import_log.log.info("initializeTable", {
275
- table
276
- }, {
277
- F: __dxlog_file,
278
- L: 32,
279
- S: void 0,
280
- C: (f, a) => f(...a)
281
- });
282
- const ContactSchema = (0, import_echo_schema3.TypedObject)({
283
- typename: `example.com/type/${import_react_client.PublicKey.random().truncate()}`,
284
- version: "0.1.0"
285
- })({
286
- name: import_echo_schema3.S.optional(import_echo_schema3.S.String).annotations({
287
- [import_echo_schema3.AST.TitleAnnotationId]: "Name"
288
- }),
289
- email: import_echo_schema3.S.optional(import_echo_schema3.Format.Email),
290
- salary: import_echo_schema3.S.optional(import_echo_schema3.Format.Currency()).annotations({
291
- [import_echo_schema3.AST.TitleAnnotationId]: "Salary"
292
- })
293
- });
294
- const contactSchema = space.db.schemaRegistry.addSchema(ContactSchema);
295
- table.view = (0, import_schema.createView)({
296
- name: "Test",
297
- typename: contactSchema.typename,
298
- jsonSchema: contactSchema.jsonSchema,
299
- fields: [
300
- "name",
301
- "email",
302
- "salary"
303
- ]
304
- });
305
- const projection = new import_schema.ViewProjection(contactSchema, table.view);
306
- projection.setFieldProjection({
307
- field: {
308
- id: table.view.fields[2].id,
309
- path: "salary",
310
- size: 150
311
- }
312
- });
313
- projection.setFieldProjection({
314
- field: {
315
- id: (0, import_schema.createFieldId)(),
316
- path: "manager",
317
- referencePath: "name"
318
- },
319
- props: {
320
- property: "manager",
321
- type: import_echo_schema3.TypeEnum.Ref,
322
- format: import_echo_schema3.FormatEnum.Ref,
323
- referenceSchema: contactSchema.typename,
324
- title: "Manager"
325
- }
326
- });
327
- if (initialRow) {
328
- space.db.add((0, import_echo3.create)(contactSchema, {}));
329
- }
330
- return contactSchema;
331
- };
332
- var TABLE_ATTRS = {
333
- columnSettings: "data-table-column-settings-button",
334
- rowMenu: "data-table-row-menu-button",
335
- newColumn: "data-table-new-column-button"
336
- };
337
- var ICONS = {
338
- columnSettings: "ph--caret-down--regular",
339
- rowMenu: "ph--dots-three--regular",
340
- newColumn: "ph--plus--regular"
341
- };
342
- var createButtonHtml = ({ button, value = "", disabled = false, testId }) => {
343
- const buttonClasses = "ch-button is-6 pli-0.5 min-bs-0 absolute inset-block-1 inline-end-2";
344
- return `<button class="${buttonClasses}" ${TABLE_ATTRS[button]}="${value}" data-testid="${testId}" ${disabled ? "disabled" : ""}><svg><use href="/icons.svg#${ICONS[button]}"/></svg></button>`;
345
- };
346
- var tableButtons = {
347
- columnSettings: {
348
- attr: TABLE_ATTRS.columnSettings,
349
- icon: ICONS.columnSettings,
350
- render: ({ fieldId }) => createButtonHtml({
351
- button: "columnSettings",
352
- value: fieldId,
353
- testId: "table-column-settings-button"
354
- })
355
- },
356
- rowMenu: {
357
- attr: TABLE_ATTRS.rowMenu,
358
- icon: ICONS.rowMenu,
359
- render: ({ rowIndex }) => createButtonHtml({
360
- button: "rowMenu",
361
- value: rowIndex.toString(),
362
- testId: "table-row-menu-button"
363
- })
364
- },
365
- addColumn: {
366
- attr: TABLE_ATTRS.newColumn,
367
- icon: ICONS.newColumn,
368
- render: ({ disabled } = {}) => createButtonHtml({
369
- button: "newColumn",
370
- disabled,
371
- testId: "table-new-column-button"
372
- })
373
- }
374
- };
375
- var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-table/src/components/TableCellEditor/TableCellEditor.tsx";
373
+ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-table/src/components/TableCellEditor/TableCellEditor.tsx";
374
+ var newValue = Symbol.for("newValue");
375
+ var createOption = (text) => ({
376
+ [newValue]: true,
377
+ text
378
+ });
379
+ var isCreateOption = (data) => typeof data === "object" && data[newValue];
376
380
  var TableCellEditor = ({ model, onEnter, onFocus, onQuery, __gridScope }) => {
377
- const { editing } = (0, import_react_ui_grid2.useGridContext)("TableCellEditor", __gridScope);
378
- const fieldProjection = (0, import_react5.useMemo)(() => {
381
+ const { id: gridId, editing, setEditing } = (0, import_react_ui_grid3.useGridContext)("TableCellEditor", __gridScope);
382
+ const suppressNextBlur = (0, import_react7.useRef)(false);
383
+ const fieldProjection = (0, import_react7.useMemo)(() => {
379
384
  if (!model || !editing) {
380
385
  return;
381
386
  }
382
- const { col } = toGridCell(editing.index);
387
+ const { col } = (0, import_react_ui_grid3.parseCellIndex)(editing.index);
383
388
  const field = model.projection.view.fields[col];
384
389
  const fieldProjection2 = model.projection.getFieldProjection(field.id);
385
390
  (0, import_invariant2.invariant)(fieldProjection2, void 0, {
386
- F: __dxlog_file2,
387
- L: 49,
391
+ F: __dxlog_file,
392
+ L: 65,
388
393
  S: void 0,
389
394
  A: [
390
395
  "fieldProjection",
@@ -396,29 +401,28 @@ var TableCellEditor = ({ model, onEnter, onFocus, onQuery, __gridScope }) => {
396
401
  model,
397
402
  editing
398
403
  ]);
399
- const handleClose = (0, import_react5.useCallback)((value, event) => {
400
- if (!model || !editing || !fieldProjection) {
404
+ const handleEnter = (0, import_react7.useCallback)((value) => {
405
+ if (!model || !editing) {
401
406
  return;
402
407
  }
403
- const cell = toGridCell(editing.index);
408
+ const cell = (0, import_react_ui_grid3.parseCellIndex)(editing.index);
409
+ model.setCellData(cell, value);
404
410
  onEnter?.(cell);
405
- if (event && onFocus) {
406
- onFocus(determineNavigationAxis(event), determineNavigationDelta(event));
407
- }
411
+ onFocus?.();
412
+ setEditing(null);
408
413
  }, [
409
414
  model,
410
- editing,
411
- onFocus,
412
- onEnter,
413
- fieldProjection,
414
- determineNavigationAxis,
415
- determineNavigationDelta
415
+ editing
416
416
  ]);
417
- const handleBlur = (0, import_react5.useCallback)((value) => {
417
+ const handleBlur = (0, import_react7.useCallback)((value) => {
418
418
  if (!model || !editing) {
419
419
  return;
420
420
  }
421
- const cell = toGridCell(editing.index);
421
+ if (suppressNextBlur.current) {
422
+ suppressNextBlur.current = false;
423
+ return;
424
+ }
425
+ const cell = (0, import_react_ui_grid3.parseCellIndex)(editing.index);
422
426
  if (value !== void 0) {
423
427
  model.setCellData(cell, value);
424
428
  }
@@ -426,12 +430,30 @@ var TableCellEditor = ({ model, onEnter, onFocus, onQuery, __gridScope }) => {
426
430
  model,
427
431
  editing
428
432
  ]);
429
- const extension = (0, import_react5.useMemo)(() => {
433
+ const handleClose = (0, import_react7.useCallback)((value, event) => {
434
+ if (!model || !editing || !fieldProjection) {
435
+ return;
436
+ }
437
+ const cell = (0, import_react_ui_grid3.parseCellIndex)(editing.index);
438
+ onEnter?.(cell);
439
+ if (event && onFocus) {
440
+ onFocus(determineNavigationAxis(event), determineNavigationDelta(event));
441
+ }
442
+ }, [
443
+ model,
444
+ editing,
445
+ onFocus,
446
+ onEnter,
447
+ fieldProjection,
448
+ determineNavigationAxis,
449
+ determineNavigationDelta
450
+ ]);
451
+ const extension = (0, import_react7.useMemo)(() => {
430
452
  if (!fieldProjection) {
431
453
  return [];
432
454
  }
433
455
  const extension2 = [
434
- (0, import_react_ui_grid2.editorKeys)({
456
+ (0, import_react_ui_grid3.editorKeys)({
435
457
  onClose: handleClose,
436
458
  ...editing?.initialContent && {
437
459
  onNav: handleClose
@@ -440,16 +462,25 @@ var TableCellEditor = ({ model, onEnter, onFocus, onQuery, __gridScope }) => {
440
462
  ];
441
463
  if (onQuery) {
442
464
  switch (fieldProjection.props.format) {
443
- case import_echo_schema2.FormatEnum.Ref: {
465
+ case import_echo_schema3.FormatEnum.Ref: {
444
466
  extension2.push([
445
467
  completion({
446
468
  onQuery: (text) => onQuery(fieldProjection, text),
447
469
  onMatch: (data) => {
448
470
  if (model && editing) {
449
- const cell = toGridCell(editing.index);
450
- model.setCellData(cell, data);
451
- onEnter?.(cell);
452
- onFocus?.();
471
+ if (isCreateOption(data)) {
472
+ const { field, props } = fieldProjection;
473
+ if (props.referenceSchema) {
474
+ suppressNextBlur.current = true;
475
+ model.modalController.openCreateRef(props.referenceSchema, document.querySelector((0, import_react_ui_grid3.cellQuery)(editing.index, gridId)), {
476
+ [field.referencePath]: data.text
477
+ }, (data2) => {
478
+ handleEnter(data2);
479
+ });
480
+ }
481
+ } else {
482
+ handleEnter(data);
483
+ }
453
484
  }
454
485
  }
455
486
  })
@@ -465,16 +496,16 @@ var TableCellEditor = ({ model, onEnter, onFocus, onQuery, __gridScope }) => {
465
496
  fieldProjection,
466
497
  handleClose
467
498
  ]);
468
- const getCellContent = (0, import_react5.useCallback)(() => {
499
+ const getCellContent = (0, import_react7.useCallback)(() => {
469
500
  if (model && editing) {
470
- const value = model.getCellData(toGridCell(editing.index));
501
+ const value = model.getCellData((0, import_react_ui_grid3.parseCellIndex)(editing.index));
471
502
  return value !== void 0 ? String(value) : "";
472
503
  }
473
504
  }, [
474
505
  model,
475
506
  editing
476
507
  ]);
477
- return /* @__PURE__ */ import_react5.default.createElement(import_react_ui_grid2.GridCellEditor, {
508
+ return /* @__PURE__ */ import_react7.default.createElement(import_react_ui_grid3.GridCellEditor, {
478
509
  extension,
479
510
  getCellContent,
480
511
  onBlur: handleBlur
@@ -504,7 +535,7 @@ var determineNavigationDelta = ({ key, shift }) => {
504
535
  }
505
536
  return shift ? -1 : 1;
506
537
  };
507
- var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-table/src/components/Table/Table.tsx";
538
+ var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-table/src/components/Table/Table.tsx";
508
539
  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";
509
540
  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";
510
541
  var frozen = {
@@ -521,6 +552,7 @@ var TableRoot = ({ children, role }) => {
521
552
  var TableMain = /* @__PURE__ */ (0, import_react.forwardRef)(({ model, ignoreAttention }, forwardedRef) => {
522
553
  const [dxGrid, setDxGrid] = (0, import_react.useState)(null);
523
554
  const { hasAttention } = (0, import_react_ui_attention.useAttention)(model?.table ? (0, import_echo.fullyQualifiedId)(model.table) : "table");
555
+ const { t } = (0, import_react_ui.useTranslation)(translationKey);
524
556
  (0, import_react.useImperativeHandle)(forwardedRef, () => {
525
557
  if (!model || !dxGrid) {
526
558
  return {};
@@ -539,15 +571,26 @@ var TableMain = /* @__PURE__ */ (0, import_react.forwardRef)(({ model, ignoreAtt
539
571
  model,
540
572
  dxGrid
541
573
  ]);
542
- const handleFocus = (increment, delta) => {
543
- dxGrid?.refocus(increment, delta);
544
- };
574
+ const handleFocus = (0, import_react.useCallback)((increment, delta) => {
575
+ if (dxGrid) {
576
+ dxGrid.refocus(increment, delta);
577
+ }
578
+ }, [
579
+ dxGrid
580
+ ]);
545
581
  const handleEnter = (0, import_react.useCallback)((cell) => {
546
582
  if (model && cell.row === model.getRowCount() - 1) {
547
583
  model.insertRow(cell.row);
584
+ if (dxGrid) {
585
+ requestAnimationFrame(() => {
586
+ dxGrid?.scrollToRow(cell.row + 1);
587
+ dxGrid?.refocus("row", 1);
588
+ });
589
+ }
548
590
  }
549
591
  }, [
550
- model
592
+ model,
593
+ dxGrid
551
594
  ]);
552
595
  const handleKeyDown = (0, import_react.useCallback)((event) => {
553
596
  const cell = (0, import_react_ui_grid.closestCell)(event.target);
@@ -580,12 +623,21 @@ var TableMain = /* @__PURE__ */ (0, import_react.forwardRef)(({ model, ignoreAtt
580
623
  hasAttention,
581
624
  ignoreAttention
582
625
  ]);
583
- const handleQuery = (0, import_react.useCallback)(async ({ field, props }, _text) => {
626
+ const handleNewColumn = (0, import_react.useCallback)(() => {
627
+ const columns = model?.getColumnCount();
628
+ if (dxGrid && columns) {
629
+ dxGrid.scrollToColumn(columns - 1);
630
+ }
631
+ }, [
632
+ model,
633
+ dxGrid
634
+ ]);
635
+ const handleQuery = (0, import_react.useCallback)(async ({ field, props }, text) => {
584
636
  if (model && props.referenceSchema && field.referencePath) {
585
637
  const space = (0, import_echo.getSpace)(model.table);
586
638
  (0, import_invariant.invariant)(space, void 0, {
587
- F: __dxlog_file3,
588
- L: 158,
639
+ F: __dxlog_file2,
640
+ L: 180,
589
641
  S: void 0,
590
642
  A: [
591
643
  "space",
@@ -595,7 +647,7 @@ var TableMain = /* @__PURE__ */ (0, import_react.forwardRef)(({ model, ignoreAtt
595
647
  const schema = space.db.schemaRegistry.getSchema(props.referenceSchema);
596
648
  if (schema) {
597
649
  const { objects } = await space.db.query(import_echo.Filter.schema(schema)).run();
598
- return objects.map((obj) => {
650
+ const options = objects.map((obj) => {
599
651
  const value = (0, import_echo_schema.getValue)(obj, field.referencePath);
600
652
  if (!value || typeof value !== "string") {
601
653
  return void 0;
@@ -605,6 +657,15 @@ var TableMain = /* @__PURE__ */ (0, import_react.forwardRef)(({ model, ignoreAtt
605
657
  data: obj
606
658
  };
607
659
  }).filter(import_util.isNotFalsy);
660
+ return [
661
+ ...options,
662
+ {
663
+ label: t("create new object label", {
664
+ text
665
+ }),
666
+ data: createOption(text)
667
+ }
668
+ ];
608
669
  }
609
670
  }
610
671
  return [];
@@ -617,7 +678,7 @@ var TableMain = /* @__PURE__ */ (0, import_react.forwardRef)(({ model, ignoreAtt
617
678
  className: "attention-surface"
618
679
  });
619
680
  }
620
- return /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement(import_react_ui_grid.Grid.Root, {
681
+ return /* @__PURE__ */ import_react.default.createElement(import_react_ui_grid.Grid.Root, {
621
682
  id: model.table.id ?? "table-grid"
622
683
  }, /* @__PURE__ */ import_react.default.createElement(TableCellEditor, {
623
684
  model,
@@ -636,11 +697,16 @@ var TableMain = /* @__PURE__ */ (0, import_react.forwardRef)(({ model, ignoreAtt
636
697
  onKeyDown: handleKeyDown,
637
698
  overscroll: "trap",
638
699
  ref: setDxGrid
639
- })), /* @__PURE__ */ import_react.default.createElement(RowActionsMenu, {
700
+ }), /* @__PURE__ */ import_react.default.createElement(RowActionsMenu, {
640
701
  model
641
702
  }), /* @__PURE__ */ import_react.default.createElement(ColumnActionsMenu, {
642
703
  model
643
704
  }), /* @__PURE__ */ import_react.default.createElement(ColumnSettings, {
705
+ model,
706
+ onNewColumn: handleNewColumn
707
+ }), /* @__PURE__ */ import_react.default.createElement(RefPanel, {
708
+ model
709
+ }), /* @__PURE__ */ import_react.default.createElement(CreateRefPanel, {
644
710
  model
645
711
  }));
646
712
  });
@@ -653,29 +719,29 @@ var tooltipProps = {
653
719
  side: "top",
654
720
  classNames: "z-10"
655
721
  };
656
- var ToolbarSeparator = () => /* @__PURE__ */ import_react7.default.createElement("div", {
722
+ var ToolbarSeparator = () => /* @__PURE__ */ import_react9.default.createElement("div", {
657
723
  role: "separator",
658
724
  className: "grow"
659
725
  });
660
726
  var ToolbarButton = ({ icon, children, ...props }) => {
661
- return /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.Tooltip.Root, null, /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.Tooltip.Trigger, {
727
+ return /* @__PURE__ */ import_react9.default.createElement(import_react_ui8.Tooltip.Root, null, /* @__PURE__ */ import_react9.default.createElement(import_react_ui8.Tooltip.Trigger, {
662
728
  asChild: true
663
- }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.Toolbar.Button, {
729
+ }, /* @__PURE__ */ import_react9.default.createElement(import_react_ui8.Toolbar.Button, {
664
730
  variant: "ghost",
665
731
  ...props,
666
732
  classNames: buttonStyles
667
- }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.Icon, {
733
+ }, /* @__PURE__ */ import_react9.default.createElement(import_react_ui8.Icon, {
668
734
  icon,
669
735
  size: 5
670
- }), /* @__PURE__ */ import_react7.default.createElement("span", {
736
+ }), /* @__PURE__ */ import_react9.default.createElement("span", {
671
737
  className: "sr-only"
672
- }, children))), /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.Tooltip.Portal, null, /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.Tooltip.Content, tooltipProps, children, /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.Tooltip.Arrow, null))));
738
+ }, children))), /* @__PURE__ */ import_react9.default.createElement(import_react_ui8.Tooltip.Portal, null, /* @__PURE__ */ import_react9.default.createElement(import_react_ui8.Tooltip.Content, tooltipProps, children, /* @__PURE__ */ import_react9.default.createElement(import_react_ui8.Tooltip.Arrow, null))));
673
739
  };
674
740
  var [ToolbarContextProvider, useToolbarContext] = (0, import_react_context.createContext)("Toolbar");
675
741
  var ToolbarRoot = ({ classNames, children, onAction }) => {
676
- return /* @__PURE__ */ import_react6.default.createElement(ToolbarContextProvider, {
742
+ return /* @__PURE__ */ import_react8.default.createElement(ToolbarContextProvider, {
677
743
  onAction
678
- }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui4.Toolbar.Root, {
744
+ }, /* @__PURE__ */ import_react8.default.createElement(import_react_ui7.Toolbar.Root, {
679
745
  classNames: [
680
746
  "is-full shrink-0 overflow-x-auto overflow-y-hidden p-1 attention-surface",
681
747
  classNames
@@ -684,8 +750,8 @@ var ToolbarRoot = ({ classNames, children, onAction }) => {
684
750
  };
685
751
  var Editing = () => {
686
752
  const { onAction } = useToolbarContext("Editing");
687
- const { t } = (0, import_react_ui4.useTranslation)(translationKey);
688
- return /* @__PURE__ */ import_react6.default.createElement(import_react6.default.Fragment, null, /* @__PURE__ */ import_react6.default.createElement(ToolbarButton, {
753
+ const { t } = (0, import_react_ui7.useTranslation)(translationKey);
754
+ return /* @__PURE__ */ import_react8.default.createElement(import_react8.default.Fragment, null, /* @__PURE__ */ import_react8.default.createElement(ToolbarButton, {
689
755
  value: "add-row",
690
756
  icon: "ph--plus--regular",
691
757
  "data-testid": "table.toolbar.add-row",
@@ -696,8 +762,8 @@ var Editing = () => {
696
762
  };
697
763
  var Actions = () => {
698
764
  const { onAction } = useToolbarContext("Actions");
699
- const { t } = (0, import_react_ui4.useTranslation)(translationKey);
700
- return /* @__PURE__ */ import_react6.default.createElement(import_react6.default.Fragment, null, /* @__PURE__ */ import_react6.default.createElement(ToolbarButton, {
765
+ const { t } = (0, import_react_ui7.useTranslation)(translationKey);
766
+ return /* @__PURE__ */ import_react8.default.createElement(import_react8.default.Fragment, null, /* @__PURE__ */ import_react8.default.createElement(ToolbarButton, {
701
767
  value: "comment",
702
768
  icon: "ph--chat-text--regular",
703
769
  "data-testid": "table.toolbar.comment",
@@ -712,6 +778,122 @@ var Toolbar = {
712
778
  Actions,
713
779
  Separator: ToolbarSeparator
714
780
  };
781
+ var touch = (value) => value;
782
+ var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-table/src/util/table.ts";
783
+ var initializeTable = ({ space, table, initialRow = true }) => {
784
+ import_log2.log.info("initializeTable", {
785
+ table
786
+ }, {
787
+ F: __dxlog_file3,
788
+ L: 32,
789
+ S: void 0,
790
+ C: (f, a) => f(...a)
791
+ });
792
+ const ContactSchema = (0, import_echo_schema5.TypedObject)({
793
+ typename: `example.com/type/${import_react_client2.PublicKey.random().truncate()}`,
794
+ version: "0.1.0"
795
+ })({
796
+ name: import_echo_schema5.S.optional(import_echo_schema5.S.String).annotations({
797
+ [import_echo_schema5.AST.TitleAnnotationId]: "Name"
798
+ }),
799
+ email: import_echo_schema5.S.optional(import_echo_schema5.Format.Email),
800
+ salary: import_echo_schema5.S.optional(import_echo_schema5.Format.Currency()).annotations({
801
+ [import_echo_schema5.AST.TitleAnnotationId]: "Salary"
802
+ })
803
+ });
804
+ const contactSchema = space.db.schemaRegistry.addSchema(ContactSchema);
805
+ table.view = (0, import_schema2.createView)({
806
+ name: "Test",
807
+ typename: contactSchema.typename,
808
+ jsonSchema: contactSchema.jsonSchema,
809
+ fields: [
810
+ "name",
811
+ "email",
812
+ "salary"
813
+ ]
814
+ });
815
+ const projection = new import_schema2.ViewProjection(contactSchema, table.view);
816
+ projection.setFieldProjection({
817
+ field: {
818
+ id: table.view.fields[2].id,
819
+ path: "salary",
820
+ size: 150
821
+ }
822
+ });
823
+ projection.setFieldProjection({
824
+ field: {
825
+ id: (0, import_schema2.createFieldId)(),
826
+ path: "manager",
827
+ referencePath: "name"
828
+ },
829
+ props: {
830
+ property: "manager",
831
+ type: import_echo_schema5.TypeEnum.Ref,
832
+ format: import_echo_schema5.FormatEnum.Ref,
833
+ referenceSchema: contactSchema.typename,
834
+ title: "Manager"
835
+ }
836
+ });
837
+ if (initialRow) {
838
+ space.db.add((0, import_echo5.create)(contactSchema, {}));
839
+ }
840
+ return contactSchema;
841
+ };
842
+ var TABLE_ATTRS = {
843
+ referencedCell: "data-table-ref-cell-button",
844
+ columnSettings: "data-table-column-settings-button",
845
+ rowMenu: "data-table-row-menu-button",
846
+ newColumn: "data-table-new-column-button"
847
+ };
848
+ var ICONS = {
849
+ referencedCell: "ph--link-simple-horizontal--regular",
850
+ columnSettings: "ph--caret-down--regular",
851
+ rowMenu: "ph--dots-three--regular",
852
+ newColumn: "ph--plus--regular"
853
+ };
854
+ var createButtonHtml = ({ button, value = "", disabled = false, testId }) => {
855
+ const buttonClasses = "ch-button is-6 pli-0.5 min-bs-0 absolute inset-block-1 inline-end-2";
856
+ return `<button class="${buttonClasses}" ${TABLE_ATTRS[button]}="${value}" data-testid="${testId}" ${disabled ? "disabled" : ""}><svg><use href="/icons.svg#${ICONS[button]}"/></svg></button>`;
857
+ };
858
+ var tableButtons = {
859
+ referencedCell: {
860
+ attr: TABLE_ATTRS.referencedCell,
861
+ icon: ICONS.referencedCell,
862
+ render: ({ targetId, schemaId }) => createButtonHtml({
863
+ button: "referencedCell",
864
+ value: `${schemaId}#${targetId}`,
865
+ testId: "table-ref-cell-button"
866
+ })
867
+ },
868
+ columnSettings: {
869
+ attr: TABLE_ATTRS.columnSettings,
870
+ icon: ICONS.columnSettings,
871
+ render: ({ fieldId }) => createButtonHtml({
872
+ button: "columnSettings",
873
+ value: fieldId,
874
+ testId: "table-column-settings-button"
875
+ })
876
+ },
877
+ rowMenu: {
878
+ attr: TABLE_ATTRS.rowMenu,
879
+ icon: ICONS.rowMenu,
880
+ render: ({ rowIndex }) => createButtonHtml({
881
+ button: "rowMenu",
882
+ value: rowIndex.toString(),
883
+ testId: "table-row-menu-button"
884
+ })
885
+ },
886
+ addColumn: {
887
+ attr: TABLE_ATTRS.newColumn,
888
+ icon: ICONS.newColumn,
889
+ render: ({ disabled } = {}) => createButtonHtml({
890
+ button: "newColumn",
891
+ disabled,
892
+ testId: "table-new-column-button"
893
+ })
894
+ }
895
+ };
896
+ var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-table/src/model/modal-controller.ts";
715
897
  var ModalController = class {
716
898
  constructor() {
717
899
  this._state = (0, import_signals_core2.signal)({
@@ -752,6 +934,16 @@ var ModalController = class {
752
934
  };
753
935
  return true;
754
936
  }
937
+ const refButton = target.closest(`button[${tableButtons.referencedCell.attr}]`);
938
+ if (refButton) {
939
+ this._triggerRef.current = refButton;
940
+ const [schemaId, targetId] = refButton.getAttribute(tableButtons.referencedCell.attr).split("#");
941
+ this._state.value = {
942
+ type: "refPanel",
943
+ targetId,
944
+ typename: schemaId
945
+ };
946
+ }
755
947
  return false;
756
948
  };
757
949
  this.openColumnSettings = () => {
@@ -768,6 +960,24 @@ var ModalController = class {
768
960
  });
769
961
  }
770
962
  };
963
+ this.openCreateRef = (typename, anchorCell, initialValues, onCreate) => {
964
+ if (anchorCell) {
965
+ this._triggerRef.current = anchorCell;
966
+ this._state.value = {
967
+ type: "createRefPanel",
968
+ typename,
969
+ initialValues,
970
+ onCreate
971
+ };
972
+ } else {
973
+ import_log.log.warn("anchor cell not found while creating new ref", void 0, {
974
+ F: __dxlog_file4,
975
+ L: 119,
976
+ S: this,
977
+ C: (f, a) => f(...a)
978
+ });
979
+ }
980
+ };
771
981
  this.close = () => {
772
982
  this._state.value = {
773
983
  type: "closed"
@@ -865,14 +1075,14 @@ var tableControls = {
865
1075
  render: renderCheckbox
866
1076
  }
867
1077
  };
868
- var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-table/src/model/table-model.ts";
1078
+ var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-table/src/model/table-model.ts";
869
1079
  var TableModel = class extends import_context.Resource {
870
1080
  constructor({ table, projection, sorting = [], pinnedRows = {
871
1081
  top: [],
872
1082
  bottom: []
873
1083
  }, onCellUpdate, onDeleteColumn, onDeleteRows, onInsertRow, onRowOrderChanged }) {
874
1084
  super();
875
- this.id = `table-model-${import_react_client2.PublicKey.random().truncate()}`;
1085
+ this.id = `table-model-${import_react_client.PublicKey.random().truncate()}`;
876
1086
  this._visibleRange = (0, import_signals_core.signal)({
877
1087
  start: {
878
1088
  row: 0,
@@ -914,14 +1124,14 @@ var TableModel = class extends import_context.Resource {
914
1124
  }
915
1125
  };
916
1126
  this.getMainGridCells = (range) => {
917
- const values = {};
1127
+ const cells = {};
918
1128
  const fields = this._table.view?.fields ?? [];
919
1129
  const addCell = (obj, field, colIndex, displayIndex) => {
920
1130
  const { props } = this._projection.getFieldProjection(field.id);
921
- const value = {
1131
+ const cell = {
922
1132
  get value() {
923
- const value2 = (0, import_echo_schema4.getValue)(obj, field.path);
924
- if (value2 == null) {
1133
+ const value = (0, import_echo_schema4.getValue)(obj, field.path);
1134
+ if (value == null) {
925
1135
  return "";
926
1136
  }
927
1137
  switch (props.format) {
@@ -929,38 +1139,45 @@ var TableModel = class extends import_context.Resource {
929
1139
  if (!field.referencePath) {
930
1140
  return "";
931
1141
  }
932
- return (0, import_echo_schema4.getValue)(value2, field.referencePath);
1142
+ return (0, import_echo_schema4.getValue)(value, field.referencePath);
933
1143
  }
934
1144
  default: {
935
- return (0, import_react_ui_form2.formatForDisplay)({
1145
+ return (0, import_react_ui_form4.formatForDisplay)({
936
1146
  type: props.type,
937
1147
  format: props.format,
938
- value: value2
1148
+ value
939
1149
  });
940
1150
  }
941
1151
  }
942
1152
  }
943
1153
  };
944
1154
  const classes = [];
945
- const formatClasses = (0, import_react_ui_form2.cellClassesForFieldType)({
1155
+ const formatClasses = (0, import_react_ui_form4.cellClassesForFieldType)({
946
1156
  type: props.type,
947
1157
  format: props.format
948
1158
  });
949
1159
  if (formatClasses) {
950
1160
  classes.push(formatClasses);
951
1161
  }
952
- const rowSelectionClasses = (0, import_react_ui_form2.cellClassesForRowSelection)(this._selection.isObjectSelected(obj));
1162
+ const rowSelectionClasses = (0, import_react_ui_form4.cellClassesForRowSelection)(this._selection.isObjectSelected(obj));
953
1163
  if (rowSelectionClasses) {
954
1164
  classes.push(rowSelectionClasses);
955
1165
  }
956
1166
  if (classes.length > 0) {
957
- value.className = (0, import_react_ui_theme2.mx)(classes.flat());
1167
+ cell.className = (0, import_react_ui_theme2.mx)(classes.flat());
1168
+ }
1169
+ if (cell.value && props.format === import_echo_schema4.FormatEnum.Ref && props.referenceSchema) {
1170
+ const targetObj = (0, import_echo_schema4.getValue)(obj, field.path);
1171
+ cell.accessoryHtml = tableButtons.referencedCell.render({
1172
+ targetId: targetObj.id,
1173
+ schemaId: props.referenceSchema
1174
+ });
958
1175
  }
959
- const idx = fromGridCell({
1176
+ const idx = (0, import_react_ui_grid4.toPlaneCellIndex)({
960
1177
  col: colIndex,
961
1178
  row: displayIndex
962
1179
  });
963
- values[idx] = value;
1180
+ cells[idx] = cell;
964
1181
  };
965
1182
  for (let row = range.start.row; row <= range.end.row && row < this._sortedRows.value.length; row++) {
966
1183
  for (let col = range.start.col; col <= range.end.col && col < fields.length; col++) {
@@ -971,17 +1188,18 @@ var TableModel = class extends import_context.Resource {
971
1188
  addCell(this._sortedRows.value[row], field, col, row);
972
1189
  }
973
1190
  }
974
- return values;
1191
+ return cells;
975
1192
  };
976
1193
  this.getHeaderCells = (range) => {
977
- const values = {};
1194
+ const cells = {};
978
1195
  const fields = this.table.view?.fields ?? [];
979
1196
  for (let col = range.start.col; col <= range.end.col && col < fields.length; col++) {
980
1197
  const { field, props } = this._projection.getFieldProjection(fields[col].id);
981
- values[fromGridCell({
1198
+ cells[(0, import_react_ui_grid4.toPlaneCellIndex)({
982
1199
  col,
983
1200
  row: 0
984
1201
  })] = {
1202
+ // TODO(burdon): Use same logic as form for fallback title.
985
1203
  value: props.title ?? field.path,
986
1204
  readonly: true,
987
1205
  resizeHandle: "col",
@@ -990,14 +1208,14 @@ var TableModel = class extends import_context.Resource {
990
1208
  })
991
1209
  };
992
1210
  }
993
- return values;
1211
+ return cells;
994
1212
  };
995
1213
  this.getSelectionColumnCells = (range) => {
996
- const values = {};
1214
+ const cells = {};
997
1215
  for (let row = range.start.row; row <= range.end.row && row < this._rows.value.length; row++) {
998
1216
  const isSelected = this._selection.isRowIndexSelected(row);
999
- const classes = (0, import_react_ui_form2.cellClassesForRowSelection)(isSelected);
1000
- values[fromGridCell({
1217
+ const classes = (0, import_react_ui_form4.cellClassesForRowSelection)(isSelected);
1218
+ cells[(0, import_react_ui_grid4.toPlaneCellIndex)({
1001
1219
  col: 0,
1002
1220
  row
1003
1221
  })] = {
@@ -1010,14 +1228,14 @@ var TableModel = class extends import_context.Resource {
1010
1228
  })
1011
1229
  };
1012
1230
  }
1013
- return values;
1231
+ return cells;
1014
1232
  };
1015
1233
  this.getActionColumnCells = (range) => {
1016
- const values = {};
1234
+ const cells = {};
1017
1235
  for (let row = range.start.row; row <= range.end.row && row < this._rows.value.length; row++) {
1018
1236
  const isSelected = this._selection.isRowIndexSelected(row);
1019
- const classes = (0, import_react_ui_form2.cellClassesForRowSelection)(isSelected);
1020
- values[fromGridCell({
1237
+ const classes = (0, import_react_ui_form4.cellClassesForRowSelection)(isSelected);
1238
+ cells[(0, import_react_ui_grid4.toPlaneCellIndex)({
1021
1239
  col: 0,
1022
1240
  row
1023
1241
  })] = {
@@ -1029,11 +1247,11 @@ var TableModel = class extends import_context.Resource {
1029
1247
  })
1030
1248
  };
1031
1249
  }
1032
- return values;
1250
+ return cells;
1033
1251
  };
1034
1252
  this.getSelectAllCell = () => {
1035
1253
  return {
1036
- [fromGridCell({
1254
+ [(0, import_react_ui_grid4.toPlaneCellIndex)({
1037
1255
  col: 0,
1038
1256
  row: 0
1039
1257
  })]: {
@@ -1049,13 +1267,13 @@ var TableModel = class extends import_context.Resource {
1049
1267
  };
1050
1268
  this.getNewColumnCell = () => {
1051
1269
  return {
1052
- [fromGridCell({
1270
+ [(0, import_react_ui_grid4.toPlaneCellIndex)({
1053
1271
  col: 0,
1054
1272
  row: 0
1055
1273
  })]: {
1056
1274
  value: "",
1057
1275
  accessoryHtml: tableButtons.addColumn.render({
1058
- disabled: (this._table.view?.fields?.length ?? 0) >= import_schema2.VIEW_FIELD_LIMIT
1276
+ disabled: (this._table.view?.fields?.length ?? 0) >= import_schema.VIEW_FIELD_LIMIT
1059
1277
  }),
1060
1278
  readonly: true
1061
1279
  }
@@ -1102,7 +1320,7 @@ var TableModel = class extends import_context.Resource {
1102
1320
  return (0, import_echo_schema4.getValue)(value, field.referencePath);
1103
1321
  }
1104
1322
  default: {
1105
- return (0, import_react_ui_form2.formatForEditing)({
1323
+ return (0, import_react_ui_form4.formatForEditing)({
1106
1324
  type: props.type,
1107
1325
  format: props.format,
1108
1326
  value
@@ -1124,7 +1342,7 @@ var TableModel = class extends import_context.Resource {
1124
1342
  break;
1125
1343
  }
1126
1344
  default: {
1127
- (0, import_echo_schema4.setValue)(this._rows.value[rowIdx], field.path, (0, import_react_ui_form2.parseValue)({
1345
+ (0, import_echo_schema4.setValue)(this._rows.value[rowIdx], field.path, (0, import_react_ui_form4.parseValue)({
1128
1346
  type: props.type,
1129
1347
  format: props.format,
1130
1348
  value
@@ -1173,8 +1391,8 @@ var TableModel = class extends import_context.Resource {
1173
1391
  }
1174
1392
  get columnMeta() {
1175
1393
  (0, import_invariant3.invariant)(this._columnMeta, void 0, {
1176
- F: __dxlog_file4,
1177
- L: 124,
1394
+ F: __dxlog_file5,
1395
+ L: 126,
1178
1396
  S: this,
1179
1397
  A: [
1180
1398
  "this._columnMeta",
@@ -1280,7 +1498,8 @@ var TableModel = class extends import_context.Resource {
1280
1498
  this?._table?.view?.fields.forEach((field) => touch((0, import_echo_schema4.getValue)(obj, field.path)));
1281
1499
  this._onCellUpdate?.({
1282
1500
  row,
1283
- col: start.col
1501
+ col: start.col,
1502
+ plane: "grid"
1284
1503
  });
1285
1504
  }));
1286
1505
  }
@@ -1341,8 +1560,8 @@ var TableModel = class extends import_context.Resource {
1341
1560
  }
1342
1561
  };
1343
1562
  var useTableModel = ({ objects, table, projection, ...props }) => {
1344
- const [model, setModel] = (0, import_react8.useState)();
1345
- (0, import_react8.useEffect)(() => {
1563
+ const [model, setModel] = (0, import_react10.useState)();
1564
+ (0, import_react10.useEffect)(() => {
1346
1565
  if (!table || !projection) {
1347
1566
  return;
1348
1567
  }
@@ -1364,7 +1583,7 @@ var useTableModel = ({ objects, table, projection, ...props }) => {
1364
1583
  table,
1365
1584
  projection
1366
1585
  ]);
1367
- (0, import_react8.useEffect)(() => {
1586
+ (0, import_react10.useEffect)(() => {
1368
1587
  if (objects) {
1369
1588
  model?.setRows(objects);
1370
1589
  }
@@ -1377,12 +1596,11 @@ var useTableModel = ({ objects, table, projection, ...props }) => {
1377
1596
  // Annotate the CommonJS export names for ESM import in node:
1378
1597
  0 && (module.exports = {
1379
1598
  Table,
1599
+ TableSchema,
1380
1600
  TableType,
1381
1601
  Toolbar,
1382
- fromGridCell,
1383
1602
  initializeTable,
1384
1603
  tableButtons,
1385
- toGridCell,
1386
1604
  touch,
1387
1605
  translations,
1388
1606
  useTableModel,