@rendra-ui/web 2.8.0 → 2.9.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 (62) hide show
  1. package/README.md +3 -3
  2. package/dist/base.css +1 -1
  3. package/dist/{button-CrSlVIsY.js → button-BcCBrlnt.js} +6 -6
  4. package/dist/{button-CrSlVIsY.js.map → button-BcCBrlnt.js.map} +1 -1
  5. package/dist/chart.js +7 -7
  6. package/dist/cli/auditar.js +1 -1
  7. package/dist/cli/codigos.js +2 -2
  8. package/dist/cli/executar-auditar.js +1 -1
  9. package/dist/cli/help.js +1 -1
  10. package/dist/cli/trocar.js +2 -2
  11. package/dist/cli/typescript-loader.js +1 -1
  12. package/dist/{cn-BlJHpkDs.js → cn-CpdCvlkP.js} +2 -2
  13. package/dist/{cn-BlJHpkDs.js.map → cn-CpdCvlkP.js.map} +1 -1
  14. package/dist/{components-6RpoJ2Od.js → components-Bus_Jh2R.js} +7 -4
  15. package/dist/components-Bus_Jh2R.js.map +1 -0
  16. package/dist/components.css +67 -26
  17. package/dist/document-viewer.js +4 -4
  18. package/dist/{dropdown-menu-BUGKtR6k.js → dropdown-menu-B3L1XSDf.js} +5 -5
  19. package/dist/{dropdown-menu-BUGKtR6k.js.map → dropdown-menu-B3L1XSDf.js.map} +1 -1
  20. package/dist/{brand-feedback-icon-CVux4pNh.js → empty-state-Bcx4M0Me.js} +64 -4
  21. package/dist/empty-state-Bcx4M0Me.js.map +1 -0
  22. package/dist/{features-max-BCIy1Ic-.js → features-max-CoyJ_kuK.js} +1 -1
  23. package/dist/flow.js +2818 -868
  24. package/dist/flow.js.map +1 -1
  25. package/dist/index.js +80 -465
  26. package/dist/index.js.map +1 -1
  27. package/dist/{motion-context-PJPj6X4g.js → motion-context-DWFl2xRr.js} +4 -4
  28. package/dist/{motion-context-PJPj6X4g.js.map → motion-context-DWFl2xRr.js.map} +1 -1
  29. package/dist/{motion-on-Bocf4Smc.js → motion-on-zwsBqYZL.js} +2 -2
  30. package/dist/{motion-on-Bocf4Smc.js.map → motion-on-zwsBqYZL.js.map} +1 -1
  31. package/dist/motion.js +2 -2
  32. package/dist/{rendra-provider-Do_qWjJC.js → rendra-provider-DuIhBatD.js} +3 -3
  33. package/dist/{rendra-provider-Do_qWjJC.js.map → rendra-provider-DuIhBatD.js.map} +1 -1
  34. package/dist/rich-text-editor.js +4 -4
  35. package/dist/router-bridge.js +2 -2
  36. package/dist/{timeline-xrMHeV92.js → toast-C7qYslCp.js} +464 -80
  37. package/dist/toast-C7qYslCp.js.map +1 -0
  38. package/dist/tokens.css +1 -1
  39. package/dist/{tooltip-to0h6aPe.js → tooltip-BSPO-bH4.js} +5 -5
  40. package/dist/{tooltip-to0h6aPe.js.map → tooltip-BSPO-bH4.js.map} +1 -1
  41. package/dist/types/components/ui/flow-config-panels.d.ts +10 -0
  42. package/dist/types/components/ui/flow-editor.d.ts +5 -0
  43. package/dist/types/components/ui/flow-sidebar.d.ts +21 -0
  44. package/dist/types/components/ui/flow-simulation-panel.d.ts +20 -0
  45. package/dist/types/components/ui/flow-viewer.d.ts +27 -10
  46. package/dist/types/flow.d.ts +1 -1
  47. package/dist/types/lib/flow-blocks.d.ts +122 -0
  48. package/dist/types/lib/flow-edit.d.ts +88 -0
  49. package/dist/types/lib/flow-layout.d.ts +3 -0
  50. package/dist/types/lib/flow-sim.d.ts +24 -0
  51. package/dist/types/lib/flow.d.ts +30 -80
  52. package/dist/{use-breakpoint-CM-yeDHJ.js → use-breakpoint-BGmY3ir-.js} +2 -2
  53. package/dist/{use-breakpoint-CM-yeDHJ.js.map → use-breakpoint-BGmY3ir-.js.map} +1 -1
  54. package/dist/{use-motion-presets-I4StrsCi.js → use-motion-presets-CmMLBQLI.js} +3 -3
  55. package/dist/{use-motion-presets-I4StrsCi.js.map → use-motion-presets-CmMLBQLI.js.map} +1 -1
  56. package/dist/widget-grid.js +2 -2
  57. package/package.json +2 -1
  58. package/dist/brand-feedback-icon-CVux4pNh.js.map +0 -1
  59. package/dist/components-6RpoJ2Od.js.map +0 -1
  60. package/dist/empty-state-i4e-LacG.js +0 -67
  61. package/dist/empty-state-i4e-LacG.js.map +0 -1
  62. package/dist/timeline-xrMHeV92.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,18 +1,17 @@
