@fayz-ai/ui 0.22.0 → 0.24.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 (75) hide show
  1. package/dist/analytics/AnalyticsCard.d.ts.map +1 -1
  2. package/dist/analytics/AnalyticsControls.d.ts.map +1 -1
  3. package/dist/analytics/DateRangeControl.d.ts +14 -0
  4. package/dist/analytics/DateRangeControl.d.ts.map +1 -0
  5. package/dist/analytics/StatementTable.d.ts +22 -0
  6. package/dist/analytics/StatementTable.d.ts.map +1 -0
  7. package/dist/analytics/context.d.ts +8 -0
  8. package/dist/analytics/context.d.ts.map +1 -1
  9. package/dist/analytics/derive.d.ts +13 -0
  10. package/dist/analytics/derive.d.ts.map +1 -1
  11. package/dist/analytics/index.d.ts +7 -1
  12. package/dist/analytics/index.d.ts.map +1 -1
  13. package/dist/analytics/statement.d.ts +58 -0
  14. package/dist/analytics/statement.d.ts.map +1 -0
  15. package/dist/{chunk-E44WOPCR.js → chunk-HO2P2XB4.js} +428 -58
  16. package/dist/chunk-HO2P2XB4.js.map +1 -0
  17. package/dist/{chunk-7G3O54CC.js → chunk-L4TXDKMN.js} +5 -5
  18. package/dist/chunk-L4TXDKMN.js.map +1 -0
  19. package/dist/{chunk-ZSOT7KTE.js → chunk-NXFVYZY7.js} +467 -405
  20. package/dist/chunk-NXFVYZY7.js.map +1 -0
  21. package/dist/{chunk-DHNUZF2X.js → chunk-OWN3GFDG.js} +4 -3
  22. package/dist/chunk-OWN3GFDG.js.map +1 -0
  23. package/dist/{chunk-PQUS22JE.js → chunk-RRNMNFLF.js} +483 -794
  24. package/dist/chunk-RRNMNFLF.js.map +1 -0
  25. package/dist/chunk-UP7WVKSU.js +631 -0
  26. package/dist/chunk-UP7WVKSU.js.map +1 -0
  27. package/dist/{chunk-SUSW4LSW.js → chunk-XKFYX3DG.js} +5 -5
  28. package/dist/{chunk-SUSW4LSW.js.map → chunk-XKFYX3DG.js.map} +1 -1
  29. package/dist/dashboard/index.js +4 -4
  30. package/dist/icons.js +1 -1
  31. package/dist/index.d.ts +2 -2
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +672 -87
  34. package/dist/index.js.map +1 -1
  35. package/dist/layout/AppShell.d.ts +7 -1
  36. package/dist/layout/AppShell.d.ts.map +1 -1
  37. package/dist/layout/ShellSearch.d.ts +53 -0
  38. package/dist/layout/ShellSearch.d.ts.map +1 -0
  39. package/dist/layout/Sidebar.d.ts +10 -6
  40. package/dist/layout/Sidebar.d.ts.map +1 -1
  41. package/dist/layout/Takeover.d.ts.map +1 -1
  42. package/dist/layout/index.d.ts +1 -0
  43. package/dist/layout/index.d.ts.map +1 -1
  44. package/dist/layout/index.js +4 -4
  45. package/dist/primitives/data-table.d.ts.map +1 -1
  46. package/dist/primitives/date-range-chip.d.ts +32 -0
  47. package/dist/primitives/date-range-chip.d.ts.map +1 -0
  48. package/dist/primitives/header-tabs.d.ts.map +1 -1
  49. package/dist/primitives/index.d.ts +2 -1
  50. package/dist/primitives/index.d.ts.map +1 -1
  51. package/dist/primitives/index.js +5 -5
  52. package/dist/primitives/list-chrome.d.ts +22 -1
  53. package/dist/primitives/list-chrome.d.ts.map +1 -1
  54. package/dist/primitives/list-view.d.ts +56 -1
  55. package/dist/primitives/list-view.d.ts.map +1 -1
  56. package/dist/primitives/modal.d.ts +2 -0
  57. package/dist/primitives/modal.d.ts.map +1 -1
  58. package/dist/primitives/multi-select.d.ts +18 -1
  59. package/dist/primitives/multi-select.d.ts.map +1 -1
  60. package/dist/primitives/page-actions.d.ts +14 -0
  61. package/dist/primitives/page-actions.d.ts.map +1 -1
  62. package/dist/primitives/page-toolbar.d.ts +16 -1
  63. package/dist/primitives/page-toolbar.d.ts.map +1 -1
  64. package/dist/primitives/segmented-control.d.ts.map +1 -1
  65. package/dist/stores/layout.store.d.ts +20 -1
  66. package/dist/stores/layout.store.d.ts.map +1 -1
  67. package/dist/styles.css +58 -0
  68. package/package.json +2 -2
  69. package/dist/chunk-7G3O54CC.js.map +0 -1
  70. package/dist/chunk-DHNUZF2X.js.map +0 -1
  71. package/dist/chunk-E44WOPCR.js.map +0 -1
  72. package/dist/chunk-HKGTF2YA.js +0 -117
  73. package/dist/chunk-HKGTF2YA.js.map +0 -1
  74. package/dist/chunk-PQUS22JE.js.map +0 -1
  75. package/dist/chunk-ZSOT7KTE.js.map +0 -1
@@ -1,25 +1,24 @@
1
- import { useSaveBarVisible, useCrossModuleBack, useBackHandler, PageHeaderActions, SegmentedControl } from './chunk-PQUS22JE.js';
2
- import { useIsWide, Dropdown, DropdownTrigger, DropdownContent, DropdownSeparator, DropdownItem, Card, DataTable, Checkbox } from './chunk-E44WOPCR.js';
1
+ import { PageHeaderActions, SegmentedControl } from './chunk-UP7WVKSU.js';
2
+ import { Hint, Dropdown, DropdownTrigger, DropdownContent, DropdownSeparator, DropdownItem, Card, PageActionBar, DataTable, Popover, PopoverTrigger, PopoverContent, Checkbox, useIsWide } from './chunk-HO2P2XB4.js';
3
+ import { useSaveBarVisible, useCrossModuleBack, useBackHandler } from './chunk-RRNMNFLF.js';
3
4
  import { cn, Button } from './chunk-OKZ6WQB3.js';
4
- import * as React18 from 'react';
5
- import React18__default, { useState, useRef, useEffect, useMemo, useCallback } from 'react';
5
+ import * as React15 from 'react';
6
+ import React15__default, { useState, useRef, useEffect, useMemo, useCallback } from 'react';
6
7
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
7
8
  import { cva } from 'class-variance-authority';
8
9
  import * as DialogPrimitive from '@radix-ui/react-dialog';
9
- import { X, ChevronDown, ChevronUp, Check, ArrowLeft, MoreHorizontal, Plus, MoreVertical, Search, ChevronLeft, ChevronRight, ImageIcon, RefreshCw, Clock, Download, Calendar, Loader2 } from 'lucide-react';
10
+ import { X, ChevronDown, ChevronUp, Check, ArrowLeft, MoreHorizontal, Search, ChevronsLeft, ChevronLeft, ChevronRight, ChevronsRight, ImageIcon, RefreshCw, Clock, Plus, Download, Calendar, Loader2, CalendarDays, SlidersHorizontal } from 'lucide-react';
10
11
  import * as SelectPrimitive from '@radix-ui/react-select';
11
12
  import { Toaster } from 'sonner';
12
13
  export { toast } from 'sonner';
13
14
  import * as TabsPrimitive from '@radix-ui/react-tabs';
14
15
  import * as SeparatorPrimitive from '@radix-ui/react-separator';
15
- import * as TooltipPrimitive from '@radix-ui/react-tooltip';
16
- import { createPortal } from 'react-dom';
17
16
  import { useTranslation, getCountry, unmaskPhone, maskPhone, getCurrentLocale } from '@fayz-ai/core';
18
- import * as PopoverPrimitive from '@radix-ui/react-popover';
17
+ import { createPortal } from 'react-dom';
19
18
 
