@dxos/react-ui-table 0.4.10-main.0302e13 → 0.4.10-main.0be5154

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.
@@ -1,39 +1,15 @@
1
1
  // packages/ui/react-ui-table/src/components/ColumnMenu.tsx
2
- import { Check, Trash, X, GearSix } from "@phosphor-icons/react";
3
- import React2, { useRef, useState } from "react";
4
- import { Button as Button2, DensityProvider, Input, Popover, Select, Separator, useTranslation } from "@dxos/react-ui";
5
- import { getSize as getSize2, mx } from "@dxos/react-ui-theme";
6
- import { safeParseInt } from "@dxos/util";
2
+ import { X as X2, GearSix, CaretDown, ArrowDown, ArrowUp } from "@phosphor-icons/react";
3
+ import React2, { useRef as useRef2, useState as useState3, useCallback } from "react";
4
+ import { Button as Button2, DensityProvider, Popover, DropdownMenu } from "@dxos/react-ui";
5
+ import { getSize as getSize2, mx as mx2 } from "@dxos/react-ui-theme";
7
6
 
8
- // packages/ui/react-ui-table/src/components/SortButton.tsx
9
- import { CaretUpDown, SortAscending, SortDescending } from "@phosphor-icons/react";
10
- import React from "react";
11
- import { Button } from "@dxos/react-ui";
12
- import { getSize } from "@dxos/react-ui-theme";
13
- var SortButton = ({ sortDirection, onClick }) => {
14
- let icon;
15
- const size = getSize(4);
16
- switch (sortDirection) {
17
- case "asc":
18
- icon = /* @__PURE__ */ React.createElement(SortAscending, {
19
- className: size
20
- });
21
- break;
22
- case "desc":
23
- icon = /* @__PURE__ */ React.createElement(SortDescending, {
24
- className: size
25
- });
26
- break;
27
- default:
28
- icon = /* @__PURE__ */ React.createElement(CaretUpDown, {
29
- className: size
30
- });
31
- }
32
- return /* @__PURE__ */ React.createElement(Button, {
33
- variant: "ghost",
34
- onClick
35
- }, icon);
36
- };
7
+ // packages/ui/react-ui-table/src/components/ColumnSettingsForm.tsx
8
+ import { Check, Trash, X } from "@phosphor-icons/react";
9
+ import React, { useRef, useState } from "react";
10
+ import { Button, Input, Select, Separator, useTranslation } from "@dxos/react-ui";
11
+ import { getSize, mx } from "@dxos/react-ui-theme";
12
+ import { safeParseInt } from "@dxos/util";
37
13
 
38
14
  // packages/ui/react-ui-table/src/translations.ts
39
15
  var translationKey = "table";
@@ -58,34 +34,12 @@ var translations_default = [
58
34
  }
59
35
  ];
60
36
 
