@rendra-ui/web 2.4.0 → 2.5.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 (68) hide show
  1. package/README.md +24 -1
  2. package/dist/base.css +33 -1
  3. package/dist/{button-C6rjowQi.js → button-BzJgR2gH.js} +86 -21
  4. package/dist/button-BzJgR2gH.js.map +1 -0
  5. package/dist/chart.js +61 -15
  6. package/dist/chart.js.map +1 -1
  7. package/dist/cli/auditar.js +1 -1
  8. package/dist/cli/codigos.js +2 -2
  9. package/dist/cli/executar-auditar.js +1 -1
  10. package/dist/cli/help.js +1 -1
  11. package/dist/cli/trocar.js +2 -2
  12. package/dist/cli/typescript-loader.js +1 -1
  13. package/dist/{cn-DXDpTGsu.js → cn-Cw7M5kEP.js} +2 -2
  14. package/dist/{cn-DXDpTGsu.js.map → cn-Cw7M5kEP.js.map} +1 -1
  15. package/dist/{components-hp7iWioq.js → components-DkpspH9h.js} +2 -2
  16. package/dist/{components-hp7iWioq.js.map → components-DkpspH9h.js.map} +1 -1
  17. package/dist/components.css +169 -33
  18. package/dist/document-viewer.js +6 -6
  19. package/dist/document-viewer.js.map +1 -1
  20. package/dist/{empty-state-CdaDLcsB.js → empty-state-Cdb1vkMT.js} +36 -12
  21. package/dist/{empty-state-CdaDLcsB.js.map → empty-state-Cdb1vkMT.js.map} +1 -1
  22. package/dist/features-max--5VEt6M7.js +3 -0
  23. package/dist/index.js +1062 -339
  24. package/dist/index.js.map +1 -1
  25. package/dist/motion-context-5BRIQAJm.js +107 -0
  26. package/dist/motion-context-5BRIQAJm.js.map +1 -0
  27. package/dist/{rendra-provider-7jUgUHzR.js → rendra-provider-CRe0XdOU.js} +9 -5
  28. package/dist/rendra-provider-CRe0XdOU.js.map +1 -0
  29. package/dist/rich-text-editor.js +4 -4
  30. package/dist/router-bridge.js +5 -4
  31. package/dist/router-bridge.js.map +1 -1
  32. package/dist/tokens.css +63 -15
  33. package/dist/tooltip-BAMSaGbS.js +224 -0
  34. package/dist/tooltip-BAMSaGbS.js.map +1 -0
  35. package/dist/types/components/rendra-provider.d.ts +7 -1
  36. package/dist/types/components/rendra-router-bridge.d.ts +3 -1
  37. package/dist/types/components/ui/accordion.d.ts +1 -1
  38. package/dist/types/components/ui/badge.d.ts +1 -1
  39. package/dist/types/components/ui/button.d.ts +1 -1
  40. package/dist/types/components/ui/dropdown-menu.d.ts +5 -5
  41. package/dist/types/components/ui/picker-panel.d.ts +1 -1
  42. package/dist/types/components/ui/popover.d.ts +3 -3
  43. package/dist/types/components/ui/radio-group.d.ts +1 -1
  44. package/dist/types/components/ui/skeleton.d.ts +5 -1
  45. package/dist/types/components/ui/stat-card.d.ts +1 -1
  46. package/dist/types/components/ui/table.d.ts +0 -6
  47. package/dist/types/components/ui/tooltip.d.ts +1 -1
  48. package/dist/types/hooks/use-reduced-motion.d.ts +3 -0
  49. package/dist/types/index.d.ts +1 -0
  50. package/dist/types/lib/motion/count.d.ts +17 -0
  51. package/dist/types/lib/motion/features-max.d.ts +1 -0
  52. package/dist/types/lib/motion/index.d.ts +5 -0
  53. package/dist/types/lib/motion/motion-context.d.ts +43 -0
  54. package/dist/types/lib/motion/native-events.d.ts +16 -0
  55. package/dist/types/lib/motion/presets.d.ts +92 -0
  56. package/dist/types/lib/motion/reorder.d.ts +7 -0
  57. package/dist/types/lib/motion/tokens.d.ts +66 -0
  58. package/dist/types/lib/motion/use-motion-presets.d.ts +8 -0
  59. package/dist/{use-breakpoint-Dyp-0E_c.js → use-breakpoint-O9eqFmsF.js} +2 -2
  60. package/dist/{use-breakpoint-Dyp-0E_c.js.map → use-breakpoint-O9eqFmsF.js.map} +1 -1
  61. package/dist/use-motion-presets-BrkgL8lG.js +401 -0
  62. package/dist/use-motion-presets-BrkgL8lG.js.map +1 -0
  63. package/dist/widget-grid.js +3 -3
  64. package/package.json +3 -1
  65. package/dist/button-C6rjowQi.js.map +0 -1
  66. package/dist/rendra-provider-7jUgUHzR.js.map +0 -1
  67. package/dist/tooltip-bdmbX6vC.js +0 -105
  68. package/dist/tooltip-bdmbX6vC.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,15 +1,18 @@
1
- /*! Rendra Design System v2.4.0 | MIT | © 2026 Bruno Magalhaes | brunomagalhaes.me */
2
- import { t as cn } from "./cn-DXDpTGsu.js";
3
- import { a as catalogByComponent, c as findComponentsWithoutDefault, d as findPresetCollisions, f as getCatalogEntry, i as assertCatalogIntegrity, l as findDuplicateCodes, n as CATALOG_EXCLUDED_FILES, o as filesMissingCatalogEntry, p as resolveCatalogCode, r as COMPONENT_CODE_PATTERN, s as findComponentsWithMultipleDefaults, t as CATALOG, u as findInvalidFormatCodes } from "./components-hp7iWioq.js";
4
- import { i as usePrefersReducedMotion, n as buttonVariants, r as Spinner, t as Button } from "./button-C6rjowQi.js";
5
- import { a as DropdownMenuContent, c as DropdownMenuLabel, d as DropdownMenuSeparator, f as DropdownMenuSub, h as DropdownMenuTrigger, i as DropdownMenuCheckboxItem, l as DropdownMenuRadioGroup, m as DropdownMenuSubTrigger, n as TooltipProvider, o as DropdownMenuGroup, p as DropdownMenuSubContent, r as DropdownMenu, s as DropdownMenuItem, t as Tooltip, u as DropdownMenuRadioItem } from "./tooltip-bdmbX6vC.js";
6
- import { a as BrandContext, i as useBrand, n as BrandFeedbackIcon, r as feedbackLabels, t as EmptyState } from "./empty-state-CdaDLcsB.js";
7
- import { a as useRendraNavigate, i as useRendraLink, n as useCurrentPath, r as useRendraBreadcrumbs, t as RendraProvider } from "./rendra-provider-7jUgUHzR.js";
8
- import { n as useBreakpoint, t as breakpoints } from "./use-breakpoint-Dyp-0E_c.js";
1
+ /*! Rendra Design System v2.5.0 | MIT | © 2026 Bruno Magalhaes | brunomagalhaes.me */
2
+ import { t as cn } from "./cn-Cw7M5kEP.js";
3
+ import { a as getReducedMotion, n as useLayoutReady, o as subscribeReducedMotion, r as useMotionMode, s as usePrefersReducedMotion } from "./motion-context-5BRIQAJm.js";
4
+ import { t as useMotionPresets } from "./use-motion-presets-BrkgL8lG.js";
5
+ import { a as catalogByComponent, c as findComponentsWithoutDefault, d as findPresetCollisions, f as getCatalogEntry, i as assertCatalogIntegrity, l as findDuplicateCodes, n as CATALOG_EXCLUDED_FILES, o as filesMissingCatalogEntry, p as resolveCatalogCode, r as COMPONENT_CODE_PATTERN, s as findComponentsWithMultipleDefaults, t as CATALOG, u as findInvalidFormatCodes } from "./components-DkpspH9h.js";
6
+ import { n as buttonVariants, r as Spinner, t as Button } from "./button-BzJgR2gH.js";
7
+ import { a as DropdownMenuContent, c as DropdownMenuLabel, d as DropdownMenuSeparator, f as DropdownMenuSub, h as DropdownMenuTrigger, i as DropdownMenuCheckboxItem, l as DropdownMenuRadioGroup, m as DropdownMenuSubTrigger, n as TooltipProvider, o as DropdownMenuGroup, p as DropdownMenuSubContent, r as DropdownMenu, s as DropdownMenuItem, t as Tooltip, u as DropdownMenuRadioItem } from "./tooltip-BAMSaGbS.js";
8
+ import { a as BrandContext, i as useBrand, n as BrandFeedbackIcon, r as feedbackLabels, t as EmptyState } from "./empty-state-Cdb1vkMT.js";
9
+ import { a as useRendraNavigate, i as useRendraLink, n as useCurrentPath, r as useRendraBreadcrumbs, t as RendraProvider } from "./rendra-provider-CRe0XdOU.js";
10
+ import { n as useBreakpoint, t as breakpoints } from "./use-breakpoint-O9eqFmsF.js";
9
11
  import { ArrowDown, ArrowDownRight, ArrowLeft, ArrowRight, ArrowRightLeft, ArrowUp, ArrowUpRight, Bell, Bot, CalendarDays, Check, CheckCheck, CheckCircle2, ChevronDown, ChevronLeft, ChevronRight, ChevronsUpDown, Clock, Columns3, Download, EllipsisVertical, Eye, EyeOff, FileText, Film, Filter, Globe, GripVertical, Home, ImageIcon, ImagePlus, Info, LayoutTemplate, LogOut, Mail, MapPin, Menu, MessageCircle, MessagesSquare, Mic, Minus, Monitor, Moon, MoreHorizontal, Palette, PanelLeft, Paperclip, Pause, Pencil, Phone, Play, Plus, Reply, RotateCw, Search, Send, SkipForward, Smartphone, Smile, Star, Sun, Trash2, TriangleAlert, UploadCloud, User, VideoIcon, X, XCircle, Zap } from "lucide-react";
12
+ import { AnimatePresence, animate, m, useDragControls, useMotionValue, useTransform } from "motion/react";
10
13
  import { Accordion as Accordion$1, Avatar as Avatar$1, Checkbox as Checkbox$1, Collapsible, ContextMenu, Dialog, Label as Label$1, NavigationMenu, Popover as Popover$1, Progress as Progress$1, RadioGroup as RadioGroup$1, Slider as Slider$1, Slot, Switch as Switch$1, Tabs as Tabs$1, VisuallyHidden } from "radix-ui";