1
- /*! Rendra Design System v2.8.0 | MIT | © 2026 Bruno Magalhaes | brunomagalhaes.me */
2
- import { t as cn } from "./cn-BlJHpkDs.js";
3
- import { a as useMotionMode, c as getReducedMotion, i as useMotionLib, l as subscribeReducedMotion, n as useLayoutReady, o as useMotionOn, r as useMotionAdopted, u as usePrefersReducedMotion } from "./motion-context-PJPj6X4g.js";
4
- import { t as useMotionPresets } from "./use-motion-presets-I4StrsCi.js";
5
- import { A as lookupCnpj, B as ActionBar, C as toE164, D as controlInput, E as controlFrame, F as CardHeader, H as useShell, I as CardTitle, L as InfoHint, M as CardContent, N as CardDescription, O as useLookup, P as CardFooter, R as Modal, S as toCents, T as controlAdornmentSpace, V as ShellContext, _ as internationalPhoneMask, a as Label, b as percentMask, c as fieldGridClass, d as Drawer, f as PickerPanel, g as formatCurrency, h as formatCents, i as Field, j as Card, k as lookupCep, l as gapClass, m as DEFAULT_DDI, n as useFillHeight, o as useFieldControl, p as Input, r as Select, s as alignClass, t as Timeline, u as justifyClass, v as masks, w as controlAdornmentButton, x as phoneCountries, y as parseLocaleNumber, z as Alert } from "./timeline-xrMHeV92.js";
6
- 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-6RpoJ2Od.js";
7
- import { n as buttonVariants, r as Spinner, t as Button } from "./button-CrSlVIsY.js";
8
- import { a as DropdownMenuItem, c as DropdownMenuRadioItem, d as DropdownMenuSubContent, f as DropdownMenuSubTrigger, i as DropdownMenuGroup, l as DropdownMenuSeparator, n as DropdownMenuCheckboxItem, o as DropdownMenuLabel, p as DropdownMenuTrigger, r as DropdownMenuContent, s as DropdownMenuRadioGroup, t as DropdownMenu, u as DropdownMenuSub } from "./dropdown-menu-BUGKtR6k.js";
9
- import { i as BrandContext, n as feedbackLabels, r as useBrand, t as BrandFeedbackIcon } from "./brand-feedback-icon-CVux4pNh.js";
10
- import { a as useRendraNavigate, i as useRendraLink, n as useCurrentPath, r as useRendraBreadcrumbs, t as RendraProvider } from "./rendra-provider-Do_qWjJC.js";
11
- import { n as useBreakpoint, t as breakpoints } from "./use-breakpoint-CM-yeDHJ.js";
12
- import { t as EmptyState } from "./empty-state-i4e-LacG.js";
13
- import { n as TooltipProvider, t as Tooltip } from "./tooltip-to0h6aPe.js";
1
+ /*! Rendra Design System v2.9.0 | MIT | © 2026 Bruno Magalhaes | brunomagalhaes.me */
2
+ import { t as cn } from "./cn-CpdCvlkP.js";
3
+ import { a as useMotionMode, c as getReducedMotion, i as useMotionLib, l as subscribeReducedMotion, n as useLayoutReady, o as useMotionOn, r as useMotionAdopted, u as usePrefersReducedMotion } from "./motion-context-DWFl2xRr.js";
4
+ import { t as useMotionPresets } from "./use-motion-presets-CmMLBQLI.js";
5
+ import { A as toE164, B as Alert, C as formatCurrency, D as percentMask, E as parseLocaleNumber, F as useLookup, H as ShellContext, I as lookupCep, L as lookupCnpj, M as controlAdornmentSpace, N as controlFrame, O as phoneCountries, P as controlInput, R as InfoHint, S as formatCents, T as masks, U as useShell, V as ActionBar, _ as PickerPanel, a as RadioGroup, b as Input, c as Select, d as useFieldControl, f as alignClass, g as Drawer, h as justifyClass, i as Textarea, j as controlAdornmentButton, k as toCents, l as Field, m as gapClass, n as toast, o as useFillHeight, p as fieldGridClass, r as Timeline, s as Tabs, t as Toaster, u as Label, v as Checkbox, w as internationalPhoneMask, x as DEFAULT_DDI, y as CheckboxGroup, z as Modal } from "./toast-C7qYslCp.js";
6
+ 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-Bus_Jh2R.js";
7
+ import { n as buttonVariants, r as Spinner, t as Button } from "./button-BcCBrlnt.js";
8
+ import { a as DropdownMenuItem, c as DropdownMenuRadioItem, d as DropdownMenuSubContent, f as DropdownMenuSubTrigger, i as DropdownMenuGroup, l as DropdownMenuSeparator, n as DropdownMenuCheckboxItem, o as DropdownMenuLabel, p as DropdownMenuTrigger, r as DropdownMenuContent, s as DropdownMenuRadioGroup, t as DropdownMenu, u as DropdownMenuSub } from "./dropdown-menu-B3L1XSDf.js";
9
+ import { a as BrandContext, i as useBrand, n as BrandFeedbackIcon, r as feedbackLabels, t as EmptyState } from "./empty-state-Bcx4M0Me.js";
10
+ import { a as useRendraNavigate, i as useRendraLink, n as useCurrentPath, r as useRendraBreadcrumbs, t as RendraProvider } from "./rendra-provider-DuIhBatD.js";
11
+ import { n as useBreakpoint, t as breakpoints } from "./use-breakpoint-BGmY3ir-.js";
12
+ import { n as TooltipProvider, t as Tooltip } from "./tooltip-BSPO-bH4.js";
14
13
  import { ArrowDown, ArrowDownRight, ArrowLeft, ArrowRight, ArrowRightLeft, ArrowUp, ArrowUpRight, Bell, Bot, CalendarClock, CalendarDays, CalendarX2, Check, CheckCheck, ChevronDown, ChevronLeft, ChevronRight, ChevronsUpDown, Clock, Columns3, Download, EllipsisVertical, FileText, Film, Filter, Globe, GripVertical, Home, ImageIcon, ImagePlus, LayoutTemplate, LogOut, Mail, MapPin, Menu, MessageCircle, MessagesSquare, Mic, Minus, Monitor, Moon, MoreHorizontal, Palette, PanelLeft, Paperclip, Pause, Pencil, Phone, Play, Plus, Reply, RotateCw, Search, Send, Settings2, Smartphone, Smile, Star, Sun, Trash2, TriangleAlert, UploadCloud, User, VideoIcon, X, Zap } from "lucide-react";