61
- // packages/ui/react-ui-table/src/components/ColumnMenu.tsx
62
- var ColumnMenu = ({ column, ...props }) => {
63
- const title = column.label?.length ? column.label : column.id;
64
- const header = props.context.header;
65
- const canSort = header.column.getCanSort();
66
- const sortDirection = header.column.getIsSorted();
67
- const toggleSort = header.column.getToggleSortingHandler();
68
- return /* @__PURE__ */ React2.createElement("div", {
69
- className: "flex items-center gap-2"
70
- }, /* @__PURE__ */ React2.createElement("div", {
71
- className: "flex-1 min-is-0 truncate",
72
- title
73
- }, title), /* @__PURE__ */ React2.createElement("div", {
74
- className: "flex gap-0"
75
- }, canSort && toggleSort && /* @__PURE__ */ React2.createElement(SortButton, {
76
- sortDirection,
77
- onClick: toggleSort
78
- }), /* @__PURE__ */ React2.createElement(ColumnPanel, {
79
- ...props,
80
- column
81
- })));
82
- };
83
- var Section = ({ children, className }) => /* @__PURE__ */ React2.createElement("div", {
37
+ // packages/ui/react-ui-table/src/components/ColumnSettingsForm.tsx
38
+ var Section = ({ children, className }) => /* @__PURE__ */ React.createElement("div", {
84
39
  role: "none",
85
40
  className: mx("p-2", className)
86
41
  }, children);
87
- var ColumnPanel = ({ context, tableDefs, tableDef, column, onUpdate, onDelete }) => {
88
- const [open, setOpen] = useState(false);
42
+ var ColumnSettingsForm = ({ column, tableDef, tableDefs, onUpdate, onDelete, onClose }) => {
89
43
  const [prop, setProp] = useState(column.id);
90
44
  const [refTable, setRefTable] = useState(column.refTable);
91
45
  const [refProp, setRefProp] = useState(column.refProp);
@@ -96,7 +50,7 @@ var ColumnPanel = ({ context, tableDefs, tableDef, column, onUpdate, onDelete })
96
50
  const { t } = useTranslation(translationKey);
97
51
  const handleCancel = () => {
98
52
  setProp(column.id);
99
- setOpen(false);
53
+ onClose;
100
54
  };
101
55
  const handleSave = () => {
102
56
  if (!prop.length || !prop.match(/^[a-zA-Z_].+/i)) {
@@ -119,117 +73,275 @@ var ColumnPanel = ({ context, tableDefs, tableDef, column, onUpdate, onDelete })
119
73
  refProp,
120
74
  digits: safeParseInt(digits)
121
75
  });
122
- setOpen(false);
76
+ onClose();
123
77
  };
124
- return /* @__PURE__ */ React2.createElement(Popover.Root, {
125
- open,
126
- onOpenChange: (nextOpen) => setOpen(nextOpen)
127
- }, /* @__PURE__ */ React2.createElement(Popover.Trigger, {
128
- asChild: true
129
- }, /* @__PURE__ */ React2.createElement(Button2, {
130
- variant: "ghost"
131
- }, /* @__PURE__ */ React2.createElement(GearSix, {
132
- className: mx(getSize2(4), "rotate-90")
133
- }))), /* @__PURE__ */ React2.createElement(Popover.Portal, null, /* @__PURE__ */ React2.createElement(Popover.Content, null, /* @__PURE__ */ React2.createElement(Popover.Viewport, {
134
- classNames: "w-60"
135
- }, /* @__PURE__ */ React2.createElement(DensityProvider, {
136
- density: "fine"
137
- }, /* @__PURE__ */ React2.createElement("div", {
78
+ return /* @__PURE__ */ React.createElement("div", {
138
79
  className: "flex flex-col gap-1"
139
- }, /* @__PURE__ */ React2.createElement(Section, null, /* @__PURE__ */ React2.createElement(Input.Root, null, /* @__PURE__ */ React2.createElement(Input.Label, {
80
+ }, /* @__PURE__ */ React.createElement(Section, null, /* @__PURE__ */ React.createElement(Input.Root, null, /* @__PURE__ */ React.createElement(Input.Label, {
140
81
  classNames: "mbe-1"
141
- }, t("column label label")), /* @__PURE__ */ React2.createElement(Input.TextInput, {
82
+ }, t("column label label")), /* @__PURE__ */ React.createElement(Input.TextInput, {
142
83
  placeholder: "Column label",
143
84
  value: label ?? "",
144
85
  onChange: (event) => setLabel(event.target.value),
145
86
  autoFocus: true
146
- })), /* @__PURE__ */ React2.createElement(Input.Root, null, /* @__PURE__ */ React2.createElement(Input.Label, {
87
+ })), /* @__PURE__ */ React.createElement(Input.Root, null, /* @__PURE__ */ React.createElement(Input.Label, {
147
88
  classNames: "mbe-1 mbs-3"
148
- }, t("property key label")), /* @__PURE__ */ React2.createElement(Input.TextInput, {
89
+ }, t("property key label")), /* @__PURE__ */ React.createElement(Input.TextInput, {
149
90
  ref: propRef,
150
91
  placeholder: "Property key",
151
92
  // TODO(burdon): Provide hooks for value normalization, ENTER, ESC, etc.
152
93
  value: prop ?? "",
153
94
  onChange: (event) => setProp(event.target.value.replace(/[^\w_]/g, ""))
154
- })), /* @__PURE__ */ React2.createElement(Input.Root, null, /* @__PURE__ */ React2.createElement(Input.Label, {
95
+ })), /* @__PURE__ */ React.createElement(Input.Root, null, /* @__PURE__ */ React.createElement(Input.Label, {
155
96
  classNames: "mbe-1 mbs-3"
156
- }, t("column type label")), /* @__PURE__ */ React2.createElement(Select.Root, {
97
+ }, t("column type label")), /* @__PURE__ */ React.createElement(Select.Root, {
157
98
  value: type,
158
99
  onValueChange: setType
159
- }, /* @__PURE__ */ React2.createElement(Select.TriggerButton, {
100
+ }, /* @__PURE__ */ React.createElement(Select.TriggerButton, {
160
101
  placeholder: "Type",
161
102
  classNames: "is-full"
162
- }), /* @__PURE__ */ React2.createElement(Select.Portal, null, /* @__PURE__ */ React2.createElement(Select.Content, null, /* @__PURE__ */ React2.createElement(Select.Viewport, null, [
103
+ }), /* @__PURE__ */ React.createElement(Select.Portal, null, /* @__PURE__ */ React.createElement(Select.Content, null, /* @__PURE__ */ React.createElement(Select.Viewport, null, [
163
104
  "number",
164
105
  "boolean",
165
106
  "string",
166
107
  "ref"
167
- ].map((type2) => /* @__PURE__ */ React2.createElement(Select.Option, {
108
+ ].map((type2) => /* @__PURE__ */ React.createElement(Select.Option, {
168
109
  key: type2,
169
110
  value: type2
170
- }, t(`${type2} column type label`))))))))), type === "number" && /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(Section, null, /* @__PURE__ */ React2.createElement(Input.Root, null, /* @__PURE__ */ React2.createElement(Input.Label, {
111
+ }, t(`${type2} column type label`))))))))), type === "number" && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Section, null, /* @__PURE__ */ React.createElement(Input.Root, null, /* @__PURE__ */ React.createElement(Input.Label, {
171
112
  classNames: "mbe-1 mbs-3"
172
- }, t("digits label")), /* @__PURE__ */ React2.createElement(Input.TextInput, {
113
+ }, t("digits label")), /* @__PURE__ */ React.createElement(Input.TextInput, {
173
114
  value: digits ?? "",
174
115
  onChange: (event) => setDigits(event.target.value)
175
- })))), type === "ref" && /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(Section, null, /* @__PURE__ */ React2.createElement(Input.Root, null, /* @__PURE__ */ React2.createElement(Input.Label, {
116
+ })))), type === "ref" && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Section, null, /* @__PURE__ */ React.createElement(Input.Root, null, /* @__PURE__ */ React.createElement(Input.Label, {
176
117
  classNames: "mbe-1 mbs-3"
177
- }, "Table"), /* @__PURE__ */ React2.createElement(Select.Root, {
118
+ }, "Table"), /* @__PURE__ */ React.createElement(Select.Root, {
178
119
  value: refTable,
179
120
  onValueChange: setRefTable
180
- }, /* @__PURE__ */ React2.createElement(Select.TriggerButton, {
121
+ }, /* @__PURE__ */ React.createElement(Select.TriggerButton, {
181
122
  placeholder: "Table",
182
123
  classNames: "is-full"
183
- }), /* @__PURE__ */ React2.createElement(Select.Portal, null, /* @__PURE__ */ React2.createElement(Select.Content, null, /* @__PURE__ */ React2.createElement(Select.Viewport, null, tableDefs.filter((t2) => t2.id !== tableDef.id).map(({ id, name }) => /* @__PURE__ */ React2.createElement(Select.Option, {
124
+ }), /* @__PURE__ */ React.createElement(Select.Portal, null, /* @__PURE__ */ React.createElement(Select.Content, null, /* @__PURE__ */ React.createElement(Select.Viewport, null, tableDefs.filter((t2) => t2.id !== tableDef.id).map(({ id, name }) => /* @__PURE__ */ React.createElement(Select.Option, {
184
125
  key: id,
185
126
  value: id
186
- }, name ?? id))))))), refTable && /* @__PURE__ */ React2.createElement(Input.Root, null, /* @__PURE__ */ React2.createElement(Input.Label, {
127
+ }, name ?? id))))))), refTable && /* @__PURE__ */ React.createElement(Input.Root, null, /* @__PURE__ */ React.createElement(Input.Label, {
187
128
  classNames: "mbe-1 mbs-3"
188
- }, "Table property"), /* @__PURE__ */ React2.createElement(Select.Root, {
129
+ }, "Table property"), /* @__PURE__ */ React.createElement(Select.Root, {
189
130
  value: refProp,
190
131
  onValueChange: setRefProp
191
- }, /* @__PURE__ */ React2.createElement(Select.TriggerButton, {
132
+ }, /* @__PURE__ */ React.createElement(Select.TriggerButton, {
192
133
  placeholder: "Property",
193
134
  classNames: "is-full"
194
- }), /* @__PURE__ */ React2.createElement(Select.Portal, null, /* @__PURE__ */ React2.createElement(Select.Content, null, /* @__PURE__ */ React2.createElement(Select.Viewport, null, tableDefs.find((tableDef2) => tableDef2.id === refTable)?.columns.map(({ id, label: label2 }) => /* @__PURE__ */ React2.createElement(Select.Option, {
135
+ }), /* @__PURE__ */ React.createElement(Select.Portal, null, /* @__PURE__ */ React.createElement(Select.Content, null, /* @__PURE__ */ React.createElement(Select.Viewport, null, tableDefs.find((tableDef2) => tableDef2.id === refTable)?.columns.map(({ id, label: label2 }) => /* @__PURE__ */ React.createElement(Select.Option, {
195
136
  key: id,
196
137
  value: id
197
- }, label2 ?? id))))))))), /* @__PURE__ */ React2.createElement(Separator, {
138
+ }, label2 ?? id))))))))), /* @__PURE__ */ React.createElement(Separator, {
198
139
  classNames: "mli-2"
199
- }), /* @__PURE__ */ React2.createElement(Section, {
140
+ }), /* @__PURE__ */ React.createElement(Section, {
200
141
  className: "space-b-1.5"
201
- }, /* @__PURE__ */ React2.createElement(Button2, {
142
+ }, /* @__PURE__ */ React.createElement(Button, {
202
143
  variant: "primary",
203
144
  classNames: "is-full flex gap-2",
204
145
  onClick: handleSave
205
- }, /* @__PURE__ */ React2.createElement("span", null, t("save label")), /* @__PURE__ */ React2.createElement("div", {
146
+ }, /* @__PURE__ */ React.createElement("span", null, t("save label")), /* @__PURE__ */ React.createElement("div", {
206
147
  className: "grow"
207
- }), /* @__PURE__ */ React2.createElement(Check, {
208
- className: getSize2(5)
209
- })), /* @__PURE__ */ React2.createElement(Button2, {
148
+ }), /* @__PURE__ */ React.createElement(Check, {
149
+ className: getSize(5)
150
+ })), /* @__PURE__ */ React.createElement(Button, {
210
151
  classNames: "is-full flex gap-2",
211
152
  onClick: handleCancel
212
- }, /* @__PURE__ */ React2.createElement("span", null, t("cancel label", {
153
+ }, /* @__PURE__ */ React.createElement("span", null, t("cancel label", {
213
154
  ns: "os"
214
- })), /* @__PURE__ */ React2.createElement("div", {
155
+ })), /* @__PURE__ */ React.createElement("div", {
215
156
  className: "grow"
216
- }), /* @__PURE__ */ React2.createElement(X, {
217
- className: getSize2(5)
218
- })), /* @__PURE__ */ React2.createElement(Button2, {
157
+ }), /* @__PURE__ */ React.createElement(X, {
158
+ className: getSize(5)
159
+ })), /* @__PURE__ */ React.createElement(Button, {
219
160
  classNames: "is-full flex gap-2",
220
161
  onClick: () => onDelete?.(column.id)
221
- }, /* @__PURE__ */ React2.createElement("span", null, t("delete label")), /* @__PURE__ */ React2.createElement("div", {
162
+ }, /* @__PURE__ */ React.createElement("span", null, t("delete label")), /* @__PURE__ */ React.createElement("div", {
163
+ className: "grow"
164
+ }), /* @__PURE__ */ React.createElement(Trash, {
165
+ className: getSize(5)
166
+ }))));
167
+ };
168
+
169
+ // packages/ui/react-ui-table/src/components/hooks/useColumnSorting.ts
170
+ import { useState as useState2 } from "react";
171
+ var useColumnSorting = (column) => {
172
+ const [sortDirection, setSortDirection] = useState2(column.getIsSorted());
173
+ const [firstSort, setFirstSort] = useState2();
174
+ const canSort = column.getCanSort();
175
+ const updateColumnSort = (direction) => {
176
+ setSortDirection(direction);
177
+ switch (direction) {
178
+ case false:
179
+ column.clearSorting();
180
+ break;
181
+ case "asc":
182
+ column.toggleSorting(false);
183
+ break;
184
+ case "desc":
185
+ column.toggleSorting(true);
186
+ break;
187
+ }
188
+ };
189
+ const onToggleSort = () => {
190
+ if (sortDirection === false) {
191
+ return;
192
+ }
193
+ if (sortDirection === firstSort) {
194
+ updateColumnSort(firstSort === "asc" ? "desc" : "asc");
195
+ } else {
196
+ updateColumnSort(false);
197
+ }
198
+ };
199
+ const onSelectSort = (direction) => {
200
+ setFirstSort(direction);
201
+ updateColumnSort(direction);
202
+ };
203
+ const onClearSort = () => {
204
+ updateColumnSort(false);
205
+ };
206
+ return {
207
+ canSort,
208
+ sortDirection,
209
+ onSelectSort,
210
+ onToggleSort,
211
+ onClearSort
212
+ };
213
+ };
214
+
215
+ // packages/ui/react-ui-table/src/components/ColumnMenu.tsx
216
+ var ColumnMenu = ({ column, ...props }) => {
217
+ const title = column.label?.length ? column.label : column.id;
218
+ const header = props.context.header;
219
+ const { canSort, sortDirection, onSelectSort, onToggleSort, onClearSort } = useColumnSorting(header.column);
220
+ const columnSettingsAnchorRef = useRef2(null);
221
+ const [isColumnSettingsOpen, setIsColumnSettingsOpen] = useState3(false);
222
+ const shouldPreventFocusOnClose = useRef2(false);
223
+ const onOpenColumnSettings = useCallback(() => {
224
+ shouldPreventFocusOnClose.current = true;
225
+ setIsColumnSettingsOpen(true);
226
+ }, [
227
+ shouldPreventFocusOnClose,
228
+ setIsColumnSettingsOpen
229
+ ]);
230
+ const onDropdownCloseAutoFocus = useCallback((event) => {
231
+ if (shouldPreventFocusOnClose.current) {
232
+ event.preventDefault();
233
+ shouldPreventFocusOnClose.current = false;
234
+ }
235
+ }, [
236
+ shouldPreventFocusOnClose
237
+ ]);
238
+ return /* @__PURE__ */ React2.createElement("div", {
239
+ className: "flex items-center justify-center justify-between"
240
+ }, /* @__PURE__ */ React2.createElement("div", {
241
+ className: "flex items-center gap-1 truncate",
242
+ title
243
+ }, /* @__PURE__ */ React2.createElement(SortIndicator, {
244
+ direction: sortDirection,
245
+ onClick: onToggleSort
246
+ }), /* @__PURE__ */ React2.createElement("div", {
247
+ className: "truncate"
248
+ }, title)), /* @__PURE__ */ React2.createElement(DropdownMenu.Root, {
249
+ modal: false
250
+ }, /* @__PURE__ */ React2.createElement(Popover.Root, {
251
+ open: isColumnSettingsOpen,
252
+ onOpenChange: setIsColumnSettingsOpen,
253
+ modal: false
254
+ }, /* @__PURE__ */ React2.createElement(DropdownMenu.Trigger, {
255
+ ref: columnSettingsAnchorRef,
256
+ asChild: true
257
+ }, /* @__PURE__ */ React2.createElement(Popover.Anchor, {
258
+ asChild: true
259
+ }, /* @__PURE__ */ React2.createElement(Button2, {
260
+ variant: "ghost"
261
+ }, /* @__PURE__ */ React2.createElement(CaretDown, {
262
+ className: getSize2(4)
263
+ })))), /* @__PURE__ */ React2.createElement(DropdownMenu.Content, {
264
+ onCloseAutoFocus: onDropdownCloseAutoFocus,
265
+ sideOffset: 4,
266
+ collisionPadding: 8
267
+ }, /* @__PURE__ */ React2.createElement(DropdownMenu.Viewport, null, canSort && /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(DropdownMenu.Item, {
268
+ onClick: () => onSelectSort("asc")
269
+ }, /* @__PURE__ */ React2.createElement("span", {
270
+ className: "grow"
271
+ }, "Sort ascending"), /* @__PURE__ */ React2.createElement("span", {
272
+ className: "opacity-50"
273
+ }, /* @__PURE__ */ React2.createElement(ArrowUp, {
274
+ className: getSize2(4)
275
+ }))), /* @__PURE__ */ React2.createElement(DropdownMenu.Item, {
276
+ onClick: () => onSelectSort("desc")
277
+ }, /* @__PURE__ */ React2.createElement("span", {
278
+ className: "grow"
279
+ }, "Sort descending"), /* @__PURE__ */ React2.createElement("span", {
280
+ className: "opacity-50"
281
+ }, /* @__PURE__ */ React2.createElement(ArrowDown, {
282
+ className: getSize2(4)
283
+ }))), sortDirection !== false && /* @__PURE__ */ React2.createElement(DropdownMenu.Item, {
284
+ onClick: onClearSort
285
+ }, /* @__PURE__ */ React2.createElement("span", {
286
+ className: "grow"
287
+ }, "Clear sort"), /* @__PURE__ */ React2.createElement("span", {
288
+ className: "opacity-50"
289
+ }, /* @__PURE__ */ React2.createElement(X2, {
290
+ className: getSize2(4)
291
+ })))), /* @__PURE__ */ React2.createElement(DropdownMenu.Item, {
292
+ onClick: onOpenColumnSettings
293
+ }, /* @__PURE__ */ React2.createElement("span", {
222
294
  className: "grow"
223
- }), /* @__PURE__ */ React2.createElement(Trash, {
224
- className: getSize2(5)
225
- })))))), /* @__PURE__ */ React2.createElement(Popover.Arrow, null))));
295
+ }, "Column settings"), /* @__PURE__ */ React2.createElement("span", {
296
+ className: "opacity-50"
297
+ }, /* @__PURE__ */ React2.createElement(GearSix, {
298
+ className: mx2(getSize2(4), "rotate-90")
299
+ })))), /* @__PURE__ */ React2.createElement(DropdownMenu.Arrow, null)), /* @__PURE__ */ React2.createElement(ColumnSettingsPanel, {
300
+ ...props,
301
+ column,
302
+ onClose: () => setIsColumnSettingsOpen(false)
303
+ }))));
304
+ };
305
+ var ColumnSettingsPanel = ({ tableDefs, tableDef, column, onUpdate, onDelete, onClose }) => /* @__PURE__ */ React2.createElement(Popover.Portal, null, /* @__PURE__ */ React2.createElement(Popover.Content, null, /* @__PURE__ */ React2.createElement(Popover.Viewport, {
306
+ classNames: "w-60"
307
+ }, /* @__PURE__ */ React2.createElement(DensityProvider, {
308
+ density: "fine"
309
+ }, /* @__PURE__ */ React2.createElement(ColumnSettingsForm, {
310
+ column,
311
+ tableDefs,
312
+ tableDef,
313
+ onUpdate,
314
+ onDelete,
315
+ onClose
316
+ }))), /* @__PURE__ */ React2.createElement(Popover.Arrow, null)));
317
+ var SortIndicator = ({ direction, onClick }) => {
318
+ if (direction === false) {
319
+ return null;
320
+ }
321
+ let icon;
322
+ switch (direction) {
323
+ case "asc":
324
+ icon = /* @__PURE__ */ React2.createElement(ArrowUp, {
325
+ className: getSize2(3)
326
+ });
327
+ break;
328
+ case "desc":
329
+ icon = /* @__PURE__ */ React2.createElement(ArrowDown, {
330
+ className: getSize2(3)
331
+ });
332
+ break;
333
+ }
334
+ return /* @__PURE__ */ React2.createElement("div", {
335
+ onClick,
336
+ className: "flex items-center cursor-pointer"
337
+ }, icon);
226
338
  };
