@fayz-ai/ui 0.15.0 → 0.16.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 (65) hide show
  1. package/dist/analytics/context.d.ts +15 -1
  2. package/dist/analytics/context.d.ts.map +1 -1
  3. package/dist/analytics/index.d.ts +1 -1
  4. package/dist/analytics/index.d.ts.map +1 -1
  5. package/dist/{chunk-5KMAEQA3.js → chunk-5VF45NLE.js} +4 -4
  6. package/dist/{chunk-5KMAEQA3.js.map → chunk-5VF45NLE.js.map} +1 -1
  7. package/dist/{chunk-J7F3Z52K.js → chunk-6BJTH3L6.js} +4 -4
  8. package/dist/chunk-6BJTH3L6.js.map +1 -0
  9. package/dist/{chunk-KD2V3TAX.js → chunk-E44WOPCR.js} +61 -49
  10. package/dist/chunk-E44WOPCR.js.map +1 -0
  11. package/dist/{chunk-FFJ2C5YH.js → chunk-HKGTF2YA.js} +41 -16
  12. package/dist/chunk-HKGTF2YA.js.map +1 -0
  13. package/dist/{chunk-NA3GE4H3.js → chunk-PZU7XC2M.js} +362 -252
  14. package/dist/chunk-PZU7XC2M.js.map +1 -0
  15. package/dist/{chunk-SLWTKHNY.js → chunk-SDPYDWWV.js} +371 -83
  16. package/dist/chunk-SDPYDWWV.js.map +1 -0
  17. package/dist/dashboard/index.js +3 -3
  18. package/dist/hooks/useIsWide.d.ts +16 -0
  19. package/dist/hooks/useIsWide.d.ts.map +1 -0
  20. package/dist/index.d.ts +4 -3
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +30 -10
  23. package/dist/index.js.map +1 -1
  24. package/dist/layout/AppShell.d.ts +25 -2
  25. package/dist/layout/AppShell.d.ts.map +1 -1
  26. package/dist/layout/ModulePage.d.ts +4 -0
  27. package/dist/layout/ModulePage.d.ts.map +1 -1
  28. package/dist/layout/SaveBar.d.ts.map +1 -1
  29. package/dist/layout/Sidebar.d.ts.map +1 -1
  30. package/dist/layout/Topbar.d.ts +5 -1
  31. package/dist/layout/Topbar.d.ts.map +1 -1
  32. package/dist/layout/index.d.ts +1 -1
  33. package/dist/layout/index.d.ts.map +1 -1
  34. package/dist/layout/index.js +3 -3
  35. package/dist/primitives/checkbox.d.ts +4 -0
  36. package/dist/primitives/checkbox.d.ts.map +1 -1
  37. package/dist/primitives/index.d.ts +3 -0
  38. package/dist/primitives/index.d.ts.map +1 -1
  39. package/dist/primitives/index.js +4 -4
  40. package/dist/primitives/list-view.d.ts +5 -1
  41. package/dist/primitives/list-view.d.ts.map +1 -1
  42. package/dist/primitives/modal.d.ts.map +1 -1
  43. package/dist/primitives/page-actions.d.ts +55 -0
  44. package/dist/primitives/page-actions.d.ts.map +1 -0
  45. package/dist/primitives/page-header.d.ts +5 -2
  46. package/dist/primitives/page-header.d.ts.map +1 -1
  47. package/dist/primitives/page-toolbar.d.ts.map +1 -1
  48. package/dist/primitives/refresh-button.d.ts.map +1 -1
  49. package/dist/primitives/row-actions.d.ts +11 -0
  50. package/dist/primitives/row-actions.d.ts.map +1 -0
  51. package/dist/primitives/whatsapp-icon.d.ts +7 -0
  52. package/dist/primitives/whatsapp-icon.d.ts.map +1 -0
  53. package/dist/stores/index.d.ts +1 -1
  54. package/dist/stores/index.d.ts.map +1 -1
  55. package/dist/stores/layout.store.d.ts +1 -0
  56. package/dist/stores/layout.store.d.ts.map +1 -1
  57. package/dist/stores/page-header.store.d.ts +39 -5
  58. package/dist/stores/page-header.store.d.ts.map +1 -1
  59. package/dist/styles.css +166 -3
  60. package/package.json +2 -2
  61. package/dist/chunk-FFJ2C5YH.js.map +0 -1
  62. package/dist/chunk-J7F3Z52K.js.map +0 -1
  63. package/dist/chunk-KD2V3TAX.js.map +0 -1
  64. package/dist/chunk-NA3GE4H3.js.map +0 -1
  65. package/dist/chunk-SLWTKHNY.js.map +0 -1
@@ -1,25 +1,25 @@
1
- import { useSaveBarVisible, useCrossModuleBack, useBackHandler, PageHeaderActions } from './chunk-NA3GE4H3.js';
2
- import { Dropdown, DropdownTrigger, DropdownContent, DropdownItem, Card, DataTable } from './chunk-KD2V3TAX.js';
1
+ import { useSaveBarVisible, useCrossModuleBack, useBackHandler, PageHeaderActions } from './chunk-PZU7XC2M.js';
2
+ import { useIsWide, Dropdown, DropdownTrigger, DropdownContent, DropdownSeparator, DropdownItem, Card, DataTable } from './chunk-E44WOPCR.js';
3
3
  import { cn, Button } from './chunk-OKZ6WQB3.js';
4
- import * as React14 from 'react';
4
+ import * as React16 from 'react';
5
5
  import { useState, useRef, useEffect, useMemo, useCallback } from 'react';
6
6
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
7
7
  import { cva } from 'class-variance-authority';
8
8
  import * as DialogPrimitive from '@radix-ui/react-dialog';
9
- import { X, ChevronDown, ChevronUp, Check, ArrowLeft, Search, ChevronLeft, ChevronRight, MoreHorizontal, ImageIcon, RefreshCw, Clock, Plus, Download, Calendar, Loader2 } from 'lucide-react';
9
+ import { X, ChevronDown, ChevronUp, Check, ArrowLeft, MoreHorizontal, Plus, MoreVertical, Search, ChevronLeft, ChevronRight, ImageIcon, RefreshCw, Clock, Download, Calendar, Loader2 } from 'lucide-react';
10
10
  import * as SelectPrimitive from '@radix-ui/react-select';