15
- import { Accordion as Accordion$1, Avatar as Avatar$1, Checkbox as Checkbox$1, Collapsible, ContextMenu, Dialog, 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";
14
+ import { Accordion as Accordion$1, Avatar as Avatar$1, Collapsible, ContextMenu, Dialog, NavigationMenu, Popover as Popover$1, Progress as Progress$1, Slider as Slider$1, Slot, Switch as Switch$1, VisuallyHidden } from "radix-ui";
16
15
  import { Fragment, createContext, forwardRef, useCallback, useContext, useEffect, useId, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
17
16
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
18
17
  import { cva } from "class-variance-authority";
@@ -23,7 +22,6 @@ import { ptBR as ptBR$1 } from "react-day-picker/locale";
23
22
  import { FormProvider, useController, useFormContext } from "react-hook-form";
24
23
  import { Command } from "cmdk";
25
24
  import { columnFilteringFeature, columnVisibilityFeature, createExpandedRowModel, createFilteredRowModel, createPaginatedRowModel, createSortedRowModel, filterFn_includesString, globalFilteringFeature, rowExpandingFeature, rowPaginationFeature, rowSelectionFeature, rowSortingFeature, sortFn_alphanumeric, sortFn_basic, tableFeatures, useTable } from "@tanstack/react-table";
26
- import { Toaster as Toaster$1, toast as toast$1 } from "sonner";
27
25
  import { z } from "zod";
28
26
  //#region src/lib/motion/reorder.ts
29
27
  function layoutEnabled({ mode, ready, dragging }) {
@@ -495,6 +493,73 @@ function ButtonGroup({ children, options, value, onChange, size = "md", fullWidt
495
493
  });
496
494
  }
497
495
  //#endregion
496
+ //#region src/components/ui/card.tsx
497
+ function Card({ className, "data-rendra": dataRendra, ...props }) {
498
+ return /* @__PURE__ */ jsx("div", {
499
+ "data-slot": "card",
500
+ "data-rendra": dataRendra ?? "CARD-001",
501
+ className: cn("flex min-w-0 flex-col rounded-surface border bg-card text-card-foreground", className),
502
+ ...props
503
+ });
504
+ }
505
+ function CardHeader({ className, actions, children, ...props }) {
506
+ if (!actions) return /* @__PURE__ */ jsx("div", {
507
+ "data-slot": "card-header",
508
+ className: cn("flex flex-col gap-1 p-4 md:p-6", className),
509
+ ...props,
510
+ children
511
+ });
512
+ return /* @__PURE__ */ jsxs("div", {
513
+ "data-slot": "card-header",
514
+ className: cn("flex flex-wrap items-start justify-between gap-x-4 gap-y-3 p-4 md:p-6", className),
515
+ ...props,
516
+ children: [/* @__PURE__ */ jsx("div", {
517
+ className: "flex min-w-0 flex-1 flex-col gap-1",
518
+ children
519
+ }), /* @__PURE__ */ jsx("div", {
520
+ className: "flex shrink-0 items-center gap-2",
521
+ children: actions
522
+ })]
523
+ });
524
+ }
525
+ function CardTitle({ className, children, help, ...props }) {
526
+ const heading = /* @__PURE__ */ jsx("h3", {
527
+ "data-slot": "card-title",
528
+ className: cn("text-lg font-semibold", className),
529
+ ...props,
530
+ children
531
+ });
532
+ if (!help) return heading;
533
+ return /* @__PURE__ */ jsxs("div", {
534
+ className: "flex min-w-0 items-center gap-1",
535
+ children: [heading, /* @__PURE__ */ jsx(InfoHint, {
536
+ title: typeof children === "string" ? children : "Sobre esta seção",
537
+ children: help
538
+ })]
539
+ });
540
+ }
541
+ function CardDescription({ className, ...props }) {
542
+ return /* @__PURE__ */ jsx("p", {
543
+ "data-slot": "card-description",
544
+ className: cn("text-sm text-muted-foreground", className),
545
+ ...props
546
+ });
547
+ }
548
+ function CardContent({ className, ...props }) {
549
+ return /* @__PURE__ */ jsx("div", {
550
+ "data-slot": "card-content",
551
+ className: cn("p-4 md:p-6 [[data-slot=card-header]+&]:pt-0", className),
552
+ ...props
553
+ });
554
+ }
555
+ function CardFooter({ className, ...props }) {
556
+ return /* @__PURE__ */ jsx("div", {
557
+ "data-slot": "card-footer",
558
+ className: cn("flex items-center gap-3 border-t px-4 py-3 md:px-6", className),
559
+ ...props
560
+ });
561
+ }
562
+ //#endregion
498
563
  //#region src/components/ui/calendar.tsx
499
564
  var viewLabels = {
500
565
  month: "Mês",
@@ -2071,124 +2136,6 @@ function QuickReplyList({ items, onPick }) {
2071
2136
  ] });
2072
2137
  }