227
339
 
228
340
  // packages/ui/react-ui-table/src/components/Table/Table.tsx
229
341
  import { useControllableState } from "@radix-ui/react-use-controllable-state";
230
342
  import { getCoreRowModel, getSortedRowModel, useReactTable, getGroupedRowModel, getExpandedRowModel } from "@tanstack/react-table";
231
343
  import { useVirtualizer } from "@tanstack/react-virtual";
232
- import React8, { Fragment, useCallback, useEffect as useEffect2, useState as useState3 } from "react";
344
+ import React8, { Fragment, useCallback as useCallback2, useEffect as useEffect2, useState as useState5 } from "react";
233
345
  import { log } from "@dxos/log";
234
346
  import { useDefaultValue, useOnTransition } from "@dxos/react-ui";
235
347
 
@@ -252,28 +364,28 @@ var useTableContext = () => {
252
364
  };
253
365
 
254
366
  // packages/ui/react-ui-table/src/theme.ts
255
- import { modalSurface, focusRing, ghostSelected, ghostSelectedCurrent, groupBorder, mx as mx2 } from "@dxos/react-ui-theme";
367
+ import { modalSurface, focusRing, ghostSelected, ghostSelectedCurrent, groupBorder, mx as mx3 } from "@dxos/react-ui-theme";
256
368
  var currentRow = "!bg-neutral-75 !dark:bg-neutral-850";
