@fayz-ai/ui 0.42.0 → 0.43.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 (37) hide show
  1. package/dist/{chunk-47B6ISJ6.js → chunk-3HGLZIQT.js} +140 -344
  2. package/dist/chunk-3HGLZIQT.js.map +1 -0
  3. package/dist/{chunk-W7CIJU5U.js → chunk-4BP33MTZ.js} +4 -4
  4. package/dist/{chunk-W7CIJU5U.js.map → chunk-4BP33MTZ.js.map} +1 -1
  5. package/dist/{chunk-UKMRHO5B.js → chunk-L6PNGGHM.js} +713 -244
  6. package/dist/chunk-L6PNGGHM.js.map +1 -0
  7. package/dist/{chunk-GG5XY6SF.js → chunk-ZMS7TNJD.js} +149 -196
  8. package/dist/chunk-ZMS7TNJD.js.map +1 -0
  9. package/dist/dashboard/index.js +3 -3
  10. package/dist/index.d.ts +1 -1
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +8 -8
  13. package/dist/layout/AppShell.d.ts +4 -1
  14. package/dist/layout/AppShell.d.ts.map +1 -1
  15. package/dist/layout/index.js +1 -1
  16. package/dist/primitives/bulk-action-bar.d.ts +3 -1
  17. package/dist/primitives/bulk-action-bar.d.ts.map +1 -1
  18. package/dist/primitives/data-table.d.ts +8 -1
  19. package/dist/primitives/data-table.d.ts.map +1 -1
  20. package/dist/primitives/dropdown.d.ts +2 -2
  21. package/dist/primitives/dropdown.d.ts.map +1 -1
  22. package/dist/primitives/index.d.ts +1 -1
  23. package/dist/primitives/index.d.ts.map +1 -1
  24. package/dist/primitives/index.js +3 -3
  25. package/dist/primitives/list-view.d.ts +3 -1
  26. package/dist/primitives/list-view.d.ts.map +1 -1
  27. package/dist/primitives/mobile-scrim.d.ts +29 -0
  28. package/dist/primitives/mobile-scrim.d.ts.map +1 -0
  29. package/dist/primitives/page-actions.d.ts +5 -14
  30. package/dist/primitives/page-actions.d.ts.map +1 -1
  31. package/dist/primitives/use-row-selection.d.ts +2 -0
  32. package/dist/primitives/use-row-selection.d.ts.map +1 -1
  33. package/dist/styles.css +55 -0
  34. package/package.json +2 -2
  35. package/dist/chunk-47B6ISJ6.js.map +0 -1
  36. package/dist/chunk-GG5XY6SF.js.map +0 -1
  37. package/dist/chunk-UKMRHO5B.js.map +0 -1
@@ -1,14 +1,13 @@
1
- import { PageViewBar } from './chunk-UKMRHO5B.js';
1
+ import { useIsWide, Dropdown, DropdownTrigger, DropdownContent, DropdownItem, PageViewBar } from './chunk-L6PNGGHM.js';
2
2
  import { cn, Button } from './chunk-FKYFYGAS.js';
3
- import * as React4 from 'react';
3
+ import * as React3 from 'react';
4
4
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
- import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
6
- import { ChevronRight, Check, Circle, Minus, ChevronDown, ArrowDown, ArrowUp, ArrowUpDown, ListFilter, X, Calendar, RefreshCw } from 'lucide-react';
5
+ import { Minus, Check, ChevronDown, ChevronRight, ArrowDown, ArrowUp, ArrowUpDown, ListFilter, X, Calendar, RefreshCw } from 'lucide-react';
7
6
  import { useReactTable, getSortedRowModel, getCoreRowModel, flexRender } from '@tanstack/react-table';
8
7
  import { useTranslation } from '@fayz-ai/core';
9
8
  import * as PopoverPrimitive from '@radix-ui/react-popover';
10
9
 
11
- var Card = React4.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
10
+ var Card = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
12
11
  "div",
13
12
  {
14
13
  ref,
@@ -20,7 +19,7 @@ var Card = React4.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ j
20
19
  }
21
20
  ));
22
21
  Card.displayName = "Card";
23
- var CardHeader = React4.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
22
+ var CardHeader = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
24
23
  "div",