2073
2138
  //#endregion
2074
- //#region src/components/ui/checkbox.tsx
2075
- /**
2076
- * Checkbox único, com estado indeterminado (checked="indeterminate").
2077
- * Com label, a linha inteira é área de toque de 44px no mobile.
2078
- */
2079
- function Checkbox({ checked, defaultChecked, onCheckedChange, label, description, disabled, invalid, id, name, className, ...aria }) {
2080
- const auto = useId();
2081
- const cid = id ?? `cb${auto}`;
2082
- const lib = useMotionLib();
2083
- const on = lib !== null;
2084
- const presets = useMotionPresets();
2085
- const [inner, setInner] = useState(defaultChecked ?? false);
2086
- const state = checked ?? inner;
2087
- const mark = checked === "indeterminate" ? /* @__PURE__ */ jsx(Minus, {
2088
- className: "size-3",
2089
- strokeWidth: 3,
2090
- "aria-hidden": true
2091
- }) : /* @__PURE__ */ jsx(Check, {
2092
- className: "size-3",
2093
- strokeWidth: 3,
2094
- "aria-hidden": true
2095
- });
2096
- const rootProps = {
2097
- id: cid,
2098
- name,
2099
- checked: on ? state : checked,
2100
- defaultChecked: on ? void 0 : defaultChecked,
2101
- onCheckedChange: (v) => {
2102
- if (on) setInner(v);
2103
- onCheckedChange?.(v === true);
2104
- },
2105
- disabled,
2106
- "aria-invalid": invalid || void 0,
2107
- "aria-label": aria["aria-label"],
2108
- "data-touch": label ? void 0 : "expanded",
2109
- 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")
2110
- };
2111
- const box = on ? /* @__PURE__ */ jsx(Checkbox$1.Root, {
2112
- asChild: true,
2113
- ...rootProps,
2114
- children: /* @__PURE__ */ jsx(lib.m.button, {
2115
- type: "button",
2116
- whileTap: presets.press.whileTap,
2117
- transition: presets.press.transition,
2118
- children: /* @__PURE__ */ jsx(lib.AnimatePresence, {
2119
- initial: false,
2120
- children: state !== false && /* @__PURE__ */ jsx(Checkbox$1.Indicator, {
2121
- forceMount: true,
2122
- asChild: true,
2123
- children: /* @__PURE__ */ jsx(lib.m.span, {
2124
- className: "flex items-center justify-center",
2125
- ...presets.indicator,
2126
- children: mark
2127
- })
2128
- })
2129
- })
2130
- })
2131
- }) : /* @__PURE__ */ jsx(Checkbox$1.Root, {
2132
- ...rootProps,
2133
- children: /* @__PURE__ */ jsx(Checkbox$1.Indicator, {
2134
- className: "flex items-center justify-center data-[state=checked]:animate-in data-[state=checked]:duration-(--rendra-duration-fast) data-[state=checked]:zoom-in-90",
2135
- children: mark
2136
- })
2137
- });
2138
- if (!label) return /* @__PURE__ */ jsx("span", {
2139
- "data-rendra": "CHK-001",
2140
- className: cn("inline-flex", className),
2141
- children: box
2142
- });
2143
- return /* @__PURE__ */ jsxs("label", {
2144
- htmlFor: cid,
2145
- "data-rendra": "CHK-001",
2146
- className: cn("flex min-h-touch cursor-pointer items-start gap-3 py-3 md:min-h-0 md:py-1", disabled && "cursor-not-allowed opacity-60", className),
2147
- children: [/* @__PURE__ */ jsx("span", {
2148
- className: "flex pt-px",
2149
- children: box
2150
- }), /* @__PURE__ */ jsxs("span", {
2151
- className: "flex min-w-0 flex-col gap-1",
2152
- children: [/* @__PURE__ */ jsx("span", {
2153
- className: "text-sm font-medium",
2154
- children: label
2155
- }), description && /* @__PURE__ */ jsx("span", {
2156
- className: "text-sm text-muted-foreground",
2157
- children: description
2158
- })]
2159
- })]
2160
- });
2161
- }
2162
- function CheckboxGroup({ options, value = [], onChange, selectAll, orientation = "vertical", invalid, id, label, ...aria }) {
2163
- const enabled = options.filter((o) => !o.disabled);
2164
- const all = enabled.length > 0 && enabled.every((o) => value.includes(o.value));
2165
- const some = value.length > 0 && !all;
2166
- return /* @__PURE__ */ jsxs("div", {
2167
- id,
2168
- role: "group",
2169
- "aria-label": label,
2170
- "aria-describedby": aria["aria-describedby"],
2171
- "data-rendra": "CHK-002",
2172
- className: "flex flex-col",
2173
- children: [selectAll && /* @__PURE__ */ jsx(Checkbox, {
2174
- label: "Selecionar todos",
2175
- checked: all ? true : some ? "indeterminate" : false,
2176
- onCheckedChange: () => onChange?.(all ? [] : enabled.map((o) => o.value)),
2177
- className: "border-b"
2178
- }), /* @__PURE__ */ jsx("div", {
2179
- className: cn("flex", orientation === "vertical" ? "flex-col" : "flex-col sm:flex-row sm:flex-wrap sm:gap-x-6"),
2180
- children: options.map((o) => /* @__PURE__ */ jsx(Checkbox, {
2181
- label: o.label,
2182
- description: o.description,
2183
- disabled: o.disabled,
2184
- invalid,
2185
- checked: value.includes(o.value),
2186
- onCheckedChange: (c) => onChange?.(c ? [...value, o.value] : value.filter((v) => v !== o.value))
2187
- }, o.value))
2188
- })]
2189
- });
2190
- }
2191
- //#endregion
2192
2139
  //#region src/components/ui/checklist.tsx