257
369
  var selectedRow = "!bg-primary-100 dark:!bg-primary-700";
258
370
  var flushPadding = "pli-0 plb-0";
259
371
  var textPadding = "pli-2 plb-0.5";
260
372
  var headPadding = "pli-2 plb-1";
261
373
  var gridCellFocusRing = "focus-within:z-[11] focus-within:outline outline-2 outline-primary-500 dark:outline-primary-400";
262
- var tableRoot = ({ fullWidth }, ...etc) => mx2("table-fixed", fullWidth && "is-full", ...etc);
263
- var groupTh = (_props, ...etc) => mx2("text-start font-medium", flushPadding, ...etc);
264
- var theadRoot = ({ header, stickyHeader }, ...etc) => mx2(header ? stickyHeader && "sticky block-start-[--sticky-top] z-[1]" : "collapse", header && "base-surface", "drop-shadow-sm", ...etc);
265
- var theadTr = (_props, ...etc) => mx2("group", ...etc);
266
- var theadTh = ({ border }, ...etc) => mx2("relative", "text-start font-medium select-none truncate", headPadding, border && groupBorder, border && "border border-t-0 border-b-0 border-neutral-200", ...etc);
374
+ var tableRoot = ({ fullWidth }, ...etc) => mx3("table-fixed", fullWidth && "is-full", ...etc);
375
+ var groupTh = (_props, ...etc) => mx3("text-start font-medium", flushPadding, ...etc);
376
+ var theadRoot = ({ header, stickyHeader }, ...etc) => mx3(header ? stickyHeader && "sticky block-start-[--sticky-top] z-[1]" : "collapse", header && "base-surface", "drop-shadow-sm", ...etc);
377
+ var theadTr = (_props, ...etc) => mx3("group", ...etc);
378
+ var theadTh = ({ border }, ...etc) => mx3("relative", "text-start font-medium select-none truncate", headPadding, border && groupBorder, border && "border border-t-0 border-b-0 border-neutral-200", ...etc);
267
379
  var theadResizeRoot = ({ isResizing }) => {
268
- return mx2("absolute h-full w-[4px] top-0 right-0", "cursor-col-resize", "user-select-none", "touch-action-none", !isResizing && "group-hover:bg-neutral-100 dark:group-hover:bg-neutral-800", "pointer-coarse:bg-neutral-100 dark:pointer-coarse:bg-neutral-800", isResizing && "bg-primary-500 dark:bg-primary-400");
380
+ return mx3("absolute h-full w-[4px] top-0 right-0", "cursor-col-resize", "user-select-none", "touch-action-none", !isResizing && "group-hover:bg-neutral-100 dark:group-hover:bg-neutral-800", "pointer-coarse:bg-neutral-100 dark:pointer-coarse:bg-neutral-800", isResizing && "bg-primary-500 dark:bg-primary-400");
269
381
  };