11
11
  import { Toaster } from 'sonner';
12
12
  export { toast } from 'sonner';
13
13
  import * as TabsPrimitive from '@radix-ui/react-tabs';
14
14
  import * as SeparatorPrimitive from '@radix-ui/react-separator';
15
15
  import * as TooltipPrimitive from '@radix-ui/react-tooltip';
16
- import { useTranslation, getCountry, unmaskPhone, maskPhone, getCurrentLocale } from '@fayz-ai/core';
17
16
  import { createPortal } from 'react-dom';
17
+ import { useTranslation, getCountry, unmaskPhone, maskPhone, getCurrentLocale } from '@fayz-ai/core';
18
18
  import * as PopoverPrimitive from '@radix-ui/react-popover';
19
19
 
20
- var Input = React14.forwardRef(
20
+ var Input = React16.forwardRef(
21
21
  ({ className, type, error, description, id, ...props }, ref) => {
22
- const inputId = id ?? React14.useId();
22
+ const inputId = id ?? React16.useId();
23
23
  const descriptionId = description ? `${inputId}-description` : void 0;
24
24
  const errorId = error ? `${inputId}-error` : void 0;
25
25
  return /* @__PURE__ */ jsxs("div", { className: "w-full", children: [
@@ -107,12 +107,12 @@ var Modal = DialogPrimitive.Root;
107
107
  var ModalTrigger = DialogPrimitive.Trigger;
108
108
  var ModalClose = DialogPrimitive.Close;
109
109
  var ModalPortal = DialogPrimitive.Portal;
110
- var ModalOverlay = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
110
+ var ModalOverlay = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
111
111
  DialogPrimitive.Overlay,
112
112
  {
113
113
  ref,
114
114
  className: cn(
115
- "fayz-modal-overlay saas-mdl-ov fixed inset-0 z-50",
115
+ "fayz-modal-overlay saas-mdl-ov fixed inset-0 z-[100]",
116
116
  "flex items-center justify-center p-0 sm:p-6",
117
117
  className
118
118
  ),
@@ -120,7 +120,7 @@ var ModalOverlay = React14.forwardRef(({ className, ...props }, ref) => /* @__PU
120
120
  }
121
121
  ));
122
122
  ModalOverlay.displayName = "ModalOverlay";
123
- var ModalContent = React14.forwardRef(({ className, children, size = "lg", hideClose, noPadding, onPointerDownOutside, onInteractOutside, onCloseAutoFocus, ...props }, ref) => /* @__PURE__ */ jsx(ModalPortal, { children: /* @__PURE__ */ jsx(ModalOverlay, { children: /* @__PURE__ */ jsxs(
123
+ var ModalContent = React16.forwardRef(({ className, children, size = "lg", hideClose, noPadding, onPointerDownOutside, onInteractOutside, onCloseAutoFocus, ...props }, ref) => /* @__PURE__ */ jsx(ModalPortal, { children: /* @__PURE__ */ jsx(ModalOverlay, { children: /* @__PURE__ */ jsxs(
124
124
  DialogPrimitive.Content,
125
125
  {
126
126
  ref,
@@ -146,7 +146,7 @@ var ModalContent = React14.forwardRef(({ className, children, size = "lg", hideC
146
146
  // fz-container: a form inside a dialog measures the DIALOG. Without
147
147
  // it a two-column field grid in an `sm` modal read the window's width
148
148
  // and kept both columns in 380px.
149
- "fayz-glass-surface fayz-modal-content saas-mdl-ct fz-container relative z-50 flex flex-col w-full outline-none",
149
+ "fayz-glass-surface fayz-modal-content saas-mdl-ct fz-container relative z-[100] flex flex-col w-full outline-none",
150
150
  // Mobile fullscreen
151
151
  "h-full rounded-none border-0",
152
152
  // Desktop centered card
@@ -173,16 +173,16 @@ function ModalBody({ className, ...props }) {
173
173
  return /* @__PURE__ */ jsx("div", { className: cn("flex-1 overflow-y-auto min-h-0", className), ...props });
174
174
  }
175
175
  function ModalFooter({ className, ...props }) {
176
- return /* @__PURE__ */ jsx("div", { className: cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2 shrink-0", className), ...props });
176
+ 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
177
  }
178
- var ModalTitle = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DialogPrimitive.Title, { ref, className: cn("text-lg font-semibold leading-none tracking-tight", className), ...props }));
178
+ var ModalTitle = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DialogPrimitive.Title, { ref, className: cn("text-lg font-semibold leading-none tracking-tight", className), ...props }));
179
179
  ModalTitle.displayName = "ModalTitle";
180
- var ModalDescription = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DialogPrimitive.Description, { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
180
+ var ModalDescription = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DialogPrimitive.Description, { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
181
181
  ModalDescription.displayName = "ModalDescription";
182
182
  var Select = SelectPrimitive.Root;
183
183
  var SelectGroup = SelectPrimitive.Group;
184
184
  var SelectValue = SelectPrimitive.Value;
185
- var SelectTrigger = React14.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
185
+ var SelectTrigger = React16.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
186
186
  SelectPrimitive.Trigger,
187
187
  {
188
188
  ref,
@@ -198,7 +198,7 @@ var SelectTrigger = React14.forwardRef(({ className, children, ...props }, ref)
198
198
  }
199
199
  ));
200
200
  SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
201
- var SelectScrollUpButton = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
201
+ var SelectScrollUpButton = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
202
202
  SelectPrimitive.ScrollUpButton,
203
203
  {
204
204
  ref,
@@ -211,7 +211,7 @@ var SelectScrollUpButton = React14.forwardRef(({ className, ...props }, ref) =>
211
211
  }
212
212
  ));
213
213
  SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
214
- var SelectScrollDownButton = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
214
+ var SelectScrollDownButton = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
215
215
  SelectPrimitive.ScrollDownButton,
216
216
  {
217
217
  ref,
@@ -224,12 +224,12 @@ var SelectScrollDownButton = React14.forwardRef(({ className, ...props }, ref) =
224
224
  }
225
225
  ));
226
226
  SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
227
- var SelectContent = React14.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
227
+ var SelectContent = React16.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
228
228
  SelectPrimitive.Content,
229
229
  {
230
230
  ref,
231
231
  className: cn(
232
- "fayz-glass-surface relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-card border bg-popover text-popover-foreground shadow-md",
232
+ "fayz-glass-surface relative z-[110] max-h-96 min-w-[8rem] overflow-hidden rounded-card border bg-popover text-popover-foreground shadow-md",
233
233
  position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
234
234
  className
235
235
  ),
@@ -252,7 +252,7 @@ var SelectContent = React14.forwardRef(({ className, children, position = "poppe
252
252
  }
253
253
  ) }));
254
254
  SelectContent.displayName = SelectPrimitive.Content.displayName;
255
- var SelectLabel = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
255
+ var SelectLabel = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
256
256
  SelectPrimitive.Label,
257
257
  {
258
258
  ref,
@@ -261,7 +261,7 @@ var SelectLabel = React14.forwardRef(({ className, ...props }, ref) => /* @__PUR
261
261
  }
262
262
  ));
263
263
  SelectLabel.displayName = SelectPrimitive.Label.displayName;
264
- var SelectItem = React14.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
264
+ var SelectItem = React16.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
265
265
  SelectPrimitive.Item,
266
266
  {
267
267
  ref,
@@ -277,7 +277,7 @@ var SelectItem = React14.forwardRef(({ className, children, ...props }, ref) =>
277
277
  }
278
278
  ));
279
279
  SelectItem.displayName = SelectPrimitive.Item.displayName;
280
- var SelectSeparator = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
280
+ var SelectSeparator = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
281
281
  SelectPrimitive.Separator,
282
282
  {
283
283
  ref,
@@ -315,7 +315,7 @@ function ToastProvider({
315
315
  );
316
316
  }
317
317
  var Tabs = TabsPrimitive.Root;
318
- var TabsList = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
318
+ var TabsList = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
319
319
  TabsPrimitive.List,
320
320
  {
321
321
  ref,
@@ -329,7 +329,7 @@ var TabsList = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__
329
329
  }
330
330
  ));
331
331
  TabsList.displayName = TabsPrimitive.List.displayName;
332
- var TabsTrigger = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
332
+ var TabsTrigger = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
333
333
  TabsPrimitive.Trigger,
334
334
  {
335
335
  ref,
@@ -341,7 +341,7 @@ var TabsTrigger = React14.forwardRef(({ className, ...props }, ref) => /* @__PUR
341
341
  }
342
342
  ));
343
343
  TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
344
- var TabsContent = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
344
+ var TabsContent = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
345
345
  TabsPrimitive.Content,
346
346
  {
347
347
  ref,
@@ -353,7 +353,7 @@ var TabsContent = React14.forwardRef(({ className, ...props }, ref) => /* @__PUR
353
353
  }
354
354
  ));
355
355
  TabsContent.displayName = TabsPrimitive.Content.displayName;
356
- var Separator2 = React14.forwardRef(
356
+ var Separator2 = React16.forwardRef(
357
357
  ({ className, orientation = "horizontal", decorative = true, ...props }, ref) => /* @__PURE__ */ jsx(
358
358
  SeparatorPrimitive.Root,
359
359
  {
@@ -404,7 +404,7 @@ function formatPhone(digits, fallback, countryCode) {
404
404
  const tail = rest.length === 9 ? rest.slice(5) : rest.slice(4);
405
405
  return `+55 (${ddd}) ${head}-${tail}`;
406
406
  }
407
- var PhoneLink = React14.forwardRef(
407
+ var PhoneLink = React16.forwardRef(
408
408
  ({ phone, message, countryCode, raw, className, children, ...props }, ref) => {
409
409
  const { e164, display } = normalizePhone(phone, countryCode);
410
410
  const label = children ?? (raw ? phone ?? "" : display);
@@ -428,6 +428,20 @@ var PhoneLink = React14.forwardRef(
428
428
  }
429
429
  );
430
430
  PhoneLink.displayName = "PhoneLink";
431
+ var WHATSAPP_BRAND_COLOR = "#25D366";
432
+ function WhatsAppIcon({ className, ...props }) {
433
+ return /* @__PURE__ */ jsx(
434
+ "svg",
435
+ {
436
+ viewBox: "0 0 24 24",
437
+ fill: "currentColor",
438
+ "aria-hidden": "true",
439
+ className,
440
+ ...props,
441
+ children: /* @__PURE__ */ jsx("path", { d: "M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.297-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 0 1-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 0 1-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 0 1 2.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0 0 12.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 0 0 5.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 0 0-3.48-8.413Z" })
442
+ }
443
+ );
444
+ }
431
445
  function Breadcrumb({ parent, current, onBack }) {
432
446
  const { onBack: effectiveOnBack, parentLabel: effectiveParent } = useCrossModuleBack(onBack, parent);
433
447
  useBackHandler(effectiveOnBack);
@@ -453,19 +467,283 @@ function Breadcrumb({ parent, current, onBack }) {
453
467
  var TooltipProvider = TooltipPrimitive.Provider;
454
468
  var Tooltip = TooltipPrimitive.Root;
455
469
  var TooltipTrigger = TooltipPrimitive.Trigger;
456
- var TooltipContent = React14.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(
470
+ var TooltipContent = React16.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(
457
471
  TooltipPrimitive.Content,
458
472
  {
459
473
  ref,
460
474
  sideOffset,
461
475
  className: cn(
462
- "fayz-glass-surface z-50 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",
476
+ "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",
463
477
  className
464
478
  ),
465
479
  ...props
466
480
  }
467
481
  ));
468
482
  TooltipContent.displayName = TooltipPrimitive.Content.displayName;
483
+ function iconOf(action, className) {
484
+ const Icon2 = action.icon;
485
+ return Icon2 ? /* @__PURE__ */ jsx(Icon2, { className }) : null;
486
+ }
487
+ function PageActionBar({ actions, className }) {
488
+ const wide = useIsWide();
489
+ const visible = actions.filter((a) => !a.hidden);
490
+ if (visible.length === 0) return null;
491
+ if (!wide) {
492
+ const usable = visible.filter((a) => !a.desktopOnly);
493
+ return usable.length > 0 ? /* @__PURE__ */ jsx(PageActionFab, { actions: usable }) : null;
494
+ }
495
+ let seenPrimary = false;
496
+ const primary = [];
497
+ const secondary = [];
498
+ const utility = [];
499
+ const danger = [];
500
+ for (const a of visible) {
501
+ const intent = a.intent ?? "secondary";
502
+ if (intent === "primary" && !seenPrimary) {
503
+ seenPrimary = true;
504
+ primary.push(a);
505
+ continue;
506
+ }
507
+ if (intent === "danger") {
508
+ danger.push(a);
509
+ continue;
510
+ }
511
+ if (intent === "utility") {
512
+ utility.push(a);
513
+ continue;
514
+ }
515
+ secondary.push(a);
516
+ }
517
+ const head = primary[0];
518
+ const menu = [...secondary, ...danger];
519
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex shrink-0 items-center gap-2", className), children: [
520
+ utility.map((a) => /* @__PURE__ */ jsx(
521
+ Button,
522
+ {
523
+ variant: "outline",
524
+ size: "icon",
525
+ onClick: () => void a.onSelect(),
526
+ disabled: a.disabled,
527
+ "aria-label": a.label,
528
+ title: a.label,
529
+ "data-testid": a.testId,
530
+ children: iconOf(a, "h-4 w-4")
531
+ },
532
+ a.id
533
+ )),
534
+ head && menu.length === 0 && /* @__PURE__ */ jsxs(Button, { onClick: () => void head.onSelect(), disabled: head.disabled, "data-testid": head.testId, children: [
535
+ iconOf(head, "mr-1.5 h-4 w-4"),
536
+ head.label
537
+ ] }),
538
+ head && menu.length > 0 && /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
539
+ /* @__PURE__ */ jsxs(Button, { className: "rounded-r-none", onClick: () => void head.onSelect(), disabled: head.disabled, "data-testid": head.testId, children: [
540
+ iconOf(head, "mr-1.5 h-4 w-4"),
541
+ head.label
542
+ ] }),
543
+ /* @__PURE__ */ jsxs(Dropdown, { children: [
544
+ /* @__PURE__ */ jsx(DropdownTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Button, { className: "-ml-px rounded-l-none px-2", "aria-label": `${head.label}\u2026`, children: /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4" }) }) }),
545
+ /* @__PURE__ */ jsx(DropdownContent, { align: "end", className: "w-56", children: /* @__PURE__ */ jsx(ActionItems, { actions: menu }) })
546
+ ] })
547
+ ] }),
548
+ !head && menu.length > 0 && /* @__PURE__ */ jsxs(Dropdown, { children: [
549
+ /* @__PURE__ */ jsx(DropdownTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Button, { variant: "outline", size: "icon", "aria-label": "A\xE7\xF5es", children: /* @__PURE__ */ jsx(MoreHorizontal, { className: "h-4 w-4" }) }) }),
550
+ /* @__PURE__ */ jsx(DropdownContent, { align: "end", className: "w-56", children: /* @__PURE__ */ jsx(ActionItems, { actions: menu }) })
551
+ ] })
552
+ ] });
553
+ }
554
+ function ActionItems({ actions, stagger }) {
555
+ const out = [];
556
+ actions.forEach((a, i) => {
557
+ const isDanger = a.intent === "danger";
558
+ const prevSafe = i > 0 && actions[i - 1].intent !== "danger";
559
+ if (isDanger && prevSafe) out.push(/* @__PURE__ */ jsx(DropdownSeparator, {}, `${a.id}-sep`));
560
+ out.push(
561
+ /* @__PURE__ */ jsxs(
562
+ DropdownItem,
563
+ {
564
+ disabled: a.disabled,
565
+ onSelect: () => void a.onSelect(),
566
+ "data-testid": a.testId,
567
+ style: stagger ? { ["--i"]: i } : void 0,
568
+ className: cn("gap-2", stagger && "fz-fab-item", isDanger && "text-destructive focus:text-destructive"),
569
+ children: [
570
+ iconOf(a, "h-4 w-4 shrink-0"),
571
+ /* @__PURE__ */ jsxs("span", { className: "min-w-0", children: [
572
+ /* @__PURE__ */ jsx("span", { className: "block truncate", children: a.label }),
573
+ a.description && /* @__PURE__ */ jsx("span", { className: "block truncate text-xs text-muted-foreground", children: a.description })
574
+ ] })
575
+ ]
576
+ },
577
+ a.id
578
+ )
579
+ );
580
+ });
581
+ return /* @__PURE__ */ jsx(Fragment, { children: out });
582
+ }
583
+ function PageActionFab({ actions }) {
584
+ const byIntent = (i) => actions.filter((a) => (a.intent ?? "secondary") === i);
585
+ const utility = byIntent("utility");
586
+ const main = [...byIntent("primary"), ...byIntent("secondary"), ...byIntent("danger")];
587
+ if (main.length === 0) return /* @__PURE__ */ jsx(FabButton, { actions: utility, tone: "neutral" });
588
+ const isCreate = main.every((a) => a.creates ?? a.icon === Plus);
589
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
590
+ utility.length > 0 && /* @__PURE__ */ jsx(FabButton, { actions: utility, tone: "neutral", mini: true }),
591
+ /* @__PURE__ */ jsx(FabButton, { actions: main, tone: isCreate ? "primary" : "neutral" })
592
+ ] });
593
+ }
594
+ function useScrim(open) {
595
+ const [mounted, setMounted] = React16.useState(open);
596
+ const [visible, setVisible] = React16.useState(open);
597
+ React16.useEffect(() => {
598
+ if (open) {
599
+ setMounted(true);
600
+ const frame = requestAnimationFrame(() => setVisible(true));
601
+ return () => cancelAnimationFrame(frame);
602
+ }
603
+ setVisible(false);
604
+ const timer = window.setTimeout(() => setMounted(false), SCRIM_MS);
605
+ return () => window.clearTimeout(timer);
606
+ }, [open]);
607
+ return { mounted, visible };
608
+ }
609
+ var SCRIM_MS = 200;
610
+ function FabButton({ actions, tone, mini }) {
611
+ const [open, setOpen] = React16.useState(false);
612
+ const scrim = useScrim(open);
613
+ if (actions.length === 0) return null;
614
+ const isCreate = tone === "primary";
615
+ const FabIcon = isCreate ? Plus : MoreVertical;
616
+ const style = {
617
+ bottom: mini ? "calc(var(--fz-bottom-bar, 0px) + 4.75rem)" : "calc(var(--fz-bottom-bar, 0px) + 1rem)"
618
+ };
619
+ const shell = cn(
620
+ "fz-tap fixed z-40 flex items-center justify-center rounded-full",
621
+ "transition-transform active:scale-95 md:hidden",
622
+ // Centred on the main circle's column, so the two read as one stack.
623
+ mini ? "right-5 h-12 w-12" : "right-4 h-14 w-14",
624
+ 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"
625
+ );
626
+ if (actions.length === 1) {
627
+ const only = actions[0];
628
+ const Icon2 = only.icon ?? FabIcon;
629
+ return /* @__PURE__ */ jsx(
630
+ "button",
631
+ {
632
+ type: "button",
633
+ style,
634
+ className: shell,
635
+ onClick: () => void only.onSelect(),
636
+ disabled: only.disabled,
637
+ "aria-label": only.label,
638
+ "data-testid": only.testId,
639
+ children: /* @__PURE__ */ jsx(Icon2, { className: mini ? "h-5 w-5" : "h-6 w-6" })
640
+ }
641
+ );
642
+ }
643
+ return /* @__PURE__ */ jsxs(Dropdown, { open, onOpenChange: setOpen, children: [
644
+ scrim.mounted && typeof document !== "undefined" && createPortal(
645
+ /* @__PURE__ */ jsx(
646
+ "div",
647
+ {
648
+ "aria-hidden": true,
649
+ onClick: () => setOpen(false),
650
+ className: cn(
651
+ "fixed inset-0 z-[100] bg-foreground/40 transition-opacity duration-200 md:hidden",
652
+ "motion-reduce:transition-none",
653
+ scrim.visible ? "opacity-100" : "opacity-0"
654
+ )
655
+ }
656
+ ),
657
+ document.body
658
+ ),
659
+ /* @__PURE__ */ jsx(DropdownTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
660
+ "button",
661
+ {
662
+ type: "button",
663
+ style,
664
+ className: cn(shell, open && "z-[105]", isCreate && "fz-fab-trigger"),
665
+ "aria-label": actionsMenuLabel,
666
+ children: /* @__PURE__ */ jsx(FabIcon, { className: mini ? "h-5 w-5" : "h-6 w-6" })
667
+ }
668
+ ) }),
669
+ /* @__PURE__ */ jsx(DropdownContent, { side: "top", align: "end", sideOffset: 12, className: "fz-fab-menu w-60 md:hidden", children: /* @__PURE__ */ jsx(ActionItems, { actions, stagger: true }) })
670
+ ] });
671
+ }
672
+ var actionsMenuLabel = "A\xE7\xF5es";
673
+ function setActionsMenuLabel(label) {
674
+ actionsMenuLabel = label;
675
+ }
676
+ var INLINE_LIMIT = 2;
677
+ function RowActions({
678
+ actions,
679
+ className,
680
+ inlineLimit = INLINE_LIMIT
681
+ }) {
682
+ const visible = actions.filter((a) => !a.hidden);
683
+ if (visible.length === 0) return null;
684
+ const safe = visible.filter((a) => a.intent !== "danger");
685
+ const danger = visible.filter((a) => a.intent === "danger");
686
+ const inline = danger.length === 0 && safe.length <= inlineLimit ? safe : safe.slice(0, 0);
687
+ const overflow = visible.filter((a) => !inline.includes(a));
688
+ const stop = (e) => e.stopPropagation();
689
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex shrink-0 items-center justify-end gap-0.5", className), onClick: stop, children: [
690
+ inline.map((a) => {
691
+ const Icon2 = a.icon;
692
+ return /* @__PURE__ */ jsx(
693
+ Button,
694
+ {
695
+ variant: "ghost",
696
+ size: "icon",
697
+ className: "fz-tap text-muted-foreground",
698
+ onClick: () => void a.onSelect(),
699
+ disabled: a.disabled,
700
+ "aria-label": a.label,
701
+ title: a.label,
702
+ "data-testid": a.testId,
703
+ children: Icon2 ? /* @__PURE__ */ jsx(Icon2, { className: "h-4 w-4" }) : null
704
+ },
705
+ a.id
706
+ );
707
+ }),
708
+ overflow.length > 0 && /* @__PURE__ */ jsxs(Dropdown, { children: [
709
+ /* @__PURE__ */ jsx(DropdownTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
710
+ Button,
711
+ {
712
+ variant: "ghost",
713
+ size: "icon",
714
+ className: "fz-tap text-muted-foreground",
715
+ "aria-label": rowActionsLabel,
716
+ children: /* @__PURE__ */ jsx(MoreHorizontal, { className: "h-4 w-4" })
717
+ }
718
+ ) }),
719
+ /* @__PURE__ */ jsx(DropdownContent, { align: "end", className: "w-52", children: overflow.map((a, i) => {
720
+ const Icon2 = a.icon;
721
+ const isDanger = a.intent === "danger";
722
+ const prevSafe = i > 0 && overflow[i - 1].intent !== "danger";
723
+ return /* @__PURE__ */ jsxs(React16.Fragment, { children: [
724
+ isDanger && prevSafe && /* @__PURE__ */ jsx(DropdownSeparator, {}),
725
+ /* @__PURE__ */ jsxs(
726
+ DropdownItem,
727
+ {
728
+ disabled: a.disabled,
729
+ onSelect: () => void a.onSelect(),
730
+ "data-testid": a.testId,
731
+ className: cn("gap-2", isDanger && "text-destructive focus:text-destructive"),
732
+ children: [
733
+ Icon2 ? /* @__PURE__ */ jsx(Icon2, { className: "h-4 w-4 shrink-0" }) : null,
734
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: a.label })
735
+ ]
736
+ }
737
+ )
738
+ ] }, a.id);
739
+ }) })
740
+ ] })
741
+ ] });
742
+ }
743
+ var rowActionsLabel = "A\xE7\xF5es";
744
+ function setRowActionsLabel(label) {
745
+ rowActionsLabel = label;
746
+ }
469
747
  function SearchField({ value, onChange, placeholder, ...rest }) {
470
748
  return /* @__PURE__ */ jsxs("div", { className: "relative", children: [
471
749
  /* @__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" }),
@@ -621,8 +899,8 @@ var ICON_CLASSES = {
621
899
  lg: "h-5 w-5"
622
900
  };
623
901
  function Thumbnail({ src, alt = "", size = "md", icon: Icon2 = ImageIcon, className }) {
624
- const [failed, setFailed] = React14.useState(false);
625
- React14.useEffect(() => {
902
+ const [failed, setFailed] = React16.useState(false);
903
+ React16.useEffect(() => {
626
904
  setFailed(false);
627
905
  }, [src]);
628
906
  const base = cn("shrink-0 overflow-hidden", SIZE_CLASSES[size], className);
@@ -649,9 +927,9 @@ function Thumbnail({ src, alt = "", size = "md", icon: Icon2 = ImageIcon, classN
649
927
  }
650
928
  Thumbnail.displayName = "Thumbnail";
651
929
  function RefreshButton({ onRefresh, fromCache, label, labelCached, className, ...rest }) {
652
- const [phase, setPhase] = React14.useState("idle");
653
- const alive = React14.useRef(true);
654
- React14.useEffect(() => () => {
930
+ const [phase, setPhase] = React16.useState("idle");
931
+ const alive = React16.useRef(true);
932
+ React16.useEffect(() => () => {
655
933
  alive.current = false;
656
934
  }, []);
657
935
  const title = fromCache ? labelCached ?? label : label;
@@ -669,16 +947,20 @@ function RefreshButton({ onRefresh, fromCache, label, labelCached, className, ..
669
947
  }, 1400);
670
948
  }
671
949
  return /* @__PURE__ */ jsx(
672
- "button",
950
+ Button,
673
951
  {
674
952
  type: "button",
953
+ variant: "ghost",
954
+ size: "icon",
675
955
  title,
676
956
  "aria-label": title,
677
957
  onClick: () => {
678
958
  void run();
679
959
  },
680
960
  className: cn(
681
- "inline-flex items-center justify-center transition",
961
+ // The state colours are the point of this control, so they stay; what
962
+ // it was missing is the shared button underneath them.
963
+ "transition",
682
964
  fromCache && phase !== "done" && "text-amber-600 hover:text-amber-700 dark:text-amber-500 dark:hover:text-amber-400",
683
965
  phase === "done" && "text-emerald-600 dark:text-emerald-500",
684
966
  className
@@ -741,8 +1023,8 @@ function StatTiles({ tiles, loading, className }) {
741
1023
  ] }, tile.id);
742
1024
  }) });
743
1025
  }
744
- var Hint = React14.forwardRef(function Hint2({ label, children, side = "top", delayDuration = 0, ...rest }, ref) {
745
- if (!label) return React14.cloneElement(children, { ...rest, ref });
1026
+ var Hint = React16.forwardRef(function Hint2({ label, children, side = "top", delayDuration = 0, ...rest }, ref) {
1027
+ if (!label) return React16.cloneElement(children, { ...rest, ref });
746
1028
  return /* @__PURE__ */ jsx(TooltipPrimitive.Provider, { delayDuration, children: /* @__PURE__ */ jsxs(Tooltip, { children: [
747
1029
  /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, ...rest, ref, children }),
748
1030
  /* @__PURE__ */ jsx(TooltipContent, { side, className: "px-2 py-1 text-xs font-medium", children: label })
@@ -869,27 +1151,27 @@ function useRowSelection({
869
1151
  getRowId,
870
1152
  enabled = true
871
1153
  }) {
872
- const identify = React14.useCallback(
1154
+ const identify = React16.useCallback(
873
1155
  (row) => getRowId ? getRowId(row) : String(row?.id ?? ""),
874
1156
  [getRowId]
875
1157
  );
876
- const visible = React14.useMemo(() => rows ?? [], [rows]);
877
- const [rawSelection, setRawSelection] = React14.useState([]);
878
- const visibleIds = React14.useMemo(() => new Set(visible.map(identify)), [visible, identify]);
879
- const selectedIds = React14.useMemo(
1158
+ const visible = React16.useMemo(() => rows ?? [], [rows]);
1159
+ const [rawSelection, setRawSelection] = React16.useState([]);
1160
+ const visibleIds = React16.useMemo(() => new Set(visible.map(identify)), [visible, identify]);
1161
+ const selectedIds = React16.useMemo(
880
1162
  () => rawSelection.filter((id) => visibleIds.has(id)),
881
1163
  [rawSelection, visibleIds]
882
1164
  );
883
- const selectedRows = React14.useMemo(() => {
1165
+ const selectedRows = React16.useMemo(() => {
884
1166
  const picked = new Set(selectedIds);
885
1167
  return visible.filter((row) => picked.has(identify(row)));
886
1168
  }, [visible, selectedIds, identify]);
887
- const clear = React14.useCallback(() => setRawSelection([]), []);
888
- const selectAll = React14.useCallback(
1169
+ const clear = React16.useCallback(() => setRawSelection([]), []);
1170
+ const selectAll = React16.useCallback(
889
1171
  () => setRawSelection(visible.map(identify)),
890
1172
  [visible, identify]
891
1173
  );
892
- const barActions = React14.useMemo(
1174
+ const barActions = React16.useMemo(
893
1175
  () => (actions ?? []).map((action) => ({
894
1176
  id: action.id,
895
1177
  label: action.label,
@@ -948,7 +1230,7 @@ function FilterChip({ allLabel, options, value, onChange, label, icon: Icon2, cl
948
1230
  ] })
949
1231
  ] });
950
1232
  }
951
- var ICON_BTN = "flex h-8 w-8 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground";
1233
+ var ICON_BTN = "fz-tap text-muted-foreground";
952
1234
  function ListView({
953
1235
  columns,
954
1236
  data,
@@ -982,7 +1264,8 @@ function ListView({
982
1264
  exportLabel = "Export",
983
1265
  onRefresh,
984
1266
  refreshLabel = "Refresh",
985
- className
1267
+ className,
1268
+ actions
986
1269
  }) {
987
1270
  const [internalSearch, setInternalSearch] = useState(controlledSearch ?? "");
988
1271
  const debounceRef = useRef();
@@ -1023,12 +1306,17 @@ function ListView({
1023
1306
  ] })
1024
1307
  ] });
1025
1308
  return /* @__PURE__ */ jsxs("div", { className: cn("space-y-4", className), children: [
1026
- (headerActions || onNew && newLabel) && /* @__PURE__ */ jsx(PageHeaderActions, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
1309
+ (headerActions || actions?.length || onNew && newLabel) && /* @__PURE__ */ jsx(PageHeaderActions, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
1027
1310
  headerActions,
1028
- onNew && newLabel && /* @__PURE__ */ jsxs(Button, { variant: "default", size: "default", onClick: onNew, className: "shrink-0", children: [
1029
- /* @__PURE__ */ jsx(Plus, { className: "h-3.5 w-3.5" }),
1030
- newLabel
1031
- ] })
1311
+ /* @__PURE__ */ jsx(
1312
+ PageActionBar,
1313
+ {
1314
+ actions: [
1315
+ ...actions ?? [],
1316
+ ...onNew && newLabel ? [{ id: "new", label: newLabel, icon: Plus, intent: "primary", onSelect: onNew }] : []
1317
+ ]
1318
+ }
1319
+ )
1032
1320
  ] }) }),
1033
1321
  toolbar,
1034
1322
  /* @__PURE__ */ jsxs(Card, { className: "overflow-hidden", children: [
@@ -1059,8 +1347,8 @@ function ListView({
1059
1347
  (tagFilter || filters || onRefresh || onExport) && /* @__PURE__ */ jsxs("div", { className: "ml-auto flex flex-wrap items-center justify-end gap-2", children: [
1060
1348
  tagFilter,
1061
1349
  filters,
1062
- onRefresh && /* @__PURE__ */ jsx("button", { type: "button", "aria-label": refreshLabel, title: refreshLabel, onClick: onRefresh, className: ICON_BTN, children: /* @__PURE__ */ jsx(RefreshCw, { className: "h-4 w-4" }) }),
1063
- onExport && /* @__PURE__ */ jsx("button", { type: "button", "aria-label": exportLabel, title: exportLabel, onClick: onExport, className: ICON_BTN, children: /* @__PURE__ */ jsx(Download, { className: "h-4 w-4" }) })
1350
+ onRefresh && /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon", "aria-label": refreshLabel, title: refreshLabel, onClick: onRefresh, className: ICON_BTN, children: /* @__PURE__ */ jsx(RefreshCw, { className: "h-4 w-4" }) }),
1351
+ onExport && /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon", "aria-label": exportLabel, title: exportLabel, onClick: onExport, className: ICON_BTN, children: /* @__PURE__ */ jsx(Download, { className: "h-4 w-4" }) })
1064
1352
  ] })
1065
1353
  ] }) }),
1066
1354
  /* @__PURE__ */ jsx(
@@ -1298,7 +1586,7 @@ function DatePicker({ value, onChange, className, variant = "input", defaultOpen
1298
1586
  )
1299
1587
  ] });
1300
1588
  }
1301
- var useIsomorphicLayoutEffect = typeof window !== "undefined" ? React14.useLayoutEffect : React14.useEffect;
1589
+ var useIsomorphicLayoutEffect = typeof window !== "undefined" ? React16.useLayoutEffect : React16.useEffect;
1302
1590
  function SearchSelect({
1303
1591
  value,
1304
1592
  displayValue,
@@ -1321,18 +1609,18 @@ function SearchSelect({
1321
1609
  disabled
1322
1610
  }) {
1323
1611
  const canCreate = !!onCreate && allowCreate !== false;
1324
- const [open, setOpen] = React14.useState(false);
1325
- const [query, setQuery] = React14.useState("");
1326
- const [results, setResults] = React14.useState([]);
1327
- const [loading, setLoading] = React14.useState(false);
1328
- const [creating, setCreating] = React14.useState(false);
1329
- const [selectedLabel, setSelectedLabel] = React14.useState(displayValue ?? "");
1330
- const containerRef = React14.useRef(null);
1331
- const inputRef = React14.useRef(null);
1332
- const timerRef = React14.useRef();
1333
- const [rect, setRect] = React14.useState(null);
1334
- const dropdownRef = React14.useRef(null);
1335
- React14.useEffect(() => {
1612
+ const [open, setOpen] = React16.useState(false);
1613
+ const [query, setQuery] = React16.useState("");
1614
+ const [results, setResults] = React16.useState([]);
1615
+ const [loading, setLoading] = React16.useState(false);
1616
+ const [creating, setCreating] = React16.useState(false);
1617
+ const [selectedLabel, setSelectedLabel] = React16.useState(displayValue ?? "");
1618
+ const containerRef = React16.useRef(null);
1619
+ const inputRef = React16.useRef(null);
1620
+ const timerRef = React16.useRef();
1621
+ const [rect, setRect] = React16.useState(null);
1622
+ const dropdownRef = React16.useRef(null);
1623
+ React16.useEffect(() => {
1336
1624
  function handler(e) {
1337
1625
  const target = e.target;
1338
1626
  if (containerRef.current?.contains(target)) return;
@@ -1342,10 +1630,10 @@ function SearchSelect({
1342
1630
  document.addEventListener("mousedown", handler);
1343
1631
  return () => document.removeEventListener("mousedown", handler);
1344
1632
  }, []);
1345
- React14.useEffect(() => {
1633
+ React16.useEffect(() => {
1346
1634
  if (displayValue !== void 0) setSelectedLabel(displayValue);
1347
1635
  }, [displayValue]);
1348
- React14.useEffect(() => {
1636
+ React16.useEffect(() => {
1349
1637
  if (open && loadOnOpen && query.length === 0 && results.length === 0 && !loading) {
1350
1638
  setLoading(true);
1351
1639
  Promise.resolve(onSearch("")).then(setResults).catch(() => setResults([])).finally(() => setLoading(false));
@@ -1403,7 +1691,7 @@ function SearchSelect({
1403
1691
  setResults([]);
1404
1692
  setTimeout(() => inputRef.current?.focus(), 0);
1405
1693
  }
1406
- const groups = React14.useMemo(() => {
1694
+ const groups = React16.useMemo(() => {
1407
1695
  const map = /* @__PURE__ */ new Map();
1408
1696
  for (const opt of results) {
1409
1697
  const group = opt.group ?? "";
@@ -1498,7 +1786,7 @@ function SearchSelect({
1498
1786
  /* @__PURE__ */ jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin" }),
1499
1787
  " ",
1500
1788
  searchingLabel
1501
- ] }) : 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(React14.Fragment, { children: [
1789
+ ] }) : 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(React16.Fragment, { children: [
1502
1790
  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 }),
1503
1791
  options.map((opt) => /* @__PURE__ */ jsx(
1504
1792
  "button",
@@ -1560,9 +1848,9 @@ function CurrencyInput({
1560
1848
  className,
1561
1849
  disabled
1562
1850
  }) {
1563
- const inputRef = React14.useRef(null);
1564
- const [focused, setFocused] = React14.useState(false);
1565
- const format = React14.useCallback((v) => {
1851
+ const inputRef = React16.useRef(null);
1852
+ const [focused, setFocused] = React16.useState(false);
1853
+ const format = React16.useCallback((v) => {
1566
1854
  return new Intl.NumberFormat(locale, {
1567
1855
  minimumFractionDigits: 2,
1568
1856
  maximumFractionDigits: 2
@@ -1635,7 +1923,7 @@ function CurrencyInput({
1635
1923
  var Popover = PopoverPrimitive.Root;
1636
1924
  var PopoverTrigger = PopoverPrimitive.Trigger;
1637
1925
  var PopoverAnchor = PopoverPrimitive.Anchor;
1638
- var PopoverContent = React14.forwardRef(({ className, align = "start", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx(
1926
+ var PopoverContent = React16.forwardRef(({ className, align = "start", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx(
1639
1927
  PopoverPrimitive.Content,
1640
1928
  {
1641
1929
  ref,
@@ -1708,7 +1996,7 @@ function renderInline(text, keyPrefix) {
1708
1996
  if (part.startsWith("`") && part.endsWith("`") && part.length > 2) {
1709
1997
  return /* @__PURE__ */ jsx("code", { className: "rounded bg-muted px-1 py-0.5 font-mono text-[0.85em]", children: part.slice(1, -1) }, key);
1710
1998
  }
1711
- return part === "" ? null : /* @__PURE__ */ jsx(React14.Fragment, { children: part }, key);
1999
+ return part === "" ? null : /* @__PURE__ */ jsx(React16.Fragment, { children: part }, key);
1712
2000
  });
1713
2001
  }
1714
2002
  function parseBlocks(source) {
@@ -1792,7 +2080,7 @@ function renderMarkdown(source) {
1792
2080
  case "ol":
1793
2081
  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);
1794
2082
  case "p":
1795
- return /* @__PURE__ */ jsx("p", { children: block.lines.map((l, li) => /* @__PURE__ */ jsxs(React14.Fragment, { children: [
2083
+ return /* @__PURE__ */ jsx("p", { children: block.lines.map((l, li) => /* @__PURE__ */ jsxs(React16.Fragment, { children: [
1796
2084
  li > 0 && /* @__PURE__ */ jsx("br", {}),
1797
2085
  renderInline(l, `${key}-${li}`)
1798
2086
  ] }, `${key}-${li}`)) }, key);
@@ -1813,7 +2101,7 @@ function MarkdownEditor({
1813
2101
  renderPreview,
1814
2102
  className
1815
2103
  }) {
1816
- const [mode, setMode] = React14.useState(
2104
+ const [mode, setMode] = React16.useState(
1817
2105
  defaultMode === "preview" && value.trim() === "" ? "edit" : defaultMode
1818
2106
  );
1819
2107
  return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-2", className), children: [
@@ -2074,6 +2362,6 @@ function SearchCombobox({
2074
2362
  ] });
2075
2363
  }
2076
2364
 
2077
- export { Badge, Breadcrumb, BulkActionBar, ChevronPager, CurrencyInput, DatePicker, FilterChip, Hint, Input, ListView, Markdown, MarkdownEditor, Modal, ModalBody, ModalClose, ModalContent, ModalDescription, ModalFooter, ModalHeader, ModalOverlay, ModalPortal, ModalTitle, ModalTrigger, PhoneField, PhoneLink, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, RefreshButton, SearchCombobox, SearchField, SearchSelect, SegmentedControl, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator2 as Separator, StatTiles, Tabs, TabsContent, TabsList, TabsTrigger, Thumbnail, TimePicker, ToastProvider, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, badgeVariants, formatPhone2 as formatPhone, normalizePhone, renderMarkdown, useRowSelection };
2078
- //# sourceMappingURL=chunk-SLWTKHNY.js.map
2079
- //# sourceMappingURL=chunk-SLWTKHNY.js.map
2365
+ export { Badge, Breadcrumb, BulkActionBar, ChevronPager, CurrencyInput, DatePicker, FilterChip, Hint, Input, ListView, Markdown, MarkdownEditor, Modal, ModalBody, ModalClose, ModalContent, ModalDescription, ModalFooter, ModalHeader, ModalOverlay, ModalPortal, ModalTitle, ModalTrigger, PageActionBar, PhoneField, PhoneLink, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, RefreshButton, RowActions, SearchCombobox, SearchField, SearchSelect, SegmentedControl, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator2 as Separator, StatTiles, Tabs, TabsContent, TabsList, TabsTrigger, Thumbnail, TimePicker, ToastProvider, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, WHATSAPP_BRAND_COLOR, WhatsAppIcon, badgeVariants, formatPhone2 as formatPhone, normalizePhone, renderMarkdown, setActionsMenuLabel, setRowActionsLabel, useRowSelection };
2366
+ //# sourceMappingURL=chunk-SDPYDWWV.js.map
2367
+ //# sourceMappingURL=chunk-SDPYDWWV.js.map