25
24
  {
26
25
  ref,
@@ -29,7 +28,7 @@ var CardHeader = React4.forwardRef(({ className, ...props }, ref) => /* @__PURE_
29
28
  }
30
29
  ));
31
30
  CardHeader.displayName = "CardHeader";
32
- var CardTitle = React4.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
31
+ var CardTitle = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
33
32
  "h3",
34
33
  {
35
34
  ref,
@@ -41,7 +40,7 @@ var CardTitle = React4.forwardRef(({ className, ...props }, ref) => /* @__PURE__
41
40
  }
42
41
  ));
43
42
  CardTitle.displayName = "CardTitle";
44
- var CardDescription = React4.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
43
+ var CardDescription = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
45
44
  "p",
46
45
  {
47
46
  ref,
@@ -50,9 +49,9 @@ var CardDescription = React4.forwardRef(({ className, ...props }, ref) => /* @__
50
49
  }
51
50
  ));
52
51
  CardDescription.displayName = "CardDescription";
53
- var CardContent = React4.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("p-4 pt-0", className), ...props }));
52
+ var CardContent = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("p-4 pt-0", className), ...props }));
54
53
  CardContent.displayName = "CardContent";
55
- var CardFooter = React4.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
54
+ var CardFooter = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
56
55
  "div",
57
56
  {
58
57
  ref,
@@ -61,147 +60,13 @@ var CardFooter = React4.forwardRef(({ className, ...props }, ref) => /* @__PURE_
61
60
  }
62
61
  ));
63
62
  CardFooter.displayName = "CardFooter";
64
- var Dropdown = DropdownMenuPrimitive.Root;
65
- var DropdownTrigger = DropdownMenuPrimitive.Trigger;
66
- var DropdownGroup = DropdownMenuPrimitive.Group;
67
- var DropdownPortal = DropdownMenuPrimitive.Portal;
68
- var DropdownSub = DropdownMenuPrimitive.Sub;
69
- var DropdownRadioGroup = DropdownMenuPrimitive.RadioGroup;
70
- var DropdownSubTrigger = React4.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxs(
71
- DropdownMenuPrimitive.SubTrigger,
72
- {
73
- ref,
74
- className: cn(
75
- "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",
76
- inset && "pl-8",
77
- className
78
- ),
79
- ...props,
80
- children: [
81
- children,
82
- /* @__PURE__ */ jsx(ChevronRight, { className: "ml-auto h-4 w-4" })
83
- ]
84
- }
85
- ));
86
- DropdownSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
87
- var DropdownSubContent = React4.forwardRef(({ className, ...props }, ref) => (
88
- // Portaled, like DropdownContent. Without it the submenu renders inside the
89
- // parent panel's DOM — and that panel is `overflow-hidden`, so the submenu
90
- // was clipped to its box: a flyout you could open and never reach.
91
- /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(
92
- DropdownMenuPrimitive.SubContent,
93
- {
94
- ref,
95
- className: cn(
96
- "fayz-glass-surface z-[110] 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",
97
- className
98
- ),
99
- ...props
100
- }
101
- ) })
102
- ));
103
- DropdownSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
104
- var DropdownContent = React4.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(
105
- DropdownMenuPrimitive.Content,
106
- {
107
- ref,
108
- sideOffset,
109
- className: cn(
110
- "fayz-glass-surface z-[110] 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",
111
- className
112
- ),
113
- ...props
114
- }
115
- ) }));
116
- DropdownContent.displayName = DropdownMenuPrimitive.Content.displayName;
117
- var DropdownItem = React4.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(
118
- DropdownMenuPrimitive.Item,
119
- {
120
- ref,
121
- className: cn(
122
- "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",
123
- inset && "pl-8",
124
- className
125
- ),
126
- ...props
127
- }
128
- ));
129
- DropdownItem.displayName = DropdownMenuPrimitive.Item.displayName;
130
- var DropdownCheckboxItem = React4.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ jsxs(
131
- DropdownMenuPrimitive.CheckboxItem,
132
- {
133
- ref,
134
- className: cn(
135
- "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",
136
- className
137
- ),
138
- checked,
139
- ...props,
140
- children: [
141
- /* @__PURE__ */ jsx("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(Check, { className: "h-4 w-4" }) }) }),
142
- children
143
- ]
144
- }
145
- ));
146
- DropdownCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
147
- var DropdownRadioItem = React4.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
148
- DropdownMenuPrimitive.RadioItem,
149
- {
150
- ref,
151
- className: cn(
152
- "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",
153
- className
154
- ),
155
- ...props,
156
- children: [
157
- /* @__PURE__ */ jsx("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(Circle, { className: "h-2 w-2 fill-current" }) }) }),
158
- children
159
- ]
160
- }
161
- ));
162
- DropdownRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
163
- var DropdownLabel = React4.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(
164
- DropdownMenuPrimitive.Label,
165
- {
166
- ref,
167
- className: cn(
168
- "px-2 py-1.5 text-sm font-semibold",
169
- inset && "pl-8",
170
- className
171
- ),
172
- ...props
173
- }
174
- ));
175
- DropdownLabel.displayName = DropdownMenuPrimitive.Label.displayName;
176
- var DropdownSeparator = React4.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
177
- DropdownMenuPrimitive.Separator,
178
- {
179
- ref,
180
- className: cn("-mx-1 my-1 h-px bg-muted", className),
181
- ...props
182
- }
183
- ));
184
- DropdownSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
185
- var DropdownShortcut = ({
186
- className,
187
- ...props
188
- }) => {
189
- return /* @__PURE__ */ jsx(
190
- "span",
191
- {
192
- className: cn("ml-auto text-xs tracking-widest opacity-60", className),
193
- ...props
194
- }
195
- );
196
- };
197
- DropdownShortcut.displayName = "DropdownShortcut";
198
63
  var COLOR_CLASSES = {
199
64
  primary: "border-primary bg-primary text-primary-foreground",
200
65
  success: "border-success bg-success text-white dark:border-success dark:bg-success",
201
66
  warning: "border-warning bg-warning text-white",
202
67
  destructive: "border-destructive bg-destructive text-destructive-foreground"
203
68
  };