2193
2140
  /** Uma lista de verificação por finalidade: itens de um checklist usam este componente. */
2194
2141
  function Checklist({ value, onChange, addLabel = "Adicionar item", disabled = false, id, className, ...aria }) {
@@ -3238,139 +3185,6 @@ function Slider({ value, defaultValue = [50], onChange, min = 0, max = 100, step
3238
3185
  });
3239
3186
  }
3240
3187
  //#endregion
3241
- //#region src/components/ui/tabs.tsx
3242
- /** Contador de instâncias, só para o `layoutId` do indicador (ver `indicatorId`). */
3243
- var tabsCreated = 0;
3244
- /**
3245
- * Tabs único. Se as abas não couberem na largura, a mesma lista vira um Select
3246
- * (nunca rolagem lateral). A troca é medida no próprio contêiner, não na tela.
3247
- */
3248
- function Tabs({ items, value, defaultValue, onChange, variant = "line", className, ...aria }) {
3249
- const [inner, setInner] = useState(defaultValue ?? items[0]?.value ?? "");
3250
- const current = value ?? inner;
3251
- const set = (v) => {
3252
- setInner(v);
3253
- onChange?.(v);
3254
- };
3255
- const boxRef = useRef(null);
3256
- const measureRef = useRef(null);
3257
- const [overflow, setOverflow] = useState(false);
3258
- useLayoutEffect(() => {
3259
- const box = boxRef.current;
3260
- const measure = measureRef.current;
3261
- if (!box || !measure) return;
3262
- const check = () => setOverflow(measure.scrollWidth > box.clientWidth + 1);
3263
- check();
3264
- const ro = new ResizeObserver(check);
3265
- ro.observe(box);
3266
- return () => ro.disconnect();
3267
- }, [items, variant]);
3268
- const presets = useMotionPresets();
3269
- const on = useLayoutReady();
3270
- const lib = useMotionLib();
3271
- const listRef = useRef(null);
3272
- const [clip, setClip] = useState({
3273
- l: 0,
3274
- r: 0
3275
- });
3276
- useLayoutEffect(() => {
3277
- const list = listRef.current;
3278
- if (!on || !list) return;
3279
- const measure = () => {
3280
- const active = list.querySelector("[role=\"tab\"][data-state=\"active\"]");
3281
- if (!active) return;
3282
- const l = active.offsetLeft;
3283
- const r = list.offsetWidth - l - active.offsetWidth;
3284
- setClip((prev) => prev.l === l && prev.r === r ? prev : {
3285
- l,
3286
- r
3287
- });
3288
- };
3289
- measure();
3290
- const ro = new ResizeObserver(measure);
3291
- ro.observe(list);
3292
- return () => ro.disconnect();
3293
- }, [
3294
- on,
3295
- current,
3296
- items,
3297
- variant,
3298
- overflow
3299
- ]);
3300
- const [indicatorId] = useState(() => `rendra-tabs-${++tabsCreated}`);
3301
- 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");
3302
- const indicator = lib && /* @__PURE__ */ jsx(lib.m.span, {
3303
- layoutId: indicatorId,
3304
- "data-indicator": "tabs",
3305
- "aria-hidden": true,
3306
- transition: presets.move,
3307
- 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"
3308
- });
3309
- const list = cn("flex", variant === "line" ? "gap-2 border-b" : "gap-1 rounded-control bg-muted p-1");
3310
- const label = (it) => /* @__PURE__ */ jsxs(Fragment$1, { children: [
3311
- it.icon,
3312
- it.label,
3313
- it.count !== void 0 && /* @__PURE__ */ jsx("span", {
3314
- className: "rounded-full bg-muted px-2 text-xs text-muted-foreground tabular-nums",
3315
- children: it.count
3316
- })
3317
- ] });
3318
- return /* @__PURE__ */ jsxs(Tabs$1.Root, {
3319
- value: current,
3320
- onValueChange: set,
3321
- "data-rendra": resolveCatalogCode("Tabs", { variant }),
3322
- className: cn("flex min-w-0 flex-col gap-6", className),
3323
- children: [/* @__PURE__ */ jsxs("div", {
3324
- ref: boxRef,
3325
- className: "relative min-w-0",
3326
- children: [/* @__PURE__ */ jsx("div", {
3327
- ref: measureRef,
3328
- "aria-hidden": true,
3329
- className: cn(list, "invisible absolute w-max"),
3330
- children: items.map((it) => /* @__PURE__ */ jsx("span", {
3331
- className: trigger,
3332
- children: label(it)
3333
- }, it.value))
3334
- }), overflow ? /* @__PURE__ */ jsx(Select, {
3335
- label: aria["aria-label"] ?? "Seção",
3336
- value: current,
3337
- onChange: (v) => v && set(v),
3338
- options: items.map((it) => ({
3339
- value: it.value,
3340
- label: it.count !== void 0 ? `${it.label} (${it.count})` : it.label,
3341
- disabled: it.disabled
3342
- }))
3343
- }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Tabs$1.List, {
3344
- ref: listRef,
3345
- "aria-label": aria["aria-label"],
3346
- className: list,
3347
- children: items.map((it) => /* @__PURE__ */ jsxs(Tabs$1.Trigger, {
3348
- value: it.value,
3349
- disabled: it.disabled,
3350
- className: trigger,
3351
- children: [on && current === it.value && indicator, label(it)]
3352
- }, it.value))
3353
- }), on && /* @__PURE__ */ jsx("div", {
3354
- "data-tabs-copy": true,
3355
- "aria-hidden": true,
3356
- className: cn(list, "pointer-events-none absolute inset-0 border-transparent bg-transparent text-foreground tabs-clip"),
3357
- style: {
3358
- "--tabs-l": `${clip.l}px`,
3359
- "--tabs-r": `${clip.r}px`
3360
- },
3361
- children: items.map((it) => /* @__PURE__ */ jsx("span", {
3362
- className: cn(trigger, "text-foreground"),
3363
- children: label(it)
3364
- }, it.value))
3365
- })] })]
3366
- }), items.map((it) => /* @__PURE__ */ jsx(Tabs$1.Content, {
3367
- value: it.value,
3368
- className: "min-w-0 outline-none",
3369
- children: it.content
3370
- }, it.value))]
3371
- });
3372
- }
3373
- //#endregion
3374
3188
  //#region src/lib/sortable.ts