11
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
12
- import { Fragment as Fragment$1, cloneElement, createContext, forwardRef, isValidElement, useCallback, useContext, useEffect, useId, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
14
+ import { Fragment, cloneElement, createContext, forwardRef, isValidElement, useCallback, useContext, useEffect, useId, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
15
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
13
16
  import { createPortal } from "react-dom";
14
17
  import { cva } from "class-variance-authority";
15
18
  import { addDays, addMonths, addWeeks, differenceInMinutes, endOfMonth, endOfWeek, format, isSameDay, isSameMonth, isToday, isYesterday, startOfDay, startOfMonth, startOfWeek } from "date-fns";
@@ -22,9 +25,119 @@ import { Command } from "cmdk";
22
25
  import { columnFilteringFeature, columnVisibilityFeature, createExpandedRowModel, createFilteredRowModel, createPaginatedRowModel, createSortedRowModel, filterFn_includesString, globalFilteringFeature, rowExpandingFeature, rowPaginationFeature, rowSelectionFeature, rowSortingFeature, sortFn_alphanumeric, sortFn_basic, tableFeatures, useTable } from "@tanstack/react-table";
23
26
  import { Toaster as Toaster$1, toast as toast$1 } from "sonner";
24
27
  import { z } from "zod";
28
+ //#region src/lib/motion/reorder.ts
29
+ function layoutEnabled({ mode, ready, dragging }) {
30
+ return mode === "on" && ready && !dragging;
31
+ }
32
+ //#endregion
33
+ //#region src/lib/motion/count.ts
34
+ var PT_BR = /^([^\d-]*)(-?)(\d{1,3}(?:\.\d{3})+|\d+)(?:,(\d+))?([^\d]*)$/;
35
+ function parseLocaleNumber$1(value) {
36
+ if (typeof value === "number") {
37
+ if (!Number.isFinite(value)) return null;
38
+ const text = String(Math.abs(value));
39
+ if (/e/i.test(text)) return null;
40
+ const decimals = text.includes(".") ? text.split(".")[1].length : 0;
41
+ return {
42
+ prefix: value < 0 ? "-" : "",
43
+ suffix: "",
44
+ value: Math.abs(value),
45
+ decimals,
46
+ grouping: false,
47
+ decimalSeparator: "."
48
+ };
49
+ }
50
+ if (typeof value !== "string") return null;
51
+ const match = PT_BR.exec(value);
52
+ if (!match) return null;
53
+ const [, prefix = "", sign = "", integer = "", fraction = "", suffix = ""] = match;
54
+ const grouping = integer.includes(".");
55
+ const n = Number(`${integer.replace(/\./g, "")}${fraction ? `.${fraction}` : ""}`);
56
+ if (!Number.isFinite(n)) return null;
57
+ return {
58
+ prefix: `${prefix}${sign}`,
59
+ suffix,
60
+ value: n,
61
+ decimals: fraction.length,
62
+ grouping,
63
+ decimalSeparator: ","
64
+ };
65
+ }
66
+ /** Escreve `n` com o mesmo formato do valor original. */
67
+ function formatLike(parsed, n) {
68
+ const [int = "0", frac = ""] = Math.abs(n).toFixed(parsed.decimals).split(".");
69
+ const grouped = parsed.grouping ? int.replace(/\B(?=(\d{3})+(?!\d))/g, ".") : int;
70
+ const number = frac ? `${grouped}${parsed.decimalSeparator}${frac}` : grouped;
71
+ return `${parsed.prefix}${number}${parsed.suffix}`;
72
+ }
73
+ //#endregion
25
74
  //#region src/components/ui/accordion.tsx
26
75
  /** Accordion único, com animação de altura e área de toque de 44px no mobile. */
27
76
  function Accordion({ items, multiple, defaultValue, className }) {
77
+ const motion = useMotionMode();
78
+ const presets = useMotionPresets();
79
+ const [open, setOpen] = useState(multiple ? defaultValue ?? [] : defaultValue?.[0] ? [defaultValue[0]] : []);
80
+ if (motion === "on") {
81
+ const rootProps = multiple ? {
82
+ type: "multiple",
83
+ value: open,
84
+ onValueChange: setOpen
85
+ } : {
86
+ type: "single",
87
+ collapsible: true,
88
+ value: open[0] ?? "",
89
+ onValueChange: (v) => setOpen(v ? [v] : [])
90
+ };
91
+ return /* @__PURE__ */ jsx(Accordion$1.Root, {
92
+ ...rootProps,
93
+ "data-rendra": "ACRN-001",
94
+ className: cn("flex flex-col", className),
95
+ children: items.map((it) => {
96
+ const isOpen = open.includes(it.value);
97
+ return /* @__PURE__ */ jsxs(Accordion$1.Item, {
98
+ value: it.value,
99
+ disabled: it.disabled,
100
+ className: "border-b last:border-b-0",
101
+ children: [/* @__PURE__ */ jsx(Accordion$1.Header, { children: /* @__PURE__ */ jsxs(Accordion$1.Trigger, {
102
+ className: "group flex min-h-touch w-full cursor-pointer items-center justify-between gap-4 py-4 text-left text-sm font-medium transition-colors hover:text-primary-text disabled:cursor-not-allowed disabled:opacity-50 md:min-h-0",
103
+ children: [it.title, /* @__PURE__ */ jsx(m.span, {
104
+ "aria-hidden": true,
105
+ className: "flex shrink-0",
106
+ animate: { rotate: isOpen ? 180 : 0 },
107
+ transition: presets.fade.transition,
108
+ children: /* @__PURE__ */ jsx(ChevronDown, { className: "size-icon-sm text-muted-foreground" })
109
+ })]
110
+ }) }), /* @__PURE__ */ jsx(AnimatePresence, {
111
+ initial: false,
112
+ children: isOpen && /* @__PURE__ */ jsx(Accordion$1.Content, {
113
+ forceMount: true,
114
+ asChild: true,
115
+ children: /* @__PURE__ */ jsx(m.div, {
116
+ className: "overflow-hidden text-sm wrap-break-word text-muted-foreground",
117
+ initial: {
118
+ height: 0,
119
+ opacity: 0
120
+ },
121
+ animate: {
122
+ height: "auto",
123
+ opacity: 1
124
+ },
125
+ exit: {
126
+ height: 0,
127
+ opacity: 0
128
+ },
129
+ transition: presets.fade.transition,
130
+ children: /* @__PURE__ */ jsx("div", {
131
+ className: "pb-4",
132
+ children: it.content
133
+ })
134
+ })
135
+ })
136
+ })]
137
+ }, it.value);
138
+ })
139
+ });
140
+ }
28
141
  const content = items.map((it) => /* @__PURE__ */ jsxs(Accordion$1.Item, {
29
142
  value: it.value,
30
143
  disabled: it.disabled,
@@ -33,10 +146,10 @@ function Accordion({ items, multiple, defaultValue, className }) {
33
146
  className: "group flex min-h-touch w-full cursor-pointer items-center justify-between gap-4 py-4 text-left text-sm font-medium transition-colors hover:text-primary-text disabled:cursor-not-allowed disabled:opacity-50 md:min-h-0",
34
147
  children: [it.title, /* @__PURE__ */ jsx(ChevronDown, {
35
148
  "aria-hidden": true,
36
- className: "size-icon-sm shrink-0 text-muted-foreground transition-transform duration-200 group-data-[state=open]:rotate-180"
149
+ className: "size-icon-sm shrink-0 text-muted-foreground transition-transform duration-(--rendra-duration-base) ease-move group-data-[state=open]:rotate-180"
37
150
  })]
38
151
  }) }), /* @__PURE__ */ jsx(Accordion$1.Content, {
39
- className: "overflow-hidden text-sm text-muted-foreground data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down",
152
+ className: "overflow-hidden text-sm wrap-break-word text-muted-foreground data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down",
40
153
  children: /* @__PURE__ */ jsx("div", {
41
154
  className: "pb-4",
42
155
  children: it.content
@@ -404,7 +517,7 @@ function Breadcrumb({ items, variant = "responsive", className }) {
404
517
  const last = i === items.length - 1;
405
518
  return /* @__PURE__ */ jsxs("li", {
406
519
  className: cn("flex min-w-0 items-center gap-1", !last && "shrink-0 max-sm:max-w-24"),
407
- children: [item.to && !last ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Link, {
520
+ children: [item.to && !last ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Link, {
408
521
  to: item.to,
409
522
  className: "hidden truncate rounded-item transition-colors hover:text-primary-text md:inline",
410
523
  children: item.label
@@ -517,7 +630,7 @@ function OverlayShell({ title, description, icon, children, footer, hideHeader,
517
630
  "aria-hidden": true
518
631
  })
519
632
  });
520
- return /* @__PURE__ */ jsxs(Fragment, { children: [
633
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
521
634
  hideHeader && /* @__PURE__ */ jsx("div", {
522
635
  className: "pointer-events-none absolute inset-x-0 top-0 z-10 flex justify-end px-2 pt-safe md:px-4 md:pt-4",
523
636
  children: closeButton
@@ -533,10 +646,10 @@ function OverlayShell({ title, description, icon, children, footer, hideHeader,
533
646
  /* @__PURE__ */ jsxs("div", {
534
647
  className: "flex min-w-0 flex-1 flex-col gap-1 pt-1",
535
648
  children: [/* @__PURE__ */ jsx(Dialog.Title, {
536
- className: "text-lg font-semibold",
649
+ className: "text-lg font-semibold wrap-break-word",
537
650
  children: title
538
651
  }), description ? /* @__PURE__ */ jsx(Dialog.Description, {
539
- className: "text-sm text-muted-foreground",
652
+ className: "text-sm wrap-break-word text-muted-foreground",
540
653
  children: description
541
654
  }) : /* @__PURE__ */ jsx(Dialog.Description, {
542
655
  className: "sr-only",
@@ -563,6 +676,9 @@ var sizes$1 = {
563
676
  md: "md:max-w-lg",
564
677
  lg: "md:max-w-2xl"
565
678
  };
679
+ var overlayCls$1 = "fixed inset-0 z-50 bg-overlay";
680
+ var overlayOffCls = cn(overlayCls$1, "data-[state=closed]:animate-out data-[state=closed]:duration-(--rendra-duration-fast) data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0");
681
+ var contentCls = cn("fixed inset-0 z-50 flex h-dvh flex-col bg-card text-card-foreground outline-none", "md:inset-auto md:top-1/2 md:left-1/2 md:h-auto md:max-h-sheet md:w-full md:-translate-x-1/2 md:-translate-y-1/2 md:rounded-surface md:border md:shadow-lg");
566
682
  var feedback = {
567
683
  confirm: "info",
568
684
  destructive: "error",
@@ -582,55 +698,85 @@ function Modal({ open, onOpenChange, title, description, type = "confirm", size
582
698
  }
583
699
  };
584
700
  const isForm = type === "form";
701
+ const motion = useMotionMode();
702
+ const presets = useMotionPresets();
703
+ const { isMobile } = useBreakpoint();
704
+ const code = resolveCatalogCode("Modal", { type: type === "destructive" ? "confirm" : type });
705
+ const sizeCls = sizes$1[size];
706
+ const shell = /* @__PURE__ */ jsxs(OverlayShell, {
707
+ title,
708
+ description: isForm ? description : void 0,
709
+ hideHeader: !isForm,
710
+ onRequestClose: close,
711
+ bodyClassName: cn(!isForm && "flex flex-col items-center justify-center gap-4 text-center"),
712
+ footer: /* @__PURE__ */ jsx(ActionBar, {
713
+ primary: {
714
+ label: confirmLabel,
715
+ destructive: type === "destructive",
716
+ loading: busy || loading,
717
+ loadingLabel: `${confirmLabel}...`,
718
+ type: isForm && formId ? "submit" : "button",
719
+ form: isForm ? formId : void 0,
720
+ onClick: isForm && formId ? void 0 : confirm
721
+ },
722
+ cancel: type === "info" && cancelLabel === void 0 ? void 0 : {
723
+ label: cancelLabel ?? "Cancelar",
724
+ onClick: close
725
+ }
726
+ }),
727
+ children: [!isForm && /* @__PURE__ */ jsxs(Fragment$1, { children: [
728
+ /* @__PURE__ */ jsx(BrandFeedbackIcon, {
729
+ type: feedback[type],
730
+ size: "2xl",
731
+ animated: true
732
+ }),
733
+ /* @__PURE__ */ jsxs("div", {
734
+ className: "flex flex-col gap-2",
735
+ children: [/* @__PURE__ */ jsx("p", {
736
+ className: "text-lg font-semibold wrap-anywhere",
737
+ children: title
738
+ }), description && /* @__PURE__ */ jsx("p", {
739
+ className: "text-sm wrap-anywhere text-muted-foreground",
740
+ children: description
741
+ })]
742
+ }),
743
+ children
744
+ ] }), isForm && /* @__PURE__ */ jsx("div", {
745
+ className: "flex flex-col gap-2",
746
+ children
747
+ })]
748
+ });
749
+ if (motion === "on") return /* @__PURE__ */ jsx(Dialog.Root, {
750
+ open,
751
+ onOpenChange,
752
+ children: /* @__PURE__ */ jsx(AnimatePresence, { children: open && /* @__PURE__ */ jsxs(Dialog.Portal, {
753
+ forceMount: true,
754
+ children: [/* @__PURE__ */ jsx(Dialog.Overlay, {
755
+ forceMount: true,
756
+ asChild: true,
757
+ children: /* @__PURE__ */ jsx(m.div, {
758
+ className: overlayCls$1,
759
+ ...presets.fade
760
+ })
761
+ }), /* @__PURE__ */ jsx(Dialog.Content, {
762
+ forceMount: true,
763
+ asChild: true,
764
+ "data-rendra": code,
765
+ className: cn(contentCls, sizeCls),
766
+ children: /* @__PURE__ */ jsx(m.div, {
767
+ ...presets.open(isMobile ? { y: 8 } : void 0),
768
+ children: shell
769
+ })
770
+ })]
771
+ }, "modal") })
772
+ });
585
773
  return /* @__PURE__ */ jsx(Dialog.Root, {
586
774
  open,
587
775
  onOpenChange,
588
- children: /* @__PURE__ */ jsxs(Dialog.Portal, { children: [/* @__PURE__ */ jsx(Dialog.Overlay, { className: "fixed inset-0 z-50 bg-overlay data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0" }), /* @__PURE__ */ jsx(Dialog.Content, {
589
- "data-rendra": resolveCatalogCode("Modal", { type: type === "destructive" ? "confirm" : type }),
590
- className: cn("fixed inset-0 z-50 flex h-dvh flex-col bg-card text-card-foreground outline-none", "md:inset-auto md:top-1/2 md:left-1/2 md:h-auto md:max-h-sheet md:w-full md:-translate-x-1/2 md:-translate-y-1/2 md:rounded-surface md:border md:shadow-lg", "data-[state=open]:animate-in data-[state=open]:fade-in-0 md:data-[state=open]:zoom-in-95", sizes$1[size]),
591
- children: /* @__PURE__ */ jsxs(OverlayShell, {
592
- title,
593
- description: isForm ? description : void 0,
594
- hideHeader: !isForm,
595
- onRequestClose: close,
596
- bodyClassName: cn(!isForm && "flex flex-col items-center justify-center gap-4 text-center"),
597
- footer: /* @__PURE__ */ jsx(ActionBar, {
598
- primary: {
599
- label: confirmLabel,
600
- destructive: type === "destructive",
601
- loading: busy || loading,
602
- loadingLabel: `${confirmLabel}...`,
603
- type: isForm && formId ? "submit" : "button",
604
- form: isForm ? formId : void 0,
605
- onClick: isForm && formId ? void 0 : confirm
606
- },
607
- cancel: type === "info" && cancelLabel === void 0 ? void 0 : {
608
- label: cancelLabel ?? "Cancelar",
609
- onClick: close
610
- }
611
- }),
612
- children: [!isForm && /* @__PURE__ */ jsxs(Fragment, { children: [
613
- /* @__PURE__ */ jsx(BrandFeedbackIcon, {
614
- type: feedback[type],
615
- size: "2xl",
616
- animated: true
617
- }),
618
- /* @__PURE__ */ jsxs("div", {
619
- className: "flex flex-col gap-2",
620
- children: [/* @__PURE__ */ jsx("p", {
621
- className: "text-lg font-semibold",
622
- children: title
623
- }), description && /* @__PURE__ */ jsx("p", {
624
- className: "text-sm text-muted-foreground",
625
- children: description
626
- })]
627
- }),
628
- children
629
- ] }), isForm && /* @__PURE__ */ jsx("div", {
630
- className: "flex flex-col gap-2",
631
- children
632
- })]
633
- })
776
+ children: /* @__PURE__ */ jsxs(Dialog.Portal, { children: [/* @__PURE__ */ jsx(Dialog.Overlay, { className: overlayOffCls }), /* @__PURE__ */ jsx(Dialog.Content, {
777
+ "data-rendra": code,
778
+ className: cn(contentCls, "data-[state=closed]:animate-out data-[state=closed]:duration-(--rendra-duration-fast) data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0 md:data-[state=open]:zoom-in-95", sizeCls),
779
+ children: shell
634
780
  })] })
635
781
  });
636
782
  }
@@ -1105,7 +1251,7 @@ function Calendar({ events, view: viewProp, defaultView = "month", onViewChange,
1105
1251
  " ",
1106
1252
  e.title
1107
1253
  ]
1108
- }) : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
1254
+ }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
1109
1255
  className: "truncate font-medium",
1110
1256
  children: e.title
1111
1257
  }), /* @__PURE__ */ jsx("span", {
@@ -1738,18 +1884,59 @@ var Input = forwardRef(function Input({ size, mask, icon, suffix, clearable, inv
1738
1884
  });
1739
1885
  //#endregion
1740
1886
  //#region src/components/ui/popover.tsx
1741
- var Popover = Popover$1.Root;
1887
+ var PopoverOpenContext = createContext(null);
1888
+ function AnimatedRoot({ open, defaultOpen, onOpenChange, ...rest }) {
1889
+ const [inner, setInner] = useState(defaultOpen ?? false);
1890
+ const current = open ?? inner;
1891
+ return /* @__PURE__ */ jsx(PopoverOpenContext.Provider, {
1892
+ value: current,
1893
+ children: /* @__PURE__ */ jsx(Popover$1.Root, {
1894
+ ...rest,
1895
+ open: current,
1896
+ onOpenChange: (next) => {
1897
+ setInner(next);
1898
+ onOpenChange?.(next);
1899
+ }
1900
+ })
1901
+ });
1902
+ }
1903
+ function Popover(props) {
1904
+ return useMotionMode() === "on" ? /* @__PURE__ */ jsx(AnimatedRoot, { ...props }) : /* @__PURE__ */ jsx(Popover$1.Root, { ...props });
1905
+ }
1742
1906
  var PopoverTrigger = Popover$1.Trigger;
1743
1907
  var PopoverClose = Popover$1.Close;
1744
1908
  var PopoverAnchor = Popover$1.Anchor;
1745
- function PopoverContent({ className, align = "center", sideOffset = 8, width = "md", ...props }) {
1909
+ function PopoverContent({ className, align = "center", sideOffset = 8, width = "md", children, asChild, ...props }) {
1910
+ const open = useContext(PopoverOpenContext);
1911
+ const motion = useMotionMode();
1912
+ const presets = useMotionPresets();
1913
+ const base = cn("z-50 origin-(--radix-popover-content-transform-origin) rounded-surface border bg-popover text-popover-foreground shadow-md outline-none", width === "sm" ? "w-popover-sm" : "w-popover");
1914
+ if (motion === "on" && open !== null && !asChild) return /* @__PURE__ */ jsx(AnimatePresence, { children: open && /* @__PURE__ */ jsx(Popover$1.Portal, {
1915
+ forceMount: true,
1916
+ children: /* @__PURE__ */ jsx(Popover$1.Content, {
1917
+ forceMount: true,
1918
+ asChild: true,
1919
+ align,
1920
+ sideOffset,
1921
+ collisionPadding: 16,
1922
+ "data-rendra": "POP-001",
1923
+ className: cn(base, className),
1924
+ ...props,
1925
+ children: /* @__PURE__ */ jsx(m.div, {
1926
+ ...presets.open(),
1927
+ children
1928
+ })
1929
+ })
1930
+ }, "popover") });
1746
1931
  return /* @__PURE__ */ jsx(Popover$1.Portal, { children: /* @__PURE__ */ jsx(Popover$1.Content, {
1747
1932
  align,
1748
1933
  sideOffset,
1749
1934
  collisionPadding: 16,
1750
1935
  "data-rendra": "POP-001",
1751
- className: cn("z-50 rounded-surface border bg-popover text-popover-foreground shadow-md outline-none", width === "sm" ? "w-popover-sm" : "w-popover", "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", className),
1752
- ...props
1936
+ className: cn(base, "animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:duration-(--rendra-duration-fast) data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95", className),
1937
+ asChild,
1938
+ ...props,
1939
+ children
1753
1940
  }) });
1754
1941
  }
1755
1942
  //#endregion
@@ -2097,7 +2284,7 @@ function Attachments({ files, mine }) {
2097
2284
  function MessageActions({ m, mine, onReply, onReact, onEdit, onDelete, kind }) {
2098
2285
  const Item = kind === "context" ? ContextMenu.Item : DropdownMenuItem;
2099
2286
  const itemClass = kind === "context" ? "flex min-h-touch cursor-pointer items-center gap-2 rounded-item px-3 text-sm outline-none select-none data-[highlighted]:bg-accent md:min-h-0 md:py-2 [&_svg]:size-icon-sm" : void 0;
2100
- return /* @__PURE__ */ jsxs(Fragment, { children: [
2287
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
2101
2288
  /* @__PURE__ */ jsx("div", {
2102
2289
  role: "group",
2103
2290
  "aria-label": "Reagir",
@@ -2114,7 +2301,7 @@ function MessageActions({ m, mine, onReply, onReact, onEdit, onDelete, kind }) {
2114
2301
  onSelect: () => onReply?.(m),
2115
2302
  children: [/* @__PURE__ */ jsx(Reply, { "aria-hidden": true }), " Responder"]
2116
2303
  }),
2117
- mine && !m.deleted && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs(Item, {
2304
+ mine && !m.deleted && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs(Item, {
2118
2305
  className: itemClass,
2119
2306
  onSelect: () => onEdit?.(m),
2120
2307
  children: [/* @__PURE__ */ jsx(Pencil, { "aria-hidden": true }), " Editar"]
@@ -2238,7 +2425,7 @@ function ChatThread({ messages, onReply, onReact, onEdit, onDelete, className })
2238
2425
  }),
2239
2426
  m.replyTo && (() => {
2240
2427
  const quoteClass = cn("flex flex-col rounded-block border-l-4 px-2 py-1 text-left text-xs", mine && !m.deleted ? "border-primary-foreground/60 bg-primary-foreground/15" : "border-primary bg-muted");
2241
- const body = /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
2428
+ const body = /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
2242
2429
  className: "font-semibold",
2243
2430
  children: m.replyTo.author
2244
2431
  }), /* @__PURE__ */ jsx("span", {
@@ -2561,7 +2748,7 @@ function ChatComposer({ onSend, placeholder = "Escreva uma mensagem", disabled,
2561
2748
  }, i))
2562
2749
  })
2563
2750
  ]
2564
- }) : /* @__PURE__ */ jsxs(Fragment, { children: [
2751
+ }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [
2565
2752
  /* @__PURE__ */ jsx(Button, {
2566
2753
  variant: "ghost",
2567
2754
  iconOnly: true,
@@ -2641,7 +2828,7 @@ function ChatComposer({ onSend, placeholder = "Escreva uma mensagem", disabled,
2641
2828
  className: "@max-xl:hidden",
2642
2829
  children: /* @__PURE__ */ jsx(Mic, {})
2643
2830
  })
2644
- ] }), recording ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Button, {
2831
+ ] }), recording ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Button, {
2645
2832
  variant: "ghost",
2646
2833
  iconOnly: true,
2647
2834
  "aria-label": "Cancelar gravação",
@@ -2652,7 +2839,7 @@ function ChatComposer({ onSend, placeholder = "Escreva uma mensagem", disabled,
2652
2839
  "aria-label": "Enviar áudio",
2653
2840
  onClick: () => stopRecording(true),
2654
2841
  children: /* @__PURE__ */ jsx(Send, {})
2655
- })] }) : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Button, {
2842
+ })] }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Button, {
2656
2843
  iconOnly: true,
2657
2844
  "aria-label": "Enviar",
2658
2845
  disabled: disabled || !text.trim() && !files.length,
@@ -2797,7 +2984,7 @@ function QuickReplyList({ items, onPick }) {
2797
2984
  const [q, setQ] = useState("");
2798
2985
  const term = q.trim().toLowerCase();
2799
2986
  const list = term ? items.filter((i) => `${i.title} ${i.text}`.toLowerCase().includes(term)) : items;
2800
- return /* @__PURE__ */ jsxs(Fragment, { children: [
2987
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
2801
2988
  /* @__PURE__ */ jsx("span", {
2802
2989
  className: "px-2 pt-1 text-xs font-semibold",
2803
2990
  children: "Mensagens rápidas"
@@ -2842,29 +3029,60 @@ function QuickReplyList({ items, onPick }) {
2842
3029
  function Checkbox({ checked, defaultChecked, onCheckedChange, label, description, disabled, invalid, id, name, className, ...aria }) {
2843
3030
  const auto = useId();
2844
3031
  const cid = id ?? `cb${auto}`;
2845
- const box = /* @__PURE__ */ jsx(Checkbox$1.Root, {
3032
+ const on = useMotionMode() === "on";
3033
+ const presets = useMotionPresets();
3034
+ const [inner, setInner] = useState(defaultChecked ?? false);
3035
+ const state = checked ?? inner;
3036
+ const mark = checked === "indeterminate" ? /* @__PURE__ */ jsx(Minus, {
3037
+ className: "size-3",
3038
+ strokeWidth: 3,
3039
+ "aria-hidden": true
3040
+ }) : /* @__PURE__ */ jsx(Check, {
3041
+ className: "size-3",
3042
+ strokeWidth: 3,
3043
+ "aria-hidden": true
3044
+ });
3045
+ const rootProps = {
2846
3046
  id: cid,
2847
3047
  name,
2848
- checked,
2849
- defaultChecked,
2850
- onCheckedChange: (v) => onCheckedChange?.(v === true),
3048
+ checked: on ? state : checked,
3049
+ defaultChecked: on ? void 0 : defaultChecked,
3050
+ onCheckedChange: (v) => {
3051
+ if (on) setInner(v);
3052
+ onCheckedChange?.(v === true);
3053
+ },
2851
3054
  disabled,
2852
3055
  "aria-invalid": invalid || void 0,
2853
3056
  "aria-label": aria["aria-label"],
2854
3057
  "data-touch": label ? void 0 : "expanded",
2855
- className: cn("peer relative flex size-icon-md shrink-0 cursor-pointer items-center justify-center rounded-item border border-input bg-card transition-colors", "hover:border-primary data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground data-[state=indeterminate]:border-primary data-[state=indeterminate]:bg-primary data-[state=indeterminate]:text-primary-foreground", "disabled:cursor-not-allowed disabled:opacity-50", invalid && "border-destructive", !label && "before:absolute before:-inset-3 md:before:hidden"),
2856
- children: /* @__PURE__ */ jsx(Checkbox$1.Indicator, {
2857
- className: "flex items-center justify-center data-[state=checked]:animate-in data-[state=checked]:zoom-in-50",
2858
- children: checked === "indeterminate" ? /* @__PURE__ */ jsx(Minus, {
2859
- className: "size-3",
2860
- strokeWidth: 3,
2861
- "aria-hidden": true
2862
- }) : /* @__PURE__ */ jsx(Check, {
2863
- className: "size-3",
2864
- strokeWidth: 3,
2865
- "aria-hidden": true
3058
+ className: cn("peer relative flex size-icon-md shrink-0 cursor-pointer items-center justify-center rounded-item border border-input bg-card transition-colors", "hover:border-primary data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground data-[state=indeterminate]:border-primary data-[state=indeterminate]:bg-primary data-[state=indeterminate]:text-primary-foreground", "disabled:cursor-not-allowed disabled:opacity-50", invalid && "border-destructive", !label && "before:absolute before:-inset-3 md:before:hidden")
3059
+ };
3060
+ const box = on ? /* @__PURE__ */ jsx(Checkbox$1.Root, {
3061
+ asChild: true,
3062
+ ...rootProps,
3063
+ children: /* @__PURE__ */ jsx(m.button, {
3064
+ type: "button",
3065
+ whileTap: presets.press.whileTap,
3066
+ transition: presets.press.transition,
3067
+ children: /* @__PURE__ */ jsx(AnimatePresence, {
3068
+ initial: false,
3069
+ children: state !== false && /* @__PURE__ */ jsx(Checkbox$1.Indicator, {
3070
+ forceMount: true,
3071
+ asChild: true,
3072
+ children: /* @__PURE__ */ jsx(m.span, {
3073
+ className: "flex items-center justify-center",
3074
+ ...presets.indicator,
3075
+ children: mark
3076
+ })
3077
+ })
2866
3078
  })
2867
3079
  })
3080
+ }) : /* @__PURE__ */ jsx(Checkbox$1.Root, {
3081
+ ...rootProps,
3082
+ children: /* @__PURE__ */ jsx(Checkbox$1.Indicator, {
3083
+ className: "flex items-center justify-center data-[state=checked]:animate-in data-[state=checked]:duration-(--rendra-duration-fast) data-[state=checked]:zoom-in-90",
3084
+ children: mark
3085
+ })
2868
3086
  });
2869
3087
  if (!label) return /* @__PURE__ */ jsx("span", {
2870
3088
  "data-rendra": "CHK-001",
@@ -3265,6 +3483,89 @@ function applyPalette(seeds, doc = document) {
3265
3483
  }
3266
3484
  //#endregion
3267
3485
  //#region src/components/ui/picker-panel.tsx
3486
+ /** A folha fecha se o arraste passou de 40% da altura ou se foi um arremesso (> 0,11 px/ms). */
3487
+ var DISMISS_FRACTION = .4;
3488
+ var DISMISS_VELOCITY = 110;
3489
+ /**
3490
+ * A folha do celular em `on`: entra de baixo, acompanha o dedo (arraste vertical pela alça, com
3491
+ * fricção ao puxar para cima), fecha por distância ou por arremesso e, se o dedo solta antes
3492
+ * disso, volta à origem com a mola da folha (a velocidade do dedo entra na mola, sem costura). O
3493
+ * fundo escurecido acompanha a distância. Só a alça arrasta: o corpo rola sem disputar o gesto.
3494
+ * Nenhum valor passa por `style`: o Motion guarda a posição do arraste, e o escurecimento do
3495
+ * fundo é gravado direto no elemento (sem render por quadro).
3496
+ */
3497
+ function MobileSheet({ open, onOpenChange, trigger, adornment, head, rest }) {
3498
+ const presets = useMotionPresets();
3499
+ const ready = useLayoutReady();
3500
+ const controls = useDragControls();
3501
+ const sheetRef = useRef(null);
3502
+ const dimRef = useRef(null);
3503
+ const height = useRef(1);
3504
+ return /* @__PURE__ */ jsxs(Dialog.Root, {
3505
+ open,
3506
+ onOpenChange,
3507
+ children: [/* @__PURE__ */ jsx(Anchor, {
3508
+ adornment,
3509
+ children: /* @__PURE__ */ jsx(Dialog.Trigger, {
3510
+ asChild: true,
3511
+ children: trigger
3512
+ })
3513
+ }), /* @__PURE__ */ jsx(AnimatePresence, { children: open && /* @__PURE__ */ jsxs(Dialog.Portal, {
3514
+ forceMount: true,
3515
+ children: [/* @__PURE__ */ jsx(Dialog.Overlay, {
3516
+ forceMount: true,
3517
+ asChild: true,
3518
+ children: /* @__PURE__ */ jsx(m.div, {
3519
+ className: "fixed inset-0 z-40",
3520
+ ...presets.fade,
3521
+ children: /* @__PURE__ */ jsx("div", {
3522
+ ref: dimRef,
3523
+ className: "absolute inset-0 bg-overlay"
3524
+ })
3525
+ })
3526
+ }), /* @__PURE__ */ jsx(Dialog.Content, {
3527
+ forceMount: true,
3528
+ asChild: true,
3529
+ "aria-describedby": void 0,
3530
+ className: "fixed inset-x-0 bottom-0 z-50 flex max-h-sheet flex-col rounded-t-surface border-t bg-popover text-popover-foreground shadow-lg outline-none",
3531
+ children: /* @__PURE__ */ jsxs(m.div, {
3532
+ ref: sheetRef,
3533
+ ...presets.sheet("bottom"),
3534
+ drag: ready ? "y" : false,
3535
+ dragControls: controls,
3536
+ dragListener: false,
3537
+ dragConstraints: { top: 0 },
3538
+ dragElastic: {
3539
+ top: .2,
3540
+ bottom: 0
3541
+ },
3542
+ dragSnapToOrigin: true,
3543
+ dragTransition: presets.sheetBounce,
3544
+ onDragStart: () => {
3545
+ height.current = sheetRef.current?.offsetHeight || 1;
3546
+ },
3547
+ onDrag: (_, info) => {
3548
+ const dim = dimRef.current;
3549
+ if (dim) dim.style.opacity = String(1 - Math.min(1, Math.max(0, info.offset.y / height.current)));
3550
+ },
3551
+ onDragEnd: (_, info) => {
3552
+ if (info.offset.y > height.current * DISMISS_FRACTION || info.velocity.y > DISMISS_VELOCITY) {
3553
+ onOpenChange(false);
3554
+ return;
3555
+ }
3556
+ if (dimRef.current) animate(dimRef.current, { opacity: 1 }, presets.springSheet);
3557
+ },
3558
+ children: [/* @__PURE__ */ jsx("div", {
3559
+ "data-sheet-handle": true,
3560
+ onPointerDown: (e) => controls.start(e),
3561
+ className: "touch-none",
3562
+ children: head
3563
+ }), rest]
3564
+ })
3565
+ })]
3566
+ }, "sheet") })]
3567
+ });
3568
+ }
3268
3569
  function Anchor({ adornment, children }) {
3269
3570
  if (!adornment) return children;
3270
3571
  return /* @__PURE__ */ jsxs("div", {
@@ -3274,6 +3575,92 @@ function Anchor({ adornment, children }) {
3274
3575
  }
3275
3576
  function PickerPanel({ open, onOpenChange, trigger, title, header, children, footer, width = "trigger", adornment, align = "start" }) {
3276
3577
  const { isMobile } = useBreakpoint();
3578
+ const motion = useMotionMode();
3579
+ const presets = useMotionPresets();
3580
+ const on = motion === "on";
3581
+ const sheetHead = /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("div", {
3582
+ className: "flex shrink-0 flex-col items-center pt-2",
3583
+ children: /* @__PURE__ */ jsx("span", {
3584
+ "aria-hidden": true,
3585
+ className: "h-1 w-12 rounded-full bg-border"
3586
+ })
3587
+ }), /* @__PURE__ */ jsxs("div", {
3588
+ className: "flex shrink-0 items-center justify-between gap-2 pr-2 pl-4",
3589
+ children: [/* @__PURE__ */ jsx(Dialog.Title, {
3590
+ className: "truncate text-base font-semibold",
3591
+ children: title
3592
+ }), /* @__PURE__ */ jsx(Dialog.Close, {
3593
+ "aria-label": "Fechar",
3594
+ className: "flex size-touch items-center justify-center rounded-item text-muted-foreground hover:bg-accent",
3595
+ children: /* @__PURE__ */ jsx(X, {
3596
+ className: "size-icon-md",
3597
+ "aria-hidden": true
3598
+ })
3599
+ })]
3600
+ })] });
3601
+ const sheetRest = /* @__PURE__ */ jsxs(Fragment$1, { children: [
3602
+ header && /* @__PURE__ */ jsx("div", {
3603
+ className: "shrink-0 border-b px-4 pb-3",
3604
+ children: header
3605
+ }),
3606
+ /* @__PURE__ */ jsx("div", {
3607
+ className: "min-h-0 flex-1 overflow-y-auto overscroll-contain p-2",
3608
+ children
3609
+ }),
3610
+ footer && /* @__PURE__ */ jsx("div", {
3611
+ className: "shrink-0 border-t px-4 pt-3 pb-safe",
3612
+ children: footer
3613
+ })
3614
+ ] });
3615
+ const sheetBody = /* @__PURE__ */ jsxs(Fragment$1, { children: [sheetHead, sheetRest] });
3616
+ const panelCls = cn("z-50 flex max-h-command origin-(--radix-popover-content-transform-origin) flex-col overflow-hidden rounded-surface border bg-popover text-popover-foreground shadow-md outline-none", width === "trigger" ? "w-trigger max-w-popover" : "w-auto max-w-popover md:max-w-none");
3617
+ const panelBody = /* @__PURE__ */ jsxs(Fragment$1, { children: [
3618
+ header && /* @__PURE__ */ jsx("div", {
3619
+ className: "shrink-0 border-b p-2",
3620
+ children: header
3621
+ }),
3622
+ /* @__PURE__ */ jsx("div", {
3623
+ className: "min-h-0 flex-1 overflow-y-auto overscroll-contain p-1",
3624
+ children
3625
+ }),
3626
+ footer && /* @__PURE__ */ jsx("div", {
3627
+ className: "shrink-0 border-t p-2",
3628
+ children: footer
3629
+ })
3630
+ ] });
3631
+ if (on && isMobile) return /* @__PURE__ */ jsx(MobileSheet, {
3632
+ open,
3633
+ onOpenChange,
3634
+ trigger,
3635
+ adornment,
3636
+ head: sheetHead,
3637
+ rest: sheetRest
3638
+ });
3639
+ if (on) return /* @__PURE__ */ jsxs(Popover$1.Root, {
3640
+ open,
3641
+ onOpenChange,
3642
+ children: [/* @__PURE__ */ jsx(Anchor, {
3643
+ adornment,
3644
+ children: /* @__PURE__ */ jsx(Popover$1.Trigger, {
3645
+ asChild: true,
3646
+ children: trigger
3647
+ })
3648
+ }), /* @__PURE__ */ jsx(AnimatePresence, { children: open && /* @__PURE__ */ jsx(Popover$1.Portal, {
3649
+ forceMount: true,
3650
+ children: /* @__PURE__ */ jsx(Popover$1.Content, {
3651
+ forceMount: true,
3652
+ asChild: true,
3653
+ align,
3654
+ sideOffset: 6,
3655
+ collisionPadding: 16,
3656
+ className: panelCls,
3657
+ children: /* @__PURE__ */ jsx(m.div, {
3658
+ ...presets.open(),
3659
+ children: panelBody
3660
+ })
3661
+ })
3662
+ }, "panel") })]
3663
+ });
3277
3664
  if (isMobile) return /* @__PURE__ */ jsxs(Dialog.Root, {
3278
3665
  open,
3279
3666
  onOpenChange,
@@ -3283,44 +3670,10 @@ function PickerPanel({ open, onOpenChange, trigger, title, header, children, foo
3283
3670
  asChild: true,
3284
3671
  children: trigger
3285
3672
  })
3286
- }), /* @__PURE__ */ jsxs(Dialog.Portal, { children: [/* @__PURE__ */ jsx(Dialog.Overlay, { className: "fixed inset-0 z-40 bg-overlay data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0" }), /* @__PURE__ */ jsxs(Dialog.Content, {
3673
+ }), /* @__PURE__ */ jsxs(Dialog.Portal, { children: [/* @__PURE__ */ jsx(Dialog.Overlay, { className: "fixed inset-0 z-40 bg-overlay data-[state=closed]:animate-out data-[state=closed]:duration-(--rendra-duration-fast) data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0" }), /* @__PURE__ */ jsx(Dialog.Content, {
3287
3674
  "aria-describedby": void 0,
3288
- className: "fixed inset-x-0 bottom-0 z-50 flex max-h-sheet flex-col rounded-t-surface border-t bg-popover text-popover-foreground shadow-lg outline-none data-[state=closed]:animate-out data-[state=closed]:slide-out-to-bottom data-[state=open]:animate-in data-[state=open]:slide-in-from-bottom",
3289
- children: [
3290
- /* @__PURE__ */ jsx("div", {
3291
- className: "flex shrink-0 flex-col items-center pt-2",
3292
- children: /* @__PURE__ */ jsx("span", {
3293
- "aria-hidden": true,
3294
- className: "h-1 w-12 rounded-full bg-border"
3295
- })
3296
- }),
3297
- /* @__PURE__ */ jsxs("div", {
3298
- className: "flex shrink-0 items-center justify-between gap-2 pr-2 pl-4",
3299
- children: [/* @__PURE__ */ jsx(Dialog.Title, {
3300
- className: "truncate text-base font-semibold",
3301
- children: title
3302
- }), /* @__PURE__ */ jsx(Dialog.Close, {
3303
- "aria-label": "Fechar",
3304
- className: "flex size-touch items-center justify-center rounded-item text-muted-foreground hover:bg-accent",
3305
- children: /* @__PURE__ */ jsx(X, {
3306
- className: "size-icon-md",
3307
- "aria-hidden": true
3308
- })
3309
- })]
3310
- }),
3311
- header && /* @__PURE__ */ jsx("div", {
3312
- className: "shrink-0 border-b px-4 pb-3",
3313
- children: header
3314
- }),
3315
- /* @__PURE__ */ jsx("div", {
3316
- className: "min-h-0 flex-1 overflow-y-auto overscroll-contain p-2",
3317
- children
3318
- }),
3319
- footer && /* @__PURE__ */ jsx("div", {
3320
- className: "shrink-0 border-t px-4 pt-3 pb-safe",
3321
- children: footer
3322
- })
3323
- ]
3675
+ className: "fixed inset-x-0 bottom-0 z-50 flex max-h-sheet flex-col rounded-t-surface border-t bg-popover text-popover-foreground shadow-lg outline-none data-[state=closed]:animate-out data-[state=closed]:duration-(--rendra-duration-fast) data-[state=closed]:slide-out-to-bottom data-[state=open]:animate-in data-[state=open]:slide-in-from-bottom",
3676
+ children: sheetBody
3324
3677
  })] })]
3325
3678
  });
3326
3679
  return /* @__PURE__ */ jsxs(Popover$1.Root, {
@@ -3332,25 +3685,12 @@ function PickerPanel({ open, onOpenChange, trigger, title, header, children, foo
3332
3685
  asChild: true,
3333
3686
  children: trigger
3334
3687
  })
3335
- }), /* @__PURE__ */ jsx(Popover$1.Portal, { children: /* @__PURE__ */ jsxs(Popover$1.Content, {
3688
+ }), /* @__PURE__ */ jsx(Popover$1.Portal, { children: /* @__PURE__ */ jsx(Popover$1.Content, {
3336
3689
  align,
3337
3690
  sideOffset: 6,
3338
3691
  collisionPadding: 16,
3339
- className: cn("z-50 flex max-h-command flex-col overflow-hidden rounded-surface border bg-popover text-popover-foreground shadow-md outline-none", "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95", width === "trigger" ? "w-trigger max-w-popover" : "w-auto max-w-popover md:max-w-none"),
3340
- children: [
3341
- header && /* @__PURE__ */ jsx("div", {
3342
- className: "shrink-0 border-b p-2",
3343
- children: header
3344
- }),
3345
- /* @__PURE__ */ jsx("div", {
3346
- className: "min-h-0 flex-1 overflow-y-auto overscroll-contain p-1",
3347
- children
3348
- }),
3349
- footer && /* @__PURE__ */ jsx("div", {
3350
- className: "shrink-0 border-t p-2",
3351
- children: footer
3352
- })
3353
- ]
3692
+ className: cn("z-50 flex max-h-command origin-(--radix-popover-content-transform-origin) flex-col overflow-hidden rounded-surface border bg-popover text-popover-foreground shadow-md outline-none", "data-[state=closed]:animate-out data-[state=closed]:duration-(--rendra-duration-fast) data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95", width === "trigger" ? "w-trigger max-w-popover" : "w-auto max-w-popover md:max-w-none"),
3693
+ children: panelBody
3354
3694
  }) })]
3355
3695
  });
3356
3696
  }
@@ -3461,35 +3801,57 @@ var sizes = {
3461
3801
  lg: "md:w-sheet-50",
3462
3802
  xl: "md:w-sheet-75"
3463
3803
  };
3804
+ var overlayCls = "fixed inset-0 z-50 bg-overlay";
3805
+ var panelCls = "fixed inset-y-0 right-0 z-50 flex h-dvh w-full flex-col bg-card text-card-foreground shadow-lg outline-none md:border-l";
3464
3806
  function Drawer({ open, onOpenChange, title, description, icon, size = "30", children, footer, dirty, discardTitle = "Descartar alterações?", discardDescription = "As informações preenchidas neste painel serão perdidas." }) {
3465
3807
  const [confirming, setConfirming] = useState(false);
3466
3808
  const requestClose = () => dirty ? setConfirming(true) : onOpenChange(false);
3467
- return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Dialog.Root, {
3809
+ const motion = useMotionMode();
3810
+ const presets = useMotionPresets();
3811
+ const keepOpenIfDirty = (e) => {
3812
+ if (dirty) {
3813
+ e.preventDefault();
3814
+ setConfirming(true);
3815
+ }
3816
+ };
3817
+ const shell = /* @__PURE__ */ jsx(OverlayShell, {
3818
+ title,
3819
+ description,
3820
+ icon,
3821
+ footer,
3822
+ onRequestClose: requestClose,
3823
+ children
3824
+ });
3825
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Dialog.Root, {
3468
3826
  open,
3469
3827
  onOpenChange: (o) => o ? onOpenChange(true) : requestClose(),
3470
- children: /* @__PURE__ */ jsxs(Dialog.Portal, { children: [/* @__PURE__ */ jsx(Dialog.Overlay, { className: "fixed inset-0 z-50 bg-overlay data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0" }), /* @__PURE__ */ jsx(Dialog.Content, {
3471
- onEscapeKeyDown: (e) => {
3472
- if (dirty) {
3473
- e.preventDefault();
3474
- setConfirming(true);
3475
- }
3476
- },
3477
- onPointerDownOutside: (e) => {
3478
- if (dirty) {
3479
- e.preventDefault();
3480
- setConfirming(true);
3481
- }
3482
- },
3828
+ children: motion === "on" ? /* @__PURE__ */ jsx(AnimatePresence, { children: open && /* @__PURE__ */ jsxs(Dialog.Portal, {
3829
+ forceMount: true,
3830
+ children: [/* @__PURE__ */ jsx(Dialog.Overlay, {
3831
+ forceMount: true,
3832
+ asChild: true,
3833
+ children: /* @__PURE__ */ jsx(m.div, {
3834
+ className: overlayCls,
3835
+ ...presets.fade
3836
+ })
3837
+ }), /* @__PURE__ */ jsx(Dialog.Content, {
3838
+ forceMount: true,
3839
+ asChild: true,
3840
+ onEscapeKeyDown: keepOpenIfDirty,
3841
+ onPointerDownOutside: keepOpenIfDirty,
3842
+ "data-rendra": "GAV-001",
3843
+ className: cn(panelCls, sizes[size]),
3844
+ children: /* @__PURE__ */ jsx(m.div, {
3845
+ ...presets.sheet("right"),
3846
+ children: shell
3847
+ })
3848
+ })]
3849
+ }, "drawer") }) : /* @__PURE__ */ jsxs(Dialog.Portal, { children: [/* @__PURE__ */ jsx(Dialog.Overlay, { className: cn(overlayCls, "data-[state=closed]:animate-out data-[state=closed]:duration-(--rendra-duration-fast) data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0") }), /* @__PURE__ */ jsx(Dialog.Content, {
3850
+ onEscapeKeyDown: keepOpenIfDirty,
3851
+ onPointerDownOutside: keepOpenIfDirty,
3483
3852
  "data-rendra": "GAV-001",
3484
- className: cn("fixed inset-y-0 right-0 z-50 flex h-dvh w-full flex-col bg-card text-card-foreground shadow-lg outline-none md:border-l", "data-[state=closed]:animate-out data-[state=closed]:slide-out-to-right data-[state=open]:animate-in data-[state=open]:slide-in-from-right", sizes[size]),
3485
- children: /* @__PURE__ */ jsx(OverlayShell, {
3486
- title,
3487
- description,
3488
- icon,
3489
- footer,
3490
- onRequestClose: requestClose,
3491
- children
3492
- })
3853
+ className: cn(panelCls, "data-[state=closed]:animate-out data-[state=closed]:duration-(--rendra-duration-fast) data-[state=closed]:slide-out-to-right data-[state=open]:animate-in data-[state=open]:slide-in-from-right", sizes[size]),
3854
+ children: shell
3493
3855
  })] })
3494
3856
  }), /* @__PURE__ */ jsx(Modal, {
3495
3857
  open: confirming,
@@ -3508,7 +3870,41 @@ function Drawer({ open, onOpenChange, title, description, icon, size = "30", chi
3508
3870
  function Switch({ checked, defaultChecked, onCheckedChange, label, description, disabled, id, name, className, ...aria }) {
3509
3871
  const auto = useId();
3510
3872
  const sid = id ?? `sw${auto}`;
3511
- const control = /* @__PURE__ */ jsx(Switch$1.Root, {
3873
+ const motion = useMotionMode();
3874
+ const presets = useMotionPresets();
3875
+ const rootCls = "relative inline-flex h-6 w-12 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent bg-input transition-colors disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary max-md:before:absolute max-md:before:-inset-3";
3876
+ const thumbCls = cn("pointer-events-none block size-icon-md rounded-full bg-card shadow-sm duration-(--rendra-duration-base) ease-move data-[state=checked]:translate-x-6", motion === "on" ? "transition-[translate]" : "transition-transform");
3877
+ const tap = presets.tap;
3878
+ const control = motion === "on" ? /* @__PURE__ */ jsx(Switch$1.Root, {
3879
+ asChild: true,
3880
+ id: sid,
3881
+ name,
3882
+ checked,
3883
+ defaultChecked,
3884
+ onCheckedChange,
3885
+ disabled,
3886
+ "aria-label": aria["aria-label"],
3887
+ "data-touch": "expanded",
3888
+ "data-rendra": "SWT-001",
3889
+ children: /* @__PURE__ */ jsx(m.button, {
3890
+ type: "button",
3891
+ className: rootCls,
3892
+ initial: "rest",
3893
+ animate: "rest",
3894
+ whileTap: tap ? "tap" : void 0,
3895
+ children: /* @__PURE__ */ jsx(Switch$1.Thumb, {
3896
+ asChild: true,
3897
+ children: /* @__PURE__ */ jsx(m.span, {
3898
+ className: thumbCls,
3899
+ variants: {
3900
+ rest: { scale: 1 },
3901
+ tap: { scale: tap ? 1.15 : 1 }
3902
+ },
3903
+ transition: presets.press.transition
3904
+ })
3905
+ })
3906
+ })
3907
+ }) : /* @__PURE__ */ jsx(Switch$1.Root, {
3512
3908
  id: sid,
3513
3909
  name,
3514
3910
  checked,
@@ -3518,8 +3914,8 @@ function Switch({ checked, defaultChecked, onCheckedChange, label, description,
3518
3914
  "aria-label": aria["aria-label"],
3519
3915
  "data-touch": "expanded",
3520
3916
  "data-rendra": "SWT-001",
3521
- className: "relative inline-flex h-6 w-12 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent bg-input transition-colors disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary max-md:before:absolute max-md:before:-inset-3",
3522
- children: /* @__PURE__ */ jsx(Switch$1.Thumb, { className: "pointer-events-none block size-icon-md rounded-full bg-card shadow-sm transition-transform duration-200 ease-out data-[state=checked]:translate-x-6" })
3917
+ className: rootCls,
3918
+ children: /* @__PURE__ */ jsx(Switch$1.Thumb, { className: thumbCls })
3523
3919
  });
3524
3920
  if (!label) return control;
3525
3921
  return /* @__PURE__ */ jsxs("label", {
@@ -3586,7 +3982,7 @@ function DataToolbar({ search, filters, filterCount = 0, onClearFilters, chips =
3586
3982
  "aria-label": search.placeholder ?? "Buscar",
3587
3983
  type: "search",
3588
3984
  className: "md:w-3xs lg:w-sm"
3589
- }), isMobile ? /* @__PURE__ */ jsxs(Fragment, { children: [(hasPanel || primaryAction) && /* @__PURE__ */ jsxs("div", {
3985
+ }), isMobile ? /* @__PURE__ */ jsxs(Fragment$1, { children: [(hasPanel || primaryAction) && /* @__PURE__ */ jsxs("div", {
3590
3986
  className: cn("grid gap-3", hasPanel && primaryAction ? "grid-actions-2" : "grid-cols-1"),
3591
3987
  children: [hasPanel && filterButton(() => setDrawer(true)), primaryAction]
3592
3988
  }), actions && /* @__PURE__ */ jsx("div", {
@@ -4352,7 +4748,7 @@ var Select = forwardRef(function Select(props, ref) {
4352
4748
  }),
4353
4749
  /* @__PURE__ */ jsx(ChevronDown, {
4354
4750
  "aria-hidden": true,
4355
- className: cn("size-icon-sm shrink-0 text-muted-foreground transition-transform duration-200", open && "rotate-180")
4751
+ className: cn("size-icon-sm shrink-0 text-muted-foreground transition-transform duration-(--rendra-duration-base) ease-move", open && "rotate-180")
4356
4752
  })
4357
4753
  ]
4358
4754
  });
@@ -4500,6 +4896,8 @@ var Select = forwardRef(function Select(props, ref) {
4500
4896
  });
4501
4897
  //#endregion
4502
4898
  //#region src/components/ui/tabs.tsx
4899
+ /** Contador de instâncias, só para o `layoutId` do indicador (ver `indicatorId`). */
4900
+ var tabsCreated = 0;
4503
4901
  /**
4504
4902
  * Tabs único. Se as abas não couberem na largura, a mesma lista vira um Select
4505
4903
  * (nunca rolagem lateral). A troca é medida no próprio contêiner, não na tela.
@@ -4524,9 +4922,48 @@ function Tabs({ items, value, defaultValue, onChange, variant = "line", classNam
4524
4922
  ro.observe(box);
4525
4923
  return () => ro.disconnect();
4526
4924
  }, [items, variant]);
4527
- const trigger = cn("inline-flex min-h-touch shrink-0 cursor-pointer items-center justify-center gap-2 px-3 text-sm font-medium whitespace-nowrap transition-colors outline-none disabled:cursor-not-allowed disabled:opacity-50 md:min-h-0 [&_svg]:size-icon-sm", variant === "line" ? "-mb-px border-b-2 border-transparent py-3 text-muted-foreground hover:text-foreground data-[state=active]:border-primary data-[state=active]:text-foreground" : "rounded-item py-2 text-muted-foreground hover:bg-card/60 hover:text-foreground data-[state=active]:bg-card data-[state=active]:text-foreground data-[state=active]:shadow-sm");
4925
+ const presets = useMotionPresets();
4926
+ const on = useLayoutReady();
4927
+ const listRef = useRef(null);
4928
+ const [clip, setClip] = useState({
4929
+ l: 0,
4930
+ r: 0
4931
+ });
4932
+ useLayoutEffect(() => {
4933
+ const list = listRef.current;
4934
+ if (!on || !list) return;
4935
+ const measure = () => {
4936
+ const active = list.querySelector("[role=\"tab\"][data-state=\"active\"]");
4937
+ if (!active) return;
4938
+ const l = active.offsetLeft;
4939
+ const r = list.offsetWidth - l - active.offsetWidth;
4940
+ setClip((prev) => prev.l === l && prev.r === r ? prev : {
4941
+ l,
4942
+ r
4943
+ });
4944
+ };
4945
+ measure();
4946
+ const ro = new ResizeObserver(measure);
4947
+ ro.observe(list);
4948
+ return () => ro.disconnect();
4949
+ }, [
4950
+ on,
4951
+ current,
4952
+ items,
4953
+ variant,
4954
+ overflow
4955
+ ]);
4956
+ const [indicatorId] = useState(() => `rendra-tabs-${++tabsCreated}`);
4957
+ const trigger = cn("inline-flex min-h-touch shrink-0 cursor-pointer items-center justify-center gap-2 px-3 text-sm font-medium whitespace-nowrap transition-colors outline-none disabled:cursor-not-allowed disabled:opacity-50 md:min-h-0 [&_svg]:size-icon-sm", variant === "line" ? on ? "relative -mb-px border-b-2 border-transparent py-3 text-muted-foreground hover:text-foreground" : "-mb-px border-b-2 border-transparent py-3 text-muted-foreground hover:text-foreground data-[state=active]:border-primary data-[state=active]:text-foreground" : on ? "relative isolate rounded-item py-2 text-muted-foreground hover:bg-card/60 hover:text-foreground" : "rounded-item py-2 text-muted-foreground hover:bg-card/60 hover:text-foreground data-[state=active]:bg-card data-[state=active]:text-foreground data-[state=active]:shadow-sm");
4958
+ const indicator = /* @__PURE__ */ jsx(m.span, {
4959
+ layoutId: indicatorId,
4960
+ "data-indicator": "tabs",
4961
+ "aria-hidden": true,
4962
+ transition: presets.move,
4963
+ className: variant === "line" ? "absolute inset-x-0 top-full border-b-2 border-primary" : "absolute inset-0 -z-10 rounded-item bg-card shadow-sm"
4964
+ });
4528
4965
  const list = cn("flex", variant === "line" ? "gap-2 border-b" : "gap-1 rounded-control bg-muted p-1");
4529
- const label = (it) => /* @__PURE__ */ jsxs(Fragment, { children: [
4966
+ const label = (it) => /* @__PURE__ */ jsxs(Fragment$1, { children: [
4530
4967
  it.icon,
4531
4968
  it.label,
4532
4969
  it.count !== void 0 && /* @__PURE__ */ jsx("span", {
@@ -4559,16 +4996,29 @@ function Tabs({ items, value, defaultValue, onChange, variant = "line", classNam
4559
4996
  label: it.count !== void 0 ? `${it.label} (${it.count})` : it.label,
4560
4997
  disabled: it.disabled
4561
4998
  }))
4562
- }) : /* @__PURE__ */ jsx(Tabs$1.List, {
4999
+ }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Tabs$1.List, {
5000
+ ref: listRef,
4563
5001
  "aria-label": aria["aria-label"],
4564
5002
  className: list,
4565
- children: items.map((it) => /* @__PURE__ */ jsx(Tabs$1.Trigger, {
5003
+ children: items.map((it) => /* @__PURE__ */ jsxs(Tabs$1.Trigger, {
4566
5004
  value: it.value,
4567
5005
  disabled: it.disabled,
4568
5006
  className: trigger,
5007
+ children: [on && current === it.value && indicator, label(it)]
5008
+ }, it.value))
5009
+ }), on && /* @__PURE__ */ jsx("div", {
5010
+ "data-tabs-copy": true,
5011
+ "aria-hidden": true,
5012
+ className: cn(list, "pointer-events-none absolute inset-0 border-transparent bg-transparent text-foreground tabs-clip"),
5013
+ style: {
5014
+ "--tabs-l": `${clip.l}px`,
5015
+ "--tabs-r": `${clip.r}px`
5016
+ },
5017
+ children: items.map((it) => /* @__PURE__ */ jsx("span", {
5018
+ className: cn(trigger, "text-foreground"),
4569
5019
  children: label(it)
4570
5020
  }, it.value))
4571
- })]
5021
+ })] })]
4572
5022
  }), items.map((it) => /* @__PURE__ */ jsx(Tabs$1.Content, {
4573
5023
  value: it.value,
4574
5024
  className: "min-w-0 outline-none",
@@ -5055,6 +5505,8 @@ function LoadMore({ onVisible }) {
5055
5505
  children: "Carregando mais cards..."
5056
5506
  });
5057
5507
  }
5508
+ /** Contador de quadros, só para o `layoutId` dos cards em `on` (um prefixo por instância). */
5509
+ var boardsCreated = 0;
5058
5510
  var dotTone = {
5059
5511
  neutral: "bg-muted-foreground",
5060
5512
  primary: "bg-primary",
@@ -5075,7 +5527,7 @@ var targetIconTone = {
5075
5527
  };
5076
5528
  function CardBody({ card, valueFields = [], formatValue, withHandle }) {
5077
5529
  const shown = valueFields.slice(0, 2);
5078
- return /* @__PURE__ */ jsxs(Fragment, { children: [
5530
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
5079
5531
  card.tags && card.tags.length > 0 && /* @__PURE__ */ jsx("span", {
5080
5532
  className: "flex flex-wrap gap-1",
5081
5533
  children: card.tags.map((t) => /* @__PURE__ */ jsx(Badge, {
@@ -5177,6 +5629,10 @@ function Kanban({ columns, cards, onCardMove, onCardClick, onAddCard, renderCard
5177
5629
  }), pageSize = 20, visibleColumns = 5, onLoadMore, hasMore, dropTargets, onDropTarget, className, ...aria }) {
5178
5630
  const code = resolveCatalogCode("Kanban", { hasDropTargets: Boolean(dropTargets?.length) });
5179
5631
  const { isMobile } = useBreakpoint();
5632
+ const motion = useMotionMode();
5633
+ const ready = useLayoutReady();
5634
+ const presets = useMotionPresets();
5635
+ const [boardId] = useState(() => `rendra-kanban-${++boardsCreated}`);
5180
5636
  const boardRef = useFillHeight();
5181
5637
  useEffect(() => {
5182
5638
  const el = boardRef.current;
@@ -5261,7 +5717,7 @@ function Kanban({ columns, cards, onCardMove, onCardClick, onAddCard, renderCard
5261
5717
  }), /* @__PURE__ */ jsxs(DropdownMenuContent, {
5262
5718
  align: "end",
5263
5719
  children: [
5264
- otherColumns.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(DropdownMenuLabel, { children: "Mover para" }), otherColumns.map((c) => /* @__PURE__ */ jsxs(DropdownMenuItem, {
5720
+ otherColumns.length > 0 && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(DropdownMenuLabel, { children: "Mover para" }), otherColumns.map((c) => /* @__PURE__ */ jsxs(DropdownMenuItem, {
5265
5721
  onSelect: () => onCardMove?.(card.id, c.id, inColumn(c.id).length),
5266
5722
  children: [/* @__PURE__ */ jsx(ArrowRightLeft, {}), c.title]
5267
5723
  }, c.id))] }),
@@ -5323,36 +5779,39 @@ function Kanban({ columns, cards, onCardMove, onCardClick, onAddCard, renderCard
5323
5779
  });
5324
5780
  const canTouchDrag = Boolean(onCardMove) || Boolean(dropTargets?.length && onDropTarget);
5325
5781
  const showHandle = isMobile && canTouchDrag;
5326
- const cardItem = (card, index) => /* @__PURE__ */ jsxs("li", {
5327
- "data-kanban-card": card.id,
5328
- draggable: !isMobile && Boolean(onCardMove),
5329
- onDragStart: (e) => {
5782
+ const cardItem = (card, index) => {
5783
+ const dragStart = (dataTransfer) => {
5330
5784
  setDragging(card.id);
5331
- e.dataTransfer.effectAllowed = "move";
5332
- e.dataTransfer.setData("text/plain", card.id);
5333
- },
5334
- onDragEnd: () => {
5785
+ if (!dataTransfer) return;
5786
+ dataTransfer.effectAllowed = "move";
5787
+ dataTransfer.setData("text/plain", card.id);
5788
+ };
5789
+ const dragEnd = () => {
5335
5790
  setDragging(null);
5336
5791
  setOver(null);
5337
- },
5338
- onDragOver: (e) => {
5339
- if (!dragging) return;
5340
- e.preventDefault();
5341
- e.stopPropagation();
5342
- const r = e.currentTarget.getBoundingClientRect();
5343
- const after = e.clientY > r.top + r.height / 2;
5344
- setOver({
5345
- column: card.columnId,
5346
- index: index + (after ? 1 : 0)
5347
- });
5348
- },
5349
- onDrop: (e) => {
5350
- e.preventDefault();
5351
- e.stopPropagation();
5352
- if (over) drop(over.column, over.index);
5353
- },
5354
- className: cn("relative flex rounded-block border bg-card p-3 shadow-sm transition-[box-shadow,opacity]", !isMobile && onCardMove && "cursor-grab active:cursor-grabbing", (dragging === card.id || touchDrag?.cardId === card.id) && "opacity-50", over?.column === card.columnId && over.index === index && dragging !== card.id && "ring-2 ring-ring ring-offset-2 ring-offset-muted"),
5355
- children: [
5792
+ };
5793
+ const common = {
5794
+ "data-kanban-card": card.id,
5795
+ draggable: !isMobile && Boolean(onCardMove),
5796
+ onDragOver: (e) => {
5797
+ if (!dragging) return;
5798
+ e.preventDefault();
5799
+ e.stopPropagation();
5800
+ const r = e.currentTarget.getBoundingClientRect();
5801
+ const after = e.clientY > r.top + r.height / 2;
5802
+ setOver({
5803
+ column: card.columnId,
5804
+ index: index + (after ? 1 : 0)
5805
+ });
5806
+ },
5807
+ onDrop: (e) => {
5808
+ e.preventDefault();
5809
+ e.stopPropagation();
5810
+ if (over) drop(over.column, over.index);
5811
+ },
5812
+ className: cn("relative flex rounded-block border bg-card p-3 shadow-sm transition-[box-shadow,opacity]", !isMobile && onCardMove && "cursor-grab active:cursor-grabbing", (dragging === card.id || touchDrag?.cardId === card.id) && "opacity-50", over?.column === card.columnId && over.index === index && dragging !== card.id && "ring-2 ring-ring ring-offset-2 ring-offset-muted")
5813
+ };
5814
+ const body = /* @__PURE__ */ jsxs(Fragment$1, { children: [
5356
5815
  onCardClick ? /* @__PURE__ */ jsx("button", {
5357
5816
  type: "button",
5358
5817
  onClick: () => onCardClick(card),
@@ -5386,8 +5845,38 @@ function Kanban({ columns, cards, onCardMove, onCardClick, onAddCard, renderCard
5386
5845
  className: "absolute top-2 right-2 z-10",
5387
5846
  children: moveMenu(card)
5388
5847
  })
5389
- ]
5390
- }, card.id);
5848
+ ] });
5849
+ if (motion === "on") {
5850
+ const layout = layoutEnabled({
5851
+ mode: motion,
5852
+ ready,
5853
+ dragging: touchDrag !== null
5854
+ });
5855
+ return /* @__PURE__ */ jsx(m.li, {
5856
+ ref: (el) => {
5857
+ if (!el) return;
5858
+ const onStart = (e) => dragStart(e.dataTransfer);
5859
+ el.addEventListener("dragstart", onStart);
5860
+ el.addEventListener("dragend", dragEnd);
5861
+ return () => {
5862
+ el.removeEventListener("dragstart", onStart);
5863
+ el.removeEventListener("dragend", dragEnd);
5864
+ };
5865
+ },
5866
+ layout,
5867
+ layoutId: layout ? `${boardId}-${card.id}` : void 0,
5868
+ transition: presets.settle,
5869
+ ...common,
5870
+ children: body
5871
+ }, card.id);
5872
+ }
5873
+ return /* @__PURE__ */ jsx("li", {
5874
+ onDragStart: (e) => dragStart(e.dataTransfer),
5875
+ onDragEnd: dragEnd,
5876
+ ...common,
5877
+ children: body
5878
+ }, card.id);
5879
+ };
5391
5880
  const totals = (col) => (valueFields ?? []).slice(0, 2).map((f) => ({
5392
5881
  ...f,
5393
5882
  total: inColumn(col.id).reduce((sum, c) => sum + (c.values?.[f.key] ?? 0), 0)
@@ -5469,7 +5958,7 @@ function Kanban({ columns, cards, onCardMove, onCardClick, onAddCard, renderCard
5469
5958
  else onLoadMore?.(col.id);
5470
5959
  } })
5471
5960
  ]
5472
- })
5961
+ }, String(ready))
5473
5962
  });
5474
5963
  };
5475
5964
  if (isMobile) return /* @__PURE__ */ jsxs("div", {
@@ -5590,14 +6079,26 @@ function List({ items, divided = true, empty, className, onReorder, itemLabel =
5590
6079
  onReorder: onReorder && ((sorted) => onReorder(sorted.map((s) => s.data)))
5591
6080
  });
5592
6081
  const sortableEnabled = Boolean(onReorder);
6082
+ const motion = useMotionMode();
6083
+ const ready = useLayoutReady();
6084
+ const presets = useMotionPresets();
6085
+ const Item = motion === "on" ? m.li : "li";
6086
+ const itemMotion = motion === "on" ? {
6087
+ layout: layoutEnabled({
6088
+ mode: motion,
6089
+ ready,
6090
+ dragging: sortable.draggingId !== null
6091
+ }),
6092
+ transition: presets.move
6093
+ } : {};
5593
6094
  const code = resolveCatalogCode("List", { sortable: sortableEnabled });
5594
- if (items.length === 0 && empty) return /* @__PURE__ */ jsx(Fragment, { children: empty });
6095
+ if (items.length === 0 && empty) return /* @__PURE__ */ jsx(Fragment$1, { children: empty });
5595
6096
  return /* @__PURE__ */ jsx("ul", {
5596
6097
  "data-rendra": code,
5597
6098
  className: cn("flex w-full min-w-0 flex-col", divided && "divide-y", className),
5598
6099
  children: items.map((it) => {
5599
6100
  const interactive = Boolean(it.to || it.onClick);
5600
- const body = /* @__PURE__ */ jsxs(Fragment, { children: [
6101
+ const body = /* @__PURE__ */ jsxs(Fragment$1, { children: [
5601
6102
  it.leading && /* @__PURE__ */ jsx("span", {
5602
6103
  className: "flex shrink-0",
5603
6104
  children: it.leading
@@ -5633,8 +6134,9 @@ function List({ items, divided = true, empty, className, onReorder, itemLabel =
5633
6134
  label: `Reordenar ${label}`,
5634
6135
  sortable
5635
6136
  });
5636
- return /* @__PURE__ */ jsxs("li", {
6137
+ return /* @__PURE__ */ jsxs(Item, {
5637
6138
  ...sortableEnabled ? sortable.itemProps(it.id) : {},
6139
+ ...itemMotion,
5638
6140
  className: cn("flex min-w-0 items-center gap-1", sortable.draggingId === it.id && "opacity-50"),
5639
6141
  children: [handle, it.to ? /* @__PURE__ */ jsx(Link, {
5640
6142
  to: it.to,
@@ -5651,7 +6153,7 @@ function List({ items, divided = true, empty, className, onReorder, itemLabel =
5651
6153
  })]
5652
6154
  }, it.id);
5653
6155
  })
5654
- });
6156
+ }, String(ready));
5655
6157
  }
5656
6158
  //#endregion
5657
6159
  //#region src/components/ui/otp-input.tsx
@@ -5661,6 +6163,9 @@ function List({ items, divided = true, empty, className, onReorder, itemLabel =
5661
6163
  */
5662
6164
  function OtpInput({ length = 6, value, onChange, onComplete, invalid, disabled, id, ...aria }) {
5663
6165
  const refs = useRef([]);
6166
+ const on = useMotionMode() === "on";
6167
+ const presets = useMotionPresets();
6168
+ const Cell = on ? m.input : "input";
5664
6169
  const digits = Array.from({ length }, (_, i) => value[i] ?? "");
5665
6170
  const set = (next) => {
5666
6171
  const clean = next.replace(/\D/g, "").slice(0, length);
@@ -5686,7 +6191,8 @@ function OtpInput({ length = 6, value, onChange, onComplete, invalid, disabled,
5686
6191
  "data-rendra": "OTP-001",
5687
6192
  className: "grid w-full max-w-sm grid-cols-otp gap-1 sm:gap-2",
5688
6193
  style: { "--otp": length },
5689
- children: digits.map((d, i) => /* @__PURE__ */ jsx("input", {
6194
+ children: digits.map((d, i) => /* @__PURE__ */ jsx(Cell, {
6195
+ ...on ? { animate: d ? presets.bump : void 0 } : {},
5690
6196
  ref: (el) => {
5691
6197
  refs.current[i] = el;
5692
6198
  },
@@ -5851,7 +6357,7 @@ function Pagination({ page, pageSize, total, onPageChange, onPageSizeChange, pag
5851
6357
  }
5852
6358
  //#endregion
5853
6359
  //#region src/components/ui/progress.tsx
5854
- var bar = cva("h-full rounded-full transition-[width] duration-300 ease-out", {
6360
+ var bar = cva("h-full rounded-full transition-[width] duration-(--rendra-duration-base) ease-linear", {
5855
6361
  variants: { tone: {
5856
6362
  primary: "bg-primary",
5857
6363
  brand: "bg-gradient-accent",
@@ -5870,6 +6376,7 @@ function Progress({ value, size = "md", tone, showValue, label, className }) {
5870
6376
  children: [/* @__PURE__ */ jsx(Progress$1.Root, {
5871
6377
  value: indeterminate ? null : value,
5872
6378
  "aria-label": label,
6379
+ "data-allow-overflow": true,
5873
6380
  className: cn("relative w-full overflow-hidden rounded-full bg-muted", size === "sm" ? "h-1" : "h-2"),
5874
6381
  children: /* @__PURE__ */ jsx(Progress$1.Indicator, {
5875
6382
  className: cn(bar({ tone }), indeterminate ? "absolute inset-y-0 left-0 w-1/3 progress-slide" : "w-progress"),
@@ -6709,26 +7216,60 @@ var cols = {
6709
7216
  2: "md:grid-cols-2",
6710
7217
  3: "md:grid-cols-3"
6711
7218
  };
7219
+ /**
7220
+ * O item do Radix. Em `on` ele é um `m.button` (asChild) que responde ao toque (whileTap 0,97,
7221
+ * em `press`); em `off` é o `R.Item` de sempre, sem nó novo.
7222
+ */
7223
+ function Item({ on, children, ...props }) {
7224
+ const presets = useMotionPresets();
7225
+ if (!on) return /* @__PURE__ */ jsx(RadioGroup$1.Item, {
7226
+ ...props,
7227
+ children
7228
+ });
7229
+ return /* @__PURE__ */ jsx(RadioGroup$1.Item, {
7230
+ asChild: true,
7231
+ ...props,
7232
+ children: /* @__PURE__ */ jsx(m.button, {
7233
+ type: "button",
7234
+ whileTap: presets.press.whileTap,
7235
+ transition: presets.press.transition,
7236
+ children
7237
+ })
7238
+ });
7239
+ }
6712
7240
  /** Radio único: em lista ou em cards, por prop. */
6713
7241
  function RadioGroup({ options, value, defaultValue, onChange, variant = "list", columns = 2, orientation = "vertical", invalid, disabled, id, name, ...aria }) {
6714
- const dot = /* @__PURE__ */ jsx("span", {
7242
+ const on = useMotionMode() === "on";
7243
+ const presets = useMotionPresets();
7244
+ const [inner, setInner] = useState(defaultValue);
7245
+ const current = value ?? inner;
7246
+ const dotFor = (optionValue) => /* @__PURE__ */ jsx("span", {
6715
7247
  "aria-hidden": true,
6716
7248
  className: cn("flex size-icon-md shrink-0 items-center justify-center rounded-full border border-input bg-card transition-colors group-data-[state=checked]:border-primary", invalid && "border-destructive"),
6717
- children: /* @__PURE__ */ jsx("span", { className: "size-2 scale-0 rounded-full bg-primary transition-transform duration-150 group-data-[state=checked]:scale-100" })
7249
+ children: on ? /* @__PURE__ */ jsx(m.span, {
7250
+ className: "size-2 rounded-full bg-primary",
7251
+ initial: false,
7252
+ animate: current === optionValue ? presets.indicator.animate : presets.indicator.initial,
7253
+ transition: presets.indicator.transition
7254
+ }) : /* @__PURE__ */ jsx("span", { className: "size-2 scale-90 rounded-full bg-primary opacity-0 transition-[transform,opacity] duration-(--rendra-duration-fast) ease-out group-data-[state=checked]:scale-100 group-data-[state=checked]:opacity-100" })
6718
7255
  });
6719
7256
  return /* @__PURE__ */ jsx(RadioGroup$1.Root, {
6720
7257
  id,
6721
7258
  name,
6722
- value,
6723
- defaultValue,
6724
- onValueChange: onChange,
7259
+ value: on ? current : value,
7260
+ defaultValue: on ? void 0 : defaultValue,
7261
+ onValueChange: (v) => {
7262
+ if (on) setInner(v);
7263
+ onChange?.(v);
7264
+ },
6725
7265
  disabled,
6726
7266
  "aria-invalid": invalid || void 0,
6727
7267
  "aria-describedby": aria["aria-describedby"],
6728
7268
  "aria-label": aria["aria-label"],
6729
7269
  "data-rendra": resolveCatalogCode("RadioGroup", { variant }),
6730
7270
  className: cn(variant === "cards" ? cn("grid grid-cols-1 gap-3", cols[columns]) : orientation === "horizontal" ? "flex flex-col sm:flex-row sm:flex-wrap sm:gap-x-6" : "flex flex-col"),
6731
- children: options.map((o) => variant === "cards" ? /* @__PURE__ */ jsxs(RadioGroup$1.Item, {
7271
+ children: options.map((o) => variant === "cards" ? /* @__PURE__ */ jsxs(Item, {
7272
+ on,
6732
7273
  value: o.value,
6733
7274
  disabled: o.disabled,
6734
7275
  className: cn("group relative flex cursor-pointer items-start gap-3 rounded-control border bg-card p-4 text-left transition-[border-color,box-shadow,background-color]", "hover:border-primary data-[state=checked]:border-primary data-[state=checked]:bg-primary-soft data-[state=checked]:ring-1 data-[state=checked]:ring-primary", "disabled:cursor-not-allowed disabled:opacity-50", invalid && "border-destructive"),
@@ -6747,15 +7288,16 @@ function RadioGroup({ options, value, defaultValue, onChange, variant = "list",
6747
7288
  children: o.description
6748
7289
  })]
6749
7290
  }),
6750
- dot
7291
+ dotFor(o.value)
6751
7292
  ]
6752
7293
  }, o.value) : /* @__PURE__ */ jsxs("label", {
6753
7294
  className: cn("flex min-h-touch cursor-pointer items-start gap-3 py-3 md:min-h-0 md:py-1", o.disabled && "cursor-not-allowed opacity-60"),
6754
- children: [/* @__PURE__ */ jsx(RadioGroup$1.Item, {
7295
+ children: [/* @__PURE__ */ jsx(Item, {
7296
+ on,
6755
7297
  value: o.value,
6756
7298
  disabled: o.disabled,
6757
7299
  className: "group flex pt-px outline-none focus-visible:[&>span]:focus-ring",
6758
- children: dot
7300
+ children: dotFor(o.value)
6759
7301
  }), /* @__PURE__ */ jsxs("span", {
6760
7302
  className: "flex min-w-0 flex-col gap-1",
6761
7303
  children: [/* @__PURE__ */ jsx("span", {
@@ -6990,18 +7532,65 @@ function Separator({ orientation = "horizontal", label, className }) {
6990
7532
  }
6991
7533
  //#endregion
6992
7534
  //#region src/components/ui/skeleton.tsx
6993
- /** Bloco de carregamento. Monte o skeleton com a mesma estrutura do conteúdo final. */
7535
+ /**
7536
+ * Bloco de carregamento. Monte o skeleton com a mesma estrutura do conteúdo final. Em `off` pulsa
7537
+ * (animate-pulse do Tailwind); em `on` um brilho suave cruza o bloco (skeleton-shimmer, em
7538
+ * globals.css: transform, tempo e curva pelos tokens, parado com "reduzir movimento").
7539
+ */
6994
7540
  function Skeleton({ className, ...props }) {
7541
+ const on = useMotionMode() === "on";
6995
7542
  return /* @__PURE__ */ jsx("div", {
6996
7543
  "aria-hidden": true,
6997
7544
  "data-slot": "skeleton",
6998
7545
  "data-rendra": "SKEL-001",
6999
- className: cn("animate-pulse rounded-block bg-muted", className),
7546
+ className: cn(on ? "skeleton-shimmer" : "animate-pulse", "rounded-block bg-muted", className),
7000
7547
  ...props
7001
7548
  });
7002
7549
  }
7003
7550
  //#endregion
7004
7551
  //#region src/components/ui/stat-card.tsx
7552
+ /** Contagem de 0 até o valor, com o formato do texto original; no fim mostra o `value` exato. */
7553
+ function Counter({ parsed, value }) {
7554
+ const presets = useMotionPresets();
7555
+ const progress = useMotionValue(0);
7556
+ const text = useTransform(progress, (n) => formatLike(parsed, n));
7557
+ const [done, setDone] = useState(false);
7558
+ useEffect(() => {
7559
+ const controls = animate(progress, parsed.value, {
7560
+ duration: presets.tokens.reveal.count,
7561
+ ease: presets.tokens.ease.out,
7562
+ onComplete: () => setDone(true)
7563
+ });
7564
+ return () => controls.stop();
7565
+ }, [
7566
+ progress,
7567
+ parsed.value,
7568
+ presets.tokens
7569
+ ]);
7570
+ return /* @__PURE__ */ jsx(m.span, {
7571
+ ...presets.fade,
7572
+ children: done ? value : text
7573
+ });
7574
+ }
7575
+ /**
7576
+ * O valor do card. Em `off`, o valor como sempre veio. Em `on`, número (ou texto pt-BR com
7577
+ * número) conta até o valor; qualquer outra coisa só aparece com fade. Com "reduzir movimento"
7578
+ * o valor final aparece direto.
7579
+ */
7580
+ function StatValue({ value }) {
7581
+ const motion = useMotionMode();
7582
+ const presets = useMotionPresets();
7583
+ const parsed = useMemo(() => parseLocaleNumber$1(value), [value]);
7584
+ if (motion !== "on") return /* @__PURE__ */ jsx(Fragment$1, { children: value });
7585
+ if (!parsed || presets.reduced) return /* @__PURE__ */ jsx(m.span, {
7586
+ ...presets.fade,
7587
+ children: value
7588
+ });
7589
+ return /* @__PURE__ */ jsx(Counter, {
7590
+ parsed,
7591
+ value
7592
+ }, String(value));
7593
+ }
7005
7594
  /** Card de indicador. Em grid: 1 coluna no mobile, 2 para cards pequenos. */
7006
7595
  function StatCard({ label, value, change, changeLabel, inverse, icon, highlight, loading, footer, className }) {
7007
7596
  const up = (change ?? 0) > 0;
@@ -7023,9 +7612,9 @@ function StatCard({ label, value, change, changeLabel, inverse, icon, highlight,
7023
7612
  children: icon
7024
7613
  })]
7025
7614
  }),
7026
- loading ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Skeleton, { className: "h-8 w-24" }), /* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-16" })] }) : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
7615
+ loading ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Skeleton, { className: "h-8 w-24" }), /* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-16" })] }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
7027
7616
  className: "text-2xl font-semibold tracking-tight tabular-nums @xs:text-3xl",
7028
- children: value
7617
+ children: /* @__PURE__ */ jsx(StatValue, { value })
7029
7618
  }), change !== void 0 && /* @__PURE__ */ jsxs("span", {
7030
7619
  className: "flex flex-wrap items-center gap-1 text-xs",
7031
7620
  children: [/* @__PURE__ */ jsxs("span", {
@@ -7109,7 +7698,7 @@ function CellContent({ col, row, title }) {
7109
7698
  className: cn("rounded-item font-medium text-foreground underline-offset-4 transition-colors outline-none hover:text-primary-text hover:underline focus-visible:ring-2 focus-visible:ring-ring", title && "inline-flex min-h-touch items-center md:min-h-0"),
7110
7699
  children: main
7111
7700
  }) : main;
7112
- if (!extra.length) return /* @__PURE__ */ jsx(Fragment, { children: value });
7701
+ if (!extra.length) return /* @__PURE__ */ jsx(Fragment$1, { children: value });
7113
7702
  return /* @__PURE__ */ jsxs("span", {
7114
7703
  className: "flex min-w-0 flex-col",
7115
7704
  children: [/* @__PURE__ */ jsx("span", {
@@ -7189,8 +7778,68 @@ var tableFeatureSet = tableFeatures({
7189
7778
  * Mobile (< 768px): a mesma tabela vira lista de cards, sem rolagem horizontal.
7190
7779
  * Desktop: tabela larga rola na horizontal só dentro do próprio contêiner.
7191
7780
  */
7781
+ /**
7782
+ * Bloco "Ver detalhes" do card no celular. Em `on` a altura abre e fecha pelos presets e o
7783
+ * conteúdo fechado sai do DOM; em `off` é o Collapsible de sempre, com as animações em CSS.
7784
+ */
7785
+ function MobileDetails({ children }) {
7786
+ const motion = useMotionMode();
7787
+ const presets = useMotionPresets();
7788
+ const [open, setOpen] = useState(false);
7789
+ const trigger = /* @__PURE__ */ jsxs(Collapsible.Trigger, {
7790
+ className: "group flex min-h-touch cursor-pointer items-center gap-1 text-sm font-medium text-primary-text",
7791
+ children: [
7792
+ /* @__PURE__ */ jsx("span", {
7793
+ className: "group-data-[state=open]:hidden",
7794
+ children: "Ver detalhes"
7795
+ }),
7796
+ /* @__PURE__ */ jsx("span", {
7797
+ className: "hidden group-data-[state=open]:inline",
7798
+ children: "Ocultar detalhes"
7799
+ }),
7800
+ /* @__PURE__ */ jsx(ChevronDown, {
7801
+ className: "size-icon-sm transition-transform duration-(--rendra-duration-base) ease-move group-data-[state=open]:rotate-180",
7802
+ "aria-hidden": true
7803
+ })
7804
+ ]
7805
+ });
7806
+ if (motion === "on") return /* @__PURE__ */ jsxs(Collapsible.Root, {
7807
+ open,
7808
+ onOpenChange: setOpen,
7809
+ children: [trigger, /* @__PURE__ */ jsx(AnimatePresence, {
7810
+ initial: false,
7811
+ children: open && /* @__PURE__ */ jsx(Collapsible.Content, {
7812
+ forceMount: true,
7813
+ asChild: true,
7814
+ children: /* @__PURE__ */ jsx(m.div, {
7815
+ className: "overflow-hidden",
7816
+ initial: {
7817
+ height: 0,
7818
+ opacity: 0
7819
+ },
7820
+ animate: {
7821
+ height: "auto",
7822
+ opacity: 1
7823
+ },
7824
+ exit: {
7825
+ height: 0,
7826
+ opacity: 0
7827
+ },
7828
+ transition: presets.fade.transition,
7829
+ children
7830
+ })
7831
+ })
7832
+ })]
7833
+ });
7834
+ return /* @__PURE__ */ jsxs(Collapsible.Root, { children: [trigger, /* @__PURE__ */ jsx(Collapsible.Content, {
7835
+ className: "overflow-hidden data-[state=closed]:animate-collapsible-up data-[state=open]:animate-collapsible-down",
7836
+ children
7837
+ })] });
7838
+ }
7192
7839
  function Table({ data: dataProp, source, queryKey = "", columns: columnsProp, statusLast = true, getRowId, selectable, expandable, sortable = true, globalFilter, columnVisibility, bulkActions, bulkMenu, rowActions, density = "default", loading, error, onRetry, empty, pageSize: pageSizeProp = 15, mobilePagination = "pages", toolbar, ...aria }) {
7193
7840
  const { isMobile } = useBreakpoint();
7841
+ const on = useMotionMode() === "on";
7842
+ const presets = useMotionPresets();
7194
7843
  const columns = useMemo(() => statusLast ? [...columnsProp.filter((c) => c.kind !== "badge"), ...columnsProp.filter((c) => c.kind === "badge")] : columnsProp, [columnsProp, statusLast]);
7195
7844
  const [sorting, setSorting] = useState([]);
7196
7845
  const [rowSelection, setRowSelection] = useState({});
@@ -7357,7 +8006,7 @@ function Table({ data: dataProp, source, queryKey = "", columns: columnsProp, st
7357
8006
  label: `${c.header} (decrescente)`
7358
8007
  }])
7359
8008
  }) : void 0;
7360
- const selectionBar = selectable && selectedRows.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
8009
+ const selectionBar = selectable && selectedRows.length > 0 ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
7361
8010
  /* @__PURE__ */ jsxs("span", {
7362
8011
  className: "text-sm font-medium tabular-nums",
7363
8012
  children: [
@@ -7448,43 +8097,24 @@ function Table({ data: dataProp, source, queryKey = "", columns: columnsProp, st
7448
8097
  }, c.id))]
7449
8098
  })]
7450
8099
  }),
7451
- (secondary.length > 0 || expandable) && /* @__PURE__ */ jsxs(Collapsible.Root, { children: [/* @__PURE__ */ jsxs(Collapsible.Trigger, {
7452
- className: "group flex min-h-touch cursor-pointer items-center gap-1 text-sm font-medium text-primary-text",
7453
- children: [
7454
- /* @__PURE__ */ jsx("span", {
7455
- className: "group-data-[state=open]:hidden",
7456
- children: "Ver detalhes"
7457
- }),
7458
- /* @__PURE__ */ jsx("span", {
7459
- className: "hidden group-data-[state=open]:inline",
7460
- children: "Ocultar detalhes"
7461
- }),
7462
- /* @__PURE__ */ jsx(ChevronDown, {
7463
- className: "size-icon-sm transition-transform duration-200 group-data-[state=open]:rotate-180",
7464
- "aria-hidden": true
7465
- })
7466
- ]
7467
- }), /* @__PURE__ */ jsxs(Collapsible.Content, {
7468
- className: "overflow-hidden data-[state=closed]:animate-collapsible-up data-[state=open]:animate-collapsible-down",
7469
- children: [/* @__PURE__ */ jsx("dl", {
7470
- className: "grid grid-cols-1 gap-3 pt-2 sm:grid-cols-2",
7471
- children: secondary.map((c) => /* @__PURE__ */ jsxs("div", {
7472
- className: "flex flex-col gap-1",
7473
- children: [/* @__PURE__ */ jsx("dt", {
7474
- className: "text-xs text-muted-foreground",
7475
- children: c.header
7476
- }), /* @__PURE__ */ jsx("dd", {
7477
- className: "text-sm",
7478
- children: /* @__PURE__ */ jsx(CellContent, {
7479
- col: c,
7480
- row
7481
- })
7482
- })]
7483
- }, c.id))
7484
- }), expandable && /* @__PURE__ */ jsx("div", {
7485
- className: "pt-3",
7486
- children: expandable(row)
7487
- })]
8100
+ (secondary.length > 0 || expandable) && /* @__PURE__ */ jsxs(MobileDetails, { children: [/* @__PURE__ */ jsx("dl", {
8101
+ className: "grid grid-cols-1 gap-3 pt-2 sm:grid-cols-2",
8102
+ children: secondary.map((c) => /* @__PURE__ */ jsxs("div", {
8103
+ className: "flex flex-col gap-1",
8104
+ children: [/* @__PURE__ */ jsx("dt", {
8105
+ className: "text-xs text-muted-foreground",
8106
+ children: c.header
8107
+ }), /* @__PURE__ */ jsx("dd", {
8108
+ className: "text-sm",
8109
+ children: /* @__PURE__ */ jsx(CellContent, {
8110
+ col: c,
8111
+ row
8112
+ })
8113
+ })]
8114
+ }, c.id))
8115
+ }), expandable && /* @__PURE__ */ jsx("div", {
8116
+ className: "pt-3",
8117
+ children: expandable(row)
7488
8118
  })] }),
7489
8119
  rowActions && rowActions.length > 0 && /* @__PURE__ */ jsx("div", {
7490
8120
  className: "border-t pt-3",
@@ -7574,59 +8204,92 @@ function Table({ data: dataProp, source, queryKey = "", columns: columnsProp, st
7574
8204
  })
7575
8205
  ] }, i)) : rows.map((r) => {
7576
8206
  const row = r.original;
7577
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("tr", {
7578
- "data-state": r.getIsSelected() ? "selected" : void 0,
7579
- className: "group/row transition-colors hover:bg-muted/40 data-[state=selected]:bg-primary-soft/60",
7580
- children: [
7581
- selectable && /* @__PURE__ */ jsx("td", {
7582
- className: "pr-2 pl-4",
7583
- children: /* @__PURE__ */ jsx(Checkbox, {
7584
- "aria-label": "Selecionar linha",
7585
- checked: r.getIsSelected(),
7586
- onCheckedChange: (v) => r.toggleSelected(v)
7587
- })
7588
- }),
7589
- expandable && /* @__PURE__ */ jsx("td", {
7590
- className: "px-2",
7591
- children: /* @__PURE__ */ jsx(Button, {
7592
- variant: "ghost",
7593
- size: "sm",
7594
- iconOnly: true,
7595
- "aria-label": r.getIsExpanded() ? "Recolher linha" : "Expandir linha",
7596
- "aria-expanded": r.getIsExpanded(),
7597
- onClick: () => r.toggleExpanded(),
7598
- children: /* @__PURE__ */ jsx(ChevronDown, { className: cn("transition-transform", r.getIsExpanded() && "rotate-180") })
7599
- })
7600
- }),
7601
- visibleCols.map((c) => {
7602
- const align = alignOf(c);
7603
- return /* @__PURE__ */ jsx("td", {
7604
- className: cn("px-4 align-middle", pad, align === "right" ? "text-right tabular-nums" : align === "center" ? "text-center" : "text-left", c.width && minWidth[c.width]),
7605
- children: /* @__PURE__ */ jsx("div", {
7606
- className: cn(clamp[c.lines ?? 2], align === "right" && "ml-auto"),
7607
- children: /* @__PURE__ */ jsx(CellContent, {
7608
- col: c,
7609
- row
8207
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
8208
+ /* @__PURE__ */ jsxs("tr", {
8209
+ "data-state": r.getIsSelected() ? "selected" : void 0,
8210
+ className: "group/row transition-colors hover:bg-muted/40 data-[state=selected]:bg-primary-soft/60",
8211
+ children: [
8212
+ selectable && /* @__PURE__ */ jsx("td", {
8213
+ className: "pr-2 pl-4",
8214
+ children: /* @__PURE__ */ jsx(Checkbox, {
8215
+ "aria-label": "Selecionar linha",
8216
+ checked: r.getIsSelected(),
8217
+ onCheckedChange: (v) => r.toggleSelected(v)
8218
+ })
8219
+ }),
8220
+ expandable && /* @__PURE__ */ jsx("td", {
8221
+ className: "px-2",
8222
+ children: /* @__PURE__ */ jsx(Button, {
8223
+ variant: "ghost",
8224
+ size: "sm",
8225
+ iconOnly: true,
8226
+ "aria-label": r.getIsExpanded() ? "Recolher linha" : "Expandir linha",
8227
+ "aria-expanded": r.getIsExpanded(),
8228
+ onClick: () => r.toggleExpanded(),
8229
+ children: /* @__PURE__ */ jsx(ChevronDown, { className: cn("transition-transform", r.getIsExpanded() && "rotate-180") })
8230
+ })
8231
+ }),
8232
+ visibleCols.map((c) => {
8233
+ const align = alignOf(c);
8234
+ return /* @__PURE__ */ jsx("td", {
8235
+ className: cn("px-4 align-middle", pad, align === "right" ? "text-right tabular-nums" : align === "center" ? "text-center" : "text-left", c.width && minWidth[c.width]),
8236
+ children: /* @__PURE__ */ jsx("div", {
8237
+ className: cn(clamp[c.lines ?? 2], align === "right" && "ml-auto"),
8238
+ children: /* @__PURE__ */ jsx(CellContent, {
8239
+ col: c,
8240
+ row
8241
+ })
7610
8242
  })
8243
+ }, c.id);
8244
+ }),
8245
+ rowActions && /* @__PURE__ */ jsx("td", {
8246
+ className: "sticky right-0 w-24 bg-card px-4 group-hover/row:bg-muted group-data-[state=selected]/row:bg-primary-soft",
8247
+ children: /* @__PURE__ */ jsx(RowActions, {
8248
+ row,
8249
+ actions: rowActions
7611
8250
  })
7612
- }, c.id);
7613
- }),
7614
- rowActions && /* @__PURE__ */ jsx("td", {
7615
- className: "sticky right-0 w-24 bg-card px-4 group-hover/row:bg-muted group-data-[state=selected]/row:bg-primary-soft",
7616
- children: /* @__PURE__ */ jsx(RowActions, {
7617
- row,
7618
- actions: rowActions
7619
8251
  })
8252
+ ]
8253
+ }),
8254
+ expandable && !on && r.getIsExpanded() && /* @__PURE__ */ jsx("tr", {
8255
+ className: "bg-muted/30",
8256
+ children: /* @__PURE__ */ jsx("td", {
8257
+ colSpan: visibleCols.length + (selectable ? 1 : 0) + 1 + (rowActions ? 1 : 0),
8258
+ className: "px-4 py-4",
8259
+ children: expandable(row)
7620
8260
  })
7621
- ]
7622
- }), expandable && r.getIsExpanded() && /* @__PURE__ */ jsx("tr", {
7623
- className: "bg-muted/30",
7624
- children: /* @__PURE__ */ jsx("td", {
7625
- colSpan: visibleCols.length + (selectable ? 1 : 0) + 1 + (rowActions ? 1 : 0),
7626
- className: "px-4 py-4",
7627
- children: expandable(row)
8261
+ }),
8262
+ expandable && on && /* @__PURE__ */ jsx(AnimatePresence, {
8263
+ initial: false,
8264
+ children: r.getIsExpanded() && /* @__PURE__ */ jsx("tr", {
8265
+ className: "bg-muted/30",
8266
+ children: /* @__PURE__ */ jsx("td", {
8267
+ colSpan: visibleCols.length + (selectable ? 1 : 0) + 1 + (rowActions ? 1 : 0),
8268
+ className: "px-4",
8269
+ children: /* @__PURE__ */ jsx(m.div, {
8270
+ className: "overflow-hidden",
8271
+ initial: {
8272
+ height: 0,
8273
+ opacity: 0
8274
+ },
8275
+ animate: {
8276
+ height: "auto",
8277
+ opacity: 1
8278
+ },
8279
+ exit: {
8280
+ height: 0,
8281
+ opacity: 0
8282
+ },
8283
+ transition: presets.fade.transition,
8284
+ children: /* @__PURE__ */ jsx("div", {
8285
+ className: "py-4",
8286
+ children: expandable(row)
8287
+ })
8288
+ })
8289
+ })
8290
+ }, "expanded")
7628
8291
  })
7629
- })] }, r.id);
8292
+ ] }, r.id);
7630
8293
  })
7631
8294
  })]
7632
8295
  })
@@ -7753,14 +8416,25 @@ var statusTextTone = {
7753
8416
  };
7754
8417
  /** Linha do tempo única, com eventos em ordem e tom semântico por evento. */
7755
8418
  function Timeline({ events, className }) {
8419
+ const on = useMotionMode() === "on";
8420
+ const presets = useMotionPresets();
8421
+ const Item = on ? m.li : "li";
8422
+ const enter = presets.slide("bottom", "short");
7756
8423
  return /* @__PURE__ */ jsx("ol", {
7757
8424
  "data-rendra": "TLN-001",
7758
8425
  className: cn("@container flex flex-col", className),
7759
8426
  children: events.map((e, i) => {
7760
8427
  const StatusIcon = e.status ? statusIcon[e.status] : null;
7761
8428
  const tone = e.tone ?? (e.status ? statusTone[e.status] : "neutral");
7762
- return /* @__PURE__ */ jsxs("li", {
8429
+ return /* @__PURE__ */ jsxs(Item, {
7763
8430
  className: "relative flex gap-3 pb-6 last:pb-0",
8431
+ ...on ? {
8432
+ ...enter,
8433
+ transition: {
8434
+ ...enter.transition,
8435
+ ...presets.stagger(i)
8436
+ }
8437
+ } : {},
7764
8438
  children: [
7765
8439
  i < events.length - 1 && /* @__PURE__ */ jsx("span", {
7766
8440
  "aria-hidden": true,
@@ -7777,7 +8451,7 @@ function Timeline({ events, className }) {
7777
8451
  /* @__PURE__ */ jsxs("div", {
7778
8452
  className: "flex min-w-0 flex-col gap-1 @sm:flex-row @sm:items-baseline @sm:justify-between @sm:gap-3",
7779
8453
  children: [/* @__PURE__ */ jsx("span", {
7780
- className: "text-sm font-medium",
8454
+ className: "text-sm font-medium wrap-break-word",
7781
8455
  children: e.title
7782
8456
  }), /* @__PURE__ */ jsx("time", {
7783
8457
  className: "shrink-0 text-xs text-muted-foreground tabular-nums",
@@ -7785,7 +8459,7 @@ function Timeline({ events, className }) {
7785
8459
  })]
7786
8460
  }),
7787
8461
  e.description && /* @__PURE__ */ jsx("p", {
7788
- className: "text-sm text-muted-foreground",
8462
+ className: "text-sm wrap-break-word text-muted-foreground",
7789
8463
  children: e.description
7790
8464
  }),
7791
8465
  e.status && StatusIcon && /* @__PURE__ */ jsxs("span", {
@@ -7822,10 +8496,10 @@ function show(type, title, opts = {}) {
7822
8496
  /* @__PURE__ */ jsxs("div", {
7823
8497
  className: "flex min-w-0 flex-1 flex-col gap-1",
7824
8498
  children: [/* @__PURE__ */ jsx("p", {
7825
- className: "text-sm font-semibold",
8499
+ className: "text-sm font-semibold wrap-break-word",
7826
8500
  children: title
7827
8501
  }), opts.description && /* @__PURE__ */ jsx("p", {
7828
- className: "text-sm text-muted-foreground",
8502
+ className: "text-sm wrap-break-word text-muted-foreground",
7829
8503
  children: opts.description
7830
8504
  })]
7831
8505
  }),
@@ -8005,6 +8679,27 @@ function Upload({ accept, multiple = true, maxSizeMb = 10, onUpload, onChange, h
8005
8679
  onReorder?.(sorted.map((s) => s.id));
8006
8680
  }
8007
8681
  });
8682
+ const motion = useMotionMode();
8683
+ const ready = useLayoutReady();
8684
+ const presets = useMotionPresets();
8685
+ const Item = motion === "on" ? m.li : "li";
8686
+ const itemMotion = motion === "on" ? {
8687
+ ...presets.fade,
8688
+ layout: layoutEnabled({
8689
+ mode: motion,
8690
+ ready,
8691
+ dragging: sortable.draggingId !== null
8692
+ }),
8693
+ transition: {
8694
+ ...presets.fade.transition,
8695
+ layout: presets.move
8696
+ }
8697
+ } : {};
8698
+ const animated = (nodes) => motion === "on" ? /* @__PURE__ */ jsx(AnimatePresence, {
8699
+ mode: "popLayout",
8700
+ initial: false,
8701
+ children: nodes
8702
+ }) : nodes;
8008
8703
  const dropzone = !(maxItems !== void 0 && items.length + pendingCrop.length >= maxItems) && /* @__PURE__ */ jsxs("label", {
8009
8704
  htmlFor: inputId,
8010
8705
  onDragOver: (e) => {
@@ -8062,8 +8757,9 @@ function Upload({ accept, multiple = true, maxSizeMb = 10, onUpload, onChange, h
8062
8757
  const listView = items.length > 0 && /* @__PURE__ */ jsx("ul", {
8063
8758
  className: "flex flex-col divide-y rounded-control border bg-card",
8064
8759
  "aria-live": "polite",
8065
- children: items.map((it) => /* @__PURE__ */ jsxs("li", {
8760
+ children: animated(items.map((it) => /* @__PURE__ */ jsxs(Item, {
8066
8761
  ...onReorder ? sortable.itemProps(it.id) : {},
8762
+ ...itemMotion,
8067
8763
  className: cn("flex items-center gap-3 p-3", sortable.draggingId === it.id && "opacity-50"),
8068
8764
  children: [
8069
8765
  handle(it),
@@ -8131,12 +8827,13 @@ function Upload({ accept, multiple = true, maxSizeMb = 10, onUpload, onChange, h
8131
8827
  children: /* @__PURE__ */ jsx(Trash2, {})
8132
8828
  })
8133
8829
  ]
8134
- }, it.id))
8135
- });
8830
+ }, it.id)))
8831
+ }, String(ready));
8136
8832
  const galleryView = items.length > 0 && /* @__PURE__ */ jsx("ul", {
8137
8833
  className: "grid grid-cols-2 gap-3 md:grid-cols-3",
8138
- children: items.map((it) => /* @__PURE__ */ jsxs("li", {
8834
+ children: animated(items.map((it) => /* @__PURE__ */ jsxs(Item, {
8139
8835
  ...onReorder ? sortable.itemProps(it.id) : {},
8836
+ ...itemMotion,
8140
8837
  className: cn("relative flex aspect-square flex-col overflow-hidden rounded-control border bg-card", sortable.draggingId === it.id && "opacity-50"),
8141
8838
  children: [
8142
8839
  it.previewUrl && it.kind === "image" ? /* @__PURE__ */ jsx("img", {
@@ -8200,8 +8897,8 @@ function Upload({ accept, multiple = true, maxSizeMb = 10, onUpload, onChange, h
8200
8897
  })]
8201
8898
  })
8202
8899
  ]
8203
- }, it.id))
8204
- });
8900
+ }, it.id)))
8901
+ }, String(ready));
8205
8902
  return /* @__PURE__ */ jsxs("div", {
8206
8903
  "data-rendra": code,
8207
8904
  className: "flex min-w-0 flex-col gap-3",
@@ -8247,6 +8944,8 @@ var statusLabel = {
8247
8944
  */
8248
8945
  function Stepper({ steps, current, errors = [], orientation = "horizontal", onStepClick, className }) {
8249
8946
  const step = steps[current];
8947
+ const motion = useMotionMode();
8948
+ const presets = useMotionPresets();
8250
8949
  return /* @__PURE__ */ jsxs("div", {
8251
8950
  "data-rendra": "WIZ-002",
8252
8951
  className: cn("min-w-0", className),
@@ -8286,7 +8985,15 @@ function Stepper({ steps, current, errors = [], orientation = "horizontal", onSt
8286
8985
  const clickable = onStepClick && st === "complete";
8287
8986
  const circle = /* @__PURE__ */ jsx("span", {
8288
8987
  className: cn("flex size-8 shrink-0 items-center justify-center rounded-full border-2 text-sm font-semibold tabular-nums transition-colors", st === "complete" && "border-primary bg-primary text-primary-foreground", st === "current" && "border-primary bg-card text-primary-text", st === "pending" && "border-border bg-card text-muted-foreground", st === "error" && "border-destructive bg-destructive text-destructive-foreground"),
8289
- children: st === "complete" ? /* @__PURE__ */ jsx(Check, {
8988
+ children: st === "complete" ? motion === "on" ? /* @__PURE__ */ jsx(m.span, {
8989
+ className: "flex",
8990
+ ...presets.pop,
8991
+ children: /* @__PURE__ */ jsx(Check, {
8992
+ className: "size-icon-sm",
8993
+ strokeWidth: 3,
8994
+ "aria-hidden": true
8995
+ })
8996
+ }) : /* @__PURE__ */ jsx(Check, {
8290
8997
  className: "size-icon-sm",
8291
8998
  strokeWidth: 3,
8292
8999
  "aria-hidden": true
@@ -8368,7 +9075,23 @@ function Wizard({ steps, children, onValidateStep, onFinish, onCancel, cancelLab
8368
9075
  setCurrent((c) => c + 1);
8369
9076
  onSkip?.();
8370
9077
  };
8371
- const body = /* @__PURE__ */ jsx("div", {
9078
+ const motion = useMotionMode();
9079
+ const presets = useMotionPresets();
9080
+ const previous = useRef(current);
9081
+ const direction = current >= previous.current ? 1 : -1;
9082
+ previous.current = current;
9083
+ const body = motion === "on" ? /* @__PURE__ */ jsx("div", {
9084
+ className: "relative flex min-w-0 flex-col gap-6",
9085
+ children: /* @__PURE__ */ jsx(AnimatePresence, {
9086
+ mode: "popLayout",
9087
+ initial: false,
9088
+ children: /* @__PURE__ */ jsx(m.div, {
9089
+ ...presets.swap(direction),
9090
+ className: "flex min-w-0 flex-col gap-6",
9091
+ children: children[current]
9092
+ }, current)
9093
+ })
9094
+ }) : /* @__PURE__ */ jsx("div", {
8372
9095
  className: "flex min-w-0 flex-col gap-6",
8373
9096
  children: children[current]
8374
9097
  });
@@ -8768,7 +9491,7 @@ function MegaItem({ item }) {
8768
9491
  const Link = useRendraLink();
8769
9492
  const Icon = item.icon;
8770
9493
  const active = item.to ? isActive(pathname, item.to) : false;
8771
- const head = /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
9494
+ const head = /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
8772
9495
  className: cn("flex size-control-md shrink-0 items-center justify-center rounded-control transition-colors", active ? "bg-primary text-primary-foreground" : "bg-primary-soft text-primary-soft-foreground group-hover/item:bg-primary group-hover/item:text-primary-foreground"),
8773
9496
  children: /* @__PURE__ */ jsx(Icon, {
8774
9497
  className: "size-icon-md",
@@ -9014,7 +9737,7 @@ function ModeItems() {
9014
9737
  }
9015
9738
  function LayoutItems() {
9016
9739
  const { layout, setLayout, resetLayout } = useShell();
9017
- const radio = (key, title) => /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(DropdownMenuLabel, { children: title }), /* @__PURE__ */ jsx(DropdownMenuRadioGroup, {
9740
+ const radio = (key, title) => /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(DropdownMenuLabel, { children: title }), /* @__PURE__ */ jsx(DropdownMenuRadioGroup, {
9018
9741
  value: layout[key],
9019
9742
  onValueChange: (v) => setLayout(key, v),
9020
9743
  children: layoutOptions[key].map((o) => /* @__PURE__ */ jsx(DropdownMenuRadioItem, {
@@ -9023,10 +9746,10 @@ function LayoutItems() {
9023
9746
  }, o.value))
9024
9747
  })] });
9025
9748
  const sidebar = layout.navigation === "sidebar";
9026
- return /* @__PURE__ */ jsxs(Fragment, { children: [
9749
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
9027
9750
  radio("navigation", "Posição do menu"),
9028
- !sidebar && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(DropdownMenuSeparator, {}), radio("topbarSubmenu", "Submenu")] }),
9029
- sidebar && /* @__PURE__ */ jsxs(Fragment, { children: [
9751
+ !sidebar && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(DropdownMenuSeparator, {}), radio("topbarSubmenu", "Submenu")] }),
9752
+ sidebar && /* @__PURE__ */ jsxs(Fragment$1, { children: [
9030
9753
  /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
9031
9754
  radio("sidebar", "Sidebar"),
9032
9755
  /* @__PURE__ */ jsx(DropdownMenuCheckboxItem, {
@@ -9085,7 +9808,7 @@ function UserMenu() {
9085
9808
  children: user.email
9086
9809
  })]
9087
9810
  }),
9088
- workspaces && workspaces.items.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
9811
+ workspaces && workspaces.items.length > 0 && /* @__PURE__ */ jsxs(Fragment$1, { children: [
9089
9812
  /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
9090
9813
  /* @__PURE__ */ jsx(DropdownMenuLabel, { children: workspaces.label ?? "Espaço" }),
9091
9814
  /* @__PURE__ */ jsx(DropdownMenuRadioGroup, {
@@ -9097,7 +9820,7 @@ function UserMenu() {
9097
9820
  }, w.id))
9098
9821
  })
9099
9822
  ] }),
9100
- userMenuItems.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(DropdownMenuSeparator, {}), userMenuItems.map((item) => {
9823
+ userMenuItems.length > 0 && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(DropdownMenuSeparator, {}), userMenuItems.map((item) => {
9101
9824
  const Icon = item.icon;
9102
9825
  return item.to ? /* @__PURE__ */ jsx(DropdownMenuItem, {
9103
9826
  asChild: true,
@@ -9275,7 +9998,7 @@ function Header() {
9275
9998
  const topbar = layout.navigation === "topbar";
9276
9999
  const hasParent = Boolean(crumbs.length >= 2 && crumbs[crumbs.length - 2]?.to);
9277
10000
  const menuInFooter = layout.bottomNav || hasParent;
9278
- const pageTitle = /* @__PURE__ */ jsxs(Fragment, { children: [headerLogo && /* @__PURE__ */ jsx("span", {
10001
+ const pageTitle = /* @__PURE__ */ jsxs(Fragment$1, { children: [headerLogo && /* @__PURE__ */ jsx("span", {
9279
10002
  "aria-hidden": true,
9280
10003
  className: "flex min-w-0 flex-1 items-center md:hidden",
9281
10004
  children: headerLogo
@@ -9309,7 +10032,7 @@ function Header() {
9309
10032
  onClick: () => setMobileNavOpen(true),
9310
10033
  children: /* @__PURE__ */ jsx(Menu, { "aria-hidden": true })
9311
10034
  }),
9312
- topbar ? /* @__PURE__ */ jsxs(Fragment, { children: [
10035
+ topbar ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
9313
10036
  /* @__PURE__ */ jsx(Link, {
9314
10037
  to: "/",
9315
10038
  "aria-label": `${brand.productName}, ir para o painel`,
@@ -9324,7 +10047,7 @@ function Header() {
9324
10047
  className: "hidden min-w-0 flex-1 lg:flex lg:justify-center",
9325
10048
  children: layout.topbarSubmenu === "mega" ? /* @__PURE__ */ jsx(MegaMenu, {}) : /* @__PURE__ */ jsx(TopNav, {})
9326
10049
  })
9327
- ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
10050
+ ] }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [
9328
10051
  /* @__PURE__ */ jsx(Tooltip, {
9329
10052
  content: collapsed ? "Expandir menu" : "Recolher menu",
9330
10053
  side: "bottom",
@@ -9480,7 +10203,7 @@ function NavEntry({ item, compact, submenu, hoverExpands, panelOpenFor, onToggle
9480
10203
  className: "size-icon-md shrink-0",
9481
10204
  "aria-hidden": true
9482
10205
  }),
9483
- !compact && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
10206
+ !compact && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
9484
10207
  className: "truncate",
9485
10208
  children: item.title
9486
10209
  }), /* @__PURE__ */ jsx(ChevronRight, {
@@ -9745,7 +10468,7 @@ function Sidebar() {
9745
10468
  return Boolean(el && rootRef.current?.contains(el) && el.matches(":focus-visible"));
9746
10469
  };
9747
10470
  const desktop = layout.navigation === "sidebar";
9748
- return /* @__PURE__ */ jsxs(Fragment, { children: [desktop && /* @__PURE__ */ jsx("aside", {
10471
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [desktop && /* @__PURE__ */ jsx("aside", {
9749
10472
  "aria-label": "Menu lateral",
9750
10473
  className: cn("relative hidden shrink-0 transition-[width] duration-200 ease-out md:block", collapsed ? "w-sidebar-collapsed" : "w-sidebar"),
9751
10474
  children: /* @__PURE__ */ jsxs("div", {
@@ -10603,6 +11326,6 @@ function createTheme(input) {
10603
11326
  };
10604
11327
  }
10605
11328
  //#endregion
10606
- export { Accordion, ActionBar, Alert, AppShell, Avatar, AvatarGroup, Badge, BrandFeedbackIcon, BrandLogo, BrandProvider, Breadcrumb, Button, ButtonGroup, CATALOG, CATALOG_EXCLUDED_FILES, COMPONENT_CODE_PATTERN, Calendar, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, ChannelBadge, ChatComposer, ChatThread, Checkbox, CheckboxGroup, Checklist, ColorPicker, Container, ConversationList, DEFAULT_DDI, DataToolbar, DatePicker, Drawer, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, ErrorPage, Field, Form, FormField, FormSection, Grid, ImageCropper, ImageViewer, InfoHint, Inline, Input, Kanban, Label, List, Modal, OtpInput, PageHeader, Pagination, Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverTrigger, Progress, QR_MAX_VERSION, QrCode, QrEncodingError, RENDRA_CREDIT_HREF, RENDRA_CREDIT_TEXT, RadioGroup, Rating, RendraCredit, RendraProvider, RepeatableField, Section, Select, Separator, Skeleton, Slider, Spinner, Stack, StatCard, Stepper, Switch, TABLE_PAGE_SIZE, TOKEN_KEYS, Table, Tabs, Textarea, Timeline, Toaster, Tooltip, TooltipProvider, Upload, Wizard, applyPalette, applyTheme, assertCatalogIntegrity, bindPointerDrag, breakpoints, buildDataCodewords, buttonVariants, catalogByComponent, chatChannels, cn, computeCropGeometry, computeFormatBits, computeMaskPenalty, computeVersionBits, contrast, contrastRatio, controlAdornmentButton, controlAdornmentSpace, controlFrame, controlInput, createPalette, createTheme, defaultShellLayout, encodeQrMatrix, feedbackLabels, filesMissingCatalogEntry, findComponentsWithMultipleDefaults, findComponentsWithoutDefault, findDragTarget, findDuplicateCodes, findInvalidFormatCodes, findPresetCollisions, formatCents, formatCurrency, getCatalogEntry, internationalPhoneMask, isValidCnpj, isValidCpf, isValidDateBR, layoutOptions, lookupCep, lookupCnpj, masks, moveKanbanCard, parseLocaleNumber, percentMask, phoneCountries, qrMatrixToSvgPath, readCodewordsForTest, readVar, reedSolomonComputeDivisor, reedSolomonComputeRemainder, reedSolomonEncode, reedSolomonMultiply, resolveCatalogCode, resolveDropIndex, shapeLabels, toCents, toE164, toast, useBrand, useBreakpoint, useCurrentPath, useDebouncedValue, useFieldControl, useFillHeight, useLookup, usePrefersReducedMotion, useRendraBreadcrumbs, useRendraLink, useRendraNavigate, useSortable, zBR };
11329
+ export { Accordion, ActionBar, Alert, AppShell, Avatar, AvatarGroup, Badge, BrandFeedbackIcon, BrandLogo, BrandProvider, Breadcrumb, Button, ButtonGroup, CATALOG, CATALOG_EXCLUDED_FILES, COMPONENT_CODE_PATTERN, Calendar, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, ChannelBadge, ChatComposer, ChatThread, Checkbox, CheckboxGroup, Checklist, ColorPicker, Container, ConversationList, DEFAULT_DDI, DataToolbar, DatePicker, Drawer, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, ErrorPage, Field, Form, FormField, FormSection, Grid, ImageCropper, ImageViewer, InfoHint, Inline, Input, Kanban, Label, List, Modal, OtpInput, PageHeader, Pagination, Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverTrigger, Progress, QR_MAX_VERSION, QrCode, QrEncodingError, RENDRA_CREDIT_HREF, RENDRA_CREDIT_TEXT, RadioGroup, Rating, RendraCredit, RendraProvider, RepeatableField, Section, Select, Separator, Skeleton, Slider, Spinner, Stack, StatCard, Stepper, Switch, TABLE_PAGE_SIZE, TOKEN_KEYS, Table, Tabs, Textarea, Timeline, Toaster, Tooltip, TooltipProvider, Upload, Wizard, applyPalette, applyTheme, assertCatalogIntegrity, bindPointerDrag, breakpoints, buildDataCodewords, buttonVariants, catalogByComponent, chatChannels, cn, computeCropGeometry, computeFormatBits, computeMaskPenalty, computeVersionBits, contrast, contrastRatio, controlAdornmentButton, controlAdornmentSpace, controlFrame, controlInput, createPalette, createTheme, defaultShellLayout, encodeQrMatrix, feedbackLabels, filesMissingCatalogEntry, findComponentsWithMultipleDefaults, findComponentsWithoutDefault, findDragTarget, findDuplicateCodes, findInvalidFormatCodes, findPresetCollisions, formatCents, formatCurrency, getCatalogEntry, getReducedMotion, internationalPhoneMask, isValidCnpj, isValidCpf, isValidDateBR, layoutOptions, lookupCep, lookupCnpj, masks, moveKanbanCard, parseLocaleNumber, percentMask, phoneCountries, qrMatrixToSvgPath, readCodewordsForTest, readVar, reedSolomonComputeDivisor, reedSolomonComputeRemainder, reedSolomonEncode, reedSolomonMultiply, resolveCatalogCode, resolveDropIndex, shapeLabels, subscribeReducedMotion, toCents, toE164, toast, useBrand, useBreakpoint, useCurrentPath, useDebouncedValue, useFieldControl, useFillHeight, useLookup, usePrefersReducedMotion, useRendraBreadcrumbs, useRendraLink, useRendraNavigate, useSortable, zBR };
10607
11330
 
10608
11331
  //# sourceMappingURL=index.js.map