204
- var Checkbox = React4.forwardRef(
69
+ var Checkbox = React3.forwardRef(
205
70
  ({ checked = false, onChange, disabled, className, color = "primary", id, indeterminate = false, ...props }, ref) => {
206
71
  const filled = checked || indeterminate;
207
72
  return /* @__PURE__ */ jsx(
@@ -243,9 +108,11 @@ function DataTable({
243
108
  onSelectedIdsChange,
244
109
  getRowId,
245
110
  rowClassName,
246
- groupBy
111
+ groupBy,
112
+ mobileLayout = "table"
247
113
  }) {
248
114
  const t = useTranslation();
115
+ const wide = useIsWide();
249
116
  const isCard = variant === "card";
250
117
  const wrapperCls = isCard ? "overflow-hidden rounded-card border bg-card shadow-sm" : variant === "bare" ? "" : "overflow-hidden rounded-lg border";
251
118
  const headerCls = isCard ? "border-b bg-muted/50" : variant === "bare" ? "border-b bg-muted/30 rounded-none" : "border-b bg-muted/30";
@@ -253,37 +120,37 @@ function DataTable({
253
120
  const tdCls = compact ? "px-3 py-1.5 align-middle text-xs" : "px-4 py-3 align-middle";
254
121
  const tableCls = compact ? "w-full text-xs min-w-max" : "w-full text-sm min-w-max";
255
122
  const rowHoverCls = isCard ? "hover:bg-muted/30" : "hover:bg-muted/20";
256
- const [sorting, setSorting] = React4.useState([]);
257
- const [ownCollapsed, setOwnCollapsed] = React4.useState([]);
123
+ const [sorting, setSorting] = React3.useState([]);
124
+ const [ownCollapsed, setOwnCollapsed] = React3.useState([]);
258
125
  const collapsedKeys = groupBy?.collapsed ?? ownCollapsed;
259
- const collapsed = React4.useMemo(() => new Set(collapsedKeys), [collapsedKeys]);
126
+ const collapsed = React3.useMemo(() => new Set(collapsedKeys), [collapsedKeys]);
260
127
  const onCollapsedChange = groupBy?.onCollapsedChange;
261
- const toggleGroup = React4.useCallback((key) => {
128
+ const toggleGroup = React3.useCallback((key) => {
262
129
  const next = collapsed.has(key) ? [...collapsed].filter((k) => k !== key) : [...collapsed, key];
263
130
  if (onCollapsedChange) onCollapsedChange(next);
264
131
  else setOwnCollapsed(next);
265
132
  }, [collapsed, onCollapsedChange]);
266
- const rowId = React4.useCallback(
133
+ const rowId = React3.useCallback(
267
134
  (row) => getRowId ? getRowId(row) : String(row.id ?? ""),
268
135
  [getRowId]
269
136
  );
270
- const selected = React4.useMemo(() => new Set(selectedIds ?? []), [selectedIds]);
271
- const pageIds = React4.useMemo(() => data.map(rowId), [data, rowId]);
137
+ const selected = React3.useMemo(() => new Set(selectedIds ?? []), [selectedIds]);
138
+ const pageIds = React3.useMemo(() => data.map(rowId), [data, rowId]);
272
139
  const selectedOnPage = pageIds.filter((id) => selected.has(id)).length;
273
140
  const allOnPageSelected = pageIds.length > 0 && selectedOnPage === pageIds.length;
274
- const toggleRow = React4.useCallback((id) => {
141
+ const toggleRow = React3.useCallback((id) => {
275
142
  const next = new Set(selected);
276
143
  if (next.has(id)) next.delete(id);
277
144
  else next.add(id);
278
145
  onSelectedIdsChange?.([...next]);
279
146
  }, [selected, onSelectedIdsChange]);
280
- const toggleAllOnPage = React4.useCallback(() => {
147
+ const toggleAllOnPage = React3.useCallback(() => {
281
148
  const next = new Set(selected);
282
149
  if (allOnPageSelected) pageIds.forEach((id) => next.delete(id));
283
150
  else pageIds.forEach((id) => next.add(id));
284
151
  onSelectedIdsChange?.([...next]);
285
152
  }, [selected, allOnPageSelected, pageIds, onSelectedIdsChange]);
286
- const selectionColumn = React4.useMemo(() => ({
153
+ const selectionColumn = React3.useMemo(() => ({
287
154
  id: "__select__",
288
155
  enableSorting: false,
289
156
  header: () => /* @__PURE__ */ jsx(
@@ -310,7 +177,7 @@ function DataTable({
310
177
  // ids: turning the page with nothing selected changes no other dep, and the
311
178
  // memo would hand the header a button that ticks the previous page's rows.
312
179
  }), [allOnPageSelected, selectedOnPage, selected, rowId, toggleRow, toggleAllOnPage, t]);
313
- const allColumns = React4.useMemo(
180
+ const allColumns = React3.useMemo(
314
181
  () => selectable ? [selectionColumn, ...columns] : columns,
315
182
  [selectable, selectionColumn, columns]
316
183
  );
@@ -322,9 +189,9 @@ function DataTable({
322
189
  onSortingChange: setSorting,
323
190
  state: { sorting }
324
191
  });
325
- const [tableEl, setTableEl] = React4.useState(null);
326
- const headScrollRef = React4.useRef(null);
327
- const [scrollEl, setScrollEl] = React4.useState(null);
192
+ const [tableEl, setTableEl] = React3.useState(null);
193
+ const headScrollRef = React3.useRef(null);
194
+ const [scrollEl, setScrollEl] = React3.useState(null);
328
195
  const overflowing = useOverflowX(scrollEl);
329
196
  const floating = useFloatingHeader(tableEl, [data, allColumns, collapsed, sorting]);
330
197
  const pinnedCls = cn("sticky right-0 z-[1]", overflowing && "before:pointer-events-none before:absolute before:inset-y-0 before:-left-8 before:w-8 before:bg-[linear-gradient(to_left,var(--pin-bg),transparent)] before:content-['']");
@@ -338,6 +205,18 @@ function DataTable({
338
205
  background: "var(--pin-bg)"
339
206
  });
340
207
  const groupBandBackground = "linear-gradient(hsl(var(--muted) / 0.4), hsl(var(--muted) / 0.4)), hsl(var(--card))";
208
+ if (loading && mobileLayout === "cards" && !wide) {
209
+ return /* @__PURE__ */ jsx("div", { className: isCard ? "space-y-2" : "divide-y", "aria-busy": true, children: Array.from({ length: skeletonRows }).map((_, i) => /* @__PURE__ */ jsxs("div", { className: cn("px-4 py-3", isCard && "rounded-card border bg-card shadow-sm"), children: [
210
+ /* @__PURE__ */ jsxs("div", { className: "flex min-h-8 items-center justify-between gap-3", children: [
211
+ /* @__PURE__ */ jsx("div", { className: "h-4 w-2/5 animate-pulse rounded bg-muted" }),
212
+ /* @__PURE__ */ jsx("div", { className: "h-5 w-9 animate-pulse rounded-full bg-muted" })
213
+ ] }),
214
+ /* @__PURE__ */ jsx("div", { className: "mt-2.5 grid grid-cols-2 gap-x-4 gap-y-2.5", children: [0, 1].map((j) => /* @__PURE__ */ jsxs("div", { children: [
215
+ /* @__PURE__ */ jsx("div", { className: "h-3 w-14 animate-pulse rounded bg-muted" }),
216
+ /* @__PURE__ */ jsx("div", { className: "mt-1.5 h-3.5 w-24 animate-pulse rounded bg-muted" })
217
+ ] }, j)) })
218
+ ] }, i)) });
219
+ }
341
220
  if (loading) {
342
221
  return /* @__PURE__ */ jsx("div", { className: wrapperCls, children: /* @__PURE__ */ jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxs("table", { className: tableCls, children: [
343
222
  /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { className: headerCls, children: allColumns.map((_, i) => /* @__PURE__ */ jsx("th", { className: thCls, children: /* @__PURE__ */ jsx("div", { className: "h-3.5 w-20 animate-pulse rounded bg-muted" }) }, i)) }) }),
@@ -348,6 +227,82 @@ function DataTable({
348
227
  if (showEmptyBlock) {
349
228
  return /* @__PURE__ */ jsx("div", { className: wrapperCls, children: /* @__PURE__ */ jsx("div", { className: "flex min-h-64 w-full items-center justify-center px-4 py-10 text-center text-muted-foreground", children: emptyMessage }) });
350
229
  }
230
+ if (mobileLayout === "cards" && !wide) {
231
+ const headerOf = new Map(table.getFlatHeaders().map((h) => [h.column.id, h]));
232
+ const renderCard = (row) => {
233
+ const isSelected = selectable && selected.has(rowId(row.original));
234
+ const cells = row.getVisibleCells();
235
+ const select = cells.find((c) => c.column.id === "__select__");
236
+ const actions = cells.filter((c) => c.column.id !== "__select__" && isPinned(c.column) && !isMobileHidden(c.column));
237
+ const fields = cells.filter((c) => c.column.id !== "__select__" && !isPinned(c.column) && !isMobileHidden(c.column));
238
+ const title = fields.find((c) => mobileRole(c.column) === "title") ?? fields[0];
239
+ const badges = fields.filter((c) => c !== title && mobileRole(c.column) === "badge");
240
+ const rest = fields.filter((c) => c !== title && !badges.includes(c) && !isEmptyCell(c));
241
+ return /* @__PURE__ */ jsxs(
242
+ "div",
243
+ {
244
+ role: onRowClick ? "button" : void 0,
245
+ tabIndex: onRowClick ? 0 : void 0,
246
+ onClick: () => onRowClick?.(row.original),
247
+ onKeyDown: (e) => {
248
+ if (onRowClick && e.key === "Enter") onRowClick(row.original);
249
+ },
250
+ "data-selected": isSelected || void 0,
251
+ "data-scrim-focus": true,
252
+ className: cn(
253
+ "flex gap-3 px-4 py-3 text-sm transition-colors",
254
+ isCard && "rounded-card border bg-card shadow-sm",
255
+ onRowClick && "cursor-pointer active:bg-muted/40",
256
+ isSelected && "bg-muted/40",
257
+ rowClassName?.(row.original)
258
+ ),
259
+ children: [
260
+ select && /* @__PURE__ */ jsx("div", { className: "flex h-8 items-center", onClick: (e) => e.stopPropagation(), children: flexRender(select.column.columnDef.cell, select.getContext()) }),
261
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
262
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
263
+ /* @__PURE__ */ jsx("div", { className: "flex min-h-8 min-w-0 flex-1 items-center font-medium", children: /* @__PURE__ */ jsx("div", { className: "min-w-0 max-w-full truncate [&_*]:truncate [&_img]:shrink-0 [&_svg]:shrink-0", children: title && flexRender(title.column.columnDef.cell, title.getContext()) }) }),
264
+ (badges.length > 0 || actions.length > 0) && /* @__PURE__ */ jsxs("div", { className: "-mr-2 flex min-h-8 shrink-0 items-center gap-3", onClick: (e) => e.stopPropagation(), children: [
265
+ badges.map((c) => /* @__PURE__ */ jsx(React3.Fragment, { children: flexRender(c.column.columnDef.cell, c.getContext()) }, c.id)),
266
+ actions.map((c) => /* @__PURE__ */ jsx(React3.Fragment, { children: flexRender(c.column.columnDef.cell, c.getContext()) }, c.id))
267
+ ] })
268
+ ] }),
269
+ rest.length > 0 && // Two columns of label-over-value. Cells written for a table align
270
+ // themselves right or centre; in a card every value reads from the left.
271
+ /* @__PURE__ */ jsx("dl", { className: "mt-2.5 grid grid-cols-2 gap-x-4 gap-y-2.5 [&_.text-center]:text-left [&_.text-right]:text-left", children: rest.map((c) => {
272
+ const header = headerOf.get(c.column.id);
273
+ return /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
274
+ /* @__PURE__ */ jsx("dt", { className: "text-xs text-muted-foreground", children: header ? flexRender(header.column.columnDef.header, header.getContext()) : null }),
275
+ /* @__PURE__ */ jsx("dd", { className: "mt-0.5 min-w-0", children: flexRender(c.column.columnDef.cell, c.getContext()) })
276
+ ] }, c.id);
277
+ }) })
278
+ ] })
279
+ ]
280
+ },
281
+ row.id
282
+ );
283
+ };
284
+ return /* @__PURE__ */ jsx("div", { className: isCard ? "space-y-2" : "divide-y", children: groupRows(table.getRowModel().rows, groupBy).flatMap((group) => {
285
+ if (!group) return table.getRowModel().rows.map(renderCard);
286
+ const isCollapsed = collapsed.has(group.key);
287
+ return [
288
+ /* @__PURE__ */ jsx("div", { className: "border-b bg-muted/40 text-sm", children: /* @__PURE__ */ jsxs(
289
+ "button",
290
+ {
291
+ type: "button",
292
+ className: "flex w-full items-center gap-2 px-4 py-2 text-left font-medium text-foreground",
293
+ onClick: () => toggleGroup(group.key),
294
+ "aria-expanded": !isCollapsed,
295
+ children: [
296
+ isCollapsed ? /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4 text-muted-foreground" }) : /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4 text-muted-foreground" }),
297
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: group.key ? groupBy?.renderLabel?.(group.key, group.rows.map((r) => r.original)) ?? group.key : groupBy?.emptyLabel ?? "\u2014" }),
298
+ /* @__PURE__ */ jsx("span", { className: "rounded-full bg-background px-2 py-0.5 text-[11px] font-medium tabular-nums text-muted-foreground", children: group.rows.length })
299
+ ]
300
+ }
301
+ ) }, `__group__${group.key}`),
302
+ ...isCollapsed ? [] : group.rows.map(renderCard)
303
+ ];
304
+ }) });
305
+ }
351
306
  const headerRows = /* @__PURE__ */ jsx(Fragment, { children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsx("tr", { className: headerCls, children: headerGroup.headers.map((header) => {
352
307
  const sorted = header.column.getIsSorted();
353
308
  return /* @__PURE__ */ jsx(
@@ -486,6 +441,17 @@ var truncateCls = "max-w-[20rem] truncate [&_*]:truncate";
486
441
  function isTruncated(column) {
487
442
  return !!column.columnDef.meta?.truncate;
488
443
  }
444
+ function isEmptyCell(cell) {
445
+ if (!cell.column.accessorFn) return false;
446
+ const value = cell.getValue();
447
+ return value == null || value === "" || Array.isArray(value) && value.length === 0;
448
+ }
449
+ function mobileRole(column) {
450
+ return column.columnDef.meta?.mobile;
451
+ }
452
+ function isMobileHidden(column) {
453
+ return mobileRole(column) === "hidden";
454
+ }
489
455
  function showFullTextOnHover(e) {
490
456
  const el = e.currentTarget;
491
457
  const clipped = el.scrollWidth > el.clientWidth || [...el.querySelectorAll("*")].some((c) => c.scrollWidth > c.clientWidth);
@@ -496,8 +462,8 @@ function isPinned(column) {
496
462
  return column.id === "actions" || column.columnDef.meta?.pin === "right";
497
463
  }
498
464
  function useOverflowX(el) {
499
- const [overflowing, setOverflowing] = React4.useState(false);
500
- React4.useEffect(() => {
465
+ const [overflowing, setOverflowing] = React3.useState(false);
466
+ React3.useEffect(() => {
501
467
  if (!el) return;
502
468
  const check = () => setOverflowing(el.scrollWidth > el.clientWidth + 1);
503
469
  check();
@@ -509,8 +475,8 @@ function useOverflowX(el) {
509
475
  return overflowing;
510
476
  }
511
477
  function useFloatingHeader(table, deps) {
512
- const [state, setState] = React4.useState({ widths: [], tableWidth: 0, headH: 0, bandH: 0, activeGroup: null });
513
- const measure = React4.useCallback(() => {
478
+ const [state, setState] = React3.useState({ widths: [], tableWidth: 0, headH: 0, bandH: 0, activeGroup: null });
479
+ const measure = React3.useCallback(() => {
514
480
  if (!table?.tHead) return;
515
481
  const cells = [...table.tHead.rows[0]?.cells ?? []];
516
482
  const widths = cells.map((c) => c.getBoundingClientRect().width);
@@ -535,10 +501,10 @@ function useFloatingHeader(table, deps) {
535
501
  }
536
502
  setState((prev) => prev.tableWidth === tableWidth && prev.headH === headH && prev.bandH === bandH && prev.activeGroup === activeGroup && prev.widths.length === widths.length && prev.widths.every((w, i) => w === widths[i]) ? prev : { widths, tableWidth, headH, bandH, activeGroup });
537
503
  }, [table]);
538
- React4.useLayoutEffect(() => {
504
+ React3.useLayoutEffect(() => {
539
505
  measure();
540
506
  }, [measure, ...deps]);
541
- React4.useEffect(() => {
507
+ React3.useEffect(() => {
542
508
  if (!table) return;
543
509
  let frame = 0;
544
510
  const schedule = () => {
@@ -569,19 +535,6 @@ function groupRows(rows, groupBy) {
569
535
  }
570
536
  return [...byKey.entries()].sort(([a], [b]) => a === "" ? 1 : b === "" ? -1 : a.localeCompare(b, void 0, { sensitivity: "base" })).map(([key, list]) => ({ key, rows: list }));
571
537
  }
572
- var WIDE_QUERY = "(min-width: 768px)";
573
- function useIsWide(query = WIDE_QUERY) {
574
- const [wide, setWide] = React4.useState(
575
- () => typeof window === "undefined" ? true : window.matchMedia(query).matches
576
- );
577
- React4.useEffect(() => {
578
- const mq = window.matchMedia(query);
579
- const onChange = () => setWide(mq.matches);
580
- mq.addEventListener("change", onChange);
581
- return () => mq.removeEventListener("change", onChange);
582
- }, [query]);
583
- return wide;
584
- }
585
538
  function Skeleton({
586
539
  className,
587
540
  ...props
@@ -612,14 +565,14 @@ function TableSkeleton({ columns = 4, rows = 2 }) {
612
565
  var Popover = PopoverPrimitive.Root;
613
566
  var PopoverTrigger = PopoverPrimitive.Trigger;
614
567
  var PopoverAnchor = PopoverPrimitive.Anchor;
615
- var PopoverContent = React4.forwardRef(({ className, align = "start", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx(
568
+ var PopoverContent = React3.forwardRef(({ className, align = "start", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx(
616
569
  PopoverPrimitive.Content,
617
570
  {
618
571
  ref,
619
572
  align,
620
573
  sideOffset,
621
574
  className: cn(
622
- "fayz-glass-surface z-[110] w-72 rounded-xl border bg-popover p-0 text-popover-foreground shadow-lg outline-none",
575
+ "fayz-glass-surface fz-menu-glass z-[110] w-72 rounded-xl border bg-popover p-0 text-popover-foreground shadow-lg outline-none",
623
576
  "data-[state=open]:animate-zoom-in data-[state=closed]:animate-zoom-out",
624
577
  className
625
578
  ),
@@ -644,14 +597,14 @@ function FilterMenuRow({ active, onClick, children }) {
644
597
  );
645
598
  }
646
599
  function FilterMenu({ fields, label = "Filtros", activeCount = 0, onClear, clearLabel = "Limpar filtros", header, align = "end", className }) {
647
- const [open, setOpen] = React4.useState(false);
648
- const [hovered, setHoveredRaw] = React4.useState(null);
649
- const [query, setQuery] = React4.useState("");
650
- const setHovered = React4.useCallback((id) => {
600
+ const [open, setOpen] = React3.useState(false);
601
+ const [hovered, setHoveredRaw] = React3.useState(null);
602
+ const [query, setQuery] = React3.useState("");
603
+ const setHovered = React3.useCallback((id) => {
651
604
  setHoveredRaw(id);
652
605
  setQuery("");
653
606
  }, []);
654
- const close = React4.useCallback(() => setOpen(false), []);
607
+ const close = React3.useCallback(() => setOpen(false), []);
655
608
  return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: (o) => {
656
609
  setOpen(o);
657
610
  if (!o) setHovered(null);
@@ -747,18 +700,18 @@ function FilterMenu({ fields, label = "Filtros", activeCount = 0, onClear, clear
747
700
  ] })
748
701
  ] });
749
702
  }
750
- var ToolbarSurfaceContext = React4.createContext({
703
+ var ToolbarSurfaceContext = React3.createContext({
751
704
  surface: "bar",
752
705
  close: () => {
753
706
  }
754
707
  });
755
708
  function useToolbarSurface() {
756
- return React4.useContext(ToolbarSurfaceContext).surface;
709
+ return React3.useContext(ToolbarSurfaceContext).surface;
757
710
  }
758
711
  function useToolbarPanelClose() {
759
- return React4.useContext(ToolbarSurfaceContext).close;
712
+ return React3.useContext(ToolbarSurfaceContext).close;
760
713
  }
761
- var ToolbarButton = React4.forwardRef(function ToolbarButton2({ icon: Icon, caret = true, children, className, ...props }, ref) {
714
+ var ToolbarButton = React3.forwardRef(function ToolbarButton2({ icon: Icon, caret = true, children, className, ...props }, ref) {
762
715
  const panel = useToolbarSurface() === "panel";
763
716
  if (panel) {
764
717
  return /* @__PURE__ */ jsxs(
@@ -802,7 +755,7 @@ var ToolbarButton = React4.forwardRef(function ToolbarButton2({ icon: Icon, care
802
755
  }
803
756
  );
804
757
  });
805
- var ToolbarAction = React4.forwardRef(function ToolbarAction2({ icon: Icon, caret = false, children, className, ...props }, ref) {
758
+ var ToolbarAction = React3.forwardRef(function ToolbarAction2({ icon: Icon, caret = false, children, className, ...props }, ref) {
806
759
  const panel = useToolbarSurface() === "panel";
807
760
  if (panel) {
808
761
  return /* @__PURE__ */ jsxs(
@@ -880,8 +833,8 @@ function PageToolbar({
880
833
  className
881
834
  }) {
882
835
  const wide = useIsWide();
883
- const [open, setOpen] = React4.useState(false);
884
- const panelSurface = React4.useMemo(
836
+ const [open, setOpen] = React3.useState(false);
837
+ const panelSurface = React3.useMemo(
885
838
  () => ({ surface: "panel", close: () => setOpen(false) }),
886
839
  []
887
840
  );
@@ -947,6 +900,6 @@ function PageToolbar({
947
900
  );
948
901
  }
949
902
 
950
- export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, DataTable, Dropdown, DropdownCheckboxItem, DropdownContent, DropdownGroup, DropdownItem, DropdownLabel, DropdownPortal, DropdownRadioGroup, DropdownRadioItem, DropdownSeparator, DropdownShortcut, DropdownSub, DropdownSubContent, DropdownSubTrigger, DropdownTrigger, FilterMenu, FilterMenuRow, PageToolbar, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, RangeControl, Skeleton, TOOLBAR_ICON_DOT, TOOLBAR_ICON_TRIGGER, TableSkeleton, ToolbarAction, ToolbarButton, WIDE_QUERY, useIsWide, useToolbarPanelClose, useToolbarSurface };
951
- //# sourceMappingURL=chunk-GG5XY6SF.js.map
952
- //# sourceMappingURL=chunk-GG5XY6SF.js.map
903
+ export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, DataTable, FilterMenu, FilterMenuRow, PageToolbar, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, RangeControl, Skeleton, TOOLBAR_ICON_DOT, TOOLBAR_ICON_TRIGGER, TableSkeleton, ToolbarAction, ToolbarButton, useToolbarPanelClose, useToolbarSurface };
904
+ //# sourceMappingURL=chunk-ZMS7TNJD.js.map
905
+ //# sourceMappingURL=chunk-ZMS7TNJD.js.map