3375
3189
  var DEFAULT_ATTR = "data-sortable-id";
3376
3190
  /**
@@ -6101,108 +5915,6 @@ function QrCode({ value, size = 160, errorCorrection = "medium", className, empt
6101
5915
  });
6102
5916
  }
6103
5917
  //#endregion
6104
- //#region src/components/ui/radio-group.tsx
6105
- var cols = {
6106
- 1: "",
6107
- 2: "md:grid-cols-2",
6108
- 3: "md:grid-cols-3"
6109
- };
6110
- /**
6111
- * O item do Radix. Em `on` ele é um `m.button` (asChild) que responde ao toque (whileTap 0,97,
6112
- * em `press`); em `off` é o `R.Item` de sempre, sem nó novo.
6113
- */
6114
- function Item({ children, ...props }) {
6115
- const presets = useMotionPresets();
6116
- const lib = useMotionLib();
6117
- if (!lib) return /* @__PURE__ */ jsx(RadioGroup$1.Item, {
6118
- ...props,
6119
- children
6120
- });
6121
- return /* @__PURE__ */ jsx(RadioGroup$1.Item, {
6122
- asChild: true,
6123
- ...props,
6124
- children: /* @__PURE__ */ jsx(lib.m.button, {
6125
- type: "button",
6126
- whileTap: presets.press.whileTap,
6127
- transition: presets.press.transition,
6128
- children
6129
- })
6130
- });
6131
- }
6132
- /** Radio único: em lista ou em cards, por prop. */
6133
- function RadioGroup({ options, value, defaultValue, onChange, variant = "list", columns = 2, orientation = "vertical", invalid, disabled, id, name, ...aria }) {
6134
- const lib = useMotionLib();
6135
- const on = lib !== null;
6136
- const presets = useMotionPresets();
6137
- const [inner, setInner] = useState(defaultValue);
6138
- const current = value ?? inner;
6139
- const dotFor = (optionValue) => /* @__PURE__ */ jsx("span", {
6140
- "aria-hidden": true,
6141
- 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"),
6142
- children: on ? /* @__PURE__ */ jsx(lib.m.span, {
6143
- className: "size-2 rounded-full bg-primary",
6144
- initial: false,
6145
- animate: current === optionValue ? presets.indicator.animate : presets.indicator.initial,
6146
- transition: presets.indicator.transition
6147
- }) : /* @__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" })
6148
- });
6149
- return /* @__PURE__ */ jsx(RadioGroup$1.Root, {
6150
- id,
6151
- name,
6152
- value: on ? current : value,
6153
- defaultValue: on ? void 0 : defaultValue,
6154
- onValueChange: (v) => {
6155
- if (on) setInner(v);
6156
- onChange?.(v);
6157
- },
6158
- disabled,
6159
- "aria-invalid": invalid || void 0,
6160
- "aria-describedby": aria["aria-describedby"],
6161
- "aria-label": aria["aria-label"],
6162
- "data-rendra": resolveCatalogCode("RadioGroup", { variant }),
6163
- 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"),
6164
- children: options.map((o) => variant === "cards" ? /* @__PURE__ */ jsxs(Item, {
6165
- value: o.value,
6166
- disabled: o.disabled,
6167
- 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"),
6168
- children: [
6169
- o.icon && /* @__PURE__ */ jsx("span", {
6170
- className: "flex size-control-sm shrink-0 items-center justify-center rounded-control bg-muted text-foreground transition-colors group-data-[state=checked]:bg-primary group-data-[state=checked]:text-primary-foreground md:size-control-md [&_svg]:size-icon-md",
6171
- children: o.icon
6172
- }),
6173
- /* @__PURE__ */ jsxs("span", {
6174
- className: "flex min-w-0 flex-1 flex-col gap-1",
6175
- children: [/* @__PURE__ */ jsx("span", {
6176
- className: "text-sm font-semibold",
6177
- children: o.label
6178
- }), o.description && /* @__PURE__ */ jsx("span", {
6179
- className: "text-sm text-muted-foreground",
6180
- children: o.description
6181
- })]
6182
- }),
6183
- dotFor(o.value)
6184
- ]
6185
- }, o.value) : /* @__PURE__ */ jsxs("label", {
6186
- 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"),
6187
- children: [/* @__PURE__ */ jsx(Item, {
6188
- value: o.value,
6189
- disabled: o.disabled,
6190
- className: "group flex pt-px outline-none focus-visible:[&>span]:focus-ring",
6191
- children: dotFor(o.value)
6192
- }), /* @__PURE__ */ jsxs("span", {
6193
- className: "flex min-w-0 flex-col gap-1",
6194
- children: [/* @__PURE__ */ jsx("span", {
6195
- className: "text-sm font-medium",
6196
- children: o.label
6197
- }), o.description && /* @__PURE__ */ jsx("span", {
6198
- className: "text-sm text-muted-foreground",
6199
- children: o.description
6200
- })]
6201
- })]
6202
- }, o.value))
6203
- });
6204
- }
6205
- //#endregion
6206
5918
  //#region src/components/ui/rating.tsx
6207
5919
  function toneClass(ratio) {
6208
5920
  if (ratio <= 1 / 3) return "data-[state=checked]:border-destructive data-[state=checked]:bg-destructive-soft data-[state=checked]:text-destructive-soft-foreground";
@@ -7255,103 +6967,6 @@ function Table({ data: dataProp, source, queryKey = "", columns: columnsProp, st
7255
6967
  });
7256
6968
  }
7257
6969
  //#endregion
7258
- //#region src/components/ui/textarea.tsx
7259
- /** Textarea único, com contador opcional. Cresce com o conteúdo até a altura máxima e depois rola por dentro. */
7260
- var Textarea = forwardRef(function Textarea({ invalid, counter, value, defaultValue, onChange, maxLength, rows = 4, className, ...props }, ref) {
7261
- const [inner, setInner] = useState(String(value ?? defaultValue ?? ""));
7262
- const current = value ?? inner;
7263
- return /* @__PURE__ */ jsxs("div", {
7264
- className: cn("flex min-w-0 flex-col gap-1", className),
7265
- children: [/* @__PURE__ */ jsx("textarea", {
7266
- ref,
7267
- rows,
7268
- maxLength,
7269
- value: current,
7270
- "data-rendra": "TXT-001",
7271
- "aria-invalid": invalid || void 0,
7272
- onChange: (e) => {
7273
- setInner(e.target.value);
7274
- onChange?.(e.target.value);
7275
- },
7276
- className: cn("field-sizing-content max-h-chart-md min-h-24 w-full resize-y rounded-control border border-input bg-field px-3 py-2 text-base transition-[border-color,box-shadow] outline-none placeholder:text-muted-foreground hover:border-foreground/40 focus:border-ring focus:bg-card focus:ring-2 focus:ring-ring/25 disabled:cursor-not-allowed disabled:opacity-60 md:text-sm", invalid && "border-destructive focus:border-destructive focus:ring-destructive/25"),
7277
- ...props
7278
- }), counter && /* @__PURE__ */ jsxs("span", {
7279
- "aria-live": "polite",
7280
- className: cn("self-end text-xs text-muted-foreground tabular-nums", maxLength && current.length >= maxLength && "font-medium text-destructive"),
7281
- children: [current.length, maxLength ? `/${maxLength}` : ""]
7282
- })]
7283
- });
7284
- });
7285
- //#endregion
7286
- //#region src/components/ui/toast.tsx
7287
- var tone = {
7288
- success: "border-success/25",
7289
- error: "border-destructive/25",
7290
- warning: "border-warning/25",
7291
- info: "border-info/25"
7292
- };
7293
- function show(type, title, opts = {}) {
7294
- return toast$1.custom((id) => /* @__PURE__ */ jsxs("div", {
7295
- role: type === "error" ? "alert" : "status",
7296
- "data-rendra": "TST-001",
7297
- className: cn("flex w-full items-start gap-3 rounded-control border bg-popover p-4 text-popover-foreground shadow-lg", tone[type]),
7298
- children: [
7299
- /* @__PURE__ */ jsx(BrandFeedbackIcon, {
7300
- type,
7301
- size: "lg",
7302
- animated: true,
7303
- className: "mt-px"
7304
- }),
7305
- /* @__PURE__ */ jsxs("div", {
7306
- className: "flex min-w-0 flex-1 flex-col gap-1",
7307
- children: [/* @__PURE__ */ jsx("p", {
7308
- className: "text-sm font-semibold wrap-break-word",
7309
- children: title
7310
- }), opts.description && /* @__PURE__ */ jsx("p", {
7311
- className: "text-sm wrap-break-word text-muted-foreground",
7312
- children: opts.description
7313
- })]
7314
- }),
7315
- opts.action && /* @__PURE__ */ jsx("button", {
7316
- type: "button",
7317
- onClick: () => {
7318
- opts.action?.onClick();
7319
- toast$1.dismiss(id);
7320
- },
7321
- className: "-my-1 flex min-h-touch shrink-0 cursor-pointer items-center rounded-item px-2 text-sm font-semibold text-primary-text hover:bg-accent md:min-h-0 md:py-1",
7322
- children: opts.action.label
7323
- })
7324
- ]
7325
- }), { duration: opts.duration ?? (type === "error" ? 8e3 : 4e3) });
7326
- }
7327
- var toast = {
7328
- success: (title, opts) => show("success", title, opts),
7329
- error: (title, opts) => show("error", title, opts),
7330
- warning: (title, opts) => show("warning", title, opts),
7331
- info: (title, opts) => show("info", title, opts),
7332
- dismiss: toast$1.dismiss
7333
- };
7334
- /** Posição: embaixo no centro no mobile (perto do polegar), canto inferior direito no desktop. */
7335
- function Toaster() {
7336
- const { isMobile } = useBreakpoint();
7337
- const { resolvedMode } = useBrand();
7338
- return /* @__PURE__ */ jsx(Toaster$1, {
7339
- position: isMobile ? "bottom-center" : "bottom-right",
7340
- theme: resolvedMode,
7341
- offset: 16,
7342
- mobileOffset: {
7343
- bottom: 88,
7344
- left: 16,
7345
- right: 16
7346
- },
7347
- visibleToasts: 3,
7348
- toastOptions: {
7349
- unstyled: true,
7350
- className: "w-full"
7351
- }
7352
- });
7353
- }
7354
- //#endregion
7355
6970
  //#region src/components/ui/upload.tsx
7356
6971
  var formatSize = (b) => b < 1048576 ? `${Math.max(1, Math.round(b / 1024))} KB` : `${(b / 1024 / 1024).toLocaleString("pt-BR", { maximumFractionDigits: 1 })} MB`;
7357
6972
  function kindOf(file) {