20
- var Input = React18.forwardRef(
19
+ var Input = React15.forwardRef(
21
20
  ({ className, type, error, description, id, ...props }, ref) => {
22
- const inputId = id ?? React18.useId();
21
+ const inputId = id ?? React15.useId();
23
22
  const descriptionId = description ? `${inputId}-description` : void 0;
24
23
  const errorId = error ? `${inputId}-error` : void 0;
25
24
  return /* @__PURE__ */ jsxs("div", { className: "w-full", children: [
@@ -101,13 +100,18 @@ var SIZE_MAP = {
101
100
  xl: "sm:max-w-xl",
102
101
  "2xl": "sm:max-w-2xl",
103
102
  "3xl": "sm:max-w-3xl",
103
+ // Duas colunas de trabalho lado a lado (ficha + linha do tempo) não cabem em
104
+ // 3xl: a coluna da direita fica com 20rem e o texto de cada anotação quebra
105
+ // a cada quatro palavras.
106
+ "4xl": "sm:max-w-4xl",
107
+ "5xl": "sm:max-w-5xl",
104
108
  full: "sm:max-w-[calc(100vw-4rem)]"
105
109
  };
106
110
  var Modal = DialogPrimitive.Root;
107
111
  var ModalTrigger = DialogPrimitive.Trigger;
108
112
  var ModalClose = DialogPrimitive.Close;
109
113
  var ModalPortal = DialogPrimitive.Portal;
110
- var ModalOverlay = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
114
+ var ModalOverlay = React15.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
111
115
  DialogPrimitive.Overlay,
112
116
  {
113
117
  ref,
@@ -120,7 +124,7 @@ var ModalOverlay = React18.forwardRef(({ className, ...props }, ref) => /* @__PU
120
124
  }
121
125
  ));
122
126
  ModalOverlay.displayName = "ModalOverlay";
123
- var ModalContent = React18.forwardRef(({ className, children, size = "lg", hideClose, noPadding, onPointerDownOutside, onInteractOutside, onCloseAutoFocus, ...props }, ref) => /* @__PURE__ */ jsx(ModalPortal, { children: /* @__PURE__ */ jsx(ModalOverlay, { children: /* @__PURE__ */ jsxs(
127
+ var ModalContent = React15.forwardRef(({ className, children, size = "lg", hideClose, noPadding, onPointerDownOutside, onInteractOutside, onCloseAutoFocus, ...props }, ref) => /* @__PURE__ */ jsx(ModalPortal, { children: /* @__PURE__ */ jsx(ModalOverlay, { children: /* @__PURE__ */ jsxs(
124
128
  DialogPrimitive.Content,
125
129
  {
126
130
  ref,
@@ -175,14 +179,14 @@ function ModalBody({ className, ...props }) {
175
179
  function ModalFooter({ className, ...props }) {
176
180
  return /* @__PURE__ */ jsx("div", { className: cn("mt-auto flex flex-col-reverse gap-2 sm:mt-0 sm:flex-row sm:justify-end sm:gap-0 sm:space-x-2 shrink-0", className), ...props });
177
181
  }
178
- var ModalTitle = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DialogPrimitive.Title, { ref, className: cn("text-lg font-semibold leading-none tracking-tight", className), ...props }));
182
+ var ModalTitle = React15.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DialogPrimitive.Title, { ref, className: cn("text-lg font-semibold leading-none tracking-tight", className), ...props }));
179
183
  ModalTitle.displayName = "ModalTitle";
180
- var ModalDescription = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DialogPrimitive.Description, { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
184
+ var ModalDescription = React15.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DialogPrimitive.Description, { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
181
185
  ModalDescription.displayName = "ModalDescription";
182
186
  var Select = SelectPrimitive.Root;
183
187
  var SelectGroup = SelectPrimitive.Group;
184
188
  var SelectValue = SelectPrimitive.Value;
185
- var SelectTrigger = React18.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
189
+ var SelectTrigger = React15.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
186
190
  SelectPrimitive.Trigger,
187
191
  {
188
192
  ref,
@@ -198,7 +202,7 @@ var SelectTrigger = React18.forwardRef(({ className, children, ...props }, ref)
198
202
  }
199
203
  ));
200
204
  SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
201
- var SelectScrollUpButton = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
205
+ var SelectScrollUpButton = React15.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
202
206
  SelectPrimitive.ScrollUpButton,
203
207
  {
204
208
  ref,
@@ -211,7 +215,7 @@ var SelectScrollUpButton = React18.forwardRef(({ className, ...props }, ref) =>
211
215
  }
212
216
  ));
213
217
  SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
214
- var SelectScrollDownButton = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
218
+ var SelectScrollDownButton = React15.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
215
219
  SelectPrimitive.ScrollDownButton,
216
220
  {
217
221
  ref,
@@ -224,7 +228,7 @@ var SelectScrollDownButton = React18.forwardRef(({ className, ...props }, ref) =
224
228
  }
225
229
  ));
226
230
  SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
227
- var SelectContent = React18.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
231
+ var SelectContent = React15.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
228
232
  SelectPrimitive.Content,
229
233
  {
230
234
  ref,
@@ -252,7 +256,7 @@ var SelectContent = React18.forwardRef(({ className, children, position = "poppe
252
256
  }
253
257
  ) }));
254
258
  SelectContent.displayName = SelectPrimitive.Content.displayName;
255
- var SelectLabel = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
259
+ var SelectLabel = React15.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
256
260
  SelectPrimitive.Label,
257
261
  {
258
262
  ref,
@@ -264,7 +268,7 @@ var SelectLabel = React18.forwardRef(({ className, ...props }, ref) => /* @__PUR
264
268
  }
265
269
  ));
266
270
  SelectLabel.displayName = SelectPrimitive.Label.displayName;
267
- var SelectItem = React18.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
271
+ var SelectItem = React15.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
268
272
  SelectPrimitive.Item,
269
273
  {
270
274
  ref,
@@ -280,7 +284,7 @@ var SelectItem = React18.forwardRef(({ className, children, ...props }, ref) =>
280
284
  }
281
285
  ));
282
286
  SelectItem.displayName = SelectPrimitive.Item.displayName;
283
- var SelectSeparator = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
287
+ var SelectSeparator = React15.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
284
288
  SelectPrimitive.Separator,
285
289
  {
286
290
  ref,
@@ -318,7 +322,7 @@ function ToastProvider({
318
322
  );
319
323
  }
320
324
  var Tabs = TabsPrimitive.Root;
321
- var TabsList = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
325
+ var TabsList = React15.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
322
326
  TabsPrimitive.List,
323
327
  {
324
328
  ref,
@@ -332,7 +336,7 @@ var TabsList = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__
332
336
  }
333
337
  ));
334
338
  TabsList.displayName = TabsPrimitive.List.displayName;
335
- var TabsTrigger = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
339
+ var TabsTrigger = React15.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
336
340
  TabsPrimitive.Trigger,
337
341
  {
338
342
  ref,
@@ -344,7 +348,7 @@ var TabsTrigger = React18.forwardRef(({ className, ...props }, ref) => /* @__PUR
344
348
  }
345
349
  ));
346
350
  TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
347
- var TabsContent = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
351
+ var TabsContent = React15.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
348
352
  TabsPrimitive.Content,
349
353
  {
350
354
  ref,
@@ -356,7 +360,7 @@ var TabsContent = React18.forwardRef(({ className, ...props }, ref) => /* @__PUR
356
360
  }
357
361
  ));
358
362
  TabsContent.displayName = TabsPrimitive.Content.displayName;
359
- var Separator2 = React18.forwardRef(
363
+ var Separator2 = React15.forwardRef(
360
364
  ({ className, orientation = "horizontal", decorative = true, ...props }, ref) => /* @__PURE__ */ jsx(
361
365
  SeparatorPrimitive.Root,
362
366
  {
@@ -407,7 +411,7 @@ function formatPhone(digits, fallback, countryCode) {
407
411
  const tail = rest.length === 9 ? rest.slice(5) : rest.slice(4);
408
412
  return `+55 (${ddd}) ${head}-${tail}`;
409
413
  }
410
- var PhoneLink = React18.forwardRef(
414
+ var PhoneLink = React15.forwardRef(
411
415
  ({ phone, message, countryCode, raw, className, children, ...props }, ref) => {
412
416
  const { e164, display } = normalizePhone(phone, countryCode);
413
417
  const label = children ?? (raw ? phone ?? "" : display);
@@ -467,235 +471,6 @@ function Breadcrumb({ parent, current, onBack }) {
467
471
  ] })
468
472
  ] });
469
473
  }
470
- var TooltipProvider = TooltipPrimitive.Provider;
471
- var Tooltip = TooltipPrimitive.Root;
472
- var TooltipTrigger = TooltipPrimitive.Trigger;
473
- var TooltipContent = React18.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(
474
- TooltipPrimitive.Content,
475
- {
476
- ref,
477
- sideOffset,
478
- className: cn(
479
- "fayz-glass-surface z-[120] overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-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",
480
- className
481
- ),
482
- ...props
483
- }
484
- ));
485
- TooltipContent.displayName = TooltipPrimitive.Content.displayName;
486
- var Hint = React18.forwardRef(function Hint2({ label, children, side = "top", delayDuration = 0, ...rest }, ref) {
487
- if (!label) return React18.cloneElement(children, { ...rest, ref });
488
- return /* @__PURE__ */ jsx(TooltipPrimitive.Provider, { delayDuration, children: /* @__PURE__ */ jsxs(Tooltip, { children: [
489
- /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, ...rest, ref, children }),
490
- /* @__PURE__ */ jsx(TooltipContent, { side, className: "px-2 py-1 text-xs font-medium", children: label })
491
- ] }) });
492
- });
493
- function iconOf(action, className) {
494
- const Icon2 = action.icon;
495
- return Icon2 ? /* @__PURE__ */ jsx(Icon2, { className }) : null;
496
- }
497
- function PageActionBar({ actions, className }) {
498
- const wide = useIsWide();
499
- const visible = actions.filter((a) => !a.hidden);
500
- if (visible.length === 0) return null;
501
- if (!wide) {
502
- const usable = visible.filter((a) => !a.desktopOnly);
503
- return usable.length > 0 ? /* @__PURE__ */ jsx(PageActionFab, { actions: usable }) : null;
504
- }
505
- let seenPrimary = false;
506
- const primary = [];
507
- const secondary = [];
508
- const utility = [];
509
- const danger = [];
510
- for (const a of visible) {
511
- const intent = a.intent ?? "secondary";
512
- if (intent === "primary" && !seenPrimary) {
513
- seenPrimary = true;
514
- primary.push(a);
515
- continue;
516
- }
517
- if (intent === "danger") {
518
- danger.push(a);
519
- continue;
520
- }
521
- if (intent === "utility") {
522
- utility.push(a);
523
- continue;
524
- }
525
- secondary.push(a);
526
- }
527
- const head = primary[0];
528
- const menu = [...secondary, ...danger];
529
- return /* @__PURE__ */ jsxs("div", { className: cn("flex shrink-0 items-center gap-2", className), children: [
530
- utility.map((a) => (
531
- // Um botão só de ícone não diz o que faz. `title=` parecia resolver e
532
- // não resolve: espera ~1s que ninguém controla, sai na pintura do
533
- // sistema operacional, nunca aparece no toque e vários leitores de tela
534
- // pulam. Hint é o tooltip do design system, e o texto é ANUNCIADO.
535
- /* @__PURE__ */ jsx(Hint, { label: a.label, children: /* @__PURE__ */ jsx(
536
- Button,
537
- {
538
- variant: "outline",
539
- size: "icon",
540
- onClick: () => void a.onSelect(),
541
- disabled: a.disabled,
542
- "aria-label": a.label,
543
- "data-testid": a.testId,
544
- "data-tour": `action.${a.id}`,
545
- children: iconOf(a, "h-4 w-4")
546
- }
547
- ) }, a.id)
548
- )),
549
- head && menu.length === 0 && /* @__PURE__ */ jsxs(Button, { onClick: () => void head.onSelect(), disabled: head.disabled, "data-testid": head.testId, "data-tour": `action.${head.id}`, children: [
550
- iconOf(head, "mr-1.5 h-4 w-4"),
551
- head.label
552
- ] }),
553
- head && menu.length > 0 && /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
554
- /* @__PURE__ */ jsxs(Button, { className: "rounded-r-none", onClick: () => void head.onSelect(), disabled: head.disabled, "data-testid": head.testId, "data-tour": `action.${head.id}`, children: [
555
- iconOf(head, "mr-1.5 h-4 w-4"),
556
- head.label
557
- ] }),
558
- /* @__PURE__ */ jsxs(Dropdown, { children: [
559
- /* @__PURE__ */ jsx(DropdownTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Hint, { label: `${head.label}\u2026`, children: /* @__PURE__ */ jsx(
560
- Button,
561
- {
562
- className: "-ml-px rounded-l-none px-2",
563
- "aria-label": `${head.label}\u2026`,
564
- "data-tour": menu.map((a) => `action.${a.id}`).join(" "),
565
- children: /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4" })
566
- }
567
- ) }) }),
568
- /* @__PURE__ */ jsx(DropdownContent, { align: "end", className: "w-56", children: /* @__PURE__ */ jsx(ActionItems, { actions: menu }) })
569
- ] })
570
- ] }),
571
- !head && menu.length > 0 && /* @__PURE__ */ jsxs(Dropdown, { children: [
572
- /* @__PURE__ */ jsx(DropdownTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Hint, { label: "A\xE7\xF5es", children: /* @__PURE__ */ jsx(Button, { variant: "outline", size: "icon", "aria-label": "A\xE7\xF5es", children: /* @__PURE__ */ jsx(MoreHorizontal, { className: "h-4 w-4" }) }) }) }),
573
- /* @__PURE__ */ jsx(DropdownContent, { align: "end", className: "w-56", children: /* @__PURE__ */ jsx(ActionItems, { actions: menu }) })
574
- ] })
575
- ] });
576
- }
577
- function ActionItems({ actions, stagger }) {
578
- const out = [];
579
- actions.forEach((a, i) => {
580
- const isDanger = a.intent === "danger";
581
- const prevSafe = i > 0 && actions[i - 1].intent !== "danger";
582
- if (isDanger && prevSafe) out.push(/* @__PURE__ */ jsx(DropdownSeparator, {}, `${a.id}-sep`));
583
- out.push(
584
- /* @__PURE__ */ jsxs(
585
- DropdownItem,
586
- {
587
- disabled: a.disabled,
588
- onSelect: () => void a.onSelect(),
589
- "data-testid": a.testId,
590
- style: stagger ? { ["--i"]: i } : void 0,
591
- className: cn("gap-2", stagger && "fz-fab-item", isDanger && "text-destructive focus:text-destructive"),
592
- children: [
593
- iconOf(a, "h-4 w-4 shrink-0"),
594
- /* @__PURE__ */ jsxs("span", { className: "min-w-0", children: [
595
- /* @__PURE__ */ jsx("span", { className: "block truncate", children: a.label }),
596
- a.description && /* @__PURE__ */ jsx("span", { className: "block truncate text-xs text-muted-foreground", children: a.description })
597
- ] })
598
- ]
599
- },
600
- a.id
601
- )
602
- );
603
- });
604
- return /* @__PURE__ */ jsx(Fragment, { children: out });
605
- }
606
- function PageActionFab({ actions }) {
607
- const byIntent = (i) => actions.filter((a) => (a.intent ?? "secondary") === i);
608
- const utility = byIntent("utility");
609
- const main = [...byIntent("primary"), ...byIntent("secondary"), ...byIntent("danger")];
610
- if (main.length === 0) return /* @__PURE__ */ jsx(FabButton, { actions: utility, tone: "neutral" });
611
- const isCreate = main.every((a) => a.creates ?? a.icon === Plus);
612
- return /* @__PURE__ */ jsxs(Fragment, { children: [
613
- utility.length > 0 && /* @__PURE__ */ jsx(FabButton, { actions: utility, tone: "neutral", mini: true }),
614
- /* @__PURE__ */ jsx(FabButton, { actions: main, tone: isCreate ? "primary" : "neutral" })
615
- ] });
616
- }
617
- function useScrim(open) {
618
- const [mounted, setMounted] = React18.useState(open);
619
- const [visible, setVisible] = React18.useState(open);
620
- React18.useEffect(() => {
621
- if (open) {
622
- setMounted(true);
623
- const frame = requestAnimationFrame(() => setVisible(true));
624
- return () => cancelAnimationFrame(frame);
625
- }
626
- setVisible(false);
627
- const timer = window.setTimeout(() => setMounted(false), SCRIM_MS);
628
- return () => window.clearTimeout(timer);
629
- }, [open]);
630
- return { mounted, visible };
631
- }
632
- var SCRIM_MS = 200;
633
- function FabButton({ actions, tone, mini }) {
634
- const [open, setOpen] = React18.useState(false);
635
- const scrim = useScrim(open);
636
- if (actions.length === 0) return null;
637
- const isCreate = tone === "primary";
638
- const FabIcon = isCreate ? Plus : MoreVertical;
639
- const style = {
640
- bottom: mini ? "calc(var(--fz-bottom-bar, 0px) + 4.75rem)" : "calc(var(--fz-bottom-bar, 0px) + 1rem)"
641
- };
642
- const shell = cn(
643
- "fz-tap fixed z-40 flex items-center justify-center rounded-full",
644
- "transition-transform active:scale-95 md:hidden",
645
- // Centred on the main circle's column, so the two read as one stack.
646
- mini ? "right-5 h-12 w-12" : "right-4 h-14 w-14",
647
- isCreate ? "bg-primary text-primary-foreground shadow-lg shadow-primary/30 ring-4 ring-background" : "bg-card text-foreground shadow-lg ring-1 ring-border"
648
- );
649
- if (actions.length === 1) {
650
- const only = actions[0];
651
- const Icon2 = only.icon ?? FabIcon;
652
- return /* @__PURE__ */ jsx(
653
- "button",
654
- {
655
- type: "button",
656
- style,
657
- className: shell,
658
- onClick: () => void only.onSelect(),
659
- disabled: only.disabled,
660
- "aria-label": only.label,
661
- "data-testid": only.testId,
662
- children: /* @__PURE__ */ jsx(Icon2, { className: mini ? "h-5 w-5" : "h-6 w-6" })
663
- }
664
- );
665
- }
666
- return /* @__PURE__ */ jsxs(Dropdown, { open, onOpenChange: setOpen, children: [
667
- scrim.mounted && typeof document !== "undefined" && createPortal(
668
- /* @__PURE__ */ jsx(
669
- "div",
670
- {
671
- "aria-hidden": true,
672
- onClick: () => setOpen(false),
673
- className: cn(
674
- "fixed inset-0 z-[100] bg-foreground/40 transition-opacity duration-200 md:hidden",
675
- "motion-reduce:transition-none",
676
- scrim.visible ? "opacity-100" : "opacity-0"
677
- )
678
- }
679
- ),
680
- document.body
681
- ),
682
- /* @__PURE__ */ jsx(DropdownTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
683
- "button",
684
- {
685
- type: "button",
686
- style,
687
- className: cn(shell, open && "z-[105]", isCreate && "fz-fab-trigger"),
688
- "aria-label": actionsMenuLabel,
689
- children: /* @__PURE__ */ jsx(FabIcon, { className: mini ? "h-5 w-5" : "h-6 w-6" })
690
- }
691
- ) }),
692
- /* @__PURE__ */ jsx(DropdownContent, { side: "top", align: "end", sideOffset: 12, className: "fz-fab-menu w-60 md:hidden", children: /* @__PURE__ */ jsx(ActionItems, { actions, stagger: true }) })
693
- ] });
694
- }
695
- var actionsMenuLabel = "A\xE7\xF5es";
696
- function setActionsMenuLabel(label) {
697
- actionsMenuLabel = label;
698
- }
699
474
  var INLINE_LIMIT = 2;
700
475
  function RowActions({
701
476
  actions,
@@ -744,7 +519,7 @@ function RowActions({
744
519
  const Icon2 = a.icon;
745
520
  const isDanger = a.intent === "danger";
746
521
  const prevSafe = i > 0 && overflow[i - 1].intent !== "danger";
747
- return /* @__PURE__ */ jsxs(React18.Fragment, { children: [
522
+ return /* @__PURE__ */ jsxs(React15.Fragment, { children: [
748
523
  isDanger && prevSafe && /* @__PURE__ */ jsx(DropdownSeparator, {}),
749
524
  /* @__PURE__ */ jsxs(
750
525
  DropdownItem,
@@ -789,6 +564,9 @@ function ChevronPager({ page, pageSize, total, onPageChange, noun }) {
789
564
  const from = total === 0 ? 0 : (page - 1) * pageSize + 1;
790
565
  const to = Math.min(page * pageSize, total);
791
566
  const button = "flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground disabled:pointer-events-none disabled:opacity-40";
567
+ const JANELA = 5;
568
+ const inicio = Math.max(1, Math.min(page - Math.floor(JANELA / 2), pages - JANELA + 1));
569
+ const numeros = Array.from({ length: Math.min(JANELA, pages) }, (_, i) => inicio + i);
792
570
  return /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2 border-t border-border px-3 py-2", children: [
793
571
  /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground", children: [
794
572
  from.toLocaleString(),
@@ -799,6 +577,17 @@ function ChevronPager({ page, pageSize, total, onPageChange, noun }) {
799
577
  noun ? ` ${noun}` : ""
800
578
  ] }),
801
579
  pages > 1 && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
580
+ pages > JANELA && /* @__PURE__ */ jsx(
581
+ "button",
582
+ {
583
+ type: "button",
584
+ "aria-label": "Primeira p\xE1gina",
585
+ className: button,
586
+ disabled: page <= 1,
587
+ onClick: () => onPageChange(1),
588
+ children: /* @__PURE__ */ jsx(ChevronsLeft, { className: "h-4 w-4" })
589
+ }
590
+ ),
802
591
  /* @__PURE__ */ jsx(
803
592
  "button",
804
593
  {
@@ -810,11 +599,18 @@ function ChevronPager({ page, pageSize, total, onPageChange, noun }) {
810
599
  children: /* @__PURE__ */ jsx(ChevronLeft, { className: "h-4 w-4" })
811
600
  }
812
601
  ),
813
- /* @__PURE__ */ jsxs("span", { className: "px-1 text-xs tabular-nums text-muted-foreground", children: [
814
- page.toLocaleString(),
815
- " / ",
816
- pages.toLocaleString()
817
- ] }),
602
+ numeros.map((n) => /* @__PURE__ */ jsx(
603
+ "button",
604
+ {
605
+ type: "button",
606
+ "aria-label": `P\xE1gina ${n}`,
607
+ "aria-current": n === page ? "page" : void 0,
608
+ onClick: () => onPageChange(n),
609
+ className: n === page ? "flex h-7 min-w-7 items-center justify-center rounded-md bg-primary px-1.5 text-xs font-medium tabular-nums text-primary-foreground" : "flex h-7 min-w-7 items-center justify-center rounded-md px-1.5 text-xs tabular-nums text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
610
+ children: n.toLocaleString()
611
+ },
612
+ n
613
+ )),
818
614
  /* @__PURE__ */ jsx(
819
615
  "button",
820
616
  {
@@ -825,6 +621,17 @@ function ChevronPager({ page, pageSize, total, onPageChange, noun }) {
825
621
  onClick: () => onPageChange(page + 1),
826
622
  children: /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4" })
827
623
  }
624
+ ),
625
+ pages > JANELA && /* @__PURE__ */ jsx(
626
+ "button",
627
+ {
628
+ type: "button",
629
+ "aria-label": "\xDAltima p\xE1gina",
630
+ className: button,
631
+ disabled: page >= pages,
632
+ onClick: () => onPageChange(pages),
633
+ children: /* @__PURE__ */ jsx(ChevronsRight, { className: "h-4 w-4" })
634
+ }
828
635
  )
829
636
  ] })
830
637
  ] });
@@ -963,8 +770,8 @@ var ICON_CLASSES = {
963
770
  lg: "h-5 w-5"
964
771
  };
965
772
  function Thumbnail({ src, alt = "", size = "md", icon: Icon2 = ImageIcon, className }) {
966
- const [failed, setFailed] = React18.useState(false);
967
- React18.useEffect(() => {
773
+ const [failed, setFailed] = React15.useState(false);
774
+ React15.useEffect(() => {
968
775
  setFailed(false);
969
776
  }, [src]);
970
777
  const base = cn("shrink-0 overflow-hidden", SIZE_CLASSES[size], className);
@@ -991,9 +798,9 @@ function Thumbnail({ src, alt = "", size = "md", icon: Icon2 = ImageIcon, classN
991
798
  }
992
799
  Thumbnail.displayName = "Thumbnail";
993
800
  function RefreshButton({ onRefresh, fromCache, label, labelCached, className, ...rest }) {
994
- const [phase, setPhase] = React18.useState("idle");
995
- const alive = React18.useRef(true);
996
- React18.useEffect(() => () => {
801
+ const [phase, setPhase] = React15.useState("idle");
802
+ const alive = React15.useRef(true);
803
+ React15.useEffect(() => () => {
997
804
  alive.current = false;
998
805
  }, []);
999
806
  const title = fromCache ? labelCached ?? label : label;
@@ -1211,27 +1018,27 @@ function useRowSelection({
1211
1018
  getRowId,
1212
1019
  enabled = true
1213
1020
  }) {
1214
- const identify = React18.useCallback(
1021
+ const identify = React15.useCallback(
1215
1022
  (row) => getRowId ? getRowId(row) : String(row?.id ?? ""),
1216
1023
  [getRowId]
1217
1024
  );
1218
- const visible = React18.useMemo(() => rows ?? [], [rows]);
1219
- const [rawSelection, setRawSelection] = React18.useState([]);
1220
- const visibleIds = React18.useMemo(() => new Set(visible.map(identify)), [visible, identify]);
1221
- const selectedIds = React18.useMemo(
1025
+ const visible = React15.useMemo(() => rows ?? [], [rows]);
1026
+ const [rawSelection, setRawSelection] = React15.useState([]);
1027
+ const visibleIds = React15.useMemo(() => new Set(visible.map(identify)), [visible, identify]);
1028
+ const selectedIds = React15.useMemo(
1222
1029
  () => rawSelection.filter((id) => visibleIds.has(id)),
1223
1030
  [rawSelection, visibleIds]
1224
1031
  );
1225
- const selectedRows = React18.useMemo(() => {
1032
+ const selectedRows = React15.useMemo(() => {
1226
1033
  const picked = new Set(selectedIds);
1227
1034
  return visible.filter((row) => picked.has(identify(row)));
1228
1035
  }, [visible, selectedIds, identify]);
1229
- const clear = React18.useCallback(() => setRawSelection([]), []);
1230
- const selectAll = React18.useCallback(
1036
+ const clear = React15.useCallback(() => setRawSelection([]), []);
1037
+ const selectAll = React15.useCallback(
1231
1038
  () => setRawSelection(visible.map(identify)),
1232
1039
  [visible, identify]
1233
1040
  );
1234
- const barActions = React18.useMemo(
1041
+ const barActions = React15.useMemo(
1235
1042
  () => (actions ?? []).map((action) => ({
1236
1043
  id: action.id,
1237
1044
  label: action.label,
@@ -1291,14 +1098,65 @@ function FilterChip({ allLabel, options, value, onChange, label, icon: Icon2, cl
1291
1098
  ] });
1292
1099
  }
1293
1100
  var ICON_BTN = "fz-tap text-muted-foreground";
1101
+ function ListFilters({ tagFilter, filters, advanced, label, count, wideCount }) {
1102
+ const wide = useIsWide();
1103
+ const [open, setOpen] = useState(false);
1104
+ if (!tagFilter && !filters && !advanced) return null;
1105
+ const inPanel = wide ? advanced : /* @__PURE__ */ jsxs(Fragment, { children: [
1106
+ tagFilter,
1107
+ filters,
1108
+ advanced
1109
+ ] });
1110
+ const badge = wide ? wideCount : count;
1111
+ const trigger = wide && !advanced ? null : /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
1112
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
1113
+ "button",
1114
+ {
1115
+ type: "button",
1116
+ "aria-label": label,
1117
+ className: cn(
1118
+ "inline-flex shrink-0 items-center gap-1.5 rounded-full border px-2.5 py-1 text-xs font-medium transition-colors",
1119
+ badge > 0 ? "border-primary/30 bg-primary/10 text-primary hover:bg-primary/15" : "border-transparent bg-muted/70 text-muted-foreground hover:bg-muted hover:text-foreground"
1120
+ ),
1121
+ children: [
1122
+ /* @__PURE__ */ jsx(SlidersHorizontal, { className: "h-3 w-3 shrink-0 opacity-70" }),
1123
+ /* @__PURE__ */ jsx("span", { className: "hidden sm:inline", children: label }),
1124
+ badge > 0 && /* @__PURE__ */ jsx("span", { className: "rounded-full bg-primary/20 px-1.5 text-[10px] font-semibold tabular-nums", children: badge })
1125
+ ]
1126
+ }
1127
+ ) }),
1128
+ /* @__PURE__ */ jsx(
1129
+ PopoverContent,
1130
+ {
1131
+ align: "end",
1132
+ sideOffset: 8,
1133
+ className: "flex max-h-[70vh] w-[min(18rem,calc(100vw-1.5rem))] flex-col gap-3 overflow-y-auto p-3 [&_button]:w-full [&_button]:justify-between",
1134
+ children: inPanel
1135
+ }
1136
+ )
1137
+ ] });
1138
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1139
+ wide && tagFilter,
1140
+ wide && filters,
1141
+ trigger
1142
+ ] });
1143
+ }
1144
+ var PAGER_BTN = "flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground disabled:pointer-events-none disabled:opacity-40";
1294
1145
  function ListView({
1295
1146
  columns,
1296
1147
  data,
1297
1148
  loading = false,
1298
1149
  searchPlaceholder = "Search...",
1150
+ filtersLabel = "Filtros",
1151
+ advancedFilters,
1152
+ activeFilterCount = 0,
1153
+ advancedFilterCount,
1154
+ onClearFilters,
1155
+ clearFiltersLabel = "Clear",
1299
1156
  search: controlledSearch,
1300
1157
  onSearchChange,
1301
1158
  searchDebounce = 300,
1159
+ searchOwnRow,
1302
1160
  tags,
1303
1161
  allTagLabel = "All",
1304
1162
  tagsLabel,
@@ -1316,6 +1174,12 @@ function ListView({
1316
1174
  total,
1317
1175
  page = 1,
1318
1176
  pageSize = 25,
1177
+ rangeOfLabel = "of",
1178
+ firstPageLabel = "First page",
1179
+ prevPageLabel = "Previous page",
1180
+ nextPageLabel = "Next page",
1181
+ lastPageLabel = "Last page",
1182
+ pageLabel = "Page",
1319
1183
  onPageChange,
1320
1184
  toolbar,
1321
1185
  filters,
@@ -1343,6 +1207,9 @@ function ListView({
1343
1207
  }, [onSearchChange, searchDebounce]);
1344
1208
  const totalItems = total ?? data.length;
1345
1209
  const totalPages = Math.max(1, Math.ceil(totalItems / pageSize));
1210
+ const PAGE_WINDOW = 5;
1211
+ const windowStart = Math.max(1, Math.min(page - Math.floor(PAGE_WINDOW / 2), totalPages - PAGE_WINDOW + 1));
1212
+ const pageWindow = Array.from({ length: Math.min(PAGE_WINDOW, totalPages) }, (_, i) => windowStart + i);
1346
1213
  const showPagination = onPageChange && totalItems > pageSize;
1347
1214
  const showSearch = !!onSearchChange;
1348
1215
  const showTags = tags && tags.length > 0 && onTagChange;
@@ -1391,7 +1258,11 @@ function ListView({
1391
1258
  actions: selection.barActions
1392
1259
  }
1393
1260
  ) : /* @__PURE__ */ jsxs(Fragment, { children: [
1394
- showSearch && /* @__PURE__ */ jsxs("div", { className: "relative min-w-0 flex-1", children: [
1261
+ showSearch && // `basis-full` e não uma segunda `div`: o contentor é
1262
+ // `flex-wrap`, então uma primeira cria que ocupa a linha
1263
+ // inteira empurra o resto para baixo sozinha. Sem filtros,
1264
+ // a busca volta a partilhar a linha com atualizar/exportar.
1265
+ /* @__PURE__ */ jsxs("div", { className: cn("relative min-w-0 flex-1", searchOwnRow && "basis-full"), children: [
1395
1266
  /* @__PURE__ */ jsx(Search, { className: "pointer-events-none absolute left-2.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground" }),
1396
1267
  /* @__PURE__ */ jsx(
1397
1268
  "input",
@@ -1404,9 +1275,34 @@ function ListView({
1404
1275
  }
1405
1276
  )
1406
1277
  ] }),
1407
- (tagFilter || filters || onRefresh || onExport) && /* @__PURE__ */ jsxs("div", { className: "ml-auto flex flex-wrap items-center justify-end gap-2", children: [
1408
- tagFilter,
1409
- filters,
1278
+ (tagFilter || filters || advancedFilters || onRefresh || onExport) && // `flex-nowrap`: envolvendo, cada filtro a mais abria uma
1279
+ // linha nova sob a busca, e quatro deles gastavam três linhas
1280
+ // antes da primeira linha da tabela. No celular eles se
1281
+ // recolhem num gatilho (abaixo) e a linha volta a ser uma.
1282
+ /* @__PURE__ */ jsxs("div", { className: "ml-auto flex flex-nowrap items-center justify-end gap-2 md:flex-wrap", children: [
1283
+ /* @__PURE__ */ jsx(
1284
+ ListFilters,
1285
+ {
1286
+ tagFilter,
1287
+ filters,
1288
+ advanced: advancedFilters,
1289
+ label: filtersLabel,
1290
+ count: activeFilterCount,
1291
+ wideCount: advancedFilterCount ?? activeFilterCount
1292
+ }
1293
+ ),
1294
+ onClearFilters && activeFilterCount > 0 && /* @__PURE__ */ jsxs(
1295
+ "button",
1296
+ {
1297
+ type: "button",
1298
+ onClick: onClearFilters,
1299
+ className: "inline-flex shrink-0 items-center gap-1 rounded-full px-2 py-1 text-xs font-medium text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
1300
+ children: [
1301
+ /* @__PURE__ */ jsx(X, { className: "h-3 w-3 shrink-0" }),
1302
+ clearFiltersLabel
1303
+ ]
1304
+ }
1305
+ ),
1410
1306
  onRefresh && /* @__PURE__ */ jsx(Hint, { label: refreshLabel, children: /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon", "aria-label": refreshLabel, onClick: onRefresh, className: ICON_BTN, children: /* @__PURE__ */ jsx(RefreshCw, { className: "h-4 w-4" }) }) }),
1411
1307
  onExport && /* @__PURE__ */ jsx(Hint, { label: exportLabel, children: /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon", "aria-label": exportLabel, onClick: onExport, className: ICON_BTN, children: /* @__PURE__ */ jsx(Download, { className: "h-4 w-4" }) }) })
1412
1308
  ] })
@@ -1426,40 +1322,75 @@ function ListView({
1426
1322
  onSelectedIdsChange: selection.setSelectedIds,
1427
1323
  getRowId
1428
1324
  }
1429
- )
1430
- ] }),
1431
- showPagination && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-1", children: [
1432
- /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground", children: [
1433
- (page - 1) * pageSize + 1,
1434
- "\u2013",
1435
- Math.min(page * pageSize, totalItems),
1436
- " of ",
1437
- totalItems
1438
- ] }),
1439
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
1440
- /* @__PURE__ */ jsx(
1441
- "button",
1442
- {
1443
- onClick: () => onPageChange(page - 1),
1444
- disabled: page <= 1,
1445
- className: "flex h-7 w-7 items-center justify-center rounded-md border hover:bg-muted bg-card shadow-button active:shadow-button-inset transition-colors disabled:opacity-30 disabled:cursor-not-allowed",
1446
- children: /* @__PURE__ */ jsx(ChevronLeft, { className: "h-3.5 w-3.5" })
1447
- }
1448
- ),
1449
- /* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground px-2", children: [
1450
- page,
1451
- " / ",
1452
- totalPages
1325
+ ),
1326
+ showPagination && /* @__PURE__ */ jsxs("div", { className: "-mt-px flex min-h-9 flex-col items-center gap-2 rounded-b-card border-t border-border px-3 py-2 sm:grid sm:grid-cols-[1fr_auto_1fr] sm:gap-3", children: [
1327
+ /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground sm:justify-self-start", children: [
1328
+ (page - 1) * pageSize + 1,
1329
+ "\u2013",
1330
+ Math.min(page * pageSize, totalItems),
1331
+ " ",
1332
+ rangeOfLabel,
1333
+ " ",
1334
+ totalItems.toLocaleString()
1453
1335
  ] }),
1454
- /* @__PURE__ */ jsx(
1455
- "button",
1456
- {
1457
- onClick: () => onPageChange(page + 1),
1458
- disabled: page >= totalPages,
1459
- className: "flex h-7 w-7 items-center justify-center rounded-md border hover:bg-muted bg-card shadow-button active:shadow-button-inset transition-colors disabled:opacity-30 disabled:cursor-not-allowed",
1460
- children: /* @__PURE__ */ jsx(ChevronRight, { className: "h-3.5 w-3.5" })
1461
- }
1462
- )
1336
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
1337
+ totalPages > PAGE_WINDOW && /* @__PURE__ */ jsx(
1338
+ "button",
1339
+ {
1340
+ type: "button",
1341
+ onClick: () => onPageChange(1),
1342
+ disabled: page <= 1,
1343
+ "aria-label": firstPageLabel,
1344
+ className: PAGER_BTN,
1345
+ children: /* @__PURE__ */ jsx(ChevronsLeft, { className: "h-4 w-4" })
1346
+ }
1347
+ ),
1348
+ /* @__PURE__ */ jsx(
1349
+ "button",
1350
+ {
1351
+ type: "button",
1352
+ onClick: () => onPageChange(page - 1),
1353
+ disabled: page <= 1,
1354
+ "aria-label": prevPageLabel,
1355
+ className: PAGER_BTN,
1356
+ children: /* @__PURE__ */ jsx(ChevronLeft, { className: "h-4 w-4" })
1357
+ }
1358
+ ),
1359
+ pageWindow.map((n) => /* @__PURE__ */ jsx(
1360
+ "button",
1361
+ {
1362
+ type: "button",
1363
+ onClick: () => onPageChange(n),
1364
+ "aria-label": `${pageLabel} ${n}`,
1365
+ "aria-current": n === page ? "page" : void 0,
1366
+ className: n === page ? "flex h-7 min-w-7 items-center justify-center rounded-md bg-primary px-1.5 text-xs font-medium tabular-nums text-primary-foreground" : "flex h-7 min-w-7 items-center justify-center rounded-md px-1.5 text-xs tabular-nums text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
1367
+ children: n
1368
+ },
1369
+ n
1370
+ )),
1371
+ /* @__PURE__ */ jsx(
1372
+ "button",
1373
+ {
1374
+ type: "button",
1375
+ onClick: () => onPageChange(page + 1),
1376
+ disabled: page >= totalPages,
1377
+ "aria-label": nextPageLabel,
1378
+ className: PAGER_BTN,
1379
+ children: /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4" })
1380
+ }
1381
+ ),
1382
+ totalPages > PAGE_WINDOW && /* @__PURE__ */ jsx(
1383
+ "button",
1384
+ {
1385
+ type: "button",
1386
+ onClick: () => onPageChange(totalPages),
1387
+ disabled: page >= totalPages,
1388
+ "aria-label": lastPageLabel,
1389
+ className: PAGER_BTN,
1390
+ children: /* @__PURE__ */ jsx(ChevronsRight, { className: "h-4 w-4" })
1391
+ }
1392
+ )
1393
+ ] })
1463
1394
  ] })
1464
1395
  ] })
1465
1396
  ] });
@@ -1667,7 +1598,7 @@ function toLocalISODate(d) {
1667
1598
  }
1668
1599
  function MiniCalendar({ selectedDate, onDateSelect, onMonthChange, markers }) {
1669
1600
  const locale = getCurrentLocale();
1670
- const [viewMonth, setViewMonth] = React18__default.useState(() => new Date(selectedDate.getFullYear(), selectedDate.getMonth(), 1));
1601
+ const [viewMonth, setViewMonth] = React15__default.useState(() => new Date(selectedDate.getFullYear(), selectedDate.getMonth(), 1));
1671
1602
  const monthLabel = viewMonth.toLocaleDateString(toDateLocale2(locale), { month: "long", year: "numeric" });
1672
1603
  const dayLabels = DAY_LABELS2[locale] ?? DAY_LABELS2.en;
1673
1604
  const weeks = useMemo(() => {
@@ -1746,7 +1677,7 @@ function FilterSection({
1746
1677
  defaultOpen = true,
1747
1678
  children
1748
1679
  }) {
1749
- const [open, setOpen] = React18__default.useState(defaultOpen);
1680
+ const [open, setOpen] = React15__default.useState(defaultOpen);
1750
1681
  return /* @__PURE__ */ jsxs(Fragment, { children: [
1751
1682
  /* @__PURE__ */ jsxs(
1752
1683
  "button",
@@ -1819,7 +1750,7 @@ function FilterCheckList({
1819
1750
  }
1820
1751
  return /* @__PURE__ */ jsx("div", { className: className ? `${className} space-y-0.5` : "space-y-0.5", children: rows });
1821
1752
  }
1822
- var useIsomorphicLayoutEffect = typeof window !== "undefined" ? React18.useLayoutEffect : React18.useEffect;
1753
+ var useIsomorphicLayoutEffect = typeof window !== "undefined" ? React15.useLayoutEffect : React15.useEffect;
1823
1754
  function SearchSelect({
1824
1755
  value,
1825
1756
  displayValue,
@@ -1843,18 +1774,18 @@ function SearchSelect({
1843
1774
  "data-tour": dataTour
1844
1775
  }) {
1845
1776
  const canCreate = !!onCreate && allowCreate !== false;
1846
- const [open, setOpen] = React18.useState(false);
1847
- const [query, setQuery] = React18.useState("");
1848
- const [results, setResults] = React18.useState([]);
1849
- const [loading, setLoading] = React18.useState(false);
1850
- const [creating, setCreating] = React18.useState(false);
1851
- const [selectedLabel, setSelectedLabel] = React18.useState(displayValue ?? "");
1852
- const containerRef = React18.useRef(null);
1853
- const inputRef = React18.useRef(null);
1854
- const timerRef = React18.useRef();
1855
- const [rect, setRect] = React18.useState(null);
1856
- const dropdownRef = React18.useRef(null);
1857
- React18.useEffect(() => {
1777
+ const [open, setOpen] = React15.useState(false);
1778
+ const [query, setQuery] = React15.useState("");
1779
+ const [results, setResults] = React15.useState([]);
1780
+ const [loading, setLoading] = React15.useState(false);
1781
+ const [creating, setCreating] = React15.useState(false);
1782
+ const [selectedLabel, setSelectedLabel] = React15.useState(displayValue ?? "");
1783
+ const containerRef = React15.useRef(null);
1784
+ const inputRef = React15.useRef(null);
1785
+ const timerRef = React15.useRef();
1786
+ const [rect, setRect] = React15.useState(null);
1787
+ const dropdownRef = React15.useRef(null);
1788
+ React15.useEffect(() => {
1858
1789
  function handler(e) {
1859
1790
  const target = e.target;
1860
1791
  if (containerRef.current?.contains(target)) return;
@@ -1864,10 +1795,10 @@ function SearchSelect({
1864
1795
  document.addEventListener("mousedown", handler);
1865
1796
  return () => document.removeEventListener("mousedown", handler);
1866
1797
  }, []);
1867
- React18.useEffect(() => {
1798
+ React15.useEffect(() => {
1868
1799
  if (displayValue !== void 0) setSelectedLabel(displayValue);
1869
1800
  }, [displayValue]);
1870
- React18.useEffect(() => {
1801
+ React15.useEffect(() => {
1871
1802
  if (open && loadOnOpen && query.length === 0 && results.length === 0 && !loading) {
1872
1803
  setLoading(true);
1873
1804
  Promise.resolve(onSearch("")).then(setResults).catch(() => setResults([])).finally(() => setLoading(false));
@@ -1925,7 +1856,7 @@ function SearchSelect({
1925
1856
  setResults([]);
1926
1857
  setTimeout(() => inputRef.current?.focus(), 0);
1927
1858
  }
1928
- const groups = React18.useMemo(() => {
1859
+ const groups = React15.useMemo(() => {
1929
1860
  const map = /* @__PURE__ */ new Map();
1930
1861
  for (const opt of results) {
1931
1862
  const group = opt.group ?? "";
@@ -2020,7 +1951,7 @@ function SearchSelect({
2020
1951
  /* @__PURE__ */ jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin" }),
2021
1952
  " ",
2022
1953
  searchingLabel
2023
- ] }) : results.length === 0 ? /* @__PURE__ */ jsx("div", { className: "px-4 py-4 text-center", children: /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: noResultsLabel ?? (query ? `No results for "${query}"` : "No results") }) }) : /* @__PURE__ */ jsx("div", { className: "max-h-64 overflow-auto py-1", children: [...groups.entries()].map(([group, options]) => /* @__PURE__ */ jsxs(React18.Fragment, { children: [
1954
+ ] }) : results.length === 0 ? /* @__PURE__ */ jsx("div", { className: "px-4 py-4 text-center", children: /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: noResultsLabel ?? (query ? `No results for "${query}"` : "No results") }) }) : /* @__PURE__ */ jsx("div", { className: "max-h-64 overflow-auto py-1", children: [...groups.entries()].map(([group, options]) => /* @__PURE__ */ jsxs(React15.Fragment, { children: [
2024
1955
  group && /* @__PURE__ */ jsx("div", { className: "sticky top-0 bg-muted/50 px-3 py-1 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground", children: group }),
2025
1956
  options.map((opt) => /* @__PURE__ */ jsx(
2026
1957
  "button",
@@ -2082,9 +2013,9 @@ function CurrencyInput({
2082
2013
  className,
2083
2014
  disabled
2084
2015
  }) {
2085
- const inputRef = React18.useRef(null);
2086
- const [focused, setFocused] = React18.useState(false);
2087
- const format = React18.useCallback((v) => {
2016
+ const inputRef = React15.useRef(null);
2017
+ const [focused, setFocused] = React15.useState(false);
2018
+ const format = React15.useCallback((v) => {
2088
2019
  return new Intl.NumberFormat(locale, {
2089
2020
  minimumFractionDigits: 2,
2090
2021
  maximumFractionDigits: 2
@@ -2154,24 +2085,125 @@ function CurrencyInput({
2154
2085
  )
2155
2086
  ] });
2156
2087
  }
2157
- var Popover = PopoverPrimitive.Root;
2158
- var PopoverTrigger = PopoverPrimitive.Trigger;
2159
- var PopoverAnchor = PopoverPrimitive.Anchor;
2160
- var PopoverContent = React18.forwardRef(({ className, align = "start", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx(
2161
- PopoverPrimitive.Content,
2162
- {
2163
- ref,
2164
- align,
2165
- sideOffset,
2166
- className: cn(
2167
- "fayz-glass-surface z-[110] w-72 rounded-xl border bg-popover p-0 text-popover-foreground shadow-lg outline-none",
2168
- "data-[state=open]:animate-zoom-in data-[state=closed]:animate-zoom-out",
2169
- className
2170
- ),
2171
- ...props
2088
+ function formatRange(from, to, locale) {
2089
+ const parse = (s) => {
2090
+ const [y, m, d] = s.split("-").map(Number);
2091
+ return new Date(y, (m ?? 1) - 1, d ?? 1);
2092
+ };
2093
+ const day = (d) => String(d.getDate());
2094
+ const dayMonth = (d) => d.toLocaleDateString(locale, { day: "numeric", month: "short" }).replace(/\.$/, "");
2095
+ if (from && to) {
2096
+ const a = parse(from);
2097
+ const b = parse(to);
2098
+ if (a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth()) {
2099
+ return a.getDate() === b.getDate() ? dayMonth(a) : `${day(a)}\u2013${dayMonth(b)}`;
2100
+ }
2101
+ return `${dayMonth(a)} \u2013 ${dayMonth(b)}`;
2172
2102
  }
2173
- ) }));
2174
- PopoverContent.displayName = PopoverPrimitive.Content.displayName;
2103
+ return dayMonth(parse(from || to));
2104
+ }
2105
+ function DateRangeChip({
2106
+ from,
2107
+ to,
2108
+ onChange,
2109
+ presets = [],
2110
+ preset,
2111
+ onPresetChange,
2112
+ allLabel,
2113
+ labels,
2114
+ label,
2115
+ className
2116
+ }) {
2117
+ const [open, setOpen] = React15.useState(false);
2118
+ const active = !!(from || to);
2119
+ const locale = typeof navigator !== "undefined" ? navigator.language : "en";
2120
+ const presetLabel = presets.find((p) => p.value === preset)?.label;
2121
+ const text = !active ? allLabel : presetLabel ?? formatRange(from, to, locale);
2122
+ return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
2123
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
2124
+ "button",
2125
+ {
2126
+ type: "button",
2127
+ "aria-label": label,
2128
+ className: cn(
2129
+ "inline-flex shrink-0 items-center gap-1 rounded-full border px-2.5 py-1 text-xs font-medium transition-colors",
2130
+ active ? "border-primary/30 bg-primary/10 text-primary hover:bg-primary/15" : "border-transparent bg-muted/70 text-muted-foreground hover:bg-muted hover:text-foreground",
2131
+ className
2132
+ ),
2133
+ children: [
2134
+ /* @__PURE__ */ jsx(CalendarDays, { className: "h-3 w-3 shrink-0 opacity-70" }),
2135
+ /* @__PURE__ */ jsx("span", { className: "max-w-[12rem] truncate", children: text })
2136
+ ]
2137
+ }
2138
+ ) }),
2139
+ /* @__PURE__ */ jsxs(PopoverContent, { align: "start", sideOffset: 6, className: "w-60 p-1.5", children: [
2140
+ /* @__PURE__ */ jsxs(
2141
+ "button",
2142
+ {
2143
+ type: "button",
2144
+ onClick: () => {
2145
+ onPresetChange?.("all");
2146
+ onChange({ from: "", to: "" });
2147
+ setOpen(false);
2148
+ },
2149
+ className: "flex w-full items-center rounded-md px-2 py-1.5 text-sm transition-colors hover:bg-muted",
2150
+ children: [
2151
+ allLabel,
2152
+ !active && /* @__PURE__ */ jsx(Check, { className: "ml-auto h-3.5 w-3.5 shrink-0" })
2153
+ ]
2154
+ }
2155
+ ),
2156
+ presets.map((p) => /* @__PURE__ */ jsxs(
2157
+ "button",
2158
+ {
2159
+ type: "button",
2160
+ onClick: () => {
2161
+ onPresetChange?.(p.value);
2162
+ setOpen(false);
2163
+ },
2164
+ className: "flex w-full items-center rounded-md px-2 py-1.5 text-sm transition-colors hover:bg-muted",
2165
+ children: [
2166
+ p.label,
2167
+ active && preset === p.value && /* @__PURE__ */ jsx(Check, { className: "ml-auto h-3.5 w-3.5 shrink-0" })
2168
+ ]
2169
+ },
2170
+ p.value
2171
+ )),
2172
+ /* @__PURE__ */ jsxs("div", { className: "mt-1 space-y-1.5 border-t border-border px-2 pb-1 pt-2", children: [
2173
+ /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
2174
+ /* @__PURE__ */ jsx("span", { className: "w-8 shrink-0", children: labels?.from ?? "From" }),
2175
+ /* @__PURE__ */ jsx(
2176
+ DatePicker,
2177
+ {
2178
+ value: from,
2179
+ onChange: (next) => {
2180
+ onPresetChange?.("custom");
2181
+ onChange({ from: next, to });
2182
+ },
2183
+ variant: "toolbar",
2184
+ className: "min-w-0 flex-1"
2185
+ }
2186
+ )
2187
+ ] }),
2188
+ /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
2189
+ /* @__PURE__ */ jsx("span", { className: "w-8 shrink-0", children: labels?.to ?? "To" }),
2190
+ /* @__PURE__ */ jsx(
2191
+ DatePicker,
2192
+ {
2193
+ value: to,
2194
+ onChange: (next) => {
2195
+ onPresetChange?.("custom");
2196
+ onChange({ from, to: next });
2197
+ },
2198
+ variant: "toolbar",
2199
+ className: "min-w-0 flex-1"
2200
+ }
2201
+ )
2202
+ ] })
2203
+ ] })
2204
+ ] })
2205
+ ] });
2206
+ }
2175
2207
  function MultiSelect({
2176
2208
  options,
2177
2209
  value,
@@ -2181,11 +2213,13 @@ function MultiSelect({
2181
2213
  emptyLabel = "Nada encontrado",
2182
2214
  disabled,
2183
2215
  className,
2184
- searchThreshold = 8
2216
+ searchThreshold = 8,
2217
+ variant = "field",
2218
+ icon: Icon2
2185
2219
  }) {
2186
- const [query, setQuery] = React18.useState("");
2187
- const selected = React18.useMemo(() => new Set(value), [value]);
2188
- const filtered = React18.useMemo(() => {
2220
+ const [query, setQuery] = React15.useState("");
2221
+ const selected = React15.useMemo(() => new Set(value), [value]);
2222
+ const filtered = React15.useMemo(() => {
2189
2223
  const q = query.trim().toLowerCase();
2190
2224
  if (!q) return options;
2191
2225
  return options.filter((o) => o.label.toLowerCase().includes(q));
@@ -2200,15 +2234,22 @@ function MultiSelect({
2200
2234
  {
2201
2235
  type: "button",
2202
2236
  disabled,
2237
+ "aria-label": allLabel,
2203
2238
  className: cn(
2204
- "flex h-9 w-full items-center justify-between gap-2 rounded-input border border-input bg-card px-3 py-1.5 text-xs",
2205
- "shadow-[inset_0_1px_0_rgb(0_0_0_/0.06)] transition-colors hover:bg-muted/40",
2206
2239
  "disabled:cursor-not-allowed disabled:opacity-50",
2207
- value.length === 0 && "text-muted-foreground",
2240
+ variant === "chip" ? cn(
2241
+ "inline-flex shrink-0 items-center gap-1 rounded-full border px-2.5 py-1 text-xs font-medium transition-colors",
2242
+ value.length > 0 ? "border-primary/30 bg-primary/10 text-primary hover:bg-primary/15" : "border-transparent bg-muted/70 text-muted-foreground hover:bg-muted hover:text-foreground"
2243
+ ) : cn(
2244
+ "flex h-9 w-full items-center justify-between gap-2 rounded-input border border-input bg-card px-3 py-1.5 text-xs",
2245
+ "shadow-[inset_0_1px_0_rgb(0_0_0_/0.06)] transition-colors hover:bg-muted/40",
2246
+ value.length === 0 && "text-muted-foreground"
2247
+ ),
2208
2248
  className
2209
2249
  ),
2210
2250
  children: [
2211
- /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: label }),
2251
+ variant === "chip" && Icon2 && /* @__PURE__ */ jsx(Icon2, { className: "h-3 w-3 shrink-0 opacity-70" }),
2252
+ /* @__PURE__ */ jsx("span", { className: cn("min-w-0 truncate", variant === "chip" && "max-w-[12rem]"), children: label }),
2212
2253
  /* @__PURE__ */ jsxs("span", { className: "flex shrink-0 items-center gap-1", children: [
2213
2254
  value.length > 0 && // Limpar dentro do gatilho: a alternativa é desmarcar cinco itens
2214
2255
  // um a um para voltar a "todos", e é o caminho de volta mais
@@ -2228,43 +2269,64 @@ function MultiSelect({
2228
2269
  children: /* @__PURE__ */ jsx(X, { className: "h-3 w-3" })
2229
2270
  }
2230
2271
  ),
2231
- /* @__PURE__ */ jsx(ChevronDown, { className: "h-3.5 w-3.5 shrink-0 opacity-50" })
2272
+ /* @__PURE__ */ jsx(ChevronDown, { className: cn("shrink-0", variant === "chip" ? "h-3 w-3 opacity-60" : "h-3.5 w-3.5 opacity-50") })
2232
2273
  ] })
2233
2274
  ]
2234
2275
  }
2235
2276
  ) }),
2236
- /* @__PURE__ */ jsxs(DropdownContent, { align: "start", className: "w-[--radix-dropdown-menu-trigger-width] p-0", children: [
2237
- options.length >= searchThreshold && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 border-b px-2 py-1.5", children: [
2238
- /* @__PURE__ */ jsx(Search, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
2239
- /* @__PURE__ */ jsx(
2240
- "input",
2241
- {
2242
- value: query,
2243
- onChange: (e) => setQuery(e.target.value),
2244
- placeholder: searchPlaceholder,
2245
- onKeyDown: (e) => e.stopPropagation(),
2246
- className: "w-full bg-transparent text-xs outline-none placeholder:text-muted-foreground"
2247
- }
2248
- )
2249
- ] }),
2250
- /* @__PURE__ */ jsx("div", { className: "max-h-64 overflow-y-auto py-1", children: filtered.length === 0 ? /* @__PURE__ */ jsx("p", { className: "px-3 py-4 text-center text-xs text-muted-foreground", children: emptyLabel }) : filtered.map((o) => /* @__PURE__ */ jsxs(
2251
- "button",
2252
- {
2253
- type: "button",
2254
- onClick: (e) => {
2255
- e.preventDefault();
2256
- toggle(o.value);
2257
- },
2258
- className: "flex w-full items-center gap-2 px-3 py-1.5 text-left text-xs transition-colors hover:bg-muted",
2259
- children: [
2260
- /* @__PURE__ */ jsx(Checkbox, { checked: selected.has(o.value), onChange: () => toggle(o.value) }),
2261
- /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children: o.label }),
2262
- o.hint && /* @__PURE__ */ jsx("span", { className: "shrink-0 text-[10px] text-muted-foreground", children: o.hint })
2263
- ]
2264
- },
2265
- o.value
2266
- )) })
2267
- ] })
2277
+ /* @__PURE__ */ jsxs(
2278
+ DropdownContent,
2279
+ {
2280
+ align: "start",
2281
+ className: cn(
2282
+ "p-0",
2283
+ // Em `field` o painel casa com o campo, que é largo. Em `chip` a
2284
+ // largura do gatilho é a do rótulo — herdá-la daria uma lista de
2285
+ // dois dedos. Aqui ele ganha a sua própria medida de leitura.
2286
+ variant === "chip" ? "w-[min(16rem,calc(100vw-1.5rem))]" : "w-[--radix-dropdown-menu-trigger-width]"
2287
+ ),
2288
+ children: [
2289
+ options.length >= searchThreshold && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 border-b px-2 py-1.5", children: [
2290
+ /* @__PURE__ */ jsx(Search, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
2291
+ /* @__PURE__ */ jsx(
2292
+ "input",
2293
+ {
2294
+ value: query,
2295
+ onChange: (e) => setQuery(e.target.value),
2296
+ placeholder: searchPlaceholder,
2297
+ onKeyDown: (e) => e.stopPropagation(),
2298
+ className: "w-full bg-transparent text-xs outline-none placeholder:text-muted-foreground"
2299
+ }
2300
+ )
2301
+ ] }),
2302
+ /* @__PURE__ */ jsx("div", { className: "max-h-64 overflow-y-auto py-1", children: filtered.length === 0 ? /* @__PURE__ */ jsx("p", { className: "px-3 py-4 text-center text-xs text-muted-foreground", children: emptyLabel }) : filtered.map((o) => /* @__PURE__ */ jsxs(
2303
+ "button",
2304
+ {
2305
+ type: "button",
2306
+ onClick: (e) => {
2307
+ e.preventDefault();
2308
+ toggle(o.value);
2309
+ },
2310
+ className: "flex w-full items-center gap-2 px-3 py-1.5 text-left text-xs transition-colors hover:bg-muted",
2311
+ children: [
2312
+ /* @__PURE__ */ jsx(Checkbox, { checked: selected.has(o.value), onChange: () => toggle(o.value) }),
2313
+ o.color && /* @__PURE__ */ jsx(
2314
+ "span",
2315
+ {
2316
+ "aria-hidden": true,
2317
+ className: "h-2 w-2 shrink-0 rounded-full ring-1 ring-inset ring-black/10",
2318
+ style: { backgroundColor: o.color }
2319
+ }
2320
+ ),
2321
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children: o.label }),
2322
+ o.hint && /* @__PURE__ */ jsx("span", { className: "shrink-0 text-[10px] text-muted-foreground", children: o.hint })
2323
+ ]
2324
+ },
2325
+ o.value
2326
+ )) })
2327
+ ]
2328
+ }
2329
+ )
2268
2330
  ] });
2269
2331
  }
2270
2332
  var INLINE_TOKEN = /(\*\*[^*]+\*\*|\*[^*]+\*|`[^`]+`)/g;
@@ -2280,7 +2342,7 @@ function renderInline(text, keyPrefix) {
2280
2342
  if (part.startsWith("`") && part.endsWith("`") && part.length > 2) {
2281
2343
  return /* @__PURE__ */ jsx("code", { className: "rounded bg-muted px-1 py-0.5 font-mono text-[0.85em]", children: part.slice(1, -1) }, key);
2282
2344
  }
2283
- return part === "" ? null : /* @__PURE__ */ jsx(React18.Fragment, { children: part }, key);
2345
+ return part === "" ? null : /* @__PURE__ */ jsx(React15.Fragment, { children: part }, key);
2284
2346
  });
2285
2347
  }
2286
2348
  function parseBlocks(source) {
@@ -2364,7 +2426,7 @@ function renderMarkdown(source) {
2364
2426
  case "ol":
2365
2427
  return /* @__PURE__ */ jsx("ol", { className: "list-decimal space-y-1 pl-5", children: block.items.map((item, li) => /* @__PURE__ */ jsx("li", { children: renderInline(item, `${key}-${li}`) }, `${key}-${li}`)) }, key);
2366
2428
  case "p":
2367
- return /* @__PURE__ */ jsx("p", { children: block.lines.map((l, li) => /* @__PURE__ */ jsxs(React18.Fragment, { children: [
2429
+ return /* @__PURE__ */ jsx("p", { children: block.lines.map((l, li) => /* @__PURE__ */ jsxs(React15.Fragment, { children: [
2368
2430
  li > 0 && /* @__PURE__ */ jsx("br", {}),
2369
2431
  renderInline(l, `${key}-${li}`)
2370
2432
  ] }, `${key}-${li}`)) }, key);
@@ -2385,7 +2447,7 @@ function MarkdownEditor({
2385
2447
  renderPreview,
2386
2448
  className
2387
2449
  }) {
2388
- const [mode, setMode] = React18.useState(
2450
+ const [mode, setMode] = React15.useState(
2389
2451
  defaultMode === "preview" && value.trim() === "" ? "edit" : defaultMode
2390
2452
  );
2391
2453
  return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-2", className), children: [
@@ -2679,13 +2741,13 @@ function StockEntryForm({
2679
2741
  labels: overrides
2680
2742
  }) {
2681
2743
  const labels = { ...DEFAULT_LABELS, ...overrides };
2682
- const [quantity, setQuantity] = React18.useState("");
2683
- const [reasonCode, setReasonCode] = React18.useState("");
2684
- const [occurredOn, setOccurredOn] = React18.useState(todayISO());
2685
- const [note, setNote] = React18.useState("");
2686
- const [noteOpen, setNoteOpen] = React18.useState(false);
2687
- const quantityRef = React18.useRef(null);
2688
- React18.useEffect(() => {
2744
+ const [quantity, setQuantity] = React15.useState("");
2745
+ const [reasonCode, setReasonCode] = React15.useState("");
2746
+ const [occurredOn, setOccurredOn] = React15.useState(todayISO());
2747
+ const [note, setNote] = React15.useState("");
2748
+ const [noteOpen, setNoteOpen] = React15.useState(false);
2749
+ const quantityRef = React15.useRef(null);
2750
+ React15.useEffect(() => {
2689
2751
  if (verb === null) return;
2690
2752
  setQuantity("");
2691
2753
  setReasonCode("");
@@ -2811,6 +2873,6 @@ function StockEntryForm({
2811
2873
  ] }) });
2812
2874
  }
2813
2875
 
2814
- export { Badge, Breadcrumb, BulkActionBar, ChevronPager, CurrencyInput, DatePicker, DotBadge, DraftCommitBar, FilterCheckBox, FilterCheckList, FilterCheckRow, FilterChip, FilterSection, Hint, Input, ListView, Markdown, MarkdownEditor, MiniCalendar, Modal, ModalBody, ModalClose, ModalContent, ModalDescription, ModalFooter, ModalHeader, ModalOverlay, ModalPortal, ModalTitle, ModalTrigger, MultiSelect, PageActionBar, PhoneField, PhoneLink, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, RefreshButton, RowActions, SearchCombobox, SearchField, SearchSelect, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator2 as Separator, StatTiles, StockEntryForm, Tabs, TabsContent, TabsList, TabsTrigger, Thumbnail, TimePicker, ToastProvider, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, WHATSAPP_BRAND_COLOR, WhatsAppIcon, badgeVariants, formatPhone2 as formatPhone, normalizePhone, renderMarkdown, setActionsMenuLabel, setRowActionsLabel, toLocalISODate, useRowSelection };
2815
- //# sourceMappingURL=chunk-ZSOT7KTE.js.map
2816
- //# sourceMappingURL=chunk-ZSOT7KTE.js.map
2876
+ export { Badge, Breadcrumb, BulkActionBar, ChevronPager, CurrencyInput, DatePicker, DateRangeChip, DotBadge, DraftCommitBar, FilterCheckBox, FilterCheckList, FilterCheckRow, FilterChip, FilterSection, Input, ListView, Markdown, MarkdownEditor, MiniCalendar, Modal, ModalBody, ModalClose, ModalContent, ModalDescription, ModalFooter, ModalHeader, ModalOverlay, ModalPortal, ModalTitle, ModalTrigger, MultiSelect, PhoneField, PhoneLink, RefreshButton, RowActions, SearchCombobox, SearchField, SearchSelect, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator2 as Separator, StatTiles, StockEntryForm, Tabs, TabsContent, TabsList, TabsTrigger, Thumbnail, TimePicker, ToastProvider, WHATSAPP_BRAND_COLOR, WhatsAppIcon, badgeVariants, formatPhone2 as formatPhone, normalizePhone, renderMarkdown, setRowActionsLabel, toLocalISODate, useRowSelection };
2877
+ //# sourceMappingURL=chunk-NXFVYZY7.js.map
2878
+ //# sourceMappingURL=chunk-NXFVYZY7.js.map