@fayz-ai/ui 0.14.0 → 0.15.0

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 (84) hide show
  1. package/dist/{ChartWidgetInner-GDE5PBTR.js → ChartWidgetInner-IOLIUYTB.js} +21 -8
  2. package/dist/ChartWidgetInner-IOLIUYTB.js.map +1 -0
  3. package/dist/analytics/AnalyticsCard.d.ts.map +1 -1
  4. package/dist/analytics/AnalyticsControls.d.ts.map +1 -1
  5. package/dist/chunk-3OVZ5JJQ.js +540 -0
  6. package/dist/chunk-3OVZ5JJQ.js.map +1 -0
  7. package/dist/{chunk-UZYXFEQS.js → chunk-4GK6IHOI.js} +16 -3
  8. package/dist/chunk-4GK6IHOI.js.map +1 -0
  9. package/dist/{chunk-46UZAKFJ.js → chunk-5KMAEQA3.js} +7 -6
  10. package/dist/chunk-5KMAEQA3.js.map +1 -0
  11. package/dist/chunk-AASANYXN.js +601 -0
  12. package/dist/chunk-AASANYXN.js.map +1 -0
  13. package/dist/{chunk-LFZFBN3P.js → chunk-FFJ2C5YH.js} +11 -61
  14. package/dist/chunk-FFJ2C5YH.js.map +1 -0
  15. package/dist/{chunk-5KAGNW45.js → chunk-J7F3Z52K.js} +4 -4
  16. package/dist/{chunk-5KAGNW45.js.map → chunk-J7F3Z52K.js.map} +1 -1
  17. package/dist/{chunk-2EFRFYGF.js → chunk-KD2V3TAX.js} +180 -33
  18. package/dist/chunk-KD2V3TAX.js.map +1 -0
  19. package/dist/{chunk-MVH64JFG.js → chunk-NA3GE4H3.js} +488 -537
  20. package/dist/chunk-NA3GE4H3.js.map +1 -0
  21. package/dist/chunk-OKZ6WQB3.js +57 -0
  22. package/dist/chunk-OKZ6WQB3.js.map +1 -0
  23. package/dist/{chunk-77CUIMOI.js → chunk-SLWTKHNY.js} +103 -158
  24. package/dist/chunk-SLWTKHNY.js.map +1 -0
  25. package/dist/dashboard/ChartWidgetInner.d.ts.map +1 -1
  26. package/dist/dashboard/index.js +5 -4
  27. package/dist/icons.d.ts.map +1 -1
  28. package/dist/icons.js +1 -1
  29. package/dist/index.d.ts +2 -1
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +30 -16
  32. package/dist/index.js.map +1 -1
  33. package/dist/layout/AppShell.d.ts +7 -2
  34. package/dist/layout/AppShell.d.ts.map +1 -1
  35. package/dist/layout/Sidebar.d.ts +27 -4
  36. package/dist/layout/Sidebar.d.ts.map +1 -1
  37. package/dist/layout/Topbar.d.ts +10 -3
  38. package/dist/layout/Topbar.d.ts.map +1 -1
  39. package/dist/layout/index.js +5 -4
  40. package/dist/primitives/SearchCombobox.d.ts +9 -1
  41. package/dist/primitives/SearchCombobox.d.ts.map +1 -1
  42. package/dist/primitives/color-palette.d.ts +24 -0
  43. package/dist/primitives/color-palette.d.ts.map +1 -0
  44. package/dist/primitives/header-tabs.d.ts +11 -1
  45. package/dist/primitives/header-tabs.d.ts.map +1 -1
  46. package/dist/primitives/image-drop.d.ts +28 -0
  47. package/dist/primitives/image-drop.d.ts.map +1 -0
  48. package/dist/primitives/index.d.ts +8 -3
  49. package/dist/primitives/index.d.ts.map +1 -1
  50. package/dist/primitives/index.js +7 -5
  51. package/dist/primitives/list-view.d.ts +7 -1
  52. package/dist/primitives/list-view.d.ts.map +1 -1
  53. package/dist/primitives/option-select.d.ts +46 -0
  54. package/dist/primitives/option-select.d.ts.map +1 -0
  55. package/dist/primitives/page-toolbar.d.ts +20 -1
  56. package/dist/primitives/page-toolbar.d.ts.map +1 -1
  57. package/dist/primitives/sheet.d.ts.map +1 -1
  58. package/dist/primitives/step-progress.d.ts +20 -0
  59. package/dist/primitives/step-progress.d.ts.map +1 -0
  60. package/dist/primitives/use-row-selection.d.ts +50 -0
  61. package/dist/primitives/use-row-selection.d.ts.map +1 -0
  62. package/dist/styles.css +20 -0
  63. package/dist/wizard/Wizard.d.ts +38 -0
  64. package/dist/wizard/Wizard.d.ts.map +1 -0
  65. package/dist/wizard/WizardField.d.ts +22 -0
  66. package/dist/wizard/WizardField.d.ts.map +1 -0
  67. package/dist/wizard/index.d.ts +6 -0
  68. package/dist/wizard/index.d.ts.map +1 -0
  69. package/dist/wizard/index.js +5 -0
  70. package/dist/wizard/index.js.map +1 -0
  71. package/dist/wizard/logic.d.ts +39 -0
  72. package/dist/wizard/logic.d.ts.map +1 -0
  73. package/dist/wizard/types.d.ts +95 -0
  74. package/dist/wizard/types.d.ts.map +1 -0
  75. package/dist/wizard/useWizard.d.ts +47 -0
  76. package/dist/wizard/useWizard.d.ts.map +1 -0
  77. package/package.json +12 -6
  78. package/dist/ChartWidgetInner-GDE5PBTR.js.map +0 -1
  79. package/dist/chunk-2EFRFYGF.js.map +0 -1
  80. package/dist/chunk-46UZAKFJ.js.map +0 -1
  81. package/dist/chunk-77CUIMOI.js.map +0 -1
  82. package/dist/chunk-LFZFBN3P.js.map +0 -1
  83. package/dist/chunk-MVH64JFG.js.map +0 -1
  84. package/dist/chunk-UZYXFEQS.js.map +0 -1
@@ -1,12 +1,12 @@
1
- import { cn, Button } from './chunk-LFZFBN3P.js';
2
- import * as React2 from 'react';
1
+ import { cn, Button } from './chunk-OKZ6WQB3.js';
2
+ import * as React5 from 'react';
3
3
  import { jsx, jsxs } from 'react/jsx-runtime';
4
4
  import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
5
- import { ChevronRight, Check, Circle, Minus, ChevronDown, ArrowDown, ArrowUp, ArrowUpDown, Calendar, RefreshCw } from 'lucide-react';
5
+ import { ChevronRight, Check, Circle, Minus, ChevronDown, ArrowDown, ArrowUp, ArrowUpDown, Calendar, GripVertical, RefreshCw } from 'lucide-react';
6
6
  import { useReactTable, getSortedRowModel, getCoreRowModel, flexRender } from '@tanstack/react-table';
7
7
  import { useTranslation } from '@fayz-ai/core';
8
8
 
9
- var Card = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
9
+ var Card = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
10
10
  "div",
11
11
  {
12
12
  ref,
@@ -18,7 +18,7 @@ var Card = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ j
18
18
  }
19
19
  ));
20
20
  Card.displayName = "Card";
21
- var CardHeader = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
21
+ var CardHeader = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
22
22
  "div",
23
23
  {
24
24
  ref,
@@ -27,7 +27,7 @@ var CardHeader = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE_
27
27
  }
28
28
  ));
29
29
  CardHeader.displayName = "CardHeader";
30
- var CardTitle = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
30
+ var CardTitle = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
31
31
  "h3",
32
32
  {
33
33
  ref,
@@ -39,7 +39,7 @@ var CardTitle = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__
39
39
  }
40
40
  ));
41
41
  CardTitle.displayName = "CardTitle";
42
- var CardDescription = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
42
+ var CardDescription = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
43
43
  "p",
