@dxos/react-ui-table 0.4.8-main.457648 → 0.4.8-main.4a229ac

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 (31) hide show
  1. package/dist/lib/browser/index.mjs +276 -191
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/types/src/components/Cell/Cell.d.ts.map +1 -1
  5. package/dist/types/src/components/ColumnMenu.d.ts.map +1 -1
  6. package/dist/types/src/components/ColumnMenu.stories.d.ts +10 -1
  7. package/dist/types/src/components/ColumnMenu.stories.d.ts.map +1 -1
  8. package/dist/types/src/components/SortButton.d.ts +8 -0
  9. package/dist/types/src/components/SortButton.d.ts.map +1 -0
  10. package/dist/types/src/components/Table/Table.d.ts +2 -0
  11. package/dist/types/src/components/Table/Table.d.ts.map +1 -1
  12. package/dist/types/src/components/Table/Table.stories.d.ts.map +1 -1
  13. package/dist/types/src/components/Table/TableBody.d.ts.map +1 -1
  14. package/dist/types/src/components/Table/TableHead.d.ts.map +1 -1
  15. package/dist/types/src/components/Table/props.d.ts +1 -0
  16. package/dist/types/src/components/Table/props.d.ts.map +1 -1
  17. package/dist/types/src/helpers.d.ts.map +1 -1
  18. package/dist/types/src/theme.d.ts +1 -1
  19. package/dist/types/src/theme.d.ts.map +1 -1
  20. package/package.json +15 -15
  21. package/src/components/Cell/Cell.tsx +4 -1
  22. package/src/components/ColumnMenu.stories.tsx +13 -6
  23. package/src/components/ColumnMenu.tsx +13 -4
  24. package/src/components/SortButton.tsx +34 -0
  25. package/src/components/Table/Table.stories.tsx +51 -62
  26. package/src/components/Table/Table.tsx +64 -41
  27. package/src/components/Table/TableBody.tsx +1 -0
  28. package/src/components/Table/TableHead.tsx +4 -2
  29. package/src/components/Table/props.ts +1 -0
  30. package/src/helpers.tsx +61 -45
  31. package/src/theme.ts +3 -1
@@ -1,10 +1,40 @@
1
1
  // packages/ui/react-ui-table/src/components/ColumnMenu.tsx
2
- import { Check, CaretDown, Trash, X } from "@phosphor-icons/react";
3
- import React, { useRef, useState } from "react";
4
- import { Button, DensityProvider, Input, Popover, Select, Separator, useTranslation } from "@dxos/react-ui";
5
- import { getSize, mx } from "@dxos/react-ui-theme";
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
6
  import { safeParseInt } from "@dxos/util";
7
7
 
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
+ };
37
+
8
38
  // packages/ui/react-ui-table/src/translations.ts
9
39
  var translationKey = "table";