270
- var tbodyRoot = (_props, ...etc) => mx2(...etc);
271
- var tbodyTr = ({ canBeCurrent, isPinned }, ...etc) => mx2("group", canBeCurrent ? ghostSelectedCurrent : ghostSelected, canBeCurrent && focusRing, canBeCurrent && "cursor-pointer rounded", isPinned && "sticky z-[20] bottom-[-1px] base-surface shadow-sm", ...etc);
272
- var tdRoot = ({ border, isGrid }, ...etc) => mx2("relative", flushPadding, border && "border", border && groupBorder, isGrid && gridCellFocusRing, ...etc);
273
- var tdContent = (_props, ...etc) => mx2(...etc);
274
- var tfootRoot = (_props, ...etc) => mx2("sticky block-end-0 z-10", modalSurface, ...etc);
275
- var tfootTr = (_props, ...etc) => mx2(...etc);
276
- var tfootTh = ({ border }, ...etc) => mx2(textPadding, modalSurface, border && groupBorder, ...etc);
382
+ var tbodyRoot = (_props, ...etc) => mx3(...etc);
383
+ var tbodyTr = ({ canBeCurrent, isPinned }, ...etc) => mx3("group", canBeCurrent ? ghostSelectedCurrent : ghostSelected, canBeCurrent && focusRing, canBeCurrent && "cursor-pointer rounded", isPinned && "sticky z-1 bottom-[-1px] base-surface", ...etc);
384
+ var tdRoot = ({ border, isGrid }, ...etc) => mx3("relative", flushPadding, border && "border", border && groupBorder, isGrid && gridCellFocusRing, ...etc);
385
+ var tdContent = (_props, ...etc) => mx3(...etc);
386
+ var tfootRoot = (_props, ...etc) => mx3("sticky block-end-0 z-10", modalSurface, ...etc);
387
+ var tfootTr = (_props, ...etc) => mx3(...etc);
388
+ var tfootTh = ({ border }, ...etc) => mx3(textPadding, modalSurface, border && groupBorder, ...etc);
277
389
 