44
44
  {
45
45
  ref,
@@ -48,9 +48,9 @@ var CardDescription = React2.forwardRef(({ className, ...props }, ref) => /* @__
48
48
  }
49
49
  ));
50
50
  CardDescription.displayName = "CardDescription";
51
- var CardContent = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("p-4 pt-0", className), ...props }));
51
+ var CardContent = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("p-4 pt-0", className), ...props }));
52
52
  CardContent.displayName = "CardContent";
53
- var CardFooter = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
53
+ var CardFooter = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
54
54
  "div",
55
55
  {
56
56
  ref,
@@ -65,7 +65,7 @@ var DropdownGroup = DropdownMenuPrimitive.Group;
65
65
  var DropdownPortal = DropdownMenuPrimitive.Portal;
66
66
  var DropdownSub = DropdownMenuPrimitive.Sub;
67
67
  var DropdownRadioGroup = DropdownMenuPrimitive.RadioGroup;
68
- var DropdownSubTrigger = React2.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxs(
68
+ var DropdownSubTrigger = React5.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxs(
69
69
  DropdownMenuPrimitive.SubTrigger,
70
70
  {
71
71
  ref,
@@ -82,7 +82,7 @@ var DropdownSubTrigger = React2.forwardRef(({ className, inset, children, ...pro
82
82
  }
83
83
  ));
84
84
  DropdownSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
85
- var DropdownSubContent = React2.forwardRef(({ className, ...props }, ref) => (
85
+ var DropdownSubContent = React5.forwardRef(({ className, ...props }, ref) => (
86
86
  // Portaled, like DropdownContent. Without it the submenu renders inside the
87
87
  // parent panel's DOM — and that panel is `overflow-hidden`, so the submenu
88
88
  // was clipped to its box: a flyout you could open and never reach.
@@ -91,7 +91,7 @@ var DropdownSubContent = React2.forwardRef(({ className, ...props }, ref) => (
91
91
  {
92
92
  ref,
93
93
  className: cn(
94
- "fayz-glass-surface z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
94
+ "fayz-glass-surface z-50 min-w-[8rem] overflow-hidden rounded-card border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
95
95
  className
96
96
  ),
97
97
  ...props
@@ -99,20 +99,20 @@ var DropdownSubContent = React2.forwardRef(({ className, ...props }, ref) => (
99
99
  ) })
100
100
  ));
101
101
  DropdownSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
102
- var DropdownContent = React2.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(
102
+ var DropdownContent = React5.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(
103
103
  DropdownMenuPrimitive.Content,
104
104
  {
105
105
  ref,
106
106
  sideOffset,
107
107
  className: cn(
108
- "fayz-glass-surface z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
108
+ "fayz-glass-surface z-50 min-w-[8rem] overflow-hidden rounded-card border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
109
109
  className
110
110
  ),
111
111
  ...props
112
112
  }
113
113
  ) }));
114
114
  DropdownContent.displayName = DropdownMenuPrimitive.Content.displayName;
115
- var DropdownItem = React2.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(
115
+ var DropdownItem = React5.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(
116
116
  DropdownMenuPrimitive.Item,
117
117
  {
118
118
  ref,
@@ -125,7 +125,7 @@ var DropdownItem = React2.forwardRef(({ className, inset, ...props }, ref) => /*
125
125
  }
126
126
  ));
127
127
  DropdownItem.displayName = DropdownMenuPrimitive.Item.displayName;
128
- var DropdownCheckboxItem = React2.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ jsxs(
128
+ var DropdownCheckboxItem = React5.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ jsxs(
129
129
  DropdownMenuPrimitive.CheckboxItem,
130
130
  {
131
131
  ref,
@@ -142,7 +142,7 @@ var DropdownCheckboxItem = React2.forwardRef(({ className, children, checked, ..
142
142
  }
143
143
  ));
144
144
  DropdownCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
145
- var DropdownRadioItem = React2.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
145
+ var DropdownRadioItem = React5.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
146
146
  DropdownMenuPrimitive.RadioItem,
147
147
  {
148
148
  ref,
@@ -158,7 +158,7 @@ var DropdownRadioItem = React2.forwardRef(({ className, children, ...props }, re
158
158
  }
159
159
  ));
160
160
  DropdownRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
161
- var DropdownLabel = React2.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(
161
+ var DropdownLabel = React5.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(
162
162
  DropdownMenuPrimitive.Label,
163
163
  {
164
164
  ref,
@@ -171,7 +171,7 @@ var DropdownLabel = React2.forwardRef(({ className, inset, ...props }, ref) => /
171
171
  }
172
172
  ));
173
173
  DropdownLabel.displayName = DropdownMenuPrimitive.Label.displayName;
174
- var DropdownSeparator = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
174
+ var DropdownSeparator = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
175
175
  DropdownMenuPrimitive.Separator,
176
176
  {
177
177
  ref,
@@ -199,7 +199,7 @@ var COLOR_CLASSES = {
199
199
  warning: "border-warning bg-warning text-white",
200
200
  destructive: "border-destructive bg-destructive text-destructive-foreground"
201
201
  };
202
- var Checkbox = React2.forwardRef(
202
+ var Checkbox = React5.forwardRef(
203
203
  ({ checked = false, onChange, disabled, className, color = "primary", id, indeterminate = false, ...props }, ref) => {
204
204
  const filled = checked || indeterminate;
205
205
  return /* @__PURE__ */ jsx(
@@ -243,34 +243,34 @@ function DataTable({
243
243
  }) {
244
244
  const t = useTranslation();
245
245
  const isCard = variant === "card";
246
- const wrapperCls = isCard ? "overflow-hidden rounded-lg border bg-card shadow-sm" : variant === "bare" ? "" : "overflow-hidden rounded-lg border";
246
+ const wrapperCls = isCard ? "overflow-hidden rounded-card border bg-card shadow-sm" : variant === "bare" ? "" : "overflow-hidden rounded-lg border";
247
247
  const headerCls = isCard ? "border-b bg-muted/50" : variant === "bare" ? "border-b bg-muted/30 rounded-none" : "border-b bg-muted/30";
248
248
  const thCls = compact ? "px-3 py-1.5 text-left text-[11px] font-medium text-muted-foreground" : "px-4 py-2.5 text-left font-medium text-muted-foreground";
249
249
  const tdCls = compact ? "px-3 py-1.5 align-middle text-xs" : "px-4 py-3 align-middle";
250
250
  const tableCls = compact ? "w-full text-xs min-w-max" : "w-full text-sm min-w-max";
251
251
  const rowHoverCls = isCard ? "hover:bg-muted/30" : "hover:bg-muted/20";
252
- const [sorting, setSorting] = React2.useState([]);
253
- const rowId = React2.useCallback(
252
+ const [sorting, setSorting] = React5.useState([]);
253
+ const rowId = React5.useCallback(
254
254
  (row) => getRowId ? getRowId(row) : String(row.id ?? ""),
255
255
  [getRowId]
256
256
  );
257
- const selected = React2.useMemo(() => new Set(selectedIds ?? []), [selectedIds]);
258
- const pageIds = React2.useMemo(() => data.map(rowId), [data, rowId]);
257
+ const selected = React5.useMemo(() => new Set(selectedIds ?? []), [selectedIds]);
258
+ const pageIds = React5.useMemo(() => data.map(rowId), [data, rowId]);
259
259
  const selectedOnPage = pageIds.filter((id) => selected.has(id)).length;
260
260
  const allOnPageSelected = pageIds.length > 0 && selectedOnPage === pageIds.length;
261
- const toggleRow = React2.useCallback((id) => {
261
+ const toggleRow = React5.useCallback((id) => {
262
262
  const next = new Set(selected);
263
263
  if (next.has(id)) next.delete(id);
264
264
  else next.add(id);
265
265
  onSelectedIdsChange?.([...next]);
266
266
  }, [selected, onSelectedIdsChange]);
267
- const toggleAllOnPage = React2.useCallback(() => {
267
+ const toggleAllOnPage = React5.useCallback(() => {
268
268
  const next = new Set(selected);
269
269
  if (allOnPageSelected) pageIds.forEach((id) => next.delete(id));
270
270
  else pageIds.forEach((id) => next.add(id));
271
271
  onSelectedIdsChange?.([...next]);
272
272
  }, [selected, allOnPageSelected, pageIds, onSelectedIdsChange]);
273
- const selectionColumn = React2.useMemo(() => ({
273
+ const selectionColumn = React5.useMemo(() => ({
274
274
  id: "__select__",
275
275
  enableSorting: false,
276
276
  header: () => /* @__PURE__ */ jsx(
@@ -297,7 +297,7 @@ function DataTable({
297
297
  // ids: turning the page with nothing selected changes no other dep, and the
298
298
  // memo would hand the header a button that ticks the previous page's rows.
299
299
  }), [allOnPageSelected, selectedOnPage, selected, rowId, toggleRow, toggleAllOnPage, t]);
300
- const allColumns = React2.useMemo(
300
+ const allColumns = React5.useMemo(
301
301
  () => selectable ? [selectionColumn, ...columns] : columns,
302
302
  [selectable, selectionColumn, columns]
303
303
  );
@@ -397,7 +397,7 @@ function TableSkeleton({ columns = 4, rows = 2 }) {
397
397
  )) }, r)) })
398
398
  ] });
399
399
  }
400
- var ToolbarButton = React2.forwardRef(function ToolbarButton2({ icon: Icon, caret = true, children, className, ...props }, ref) {
400
+ var ToolbarButton = React5.forwardRef(function ToolbarButton2({ icon: Icon, caret = true, children, className, ...props }, ref) {
401
401
  return /* @__PURE__ */ jsxs(
402
402
  Button,
403
403
  {
@@ -422,6 +422,27 @@ var ToolbarButton = React2.forwardRef(function ToolbarButton2({ icon: Icon, care
422
422
  }
423
423
  );
424
424
  });
425
+ var ToolbarAction = React5.forwardRef(function ToolbarAction2({ icon: Icon, caret = false, children, className, ...props }, ref) {
426
+ return /* @__PURE__ */ jsxs(
427
+ Button,
428
+ {
429
+ ref,
430
+ variant: "ghost",
431
+ size: "sm",
432
+ className: cn(
433
+ "gap-1.5 border-0 bg-transparent px-2 font-medium text-muted-foreground shadow-none",
434
+ "hover:bg-transparent hover:text-foreground",
435
+ className
436
+ ),
437
+ ...props,
438
+ children: [
439
+ Icon ? /* @__PURE__ */ jsx(Icon, { className: "h-3 w-3 shrink-0 opacity-70" }) : null,
440
+ children,
441
+ caret ? /* @__PURE__ */ jsx(ChevronDown, { className: "h-3 w-3 shrink-0 opacity-60" }) : null
442
+ ]
443
+ }
444
+ );
445
+ });
425
446
  function RangeControl({
426
447
  options,
427
448
  value,
@@ -451,6 +472,109 @@ function RangeControl({
451
472
  children
452
473
  ] });
453
474
  }
475
+ var OFFSET_KEY = (scope) => `fayz.toolbar.offset.${scope}`;
476
+ var EDGE = 8;
477
+ function readOffset(key) {
478
+ if (typeof window === "undefined") return { x: 0, y: 0 };
479
+ try {
480
+ const raw = window.localStorage.getItem(key);
481
+ if (!raw) return { x: 0, y: 0 };
482
+ const parsed = JSON.parse(raw);
483
+ return {
484
+ x: Number.isFinite(parsed.x) ? Number(parsed.x) : 0,
485
+ y: Number.isFinite(parsed.y) ? Number(parsed.y) : 0
486
+ };
487
+ } catch {
488
+ return { x: 0, y: 0 };
489
+ }
490
+ }
491
+ function writeOffset(key, offset) {
492
+ if (typeof window === "undefined") return;
493
+ try {
494
+ if (offset.x === 0 && offset.y === 0) window.localStorage.removeItem(key);
495
+ else window.localStorage.setItem(key, JSON.stringify(offset));
496
+ } catch {
497
+ }
498
+ }
499
+ function useToolbarOffset(storageKey, enabled) {
500
+ const key = OFFSET_KEY(storageKey);
501
+ const barRef = React5.useRef(null);
502
+ const [offset, setOffset] = React5.useState(() => enabled ? readOffset(key) : { x: 0, y: 0 });
503
+ const [dragging, setDragging] = React5.useState(false);
504
+ const latest = React5.useRef(offset);
505
+ latest.current = offset;
506
+ const origin = React5.useRef(null);
507
+ const clamp = React5.useCallback((next) => {
508
+ const el = barRef.current;
509
+ if (!el || typeof window === "undefined") return next;
510
+ const rect = el.getBoundingClientRect();
511
+ const anchorLeft = rect.left - latest.current.x;
512
+ const anchorTop = rect.top - latest.current.y;
513
+ return {
514
+ x: Math.min(
515
+ Math.max(next.x, EDGE - anchorLeft),
516
+ Math.max(EDGE - anchorLeft, window.innerWidth - EDGE - rect.width - anchorLeft)
517
+ ),
518
+ y: Math.min(
519
+ Math.max(next.y, EDGE - anchorTop),
520
+ Math.max(EDGE - anchorTop, window.innerHeight - EDGE - rect.height - anchorTop)
521
+ )
522
+ };
523
+ }, []);
524
+ const move = React5.useCallback((next, persist) => {
525
+ const clamped = clamp(next);
526
+ setOffset(clamped);
527
+ if (persist) writeOffset(key, clamped);
528
+ }, [clamp, key]);
529
+ const onPointerDown = (event) => {
530
+ if (!enabled || event.button !== 0) return;
531
+ event.preventDefault();
532
+ event.currentTarget.setPointerCapture(event.pointerId);
533
+ origin.current = { px: event.clientX, py: event.clientY, ox: latest.current.x, oy: latest.current.y };
534
+ setDragging(true);
535
+ };
536
+ const onPointerMove = (event) => {
537
+ const from = origin.current;
538
+ if (!from) return;
539
+ move({ x: from.ox + (event.clientX - from.px), y: from.oy + (event.clientY - from.py) }, false);
540
+ };
541
+ const endDrag = (event) => {
542
+ if (!origin.current) return;
543
+ origin.current = null;
544
+ setDragging(false);
545
+ if (event.currentTarget.hasPointerCapture(event.pointerId)) {
546
+ event.currentTarget.releasePointerCapture(event.pointerId);
547
+ }
548
+ writeOffset(key, latest.current);
549
+ };
550
+ const onKeyDown = (event) => {
551
+ if (!enabled) return;
552
+ const step = event.shiftKey ? 24 : 8;
553
+ const delta = {
554
+ ArrowLeft: { x: -step, y: 0 },
555
+ ArrowRight: { x: step, y: 0 },
556
+ ArrowUp: { x: 0, y: -step },
557
+ ArrowDown: { x: 0, y: step }
558
+ };
559
+ if (event.key === "Escape" || event.key === "Home") {
560
+ event.preventDefault();
561
+ move({ x: 0, y: 0 }, true);
562
+ return;
563
+ }
564
+ const d = delta[event.key];
565
+ if (!d) return;
566
+ event.preventDefault();
567
+ move({ x: latest.current.x + d.x, y: latest.current.y + d.y }, true);
568
+ };
569
+ const reset = React5.useCallback(() => move({ x: 0, y: 0 }, true), [move]);
570
+ React5.useEffect(() => {
571
+ if (!enabled) return;
572
+ const onResize = () => move(latest.current, false);
573
+ window.addEventListener("resize", onResize);
574
+ return () => window.removeEventListener("resize", onResize);
575
+ }, [enabled, move]);
576
+ return { barRef, offset, dragging, reset, handlers: { onPointerDown, onPointerMove, onPointerUp: endDrag, onPointerCancel: endDrag, onKeyDown } };
577
+ }
454
578
  function PageToolbar({
455
579
  range,
456
580
  filters,
@@ -460,8 +584,12 @@ function PageToolbar({
460
584
  onRefresh,
461
585
  refreshLabel,
462
586
  sticky = true,
587
+ movable = true,
588
+ storageKey = "shared",
589
+ moveLabel,
463
590
  className
464
591
  }) {
592
+ const { barRef, offset, dragging, reset, handlers } = useToolbarOffset(storageKey, movable);
465
593
  if (!range && !filters && !chips && !customize && !actions && !onRefresh) return null;
466
594
  return (
467
595
  // Caixa de altura ZERO: a barra flutua sobre os cartões em vez de abrir uma
@@ -486,15 +614,34 @@ function PageToolbar({
486
614
  children: /* @__PURE__ */ jsxs(
487
615
  "div",
488
616
  {
617
+ ref: barRef,
618
+ style: offset.x || offset.y ? { transform: `translate3d(${offset.x}px, ${offset.y}px, 0)` } : void 0,
489
619
  className: cn(
490
620
  // O mesmo vidro do assistente (fayz-floating-surface, em styles.css):
491
621
  // é a outra coisa que flutua sobre a página, e as duas se diziam
492
622
  // flutuantes em materiais diferentes. Fill fino + blur pesado, para a
493
623
  // grade passar por baixo sem competir.
494
624
  "fayz-floating-surface pointer-events-auto flex max-w-full flex-wrap items-center justify-end gap-2 rounded-2xl px-2 py-1.5",
625
+ dragging && "select-none",
495
626
  className
496
627
  ),
497
628
  children: [
629
+ movable ? /* @__PURE__ */ jsx(
630
+ "button",
631
+ {
632
+ type: "button",
633
+ "aria-label": moveLabel ?? "Mover a barra",
634
+ title: moveLabel ?? "Mover a barra",
635
+ onDoubleClick: reset,
636
+ ...handlers,
637
+ className: cn(
638
+ "flex h-[26px] w-4 shrink-0 touch-none items-center justify-center rounded-md text-muted-foreground/50",
639
+ "transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
640
+ dragging ? "cursor-grabbing text-foreground" : "cursor-grab"
641
+ ),
642
+ children: /* @__PURE__ */ jsx(GripVertical, { className: "h-3.5 w-3.5" })
643
+ }
644
+ ) : null,
498
645
  range,
499
646
  filters,
500
647
  chips,
@@ -519,6 +666,6 @@ function PageToolbar({
519
666
  );
520
667
  }
521
668
 
522
- export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, DataTable, Dropdown, DropdownCheckboxItem, DropdownContent, DropdownGroup, DropdownItem, DropdownLabel, DropdownPortal, DropdownRadioGroup, DropdownRadioItem, DropdownSeparator, DropdownShortcut, DropdownSub, DropdownSubContent, DropdownSubTrigger, DropdownTrigger, PageToolbar, RangeControl, Skeleton, TableSkeleton, ToolbarButton };
523
- //# sourceMappingURL=chunk-2EFRFYGF.js.map
524
- //# sourceMappingURL=chunk-2EFRFYGF.js.map
669
+ export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, DataTable, Dropdown, DropdownCheckboxItem, DropdownContent, DropdownGroup, DropdownItem, DropdownLabel, DropdownPortal, DropdownRadioGroup, DropdownRadioItem, DropdownSeparator, DropdownShortcut, DropdownSub, DropdownSubContent, DropdownSubTrigger, DropdownTrigger, PageToolbar, RangeControl, Skeleton, TableSkeleton, ToolbarAction, ToolbarButton };
670
+ //# sourceMappingURL=chunk-KD2V3TAX.js.map
671
+ //# sourceMappingURL=chunk-KD2V3TAX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/primitives/card.tsx","../src/primitives/dropdown.tsx","../src/primitives/checkbox.tsx","../src/primitives/data-table.tsx","../src/primitives/skeleton.tsx","../src/primitives/page-toolbar.tsx"],"names":["React","React2","jsx","React3","Check","React4","jsxs","_","ToolbarButton","ToolbarAction"],"mappings":"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","file":"chunk-KD2V3TAX.js","sourcesContent":["import * as React from 'react'\n\nimport { cn } from '../lib/cn'\n\nconst Card = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n 'fayz-glass-surface rounded-card border bg-card text-card-foreground shadow-sm',\n className\n )}\n {...props}\n />\n))\nCard.displayName = 'Card'\n\nconst CardHeader = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn('flex flex-col space-y-1 p-4', className)}\n {...props}\n />\n))\nCardHeader.displayName = 'CardHeader'\n\nconst CardTitle = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLHeadingElement>\n>(({ className, ...props }, ref) => (\n <h3\n ref={ref}\n className={cn(\n 'text-sm font-semibold leading-tight tracking-tight',\n className\n )}\n {...props}\n />\n))\nCardTitle.displayName = 'CardTitle'\n\nconst CardDescription = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => (\n <p\n ref={ref}\n className={cn('text-xs text-muted-foreground', className)}\n {...props}\n />\n))\nCardDescription.displayName = 'CardDescription'\n\nconst CardContent = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div ref={ref} className={cn('p-4 pt-0', className)} {...props} />\n))\nCardContent.displayName = 'CardContent'\n\nconst CardFooter = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn('flex items-center p-4 pt-0', className)}\n {...props}\n />\n))\nCardFooter.displayName = 'CardFooter'\n\nexport { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }\n","import * as React from 'react'\nimport * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu'\nimport { Check, ChevronRight, Circle } from 'lucide-react'\n\nimport { cn } from '../lib/cn'\n\nconst Dropdown = DropdownMenuPrimitive.Root\n\nconst DropdownTrigger = DropdownMenuPrimitive.Trigger\n\nconst DropdownGroup = DropdownMenuPrimitive.Group\n\nconst DropdownPortal = DropdownMenuPrimitive.Portal\n\nconst DropdownSub = DropdownMenuPrimitive.Sub\n\nconst DropdownRadioGroup = DropdownMenuPrimitive.RadioGroup\n\nconst DropdownSubTrigger = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {\n inset?: boolean\n }\n>(({ className, inset, children, ...props }, ref) => (\n <DropdownMenuPrimitive.SubTrigger\n ref={ref}\n className={cn(\n 'flex cursor-default select-none items-center rounded-button px-2 py-1.5 text-sm outline-none focus:bg-muted data-[state=open]:bg-muted',\n inset && 'pl-8',\n className\n )}\n {...props}\n >\n {children}\n <ChevronRight className=\"ml-auto h-4 w-4\" />\n </DropdownMenuPrimitive.SubTrigger>\n))\nDropdownSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName\n\nconst DropdownSubContent = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>\n>(({ className, ...props }, ref) => (\n // Portaled, like DropdownContent. Without it the submenu renders inside the\n // parent panel's DOM — and that panel is `overflow-hidden`, so the submenu\n // was clipped to its box: a flyout you could open and never reach.\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.SubContent\n ref={ref}\n className={cn(\n 'fayz-glass-surface z-50 min-w-[8rem] overflow-hidden rounded-card border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',\n className\n )}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n))\nDropdownSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName\n\nconst DropdownContent = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>\n>(({ className, sideOffset = 4, ...props }, ref) => (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Content\n ref={ref}\n sideOffset={sideOffset}\n className={cn(\n 'fayz-glass-surface z-50 min-w-[8rem] overflow-hidden rounded-card border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',\n className\n )}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n))\nDropdownContent.displayName = DropdownMenuPrimitive.Content.displayName\n\nconst DropdownItem = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {\n inset?: boolean\n }\n>(({ className, inset, ...props }, ref) => (\n <DropdownMenuPrimitive.Item\n ref={ref}\n className={cn(\n 'relative flex cursor-default select-none items-center rounded-button px-2 py-1.5 text-sm outline-none transition-colors focus:bg-muted data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n inset && 'pl-8',\n className\n )}\n {...props}\n />\n))\nDropdownItem.displayName = DropdownMenuPrimitive.Item.displayName\n\nconst DropdownCheckboxItem = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>\n>(({ className, children, checked, ...props }, ref) => (\n <DropdownMenuPrimitive.CheckboxItem\n ref={ref}\n className={cn(\n 'relative flex cursor-default select-none items-center rounded-button py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-muted data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n className\n )}\n checked={checked}\n {...props}\n >\n <span className=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <Check className=\"h-4 w-4\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.CheckboxItem>\n))\nDropdownCheckboxItem.displayName =\n DropdownMenuPrimitive.CheckboxItem.displayName\n\nconst DropdownRadioItem = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>\n>(({ className, children, ...props }, ref) => (\n <DropdownMenuPrimitive.RadioItem\n ref={ref}\n className={cn(\n 'relative flex cursor-default select-none items-center rounded-button py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-muted data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n className\n )}\n {...props}\n >\n <span className=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <Circle className=\"h-2 w-2 fill-current\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.RadioItem>\n))\nDropdownRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName\n\nconst DropdownLabel = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.Label>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {\n inset?: boolean\n }\n>(({ className, inset, ...props }, ref) => (\n <DropdownMenuPrimitive.Label\n ref={ref}\n className={cn(\n 'px-2 py-1.5 text-sm font-semibold',\n inset && 'pl-8',\n className\n )}\n {...props}\n />\n))\nDropdownLabel.displayName = DropdownMenuPrimitive.Label.displayName\n\nconst DropdownSeparator = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.Separator>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n <DropdownMenuPrimitive.Separator\n ref={ref}\n className={cn('-mx-1 my-1 h-px bg-muted', className)}\n {...props}\n />\n))\nDropdownSeparator.displayName = DropdownMenuPrimitive.Separator.displayName\n\nconst DropdownShortcut = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLSpanElement>) => {\n return (\n <span\n className={cn('ml-auto text-xs tracking-widest opacity-60', className)}\n {...props}\n />\n )\n}\nDropdownShortcut.displayName = 'DropdownShortcut'\n\nexport {\n Dropdown,\n DropdownTrigger,\n DropdownContent,\n DropdownItem,\n DropdownCheckboxItem,\n DropdownRadioItem,\n DropdownLabel,\n DropdownSeparator,\n DropdownShortcut,\n DropdownGroup,\n DropdownPortal,\n DropdownSub,\n DropdownSubContent,\n DropdownSubTrigger,\n DropdownRadioGroup,\n}\n","import * as React from 'react'\nimport { Check, Minus } from 'lucide-react'\nimport { cn } from '../lib/cn'\n\ntype CheckboxColor = 'primary' | 'success' | 'warning' | 'destructive'\n\ninterface CheckboxProps {\n checked?: boolean\n onChange?: (checked: boolean) => void\n disabled?: boolean\n className?: string\n color?: CheckboxColor\n id?: string\n /** Some but not all of what this box stands for is checked (a table header\n * over a partly selected page). Painted filled with a dash, and announced as\n * \"mixed\" — an empty box would claim nothing is selected. */\n indeterminate?: boolean\n 'aria-label'?: string\n}\n\nconst COLOR_CLASSES: Record<CheckboxColor, string> = {\n primary: 'border-primary bg-primary text-primary-foreground',\n success: 'border-success bg-success text-white dark:border-success dark:bg-success',\n warning: 'border-warning bg-warning text-white',\n destructive: 'border-destructive bg-destructive text-destructive-foreground',\n}\n\nconst Checkbox = React.forwardRef<HTMLButtonElement, CheckboxProps>(\n ({ checked = false, onChange, disabled, className, color = 'primary', id, indeterminate = false, ...props }, ref) => {\n const filled = checked || indeterminate\n return (\n <button\n ref={ref}\n id={id}\n type=\"button\"\n role=\"checkbox\"\n aria-checked={indeterminate ? 'mixed' : checked}\n disabled={disabled}\n onClick={() => onChange?.(!checked)}\n className={cn(\n 'peer inline-flex h-[18px] w-[18px] shrink-0 items-center justify-center rounded-[5px] border-2 transition-all duration-150',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n filled\n ? `${COLOR_CLASSES[color]} shadow-sm`\n : 'border-muted-foreground/40 bg-background hover:border-muted-foreground/60',\n className,\n )}\n {...props}\n >\n {indeterminate\n ? <Minus className=\"h-3.5 w-3.5\" strokeWidth={3} />\n : checked && <Check className=\"h-3.5 w-3.5\" strokeWidth={3} />}\n </button>\n )\n },\n)\nCheckbox.displayName = 'Checkbox'\n\nexport { Checkbox }\nexport type { CheckboxColor, CheckboxProps }\n","import * as React from 'react'\nimport {\n type ColumnDef,\n type SortingState,\n flexRender,\n getCoreRowModel,\n getSortedRowModel,\n useReactTable,\n} from '@tanstack/react-table'\nimport { ArrowUpDown, ArrowUp, ArrowDown } from 'lucide-react'\nimport { useTranslation } from '@fayz-ai/core'\n\nimport { cn } from '../lib/cn'\nimport { Checkbox } from './checkbox'\n\ninterface DataTableProps<TData, TValue> {\n columns: ColumnDef<TData, TValue>[]\n data: TData[]\n loading?: boolean\n skeletonRows?: number\n emptyMessage?: React.ReactNode\n onRowClick?: (row: TData) => void\n /** Visual variant: 'card' (white bg, card wrapper — default), 'flat'\n * (transparent bg, still bordered), or 'bare' — no wrapper chrome at all,\n * for a table already inside a card that owns the border and radius. */\n variant?: 'card' | 'flat' | 'bare'\n /** Compact mode: smaller padding and font size */\n compact?: boolean\n /**\n * Qual coluna está ordenada e para que lado, quando quem ordena é OUTRO\n * controle (o menu \"Ordenar\" da barra de ferramentas).\n *\n * Marca o cabeçalho sem torná-lo clicável: com a ordenação fora da tabela,\n * a seta é INFORMAÇÃO (\"está ordenado por isto, assim\"), não um botão. Sem\n * ela, mudar a ordem por um menu que fecha em seguida não deixava rastro\n * nenhum na tela.\n */\n sortIndicator?: { columnId: string; dir: 'asc' | 'desc' }\n /**\n * Turns on the checkbox column on the left. Selection is CONTROLLED by ids:\n * what a bulk action needs is \"which records\", and the table's own row indexes\n * stop meaning that the moment the list refetches, sorts or pages.\n */\n selectable?: boolean\n selectedIds?: string[]\n onSelectedIdsChange?: (ids: string[]) => void\n /** Row identity for selection. Defaults to `row.id`. */\n getRowId?: (row: TData) => string\n}\n\nfunction DataTable<TData, TValue>({\n columns,\n data,\n loading = false,\n skeletonRows = 3,\n emptyMessage = 'No results.',\n onRowClick,\n variant = 'card',\n compact = false,\n sortIndicator,\n selectable = false,\n selectedIds,\n onSelectedIdsChange,\n getRowId,\n}: DataTableProps<TData, TValue>) {\n const t = useTranslation()\n const isCard = variant === 'card'\n // Rounded box and scroll container must be SEPARATE elements: a scroll\n // container paints its content over its own border-radius, which squared\n // the corners the moment a row background met them.\n const wrapperCls = isCard\n ? 'overflow-hidden rounded-card border bg-card shadow-sm'\n : variant === 'bare'\n ? ''\n : 'overflow-hidden rounded-lg border'\n // 'bare' sits below something else inside its parent card (a search/tools\n // toolbar), so its header is a mid-card band: no rounding, and it keeps the\n // card's own surface rather than starting a new tinted block.\n const headerCls = isCard\n ? 'border-b bg-muted/50'\n : variant === 'bare'\n ? 'border-b bg-muted/30 rounded-none'\n : 'border-b bg-muted/30'\n const thCls = compact ? 'px-3 py-1.5 text-left text-[11px] font-medium text-muted-foreground' : 'px-4 py-2.5 text-left font-medium text-muted-foreground'\n const tdCls = compact ? 'px-3 py-1.5 align-middle text-xs' : 'px-4 py-3 align-middle'\n const tableCls = compact ? 'w-full text-xs min-w-max' : 'w-full text-sm min-w-max'\n const rowHoverCls = isCard ? 'hover:bg-muted/30' : 'hover:bg-muted/20'\n const [sorting, setSorting] = React.useState<SortingState>([])\n\n const rowId = React.useCallback(\n (row: TData) => (getRowId ? getRowId(row) : String((row as { id?: unknown }).id ?? '')),\n [getRowId],\n )\n const selected = React.useMemo(() => new Set(selectedIds ?? []), [selectedIds])\n const pageIds = React.useMemo(() => data.map(rowId), [data, rowId])\n const selectedOnPage = pageIds.filter((id) => selected.has(id)).length\n const allOnPageSelected = pageIds.length > 0 && selectedOnPage === pageIds.length\n\n const toggleRow = React.useCallback((id: string) => {\n const next = new Set(selected)\n if (next.has(id)) next.delete(id)\n else next.add(id)\n onSelectedIdsChange?.([...next])\n }, [selected, onSelectedIdsChange])\n // The header box acts on THIS page only — it must not silently drop a\n // selection made on another page, nor claim to have selected rows that were\n // never loaded.\n const toggleAllOnPage = React.useCallback(() => {\n const next = new Set(selected)\n if (allOnPageSelected) pageIds.forEach((id) => next.delete(id))\n else pageIds.forEach((id) => next.add(id))\n onSelectedIdsChange?.([...next])\n }, [selected, allOnPageSelected, pageIds, onSelectedIdsChange])\n\n // Built here rather than asked of every caller: the column is pure chrome, and\n // a hand-rolled copy per list is where the checkbox column drifts.\n const selectionColumn = React.useMemo<ColumnDef<TData, TValue>>(() => ({\n id: '__select__',\n enableSorting: false,\n header: () => (\n <Checkbox\n checked={allOnPageSelected}\n indeterminate={selectedOnPage > 0 && !allOnPageSelected}\n onChange={toggleAllOnPage}\n aria-label={t('crud.list.selectAllRows')}\n />\n ),\n cell: ({ row }) => {\n const id = rowId(row.original)\n return (\n <Checkbox\n checked={selected.has(id)}\n onChange={() => toggleRow(id)}\n aria-label={t('crud.list.selectRow')}\n />\n )\n },\n // `toggleAllOnPage` is in the deps because it closes over the CURRENT page's\n // ids: turning the page with nothing selected changes no other dep, and the\n // memo would hand the header a button that ticks the previous page's rows.\n }), [allOnPageSelected, selectedOnPage, selected, rowId, toggleRow, toggleAllOnPage, t])\n\n const allColumns = React.useMemo(\n () => (selectable ? [selectionColumn, ...columns] : columns),\n [selectable, selectionColumn, columns],\n )\n\n const table = useReactTable({\n data,\n columns: allColumns,\n getCoreRowModel: getCoreRowModel(),\n getSortedRowModel: getSortedRowModel(),\n onSortingChange: setSorting,\n state: { sorting },\n })\n\n if (loading) {\n return (\n <div className={wrapperCls}>\n <div className=\"overflow-x-auto\">\n <table className={tableCls}>\n <thead>\n <tr className={headerCls}>\n {allColumns.map((_, i) => (\n <th key={i} className={thCls}>\n <div className=\"h-3.5 w-20 animate-pulse rounded bg-muted\" />\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {Array.from({ length: skeletonRows }).map((_, i) => (\n <tr key={i} className=\"border-b last:border-0\">\n {allColumns.map((_, j) => (\n <td key={j} className={tdCls}>\n <div className=\"h-3.5 w-full animate-pulse rounded bg-muted\" />\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </div>\n )\n }\n\n return (\n <div className={wrapperCls}>\n <div className=\"overflow-x-auto\">\n <table className={tableCls}>\n <thead>\n {table.getHeaderGroups().map((headerGroup) => (\n <tr key={headerGroup.id} className={headerCls}>\n {headerGroup.headers.map((header) => {\n const sorted = header.column.getIsSorted()\n return (\n <th\n key={header.id}\n className={cn(thCls, header.column.id === '__select__' && 'w-10 pr-0')}\n >\n {header.isPlaceholder ? null : sortIndicator?.columnId === header.column.id ? (\n <span className=\"inline-flex items-center gap-1 text-foreground\">\n {flexRender(header.column.columnDef.header, header.getContext())}\n {sortIndicator.dir === 'desc'\n ? <ArrowDown className=\"h-3 w-3\" />\n : <ArrowUp className=\"h-3 w-3\" />}\n </span>\n ) : header.column.getCanSort() ? (\n <button\n className=\"flex items-center gap-1 hover:text-foreground transition-colors\"\n onClick={header.column.getToggleSortingHandler()}\n >\n {flexRender(header.column.columnDef.header, header.getContext())}\n {sorted === 'asc' ? (\n <ArrowUp className=\"h-3 w-3\" />\n ) : sorted === 'desc' ? (\n <ArrowDown className=\"h-3 w-3\" />\n ) : (\n <ArrowUpDown className=\"h-3 w-3 opacity-40\" />\n )}\n </button>\n ) : (\n flexRender(header.column.columnDef.header, header.getContext())\n )}\n </th>\n )\n })}\n </tr>\n ))}\n </thead>\n <tbody>\n {table.getRowModel().rows?.length ? (\n table.getRowModel().rows.map((row) => {\n const isSelected = selectable && selected.has(rowId(row.original))\n return (\n <tr\n key={row.id}\n className={cn(\n `border-b last:border-0 transition-colors ${rowHoverCls}`,\n onRowClick && 'cursor-pointer',\n isSelected && 'bg-muted/40',\n )}\n onClick={() => onRowClick?.(row.original)}\n data-selected={isSelected || undefined}\n >\n {row.getVisibleCells().map((cell) => {\n const isSelectCell = cell.column.id === '__select__'\n return (\n <td\n key={cell.id}\n className={cn(tdCls, isSelectCell && 'w-10 pr-0')}\n // Ticking a box is not opening the record: without this\n // the row's own click handler fired underneath and the\n // list navigated away from the selection just made.\n onClick={isSelectCell ? (e) => e.stopPropagation() : undefined}\n >\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </td>\n )\n })}\n </tr>\n )\n })\n ) : (\n <tr>\n {/* Height, not just padding: an empty table that collapses to one\n thin row reads as a rendering glitch rather than \"nothing\n here yet\". `emptyMessage` takes a node so callers can hand in\n a full empty state (icon, headline, create action). */}\n <td colSpan={allColumns.length} className=\"h-64 px-6 text-center align-middle text-muted-foreground\">\n {emptyMessage}\n </td>\n </tr>\n )}\n </tbody>\n </table>\n </div>\n </div>\n )\n}\n\nexport { DataTable, type DataTableProps }\n","import { cn } from '../lib/cn'\n\nfunction Skeleton({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) {\n return (\n <div\n className={cn('animate-pulse rounded-md bg-muted', className)}\n {...props}\n />\n )\n}\n\n/**\n * Skeleton loader that mimics a table with rows and columns.\n * Drop-in replacement for \"Loading...\" text in list views.\n */\nfunction TableSkeleton({ columns = 4, rows = 2 }: { columns?: number; rows?: number }) {\n return (\n <div className=\"rounded-lg border overflow-hidden\">\n <div className=\"border-b bg-muted/30 flex gap-4 px-4 py-2.5\">\n {Array.from({ length: columns }).map((_, i) => (\n <Skeleton key={i} className=\"h-3 flex-1 rounded bg-muted-foreground/10\" />\n ))}\n </div>\n <div className=\"divide-y\">\n {Array.from({ length: rows }).map((_, r) => (\n <div key={r} className=\"flex items-center gap-4 px-4 py-3.5\">\n {Array.from({ length: columns }).map((_, c) => (\n <Skeleton\n key={c}\n className={cn(\n 'h-3 rounded',\n c === 0 ? 'flex-[2]' : 'flex-1',\n )}\n />\n ))}\n </div>\n ))}\n </div>\n </div>\n )\n}\n\nexport { Skeleton, TableSkeleton }\n","import * as React from 'react'\nimport { Calendar, Check, ChevronDown, GripVertical, RefreshCw } from 'lucide-react'\nimport { cn } from '../lib/cn'\nimport { Button } from './button'\nimport { Dropdown, DropdownTrigger, DropdownContent, DropdownItem } from './dropdown'\n\n// ---------------------------------------------------------------------------\n// PageToolbar — a barra flutuante do que a tela está MOSTRANDO.\n//\n// A barra da shell carrega o que se FAZ numa tela (Novo, Importar, Salvar).\n// Esta carrega a pergunta que a tela responde: qual período, quais filtros,\n// quais cartões. Eram duas respostas diferentes para as mesmas três coisas — a\n// faixa de Análises, larga e com cromo próprio, e o \"Customize\" solto do\n// dashboard —, então o mesmo trabalho parecia recurso de produto diferente\n// dependendo da página aberta.\n//\n// Flutuante e à direita de propósito: ela governa a grade ABAIXO dela e fica\n// parada enquanto essa grade rola por baixo (sticky, com borda e sombra, para\n// ler como algo POR CIMA dos cartões e não como uma emenda no layout).\n// ---------------------------------------------------------------------------\n\n/**\n * O gatilho padrão da barra: sem contorno, com o rótulo sublinhado tracejado.\n *\n * Contornados, os três viravam três caixas arredondadas dentro de outra caixa\n * arredondada — a borda do vidro e a dos botões disputavam a mesma leitura, e a\n * barra parecia um grupo de botões e não um controle. O tracejado é o traço\n * clássico de \"este valor se troca\": diz que clica sem desenhar mais um limite.\n */\nexport const ToolbarButton = React.forwardRef<\n HTMLButtonElement,\n React.ComponentProps<typeof Button> & { icon?: React.ElementType; caret?: boolean }\n>(function ToolbarButton({ icon: Icon, caret = true, children, className, ...props }, ref) {\n return (\n <Button\n ref={ref}\n variant=\"ghost\"\n size=\"sm\"\n className={cn(\n // Sem fundo no hover: um retângulo arredondado aparecendo atrás do\n // rótulo desenha, no hover, exatamente o botão que o repouso não tem.\n // O que muda é o texto e o traço — mais firmes, e o tracejado vira\n // contínuo, que é o mesmo \"agora sim, clique\" sem inventar caixa.\n 'group gap-1.5 border-0 bg-transparent px-2 font-medium text-muted-foreground shadow-none',\n 'hover:bg-transparent hover:text-foreground',\n className,\n )}\n {...props}\n >\n {Icon ? <Icon className=\"h-3 w-3 shrink-0 opacity-70\" /> : null}\n <span className=\"inline-flex items-center gap-1.5 border-b border-dashed border-muted-foreground/40 pb-px transition-colors group-hover:border-solid group-hover:border-foreground\">\n {children}\n </span>\n {caret ? <ChevronDown className=\"h-3 w-3 shrink-0 opacity-60\" /> : null}\n </Button>\n )\n})\n\n/**\n * O gatilho de COMANDO da barra — Exportar, Imprimir, Novo.\n *\n * Mesma matéria do ToolbarButton acima (sem contorno, sem fundo, fantasma) e\n * sem o sublinhado tracejado: o tracejado promete \"este valor se troca\", e\n * imprimir não é um valor. Eram botões contornados no meio de uma barra sem\n * contorno nenhum — duas caixas arredondadas ao lado de três rótulos soltos,\n * que é o desenho que faz a barra parecer duas barras.\n */\nexport const ToolbarAction = React.forwardRef<\n HTMLButtonElement,\n React.ComponentProps<typeof Button> & { icon?: React.ElementType; caret?: boolean }\n>(function ToolbarAction({ icon: Icon, caret = false, children, className, ...props }, ref) {\n return (\n <Button\n ref={ref}\n variant=\"ghost\"\n size=\"sm\"\n className={cn(\n 'gap-1.5 border-0 bg-transparent px-2 font-medium text-muted-foreground shadow-none',\n 'hover:bg-transparent hover:text-foreground',\n className,\n )}\n {...props}\n >\n {Icon ? <Icon className=\"h-3 w-3 shrink-0 opacity-70\" /> : null}\n {children}\n {caret ? <ChevronDown className=\"h-3 w-3 shrink-0 opacity-60\" /> : null}\n </Button>\n )\n})\n\nexport interface RangeOption {\n value: string\n label: string\n}\n\nexport interface RangeControlProps {\n options: RangeOption[]\n value: string\n onChange: (value: string) => void\n /** Rótulo do gatilho quando não é nenhum dos presets (ex.: \"Personalizado\"). */\n label?: string\n /** \"21 jul – 19 ago\" — a janela que os números realmente cobrem. Um nome de\n * preset sozinho deixa a dúvida se \"este mês\" já inclui hoje. */\n span?: string\n /** Itens extras no fim do menu (ex.: abrir uma janela personalizada). */\n extra?: React.ReactNode\n /** Desenhado ao lado do gatilho (ex.: os dois seletores de data). */\n children?: React.ReactNode\n icon?: React.ElementType\n className?: string\n}\n\n/**\n * O controle de período — um só, para o dashboard e para as análises.\n *\n * Puramente apresentacional: quem tem o estado (o contexto de analytics, o de\n * dashboard) passa opções e valor. Eram dois desenhos para a mesma escolha, um\n * segmentado de 7d/30d/90d e um menu de presets, e trocar de tela trocava a\n * gramática do controle sem trocar o que ele faz.\n */\nexport function RangeControl({\n options, value, onChange, label, span, extra, children, icon = Calendar, className,\n}: RangeControlProps) {\n const current = options.find((o) => o.value === value)\n return (\n <div className={cn('flex items-center gap-1.5', className)}>\n <Dropdown>\n <DropdownTrigger asChild>\n <ToolbarButton icon={icon}>\n {label ?? current?.label ?? value}\n {span ? <span className=\"font-normal text-muted-foreground\">{span}</span> : null}\n </ToolbarButton>\n </DropdownTrigger>\n <DropdownContent align=\"end\" className=\"w-56\">\n {options.map((o) => (\n <DropdownItem key={o.value} onSelect={() => onChange(o.value)}>\n {o.label}\n {o.value === value ? <Check className=\"ml-auto h-3.5 w-3.5 shrink-0 pl-1\" /> : null}\n </DropdownItem>\n ))}\n {extra}\n </DropdownContent>\n </Dropdown>\n {children}\n </div>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Onde a barra mora.\n//\n// Ela flutua sobre a grade, e \"sobre a grade\" às vezes quer dizer \"em cima do\n// título do terceiro cartão\". Em vez de escolher por todo mundo um canto que\n// nunca atrapalhe — não existe —, a barra ganha uma alça e o usuário resolve.\n//\n// UMA posição para todas as telas, por omissão: \"onde fica a barra flutuante\" é\n// uma preferência, não sete. Uma superfície que precise da sua passa `storageKey`.\n// ---------------------------------------------------------------------------\n\ninterface ToolbarOffset { x: number; y: number }\n\nconst OFFSET_KEY = (scope: string) => `fayz.toolbar.offset.${scope}`\nconst EDGE = 8\n\nfunction readOffset(key: string): ToolbarOffset {\n if (typeof window === 'undefined') return { x: 0, y: 0 }\n try {\n const raw = window.localStorage.getItem(key)\n if (!raw) return { x: 0, y: 0 }\n const parsed = JSON.parse(raw) as Partial<ToolbarOffset>\n return {\n x: Number.isFinite(parsed.x) ? Number(parsed.x) : 0,\n y: Number.isFinite(parsed.y) ? Number(parsed.y) : 0,\n }\n } catch {\n return { x: 0, y: 0 }\n }\n}\n\nfunction writeOffset(key: string, offset: ToolbarOffset): void {\n if (typeof window === 'undefined') return\n try {\n if (offset.x === 0 && offset.y === 0) window.localStorage.removeItem(key)\n else window.localStorage.setItem(key, JSON.stringify(offset))\n } catch {\n /* quota / private mode — perder isto custa uma posição, não um dado */\n }\n}\n\n/**\n * Deslocamento arrastável, preso à viewport.\n *\n * O clamp mede o elemento JÁ transladado e desconta o deslocamento atual para\n * achar a âncora — é o que mantém a barra inteira na tela depois de um resize,\n * de um rail que abre, ou de uma posição guardada numa janela maior.\n */\nfunction useToolbarOffset(storageKey: string, enabled: boolean) {\n const key = OFFSET_KEY(storageKey)\n const barRef = React.useRef<HTMLDivElement>(null)\n const [offset, setOffset] = React.useState<ToolbarOffset>(() => (enabled ? readOffset(key) : { x: 0, y: 0 }))\n const [dragging, setDragging] = React.useState(false)\n const latest = React.useRef(offset)\n latest.current = offset\n const origin = React.useRef<{ px: number; py: number; ox: number; oy: number } | null>(null)\n\n const clamp = React.useCallback((next: ToolbarOffset): ToolbarOffset => {\n const el = barRef.current\n if (!el || typeof window === 'undefined') return next\n const rect = el.getBoundingClientRect()\n const anchorLeft = rect.left - latest.current.x\n const anchorTop = rect.top - latest.current.y\n return {\n x: Math.min(\n Math.max(next.x, EDGE - anchorLeft),\n Math.max(EDGE - anchorLeft, window.innerWidth - EDGE - rect.width - anchorLeft),\n ),\n y: Math.min(\n Math.max(next.y, EDGE - anchorTop),\n Math.max(EDGE - anchorTop, window.innerHeight - EDGE - rect.height - anchorTop),\n ),\n }\n }, [])\n\n const move = React.useCallback((next: ToolbarOffset, persist: boolean) => {\n const clamped = clamp(next)\n setOffset(clamped)\n if (persist) writeOffset(key, clamped)\n }, [clamp, key])\n\n const onPointerDown = (event: React.PointerEvent<HTMLElement>) => {\n if (!enabled || event.button !== 0) return\n event.preventDefault()\n event.currentTarget.setPointerCapture(event.pointerId)\n origin.current = { px: event.clientX, py: event.clientY, ox: latest.current.x, oy: latest.current.y }\n setDragging(true)\n }\n\n const onPointerMove = (event: React.PointerEvent<HTMLElement>) => {\n const from = origin.current\n if (!from) return\n move({ x: from.ox + (event.clientX - from.px), y: from.oy + (event.clientY - from.py) }, false)\n }\n\n const endDrag = (event: React.PointerEvent<HTMLElement>) => {\n if (!origin.current) return\n origin.current = null\n setDragging(false)\n if (event.currentTarget.hasPointerCapture(event.pointerId)) {\n event.currentTarget.releasePointerCapture(event.pointerId)\n }\n writeOffset(key, latest.current)\n }\n\n // Teclado: a alça é um botão, e um controle que só responde ao arrasto não\n // existe para quem não usa mouse.\n const onKeyDown = (event: React.KeyboardEvent) => {\n if (!enabled) return\n const step = event.shiftKey ? 24 : 8\n const delta: Record<string, ToolbarOffset> = {\n ArrowLeft: { x: -step, y: 0 },\n ArrowRight: { x: step, y: 0 },\n ArrowUp: { x: 0, y: -step },\n ArrowDown: { x: 0, y: step },\n }\n if (event.key === 'Escape' || event.key === 'Home') {\n event.preventDefault()\n move({ x: 0, y: 0 }, true)\n return\n }\n const d = delta[event.key]\n if (!d) return\n event.preventDefault()\n move({ x: latest.current.x + d.x, y: latest.current.y + d.y }, true)\n }\n\n const reset = React.useCallback(() => move({ x: 0, y: 0 }, true), [move])\n\n // Uma posição guardada numa janela larga não pode esconder a barra numa\n // estreita — reancora sem gravar, para não sobrescrever a escolha do usuário.\n React.useEffect(() => {\n if (!enabled) return\n const onResize = () => move(latest.current, false)\n window.addEventListener('resize', onResize)\n return () => window.removeEventListener('resize', onResize)\n }, [enabled, move])\n\n return { barRef, offset, dragging, reset, handlers: { onPointerDown, onPointerMove, onPointerUp: endDrag, onPointerCancel: endDrag, onKeyDown } }\n}\n\nexport interface PageToolbarProps {\n /** O período. */\n range?: React.ReactNode\n /** Filtros gerais e comparação — o que estreita a pergunta. */\n filters?: React.ReactNode\n /** Filtros aplicados, como pastilhas removíveis. */\n chips?: React.ReactNode\n /** Quais componentes aparecem. */\n customize?: React.ReactNode\n /** Extras da tela (exportar, um relatório novo). */\n actions?: React.ReactNode\n onRefresh?: () => void\n refreshLabel?: string\n /** Solta a barra do topo (dentro de um modal, ou ao imprimir). */\n sticky?: boolean\n /** Alça de arrastar à esquerda. Desligue onde a barra não flutua sobre nada. */\n movable?: boolean\n /** Separa a posição desta barra da compartilhada. Ver useToolbarOffset. */\n storageKey?: string\n /** Rótulo acessível da alça. */\n moveLabel?: string\n className?: string\n}\n\nexport function PageToolbar({\n range, filters, chips, customize, actions, onRefresh, refreshLabel,\n sticky = true, movable = true, storageKey = 'shared', moveLabel, className,\n}: PageToolbarProps) {\n const { barRef, offset, dragging, reset, handlers } = useToolbarOffset(storageKey, movable)\n if (!range && !filters && !chips && !customize && !actions && !onRefresh) return null\n return (\n // Caixa de altura ZERO: a barra flutua sobre os cartões em vez de abrir uma\n // linha só para ela. Ocupando espaço, ela empurrava a grade inteira para\n // baixo para hospedar controles que a maioria das visitas nem toca — e\n // \"flutuante\" que reserva o próprio lugar não está flutuando.\n //\n // Zero + sticky, não `absolute`: absoluto não gruda, e a pergunta que a\n // página responde tem de continuar à mão depois de vinte cartões de rolagem.\n // `pointer-events-none` na caixa para que a faixa vazia dos lados não coma o\n // clique do cartão embaixo.\n <div\n className={cn(\n // `items-start` não é enfeite: num flex de altura 0, o alinhamento\n // padrão (stretch) achata o filho para 0px — a barra some e só os\n // botões transbordam, sem vidro nenhum atrás.\n 'pointer-events-none z-20 flex h-0 items-start justify-end',\n sticky && 'sticky top-0',\n )}\n >\n <div\n ref={barRef}\n // Transform, não `top/left`: um deslocamento composto não tira a barra\n // do fluxo nem briga com o `sticky` do pai — ele desloca o que o sticky\n // já posicionou.\n style={offset.x || offset.y ? { transform: `translate3d(${offset.x}px, ${offset.y}px, 0)` } : undefined}\n className={cn(\n // O mesmo vidro do assistente (fayz-floating-surface, em styles.css):\n // é a outra coisa que flutua sobre a página, e as duas se diziam\n // flutuantes em materiais diferentes. Fill fino + blur pesado, para a\n // grade passar por baixo sem competir.\n 'fayz-floating-surface pointer-events-auto flex max-w-full flex-wrap items-center justify-end gap-2 rounded-2xl px-2 py-1.5',\n dragging && 'select-none',\n className,\n )}\n >\n {movable ? (\n <button\n type=\"button\"\n aria-label={moveLabel ?? 'Mover a barra'}\n title={moveLabel ?? 'Mover a barra'}\n // `touch-none` para o arrasto não virar rolagem no celular; o\n // duplo clique devolve a barra ao canto de origem, que é a saída\n // para quem a largou num lugar ruim.\n onDoubleClick={reset}\n {...handlers}\n className={cn(\n 'flex h-[26px] w-4 shrink-0 touch-none items-center justify-center rounded-md text-muted-foreground/50',\n 'transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n dragging ? 'cursor-grabbing text-foreground' : 'cursor-grab',\n )}\n >\n <GripVertical className=\"h-3.5 w-3.5\" />\n </button>\n ) : null}\n {range}\n {filters}\n {chips}\n {customize}\n {actions}\n {onRefresh ? (\n <Button\n variant=\"ghost\" size=\"sm\" onClick={onRefresh}\n aria-label={refreshLabel}\n className=\"w-[26px] border-0 bg-transparent p-0 text-muted-foreground shadow-none hover:bg-transparent hover:text-foreground\"\n >\n <RefreshCw className=\"h-3 w-3\" />\n </Button>\n ) : null}\n </div>\n </div>\n )\n}\n"]}