10
40
  var translations_default = [
@@ -31,19 +61,26 @@ var translations_default = [
31
61
  // packages/ui/react-ui-table/src/components/ColumnMenu.tsx
32
62
  var ColumnMenu = ({ column, ...props }) => {
33
63
  const title = column.label?.length ? column.label : column.id;
34
- return /* @__PURE__ */ React.createElement("div", {
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", {
35
69
  className: "flex items-center gap-2"
36
- }, /* @__PURE__ */ React.createElement("div", {
70
+ }, /* @__PURE__ */ React2.createElement("div", {
37
71
  className: "flex-1 min-is-0 truncate",
38
72
  title
39
- }, title), /* @__PURE__ */ React.createElement("div", {
40
- className: "flex shrink-0"
41
- }, /* @__PURE__ */ React.createElement(ColumnPanel, {
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, {
42
79
  ...props,
43
80
  column
44
81
  })));
45
82
  };
46
- var Section = ({ children, className }) => /* @__PURE__ */ React.createElement("div", {
83
+ var Section = ({ children, className }) => /* @__PURE__ */ React2.createElement("div", {
47
84
  role: "none",
48
85
  className: mx("p-2", className)
49
86
  }, children);
@@ -84,123 +121,123 @@ var ColumnPanel = ({ context, tableDefs, tableDef, column, onUpdate, onDelete })
84
121
  });
85
122
  setOpen(false);
86
123
  };
87
- return /* @__PURE__ */ React.createElement(Popover.Root, {
124
+ return /* @__PURE__ */ React2.createElement(Popover.Root, {
88
125
  open,
89
126
  onOpenChange: (nextOpen) => setOpen(nextOpen)
90
- }, /* @__PURE__ */ React.createElement(Popover.Trigger, {
127
+ }, /* @__PURE__ */ React2.createElement(Popover.Trigger, {
91
128
  asChild: true
92
- }, /* @__PURE__ */ React.createElement(Button, {
93
- variant: "ghost",
94
- classNames: "p-1"
95
- }, /* @__PURE__ */ React.createElement(CaretDown, {
96
- className: getSize(4)
97
- }))), /* @__PURE__ */ React.createElement(Popover.Portal, null, /* @__PURE__ */ React.createElement(Popover.Content, null, /* @__PURE__ */ React.createElement(Popover.Viewport, {
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, {
98
134
  classNames: "w-60"
99
- }, /* @__PURE__ */ React.createElement(DensityProvider, {
135
+ }, /* @__PURE__ */ React2.createElement(DensityProvider, {
100
136
  density: "fine"
101
- }, /* @__PURE__ */ React.createElement("div", {
137
+ }, /* @__PURE__ */ React2.createElement("div", {
102
138
  className: "flex flex-col gap-1"
103
- }, /* @__PURE__ */ React.createElement(Section, null, /* @__PURE__ */ React.createElement(Input.Root, null, /* @__PURE__ */ React.createElement(Input.Label, {
139
+ }, /* @__PURE__ */ React2.createElement(Section, null, /* @__PURE__ */ React2.createElement(Input.Root, null, /* @__PURE__ */ React2.createElement(Input.Label, {
104
140
  classNames: "mbe-1"
105
- }, t("column label label")), /* @__PURE__ */ React.createElement(Input.TextInput, {
141
+ }, t("column label label")), /* @__PURE__ */ React2.createElement(Input.TextInput, {
106
142
  placeholder: "Column label",
107
143
  value: label ?? "",
108
144
  onChange: (event) => setLabel(event.target.value),
109
145
  autoFocus: true
110
- })), /* @__PURE__ */ React.createElement(Input.Root, null, /* @__PURE__ */ React.createElement(Input.Label, {
146
+ })), /* @__PURE__ */ React2.createElement(Input.Root, null, /* @__PURE__ */ React2.createElement(Input.Label, {
111
147
  classNames: "mbe-1 mbs-3"
112
- }, t("property key label")), /* @__PURE__ */ React.createElement(Input.TextInput, {
148
+ }, t("property key label")), /* @__PURE__ */ React2.createElement(Input.TextInput, {
113
149
  ref: propRef,
114
150
  placeholder: "Property key",
115
151
  // TODO(burdon): Provide hooks for value normalization, ENTER, ESC, etc.
116
152
  value: prop ?? "",
117
153
  onChange: (event) => setProp(event.target.value.replace(/[^\w_]/g, ""))
118
- })), /* @__PURE__ */ React.createElement(Input.Root, null, /* @__PURE__ */ React.createElement(Input.Label, {
154
+ })), /* @__PURE__ */ React2.createElement(Input.Root, null, /* @__PURE__ */ React2.createElement(Input.Label, {
119
155
  classNames: "mbe-1 mbs-3"
120
- }, t("column type label")), /* @__PURE__ */ React.createElement(Select.Root, {
156
+ }, t("column type label")), /* @__PURE__ */ React2.createElement(Select.Root, {
121
157
  value: type,
122
158
  onValueChange: setType
123
- }, /* @__PURE__ */ React.createElement(Select.TriggerButton, {
159
+ }, /* @__PURE__ */ React2.createElement(Select.TriggerButton, {
124
160
  placeholder: "Type",
125
161
  classNames: "is-full"
126
- }), /* @__PURE__ */ React.createElement(Select.Portal, null, /* @__PURE__ */ React.createElement(Select.Content, null, /* @__PURE__ */ React.createElement(Select.Viewport, null, [
162
+ }), /* @__PURE__ */ React2.createElement(Select.Portal, null, /* @__PURE__ */ React2.createElement(Select.Content, null, /* @__PURE__ */ React2.createElement(Select.Viewport, null, [
127
163
  "number",
128
164
  "boolean",
129
165
  "string",
130
166
  "ref"
131
- ].map((type2) => /* @__PURE__ */ React.createElement(Select.Option, {
167
+ ].map((type2) => /* @__PURE__ */ React2.createElement(Select.Option, {
132
168
  key: type2,
133
169
  value: type2
134
- }, 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, {
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, {
135
171
  classNames: "mbe-1 mbs-3"
136
- }, t("digits label")), /* @__PURE__ */ React.createElement(Input.TextInput, {
172
+ }, t("digits label")), /* @__PURE__ */ React2.createElement(Input.TextInput, {
137
173
  value: digits ?? "",
138
174
  onChange: (event) => setDigits(event.target.value)
139
- })))), type === "ref" && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Section, null, /* @__PURE__ */ React.createElement(Input.Root, null, /* @__PURE__ */ React.createElement(Input.Label, {
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, {
140
176
  classNames: "mbe-1 mbs-3"
141
- }, "Table"), /* @__PURE__ */ React.createElement(Select.Root, {
177
+ }, "Table"), /* @__PURE__ */ React2.createElement(Select.Root, {
142
178
  value: refTable,
143
179
  onValueChange: setRefTable
144
- }, /* @__PURE__ */ React.createElement(Select.TriggerButton, {
180
+ }, /* @__PURE__ */ React2.createElement(Select.TriggerButton, {
145
181
  placeholder: "Table",
146
182
  classNames: "is-full"
147
- }), /* @__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, {
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, {
148
184
  key: id,
149
185
  value: id
150
- }, name ?? id))))))), refTable && /* @__PURE__ */ React.createElement(Input.Root, null, /* @__PURE__ */ React.createElement(Input.Label, {
186
+ }, name ?? id))))))), refTable && /* @__PURE__ */ React2.createElement(Input.Root, null, /* @__PURE__ */ React2.createElement(Input.Label, {
151
187
  classNames: "mbe-1 mbs-3"
152
- }, "Table property"), /* @__PURE__ */ React.createElement(Select.Root, {
188
+ }, "Table property"), /* @__PURE__ */ React2.createElement(Select.Root, {
153
189
  value: refProp,
154
190
  onValueChange: setRefProp
155
- }, /* @__PURE__ */ React.createElement(Select.TriggerButton, {
191
+ }, /* @__PURE__ */ React2.createElement(Select.TriggerButton, {
156
192
  placeholder: "Property",
157
193
  classNames: "is-full"
158
- }), /* @__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, {
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, {
159
195
  key: id,
160
196
  value: id
161
- }, label2 ?? id))))))))), /* @__PURE__ */ React.createElement(Separator, {
197
+ }, label2 ?? id))))))))), /* @__PURE__ */ React2.createElement(Separator, {
162
198
  classNames: "mli-2"
163
- }), /* @__PURE__ */ React.createElement(Section, {
199
+ }), /* @__PURE__ */ React2.createElement(Section, {
164
200
  className: "space-b-1.5"
165
- }, /* @__PURE__ */ React.createElement(Button, {
201
+ }, /* @__PURE__ */ React2.createElement(Button2, {
166
202
  variant: "primary",
167
203
  classNames: "is-full flex gap-2",
168
204
  onClick: handleSave
169
- }, /* @__PURE__ */ React.createElement("span", null, t("save label")), /* @__PURE__ */ React.createElement("div", {
205
+ }, /* @__PURE__ */ React2.createElement("span", null, t("save label")), /* @__PURE__ */ React2.createElement("div", {
170
206
  className: "grow"
171
- }), /* @__PURE__ */ React.createElement(Check, {
172
- className: getSize(5)
173
- })), /* @__PURE__ */ React.createElement(Button, {
207
+ }), /* @__PURE__ */ React2.createElement(Check, {
208
+ className: getSize2(5)
209
+ })), /* @__PURE__ */ React2.createElement(Button2, {
174
210
  classNames: "is-full flex gap-2",
175
211
  onClick: handleCancel
176
- }, /* @__PURE__ */ React.createElement("span", null, t("cancel label", {
212
+ }, /* @__PURE__ */ React2.createElement("span", null, t("cancel label", {
177
213
  ns: "os"
178
- })), /* @__PURE__ */ React.createElement("div", {
214
+ })), /* @__PURE__ */ React2.createElement("div", {
179
215
  className: "grow"
180
- }), /* @__PURE__ */ React.createElement(X, {
181
- className: getSize(5)
182
- })), /* @__PURE__ */ React.createElement(Button, {
216
+ }), /* @__PURE__ */ React2.createElement(X, {
217
+ className: getSize2(5)
218
+ })), /* @__PURE__ */ React2.createElement(Button2, {
183
219
  classNames: "is-full flex gap-2",
184
220
  onClick: () => onDelete?.(column.id)
185
- }, /* @__PURE__ */ React.createElement("span", null, t("delete label")), /* @__PURE__ */ React.createElement("div", {
221
+ }, /* @__PURE__ */ React2.createElement("span", null, t("delete label")), /* @__PURE__ */ React2.createElement("div", {
186
222
  className: "grow"
187
- }), /* @__PURE__ */ React.createElement(Trash, {
188
- className: getSize(5)
189
- })))))), /* @__PURE__ */ React.createElement(Popover.Arrow, null))));
223
+ }), /* @__PURE__ */ React2.createElement(Trash, {
224
+ className: getSize2(5)
225
+ })))))), /* @__PURE__ */ React2.createElement(Popover.Arrow, null))));
190
226
  };
191
227
 
192
228
  // packages/ui/react-ui-table/src/components/Table/Table.tsx
193
229
  import { useControllableState } from "@radix-ui/react-use-controllable-state";
194
- import { getCoreRowModel, useReactTable, getGroupedRowModel } from "@tanstack/react-table";
230
+ import { getCoreRowModel, getSortedRowModel, useReactTable, getGroupedRowModel, getExpandedRowModel } from "@tanstack/react-table";
195
231
  import { useVirtualizer } from "@tanstack/react-virtual";
196
- import React6, { Fragment, useCallback, useEffect, useState as useState2 } from "react";
232
+ import React7, { Fragment, useCallback, useEffect, useState as useState2 } from "react";
197
233
  import { debounce } from "@dxos/async";
198
234
  import { log } from "@dxos/log";
235
+ import { useDefaultValue } from "@dxos/react-ui";
199
236
 
200
237
  // packages/ui/react-ui-table/src/components/Table/TableBody.tsx
201
238
  import { useArrowNavigationGroup } from "@fluentui/react-tabster";
202
239
  import { flexRender } from "@tanstack/react-table";
203
- import React3 from "react";
240
+ import React4 from "react";
204
241
 
205
242
  // packages/ui/react-ui-table/src/components/Table/TableContext.tsx
206
243
  import { createContext } from "@radix-ui/react-context";
@@ -215,7 +252,7 @@ var selectedRow = "!bg-primary-100 dark:!bg-primary-700";
215
252
  var flushPadding = "pli-0 plb-0";
216
253
  var textPadding = "pli-2 plb-0.5";
217
254
  var headPadding = "pli-2 plb-1.5";
218
- var gridCellFocusRing = "focus:z-[11] focus:outline outline-2 outline-primary-500 dark:outline-primary-400";
255
+ var gridCellFocusRing = "focus-within:z-[11] focus-within:outline outline-2 outline-primary-500 dark:outline-primary-400";
219
256
  var tableRoot = ({ fullWidth }, ...etc) => mx2("table-fixed", fullWidth && "is-full", ...etc);
220
257
  var groupTh = (_props, ...etc) => mx2("text-start font-medium", flushPadding, ...etc);
221
258
  var theadRoot = ({ header, stickyHeader }, ...etc) => mx2(header ? stickyHeader && "sticky block-start-[--sticky-top] z-[1]" : "collapse", header && fixedSurface, ...etc);
@@ -233,29 +270,30 @@ var tfootTh = ({ border }, ...etc) => mx2(textPadding, modalSurface, border && g
233
270
 
234
271
  // packages/ui/react-ui-table/src/components/Cell/Cell.tsx
235
272
  import { useFocusableGroup } from "@fluentui/react-tabster";
236
- import React2 from "react";
273
+ import React3 from "react";
237
274
  var CELL_NAME = "Cell";
238
275
  var FocusableCell = ({ cell, children }) => {
239
276
  const tableContext = useTableContext(CELL_NAME);
240
277
  const domAttributes = useFocusableGroup({
241
278
  tabBehavior: "limited"
242
279
  });
243
- return /* @__PURE__ */ React2.createElement("td", {
280
+ const className = tdRoot(tableContext, cell.column.columnDef.meta?.cell?.classNames);
281
+ return /* @__PURE__ */ React3.createElement("td", {
244
282
  tabIndex: 0,
245
283
  ...domAttributes,
246
- className: tdRoot(tableContext, cell.column.columnDef.meta?.cell?.classNames)
284
+ className
247
285
  }, children);
248
286
  };
249
287
  var StaticCell = ({ cell, children }) => {
250
288
  const tableContext = useTableContext(CELL_NAME);
251
- return /* @__PURE__ */ React2.createElement("td", {
289
+ return /* @__PURE__ */ React3.createElement("td", {
252
290
  className: tdRoot(tableContext, cell.column.columnDef.meta?.cell?.classNames)
253
291
  }, children);
254
292
  };
255
293
  var Cell = ({ cell, children }) => {
256
294
  const { isGrid } = useTableContext(CELL_NAME);
257
295
  const Root = isGrid ? FocusableCell : StaticCell;
258
- return /* @__PURE__ */ React2.createElement(Root, {
296
+ return /* @__PURE__ */ React3.createElement(Root, {
259
297
  cell
260
298
  }, children);
261
299
  };
@@ -270,10 +308,10 @@ var TableBody = ({ rows }) => {
270
308
  axis: "grid"
271
309
  });
272
310
  const canBeCurrent = !isGrid && !!onDatumClick;
273
- return /* @__PURE__ */ React3.createElement("tbody", isGrid && domAttributes, rows.map((row) => {
311
+ return /* @__PURE__ */ React4.createElement("tbody", isGrid && domAttributes, rows.map((row) => {
274
312
  const isCurrent = currentDatum === row.original;
275
313
  const isSelected = rowSelection?.[row.id];
276
- return /* @__PURE__ */ React3.createElement("tr", {
314
+ return /* @__PURE__ */ React4.createElement("tr", {
277
315
  key: keyAccessor ? keyAccessor(row.original) : row.id,
278
316
  className: tbodyTr({
279
317
  canBeCurrent
@@ -295,82 +333,83 @@ var TableBody = ({ rows }) => {
295
333
  }
296
334
  }
297
335
  }
298
- }, debug && /* @__PURE__ */ React3.createElement("td", null, row.id), row.getVisibleCells().map((cell) => {
299
- return /* @__PURE__ */ React3.createElement(Cell, {
336
+ }, debug && /* @__PURE__ */ React4.createElement("td", null, row.id), row.getVisibleCells().map((cell) => {
337
+ return /* @__PURE__ */ React4.createElement(Cell, {
300
338
  key: cell.id,
301
339
  cell
302
340
  }, flexRender(cell.column.columnDef.cell, {
303
341
  className: "pli-2",
304
342
  ...cell.getContext()
305
343
  }));
306
- }), expand && /* @__PURE__ */ React3.createElement("td", null));
344
+ }), expand && /* @__PURE__ */ React4.createElement("td", null));
307
345
  }));
308
346
  };
309
347
  TableBody.displayName = TABLE_BODY_NAME;
310
348
 
311
349
  // packages/ui/react-ui-table/src/components/Table/TableFooter.tsx
312
350
  import { flexRender as flexRender2 } from "@tanstack/react-table";
313
- import React4 from "react";
351
+ import React5 from "react";
314
352
  var TABLE_FOOT_NAME = "TableFooter";
315
353
  var TableFooter = (props) => {
316
354
  const tableContext = useTableContext(TABLE_FOOT_NAME);
317
355
  const { table, expand, debug } = tableContext;
318
356
  const footers = table.getFooterGroups();
319
- return /* @__PURE__ */ React4.createElement("tfoot", {
357
+ return /* @__PURE__ */ React5.createElement("tfoot", {
320
358
  className: tfootRoot(props)
321
- }, footers.map((footerGroup) => /* @__PURE__ */ React4.createElement("tr", {
359
+ }, footers.map((footerGroup) => /* @__PURE__ */ React5.createElement("tr", {
322
360
  key: footerGroup.id,
323
361
  className: tfootTr(tableContext)
324
- }, debug && /* @__PURE__ */ React4.createElement("th", null), footerGroup.headers.map((footer) => {
325
- return /* @__PURE__ */ React4.createElement("th", {
362
+ }, debug && /* @__PURE__ */ React5.createElement("th", null), footerGroup.headers.map((footer) => {
363
+ return /* @__PURE__ */ React5.createElement("th", {
326
364
  key: footer.id,
327
365
  className: tfootTh(tableContext, footer.column.columnDef.meta?.footer?.classNames)
328
366
  }, footer.isPlaceholder ? null : flexRender2(footer.column.columnDef.footer, footer.getContext()));
329
- }), expand && /* @__PURE__ */ React4.createElement("th", null))));
367
+ }), expand && /* @__PURE__ */ React5.createElement("th", null))));
330
368
  };
331
369
  TableFooter.displayName = TABLE_FOOT_NAME;
332
370
 
333
371
  // packages/ui/react-ui-table/src/components/Table/TableHead.tsx
334
372
  import { flexRender as flexRender3 } from "@tanstack/react-table";
335
- import React5 from "react";
373
+ import React6 from "react";
336
374
  import { mx as mx3 } from "@dxos/react-ui-theme";
337
375
  var TABLE_HEAD_NAME = "TableHeader";
338
376
  var TableHead = (_props) => {
339
377
  const tableContext = useTableContext(TABLE_HEAD_NAME);
340
378
  const headerGroups = tableContext.table.getHeaderGroups();
341
379
  const state = tableContext.table.getState();
342
- return /* @__PURE__ */ React5.createElement("thead", {
380
+ return /* @__PURE__ */ React6.createElement("thead", {
343
381
  className: theadRoot(tableContext)
344
382
  }, headerGroups.map((headerGroup) => {
345
383
  return (
346
384
  // Group element to hover resize handles.
347
- /* @__PURE__ */ React5.createElement("tr", {
385
+ /* @__PURE__ */ React6.createElement("tr", {
348
386
  key: headerGroup.id,
349
387
  className: theadTr(tableContext)
350
- }, tableContext.debug && /* @__PURE__ */ React5.createElement("th", {
388
+ }, tableContext.debug && /* @__PURE__ */ React6.createElement("th", {
351
389
  className: "font-mono",
352
390
  style: {
353
391
  width: 32
354
392
  }
355
393
  }, "#"), headerGroup.headers.map((header) => {
356
394
  const isResizing = header.column.getIsResizing();
357
- return /* @__PURE__ */ React5.createElement("th", {
395
+ const resizeHandler = header.getResizeHandler();
396
+ return /* @__PURE__ */ React6.createElement("th", {
358
397
  key: header.id,
359
398
  style: {
360
399
  width: header.getSize()
361
400
  },
362
401
  className: theadTh(tableContext, header.column.columnDef.meta?.header?.classNames)
363
- }, !header || header.isPlaceholder ? null : flexRender3(header.column.columnDef.header, header.getContext()), header.column.columnDef.meta?.resizable && /* @__PURE__ */ React5.createElement("div", {
402
+ }, !header || header.isPlaceholder ? null : flexRender3(header.column.columnDef.header, header.getContext()), header.column.columnDef.meta?.resizable && /* @__PURE__ */ React6.createElement("div", {
364
403
  className: theadResizeRoot(tableContext, isResizing && "hidden"),
365
404
  style: {
366
405
  transform: `translateX(${isResizing ? state.columnSizingInfo.deltaOffset : 0}px)`
367
406
  },
368
- onMouseDown: header.getResizeHandler(),
369
- onTouchStart: header.getResizeHandler()
370
- }, /* @__PURE__ */ React5.createElement("div", {
407
+ onMouseDown: resizeHandler,
408
+ onTouchStart: resizeHandler
409
+ }, /* @__PURE__ */ React6.createElement("div", {
371
410
  className: mx3(theadResizeThumb(tableContext))
372
411
  })));
373
- }), tableContext.expand && /* @__PURE__ */ React5.createElement("th", null))
412
+ }), tableContext.expand && /* @__PURE__ */ React6.createElement("th", null))
374
413
  );
375
414
  }));
376
415
  };
@@ -379,7 +418,9 @@ TableHead.displayName = TABLE_HEAD_NAME;
379
418
  // packages/ui/react-ui-table/src/components/Table/Table.tsx
380
419
  var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-table/src/components/Table/Table.tsx";
381
420
  var Table = (props) => {
382
- const { role, data = [], columns = [], onColumnResize, columnVisibility, header = true, rowsSelectable, debug, onDataSelectionChange, getScrollElement } = props;
421
+ const { role, onColumnResize, columnVisibility, header = true, rowsSelectable, debug, onDataSelectionChange, getScrollElement, pinLastRow } = props;
422
+ const columns = useDefaultValue(props.columns, []);
423
+ const data = useDefaultValue(props.data, []);
383
424
  const TableProvider2 = TableProvider;
384
425
  const [columnSizing, setColumnSizing] = useState2({});
385
426
  useEffect(() => {
@@ -388,28 +429,15 @@ var Table = (props) => {
388
429
  return state;
389
430
  }, {}));
390
431
  }, [
391
- columns
432
+ columns,
433
+ setColumnSizing
392
434
  ]);
393
435
  const [columnSizingInfo, setColumnSizingInfo] = useState2({});
394
- const onColumnResizeDebounced = onColumnResize && debounce(onColumnResize, 1e3);
395
- useEffect(() => {
396
- if (columnSizingInfo.columnSizingStart?.length === 0) {
397
- onColumnResizeDebounced?.(table.getState().columnSizing);
398
- }
399
- }, [
400
- columnSizingInfo
401
- ]);
402
436
  const [rowSelection = {}, setRowSelection] = useControllableState({
403
437
  prop: props.rowSelection,
404
438
  onChange: props.onRowSelectionChange,
405
439
  defaultProp: props.defaultRowSelection
406
440
  });
407
- useEffect(() => {
408
- onDataSelectionChange?.(Object.keys(rowSelection).map((id) => table.getRowModel().rowsById[id].original));
409
- }, [
410
- onDataSelectionChange,
411
- rowSelection
412
- ]);
413
441
  const handleRowSelectionChange = useCallback((updaterOrValue) => {
414
442
  const nextRowSelection = typeof updaterOrValue === "function" ? updaterOrValue(rowSelection) : updaterOrValue;
415
443
  if (rowsSelectable === "multi") {
@@ -423,11 +451,13 @@ var Table = (props) => {
423
451
  setRowSelection({});
424
452
  }
425
453
  }, [
426
- rowSelection,
427
- setRowSelection
454
+ rowsSelectable,
455
+ setRowSelection,
456
+ rowSelection
428
457
  ]);
429
458
  const [grouping, handleGroupingChange] = useState2(props.grouping ?? []);
430
459
  useEffect(() => handleGroupingChange(props.grouping ?? []), [
460
+ handleGroupingChange,
431
461
  props.grouping
432
462
  ]);
433
463
  const table = useReactTable({
@@ -455,35 +485,64 @@ var Table = (props) => {
455
485
  onColumnSizingInfoChange: setColumnSizingInfo,
456
486
  // Rows
457
487
  getCoreRowModel: getCoreRowModel(),
488
+ getSortedRowModel: getSortedRowModel(),
489
+ getExpandedRowModel: getExpandedRowModel(),
458
490
  // Grouping
459
491
  getGroupedRowModel: grouping.length > 1 ? getGroupedRowModel() : void 0,
460
492
  onGroupingChange: handleGroupingChange,
461
- // Selection
462
- ...rowsSelectable === "multi" ? {
463
- enableMultiRowSelection: true
464
- } : rowsSelectable ? {
465
- enableRowSelection: true
466
- } : {},
493
+ enableMultiRowSelection: rowsSelectable === "multi" ? true : void 0,
494
+ enableRowSelection: rowsSelectable === true ? true : void 0,
467
495
  onRowSelectionChange: handleRowSelectionChange,
496
+ enableSorting: true,
497
+ enableColumnPinning: true,
468
498
  // Debug
469
499
  debugTable: debug
470
500
  });
501
+ const onColumnResizeDebounced = onColumnResize && debounce(onColumnResize, 1e3);
502
+ useEffect(() => {
503
+ onDataSelectionChange?.(Object.keys(rowSelection).map((id) => table.getRowModel().rowsById[id].original));
504
+ }, [
505
+ onDataSelectionChange,
506
+ rowSelection,
507
+ table
508
+ ]);
509
+ useEffect(() => {
510
+ if (pinLastRow) {
511
+ table.resetRowPinning();
512
+ const rows = table.getRowModel().rows;
513
+ rows[rows.length - 1].pin("bottom");
514
+ }
515
+ }, [
516
+ pinLastRow,
517
+ table,
518
+ data
519
+ ]);
520
+ useEffect(() => {
521
+ const shouldTriggerResize = columnSizingInfo.columnSizingStart?.length === 0;
522
+ if (shouldTriggerResize) {
523
+ onColumnResizeDebounced?.(table.getState().columnSizing);
524
+ }
525
+ }, [
526
+ columnSizingInfo,
527
+ onColumnResizeDebounced,
528
+ table
529
+ ]);
471
530
  const expand = false;
472
531
  if (!getScrollElement) {
473
532
  log.warn("Table: getScrollElement is not set. This is required for virtualized tables.", void 0, {
474
533
  F: __dxlog_file,
475
- L: 159,
534
+ L: 167,
476
535
  S: void 0,
477
536
  C: (f, a) => f(...a)
478
537
  });
479
538
  }
480
- return /* @__PURE__ */ React6.createElement(TableProvider2, {
539
+ return /* @__PURE__ */ React7.createElement(TableProvider2, {
481
540
  ...props,
482
541
  table,
483
542
  header,
484
543
  expand,
485
544
  isGrid: role === "grid" || role === "treegrid"
486
- }, /* @__PURE__ */ React6.createElement(TableImpl, {
545
+ }, /* @__PURE__ */ React7.createElement(TableImpl, {
487
546
  debug: false,
488
547
  getScrollElement,
489
548
  ...props
@@ -492,13 +551,19 @@ var Table = (props) => {
492
551
  var TableImpl = (props) => {
493
552
  const { debug, classNames, getScrollElement, role, footer, grouping, fullWidth } = props;
494
553
  const { table } = useTableContext("TableImpl");
495
- const { rows } = table.getRowModel();
554
+ const centerRows = table.getCenterRows();
555
+ const bottomRows = table.getBottomRows();
556
+ const rows = [
557
+ ...centerRows,
558
+ ...bottomRows
559
+ ];
496
560
  if (debug) {
497
- return /* @__PURE__ */ React6.createElement("pre", {
561
+ return /* @__PURE__ */ React7.createElement("pre", {
498
562
  className: "font-mono text-xs text-neutral-500 m-1 p-2 ring"
499
- }, /* @__PURE__ */ React6.createElement("code", null, JSON.stringify(table.getState(), void 0, 2)));
563
+ }, /* @__PURE__ */ React7.createElement("code", null, JSON.stringify(table.getState(), void 0, 2)));
500
564
  }
501
- return /* @__PURE__ */ React6.createElement("table", {
565
+ const isResizingColumn = table.getState().columnSizingInfo.isResizingColumn;
566
+ return /* @__PURE__ */ React7.createElement("table", {
502
567
  role,
503
568
  className: tableRoot(props, classNames),
504
569
  ...!fullWidth && {
@@ -506,15 +571,22 @@ var TableImpl = (props) => {
506
571
  width: table.getTotalSize()
507
572
  }
508
573
  }
509
- }, /* @__PURE__ */ React6.createElement(TableHead, null), grouping?.length !== 0 ? getScrollElement ? /* @__PURE__ */ React6.createElement(VirtualizedTableContent, {
574
+ }, /* @__PURE__ */ React7.createElement(TableHead, null), grouping?.length !== 0 ? getScrollElement ? isResizingColumn ? /* @__PURE__ */ React7.createElement(MemoizedVirtualisedTableContent, {
510
575
  getScrollElement
511
- }) : /* @__PURE__ */ React6.createElement(TableBody, {
576
+ }) : /* @__PURE__ */ React7.createElement(VirtualizedTableContent, {
577
+ getScrollElement
578
+ }) : /* @__PURE__ */ React7.createElement(TableBody, {
512
579
  rows
513
- }) : /* @__PURE__ */ React6.createElement(GroupedTableContent, null), footer && /* @__PURE__ */ React6.createElement(TableFooter, null));
580
+ }) : /* @__PURE__ */ React7.createElement(GroupedTableContent, null), footer && /* @__PURE__ */ React7.createElement(TableFooter, null));
514
581
  };
515
582
  var VirtualizedTableContent = ({ getScrollElement }) => {
516
- const { table: { getRowModel } } = useTableContext("VirtualizedTableContent");
517
- const rows = getRowModel().rows;
583
+ const { table } = useTableContext("VirtualizedTableContent");
584
+ const centerRows = table.getCenterRows();
585
+ const pinnedRows = table.getBottomRows();
586
+ const rows = [
587
+ ...centerRows,
588
+ ...pinnedRows
589
+ ];
518
590
  const { getTotalSize, getVirtualItems } = useVirtualizer({
519
591
  getScrollElement,
520
592
  count: rows.length,
@@ -525,49 +597,50 @@ var VirtualizedTableContent = ({ getScrollElement }) => {
525
597
  const totalSize = getTotalSize();
526
598
  const paddingTop = virtualRows.length > 0 ? virtualRows?.[0]?.start || 0 : 0;
527
599
  const paddingBottom = virtualRows.length > 0 ? totalSize - (virtualRows?.[virtualRows.length - 1]?.end || 0) : 0;
528
- return /* @__PURE__ */ React6.createElement(React6.Fragment, null, paddingTop > 0 && /* @__PURE__ */ React6.createElement("tbody", {
600
+ return /* @__PURE__ */ React7.createElement(React7.Fragment, null, paddingTop > 0 && /* @__PURE__ */ React7.createElement("tbody", {
529
601
  role: "none"
530
- }, /* @__PURE__ */ React6.createElement("tr", {
602
+ }, /* @__PURE__ */ React7.createElement("tr", {
531
603
  role: "none"
532
- }, /* @__PURE__ */ React6.createElement("td", {
604
+ }, /* @__PURE__ */ React7.createElement("td", {
533
605
  style: {
534
606
  height: `${paddingTop}px`
535
607
  },
536
608
  role: "none"
537
- }))), /* @__PURE__ */ React6.createElement(TableBody, {
609
+ }))), /* @__PURE__ */ React7.createElement(TableBody, {
538
610
  rows: virtualRows.map((virtualRow) => rows[virtualRow.index])
539
- }), paddingBottom > 0 && /* @__PURE__ */ React6.createElement("tbody", {
611
+ }), paddingBottom > 0 && /* @__PURE__ */ React7.createElement("tbody", {
540
612
  role: "none"
541
- }, /* @__PURE__ */ React6.createElement("tr", {
613
+ }, /* @__PURE__ */ React7.createElement("tr", {
542
614
  role: "none"
543
- }, /* @__PURE__ */ React6.createElement("td", {
615
+ }, /* @__PURE__ */ React7.createElement("td", {
544
616
  style: {
545
617
  height: `${paddingBottom}px`
546
618
  },
547
619
  role: "none"
548
620
  }))));
549
621
  };
622
+ var MemoizedVirtualisedTableContent = /* @__PURE__ */ React7.memo(VirtualizedTableContent);
550
623
  var GroupedTableContent = () => {
551
624
  const { table: { getGroupedRowModel: getGroupedRowModel2, getHeaderGroups, getState }, debug } = useTableContext("GroupedTableContent");
552
- return /* @__PURE__ */ React6.createElement(React6.Fragment, null, getGroupedRowModel2().rows.map((row, i) => {
553
- return /* @__PURE__ */ React6.createElement(Fragment, {
625
+ return /* @__PURE__ */ React7.createElement(React7.Fragment, null, getGroupedRowModel2().rows.map((row, i) => {
626
+ return /* @__PURE__ */ React7.createElement(Fragment, {
554
627
  key: i
555
- }, /* @__PURE__ */ React6.createElement("thead", null, /* @__PURE__ */ React6.createElement("tr", null, debug && /* @__PURE__ */ React6.createElement("th", null), /* @__PURE__ */ React6.createElement("th", {
628
+ }, /* @__PURE__ */ React7.createElement("thead", null, /* @__PURE__ */ React7.createElement("tr", null, debug && /* @__PURE__ */ React7.createElement("th", null), /* @__PURE__ */ React7.createElement("th", {
556
629
  // TODO(burdon): Calculate row span.
557
630
  colSpan: getHeaderGroups()[0].headers.length,
558
631
  className: groupTh({})
559
- }, getState().grouping[0], "[", String(row.getGroupingValue(getState().grouping[0])), "]"))), /* @__PURE__ */ React6.createElement(TableBody, {
632
+ }, getState().grouping[0], "[", String(row.getGroupingValue(getState().grouping[0])), "]"))), /* @__PURE__ */ React7.createElement(TableBody, {
560
633
  rows: row.subRows
561
634
  }));
562
635
  }));
563
636
  };
564
637
 
565
638
  // packages/ui/react-ui-table/src/components/Cell/CellCombobox.tsx
566
- import { CaretDown as CaretDown2 } from "@phosphor-icons/react";
567
- import React7, { useCallback as useCallback2, useState as useState3 } from "react";
639
+ import { CaretDown } from "@phosphor-icons/react";
640
+ import React8, { useCallback as useCallback2, useState as useState3 } from "react";
568
641
  import { Popover as Popover2, useTranslation as useTranslation2 } from "@dxos/react-ui";
569
642
  import { PopoverCombobox } from "@dxos/react-ui-searchlist";
570
- import { descriptionText, getSize as getSize2, mx as mx4, staticPlaceholderText } from "@dxos/react-ui-theme";
643
+ import { descriptionText, getSize as getSize3, mx as mx4, staticPlaceholderText } from "@dxos/react-ui-theme";
571
644
  var initialItems = (model, value) => value ? {
572
645
  [model.getId(value)]: {
573
646
  label: model.getText(value),
@@ -598,37 +671,37 @@ var CellCombobox = ({ model, value, onValueChange }) => {
598
671
  items,
599
672
  onValueChange
600
673
  ]);
601
- return /* @__PURE__ */ React7.createElement(PopoverCombobox.Root, {
674
+ return /* @__PURE__ */ React8.createElement(PopoverCombobox.Root, {
602
675
  placeholder: t("no selection label")
603
- }, /* @__PURE__ */ React7.createElement(PopoverCombobox.Trigger, {
676
+ }, /* @__PURE__ */ React8.createElement(PopoverCombobox.Trigger, {
604
677
  variant: "ghost",
605
678
  classNames: "is-full rounded-none ring-inset"
606
- }, value ? /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement("span", {
679
+ }, value ? /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement("span", {
607
680
  className: mx4("font-normal text-start text-base flex-1 min-is-0 truncate mie-2", !value && staticPlaceholderText)
608
- }, model.getText(value)), /* @__PURE__ */ React7.createElement(CaretDown2, {
681
+ }, model.getText(value)), /* @__PURE__ */ React8.createElement(CaretDown, {
609
682
  weight: "bold",
610
- className: getSize2(3)
611
- })) : null), /* @__PURE__ */ React7.createElement(PopoverCombobox.Content, {
683
+ className: getSize3(3)
684
+ })) : null), /* @__PURE__ */ React8.createElement(PopoverCombobox.Content, {
612
685
  shouldFilter: false,
613
686
  classNames: "is-[--radix-popover-trigger-width]"
614
- }, /* @__PURE__ */ React7.createElement(PopoverCombobox.Input, {
687
+ }, /* @__PURE__ */ React8.createElement(PopoverCombobox.Input, {
615
688
  value: searchInputValue,
616
689
  onValueChange: handleSearchInputValueChange
617
- }), /* @__PURE__ */ React7.createElement(PopoverCombobox.List, null, searchInputValue.length < 1 ? /* @__PURE__ */ React7.createElement("p", {
690
+ }), /* @__PURE__ */ React8.createElement(PopoverCombobox.List, null, searchInputValue.length < 1 ? /* @__PURE__ */ React8.createElement("p", {
618
691
  className: mx4("text-center", descriptionText)
619
- }, "Start typing to search") : loading ? /* @__PURE__ */ React7.createElement("p", {
692
+ }, "Start typing to search") : loading ? /* @__PURE__ */ React8.createElement("p", {
620
693
  className: mx4("text-center", descriptionText)
621
- }, "Searching\u2026") : /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(PopoverCombobox.Empty, {
694
+ }, "Searching\u2026") : /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(PopoverCombobox.Empty, {
622
695
  classNames: [
623
696
  "text-center",
624
697
  descriptionText
625
698
  ]
626
- }, "No results"), Object.entries(items).map(([id, { label }]) => /* @__PURE__ */ React7.createElement(PopoverCombobox.Item, {
699
+ }, "No results"), Object.entries(items).map(([id, { label }]) => /* @__PURE__ */ React8.createElement(PopoverCombobox.Item, {
627
700
  key: id,
628
701
  value: id,
629
702
  onSelect: handleValueChange,
630
703
  classNames: "truncate"
631
- }, label)))), /* @__PURE__ */ React7.createElement(Popover2.Arrow, null)));
704
+ }, label)))), /* @__PURE__ */ React8.createElement(Popover2.Arrow, null)));
632
705
  };
633
706
 
634
707
  // packages/ui/react-ui-table/src/helpers.tsx
@@ -637,10 +710,10 @@ import { Check as Check2, ClipboardText, X as X2 } from "@phosphor-icons/react";
637
710
  import { createColumnHelper } from "@tanstack/react-table";
638
711
  import { format } from "date-fns/format";
639
712
  import { formatDistanceToNow } from "date-fns/formatDistanceToNow";
640
- import React8, { useEffect as useEffect2, useRef as useRef2, useState as useState4 } from "react";
713
+ import React9, { useEffect as useEffect2, useRef as useRef2, useState as useState4 } from "react";
641
714
  import { log as log2 } from "@dxos/log";
642
715
  import { Input as Input2, Tooltip } from "@dxos/react-ui";
643
- import { getSize as getSize3, mx as mx5 } from "@dxos/react-ui-theme";
716
+ import { getSize as getSize4, mx as mx5 } from "@dxos/react-ui-theme";
644
717
  var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-table/src/helpers.tsx";
645
718
  var createColumnBuilder = () => ({
646
719
  helper: createColumnHelper(),
@@ -648,15 +721,16 @@ var createColumnBuilder = () => ({
648
721
  });
649
722
  var ComboboxBuilderCell = (cellContext) => {
650
723
  const { model, onUpdate } = cellContext.column.columnDef.meta;
651
- return model ? /* @__PURE__ */ React8.createElement(CellCombobox, {
724
+ return model ? /* @__PURE__ */ React9.createElement(CellCombobox, {
652
725
  model,
653
726
  value: cellContext.getValue(),
654
727
  onValueChange: (value) => onUpdate?.(cellContext.row.original, cellContext.column.id, value)
655
728
  }) : null;
656
729
  };
657
730
  var StringBuilderCell = (cellContext) => {
658
- const inputRef = useRef2(null);
659
- const { onUpdate } = cellContext.column.columnDef.meta;
731
+ const ref = useRef2(null);
732
+ const { findPrevFocusable } = useFocusFinders();
733
+ const { onUpdate, cell } = cellContext.column.columnDef.meta;
660
734
  const initialValue = cellContext.getValue();
661
735
  const [value, setValue] = useState4(() => {
662
736
  if (initialValue?.content) {
@@ -665,27 +739,29 @@ var StringBuilderCell = (cellContext) => {
665
739
  return initialValue;
666
740
  });
667
741
  const handleSave = () => {
668
- if (value === initialValue) {
669
- return;
742
+ ref.current && document.activeElement === ref.current && findPrevFocusable(ref.current)?.focus();
743
+ if (value !== initialValue) {
744
+ onUpdate?.(cellContext.row.original, cellContext.column.id, value);
670
745
  }
671
- onUpdate?.(cellContext.row.original, cellContext.column.id, value);
672
- };
673
- const handleCancel = () => {
674
- setValue(initialValue);
675
746
  };
676
- const rows = cellContext.table.getRowModel().flatRows;
747
+ const handleCancel = () => setValue(initialValue);
748
+ let placeholder = false;
677
749
  const columns = cellContext.table.getVisibleFlatColumns();
678
- const placeholder = cellContext.row.index === rows.length - 1 && columns[0].id === cellContext.column.id;
679
- return /* @__PURE__ */ React8.createElement(Input2.Root, null, /* @__PURE__ */ React8.createElement(Input2.TextInput, {
680
- ref: inputRef,
750
+ if (columns[0].id === cellContext.column.id) {
751
+ const rowCount = cellContext.table.getRowModel().rows.length;
752
+ placeholder = cellContext.row.index === rowCount - 1 && columns[0].id === cellContext.column.id;
753
+ }
754
+ return /* @__PURE__ */ React9.createElement(Input2.Root, null, /* @__PURE__ */ React9.createElement(Input2.TextInput, {
755
+ ref,
681
756
  variant: "subdued",
682
757
  placeholder: placeholder ? "Add row..." : void 0,
683
758
  classNames: [
684
759
  "is-full",
685
- textPadding
760
+ textPadding,
761
+ cell?.classNames
686
762
  ],
687
763
  value: value ?? "",
688
- onBlur: () => handleSave(),
764
+ onBlur: handleSave,
689
765
  onChange: (event) => setValue(event.target.value),
690
766
  onKeyDown: (event) => event.key === "Enter" && handleSave() || event.key === "Escape" && handleCancel()
691
767
  }));
@@ -707,22 +783,22 @@ var NumberBuilderCell = (cellContext) => {
707
783
  digits,
708
784
  value
709
785
  ]);
710
- const handleEdit = () => {
711
- if (onUpdate) {
712
- setText(value !== void 0 ? String(value) : "");
713
- }
714
- };
786
+ const handleEdit = () => setText(value !== void 0 ? String(value) : "");
715
787
  const handleSave = () => {
716
788
  const nextValue = parseNumber(text);
717
- onUpdate?.(cellContext.row.original, cellContext.column.id, isNaN(nextValue) ? void 0 : nextValue);
718
- setText(displayNumber(nextValue, digits));
789
+ if (!isNaN(nextValue)) {
790
+ onUpdate?.(cellContext.row.original, cellContext.column.id, nextValue);
791
+ setText(displayNumber(nextValue, digits));
792
+ } else {
793
+ setText(displayNumber(value, digits));
794
+ }
719
795
  ref.current && document.activeElement === ref.current && findPrevFocusable(ref.current)?.focus();
720
796
  };
721
797
  const _handleCancel = () => {
722
798
  setText(displayNumber(value, digits));
723
799
  ref.current && findPrevFocusable(ref.current)?.focus();
724
800
  };
725
- return /* @__PURE__ */ React8.createElement(Input2.Root, null, /* @__PURE__ */ React8.createElement(Input2.TextInput, {
801
+ return /* @__PURE__ */ React9.createElement(Input2.Root, null, /* @__PURE__ */ React9.createElement(Input2.TextInput, {
726
802
  ref,
727
803
  variant: "subdued",
728
804
  value: text,
@@ -745,10 +821,12 @@ var RowSelectorBuilderCell = (cellContext) => {
745
821
  const { cell } = cellContext.column.columnDef.meta;
746
822
  const { row } = cellContext;
747
823
  const checked = row.getCanSelect() ? row.getIsSelected() : row.getCanSelectSubRows() && (row.getIsSomeSelected() ? "indeterminate" : row.getIsAllSubRowsSelected());
748
- return /* @__PURE__ */ React8.createElement(Input2.Root, null, /* @__PURE__ */ React8.createElement(Input2.Checkbox, {
824
+ return /* @__PURE__ */ React9.createElement("div", {
825
+ className: "flex justify-center w-full h-full",
826
+ role: "presentation"
827
+ }, /* @__PURE__ */ React9.createElement(Input2.Root, null, /* @__PURE__ */ React9.createElement(Input2.Checkbox, {
749
828
  size: 4,
750
829
  classNames: [
751
- "mli-auto",
752
830
  cell?.classNames
753
831
  ],
754
832
  checked,
@@ -758,12 +836,12 @@ var RowSelectorBuilderCell = (cellContext) => {
758
836
  }
759
837
  },
760
838
  disabled: !(row.getCanSelect() || row.getCanSelectSubRows())
761
- }));
839
+ })));
762
840
  };
763
841
  var SwitchBuilderCell = (cellContext) => {
764
842
  const { onUpdate } = cellContext.column.columnDef.meta;
765
843
  const value = cellContext.getValue();
766
- return /* @__PURE__ */ React8.createElement(Input2.Root, null, /* @__PURE__ */ React8.createElement(Input2.Switch, {
844
+ return /* @__PURE__ */ React9.createElement(Input2.Root, null, /* @__PURE__ */ React9.createElement(Input2.Switch, {
767
845
  classNames: "block mli-auto",
768
846
  onClick: (event) => event.stopPropagation(),
769
847
  disabled: !onUpdate,
@@ -785,7 +863,7 @@ var ColumnBuilder = class {
785
863
  },
786
864
  cell: model && onUpdate ? ComboboxBuilderCell : (cellContext) => {
787
865
  const cellValue = cellContext.getValue();
788
- return /* @__PURE__ */ React8.createElement("div", {
866
+ return /* @__PURE__ */ React9.createElement("div", {
789
867
  className: mx5("truncate", classNames)
790
868
  }, cellValue ? model?.getText(cellValue) : "");
791
869
  },
@@ -816,7 +894,7 @@ var ColumnBuilder = class {
816
894
  if (typeof value === "object" && value?.__typename === "dxos.Text.v0") {
817
895
  value = value.content;
818
896
  }
819
- return /* @__PURE__ */ React8.createElement("div", {
897
+ return /* @__PURE__ */ React9.createElement("div", {
820
898
  className: mx5("truncate", textPadding, classNames)
821
899
  }, value);
822
900
  },
@@ -871,7 +949,7 @@ var ColumnBuilder = class {
871
949
  const str = value ? formatSpec ? format(value, formatSpec) : relative ? formatDistanceToNow(value, {
872
950
  addSuffix: true
873
951
  }) : value.toISOString() : void 0;
874
- return /* @__PURE__ */ React8.createElement("div", {
952
+ return /* @__PURE__ */ React9.createElement("div", {
875
953
  className: mx5(textPadding, classNames)
876
954
  }, str);
877
955
  } catch (err) {
@@ -879,7 +957,7 @@ var ColumnBuilder = class {
879
957
  value
880
958
  }, {
881
959
  F: __dxlog_file2,
882
- L: 363,
960
+ L: 374,
883
961
  S: this,
884
962
  C: (f, a) => f(...a)
885
963
  });
@@ -913,9 +991,9 @@ var ColumnBuilder = class {
913
991
  if (!tooltip) {
914
992
  return element;
915
993
  }
916
- return /* @__PURE__ */ React8.createElement(Tooltip.Provider, null, /* @__PURE__ */ React8.createElement(Tooltip.Root, null, /* @__PURE__ */ React8.createElement(Tooltip.Trigger, null, element), /* @__PURE__ */ React8.createElement(Tooltip.Portal, null, /* @__PURE__ */ React8.createElement(Tooltip.Content, {
994
+ return /* @__PURE__ */ React9.createElement(Tooltip.Provider, null, /* @__PURE__ */ React9.createElement(Tooltip.Root, null, /* @__PURE__ */ React9.createElement(Tooltip.Trigger, null, element), /* @__PURE__ */ React9.createElement(Tooltip.Portal, null, /* @__PURE__ */ React9.createElement(Tooltip.Content, {
917
995
  side: "right"
918
- }, /* @__PURE__ */ React8.createElement(Tooltip.Arrow, null), /* @__PURE__ */ React8.createElement(ClipboardText, {
996
+ }, /* @__PURE__ */ React9.createElement(Tooltip.Arrow, null), /* @__PURE__ */ React9.createElement(ClipboardText, {
919
997
  onClick: (ev) => {
920
998
  ev.stopPropagation();
921
999
  void navigator.clipboard.writeText(value.toHex());
@@ -943,8 +1021,7 @@ var ColumnBuilder = class {
943
1021
  return {
944
1022
  id,
945
1023
  size: 32,
946
- minSize: 32,
947
- maxSize: 32,
1024
+ enableResizing: false,
948
1025
  meta: {
949
1026
  onUpdate,
950
1027
  cell: {
@@ -954,7 +1031,10 @@ var ColumnBuilder = class {
954
1031
  header: ({ table }) => {
955
1032
  const { rowsSelectable } = useTableContext("HELPER_SELECT_ROW_HEADER_CELL");
956
1033
  const checked = table.getIsSomeRowsSelected() ? "indeterminate" : table.getIsAllRowsSelected();
957
- return rowsSelectable === "multi" ? /* @__PURE__ */ React8.createElement(Input2.Root, null, /* @__PURE__ */ React8.createElement(Input2.Checkbox, {
1034
+ return rowsSelectable === "multi" ? /* @__PURE__ */ React9.createElement("div", {
1035
+ className: "flex justify-center w-full h-full",
1036
+ role: "presentation"
1037
+ }, /* @__PURE__ */ React9.createElement(Input2.Root, null, /* @__PURE__ */ React9.createElement(Input2.Checkbox, {
958
1038
  size: 4,
959
1039
  classNames: [
960
1040
  "mli-auto",
@@ -962,7 +1042,7 @@ var ColumnBuilder = class {
962
1042
  ],
963
1043
  checked,
964
1044
  onCheckedChange: () => table.toggleAllRowsSelected()
965
- })) : null;
1045
+ }))) : null;
966
1046
  },
967
1047
  cell: RowSelectorBuilderCell
968
1048
  };
@@ -975,6 +1055,8 @@ var ColumnBuilder = class {
975
1055
  size: 50,
976
1056
  minSize: 50,
977
1057
  header: (column) => label ?? column.header.id,
1058
+ // TODO(Zan): Implement sort algorithm
1059
+ enableSorting: true,
978
1060
  cell: SwitchBuilderCell,
979
1061
  ...props,
980
1062
  meta: {
@@ -998,18 +1080,20 @@ var ColumnBuilder = class {
998
1080
  const IconOff = off?.Icon ?? X2;
999
1081
  return {
1000
1082
  size: size ?? 32,
1001
- header: (column) => /* @__PURE__ */ React8.createElement("div", {
1083
+ // TODO(Zan): Implement sort algorithm
1084
+ enableSorting: false,
1085
+ header: (column) => /* @__PURE__ */ React9.createElement("div", {
1002
1086
  className: "justify-center"
1003
1087
  }, label ?? column.header.id),
1004
1088
  cell: (cell) => {
1005
1089
  const value = cell.getValue();
1006
1090
  if (value) {
1007
- return /* @__PURE__ */ React8.createElement(IconOn, {
1008
- className: mx5("block mli-auto", getSize3(6), on?.className ?? "text-green-700")
1091
+ return /* @__PURE__ */ React9.createElement(IconOn, {
1092
+ className: mx5("block mli-auto", getSize4(6), on?.className ?? "text-green-700")
1009
1093
  });
1010
1094
  } else if (value === false) {
1011
- return /* @__PURE__ */ React8.createElement(IconOff, {
1012
- className: mx5("block mli-auto", getSize3(6), off?.className ?? "text-red-700")
1095
+ return /* @__PURE__ */ React9.createElement(IconOff, {
1096
+ className: mx5("block mli-auto", getSize4(6), off?.className ?? "text-red-700")
1013
1097
  });
1014
1098
  } else {
1015
1099
  return null;
@@ -1024,6 +1108,7 @@ export {
1024
1108
  ColumnBuilder,
1025
1109
  ColumnMenu,
1026
1110
  ColumnPanel,
1111
+ MemoizedVirtualisedTableContent,
1027
1112
  Table,
1028
1113
  createColumnBuilder,
1029
1114
  currentRow,