278
390
  // packages/ui/react-ui-table/src/components/Cell/Cell.tsx
279
391
  import { useFocusableGroup } from "@fluentui/react-tabster";
@@ -423,9 +535,9 @@ var TableHead = (_props) => {
423
535
  TableHead.displayName = TABLE_HEAD_NAME;
424
536
 
425
537
  // packages/ui/react-ui-table/src/components/hooks/usePinLastRow.ts
426
- import { useEffect, useState as useState2 } from "react";
538
+ import { useEffect, useState as useState4 } from "react";
427
539
  var usePinLastRow = (pinLastRow, table, data, getScrollElement) => {
428
- const [pinnedRowKey, setPinnedRowKey] = useState2();
540
+ const [pinnedRowKey, setPinnedRowKey] = useState4();
429
541
  useEffect(() => {
430
542
  if (!pinLastRow) {
431
543
  return;
@@ -465,8 +577,8 @@ var Table = (props) => {
465
577
  const columns = useDefaultValue(props.columns, []);
466
578
  const data = useDefaultValue(props.data, []);
467
579
  const TableProvider2 = TableProvider;
468
- const [columnsInitialised, setColumnsInitialised] = useState3(false);
469
- const [columnSizing, setColumnSizing] = useState3({});
580
+ const [columnsInitialised, setColumnsInitialised] = useState5(false);
581
+ const [columnSizing, setColumnSizing] = useState5({});
470
582
  useEffect2(() => {
471
583
  if (columnsInitialised) {
472
584
  return;
@@ -480,8 +592,8 @@ var Table = (props) => {
480
592
  columns,
481
593
  setColumnSizing
482
594
  ]);
483
- const [columnSizingInfo, setColumnSizingInfo] = useState3({});
484
- const notifyColumnResize = useCallback(() => onColumnResize?.(columnSizing), [
595
+ const [columnSizingInfo, setColumnSizingInfo] = useState5({});
596
+ const notifyColumnResize = useCallback2(() => onColumnResize?.(columnSizing), [
485
597
  onColumnResize,
486
598
  columnSizing
487
599
  ]);
@@ -491,7 +603,7 @@ var Table = (props) => {
491
603
  onChange: props.onRowSelectionChange,
492
604
  defaultProp: props.defaultRowSelection
493
605
  });
494
- const handleRowSelectionChange = useCallback((updaterOrValue) => {
606
+ const handleRowSelectionChange = useCallback2((updaterOrValue) => {
495
607
  const nextRowSelection = typeof updaterOrValue === "function" ? updaterOrValue(rowSelection) : updaterOrValue;
496
608
  if (rowsSelectable === "multi") {
497
609
  setRowSelection(nextRowSelection);
@@ -508,7 +620,7 @@ var Table = (props) => {
508
620
  setRowSelection,
509
621
  rowSelection
510
622
  ]);
511
- const [grouping, handleGroupingChange] = useState3(props.grouping ?? []);
623
+ const [grouping, handleGroupingChange] = useState5(props.grouping ?? []);
512
624
  useEffect2(() => handleGroupingChange(props.grouping ?? []), [
513
625
  handleGroupingChange,
514
626
  props.grouping
@@ -669,11 +781,11 @@ var GroupedTableContent = () => {
669
781
  };
670
782
 
671
783
  // packages/ui/react-ui-table/src/components/Cell/CellCombobox.tsx
672
- import { CaretDown } from "@phosphor-icons/react";
673
- import React9, { useCallback as useCallback2, useState as useState4 } from "react";
784
+ import { CaretDown as CaretDown2 } from "@phosphor-icons/react";
785
+ import React9, { useCallback as useCallback3, useState as useState6 } from "react";
674
786
  import { Popover as Popover2, useTranslation as useTranslation2 } from "@dxos/react-ui";
675
787
  import { PopoverCombobox } from "@dxos/react-ui-searchlist";
676
- import { descriptionText, getSize as getSize3, mx as mx3, staticPlaceholderText } from "@dxos/react-ui-theme";
788
+ import { descriptionText, getSize as getSize3, mx as mx4, staticPlaceholderText } from "@dxos/react-ui-theme";
677
789
  var initialItems = (model, value) => value ? {
678
790
  [model.getId(value)]: {
679
791
  label: model.getText(value),
@@ -682,9 +794,9 @@ var initialItems = (model, value) => value ? {
682
794
  } : {};
683
795
  var CellCombobox = ({ model, value, onValueChange }) => {
684
796
  const { t } = useTranslation2(translationKey);
685
- const [items, setItems] = useState4(initialItems(model, value));
686
- const [loading, setLoading] = useState4(false);
687
- const [searchInputValue, setSearchInputValue] = useState4("");
797
+ const [items, setItems] = useState6(initialItems(model, value));
798
+ const [loading, setLoading] = useState6(false);
799
+ const [searchInputValue, setSearchInputValue] = useState6("");
688
800
  const handleSearchInputValueChange = async (text) => {
689
801
  setSearchInputValue(text ?? "");
690
802
  setLoading(true);
@@ -698,7 +810,7 @@ var CellCombobox = ({ model, value, onValueChange }) => {
698
810
  }, initialItems(model, value)));
699
811
  setLoading(false);
700
812
  };
701
- const handleValueChange = useCallback2((id) => {
813
+ const handleValueChange = useCallback3((id) => {
702
814
  onValueChange(items[id]?.data);
703
815
  }, [
704
816
  items,
@@ -710,8 +822,8 @@ var CellCombobox = ({ model, value, onValueChange }) => {
710
822
  variant: "ghost",
711
823
  classNames: "is-full rounded-none ring-inset"
712
824
  }, value ? /* @__PURE__ */ React9.createElement(React9.Fragment, null, /* @__PURE__ */ React9.createElement("span", {
713
- className: mx3("font-normal text-start text-base flex-1 min-is-0 truncate mie-2", !value && staticPlaceholderText)
714
- }, model.getText(value)), /* @__PURE__ */ React9.createElement(CaretDown, {
825
+ className: mx4("font-normal text-start text-base flex-1 min-is-0 truncate mie-2", !value && staticPlaceholderText)
826
+ }, model.getText(value)), /* @__PURE__ */ React9.createElement(CaretDown2, {
715
827
  weight: "bold",
716
828
  className: getSize3(3)
717
829
  })) : null), /* @__PURE__ */ React9.createElement(PopoverCombobox.Content, {
@@ -721,9 +833,9 @@ var CellCombobox = ({ model, value, onValueChange }) => {
721
833
  value: searchInputValue,
722
834
  onValueChange: handleSearchInputValueChange
723
835
  }), /* @__PURE__ */ React9.createElement(PopoverCombobox.List, null, searchInputValue.length < 1 ? /* @__PURE__ */ React9.createElement("p", {
724
- className: mx3("text-center", descriptionText)
836
+ className: mx4("text-center", descriptionText)
725
837
  }, "Start typing to search") : loading ? /* @__PURE__ */ React9.createElement("p", {
726
- className: mx3("text-center", descriptionText)
838
+ className: mx4("text-center", descriptionText)
727
839
  }, "Searching\u2026") : /* @__PURE__ */ React9.createElement(React9.Fragment, null, /* @__PURE__ */ React9.createElement(PopoverCombobox.Empty, {
728
840
  classNames: [
729
841
  "text-center",
@@ -739,14 +851,14 @@ var CellCombobox = ({ model, value, onValueChange }) => {
739
851
 
740
852
  // packages/ui/react-ui-table/src/helpers.tsx
741
853
  import { useFocusFinders } from "@fluentui/react-tabster";
742
- import { Check as Check2, ClipboardText, X as X2 } from "@phosphor-icons/react";
854
+ import { Check as Check2, ClipboardText, X as X3 } from "@phosphor-icons/react";
743
855
  import { createColumnHelper } from "@tanstack/react-table";
744
856
  import { format } from "date-fns/format";
745
857
  import { formatDistanceToNow } from "date-fns/formatDistanceToNow";
746
- import React10, { useEffect as useEffect3, useRef as useRef2, useState as useState5 } from "react";
858
+ import React10, { useEffect as useEffect3, useRef as useRef3, useState as useState7 } from "react";
747
859
  import { log as log2 } from "@dxos/log";
748
860
  import { Input as Input2, Tooltip } from "@dxos/react-ui";
749
- import { getSize as getSize4, mx as mx4 } from "@dxos/react-ui-theme";
861
+ import { getSize as getSize4, mx as mx5 } from "@dxos/react-ui-theme";
750
862
  var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-table/src/helpers.tsx";
751
863
  var createColumnBuilder = () => ({
752
864
  helper: createColumnHelper(),
@@ -761,11 +873,11 @@ var ComboboxBuilderCell = (cellContext) => {
761
873
  }) : null;
762
874
  };
763
875
  var StringBuilderCell = (cellContext) => {
764
- const ref = useRef2(null);
876
+ const ref = useRef3(null);
765
877
  const { findPrevFocusable } = useFocusFinders();
766
878
  const { onUpdate, cell } = cellContext.column.columnDef.meta;
767
879
  const initialValue = cellContext.getValue();
768
- const [value, setValue] = useState5(() => {
880
+ const [value, setValue] = useState7(() => {
769
881
  if (initialValue?.content) {
770
882
  return initialValue?.content;
771
883
  }
@@ -807,9 +919,9 @@ var displayNumber = (value, digits) => value || value === 0 ? value.toLocaleStri
807
919
  var NumberBuilderCell = (cellContext) => {
808
920
  const { onUpdate, digits } = cellContext.column.columnDef.meta;
809
921
  const value = cellContext.getValue();
810
- const [text, setText] = useState5(displayNumber(value, digits));
922
+ const [text, setText] = useState7(displayNumber(value, digits));
811
923
  const { findPrevFocusable } = useFocusFinders();
812
- const ref = useRef2(null);
924
+ const ref = useRef3(null);
813
925
  useEffect3(() => {
814
926
  (!document.activeElement || document.activeElement !== ref.current) && setText(displayNumber(value, digits));
815
927
  }, [
@@ -897,7 +1009,7 @@ var ColumnBuilder = class {
897
1009
  cell: model && onUpdate ? ComboboxBuilderCell : (cellContext) => {
898
1010
  const cellValue = cellContext.getValue();
899
1011
  return /* @__PURE__ */ React10.createElement("div", {
900
- className: mx4("truncate", classNames)
1012
+ className: mx5("truncate", classNames)
901
1013
  }, cellValue ? model?.getText(cellValue) : "");
902
1014
  },
903
1015
  ...props,
@@ -928,7 +1040,7 @@ var ColumnBuilder = class {
928
1040
  value = value.content;
929
1041
  }
930
1042
  return /* @__PURE__ */ React10.createElement("div", {
931
- className: mx4("truncate", textPadding, classNames)
1043
+ className: mx5("truncate", textPadding, classNames)
932
1044
  }, value);
933
1045
  },
934
1046
  ...props,
@@ -957,7 +1069,6 @@ var ColumnBuilder = class {
957
1069
  onUpdate,
958
1070
  digits,
959
1071
  header: {
960
- classNames: "text-end",
961
1072
  ...props.meta?.header
962
1073
  },
963
1074
  cell: {
@@ -983,7 +1094,7 @@ var ColumnBuilder = class {
983
1094
  addSuffix: true
984
1095
  }) : value.toISOString() : void 0;
985
1096
  return /* @__PURE__ */ React10.createElement("div", {
986
- className: mx4(textPadding, classNames)
1097
+ className: mx5(textPadding, classNames)
987
1098
  }, str);
988
1099
  } catch (err) {
989
1100
  log2.info("formatError", {
@@ -1110,7 +1221,7 @@ var ColumnBuilder = class {
1110
1221
  */
1111
1222
  icon({ label, size, on, off, ...props } = {}) {
1112
1223
  const IconOn = on?.Icon ?? Check2;
1113
- const IconOff = off?.Icon ?? X2;
1224
+ const IconOff = off?.Icon ?? X3;
1114
1225
  return {
1115
1226
  size: size ?? 32,
1116
1227
  // TODO(Zan): Implement sort algorithm
@@ -1122,11 +1233,11 @@ var ColumnBuilder = class {
1122
1233
  const value = cell.getValue();
1123
1234
  if (value) {
1124
1235
  return /* @__PURE__ */ React10.createElement(IconOn, {
1125
- className: mx4("block mli-auto", getSize4(6), on?.className ?? "text-green-700")
1236
+ className: mx5("block mli-auto", getSize4(6), on?.className ?? "text-green-700")
1126
1237
  });
1127
1238
  } else if (value === false) {
1128
1239
  return /* @__PURE__ */ React10.createElement(IconOff, {
1129
- className: mx4("block mli-auto", getSize4(6), off?.className ?? "text-red-700")
1240
+ className: mx5("block mli-auto", getSize4(6), off?.className ?? "text-red-700")
1130
1241
  });
1131
1242
  } else {
1132
1243
  return null;
@@ -1140,8 +1251,9 @@ export {
1140
1251
  CellCombobox,
1141
1252
  ColumnBuilder,
1142
1253
  ColumnMenu,
1143
- ColumnPanel,
1254
+ ColumnSettingsPanel,
1144
1255
  MemoizedVirtualisedTableContent,
1256
+ SortIndicator,
1145
1257
  Table,
1146
1258
  createColumnBuilder,
1147
1259
  currentRow,