@rendra-ui/web 2.7.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 (64) hide show
  1. package/README.md +16 -16
  2. package/dist/base.css +1 -1
  3. package/dist/{button-DlzWwpZk.js → button-BcCBrlnt.js} +6 -6
  4. package/dist/{button-DlzWwpZk.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-B0N3Pek0.js → cn-CpdCvlkP.js} +2 -2
  13. package/dist/{cn-B0N3Pek0.js.map → cn-CpdCvlkP.js.map} +1 -1
  14. package/dist/{components-CpQPMGfT.js → components-Bus_Jh2R.js} +9 -6
  15. package/dist/components-Bus_Jh2R.js.map +1 -0
  16. package/dist/components.css +85 -26
  17. package/dist/document-viewer.js +4 -4
  18. package/dist/{dropdown-menu-M8vs0byD.js → dropdown-menu-B3L1XSDf.js} +5 -5
  19. package/dist/{dropdown-menu-M8vs0byD.js.map → dropdown-menu-B3L1XSDf.js.map} +1 -1
  20. package/dist/{brand-feedback-icon-BYNcqBel.js → empty-state-Bcx4M0Me.js} +64 -4
  21. package/dist/empty-state-Bcx4M0Me.js.map +1 -0
  22. package/dist/{features-max-ScxV8gb3.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 +875 -681
  26. package/dist/index.js.map +1 -1
  27. package/dist/{motion-context-BUMPf0e9.js → motion-context-DWFl2xRr.js} +4 -4
  28. package/dist/{motion-context-BUMPf0e9.js.map → motion-context-DWFl2xRr.js.map} +1 -1
  29. package/dist/{motion-on-CNN6y8g-.js → motion-on-zwsBqYZL.js} +2 -2
  30. package/dist/{motion-on-CNN6y8g-.js.map → motion-on-zwsBqYZL.js.map} +1 -1
  31. package/dist/motion.js +2 -2
  32. package/dist/{rendra-provider-DEURIIL3.js → rendra-provider-DuIhBatD.js} +3 -3
  33. package/dist/{rendra-provider-DEURIIL3.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-BOh7gUdA.js → toast-C7qYslCp.js} +464 -80
  37. package/dist/toast-C7qYslCp.js.map +1 -0
  38. package/dist/tokens.css +9 -1
  39. package/dist/{tooltip-Ym9S4h9_.js → tooltip-BSPO-bH4.js} +5 -5
  40. package/dist/{tooltip-Ym9S4h9_.js.map → tooltip-BSPO-bH4.js.map} +1 -1
  41. package/dist/types/components/ui/data-toolbar.d.ts +6 -1
  42. package/dist/types/components/ui/flow-config-panels.d.ts +10 -0
  43. package/dist/types/components/ui/flow-editor.d.ts +5 -0
  44. package/dist/types/components/ui/flow-sidebar.d.ts +21 -0
  45. package/dist/types/components/ui/flow-simulation-panel.d.ts +20 -0
  46. package/dist/types/components/ui/flow-viewer.d.ts +27 -10
  47. package/dist/types/components/ui/kanban.d.ts +75 -6
  48. package/dist/types/flow.d.ts +1 -1
  49. package/dist/types/lib/flow-blocks.d.ts +122 -0
  50. package/dist/types/lib/flow-edit.d.ts +88 -0
  51. package/dist/types/lib/flow-layout.d.ts +3 -0
  52. package/dist/types/lib/flow-sim.d.ts +24 -0
  53. package/dist/types/lib/flow.d.ts +30 -80
  54. package/dist/{use-breakpoint-En17oXKY.js → use-breakpoint-BGmY3ir-.js} +2 -2
  55. package/dist/{use-breakpoint-En17oXKY.js.map → use-breakpoint-BGmY3ir-.js.map} +1 -1
  56. package/dist/{use-motion-presets-D3ww1oJX.js → use-motion-presets-CmMLBQLI.js} +3 -3
  57. package/dist/{use-motion-presets-D3ww1oJX.js.map → use-motion-presets-CmMLBQLI.js.map} +1 -1
  58. package/dist/widget-grid.js +2 -2
  59. package/package.json +3 -1
  60. package/dist/brand-feedback-icon-BYNcqBel.js.map +0 -1
  61. package/dist/components-CpQPMGfT.js.map +0 -1
  62. package/dist/empty-state-a47Kd_Ci.js +0 -67
  63. package/dist/empty-state-a47Kd_Ci.js.map +0 -1
  64. package/dist/timeline-BOh7gUdA.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"timeline-BOh7gUdA.js","names":[],"sources":["../src/components/app-shell/shell-context.ts","../src/components/ui/action-bar.tsx","../src/components/ui/alert.tsx","../src/components/ui/overlay-shell.tsx","../src/components/ui/modal.tsx","../src/components/ui/info-hint.tsx","../src/components/ui/card.tsx","../src/lib/lookup.ts","../src/hooks/use-lookup.ts","../src/lib/control.ts","../src/lib/masks.ts","../src/components/ui/input.tsx","../src/components/ui/picker-panel.tsx","../src/components/ui/drawer.tsx","../src/components/layout/tokens.ts","../src/components/ui/field.tsx","../src/components/ui/select.tsx","../src/hooks/use-fill-height.ts","../src/components/ui/timeline.tsx"],"sourcesContent":["import { createContext, useContext, type ReactNode } from 'react'\nimport type { ShellLayout } from './layout'\nimport type { NavigationTarget } from './navigation-utils'\nimport type {\n NavGroup,\n NavItem,\n ShellMenuItem,\n ShellNotificationsConfig,\n ShellUser,\n ShellUserMenuConfig,\n ShellWorkspacesConfig,\n} from './types'\n\nexport interface ShellContextValue {\n /** Layout efetivo: padrão interno + prop `layout` do AppShell + escolha do usuário. */\n layout: ShellLayout\n /** Altera uma opção de layout (guardada no navegador do usuário). */\n setLayout: <K extends keyof ShellLayout>(key: K, value: ShellLayout[K]) => void\n /** Altera várias opções de uma vez (ex.: um código de menu M1 a M6). */\n applyLayout: (partial: Partial<ShellLayout>) => void\n /** Volta ao layout padrão do projeto. */\n resetLayout: () => void\n /** Gaveta de navegação aberta no mobile. */\n mobileNavOpen: boolean\n setMobileNavOpen: (open: boolean) => void\n /**\n * Espaço do rodapé fixo da página, entre o conteúdo e a barra inferior. A ActionBar\n * sticky é desenhada aqui: fica sempre colada embaixo, na largura inteira.\n */\n footerSlot: HTMLElement | null\n /** Texto orientativo da tela (PageHeader help): o header mostra o ícone ao lado do título. */\n pageHelp: ReactNode\n setPageHelp: (help: ReactNode) => void\n /** Busca global (Ctrl+K). */\n searchOpen: boolean\n setSearchOpen: (open: boolean) => void\n /** Menu do sistema, recebido pela prop `navigation` do AppShell (obrigatória). */\n navigation: NavGroup[]\n /** Até 4 itens marcados `bottomNav`, calculados a partir de `navigation`. */\n bottomNavItems: NavItem[]\n /** Lista plana de destinos: busca global e cálculo do item ativo. */\n navigationTargets: NavigationTarget[]\n /** Usuário exibido no menu do avatar e no rodapé da sidebar. */\n user: ShellUser\n /** Itens do menu do avatar (ex.: \"Meu perfil\", \"Configurações\"). */\n userMenuItems: ShellMenuItem[]\n /** Chamado ao selecionar \"Sair\". Sem ele, o botão não faz nada. */\n onLogout?: () => void\n /** Rótulo do destino inicial na trilha do header. */\n homeLabel: string\n /** Ações rápidas da busca global (ex.: \"Novo cliente\"). */\n quickActions: ShellMenuItem[]\n /** Notificações do sino do header. Sem esta prop, o sino não aparece. */\n notifications?: ShellNotificationsConfig\n /** Submenus Tema, Template e Layout do menu do avatar. Sem esta prop, os três aparecem. */\n userMenu?: ShellUserMenuConfig\n /** Seletor de espaço no topo do menu do avatar. Sem esta prop, não aparece. */\n workspaces?: ShellWorkspacesConfig\n /** Logo que ocupa o lugar do título e da trilha no header, abaixo de `md`. */\n headerLogo?: ReactNode\n}\n\nexport const ShellContext = createContext<ShellContextValue | null>(null)\n\nexport function useShell() {\n const ctx = useContext(ShellContext)\n if (!ctx) throw new Error('useShell precisa estar dentro de <AppShell>.')\n return ctx\n}\n","import { MoreHorizontal } from 'lucide-react'\nimport { useContext, type ReactNode } from 'react'\nimport { createPortal } from 'react-dom'\nimport { ShellContext } from '@/components/app-shell/shell-context'\nimport { Button } from '@/components/ui/button'\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@/components/ui/dropdown-menu'\nimport { cn } from '@/lib/cn'\n\nexport interface ActionBarAction {\n label: string\n onClick?: () => void\n icon?: ReactNode\n disabled?: boolean\n destructive?: boolean\n}\n\nexport interface ActionBarProps {\n /** Ação principal: sempre primária (ou destrutiva), 70% da largura. */\n primary: ActionBarAction & {\n type?: 'button' | 'submit'\n form?: string\n loading?: boolean\n loadingLabel?: string\n }\n /** Cancelar: sempre outline, 30% à esquerda. Sem ele, a principal ocupa 100%. */\n cancel?: ActionBarAction\n /** A partir da terceira ação: vão para o menu de três pontinhos. */\n secondary?: ActionBarAction[]\n /**\n * sticky: rodapé fixo das telas de formulário. Fica sempre colado embaixo, na largura\n * inteira, fora da área rolável (nunca sobe, mesmo com formulário curto). Em drawer e\n * modal o rodapé já é fixo; no wizard os botões seguem junto do card. Como o botão fica\n * fora do <form>, use primary.form com o id do formulário para enviar.\n */\n sticky?: boolean\n className?: string\n}\n\n/**\n * Barra de ações única, com a regra de botões do sistema:\n * 1 botão = 100%; 2 botões = cancelar 30% + principal 70%; 3 ou mais = extras no menu.\n * Vale para drawer, modal e formulário em página, em qualquer tamanho de tela.\n */\nexport function ActionBar({ primary, cancel, secondary, sticky, className }: ActionBarProps) {\n const slot = useContext(ShellContext)?.footerSlot\n const hasMenu = Boolean(secondary?.length)\n const layout = cancel\n ? hasMenu\n ? 'grid-actions-3'\n : 'grid-actions-2'\n : hasMenu\n ? 'grid-actions-3'\n : ''\n\n const bar = (\n <div\n data-rendra=\"ACB-001\"\n className={cn(\n sticky && 'border-t bg-card px-4 pt-4 pb-safe md:px-6',\n // Fora do AppShell (Storybook, telas soltas): fixo no fim da área rolável.\n sticky && !slot && 'sticky bottom-0 z-20',\n className,\n )}\n >\n <div className={cn('grid gap-3', layout || 'grid-cols-1', sticky && 'w-full')}>\n {hasMenu && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"outline\" iconOnly aria-label=\"Mais ações\">\n <MoreHorizontal />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" side=\"top\">\n {secondary!.map((a) => (\n <DropdownMenuItem\n key={a.label}\n onSelect={a.onClick}\n disabled={a.disabled}\n destructive={a.destructive}\n >\n {a.icon}\n {a.label}\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n {cancel ? (\n <Button\n variant=\"outline\"\n icon={cancel.icon}\n onClick={cancel.onClick}\n disabled={cancel.disabled || primary.loading}\n fullWidth\n >\n {cancel.label}\n </Button>\n ) : hasMenu ? (\n <span aria-hidden />\n ) : null}\n <Button\n type={primary.type ?? 'button'}\n form={primary.form}\n variant={primary.destructive ? 'destructive' : 'primary'}\n icon={primary.icon}\n onClick={primary.onClick}\n disabled={primary.disabled}\n loading={primary.loading}\n fullWidth\n >\n {primary.loading ? (primary.loadingLabel ?? 'Salvando...') : primary.label}\n </Button>\n </div>\n </div>\n )\n return sticky && slot ? createPortal(bar, slot) : bar\n}\n","import { cva, type VariantProps } from 'class-variance-authority'\nimport { X } from 'lucide-react'\nimport type { ReactNode } from 'react'\nimport { useBrand } from '@/brand/use-brand'\nimport type { FeedbackType } from '@/brand/types'\nimport { BrandFeedbackIcon } from '@/components/ui/brand-feedback-icon'\nimport { cn } from '@/lib/cn'\n\n/**\n * Alert único do sistema: ícone da marca à esquerda, título em destaque e descrição.\n * O tipo é prop; o formato vem do template ativo (quadrado, meio-termo ou arredondado).\n */\nconst alertVariants = cva('flex w-full min-w-0 items-start gap-3 rounded-control border', {\n variants: {\n type: {\n success: 'border-success/25 bg-success-soft text-success-soft-foreground',\n error: 'border-destructive/25 bg-destructive-soft text-destructive-soft-foreground',\n warning: 'border-warning/25 bg-warning-soft text-warning-soft-foreground',\n info: 'border-info/25 bg-info-soft text-info-soft-foreground',\n },\n },\n defaultVariants: { type: 'info' },\n})\n\nexport interface AlertProps extends VariantProps<typeof alertVariants> {\n type: FeedbackType\n /** Título curto, em negrito. */\n title: ReactNode\n /** Texto de apoio abaixo do título. */\n description?: ReactNode\n /** Ação opcional à direita (ex.: botão \"Desfazer\"). */\n action?: ReactNode\n /** Mostra botão de fechar. */\n onDismiss?: () => void\n /** Anima o ícone na entrada (check se formando, X se riscando). */\n animated?: boolean\n className?: string\n}\n\nexport function Alert({\n type,\n title,\n description,\n action,\n onDismiss,\n animated = false,\n className,\n}: AlertProps) {\n const { shape } = useBrand()\n const pill = shape === 'pill'\n return (\n <div\n role={type === 'error' || type === 'warning' ? 'alert' : 'status'}\n data-rendra=\"ALRT-001\"\n className={cn(\n alertVariants({ type }),\n pill ? 'items-center py-3 pr-4 pl-4 md:pr-6' : 'p-4',\n className,\n )}\n >\n <BrandFeedbackIcon\n type={type}\n size=\"lg\"\n animated={animated}\n className={cn(!pill && 'mt-px')}\n />\n <div className={cn('flex min-w-0 flex-1 flex-col', !pill && 'gap-1')}>\n <p className=\"text-sm font-semibold\">{title}</p>\n {description && <p className=\"text-sm opacity-90\">{description}</p>}\n </div>\n {action && <div className=\"shrink-0 self-center\">{action}</div>}\n {onDismiss && (\n <button\n type=\"button\"\n onClick={onDismiss}\n aria-label=\"Fechar aviso\"\n className={cn(\n 'flex size-touch shrink-0 items-center justify-center rounded-full transition-colors hover:bg-card/60 md:size-8',\n pill ? '-my-2' : '-mt-2 -mr-2',\n )}\n >\n <X className=\"size-icon-sm\" aria-hidden />\n </button>\n )}\n </div>\n )\n}\n","import { X } from 'lucide-react'\nimport { Dialog } from 'radix-ui'\nimport type { ReactNode } from 'react'\nimport { cn } from '@/lib/cn'\n\n/*\n * Estrutura interna de Drawer e Modal (não usar direto nas telas):\n * header fixo (ícone, título, descrição, fechar), body como única área rolável\n * e footer fixo com borda superior, respeitando a área segura do aparelho.\n */\n\ninterface OverlayShellProps {\n title: ReactNode\n description?: ReactNode\n icon?: ReactNode\n children: ReactNode\n footer?: ReactNode\n /** Esconde o header visualmente (o título continua para leitores de tela). */\n hideHeader?: boolean\n onRequestClose: () => void\n bodyClassName?: string\n}\n\nexport function OverlayShell({\n title,\n description,\n icon,\n children,\n footer,\n hideHeader,\n onRequestClose,\n bodyClassName,\n}: OverlayShellProps) {\n const closeButton = (\n <button\n type=\"button\"\n onClick={onRequestClose}\n aria-label=\"Fechar\"\n className={cn(\n '-mt-1 -mr-2 flex size-touch shrink-0 cursor-pointer items-center justify-center rounded-item text-muted-foreground transition-colors hover:bg-accent hover:text-foreground md:size-control-md',\n // Sem cabeçalho visível, o botão sai do header oculto e fica invisível (sem clip, para\n // receber clique e foco), aparecendo só com foco de teclado.\n hideHeader &&\n 'pointer-events-auto m-0 cursor-default opacity-0 focus-visible:cursor-pointer focus-visible:opacity-100',\n )}\n >\n <X className=\"size-icon-md\" aria-hidden />\n </button>\n )\n\n return (\n <>\n {hideHeader && (\n <div 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\">\n {closeButton}\n </div>\n )}\n <header\n className={cn(\n 'flex shrink-0 items-start gap-3 border-b px-4 pt-safe pb-4 md:px-6 md:pt-6',\n hideHeader && 'sr-only',\n )}\n >\n {icon && (\n <span\n aria-hidden\n className=\"flex size-control-md shrink-0 items-center justify-center rounded-control bg-primary-soft text-primary-soft-foreground [&_svg]:size-icon-md\"\n >\n {icon}\n </span>\n )}\n <div className=\"flex min-w-0 flex-1 flex-col gap-1 pt-1\">\n <Dialog.Title className=\"text-lg font-semibold wrap-break-word\">{title}</Dialog.Title>\n {description ? (\n <Dialog.Description className=\"text-sm wrap-break-word text-muted-foreground\">\n {description}\n </Dialog.Description>\n ) : (\n <Dialog.Description className=\"sr-only\">{title}</Dialog.Description>\n )}\n </div>\n {!hideHeader && closeButton}\n </header>\n <div\n className={cn(\n 'min-h-0 flex-1 overflow-y-auto overscroll-contain px-4 py-6 md:px-6',\n bodyClassName,\n )}\n >\n {children}\n </div>\n {footer && (\n <footer className=\"shrink-0 border-t bg-card px-4 pt-4 pb-safe md:px-6 md:pb-6\">\n {footer}\n </footer>\n )}\n </>\n )\n}\n","import { Dialog } from 'radix-ui'\nimport { useState, type ReactNode } from 'react'\nimport { resolveCatalogCode } from '@/catalog/components'\nimport { BrandFeedbackIcon } from '@/components/ui/brand-feedback-icon'\nimport { ActionBar } from '@/components/ui/action-bar'\nimport { cn } from '@/lib/cn'\nimport { useBreakpoint } from '@/hooks/use-breakpoint'\nimport { useMotionLib, useMotionPresets } from '@/lib/motion'\nimport { OverlayShell } from './overlay-shell'\n\n/*\n * Modal único. Só para confirmações, mensagens e formulários de até 3 campos simples.\n * Mais que isso vai em Drawer (até ~12 campos) ou em página inteira. Nunca modal dentro de modal.\n * type confirm pergunta com ícone de info e ação principal primária\n * type destructive ação irreversível: ícone de erro e ação principal destrutiva\n * type info só informa: um botão de largura total\n * type form até 3 campos no body, ações no rodapé\n */\n\nexport type ModalType = 'confirm' | 'destructive' | 'info' | 'form'\n\nconst sizes = { sm: 'md:max-w-sm', md: 'md:max-w-lg', lg: 'md:max-w-2xl' } as const\n\nexport interface ModalProps {\n open: boolean\n onOpenChange: (open: boolean) => void\n title: string\n description?: ReactNode\n type?: ModalType\n size?: keyof typeof sizes\n /** Conteúdo do body (em form, os campos). */\n children?: ReactNode\n confirmLabel?: string\n /**\n * Rótulo do botão de cancelar. Em `confirm` e `destructive` o padrão é \"Cancelar\". Em `info`\n * não há botão de cancelar: o segundo botão só aparece quando `cancelLabel` é passado.\n */\n cancelLabel?: string\n /** Pode ser assíncrono: o botão mostra carregamento até terminar. */\n onConfirm?: () => void | Promise<void>\n /** id do <form> quando type=\"form\" (o botão principal vira submit dele). */\n formId?: string\n /** Estado de envio controlado de fora (ex.: isSubmitting do React Hook Form). */\n loading?: boolean\n}\n\n// Classes do Tailwind do caminho `off`; em `on` o Motion anima e `tw-animate-css` sai.\nconst overlayCls = 'fixed inset-0 z-50 bg-overlay'\nconst overlayOffCls = cn(\n overlayCls,\n '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',\n)\nconst contentCls = cn(\n // Mobile: tela inteira. Desktop: centralizado.\n 'fixed inset-0 z-50 flex h-dvh flex-col bg-card text-card-foreground outline-none',\n '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',\n)\n\nconst feedback = { confirm: 'info', destructive: 'error', info: 'info' } as const\n\nexport function Modal({\n open,\n onOpenChange,\n title,\n description,\n type = 'confirm',\n size = 'sm',\n children,\n confirmLabel = type === 'destructive' ? 'Excluir' : type === 'info' ? 'Entendi' : 'Confirmar',\n cancelLabel,\n onConfirm,\n formId,\n loading,\n}: ModalProps) {\n const [busy, setBusy] = useState(false)\n const close = () => onOpenChange(false)\n const confirm = async () => {\n if (!onConfirm) return close()\n try {\n setBusy(true)\n await onConfirm()\n close()\n } finally {\n setBusy(false)\n }\n }\n const isForm = type === 'form'\n const lib = useMotionLib()\n const presets = useMotionPresets()\n const { isMobile } = useBreakpoint()\n\n // destructive tem o mesmo formato do confirm (só muda a cor): mesmo código, MOD-001.\n // O desvio fica explícito de propósito: sem ele, destructive só cairia em MOD-001\n // pelo fallback de resolveCatalogCode (o primeiro código do Modal no catálogo), ou\n // seja, dependeria da ordem das entradas em src/catalog/components.ts.\n const code = resolveCatalogCode('Modal', {\n type: type === 'destructive' ? 'confirm' : type,\n })\n const sizeCls = sizes[size]\n const shell = (\n <OverlayShell\n title={title}\n description={isForm ? description : undefined}\n hideHeader={!isForm}\n onRequestClose={close}\n bodyClassName={cn(!isForm && 'flex flex-col items-center justify-center gap-4 text-center')}\n footer={\n <ActionBar\n primary={{\n label: confirmLabel,\n destructive: type === 'destructive',\n loading: busy || loading,\n loadingLabel: `${confirmLabel}...`,\n type: isForm && formId ? 'submit' : 'button',\n form: isForm ? formId : undefined,\n onClick: isForm && formId ? undefined : confirm,\n }}\n cancel={\n type === 'info' && cancelLabel === undefined\n ? undefined\n : { label: cancelLabel ?? 'Cancelar', onClick: close }\n }\n />\n }\n >\n {!isForm && (\n <>\n <BrandFeedbackIcon type={feedback[type as keyof typeof feedback]} size=\"2xl\" animated />\n <div className=\"flex flex-col gap-2\">\n <p className=\"text-lg font-semibold wrap-anywhere\">{title}</p>\n {description && (\n <p className=\"text-sm wrap-anywhere text-muted-foreground\">{description}</p>\n )}\n </div>\n {children}\n </>\n )}\n {isForm && <div className=\"flex flex-col gap-2\">{children}</div>}\n </OverlayShell>\n )\n\n // `on`: o conteúdo só existe enquanto aberto ou saindo (AnimatePresence); o Radix fica com\n // forceMount e o `m.div` entra por asChild, preservando data-rendra e o foco do Dialog.\n if (lib) {\n return (\n <Dialog.Root open={open} onOpenChange={onOpenChange}>\n <lib.AnimatePresence>\n {open && (\n <Dialog.Portal forceMount key=\"modal\">\n <Dialog.Overlay forceMount asChild>\n <lib.m.div className={overlayCls} {...presets.fade} />\n </Dialog.Overlay>\n <Dialog.Content\n forceMount\n asChild\n data-rendra={code}\n className={cn(contentCls, sizeCls)}\n >\n {/* Em tela cheia (celular) a escala do centro perde o sentido: entra de baixo, 8 px. */}\n <lib.m.div {...presets.open(isMobile ? { y: 8 } : undefined)}>{shell}</lib.m.div>\n </Dialog.Content>\n </Dialog.Portal>\n )}\n </lib.AnimatePresence>\n </Dialog.Root>\n )\n }\n\n return (\n <Dialog.Root open={open} onOpenChange={onOpenChange}>\n <Dialog.Portal>\n <Dialog.Overlay className={overlayOffCls} />\n <Dialog.Content\n data-rendra={code}\n className={cn(\n contentCls,\n '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',\n sizeCls,\n )}\n >\n {shell}\n </Dialog.Content>\n </Dialog.Portal>\n </Dialog.Root>\n )\n}\n","import { Info } from 'lucide-react'\nimport { useState, type ReactNode } from 'react'\nimport { Button } from '@/components/ui/button'\nimport { Modal } from '@/components/ui/modal'\nimport { cn } from '@/lib/cn'\n\n/*\n * Texto orientativo (como usar a tela, o que um campo faz, de onde vem um número). Nunca fica\n * solto no corpo da tela nem num botão \"Saiba mais\" avulso: é um ícone de informação discreto,\n * ao lado do título a que se refere, que abre um Modal informativo.\n * Onde aparece: PageHeader help (ao lado do título da tela, no header fixo), CardTitle help e\n * FormSection help (ao lado do título do card). Use direto só quando nenhum desses servir.\n */\n\nexport interface InfoHintProps {\n /** Título do modal (em geral, o título da tela ou da seção). */\n title: string\n /** O texto orientativo. Pode ter parágrafos e listas. */\n children: ReactNode\n className?: string\n}\n\nexport function InfoHint({ title, children, className }: InfoHintProps) {\n const [open, setOpen] = useState(false)\n return (\n // Wrapper sem layout próprio (display: contents): o botão é o único elemento sempre\n // presente (o Modal só monta o próprio conteúdo quando aberto), então o data-rendra\n // do InfoHint vive aqui, não no botão (que já carrega o código do Button).\n <span className=\"contents\" data-rendra=\"INFO-001\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n iconOnly\n aria-label={`Sobre: ${title}`}\n onClick={() => setOpen(true)}\n className={cn(\n 'shrink-0 text-muted-foreground hover:text-primary-text max-md:size-touch',\n className,\n )}\n >\n <Info aria-hidden />\n </Button>\n <Modal open={open} onOpenChange={setOpen} type=\"info\" title={title} size=\"md\">\n <div className=\"flex flex-col gap-3 text-sm text-muted-foreground\">{children}</div>\n </Modal>\n </span>\n )\n}\n","import type { HTMLAttributes, ReactNode } from 'react'\nimport { InfoHint } from '@/components/ui/info-hint'\nimport { cn } from '@/lib/cn'\n\n/**\n * Card: agrupa conteúdo de página. Borda de 1px, sem sombra pesada.\n * Nunca aninhe Card dentro de Card: para hierarquia interna use Separator ou título de seção.\n * Nunca coloque rolagem dentro de Card.\n */\nexport interface CardProps extends HTMLAttributes<HTMLDivElement> {\n /**\n * Uso interno: quando outro componente catalogado (Calendar, FormSection, StatCard,\n * Table) usa o Card como o próprio elemento raiz, ele passa o seu código aqui para que\n * o data-rendra mostre a variante certa, não CARD-001. Sem essa prop, o Card se\n * identifica como CARD-001, o próprio código dele no catálogo.\n */\n 'data-rendra'?: string\n}\n\nexport function Card({ className, 'data-rendra': dataRendra, ...props }: CardProps) {\n return (\n <div\n data-slot=\"card\"\n data-rendra={dataRendra ?? 'CARD-001'}\n className={cn(\n 'flex min-w-0 flex-col rounded-surface border bg-card text-card-foreground',\n className,\n )}\n {...props}\n />\n )\n}\n\nexport interface CardHeaderProps extends HTMLAttributes<HTMLDivElement> {\n /**\n * Ações do card, no canto do cabeçalho (ex.: Ligar, Restaurar padrão). É o lugar das ações\n * de um card: nunca um botão solto no meio do conteúdo.\n */\n actions?: ReactNode\n}\n\nexport function CardHeader({ className, actions, children, ...props }: CardHeaderProps) {\n if (!actions)\n return (\n <div\n data-slot=\"card-header\"\n className={cn('flex flex-col gap-1 p-4 md:p-6', className)}\n {...props}\n >\n {children}\n </div>\n )\n return (\n <div\n data-slot=\"card-header\"\n className={cn(\n 'flex flex-wrap items-start justify-between gap-x-4 gap-y-3 p-4 md:p-6',\n className,\n )}\n {...props}\n >\n <div className=\"flex min-w-0 flex-1 flex-col gap-1\">{children}</div>\n <div className=\"flex shrink-0 items-center gap-2\">{actions}</div>\n </div>\n )\n}\n\nexport interface CardTitleProps extends HTMLAttributes<HTMLHeadingElement> {\n /** Texto orientativo da seção: ícone de informação ao lado do título, que abre um modal. */\n help?: ReactNode\n}\n\nexport function CardTitle({ className, children, help, ...props }: CardTitleProps) {\n const heading = (\n <h3 data-slot=\"card-title\" className={cn('text-lg font-semibold', className)} {...props}>\n {children}\n </h3>\n )\n if (!help) return heading\n return (\n <div className=\"flex min-w-0 items-center gap-1\">\n {heading}\n <InfoHint title={typeof children === 'string' ? children : 'Sobre esta seção'}>\n {help}\n </InfoHint>\n </div>\n )\n}\n\nexport function CardDescription({ className, ...props }: HTMLAttributes<HTMLParagraphElement>) {\n return (\n <p\n data-slot=\"card-description\"\n className={cn('text-sm text-muted-foreground', className)}\n {...props}\n />\n )\n}\n\nexport function CardContent({ className, ...props }: HTMLAttributes<HTMLDivElement>) {\n return (\n <div\n data-slot=\"card-content\"\n className={cn('p-4 md:p-6 [[data-slot=card-header]+&]:pt-0', className)}\n {...props}\n />\n )\n}\n\nexport function CardFooter({ className, ...props }: HTMLAttributes<HTMLDivElement>) {\n return (\n <div\n data-slot=\"card-footer\"\n className={cn('flex items-center gap-3 border-t px-4 py-3 md:px-6', className)}\n {...props}\n />\n )\n}\n","/*\n * Buscas que preenchem o formulário, direto do navegador (APIs públicas e gratuitas, com\n * CORS liberado, sem backend):\n * CEP ViaCEP https://viacep.com.br\n * CNPJ BrasilAPI https://brasilapi.com.br\n * Regra de tela: o campo que faz a busca vem primeiro (25% da linha) e os campos que ele\n * preenche ficam abaixo, para a pessoa saber da busca antes de digitar o resto.\n */\n\nconst digits = (v: string) => v.replace(/\\D/g, '')\n\nexport interface Address {\n cep: string\n logradouro: string\n complemento: string\n bairro: string\n cidade: string\n uf: string\n}\n\n/** Endereço do CEP (8 dígitos). null se não existir; lança erro se a busca falhar. */\nexport async function lookupCep(cep: string, signal?: AbortSignal): Promise<Address | null> {\n const d = digits(cep)\n if (d.length !== 8) return null\n const res = await fetch(`https://viacep.com.br/ws/${d}/json/`, { signal })\n if (!res.ok) throw new Error('Não foi possível buscar o CEP agora.')\n const data = (await res.json()) as Record<string, string | boolean>\n if (data.erro) return null\n return {\n cep: String(data.cep ?? ''),\n logradouro: String(data.logradouro ?? ''),\n complemento: String(data.complemento ?? ''),\n bairro: String(data.bairro ?? ''),\n cidade: String(data.localidade ?? ''),\n uf: String(data.uf ?? ''),\n }\n}\n\nexport interface Company {\n razaoSocial: string\n nomeFantasia: string\n email: string\n telefone: string\n situacao: string\n endereco: Address & { numero: string }\n}\n\n/** Dados públicos do CNPJ (14 dígitos). null se não existir; lança erro se a busca falhar. */\nexport async function lookupCnpj(cnpj: string, signal?: AbortSignal): Promise<Company | null> {\n const d = digits(cnpj)\n if (d.length !== 14) return null\n const res = await fetch(`https://brasilapi.com.br/api/cnpj/v1/${d}`, { signal })\n if (res.status === 404) return null\n if (!res.ok) throw new Error('Não foi possível buscar o CNPJ agora.')\n const data = (await res.json()) as Record<string, string | number | null>\n const s = (k: string) => (data[k] == null ? '' : String(data[k]))\n const fone = digits(s('ddd_telefone_1'))\n return {\n razaoSocial: s('razao_social'),\n nomeFantasia: s('nome_fantasia'),\n email: s('email').toLowerCase(),\n telefone:\n fone.length >= 10 ? `(${fone.slice(0, 2)}) ${fone.slice(2, -4)}-${fone.slice(-4)}` : '',\n situacao: s('descricao_situacao_cadastral'),\n endereco: {\n cep: s('cep'),\n logradouro: [s('descricao_tipo_de_logradouro'), s('logradouro')].filter(Boolean).join(' '),\n numero: s('numero'),\n complemento: s('complemento'),\n bairro: s('bairro'),\n cidade: s('municipio'),\n uf: s('uf'),\n },\n }\n}\n","import { useEffect, useRef, useState } from 'react'\nimport { lookupCep, lookupCnpj, type Address, type Company } from '@/lib/lookup'\n\n/** Resultado da busca embutida no Input (CEP e CNPJ). */\nexport type LookupResult =\n | { status: 'loading'; kind: 'cep' | 'cnpj' }\n | { status: 'found'; kind: 'cep'; data: Address; message: string }\n | { status: 'found'; kind: 'cnpj'; data: Company; message: string }\n | { status: 'not-found'; kind: 'cep' | 'cnpj'; message: string }\n | { status: 'error'; kind: 'cep' | 'cnpj'; message: string }\n\n/**\n * Busca CEP (8 dígitos) ou CNPJ (14 dígitos) assim que o valor fica completo. Cancela a\n * busca anterior quando o valor muda. `kind` 'auto' decide pelo tamanho (CPF ou CNPJ: só\n * o CNPJ busca). Sem `onResult`, não faz nada.\n */\nexport function useLookup(\n kind: 'cep' | 'cnpj' | 'auto' | undefined,\n value: string,\n onResult: ((r: LookupResult) => void) | undefined,\n) {\n const [loading, setLoading] = useState(false)\n const cb = useRef(onResult)\n cb.current = onResult\n const digits = value.replace(/\\D/g, '')\n const target =\n kind === 'cep' && digits.length === 8\n ? 'cep'\n : (kind === 'cnpj' || kind === 'auto') && digits.length === 14\n ? 'cnpj'\n : null\n const enabled = Boolean(onResult) && target !== null\n\n useEffect(() => {\n if (!enabled || !target) return\n const ctrl = new AbortController()\n const send = (r: LookupResult) => {\n if (!ctrl.signal.aborted) cb.current?.(r)\n }\n setLoading(true)\n send({ status: 'loading', kind: target })\n const run =\n target === 'cep'\n ? lookupCep(digits, ctrl.signal).then((data) =>\n data\n ? send({\n status: 'found',\n kind: 'cep',\n data,\n message: 'Endereço preenchido pelo CEP.',\n })\n : send({\n status: 'not-found',\n kind: 'cep',\n message: 'CEP não encontrado. Preencha o endereço.',\n }),\n )\n : lookupCnpj(digits, ctrl.signal).then((data) =>\n data\n ? send({\n status: 'found',\n kind: 'cnpj',\n data,\n message: `${data.situacao ? `Situação: ${data.situacao}. ` : ''}Dados preenchidos pelo CNPJ.`,\n })\n : send({\n status: 'not-found',\n kind: 'cnpj',\n message: 'CNPJ não encontrado. Preencha os dados abaixo.',\n }),\n )\n run\n .catch((e: unknown) =>\n send({\n status: 'error',\n kind: target,\n message: e instanceof Error ? e.message : 'Não foi possível buscar agora.',\n }),\n )\n .finally(() => {\n if (!ctrl.signal.aborted) setLoading(false)\n })\n return () => {\n ctrl.abort()\n setLoading(false)\n }\n }, [enabled, target, digits])\n\n return loading\n}\n","import { cva, type VariantProps } from 'class-variance-authority'\n\n/**\n * Moldura única dos campos (Input, Select, DatePicker, Textarea). Mesma altura dos botões\n * em cada tamanho; fonte de 16px no mobile para o iOS não dar zoom ao focar.\n */\n/** Marque o elemento com data-slot=\"control\": o teste de toque mede a moldura, não o input. */\nexport const controlFrame = cva(\n 'group/control flex w-full min-w-0 items-center gap-2 rounded-control border border-input bg-field text-base text-foreground transition-[border-color,box-shadow] duration-150 focus-within:border-ring focus-within:bg-card focus-within:ring-2 focus-within:ring-ring/25 hover:border-foreground/40 has-[:disabled]:cursor-not-allowed has-[:disabled]:opacity-60 has-[:disabled]:hover:border-input md:text-sm',\n {\n variants: {\n size: {\n sm: 'h-control-sm px-3',\n md: 'h-control-md px-3',\n lg: 'h-control-lg px-4',\n },\n invalid: {\n true: 'border-destructive focus-within:border-destructive focus-within:ring-destructive/25 hover:border-destructive',\n false: '',\n },\n },\n defaultVariants: { size: 'md', invalid: false },\n },\n)\n\nexport type ControlSize = NonNullable<VariantProps<typeof controlFrame>['size']>\n\n/** Classe do <input> nativo dentro da moldura. */\nexport const controlInput =\n 'h-full min-w-0 flex-1 bg-transparent outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed'\n\n/** Botão pequeno dentro da moldura (limpar, mostrar senha). */\nexport const controlAdornmentButton =\n '-mr-2 flex size-control-sm shrink-0 cursor-pointer items-center justify-center rounded-item text-muted-foreground transition-colors outline-none hover:bg-accent hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring md:-mr-1 md:size-8 [&_svg]:size-icon-sm'\n\n/**\n * Reserva, dentro de um gatilho, o espaço do botão sobreposto (limpar do Select e do\n * DatePicker), para o texto não passar por baixo dele.\n */\nexport const controlAdornmentSpace = 'size-control-sm shrink-0 md:size-8'\n","import type { FactoryArg } from 'imask'\n\n/** Máscaras disponíveis na prop mask do Input. Cada uma já define o teclado certo no mobile. */\nexport type MaskName =\n 'cpf' | 'cnpj' | 'cpfCnpj' | 'phone' | 'cep' | 'date' | 'time' | 'currency' | 'percent'\n\ntype InputMode = 'numeric' | 'tel' | 'decimal'\n\nconst numberBlock = (scale: number, max?: number) => ({\n mask: Number,\n scale,\n thousandsSeparator: '.',\n radix: ',',\n mapToRadix: ['.'],\n padFractionalZeros: true,\n normalizeZeros: true,\n min: 0,\n ...(max !== undefined ? { max } : {}),\n})\n\nexport const masks: Record<\n MaskName,\n { options: FactoryArg; inputMode: InputMode; placeholder: string }\n> = {\n cpf: { options: { mask: '000.000.000-00' }, inputMode: 'numeric', placeholder: '000.000.000-00' },\n cnpj: {\n options: { mask: '00.000.000/0000-00' },\n inputMode: 'numeric',\n placeholder: '00.000.000/0000-00',\n },\n // CPF até 11 dígitos, CNPJ a partir do 12º: a máscara troca sozinha.\n cpfCnpj: {\n options: { mask: [{ mask: '000.000.000-00' }, { mask: '00.000.000/0000-00' }] },\n inputMode: 'numeric',\n placeholder: 'CPF ou CNPJ',\n },\n phone: {\n options: { mask: [{ mask: '(00) 0000-0000' }, { mask: '(00) 00000-0000' }] },\n inputMode: 'tel',\n placeholder: '(00) 00000-0000',\n },\n cep: { options: { mask: '00000-000' }, inputMode: 'numeric', placeholder: '00000-000' },\n date: { options: { mask: '00/00/0000' }, inputMode: 'numeric', placeholder: 'DD/MM/AAAA' },\n time: { options: { mask: '00:00' }, inputMode: 'numeric', placeholder: '00:00' },\n currency: {\n options: { mask: 'R$ num', lazy: false, blocks: { num: numberBlock(2) } } as FactoryArg,\n inputMode: 'decimal',\n placeholder: 'R$ 0,00',\n },\n percent: {\n options: { mask: 'num %', lazy: false, blocks: { num: numberBlock(2, 100) } } as FactoryArg,\n inputMode: 'decimal',\n placeholder: '0,00 %',\n },\n}\n\n/** Máscara de percentual com teto configurável (padrão 100), para o Input com unidades (A9). */\nexport function percentMask(max = 100) {\n return {\n options: { mask: 'num %', lazy: false, blocks: { num: numberBlock(2, max) } } as FactoryArg,\n inputMode: 'decimal' as InputMode,\n placeholder: '0,00 %',\n }\n}\n\n/** País para o seletor de DDI do telefone. */\nexport interface PhoneCountry {\n /** DDI sem o \"+\", ex.: \"55\". */\n ddi: string\n /** Nome em português, mostrado na lista. */\n name: string\n}\n\n/** DDI padrão do campo de telefone. */\nexport const DEFAULT_DDI = '55'\n\n/** Lista padrão do seletor de DDI (Brasil primeiro). Troque com a prop ddiOptions do Input. */\nexport const phoneCountries: PhoneCountry[] = [\n { ddi: '55', name: 'Brasil' },\n { ddi: '54', name: 'Argentina' },\n { ddi: '56', name: 'Chile' },\n { ddi: '57', name: 'Colômbia' },\n { ddi: '595', name: 'Paraguai' },\n { ddi: '598', name: 'Uruguai' },\n { ddi: '52', name: 'México' },\n { ddi: '1', name: 'Estados Unidos e Canadá' },\n { ddi: '351', name: 'Portugal' },\n { ddi: '34', name: 'Espanha' },\n { ddi: '33', name: 'França' },\n { ddi: '39', name: 'Itália' },\n { ddi: '49', name: 'Alemanha' },\n { ddi: '44', name: 'Reino Unido' },\n]\n\n/** Máscara do número fora do Brasil: só dígitos, em grupos, até 15 (limite do padrão E.164). */\nexport const internationalPhoneMask = {\n options: { mask: '000 000 000 000 000' } as FactoryArg,\n inputMode: 'tel' as InputMode,\n placeholder: 'Número com DDD',\n}\n\n/** Número completo no padrão internacional: toE164(\"55\", \"(11) 91234-5678\") = \"+5511912345678\". */\nexport function toE164(ddi: string, national: string) {\n const digits = national.replace(/\\D/g, '')\n return digits ? `+${ddi}${digits}` : ''\n}\n\n/** Converte \"R$ 1.250,00\" ou \"12,5 %\" em número. */\nexport function parseLocaleNumber(masked: string): number | null {\n const clean = masked.replace(/[^\\d,-]/g, '').replace(',', '.')\n if (!clean) return null\n const n = Number(clean)\n return Number.isFinite(n) ? n : null\n}\n\n/**\n * Moeda em centavos inteiros, sem erro de arredondamento de ponto flutuante:\n * \"R$ 1.250,50\" -> 125050. Vazio -> null. Use centavos para guardar e somar dinheiro.\n */\nexport function toCents(masked: string): number | null {\n const d = masked.replace(/\\D/g, '')\n if (!d) return null\n const hasDecimals = /,\\d{1,2}\\s*$/.test(masked.replace(/\\s*%$/, ''))\n if (!hasDecimals) return Number(d) * 100\n const [int = '', dec = ''] = masked.replace(/[^\\d,]/g, '').split(',')\n return Number(int || '0') * 100 + Number(dec.padEnd(2, '0').slice(0, 2))\n}\n\n/** Centavos para o texto do campo de moeda: 125050 -> \"R$ 1.250,50\". */\nexport function formatCents(cents: number) {\n return formatCurrency(cents / 100)\n}\n\n/** Formata número como moeda brasileira: 1250 -> \"R$ 1.250,00\". */\nexport function formatCurrency(value: number) {\n return value.toLocaleString('pt-BR', { style: 'currency', currency: 'BRL' })\n}\n","import IMask, { type FactoryArg, type InputMask } from 'imask'\nimport { ChevronDown, Eye, EyeOff, X } from 'lucide-react'\nimport {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n type ChangeEvent,\n type InputHTMLAttributes,\n type ReactNode,\n} from 'react'\nimport { Button } from '@/components/ui/button'\nimport { Spinner } from '@/components/ui/spinner'\nimport { useLookup, type LookupResult } from '@/hooks/use-lookup'\nimport { cn } from '@/lib/cn'\nimport { controlAdornmentButton, controlFrame, controlInput, type ControlSize } from '@/lib/control'\nimport {\n DEFAULT_DDI,\n internationalPhoneMask,\n masks,\n percentMask,\n phoneCountries,\n toCents,\n type MaskName,\n type PhoneCountry,\n} from '@/lib/masks'\n\n/** Uma unidade do seletor embutido do Input (A9). */\nexport interface InputUnitOption {\n /** \"percent\" e \"currency\" ligam a máscara de percentual e de moeda automaticamente. */\n id: string\n label: string\n}\n\nexport interface InputProps extends Omit<\n InputHTMLAttributes<HTMLInputElement>,\n 'size' | 'onChange'\n> {\n size?: ControlSize\n /** Máscara brasileira. Define também o teclado do celular (inputMode). */\n mask?: MaskName\n /** Ícone à esquerda. */\n icon?: ReactNode\n /** Conteúdo fixo à direita (ex.: \"kg\", \"dias\"). Ignorado quando `units` está presente. */\n suffix?: ReactNode\n /** Mostra botão para limpar quando há valor. */\n clearable?: boolean\n /** Estado de erro (normalmente vem do Field). */\n invalid?: boolean\n value?: string\n /** Recebe o valor como aparece no campo (com máscara). */\n onChange?: (value: string) => void\n /** Recebe o valor sem máscara (só dígitos, ou número para moeda e percentual). */\n onValueChange?: (unmasked: string, masked: string) => void\n /**\n * Telefone (mask=\"phone\"): DDI escolhido no seletor embutido à esquerda, sem o \"+\".\n * Padrão \"55\". Com +55 a máscara é a brasileira; com outro DDI, só dígitos.\n * O valor do campo continua sendo o número nacional; o completo sai de toE164(ddi, valor).\n */\n ddi?: string\n onDdiChange?: (ddi: string) => void\n /** Países do seletor de DDI. Padrão: phoneCountries (Brasil primeiro). */\n ddiOptions?: PhoneCountry[]\n /** Esconde o seletor de DDI do telefone (só números brasileiros). */\n hideDdi?: boolean\n /**\n * Moeda (mask=\"currency\"): recebe o valor em centavos inteiros (R$ 1.250,50 -> 125050),\n * ou null quando vazio. Guarde e some dinheiro sempre em centavos.\n */\n onCentsChange?: (cents: number | null) => void\n /**\n * CEP, CNPJ e CPF ou CNPJ (mask=\"cep\", \"cnpj\" ou \"cpfCnpj\"): busca os dados assim que o\n * campo fica completo (ViaCEP e BrasilAPI), mostra o carregamento no campo e entrega o\n * resultado. A tela decide o que preencher; use `result.message` como ajuda do Field.\n */\n onLookup?: (result: LookupResult) => void\n /**\n * Unidades (A9): seletor embutido à direita, no mesmo padrão do seletor de DDI. O id\n * \"percent\" liga a máscara de percentual (teto configurável por `percentMax`); \"currency\"\n * liga a máscara de moeda (R$ 1.250,00). Qualquer outro id não aplica máscara, só rótulo.\n * Trocar de unidade sempre limpa o valor do campo.\n */\n units?: InputUnitOption[]\n /** Unidade escolhida (controlada). Sem ela, usa a primeira de `units`. */\n unit?: string\n onUnitChange?: (unit: string) => void\n /** Teto do percentual quando a unidade escolhida é \"percent\". Padrão 100. */\n percentMax?: number\n /**\n * Variante de valor guardado (A10): mostra `maskedHint` no lugar do valor real, que nunca\n * chega a existir no DOM. \"Trocar\" abre um campo vazio (`isEditing`); cancelar volta à\n * máscara. O componente é controlado pela tela: `isEditing`, `onStartEdit`, `onCancelEdit`.\n */\n variant?: 'secret'\n /** Há um valor salvo (mesmo sem mostrá-lo). */\n hasValue?: boolean\n /** Texto mascarado mostrado no lugar do valor, ex.: \"••••••a1b2c3\". */\n maskedHint?: string\n /** Campo aberto para digitar um valor novo. */\n isEditing?: boolean\n onStartEdit?: () => void\n onCancelEdit?: () => void\n /** Remove o valor salvo. Sem essa prop, o botão \"Remover\" não aparece. */\n onRemove?: () => void\n /** Remoção em andamento: desabilita e mostra o carregamento no botão \"Remover\". */\n removing?: boolean\n className?: string\n /**\n * Classe extra no próprio elemento `<input>` (className vai no quadro em volta). Uso raro:\n * hoje só o texto riscado de um item marcado no Checklist.\n */\n inputClassName?: string\n}\n\n/**\n * Input único. Tipos, máscaras, ícone, limpar, senha, unidades e valor guardado são props:\n * nunca crie InputCPF, InputTelefone, InputSenha ou InputSegredo.\n */\nexport const Input = forwardRef<HTMLInputElement, InputProps>(function Input(\n {\n size,\n mask,\n icon,\n suffix,\n clearable,\n invalid,\n type = 'text',\n value,\n defaultValue,\n onChange,\n onValueChange,\n disabled,\n className,\n inputClassName,\n inputMode,\n placeholder,\n ddi: ddiProp,\n onDdiChange,\n ddiOptions = phoneCountries,\n hideDdi,\n onCentsChange,\n onLookup,\n units,\n unit: unitProp,\n onUnitChange,\n percentMax,\n variant,\n hasValue,\n maskedHint,\n isEditing,\n onStartEdit,\n onCancelEdit,\n onRemove,\n removing,\n ...props\n },\n ref,\n) {\n const inputRef = useRef<HTMLInputElement>(null)\n useImperativeHandle(ref, () => inputRef.current as HTMLInputElement)\n const maskRef = useRef<InputMask<FactoryArg> | null>(null)\n const [showPassword, setShowPassword] = useState(false)\n const [inner, setInner] = useState(String(value ?? defaultValue ?? ''))\n const current = value ?? inner\n // variant=\"secret\" em edição: o campo nunca deriva de `value` do consumidor (o valor salvo\n // não pode aparecer nem acionar o \"Limpar campo\"); o rascunho é próprio e abre vazio.\n const [secretDraft, setSecretDraft] = useState('')\n const [lastIsEditing, setLastIsEditing] = useState(isEditing)\n if (isEditing !== lastIsEditing) {\n setLastIsEditing(isEditing)\n if (isEditing) setSecretDraft('')\n }\n const cb = useRef({ onChange, onValueChange, onCentsChange })\n cb.current = { onChange, onValueChange, onCentsChange }\n const lookupKind =\n mask === 'cep' ? 'cep' : mask === 'cnpj' ? 'cnpj' : mask === 'cpfCnpj' ? 'auto' : undefined\n const searching = useLookup(lookupKind, current, onLookup)\n\n // Telefone: seletor de DDI embutido. Controlado pela prop ddi ou interno.\n const isPhone = mask === 'phone'\n const [innerDdi, setInnerDdi] = useState(ddiProp ?? DEFAULT_DDI)\n const ddi = ddiProp ?? innerDdi\n const showDdi = isPhone && !hideDdi\n const intl = isPhone && ddi !== DEFAULT_DDI\n\n // Unidades (A9): seletor embutido à direita. A unidade escolhida decide a máscara.\n const hasUnits = Boolean(units && units.length > 0)\n const [innerUnit, setInnerUnit] = useState(unitProp ?? units?.[0]?.id ?? '')\n const unit = hasUnits ? (unitProp ?? innerUnit) : undefined\n const unitMaskName = unit === 'percent' ? 'percent' : unit === 'currency' ? 'currency' : undefined\n\n const def = intl\n ? internationalPhoneMask\n : hasUnits\n ? unitMaskName === 'percent'\n ? percentMask(percentMax)\n : unitMaskName === 'currency'\n ? masks.currency\n : undefined\n : mask\n ? masks[mask]\n : undefined\n const maskKey = !def\n ? undefined\n : intl\n ? 'phone-intl'\n : hasUnits\n ? `unit-${unitMaskName}-${percentMax ?? ''}`\n : mask\n\n // Máscara: criada uma vez por tipo de máscara, sincronizada com o valor controlado.\n useEffect(() => {\n if (!maskKey || !def || !inputRef.current) return\n const m = IMask(inputRef.current, def.options)\n maskRef.current = m\n m.on('accept', () => {\n setInner(m.value)\n cb.current.onChange?.(m.value)\n cb.current.onValueChange?.(m.unmaskedValue, m.value)\n if (mask === 'currency' || unitMaskName === 'currency')\n cb.current.onCentsChange?.(toCents(m.value))\n })\n return () => {\n m.destroy()\n maskRef.current = null\n }\n // A máscara só muda com o tipo (maskKey); def acompanha o maskKey.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [maskKey])\n\n useEffect(() => {\n const m = maskRef.current\n if (m && value !== undefined && value !== m.value) m.value = value\n }, [value])\n\n const isPassword = type === 'password'\n const country = ddiOptions.find((c) => c.ddi === ddi)\n const isSecret = variant === 'secret'\n // id e aria-* que o Field injeta no controle (não removidos de props: o <input> normal\n // continua recebendo pelo {...props}). No modo leitura do secret não há <input>; sem\n // repassar para o botão Trocar, o Label do Field fica apontando para um id inexistente.\n const {\n id: fieldId,\n 'aria-describedby': fieldDescribedBy,\n 'aria-required': fieldRequired,\n } = props\n\n // Esvazia o valor (máscara, estado interno e os callbacks): usado por \"Limpar campo\" e\n // por trocar de unidade, que nunca deve carregar o número de uma unidade para outra.\n const resetValue = () => {\n if (maskRef.current) maskRef.current.value = ''\n setInner('')\n setSecretDraft('')\n onChange?.('')\n onValueChange?.('', '')\n onCentsChange?.(null)\n }\n\n const clear = () => {\n resetValue()\n inputRef.current?.focus()\n }\n\n // Trocar de unidade sempre limpa o valor (a máscara muda junto).\n const changeUnit = (id: string) => {\n setInnerUnit(id)\n onUnitChange?.(id)\n resetValue()\n }\n\n // ---------------------------------------------------------------- variant=\"secret\" (A10)\n if (isSecret && !isEditing) {\n return (\n <div\n data-slot=\"control\"\n data-rendra=\"CAMP-001\"\n className={cn(controlFrame({ size, invalid }), className)}\n >\n <span className=\"min-w-0 flex-1 truncate font-mono text-sm text-muted-foreground\">\n {hasValue ? (maskedHint ?? '••••••••') : 'Nenhum valor salvo'}\n </span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={onStartEdit}\n disabled={disabled}\n id={fieldId}\n aria-describedby={fieldDescribedBy}\n aria-required={fieldRequired}\n >\n Trocar\n </Button>\n {hasValue && onRemove && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={onRemove}\n disabled={disabled || removing}\n loading={removing}\n >\n Remover\n </Button>\n )}\n </div>\n )\n }\n\n return (\n <div\n data-slot=\"control\"\n data-rendra=\"CAMP-001\"\n className={cn(controlFrame({ size, invalid }), className)}\n >\n {showDdi && (\n // Seletor nativo transparente sobre o \"+55\": no celular abre a lista do sistema.\n <span className=\"relative -ml-1 flex h-full min-w-touch shrink-0 items-center gap-1 border-r pr-2 text-sm font-medium\">\n <span aria-hidden>+{ddi}</span>\n <ChevronDown className=\"size-icon-sm text-muted-foreground\" aria-hidden />\n <select\n aria-label={`Código do país (DDI): ${country?.name ?? ''} +${ddi}`}\n value={ddi}\n disabled={disabled}\n onChange={(e) => {\n setInnerDdi(e.target.value)\n onDdiChange?.(e.target.value)\n }}\n className=\"absolute inset-0 cursor-pointer bg-popover text-popover-foreground opacity-0 disabled:cursor-not-allowed\"\n >\n {ddiOptions.map((c) => (\n <option key={c.ddi} value={c.ddi} className=\"bg-popover text-popover-foreground\">\n {c.name} (+{c.ddi})\n </option>\n ))}\n </select>\n </span>\n )}\n {icon && (\n <span className=\"flex shrink-0 text-muted-foreground [&_svg]:size-icon-sm\" aria-hidden>\n {icon}\n </span>\n )}\n <input\n key={hasUnits ? `unit-${unit}` : undefined}\n ref={inputRef}\n type={\n isSecret\n ? showPassword\n ? 'text'\n : 'password'\n : isPassword && showPassword\n ? 'text'\n : type\n }\n inputMode={inputMode ?? def?.inputMode}\n placeholder={placeholder ?? def?.placeholder}\n disabled={disabled}\n aria-invalid={invalid || undefined}\n aria-busy={searching || undefined}\n className={cn(controlInput, inputClassName)}\n {...(isSecret\n ? {\n // \"Trocar\" sempre abre vazio: o valor salvo nunca chega a existir no DOM.\n value: secretDraft,\n onChange: (e: ChangeEvent<HTMLInputElement>) => {\n setSecretDraft(e.target.value)\n onChange?.(e.target.value)\n onValueChange?.(e.target.value, e.target.value)\n },\n }\n : maskKey\n ? { defaultValue: current }\n : {\n value: current,\n onChange: (e: ChangeEvent<HTMLInputElement>) => {\n setInner(e.target.value)\n onChange?.(e.target.value)\n onValueChange?.(e.target.value, e.target.value)\n },\n })}\n {...props}\n />\n {searching && (\n <Spinner size=\"sm\" label=\"Buscando…\" className=\"shrink-0 text-muted-foreground\" />\n )}\n {hasUnits && (\n // Mesmo padrão do seletor de DDI, à direita: rótulo visível e select nativo por cima.\n <span className=\"relative -mr-1 flex h-full min-w-touch shrink-0 items-center gap-1 border-l pl-2 text-sm font-medium\">\n <span aria-hidden>{units?.find((u) => u.id === unit)?.label ?? unit}</span>\n <ChevronDown className=\"size-icon-sm text-muted-foreground\" aria-hidden />\n <select\n aria-label={`Unidade: ${units?.find((u) => u.id === unit)?.label ?? unit}`}\n value={unit}\n disabled={disabled}\n onChange={(e) => changeUnit(e.target.value)}\n className=\"absolute inset-0 cursor-pointer bg-popover text-popover-foreground opacity-0 disabled:cursor-not-allowed\"\n >\n {units?.map((u) => (\n <option key={u.id} value={u.id} className=\"bg-popover text-popover-foreground\">\n {u.label}\n </option>\n ))}\n </select>\n </span>\n )}\n {!hasUnits && suffix && (\n <span className=\"shrink-0 text-sm text-muted-foreground\">{suffix}</span>\n )}\n {clearable && (isSecret ? secretDraft : current) && !disabled && (\n <button\n type=\"button\"\n onClick={clear}\n aria-label=\"Limpar campo\"\n className={controlAdornmentButton}\n >\n <X aria-hidden />\n </button>\n )}\n {(isPassword || isSecret) && (\n <button\n type=\"button\"\n onClick={() => setShowPassword((s) => !s)}\n aria-label={showPassword ? 'Ocultar senha' : 'Mostrar senha'}\n aria-pressed={showPassword}\n className={controlAdornmentButton}\n >\n {showPassword ? <EyeOff aria-hidden /> : <Eye aria-hidden />}\n </button>\n )}\n {isSecret && (\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" onClick={onCancelEdit} disabled={disabled}>\n Cancelar\n </Button>\n )}\n </div>\n )\n})\n","import { X } from 'lucide-react'\nimport { Dialog, Popover } from 'radix-ui'\nimport { useRef, type ReactNode } from 'react'\nimport { useBreakpoint } from '@/hooks/use-breakpoint'\nimport { cn } from '@/lib/cn'\nimport { useLayoutReady, useMotionLib, useMotionOn, useMotionPresets } from '@/lib/motion'\n\n/*\n * Painel de escolha usado por Select e DatePicker (não é para uso direto nas telas).\n * Desktop: popover ancorado no campo, na largura dele.\n * Mobile (< 768px): o mesmo conteúdo reconstruído como bottom sheet, com título,\n * área rolável e rodapé fixo que respeita a área segura do aparelho.\n */\n\ninterface PickerPanelProps {\n open: boolean\n onOpenChange: (open: boolean) => void\n /** O gatilho (renderizado com asChild). */\n trigger: ReactNode\n /** Título do bottom sheet no mobile (normalmente o rótulo do campo). */\n title: string\n /** Topo fixo (ex.: campo de busca). */\n header?: ReactNode\n children: ReactNode\n /** Rodapé fixo (ex.: Limpar / Aplicar). */\n footer?: ReactNode\n /** Largura no desktop: do gatilho ou automática (calendário). */\n width?: 'trigger' | 'auto'\n /**\n * Botão sobreposto ao gatilho (ex.: limpar). Fica como irmão do gatilho, nunca dentro\n * dele: botão dentro de botão é HTML inválido e confunde leitores de tela.\n */\n adornment?: ReactNode\n align?: 'start' | 'center' | 'end'\n}\n\n/** A folha fecha se o arraste passou de 40% da altura ou se foi um arremesso (> 0,11 px/ms). */\nconst DISMISS_FRACTION = 0.4\nconst DISMISS_VELOCITY = 110\n\ninterface MobileSheetProps {\n open: boolean\n onOpenChange: (open: boolean) => void\n trigger: ReactNode\n adornment?: ReactNode\n /** Alça e título: a única área que começa o arraste (o resto rola). */\n head: ReactNode\n /** Busca, lista e rodapé. */\n rest: ReactNode\n}\n\n/**\n * A folha do celular em `on`: entra de baixo, acompanha o dedo (arraste vertical pela alça, com\n * fricção ao puxar para cima), fecha por distância ou por arremesso e, se o dedo solta antes\n * disso, volta à origem com a mola da folha (a velocidade do dedo entra na mola, sem costura). O\n * fundo escurecido acompanha a distância. Só a alça arrasta: o corpo rola sem disputar o gesto.\n * Nenhum valor passa por `style`: o Motion guarda a posição do arraste, e o escurecimento do\n * fundo é gravado direto no elemento (sem render por quadro).\n */\nfunction MobileSheet({ open, onOpenChange, trigger, adornment, head, rest }: MobileSheetProps) {\n const { AnimatePresence, animate, m, useDragControls } = useMotionOn()\n const presets = useMotionPresets()\n const ready = useLayoutReady()\n const controls = useDragControls()\n const sheetRef = useRef<HTMLDivElement>(null)\n const dimRef = useRef<HTMLDivElement>(null)\n const height = useRef(1)\n return (\n <Dialog.Root open={open} onOpenChange={onOpenChange}>\n <Anchor adornment={adornment}>\n <Dialog.Trigger asChild>{trigger}</Dialog.Trigger>\n </Anchor>\n <AnimatePresence>\n {open && (\n <Dialog.Portal forceMount key=\"sheet\">\n <Dialog.Overlay forceMount asChild>\n <m.div className=\"fixed inset-0 z-40\" {...presets.fade}>\n <div ref={dimRef} className=\"absolute inset-0 bg-overlay\" />\n </m.div>\n </Dialog.Overlay>\n <Dialog.Content\n forceMount\n asChild\n aria-describedby={undefined}\n 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\"\n >\n <m.div\n ref={sheetRef}\n {...presets.sheet('bottom')}\n drag={ready ? 'y' : false}\n dragControls={controls}\n dragListener={false}\n dragConstraints={{ top: 0 }}\n dragElastic={{ top: 0.2, bottom: 0 }}\n dragSnapToOrigin\n dragTransition={presets.sheetBounce}\n onDragStart={() => {\n height.current = sheetRef.current?.offsetHeight || 1\n }}\n onDrag={(_, info) => {\n const dim = dimRef.current\n if (dim)\n dim.style.opacity = String(\n 1 - Math.min(1, Math.max(0, info.offset.y / height.current)),\n )\n }}\n onDragEnd={(_, info) => {\n if (\n info.offset.y > height.current * DISMISS_FRACTION ||\n info.velocity.y > DISMISS_VELOCITY\n ) {\n onOpenChange(false)\n return\n }\n // Soltou antes: o fundo volta a escurecer por inteiro junto com a folha.\n if (dimRef.current) animate(dimRef.current, { opacity: 1 }, presets.springSheet)\n }}\n >\n <div\n data-sheet-handle\n onPointerDown={(e) => controls.start(e)}\n className=\"touch-none\"\n >\n {head}\n </div>\n {rest}\n </m.div>\n </Dialog.Content>\n </Dialog.Portal>\n )}\n </AnimatePresence>\n </Dialog.Root>\n )\n}\n\nfunction Anchor({ adornment, children }: { adornment?: ReactNode; children: ReactNode }) {\n if (!adornment) return children\n return (\n <div className=\"relative w-full min-w-0\">\n {children}\n {adornment}\n </div>\n )\n}\n\nexport function PickerPanel({\n open,\n onOpenChange,\n trigger,\n title,\n header,\n children,\n footer,\n width = 'trigger',\n adornment,\n align = 'start',\n}: PickerPanelProps) {\n const { isMobile } = useBreakpoint()\n const lib = useMotionLib()\n const presets = useMotionPresets()\n const on = lib !== null\n\n // Conteúdo interno do sheet (mobile) e do painel (desktop), igual nos dois modos. A alça e o\n // título ficam à parte porque, em `on`, só eles começam o arraste da folha.\n const sheetHead = (\n <>\n <div className=\"flex shrink-0 flex-col items-center pt-2\">\n <span aria-hidden className=\"h-1 w-12 rounded-full bg-border\" />\n </div>\n <div className=\"flex shrink-0 items-center justify-between gap-2 pr-2 pl-4\">\n <Dialog.Title className=\"truncate text-base font-semibold\">{title}</Dialog.Title>\n <Dialog.Close\n aria-label=\"Fechar\"\n className=\"flex size-touch items-center justify-center rounded-item text-muted-foreground hover:bg-accent\"\n >\n <X className=\"size-icon-md\" aria-hidden />\n </Dialog.Close>\n </div>\n </>\n )\n const sheetRest = (\n <>\n {header && <div className=\"shrink-0 border-b px-4 pb-3\">{header}</div>}\n <div className=\"min-h-0 flex-1 overflow-y-auto overscroll-contain p-2\">{children}</div>\n {footer && <div className=\"shrink-0 border-t px-4 pt-3 pb-safe\">{footer}</div>}\n </>\n )\n const sheetBody = (\n <>\n {sheetHead}\n {sheetRest}\n </>\n )\n // O painel nasce do campo, não do centro (W6): a origem vem do Radix (é um Popover).\n const panelCls = cn(\n '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',\n width === 'trigger' ? 'w-trigger max-w-popover' : 'w-auto max-w-popover md:max-w-none',\n )\n const panelBody = (\n <>\n {header && <div className=\"shrink-0 border-b p-2\">{header}</div>}\n <div className=\"min-h-0 flex-1 overflow-y-auto overscroll-contain p-1\">{children}</div>\n {footer && <div className=\"shrink-0 border-t p-2\">{footer}</div>}\n </>\n )\n\n if (on && isMobile) {\n return (\n <MobileSheet\n open={open}\n onOpenChange={onOpenChange}\n trigger={trigger}\n adornment={adornment}\n head={sheetHead}\n rest={sheetRest}\n />\n )\n }\n\n if (on) {\n return (\n <Popover.Root open={open} onOpenChange={onOpenChange}>\n <Anchor adornment={adornment}>\n <Popover.Trigger asChild>{trigger}</Popover.Trigger>\n </Anchor>\n <lib.AnimatePresence>\n {open && (\n <Popover.Portal forceMount key=\"panel\">\n <Popover.Content\n forceMount\n asChild\n align={align}\n sideOffset={6}\n collisionPadding={16}\n className={panelCls}\n >\n <lib.m.div {...presets.open()}>{panelBody}</lib.m.div>\n </Popover.Content>\n </Popover.Portal>\n )}\n </lib.AnimatePresence>\n </Popover.Root>\n )\n }\n\n if (isMobile) {\n return (\n <Dialog.Root open={open} onOpenChange={onOpenChange}>\n <Anchor adornment={adornment}>\n <Dialog.Trigger asChild>{trigger}</Dialog.Trigger>\n </Anchor>\n <Dialog.Portal>\n <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\" />\n <Dialog.Content\n aria-describedby={undefined}\n 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\"\n >\n {sheetBody}\n </Dialog.Content>\n </Dialog.Portal>\n </Dialog.Root>\n )\n }\n\n return (\n <Popover.Root open={open} onOpenChange={onOpenChange}>\n <Anchor adornment={adornment}>\n <Popover.Trigger asChild>{trigger}</Popover.Trigger>\n </Anchor>\n <Popover.Portal>\n <Popover.Content\n align={align}\n sideOffset={6}\n collisionPadding={16}\n className={cn(\n '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',\n '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',\n width === 'trigger' ? 'w-trigger max-w-popover' : 'w-auto max-w-popover md:max-w-none',\n )}\n >\n {panelBody}\n </Popover.Content>\n </Popover.Portal>\n </Popover.Root>\n )\n}\n","import { Dialog } from 'radix-ui'\nimport { useState, type ReactNode } from 'react'\nimport { Modal } from '@/components/ui/modal'\nimport { cn } from '@/lib/cn'\nimport { useMotionLib, useMotionPresets } from '@/lib/motion'\nimport { OverlayShell } from './overlay-shell'\n\n/*\n * Drawer único, componente central do sistema. Desliza da direita para a esquerda.\n * Para formulários e detalhes de volume médio (até ~12 campos).\n * Header fixo: ícone, título, descrição e fechar.\n * Body: única área com rolagem.\n * Footer fixo: ações (use <ActionBar>), com borda superior.\n * Mobile: tela inteira (100dvh), footer acima da área segura e do teclado.\n * Fecha por Esc e clique fora; com dirty, pede confirmação antes.\n */\n\n/*\n * Largura no desktop, em porcentagem da tela: 30 (padrão), 40, 50 ou 75. Nunca menos que\n * 28rem (para caber o formulário em telas médias); no celular, sempre tela inteira.\n * sm, md, lg e xl são os nomes antigos e valem 30, 30, 50 e 75.\n */\nconst sizes = {\n '30': 'md:w-sheet-30',\n '40': 'md:w-sheet-40',\n '50': 'md:w-sheet-50',\n '75': 'md:w-sheet-75',\n full: 'md:w-full',\n sm: 'md:w-sheet-30',\n md: 'md:w-sheet-30',\n lg: 'md:w-sheet-50',\n xl: 'md:w-sheet-75',\n} as const\n\nconst overlayCls = 'fixed inset-0 z-50 bg-overlay'\nconst panelCls =\n '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'\n\nexport interface DrawerProps {\n open: boolean\n onOpenChange: (open: boolean) => void\n title: ReactNode\n description?: ReactNode\n icon?: ReactNode\n size?: keyof typeof sizes\n children: ReactNode\n /** Rodapé fixo. Normalmente um <ActionBar>. */\n footer?: ReactNode\n /** Há alterações não salvas: fechar pede confirmação. */\n dirty?: boolean\n /** Textos da confirmação de descarte. */\n discardTitle?: string\n discardDescription?: string\n}\n\nexport function Drawer({\n open,\n onOpenChange,\n title,\n description,\n icon,\n size = '30',\n children,\n footer,\n dirty,\n discardTitle = 'Descartar alterações?',\n discardDescription = 'As informações preenchidas neste painel serão perdidas.',\n}: DrawerProps) {\n const [confirming, setConfirming] = useState(false)\n const requestClose = () => (dirty ? setConfirming(true) : onOpenChange(false))\n const lib = useMotionLib()\n const presets = useMotionPresets()\n\n const keepOpenIfDirty = (e: { preventDefault: () => void }) => {\n if (dirty) {\n e.preventDefault()\n setConfirming(true)\n }\n }\n const shell = (\n <OverlayShell\n title={title}\n description={description}\n icon={icon}\n footer={footer}\n onRequestClose={requestClose}\n >\n {children}\n </OverlayShell>\n )\n\n return (\n <>\n <Dialog.Root open={open} onOpenChange={(o) => (o ? onOpenChange(true) : requestClose())}>\n {lib ? (\n // `on`: o painel só existe enquanto aberto ou saindo; o Radix fica com forceMount.\n <lib.AnimatePresence>\n {open && (\n <Dialog.Portal forceMount key=\"drawer\">\n <Dialog.Overlay forceMount asChild>\n <lib.m.div className={overlayCls} {...presets.fade} />\n </Dialog.Overlay>\n <Dialog.Content\n forceMount\n asChild\n onEscapeKeyDown={keepOpenIfDirty}\n onPointerDownOutside={keepOpenIfDirty}\n data-rendra=\"GAV-001\"\n className={cn(panelCls, sizes[size])}\n >\n <lib.m.div {...presets.sheet('right')}>{shell}</lib.m.div>\n </Dialog.Content>\n </Dialog.Portal>\n )}\n </lib.AnimatePresence>\n ) : (\n <Dialog.Portal>\n <Dialog.Overlay\n className={cn(\n overlayCls,\n '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',\n )}\n />\n <Dialog.Content\n onEscapeKeyDown={keepOpenIfDirty}\n onPointerDownOutside={keepOpenIfDirty}\n data-rendra=\"GAV-001\"\n className={cn(\n panelCls,\n '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',\n sizes[size],\n )}\n >\n {shell}\n </Dialog.Content>\n </Dialog.Portal>\n )}\n </Dialog.Root>\n <Modal\n open={confirming}\n onOpenChange={setConfirming}\n type=\"destructive\"\n title={discardTitle}\n description={discardDescription}\n confirmLabel=\"Descartar\"\n cancelLabel=\"Continuar editando\"\n onConfirm={() => onOpenChange(false)}\n />\n </>\n )\n}\n","/**\n * Mapas de classes das primitivas de layout. Classes completas e estáticas,\n * para o Tailwind encontrá-las. Só os degraus da escala permitida.\n */\nexport type Space =\n '0' | '1' | '2' | '3' | '4' | '6' | '8' | '12' | '16' | '24' | 'section' | 'fields'\n\nexport const gapClass: Record<Space, string> = {\n '0': 'gap-0',\n '1': 'gap-1',\n '2': 'gap-2',\n '3': 'gap-3',\n '4': 'gap-4',\n '6': 'gap-6',\n '8': 'gap-8',\n '12': 'gap-12',\n '16': 'gap-16',\n '24': 'gap-24',\n // Espaço entre seções de página: menor no mobile, cheio no desktop.\n section: 'gap-8 md:gap-12',\n // Entre campos de formulário (Field): 16px do fim de um campo ao rótulo do próximo.\n fields: 'gap-x-4 gap-y-4 md:gap-x-6',\n}\n\n/**\n * Grade de formulário, pela largura do próprio bloco (container query), não da tela:\n * 1 coluna estreito, 6 colunas a partir de 28rem, 12 colunas a partir de 48rem.\n * No largo, o padrão é 3 campos por linha (md = 4/12). Nunca 2 por linha por padrão.\n */\nexport const fieldGridClass = 'grid grid-cols-1 @md:grid-cols-6 @3xl:grid-cols-12'\n\n/** Largura do Field na grade de formulário (no largo, em 12 colunas). */\nexport const fieldSpanClass = {\n /** 2/12, cerca de 17%: UF, número, DDD. */\n xs: '@md:col-span-2 @3xl:col-span-2',\n /** 3/12 = 25%: CEP, CNPJ, CPF, datas curtas. */\n sm: '@md:col-span-2 @3xl:col-span-3',\n /** 4/12 = 33%: o padrão, 3 campos por linha. */\n md: '@md:col-span-3 @3xl:col-span-4',\n /** 6/12 = 50%. */\n lg: '@md:col-span-3 @3xl:col-span-6',\n /** 8/12 = 67%: nome, logradouro longo. */\n xl: '@md:col-span-6 @3xl:col-span-8',\n /** Linha inteira. */\n full: '@md:col-span-6 @3xl:col-span-12',\n} as const\n\nexport type FieldSpan = keyof typeof fieldSpanClass\n\nexport const alignClass = {\n start: 'items-start',\n center: 'items-center',\n end: 'items-end',\n stretch: 'items-stretch',\n baseline: 'items-baseline',\n} as const\n\nexport const justifyClass = {\n start: 'justify-start',\n center: 'justify-center',\n end: 'justify-end',\n between: 'justify-between',\n} as const\n\nexport type Align = keyof typeof alignClass\nexport type Justify = keyof typeof justifyClass\n","import { Label as L } from 'radix-ui'\nimport {\n cloneElement,\n createContext,\n isValidElement,\n useContext,\n useId,\n type ComponentProps,\n type ReactElement,\n type ReactNode,\n} from 'react'\nimport { fieldSpanClass, type FieldSpan } from '@/components/layout/tokens'\nimport { cn } from '@/lib/cn'\n\n/*\n * Rótulo, ajuda e erro padronizados.\n * Regras: rótulo sempre acima; obrigatório marcado no rótulo; erro abaixo do campo em\n * espaço reservado (a tela não pula quando o erro aparece).\n */\n\nexport function Label({\n className,\n required,\n children,\n ...props\n}: ComponentProps<typeof L.Root> & { required?: boolean }) {\n return (\n <L.Root\n data-rendra=\"FLD-002\"\n className={cn('text-label text-label-foreground label-case', className)}\n {...props}\n >\n {children}\n {required && (\n <span className=\"text-destructive\" aria-hidden>\n {' '}\n *\n </span>\n )}\n {required && <span className=\"sr-only\"> (obrigatório)</span>}\n </L.Root>\n )\n}\n\ninterface FieldContextValue {\n id: string\n describedBy: string\n invalid: boolean\n}\nconst FieldContext = createContext<FieldContextValue | null>(null)\n\n/** Liga um controle ao Field mais próximo (id, aria-describedby, aria-invalid). */\nexport function useFieldControl() {\n return useContext(FieldContext)\n}\n\nexport interface FieldProps {\n label?: ReactNode\n required?: boolean\n /** Texto de ajuda sempre visível (substitui tooltip no mobile). */\n help?: ReactNode\n /** Mensagem de erro, abaixo do controle, no lugar da ajuda. */\n error?: ReactNode\n /**\n * Largura na grade de formulário (Grid form ou FormSection): xs (17%), sm (25%),\n * md (33%, padrão: 3 por linha), lg (50%), xl (67%), full. half é o antigo e vale md.\n */\n span?: FieldSpan | 'half'\n /** Começa uma linha nova (ex.: os campos que vêm depois do CEP ou do CNPJ). */\n newRow?: boolean\n /**\n * Reserva a linha da mensagem mesmo vazia, para o erro não empurrar o que vem abaixo\n * (útil em formulários em grid de 2 colunas com validação ao digitar). Padrão: não\n * reserva, e os campos ficam mais próximos.\n */\n reserveMessage?: boolean\n /** Obsoleto: sem reserva já é o padrão. Mantido para não quebrar telas existentes. */\n compact?: boolean\n /** id do controle; gerado automaticamente se omitido. */\n id?: string\n className?: string\n children: ReactNode\n}\n\nexport function Field({\n label,\n required,\n help,\n error,\n span = 'md',\n newRow,\n reserveMessage = false,\n id,\n className,\n children,\n}: FieldProps) {\n const auto = useId()\n const controlId = id ?? `campo${auto}`\n const messageId = `${controlId}-mensagem`\n const invalid = Boolean(error)\n const message = error ?? help\n\n // Repassa id e acessibilidade ao controle filho quando ele é um elemento simples.\n const child =\n isValidElement(children) && typeof children.type !== 'string'\n ? cloneElement(children as ReactElement<Record<string, unknown>>, {\n id: (children.props as { id?: string }).id ?? controlId,\n // Só repassa invalid quando há erro, para não vazar o atributo em elementos comuns.\n ...(invalid\n ? { invalid: (children.props as { invalid?: boolean }).invalid ?? true }\n : {}),\n 'aria-describedby': message ? messageId : undefined,\n 'aria-required': required || undefined,\n })\n : children\n\n return (\n <FieldContext.Provider\n value={{ id: controlId, describedBy: message ? messageId : '', invalid }}\n >\n <div\n data-slot=\"field\"\n data-rendra=\"FLD-001\"\n className={cn(\n 'flex min-w-0 flex-col gap-2',\n fieldSpanClass[span === 'half' ? 'md' : span],\n newRow && '@md:col-start-1 @3xl:col-start-1',\n className,\n )}\n >\n {label && (\n <Label htmlFor={controlId} required={required}>\n {label}\n </Label>\n )}\n {child}\n {(reserveMessage || message) && (\n <p\n id={messageId}\n role={invalid ? 'alert' : undefined}\n className={cn(\n '-mt-1 min-h-4 text-help',\n invalid ? 'font-medium text-destructive' : 'text-help-foreground',\n )}\n >\n {message}\n </p>\n )}\n </div>\n </FieldContext.Provider>\n )\n}\n","import { Command } from 'cmdk'\nimport { Check, ChevronDown, Plus, Search, X } from 'lucide-react'\nimport { forwardRef, useEffect, useId, useMemo, useRef, useState, type ReactNode } from 'react'\nimport { Button } from '@/components/ui/button'\nimport { Spinner } from '@/components/ui/spinner'\nimport { useBreakpoint } from '@/hooks/use-breakpoint'\nimport { cn } from '@/lib/cn'\nimport {\n controlAdornmentButton,\n controlAdornmentSpace,\n controlFrame,\n type ControlSize,\n} from '@/lib/control'\nimport { PickerPanel } from './picker-panel'\n\nexport interface SelectOption {\n value: string\n label: string\n description?: string\n icon?: ReactNode\n disabled?: boolean\n /** Agrupa opções sob um título. */\n group?: string\n}\n\ninterface BaseProps {\n options?: SelectOption[]\n placeholder?: string\n /**\n * Nome do campo: título do painel no mobile e, quando o Select não está dentro de um\n * Field (sem id ligado a um rótulo visível), nome acessível do gatilho.\n */\n label?: string\n size?: ControlSize\n invalid?: boolean\n disabled?: boolean\n /** Campo de busca no topo da lista. */\n searchable?: boolean\n /** Permite criar uma opção nova a partir do texto buscado. */\n creatable?: boolean\n onCreate?: (label: string) => SelectOption | Promise<SelectOption>\n /** Busca remota: recebe o texto e devolve as opções. Liga a busca automaticamente. */\n loadOptions?: (query: string) => Promise<SelectOption[]>\n /** Mostra indicador de carregamento na lista. */\n loading?: boolean\n /** Botão de limpar no campo. */\n clearable?: boolean\n emptyText?: string\n id?: string\n className?: string\n 'aria-describedby'?: string\n}\n\n/** Acima deste número de opções, o \"Selecionar todos\" aparece sem a prop `selectAll`. */\nconst SELECT_ALL_AUTO_MIN = 5\n\ninterface SingleProps extends BaseProps {\n multiple?: false\n value?: string | null\n onChange?: (value: string | null) => void\n selectAll?: never\n showCount?: never\n maxChips?: never\n}\n\ninterface MultipleProps extends BaseProps {\n /** Seleção múltipla com checkbox e chips. */\n multiple: true\n value?: string[]\n onChange?: (value: string[]) => void\n /**\n * Linha \"Selecionar todos\" no topo da lista (vira \"Desmarcar todos\" com tudo marcado).\n * Padrão: aparece sozinha com mais de 5 opções; `false` desliga, `true` força com 5 ou menos.\n */\n selectAll?: boolean\n /** Mostra \"3 selecionados\" no lugar dos chips. */\n showCount?: boolean\n /** Máximo de chips visíveis antes de \"+N\". */\n maxChips?: number\n}\n\nexport type SelectProps = SingleProps | MultipleProps\n\n/**\n * Select único do sistema. Busca, múltiplo, selecionar todos, contador, criar opção,\n * busca remota e carregamento são props. No mobile abre como bottom sheet.\n */\nexport const Select = forwardRef<HTMLButtonElement, SelectProps>(function Select(props, ref) {\n const {\n options: staticOptions = [],\n placeholder = 'Selecione',\n label,\n size,\n invalid,\n disabled,\n searchable,\n creatable,\n onCreate,\n loadOptions,\n loading,\n clearable,\n emptyText = 'Nenhuma opção encontrada.',\n id,\n className,\n } = props\n const multiple = props.multiple === true\n const { isMobile } = useBreakpoint()\n const [open, setOpen] = useState(false)\n const listId = `${useId()}-lista`\n const [query, setQuery] = useState('')\n const [remote, setRemote] = useState<SelectOption[] | null>(null)\n const [remoteLoading, setRemoteLoading] = useState(false)\n const [created, setCreated] = useState<SelectOption[]>([])\n const [innerSingle, setInnerSingle] = useState<string | null>(null)\n const [innerMulti, setInnerMulti] = useState<string[]>([])\n // No mobile, o múltiplo só aplica ao confirmar.\n const [draft, setDraft] = useState<string[]>([])\n\n const selectedSingle = multiple ? null : ((props as SingleProps).value ?? innerSingle)\n const selectedMulti = multiple ? ((props as MultipleProps).value ?? innerMulti) : []\n\n // Busca remota com espera curta entre teclas.\n const seq = useRef(0)\n useEffect(() => {\n if (!loadOptions || !open) return\n const n = ++seq.current\n setRemoteLoading(true)\n const t = window.setTimeout(async () => {\n const res = await loadOptions(query)\n if (n === seq.current) {\n setRemote(res)\n setRemoteLoading(false)\n }\n }, 250)\n return () => window.clearTimeout(t)\n }, [loadOptions, query, open])\n\n const all = useMemo(() => {\n const base = remote ?? staticOptions\n const map = new Map<string, SelectOption>()\n ;[...base, ...created].forEach((o) => map.set(o.value, o))\n return [...map.values()]\n }, [remote, staticOptions, created])\n\n const byValue = (v: string) => all.find((o) => o.value === v)\n const isSearchable = searchable || creatable || Boolean(loadOptions)\n const busy = loading || remoteLoading\n const multiValue = isMobile && multiple ? draft : selectedMulti\n\n const commitSingle = (v: string | null) => {\n setInnerSingle(v)\n ;(props as SingleProps).onChange?.(v)\n }\n const commitMulti = (v: string[]) => {\n setInnerMulti(v)\n ;(props as MultipleProps).onChange?.(v)\n }\n\n const toggle = (v: string) => {\n if (!multiple) {\n commitSingle(v)\n setOpen(false)\n return\n }\n const next = multiValue.includes(v) ? multiValue.filter((x) => x !== v) : [...multiValue, v]\n if (isMobile) setDraft(next)\n else commitMulti(next)\n }\n\n const enabled = all.filter((o) => !o.disabled)\n const allSelected = enabled.length > 0 && enabled.every((o) => multiValue.includes(o.value))\n const showSelectAll =\n multiple && ((props as MultipleProps).selectAll ?? all.length > SELECT_ALL_AUTO_MIN)\n const toggleAll = () => {\n const next = allSelected ? [] : enabled.map((o) => o.value)\n if (isMobile) setDraft(next)\n else commitMulti(next)\n }\n\n const create = async () => {\n const text = query.trim()\n if (!text) return\n const opt = onCreate ? await onCreate(text) : { value: text, label: text }\n setCreated((c) => [...c, opt])\n setQuery('')\n toggle(opt.value)\n }\n\n const onOpenChange = (o: boolean) => {\n setOpen(o)\n if (o) setDraft(selectedMulti)\n else setQuery('')\n }\n\n // ------------------------------------------------ gatilho\n const hasValue = multiple ? selectedMulti.length > 0 : selectedSingle != null\n const maxChips = (props as MultipleProps).maxChips ?? 2\n let display: ReactNode = <span className=\"truncate text-muted-foreground\">{placeholder}</span>\n if (!multiple && selectedSingle != null) {\n const o = byValue(selectedSingle)\n display = (\n <span className=\"flex min-w-0 items-center gap-2\">\n {o?.icon}\n <span className=\"truncate\">{o?.label ?? selectedSingle}</span>\n </span>\n )\n } else if (multiple && selectedMulti.length > 0) {\n display = (props as MultipleProps).showCount ? (\n <span className=\"truncate\">\n {selectedMulti.length} {selectedMulti.length === 1 ? 'selecionado' : 'selecionados'}\n </span>\n ) : (\n <span className=\"flex min-w-0 items-center gap-1 overflow-hidden\">\n {selectedMulti.slice(0, maxChips).map((v) => (\n <span\n key={v}\n className=\"max-w-3xs shrink-0 truncate rounded-item bg-primary-soft px-2 py-1 text-xs leading-none font-medium text-primary-soft-foreground\"\n >\n {byValue(v)?.label ?? v}\n </span>\n ))}\n {selectedMulti.length > maxChips && (\n <span className=\"shrink-0 rounded-item bg-muted px-2 py-1 text-xs leading-none font-medium\">\n +{selectedMulti.length - maxChips}\n </span>\n )}\n </span>\n )\n }\n\n const showClear = clearable && hasValue && !disabled\n const clear = showClear ? (\n <button\n type=\"button\"\n aria-label=\"Limpar seleção\"\n className={cn(\n controlAdornmentButton,\n 'absolute top-1/2 right-8 mr-0 -translate-y-1/2 md:mr-0',\n )}\n onClick={() => (multiple ? commitMulti([]) : commitSingle(null))}\n >\n <X aria-hidden />\n </button>\n ) : undefined\n\n const trigger = (\n <button\n ref={ref}\n id={id}\n type=\"button\"\n role=\"combobox\"\n aria-expanded={open}\n aria-controls={listId}\n aria-haspopup=\"listbox\"\n aria-invalid={invalid || undefined}\n aria-describedby={props['aria-describedby']}\n aria-label={id ? undefined : label}\n disabled={disabled}\n data-rendra=\"SEL-001\"\n // Teclas no gatilho não chegam à lista (Enter não seleciona opção com o painel fechado).\n onKeyDown={(e) => e.stopPropagation()}\n className={cn(\n controlFrame({ size, invalid }),\n 'cursor-pointer text-left disabled:cursor-not-allowed disabled:opacity-60',\n className,\n )}\n >\n <span className=\"flex min-w-0 flex-1 items-center\">{display}</span>\n {showClear && <span aria-hidden className={cn(controlAdornmentSpace, '-mr-1')} />}\n <ChevronDown\n aria-hidden\n className={cn(\n 'size-icon-sm shrink-0 text-muted-foreground transition-transform duration-(--rendra-duration-base) ease-move',\n open && 'rotate-180',\n )}\n />\n </button>\n )\n\n // ------------------------------------------------ lista\n const groups = all.reduce<Record<string, SelectOption[]>>((acc, o) => {\n ;(acc[o.group ?? ''] ??= []).push(o)\n return acc\n }, {})\n const q = query.trim().toLowerCase()\n const showCreate = creatable && q && !all.some((o) => o.label.toLowerCase() === q)\n\n const itemClass =\n 'relative flex min-h-touch cursor-pointer items-center gap-3 rounded-item px-3 text-sm outline-none select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 data-[selected=true]:bg-accent md:min-h-0 md:py-2'\n\n const checkbox = (checked: boolean) => (\n <span\n aria-hidden\n className={cn(\n 'flex size-icon-sm shrink-0 items-center justify-center rounded-item border transition-colors',\n checked ? 'border-primary bg-primary text-primary-foreground' : 'border-input bg-card',\n )}\n >\n {checked && <Check className=\"size-3\" strokeWidth={3} />}\n </span>\n )\n\n const list = (\n <Command.List id={listId} aria-label={label ?? placeholder}>\n {busy && (\n <Command.Loading>\n <div className=\"flex items-center gap-2 px-3 py-4 text-sm text-muted-foreground\">\n <Spinner size=\"sm\" />\n Carregando opções...\n </div>\n </Command.Loading>\n )}\n {!busy && (\n <Command.Empty className=\"px-3 py-6 text-center text-sm text-muted-foreground\">\n {emptyText}\n </Command.Empty>\n )}\n {showCreate && (\n <Command.Item value={`__criar__${query}`} onSelect={create} className={itemClass}>\n <Plus className=\"size-icon-sm shrink-0 text-primary-text\" aria-hidden />\n <span className=\"truncate\">\n Criar <strong className=\"font-semibold\">“{query.trim()}”</strong>\n </span>\n </Command.Item>\n )}\n {showSelectAll && !q && enabled.length > 0 && (\n <Command.Item\n value=\"__todos__\"\n onSelect={toggleAll}\n className={cn(itemClass, 'font-medium')}\n >\n {checkbox(allSelected)}\n {allSelected ? 'Desmarcar todos' : 'Selecionar todos'}\n </Command.Item>\n )}\n {Object.entries(groups).map(([group, opts]) => (\n <Command.Group\n key={group || 'sem-grupo'}\n heading={group || undefined}\n className=\"[&_[cmdk-group-heading]]:px-3 [&_[cmdk-group-heading]]:py-2 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground\"\n >\n {opts.map((o) => {\n const checked = multiple ? multiValue.includes(o.value) : selectedSingle === o.value\n return (\n <Command.Item\n key={o.value}\n value={`${o.label} ${o.description ?? ''} ${o.value}`}\n disabled={o.disabled}\n onSelect={() => toggle(o.value)}\n aria-selected={checked}\n className={itemClass}\n >\n {multiple && checkbox(checked)}\n {o.icon && <span className=\"flex shrink-0 [&_svg]:size-icon-sm\">{o.icon}</span>}\n <span className=\"flex min-w-0 flex-1 flex-col\">\n <span className={cn('truncate', checked && !multiple && 'font-medium')}>\n {o.label}\n </span>\n {o.description && (\n <span className=\"truncate text-xs text-muted-foreground\">{o.description}</span>\n )}\n </span>\n {!multiple && checked && (\n <Check className=\"size-icon-sm shrink-0 text-primary-text\" aria-hidden />\n )}\n </Command.Item>\n )\n })}\n </Command.Group>\n ))}\n </Command.List>\n )\n\n const search = isSearchable ? (\n <div className={cn(controlFrame({ size: 'md' }), 'bg-background')}>\n <Search className=\"size-icon-sm shrink-0 text-muted-foreground\" aria-hidden />\n <Command.Input\n value={query}\n onValueChange={setQuery}\n placeholder={creatable ? 'Buscar ou criar...' : 'Buscar...'}\n className=\"h-full min-w-0 flex-1 bg-transparent outline-none placeholder:text-muted-foreground\"\n />\n </div>\n ) : null\n\n const count = multiValue.length\n const footer =\n multiple && (isMobile || count > 0) ? (\n <div className=\"grid grid-actions-2 gap-3\">\n <Button\n variant=\"outline\"\n onClick={() => (isMobile ? setDraft([]) : commitMulti([]))}\n disabled={count === 0}\n >\n Limpar\n </Button>\n {isMobile ? (\n <Button\n onClick={() => {\n commitMulti(draft)\n setOpen(false)\n }}\n >\n Aplicar{count ? ` (${count})` : ''}\n </Button>\n ) : (\n <Button variant=\"secondary\" onClick={() => setOpen(false)}>\n Pronto ({count})\n </Button>\n )}\n </div>\n ) : undefined\n\n return (\n <Command shouldFilter={!loadOptions} loop className=\"contents\" label={label ?? placeholder}>\n <PickerPanel\n open={open}\n onOpenChange={onOpenChange}\n trigger={trigger}\n adornment={clear}\n title={label ?? placeholder}\n header={search}\n footer={footer}\n >\n {list}\n </PickerPanel>\n </Command>\n )\n})\n","import { useLayoutEffect, useRef } from 'react'\n\n/**\n * Mede o espaço que sobra na área de conteúdo (o <main>) abaixo do elemento e grava em\n * --board-h. Com a classe h-board, o elemento ocupa exatamente essa altura: a página não\n * rola e a rolagem acontece dentro dele (kanban, chat).\n */\nexport function useFillHeight<T extends HTMLElement = HTMLDivElement>() {\n const ref = useRef<T>(null)\n useLayoutEffect(() => {\n const el = ref.current\n if (!el) return\n const main = el.closest('main')\n const measure = () => {\n // O quadro fica com a altura que sobra na área de conteúdo depois de tudo o que está\n // acima e abaixo dele (título, ações, respiro da página): a página nunca rola por ele.\n // Nunca menos que 20rem, para caber ao menos alguns cards.\n const h = el.getBoundingClientRect().height\n // Altura real do conteúdo da página (o primeiro filho do <main>), não a de rolagem.\n const page = main?.firstElementChild as HTMLElement | null\n const room =\n main && page\n ? main.clientHeight - (page.getBoundingClientRect().height - h)\n : window.innerHeight - el.getBoundingClientRect().top\n el.style.setProperty('--board-h', `${Math.max(320, Math.floor(room))}px`)\n }\n measure()\n const ro = new ResizeObserver(measure)\n ro.observe(document.documentElement)\n if (main) ro.observe(main)\n return () => ro.disconnect()\n }, [])\n return ref\n}\n","import { CheckCircle2, SkipForward, XCircle } from 'lucide-react'\nimport type { ComponentType, ElementType, ReactNode } from 'react'\nimport type { FeedbackType } from '@/brand/types'\nimport { cn } from '@/lib/cn'\nimport { useMotionLib, useMotionPresets } from '@/lib/motion'\n\nexport interface TimelineEvent {\n id: string\n title: ReactNode\n description?: ReactNode\n /** Data em formato curto (ex.: \"22/09/2026 14:30\"). */\n date: string\n tone?: FeedbackType | 'neutral'\n icon?: ReactNode\n /** Resultado do evento: mostrado com ícone e texto, nunca só pela cor. */\n status?: 'succeeded' | 'failed' | 'skipped'\n}\n\nconst dot: Record<NonNullable<TimelineEvent['tone']>, string> = {\n neutral: 'bg-muted text-muted-foreground',\n info: 'bg-info-soft text-info-soft-foreground',\n success: 'bg-success-soft text-success-soft-foreground',\n warning: 'bg-warning-soft text-warning-soft-foreground',\n error: 'bg-destructive-soft text-destructive-soft-foreground',\n}\n\nconst statusTone: Record<\n NonNullable<TimelineEvent['status']>,\n NonNullable<TimelineEvent['tone']>\n> = {\n succeeded: 'success',\n failed: 'error',\n skipped: 'neutral',\n}\n\nconst statusIcon: Record<\n NonNullable<TimelineEvent['status']>,\n ComponentType<{ className?: string }>\n> = {\n succeeded: CheckCircle2,\n failed: XCircle,\n skipped: SkipForward,\n}\n\nconst statusLabel: Record<NonNullable<TimelineEvent['status']>, string> = {\n succeeded: 'Concluído',\n failed: 'Falhou',\n skipped: 'Ignorado',\n}\n\nconst statusTextTone: Record<NonNullable<TimelineEvent['status']>, string> = {\n succeeded: 'text-success-soft-foreground',\n failed: 'text-destructive-soft-foreground',\n skipped: 'text-muted-foreground',\n}\n\n/** Linha do tempo única, com eventos em ordem e tom semântico por evento. */\nexport function Timeline({ events, className }: { events: TimelineEvent[]; className?: string }) {\n const lib = useMotionLib()\n const on = lib !== null\n const presets = useMotionPresets()\n // Em `on` cada evento entra com slide curto e atraso escalonado (no máximo 10 itens).\n const Item: ElementType = on ? lib.m.li : 'li'\n const enter = presets.slide('bottom', 'short')\n return (\n <ol data-rendra=\"TLN-001\" className={cn('@container flex flex-col', className)}>\n {events.map((e, i) => {\n const StatusIcon = e.status ? statusIcon[e.status] : null\n const tone = e.tone ?? (e.status ? statusTone[e.status] : 'neutral')\n return (\n <Item\n key={e.id}\n className=\"relative flex gap-3 pb-6 last:pb-0\"\n {...(on\n ? { ...enter, transition: { ...enter.transition, ...presets.stagger(i) } }\n : {})}\n >\n {i < events.length - 1 && (\n <span\n aria-hidden\n className=\"absolute top-8 bottom-0 left-4 w-px -translate-x-1/2 bg-border\"\n />\n )}\n <span\n aria-hidden\n className={cn(\n 'relative flex size-8 shrink-0 items-center justify-center rounded-full [&_svg]:size-icon-sm',\n dot[tone],\n )}\n >\n {e.icon ?? (StatusIcon && <StatusIcon />) ?? (\n <span className=\"size-2 rounded-full bg-current\" />\n )}\n </span>\n <div className=\"flex min-w-0 flex-1 flex-col gap-1 pt-1\">\n <div className=\"flex min-w-0 flex-col gap-1 @sm:flex-row @sm:items-baseline @sm:justify-between @sm:gap-3\">\n <span className=\"text-sm font-medium wrap-break-word\">{e.title}</span>\n <time className=\"shrink-0 text-xs text-muted-foreground tabular-nums\">\n {e.date}\n </time>\n </div>\n {e.description && (\n <p className=\"text-sm wrap-break-word text-muted-foreground\">{e.description}</p>\n )}\n {e.status && StatusIcon && (\n <span\n className={cn(\n 'inline-flex w-fit items-center gap-1 text-xs font-medium [&_svg]:size-icon-sm',\n statusTextTone[e.status],\n )}\n >\n <StatusIcon />\n {statusLabel[e.status]}\n </span>\n )}\n </div>\n </Item>\n )\n })}\n </ol>\n )\n}\n"],"mappings":"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"}