@rendra-ui/web 2.8.0 → 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/base.css +1 -1
- package/dist/{button-CrSlVIsY.js → button-BcCBrlnt.js} +6 -6
- package/dist/{button-CrSlVIsY.js.map → button-BcCBrlnt.js.map} +1 -1
- package/dist/chart.js +7 -7
- package/dist/cli/auditar.js +1 -1
- package/dist/cli/codigos.js +2 -2
- package/dist/cli/executar-auditar.js +1 -1
- package/dist/cli/help.js +1 -1
- package/dist/cli/trocar.js +2 -2
- package/dist/cli/typescript-loader.js +1 -1
- package/dist/{cn-BlJHpkDs.js → cn-CpdCvlkP.js} +2 -2
- package/dist/{cn-BlJHpkDs.js.map → cn-CpdCvlkP.js.map} +1 -1
- package/dist/{components-6RpoJ2Od.js → components-Bus_Jh2R.js} +7 -4
- package/dist/components-Bus_Jh2R.js.map +1 -0
- package/dist/components.css +67 -26
- package/dist/document-viewer.js +4 -4
- package/dist/{dropdown-menu-BUGKtR6k.js → dropdown-menu-B3L1XSDf.js} +5 -5
- package/dist/{dropdown-menu-BUGKtR6k.js.map → dropdown-menu-B3L1XSDf.js.map} +1 -1
- package/dist/{brand-feedback-icon-CVux4pNh.js → empty-state-Bcx4M0Me.js} +64 -4
- package/dist/empty-state-Bcx4M0Me.js.map +1 -0
- package/dist/{features-max-BCIy1Ic-.js → features-max-CoyJ_kuK.js} +1 -1
- package/dist/flow.js +2818 -868
- package/dist/flow.js.map +1 -1
- package/dist/index.js +80 -465
- package/dist/index.js.map +1 -1
- package/dist/{motion-context-PJPj6X4g.js → motion-context-DWFl2xRr.js} +4 -4
- package/dist/{motion-context-PJPj6X4g.js.map → motion-context-DWFl2xRr.js.map} +1 -1
- package/dist/{motion-on-Bocf4Smc.js → motion-on-zwsBqYZL.js} +2 -2
- package/dist/{motion-on-Bocf4Smc.js.map → motion-on-zwsBqYZL.js.map} +1 -1
- package/dist/motion.js +2 -2
- package/dist/{rendra-provider-Do_qWjJC.js → rendra-provider-DuIhBatD.js} +3 -3
- package/dist/{rendra-provider-Do_qWjJC.js.map → rendra-provider-DuIhBatD.js.map} +1 -1
- package/dist/rich-text-editor.js +4 -4
- package/dist/router-bridge.js +2 -2
- package/dist/{timeline-xrMHeV92.js → toast-C7qYslCp.js} +464 -80
- package/dist/toast-C7qYslCp.js.map +1 -0
- package/dist/tokens.css +1 -1
- package/dist/{tooltip-to0h6aPe.js → tooltip-BSPO-bH4.js} +5 -5
- package/dist/{tooltip-to0h6aPe.js.map → tooltip-BSPO-bH4.js.map} +1 -1
- package/dist/types/components/ui/flow-config-panels.d.ts +10 -0
- package/dist/types/components/ui/flow-editor.d.ts +5 -0
- package/dist/types/components/ui/flow-sidebar.d.ts +21 -0
- package/dist/types/components/ui/flow-simulation-panel.d.ts +20 -0
- package/dist/types/components/ui/flow-viewer.d.ts +27 -10
- package/dist/types/flow.d.ts +1 -1
- package/dist/types/lib/flow-blocks.d.ts +122 -0
- package/dist/types/lib/flow-edit.d.ts +88 -0
- package/dist/types/lib/flow-layout.d.ts +3 -0
- package/dist/types/lib/flow-sim.d.ts +24 -0
- package/dist/types/lib/flow.d.ts +30 -80
- package/dist/{use-breakpoint-CM-yeDHJ.js → use-breakpoint-BGmY3ir-.js} +2 -2
- package/dist/{use-breakpoint-CM-yeDHJ.js.map → use-breakpoint-BGmY3ir-.js.map} +1 -1
- package/dist/{use-motion-presets-I4StrsCi.js → use-motion-presets-CmMLBQLI.js} +3 -3
- package/dist/{use-motion-presets-I4StrsCi.js.map → use-motion-presets-CmMLBQLI.js.map} +1 -1
- package/dist/widget-grid.js +2 -2
- package/package.json +2 -1
- package/dist/brand-feedback-icon-CVux4pNh.js.map +0 -1
- package/dist/components-6RpoJ2Od.js.map +0 -1
- package/dist/empty-state-i4e-LacG.js +0 -67
- package/dist/empty-state-i4e-LacG.js.map +0 -1
- package/dist/timeline-xrMHeV92.js.map +0 -1
package/README.md
CHANGED
|
@@ -180,7 +180,7 @@ Todos em `src/components/ui`, um por finalidade, com o ícone de feedback da mar
|
|
|
180
180
|
| **Atendimento** | Chat omnichannel: ConversationList (foto com o logotipo do canal: WhatsApp, WhatsApp Web, Instagram, Facebook, TikTok, Google Meu Negócio e Reclame Aqui), ChatThread (cliente, atendente, robô e avisos; botão direito ou "…" para responder, reagir, editar e excluir; citação que leva à mensagem original; áudio em 1x, 1,5x e 2x; baixar anexos) e ChatComposer (textarea que cresce, anexos, emoji, mensagens rápidas, gravação de áudio, arrastar e soltar ou colar prints; no celular, campo, enviar e um botão de ações) |
|
|
181
181
|
| **Conteúdo** | RichTextEditor (Tiptap): formatação completa, listas, alinhamento, links, tabela, imagem com 4 alças para redimensionar, colar print, arrastar imagens e modo HTML |
|
|
182
182
|
| **Painel** | WidgetGrid: widgets que se arrastam e redimensionam no modo "Ajustar dashboard", com a arrumação salva; Chart com velocímetro de meta, funil com conversão, barras com linha, barras coloridas e empilhadas |
|
|
183
|
-
| **Fluxo** | FlowEditor (
|
|
183
|
+
| **Fluxo** | FlowEditor (editor de automações no estilo N8N: quadro horizontal com cards e ligações animadas, barra lateral com busca e blocos agrupados, configuração por bloco, condição com várias regras, webhooks simulados com mapeamento de campos, ligar soltando no bloco, exclusão com confirmação, validar e testar o caminho passo a passo; o JSON v2 vai e volta por `serializeFlow` e `parseFlow`, e o da 2.7.0 também abre; no celular só vê e navega, e a barra abre num Drawer) e FlowViewer (só leitura), em `@rendra-ui/web/flow` com o React Flow |
|
|
184
184
|
| **Planejamento** | Calendar (mês, semana, dia e agenda em lista, no mesmo componente; no celular vira mês compacto com a lista do dia), Kanban (altura da tela, 5 etapas visíveis e rolagem lateral também pelo touchpad, rolagem infinita por etapa, (+) no título da etapa, totais em R$ de P&S e MRR por etapa, com percentual, e por cartão, status por cor com cadência por etapa e calendário da próxima atividade, barra do quadro com busca, filtros e Customizar, arrastar no computador até o rodapé flutuante com confirmação, menu "Mover para" no toque e no teclado, uma coluna por vez no celular, limite por coluna) e ImageViewer (imagens em popup, com setas, Esc, arrastar e pinça) |
|
|
185
185
|
| **Layout** | Container (respiro igual em todos os lados), Stack, Inline, Grid (por tela ou por container query), Section e PageHeader (título no corpo do celular por `bodyTitle`, sem reservar o bloco do título por `titleSpace`) |
|
|
186
186
|
|
|
@@ -199,7 +199,7 @@ Tudo configurável por props, com o padrão em `src/config/layout.ts`:
|
|
|
199
199
|
|
|
200
200
|
### Telas base
|
|
201
201
|
|
|
202
|
-
Login, esqueci a senha, verificação em duas etapas (2FA), nova senha, cadastro, painel com indicadores e gráficos, listagem com barra de ferramentas e filtros, detalhe com abas, formulário longo em seções, cadastro em wizard, configurações com navegação interna, criação e edição de registro em drawer (com busca de CNPJ e CEP), tarefas, atendimento omnichannel, agenda, funil de vendas em kanban, painel em widgets, galeria e página 404.
|
|
202
|
+
Login, esqueci a senha, verificação em duas etapas (2FA), nova senha, cadastro, painel com indicadores e gráficos, listagem com barra de ferramentas e filtros, detalhe com abas, formulário longo em seções, cadastro em wizard, configurações com navegação interna, criação e edição de registro em drawer (com busca de CNPJ e CEP), tarefas, atendimento omnichannel, agenda, funil de vendas em kanban, automações (listagem e a tela cheia de automação, com abas e histórico de execuções), painel em widgets, galeria e página 404.
|
|
203
203
|
|
|
204
204
|
### Movimento (opcional, desligado por padrão)
|
|
205
205
|
|
|
@@ -232,7 +232,7 @@ Com React Router, ponha a prop na ponte, que já entrega ao provider o link, o c
|
|
|
232
232
|
- **Storybook 10** com mais de 100 stories: viewport de celular por padrão, com tablet e desktop, e alternância de template, paleta e modo claro/escuro na barra.
|
|
233
233
|
- **Testes de layout com Playwright** (`npm run test:layout`): 16 rotas × 5 larguras (360, 390, 768, 1280 e 1920) × 3 templates no modo claro, mais 360 e 1280 no escuro, somando 336 testes. Falham se houver rolagem horizontal, elemento maior que a tela, toque menor que 44px no celular ou erro de JavaScript, e geram capturas de todas as telas.
|
|
234
234
|
- **Testes de acessibilidade com axe-core** (`npm run test:a11y`): 144 testes, todas as rotas nos três templates, claro e escuro, mais a paleta Ardósia e o celular. Falham em qualquer violação WCAG 2.1 A ou AA, inclusive contraste.
|
|
235
|
-
- **Regressão visual** (`npm run test:visual`):
|
|
235
|
+
- **Regressão visual** (`npm run test:visual`): 168 capturas comparadas (21 rotas, as duas das automações entram com o rótulo `atualizar-visual`) com a referência aprovada. Pegam cor que mudou, espaçamento que quebrou e ícone que sumiu. As referências são geradas no Linux do CI; depois de uma mudança visual intencional, aplique o rótulo `atualizar-visual` no Pull Request.
|
|
236
236
|
- **Testes unitários e de componente com Vitest e Testing Library** (`npm test`; `npm run test:coverage` com o piso por arquivo): comportamento de Table (ordenação, busca, paginação, seleção, ações em massa, modo remoto e cartões no celular), Select, Input (máscaras, centavos e busca de CEP e CNPJ), Modal, Drawer, campos de formulário e navegação, além de validadores, máscaras, buscas e o gerador de paletas (AA garantido em todas). Cada componente tem o teste ao lado, e ele vai junto quando você copia o componente para outro projeto.
|
|
237
237
|
- **CI no GitHub Actions**: todo Pull Request passa por tipos, lint, formatação, regras, unitários, build, Storybook e os três testes no navegador. A `main` só aceita merge com tudo verde. Os alertas de segurança do GitHub avisam de dependência vulnerável; as atualizações de versão são feitas à mão (veja o `CONTRIBUTING.md`).
|
|
238
238
|
- **Verificador de regras** (`npm run check:rules`): barra cor fixa, valor arbitrário, degrau fora da escala, estilo inline, fonte fixa, `100vh` e arquivos duplicados ou mobile. A mesma varredura, com as 17 regras, roda em qualquer projeto por `npx @rendra-ui/web auditar --all`.
|
package/dist/base.css
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
/*! Rendra Design System v2.
|
|
2
|
-
import { t as cn } from "./cn-
|
|
3
|
-
import { a as useMotionMode, o as useMotionOn, u as usePrefersReducedMotion } from "./motion-context-
|
|
4
|
-
import { t as useMotionPresets } from "./use-motion-presets-
|
|
5
|
-
import { p as resolveCatalogCode } from "./components-
|
|
1
|
+
/*! Rendra Design System v2.9.0 | MIT | © 2026 Bruno Magalhaes | brunomagalhaes.me */
|
|
2
|
+
import { t as cn } from "./cn-CpdCvlkP.js";
|
|
3
|
+
import { a as useMotionMode, o as useMotionOn, u as usePrefersReducedMotion } from "./motion-context-DWFl2xRr.js";
|
|
4
|
+
import { t as useMotionPresets } from "./use-motion-presets-CmMLBQLI.js";
|
|
5
|
+
import { p as resolveCatalogCode } from "./components-Bus_Jh2R.js";
|
|
6
6
|
import { Loader2 } from "lucide-react";
|
|
7
7
|
import { Slot } from "radix-ui";
|
|
8
8
|
import { forwardRef } from "react";
|
|
@@ -205,4 +205,4 @@ var Button = forwardRef(function Button({ className, variant, size, icon, iconRi
|
|
|
205
205
|
//#endregion
|
|
206
206
|
export { buttonVariants as n, Spinner as r, Button as t };
|
|
207
207
|
|
|
208
|
-
//# sourceMappingURL=button-
|
|
208
|
+
//# sourceMappingURL=button-BcCBrlnt.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"button-CrSlVIsY.js","names":[],"sources":["../src/components/ui/spinner.tsx","../src/lib/motion/native-events.ts","../src/components/ui/button.tsx"],"sourcesContent":["import { Loader2 } from 'lucide-react'\nimport { usePrefersReducedMotion } from '@/hooks/use-reduced-motion'\nimport { cn } from '@/lib/cn'\n\n/*\n * Indicador de carregamento único do sistema (A17 do plano da v2). Substitui qualquer\n * `Loader2 animate-spin` solto em Button, Input e Select. Sem label é decorativo\n * (aria-hidden); com label, anuncia o carregamento a quem usa leitor de tela. Para de girar\n * quando o sistema pede menos movimento.\n */\n\nexport interface SpinnerProps {\n size?: 'sm' | 'md' | 'lg'\n /** Nome do que está carregando. Vazio (padrão): decorativo, sem anúncio de leitor de tela. */\n label?: string\n className?: string\n}\n\nconst sizeClass: Record<NonNullable<SpinnerProps['size']>, string> = {\n sm: 'size-icon-sm',\n md: 'size-icon-md',\n lg: 'size-icon-lg',\n}\n\nexport function Spinner({ size = 'md', label, className }: SpinnerProps) {\n const reduced = usePrefersReducedMotion()\n const icon = (\n <Loader2 aria-hidden className={cn(sizeClass[size], reduced ? '' : 'animate-spin')} />\n )\n\n if (!label) {\n return (\n <span data-rendra=\"SPIN-001\" aria-hidden className={cn('inline-flex', className)}>\n {icon}\n </span>\n )\n }\n\n return (\n <span\n data-rendra=\"SPIN-001\"\n role=\"status\"\n className={cn('inline-flex items-center gap-2', className)}\n >\n {icon}\n <span className=\"sr-only\">{label}</span>\n </span>\n )\n}\n","/*\n * O Motion toma `onDrag`, `onDragStart`, `onDragEnd` e `onAnimationStart` para os gestos e\n * animações dele: tira essas props do DOM e as tipa com outra assinatura. Em `m.button` e\n * `m.li`, o consumidor que passa o evento nativo (HTML5 drag, animationstart do CSS) o perderia.\n * Estes ajudantes separam essas chaves das props e as ligam como ouvintes nativos no elemento.\n */\n\nconst NATIVE_EVENTS = {\n onDrag: 'drag',\n onDragStart: 'dragstart',\n onDragEnd: 'dragend',\n onAnimationStart: 'animationstart',\n} as const\n\ntype NativeKey = keyof typeof NATIVE_EVENTS\ntype Handler = ((event: never) => void) | undefined\n\n/** Separa as quatro chaves em conflito; o resto segue para o elemento do Motion. */\nexport function splitNativeEvents<P extends object>(props: P) {\n const native: Partial<Record<NativeKey, Handler>> = {}\n const rest: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(props)) {\n if (key in NATIVE_EVENTS) native[key as NativeKey] = value as Handler\n else rest[key] = value\n }\n return { native, rest: rest as Omit<P, NativeKey> }\n}\n\n/** Liga os manipuladores como ouvintes nativos. Devolve a função que os remove. */\nexport function bindNativeEvents(el: HTMLElement, native: Partial<Record<NativeKey, Handler>>) {\n const bound: [string, EventListener][] = []\n for (const [key, type] of Object.entries(NATIVE_EVENTS)) {\n const handler = native[key as NativeKey]\n if (!handler) continue\n const listener = ((event: Event) => handler(event as never)) as EventListener\n el.addEventListener(type, listener)\n bound.push([type, listener])\n }\n return () => bound.forEach(([type, listener]) => el.removeEventListener(type, listener))\n}\n","import { cva, type VariantProps } from 'class-variance-authority'\nimport { Slot } from 'radix-ui'\nimport { forwardRef, type ButtonHTMLAttributes, type ReactNode, type Ref } from 'react'\nimport { resolveCatalogCode } from '@/catalog/components'\nimport { Spinner } from '@/components/ui/spinner'\nimport { cn } from '@/lib/cn'\nimport { useMotionMode, useMotionOn, useMotionPresets } from '@/lib/motion'\nimport { bindNativeEvents, splitNativeEvents } from '@/lib/motion/native-events'\n\n/**\n * Botão único do sistema. Variantes, tamanho, ícone, só ícone, carregamento e\n * largura total são props: nunca crie outro arquivo de botão.\n * Altura vem de h-control-*: 44px ou mais no mobile, compacta a partir de md.\n */\nexport const buttonVariants = cva(\n 'inline-flex shrink-0 cursor-pointer items-center justify-center gap-2 rounded-control font-medium whitespace-nowrap transition-[color,background-color,border-color,box-shadow,transform] duration-(--rendra-duration-press) ease-out select-none active:scale-97 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 motion-reduce:active:scale-100 [&_svg]:pointer-events-none [&_svg]:shrink-0',\n {\n variants: {\n variant: {\n // Hover troca para a cor de hover da marca e eleva um nível; pressionar comprime.\n primary:\n 'bg-primary text-primary-foreground shadow-sm hover:bg-primary-hover hover:text-primary-hover-foreground hover:shadow-md active:bg-primary-hover active:text-primary-hover-foreground active:shadow-sm',\n secondary:\n 'bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary-hover hover:text-secondary-hover-foreground hover:shadow-md active:bg-secondary-hover active:text-secondary-hover-foreground active:shadow-sm',\n outline:\n 'border border-input bg-card text-foreground hover:border-primary hover:bg-primary-soft hover:text-primary-soft-foreground active:bg-primary-soft',\n // Transparentes: no hover, assumem a cor primária do template.\n ghost:\n 'text-foreground hover:bg-primary-soft hover:text-primary-soft-foreground active:bg-primary-soft',\n destructive:\n 'bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive-hover hover:shadow-md active:bg-destructive-hover active:shadow-sm',\n link: 'min-h-touch min-w-touch text-primary-text underline-offset-4 hover:text-primary-hover hover:underline md:min-h-0 md:min-w-0',\n },\n size: {\n sm: 'h-control-sm px-3 text-sm [&_svg]:size-icon-sm',\n md: 'h-control-md px-4 text-sm [&_svg]:size-icon-sm',\n lg: 'h-control-lg px-6 text-base [&_svg]:size-icon-md',\n },\n iconOnly: { true: 'px-0', false: '' },\n fullWidth: { true: 'w-full', false: '' },\n },\n compoundVariants: [\n { iconOnly: true, size: 'sm', className: 'w-control-sm' },\n { iconOnly: true, size: 'md', className: 'w-control-md' },\n { iconOnly: true, size: 'lg', className: 'w-control-lg' },\n { variant: 'link', className: 'h-auto px-0' },\n ],\n defaultVariants: { variant: 'primary', size: 'md', iconOnly: false, fullWidth: false },\n },\n)\n\ntype Variants = VariantProps<typeof buttonVariants>\n\nexport interface ButtonProps\n extends ButtonHTMLAttributes<HTMLButtonElement>, Omit<Variants, 'iconOnly' | 'fullWidth'> {\n /** Ícone à esquerda do texto (ou o próprio conteúdo, com iconOnly). */\n icon?: ReactNode\n /** Ícone à direita do texto. */\n iconRight?: ReactNode\n /** Botão só com ícone: quadrado, e aria-label passa a ser obrigatório. */\n iconOnly?: boolean\n /** Mostra indicador, bloqueia cliques e marca aria-busy. */\n loading?: boolean\n /** Ocupa toda a largura do contêiner. */\n fullWidth?: boolean\n /** Renderiza o filho (ex.: <Link>) com a aparência de botão. */\n asChild?: boolean\n}\n\ntype MotionButtonProps = Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'children'> & {\n children: ReactNode\n}\n\n/**\n * O botão de `on`: `m.button` com toque discreto (whileTap). Os eventos que o Motion toma\n * (`onDrag*` e `onAnimationStart`) saem das props dele e viram ouvintes nativos no elemento,\n * então o consumidor continua recebendo o evento. Só existe em `on`; por isso os hooks de motion\n * moram aqui e o `off` não paga nada.\n */\nconst MotionButton = forwardRef<HTMLButtonElement, MotionButtonProps>(\n function MotionButton(props, ref) {\n const { m } = useMotionOn()\n const presets = useMotionPresets()\n const { native, rest } = splitNativeEvents(props)\n const attach = (el: HTMLButtonElement | null) => {\n assignRef(ref, el)\n if (!el) return\n const unbind = bindNativeEvents(el, native)\n return () => {\n unbind()\n assignRef(ref, null)\n }\n }\n return (\n <m.button\n ref={attach}\n whileTap={presets.press.whileTap}\n transition={presets.press.transition}\n {...rest}\n />\n )\n },\n)\n\nfunction assignRef<T>(ref: Ref<T> | undefined, value: T | null) {\n if (typeof ref === 'function') ref(value)\n else if (ref) ref.current = value\n}\n\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button(\n {\n className,\n variant,\n size,\n icon,\n iconRight,\n iconOnly = false,\n loading = false,\n fullWidth = false,\n asChild = false,\n disabled,\n type = 'button',\n children,\n ...props\n },\n ref,\n) {\n if (import.meta.env.DEV && iconOnly && !props['aria-label']) {\n console.warn('Button com iconOnly precisa de aria-label.')\n }\n const on = useMotionMode() === 'on'\n // Em `on` o toque é do whileTap: a classe `active:scale-97` sairia somando com ele, e o\n // `transform` sai da lista de transition (senão o CSS transiciona cada quadro que o Motion grava\n // e o toque chega atrasado). Com asChild nada disso: é só CSS, como em `off`.\n const classes = cn(\n buttonVariants({ variant, size, iconOnly, fullWidth }),\n on &&\n !asChild &&\n 'transition-[color,background-color,border-color,box-shadow] active:scale-100',\n className,\n )\n const code = resolveCatalogCode('Button', { variant: variant ?? 'primary' })\n\n if (asChild) {\n return (\n <Slot.Root ref={ref} data-rendra={code} className={classes} {...props}>\n {children}\n </Slot.Root>\n )\n }\n\n // Ícone dentro do botão segue o tamanho do próprio botão (sm/md -> sm, lg -> md, como o\n // [&_svg]:size-icon-* de buttonVariants já fazia com o Loader2 solto).\n const leading = loading ? <Spinner size={size === 'lg' ? 'md' : 'sm'} /> : icon\n if (on) {\n return (\n <MotionButton\n ref={ref}\n type={type}\n data-rendra={code}\n className={classes}\n disabled={disabled || loading}\n aria-busy={loading || undefined}\n {...props}\n >\n {leading}\n {iconOnly ? (loading ? null : children) : children}\n {!iconOnly && iconRight}\n </MotionButton>\n )\n }\n return (\n <button\n ref={ref}\n type={type}\n data-rendra={code}\n className={classes}\n disabled={disabled || loading}\n aria-busy={loading || undefined}\n {...props}\n >\n {leading}\n {iconOnly ? (loading ? null : children) : children}\n {!iconOnly && iconRight}\n </button>\n )\n})\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"button-BcCBrlnt.js","names":[],"sources":["../src/components/ui/spinner.tsx","../src/lib/motion/native-events.ts","../src/components/ui/button.tsx"],"sourcesContent":["import { Loader2 } from 'lucide-react'\nimport { usePrefersReducedMotion } from '@/hooks/use-reduced-motion'\nimport { cn } from '@/lib/cn'\n\n/*\n * Indicador de carregamento único do sistema (A17 do plano da v2). Substitui qualquer\n * `Loader2 animate-spin` solto em Button, Input e Select. Sem label é decorativo\n * (aria-hidden); com label, anuncia o carregamento a quem usa leitor de tela. Para de girar\n * quando o sistema pede menos movimento.\n */\n\nexport interface SpinnerProps {\n size?: 'sm' | 'md' | 'lg'\n /** Nome do que está carregando. Vazio (padrão): decorativo, sem anúncio de leitor de tela. */\n label?: string\n className?: string\n}\n\nconst sizeClass: Record<NonNullable<SpinnerProps['size']>, string> = {\n sm: 'size-icon-sm',\n md: 'size-icon-md',\n lg: 'size-icon-lg',\n}\n\nexport function Spinner({ size = 'md', label, className }: SpinnerProps) {\n const reduced = usePrefersReducedMotion()\n const icon = (\n <Loader2 aria-hidden className={cn(sizeClass[size], reduced ? '' : 'animate-spin')} />\n )\n\n if (!label) {\n return (\n <span data-rendra=\"SPIN-001\" aria-hidden className={cn('inline-flex', className)}>\n {icon}\n </span>\n )\n }\n\n return (\n <span\n data-rendra=\"SPIN-001\"\n role=\"status\"\n className={cn('inline-flex items-center gap-2', className)}\n >\n {icon}\n <span className=\"sr-only\">{label}</span>\n </span>\n )\n}\n","/*\n * O Motion toma `onDrag`, `onDragStart`, `onDragEnd` e `onAnimationStart` para os gestos e\n * animações dele: tira essas props do DOM e as tipa com outra assinatura. Em `m.button` e\n * `m.li`, o consumidor que passa o evento nativo (HTML5 drag, animationstart do CSS) o perderia.\n * Estes ajudantes separam essas chaves das props e as ligam como ouvintes nativos no elemento.\n */\n\nconst NATIVE_EVENTS = {\n onDrag: 'drag',\n onDragStart: 'dragstart',\n onDragEnd: 'dragend',\n onAnimationStart: 'animationstart',\n} as const\n\ntype NativeKey = keyof typeof NATIVE_EVENTS\ntype Handler = ((event: never) => void) | undefined\n\n/** Separa as quatro chaves em conflito; o resto segue para o elemento do Motion. */\nexport function splitNativeEvents<P extends object>(props: P) {\n const native: Partial<Record<NativeKey, Handler>> = {}\n const rest: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(props)) {\n if (key in NATIVE_EVENTS) native[key as NativeKey] = value as Handler\n else rest[key] = value\n }\n return { native, rest: rest as Omit<P, NativeKey> }\n}\n\n/** Liga os manipuladores como ouvintes nativos. Devolve a função que os remove. */\nexport function bindNativeEvents(el: HTMLElement, native: Partial<Record<NativeKey, Handler>>) {\n const bound: [string, EventListener][] = []\n for (const [key, type] of Object.entries(NATIVE_EVENTS)) {\n const handler = native[key as NativeKey]\n if (!handler) continue\n const listener = ((event: Event) => handler(event as never)) as EventListener\n el.addEventListener(type, listener)\n bound.push([type, listener])\n }\n return () => bound.forEach(([type, listener]) => el.removeEventListener(type, listener))\n}\n","import { cva, type VariantProps } from 'class-variance-authority'\nimport { Slot } from 'radix-ui'\nimport { forwardRef, type ButtonHTMLAttributes, type ReactNode, type Ref } from 'react'\nimport { resolveCatalogCode } from '@/catalog/components'\nimport { Spinner } from '@/components/ui/spinner'\nimport { cn } from '@/lib/cn'\nimport { useMotionMode, useMotionOn, useMotionPresets } from '@/lib/motion'\nimport { bindNativeEvents, splitNativeEvents } from '@/lib/motion/native-events'\n\n/**\n * Botão único do sistema. Variantes, tamanho, ícone, só ícone, carregamento e\n * largura total são props: nunca crie outro arquivo de botão.\n * Altura vem de h-control-*: 44px ou mais no mobile, compacta a partir de md.\n */\nexport const buttonVariants = cva(\n 'inline-flex shrink-0 cursor-pointer items-center justify-center gap-2 rounded-control font-medium whitespace-nowrap transition-[color,background-color,border-color,box-shadow,transform] duration-(--rendra-duration-press) ease-out select-none active:scale-97 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 motion-reduce:active:scale-100 [&_svg]:pointer-events-none [&_svg]:shrink-0',\n {\n variants: {\n variant: {\n // Hover troca para a cor de hover da marca e eleva um nível; pressionar comprime.\n primary:\n 'bg-primary text-primary-foreground shadow-sm hover:bg-primary-hover hover:text-primary-hover-foreground hover:shadow-md active:bg-primary-hover active:text-primary-hover-foreground active:shadow-sm',\n secondary:\n 'bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary-hover hover:text-secondary-hover-foreground hover:shadow-md active:bg-secondary-hover active:text-secondary-hover-foreground active:shadow-sm',\n outline:\n 'border border-input bg-card text-foreground hover:border-primary hover:bg-primary-soft hover:text-primary-soft-foreground active:bg-primary-soft',\n // Transparentes: no hover, assumem a cor primária do template.\n ghost:\n 'text-foreground hover:bg-primary-soft hover:text-primary-soft-foreground active:bg-primary-soft',\n destructive:\n 'bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive-hover hover:shadow-md active:bg-destructive-hover active:shadow-sm',\n link: 'min-h-touch min-w-touch text-primary-text underline-offset-4 hover:text-primary-hover hover:underline md:min-h-0 md:min-w-0',\n },\n size: {\n sm: 'h-control-sm px-3 text-sm [&_svg]:size-icon-sm',\n md: 'h-control-md px-4 text-sm [&_svg]:size-icon-sm',\n lg: 'h-control-lg px-6 text-base [&_svg]:size-icon-md',\n },\n iconOnly: { true: 'px-0', false: '' },\n fullWidth: { true: 'w-full', false: '' },\n },\n compoundVariants: [\n { iconOnly: true, size: 'sm', className: 'w-control-sm' },\n { iconOnly: true, size: 'md', className: 'w-control-md' },\n { iconOnly: true, size: 'lg', className: 'w-control-lg' },\n { variant: 'link', className: 'h-auto px-0' },\n ],\n defaultVariants: { variant: 'primary', size: 'md', iconOnly: false, fullWidth: false },\n },\n)\n\ntype Variants = VariantProps<typeof buttonVariants>\n\nexport interface ButtonProps\n extends ButtonHTMLAttributes<HTMLButtonElement>, Omit<Variants, 'iconOnly' | 'fullWidth'> {\n /** Ícone à esquerda do texto (ou o próprio conteúdo, com iconOnly). */\n icon?: ReactNode\n /** Ícone à direita do texto. */\n iconRight?: ReactNode\n /** Botão só com ícone: quadrado, e aria-label passa a ser obrigatório. */\n iconOnly?: boolean\n /** Mostra indicador, bloqueia cliques e marca aria-busy. */\n loading?: boolean\n /** Ocupa toda a largura do contêiner. */\n fullWidth?: boolean\n /** Renderiza o filho (ex.: <Link>) com a aparência de botão. */\n asChild?: boolean\n}\n\ntype MotionButtonProps = Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'children'> & {\n children: ReactNode\n}\n\n/**\n * O botão de `on`: `m.button` com toque discreto (whileTap). Os eventos que o Motion toma\n * (`onDrag*` e `onAnimationStart`) saem das props dele e viram ouvintes nativos no elemento,\n * então o consumidor continua recebendo o evento. Só existe em `on`; por isso os hooks de motion\n * moram aqui e o `off` não paga nada.\n */\nconst MotionButton = forwardRef<HTMLButtonElement, MotionButtonProps>(\n function MotionButton(props, ref) {\n const { m } = useMotionOn()\n const presets = useMotionPresets()\n const { native, rest } = splitNativeEvents(props)\n const attach = (el: HTMLButtonElement | null) => {\n assignRef(ref, el)\n if (!el) return\n const unbind = bindNativeEvents(el, native)\n return () => {\n unbind()\n assignRef(ref, null)\n }\n }\n return (\n <m.button\n ref={attach}\n whileTap={presets.press.whileTap}\n transition={presets.press.transition}\n {...rest}\n />\n )\n },\n)\n\nfunction assignRef<T>(ref: Ref<T> | undefined, value: T | null) {\n if (typeof ref === 'function') ref(value)\n else if (ref) ref.current = value\n}\n\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button(\n {\n className,\n variant,\n size,\n icon,\n iconRight,\n iconOnly = false,\n loading = false,\n fullWidth = false,\n asChild = false,\n disabled,\n type = 'button',\n children,\n ...props\n },\n ref,\n) {\n if (import.meta.env.DEV && iconOnly && !props['aria-label']) {\n console.warn('Button com iconOnly precisa de aria-label.')\n }\n const on = useMotionMode() === 'on'\n // Em `on` o toque é do whileTap: a classe `active:scale-97` sairia somando com ele, e o\n // `transform` sai da lista de transition (senão o CSS transiciona cada quadro que o Motion grava\n // e o toque chega atrasado). Com asChild nada disso: é só CSS, como em `off`.\n const classes = cn(\n buttonVariants({ variant, size, iconOnly, fullWidth }),\n on &&\n !asChild &&\n 'transition-[color,background-color,border-color,box-shadow] active:scale-100',\n className,\n )\n const code = resolveCatalogCode('Button', { variant: variant ?? 'primary' })\n\n if (asChild) {\n return (\n <Slot.Root ref={ref} data-rendra={code} className={classes} {...props}>\n {children}\n </Slot.Root>\n )\n }\n\n // Ícone dentro do botão segue o tamanho do próprio botão (sm/md -> sm, lg -> md, como o\n // [&_svg]:size-icon-* de buttonVariants já fazia com o Loader2 solto).\n const leading = loading ? <Spinner size={size === 'lg' ? 'md' : 'sm'} /> : icon\n if (on) {\n return (\n <MotionButton\n ref={ref}\n type={type}\n data-rendra={code}\n className={classes}\n disabled={disabled || loading}\n aria-busy={loading || undefined}\n {...props}\n >\n {leading}\n {iconOnly ? (loading ? null : children) : children}\n {!iconOnly && iconRight}\n </MotionButton>\n )\n }\n return (\n <button\n ref={ref}\n type={type}\n data-rendra={code}\n className={classes}\n disabled={disabled || loading}\n aria-busy={loading || undefined}\n {...props}\n >\n {leading}\n {iconOnly ? (loading ? null : children) : children}\n {!iconOnly && iconRight}\n </button>\n )\n})\n"],"mappings":"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"}
|
package/dist/chart.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
/*! Rendra Design System v2.
|
|
2
|
-
import { t as cn } from "./cn-
|
|
3
|
-
import { a as useMotionMode, i as useMotionLib, s as useRevealScope } from "./motion-context-
|
|
4
|
-
import { n as toCubicBezier, t as useMotionPresets } from "./use-motion-presets-
|
|
5
|
-
import { p as resolveCatalogCode } from "./components-
|
|
6
|
-
import { t as Button } from "./button-
|
|
7
|
-
import { n as useBreakpoint } from "./use-breakpoint-
|
|
1
|
+
/*! Rendra Design System v2.9.0 | MIT | © 2026 Bruno Magalhaes | brunomagalhaes.me */
|
|
2
|
+
import { t as cn } from "./cn-CpdCvlkP.js";
|
|
3
|
+
import { a as useMotionMode, i as useMotionLib, s as useRevealScope } from "./motion-context-DWFl2xRr.js";
|
|
4
|
+
import { n as toCubicBezier, t as useMotionPresets } from "./use-motion-presets-CmMLBQLI.js";
|
|
5
|
+
import { p as resolveCatalogCode } from "./components-Bus_Jh2R.js";
|
|
6
|
+
import { t as Button } from "./button-BcCBrlnt.js";
|
|
7
|
+
import { n as useBreakpoint } from "./use-breakpoint-BGmY3ir-.js";
|
|
8
8
|
import { ArrowDown, BarChart3, List } from "lucide-react";
|
|
9
9
|
import { useId, useRef, useState } from "react";
|
|
10
10
|
import { jsx, jsxs } from "react/jsx-runtime";
|
package/dist/cli/auditar.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! Rendra Design System v2.
|
|
1
|
+
/*! Rendra Design System v2.9.0 | MIT | © 2026 Bruno Magalhaes | brunomagalhaes.me */
|
|
2
2
|
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
3
3
|
import { join, relative, sep } from "node:path";
|
|
4
4
|
//#region src/cli/auditar.ts
|
package/dist/cli/codigos.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/*! Rendra Design System v2.
|
|
2
|
-
import { t as CATALOG } from "../components-
|
|
1
|
+
/*! Rendra Design System v2.9.0 | MIT | © 2026 Bruno Magalhaes | brunomagalhaes.me */
|
|
2
|
+
import { t as CATALOG } from "../components-Bus_Jh2R.js";
|
|
3
3
|
//#region src/cli/codigos.ts
|
|
4
4
|
/** Todo o catálogo, na ordem cadastrada. Sem duplicata: garantido por assertCatalogIntegrity. */
|
|
5
5
|
function codigos() {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! Rendra Design System v2.
|
|
1
|
+
/*! Rendra Design System v2.9.0 | MIT | © 2026 Bruno Magalhaes | brunomagalhaes.me */
|
|
2
2
|
import { EXTENSAO_VARRIDA, IDS_REGRAS_GENERICAS, auditLines, auditar, casaPrefixo, coletarArquivos, percorrer, relativoA } from "./auditar.js";
|
|
3
3
|
import { formatHelp } from "./help.js";
|
|
4
4
|
import { existsSync, readFileSync } from "node:fs";
|
package/dist/cli/help.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! Rendra Design System v2.
|
|
1
|
+
/*! Rendra Design System v2.9.0 | MIT | © 2026 Bruno Magalhaes | brunomagalhaes.me */
|
|
2
2
|
//#region src/cli/help.ts
|
|
3
3
|
/** Linha final de autoria, igual em toda saída publicável (CLI, banner do pacote). */
|
|
4
4
|
var AUTHOR_LINE = "Rendra Design System, por Bruno Magalhaes: brunomagalhaes.me · instagram.com/brunomagalhaes.me";
|
package/dist/cli/trocar.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/*! Rendra Design System v2.
|
|
2
|
-
import { f as getCatalogEntry } from "../components-
|
|
1
|
+
/*! Rendra Design System v2.9.0 | MIT | © 2026 Bruno Magalhaes | brunomagalhaes.me */
|
|
2
|
+
import { f as getCatalogEntry } from "../components-Bus_Jh2R.js";
|
|
3
3
|
import { existsSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { join, relative, sep } from "node:path";
|
|
5
5
|
//#region src/cli/trocar.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! Rendra Design System v2.
|
|
1
|
+
/*! Rendra Design System v2.9.0 | MIT | © 2026 Bruno Magalhaes | brunomagalhaes.me */
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import { pathToFileURL } from "node:url";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! Rendra Design System v2.
|
|
1
|
+
/*! Rendra Design System v2.9.0 | MIT | © 2026 Bruno Magalhaes | brunomagalhaes.me */
|
|
2
2
|
import { clsx } from "clsx";
|
|
3
3
|
import { extendTailwindMerge } from "tailwind-merge";
|
|
4
4
|
//#region src/lib/cn.ts
|
|
@@ -19,4 +19,4 @@ function cn(...inputs) {
|
|
|
19
19
|
//#endregion
|
|
20
20
|
export { cn as t };
|
|
21
21
|
|
|
22
|
-
//# sourceMappingURL=cn-
|
|
22
|
+
//# sourceMappingURL=cn-CpdCvlkP.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cn-
|
|
1
|
+
{"version":3,"file":"cn-CpdCvlkP.js","names":[],"sources":["../src/lib/cn.ts"],"sourcesContent":["import { clsx, type ClassValue } from 'clsx'\nimport { extendTailwindMerge } from 'tailwind-merge'\n\n// Ensina o tailwind-merge sobre os tokens próprios, para que text-xs e text-primary-text\n// não sejam tratados como conflito, e h-control-md substitua h-12 corretamente. text-label e\n// text-help são tamanho (rótulo e orientação do campo); text-label-foreground é cor.\nconst twMerge = extendTailwindMerge({\n extend: {\n classGroups: {\n 'font-size': [{ text: ['xs', 'sm', 'base', 'lg', 'xl', '2xl', '3xl', 'label', 'help'] }],\n },\n },\n})\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n"],"mappings":";;;;AAMA,IAAM,UAAU,oBAAoB,EAClC,QAAQ,EACN,aAAa,EACX,aAAa,CAAC,EAAE,MAAM;CAAC;CAAM;CAAM;CAAQ;CAAM;CAAM;CAAO;CAAO;CAAS;AAAM,EAAE,CAAC,EACzF,EACF,EACF,CAAC;AAED,SAAgB,GAAG,GAAG,QAAsB;CAC1C,OAAO,QAAQ,KAAK,MAAM,CAAC;AAC7B"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! Rendra Design System v2.
|
|
1
|
+
/*! Rendra Design System v2.9.0 | MIT | © 2026 Bruno Magalhaes | brunomagalhaes.me */
|
|
2
2
|
//#region src/catalog/components.ts
|
|
3
3
|
/** Formato do código: de 3 a 4 letras maiúsculas, hífen, três dígitos. */
|
|
4
4
|
var COMPONENT_CODE_PATTERN = /^[A-Z]{3,4}-\d{3}$/;
|
|
@@ -9,7 +9,10 @@ var COMPONENT_CODE_PATTERN = /^[A-Z]{3,4}-\d{3}$/;
|
|
|
9
9
|
var CATALOG_EXCLUDED_FILES = [
|
|
10
10
|
"components/ui/overlay-shell.tsx",
|
|
11
11
|
"components/ui/picker-panel.tsx",
|
|
12
|
-
"components/ui/sortable-handle.tsx"
|
|
12
|
+
"components/ui/sortable-handle.tsx",
|
|
13
|
+
"components/ui/flow-sidebar.tsx",
|
|
14
|
+
"components/ui/flow-config-panels.tsx",
|
|
15
|
+
"components/ui/flow-simulation-panel.tsx"
|
|
13
16
|
];
|
|
14
17
|
var CATALOG = [
|
|
15
18
|
{
|
|
@@ -709,7 +712,7 @@ var CATALOG = [
|
|
|
709
712
|
component: "FlowEditor",
|
|
710
713
|
file: "components/ui/flow-editor.tsx",
|
|
711
714
|
variantProps: {},
|
|
712
|
-
whenToUse: "Para montar, ligar, validar e testar um fluxo de automação (
|
|
715
|
+
whenToUse: "Para montar, ligar, validar e testar um fluxo de automação (gatilhos, mensagens, condição com várias regras, espera, webhooks e tarefa)."
|
|
713
716
|
},
|
|
714
717
|
{
|
|
715
718
|
code: "FLX-002",
|
|
@@ -830,4 +833,4 @@ function assertCatalogIntegrity() {
|
|
|
830
833
|
//#endregion
|
|
831
834
|
export { catalogByComponent as a, findComponentsWithoutDefault as c, findPresetCollisions as d, getCatalogEntry as f, assertCatalogIntegrity as i, findDuplicateCodes as l, CATALOG_EXCLUDED_FILES as n, filesMissingCatalogEntry as o, resolveCatalogCode as p, COMPONENT_CODE_PATTERN as r, findComponentsWithMultipleDefaults as s, CATALOG as t, findInvalidFormatCodes as u };
|
|
832
835
|
|
|
833
|
-
//# sourceMappingURL=components-
|
|
836
|
+
//# sourceMappingURL=components-Bus_Jh2R.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"components-Bus_Jh2R.js","names":[],"sources":["../src/catalog/components.ts"],"sourcesContent":["/**\n * Catálogo de códigos de componente (etapa 1.2.0-alpha.1 do plano da v2).\n *\n * Cada componente de `src/components/ui` (menos os internos `overlay-shell` e\n * `picker-panel`, e menos os arquivos de teste) tem ao menos um código aqui. Uma variante\n * visual relevante (a prop que muda o formato do componente, não tom nem tamanho) ganha o\n * seu próprio código, numerado 001, 002... na ordem em que aparece neste arquivo.\n *\n * O código é o que o cliente escolhe no `docs/BRIEFING_MODELO.md` (\"Componentes e\n * variantes\") e o que aparece na vitrine (`/componentes`), no `data-rendra` do elemento\n * raiz de cada componente e no `registry.json` (`meta.codes`).\n *\n * Formato: `^[A-Z]{3,4}-\\d{3}$` (ex.: \"ABA-001\", \"BTN-006\"). Nunca editar um código depois\n * de publicado: ele é o identificador estável de uma variante.\n */\n\nexport interface ComponentCatalogEntry {\n /** Formato ^[A-Z]{3,4}-\\d{3}$, ex.: \"ABA-001\". Único no catálogo inteiro. */\n code: string\n /** Nome em português do Brasil, ex.: \"Abas em linha\". */\n name: string\n /** Nome do componente React, ex.: \"Tabs\". */\n component: string\n /** Caminho relativo a partir de src/, ex.: \"components/ui/tabs.tsx\". */\n file: string\n /** Props (nome: valor) que definem esta variante especificamente. */\n variantProps: Record<string, string | number | boolean>\n /** Frase curta de quando usar esta variante, para o BRIEFING_MODELO. */\n whenToUse: string\n /**\n * Esta é a variante que o componente usa quando a prop não é passada (o valor padrão de\n * `variantProps` no próprio componente React, ex.: `variant = 'line'` em `tabs.tsx`)? No\n * máximo uma por componente (nenhuma, para o componente sem variante ou sem um padrão real,\n * como `Chart`, cuja prop `type` é obrigatória); um componente com mais de uma variante tem\n * exatamente uma marcada `true` (teste de integridade, `assertCatalogIntegrity`). Usada por\n * `rendra trocar`: um elemento sem a prop conta como esta variante, e trocar para uma\n * variante `isDefault` remove a prop em vez de escrever o valor por extenso.\n */\n isDefault?: true\n}\n\n/** Formato do código: de 3 a 4 letras maiúsculas, hífen, três dígitos. */\nexport const COMPONENT_CODE_PATTERN = /^[A-Z]{3,4}-\\d{3}$/\n\n/**\n * Arquivos de `src/components/ui` que não entram no catálogo: são peças internas, sem uso\n * direto em tela (nunca aparecem sozinhos numa tela, só dentro de outro componente).\n */\nexport const CATALOG_EXCLUDED_FILES = [\n 'components/ui/overlay-shell.tsx',\n 'components/ui/picker-panel.tsx',\n 'components/ui/sortable-handle.tsx',\n // peças internas do FlowEditor (barra lateral, configuração, teste e validação)\n 'components/ui/flow-sidebar.tsx',\n 'components/ui/flow-config-panels.tsx',\n 'components/ui/flow-simulation-panel.tsx',\n]\n\nexport const CATALOG: ComponentCatalogEntry[] = [\n // ---------------------------------------------------------------- accordion\n {\n code: 'ACRN-001',\n name: 'Acordeão',\n component: 'Accordion',\n file: 'components/ui/accordion.tsx',\n variantProps: {},\n whenToUse: 'Para agrupar conteúdo que a pessoa abre um de cada vez, como perguntas frequentes.',\n },\n // ---------------------------------------------------------------- action-bar\n {\n code: 'ACB-001',\n name: 'Barra de ação',\n component: 'ActionBar',\n file: 'components/ui/action-bar.tsx',\n variantProps: {},\n whenToUse:\n 'Para os botões de salvar, cancelar e ações extras de um formulário, drawer ou modal.',\n },\n // ---------------------------------------------------------------- alert\n {\n code: 'ALRT-001',\n name: 'Alerta',\n component: 'Alert',\n file: 'components/ui/alert.tsx',\n variantProps: {},\n whenToUse: 'Para um aviso de sucesso, erro, atenção ou informação dentro do corpo da tela.',\n },\n // ---------------------------------------------------------------- avatar\n {\n code: 'AVT-001',\n name: 'Avatar',\n component: 'Avatar',\n file: 'components/ui/avatar.tsx',\n variantProps: {},\n whenToUse: 'Para a foto ou as iniciais de uma pessoa.',\n },\n {\n code: 'AVT-002',\n name: 'Avatar em grupo',\n component: 'AvatarGroup',\n file: 'components/ui/avatar.tsx',\n variantProps: {},\n whenToUse: 'Para mostrar várias pessoas sobrepostas, com contador do excedente.',\n },\n // ---------------------------------------------------------------- badge\n {\n code: 'BDG-001',\n name: 'Selo',\n component: 'Badge',\n file: 'components/ui/badge.tsx',\n variantProps: {},\n whenToUse: 'Para marcar situação, categoria ou contagem curta ao lado de um texto.',\n },\n // ---------------------------------------------------------------- brand-feedback-icon\n {\n code: 'BFI-001',\n name: 'Ícone de feedback da marca',\n component: 'BrandFeedbackIcon',\n file: 'components/ui/brand-feedback-icon.tsx',\n variantProps: {},\n whenToUse:\n 'Para o símbolo da marca tingido pela cor semântica em toast, alerta e telas de status.',\n },\n // ---------------------------------------------------------------- brand-logo\n {\n code: 'LOGO-001',\n name: 'Logotipo',\n component: 'BrandLogo',\n file: 'components/ui/brand-logo.tsx',\n variantProps: {},\n whenToUse: 'Para o logotipo da marca na sidebar, no header ou no painel do login.',\n },\n // ---------------------------------------------------------------- breadcrumb\n {\n code: 'BRD-001',\n name: 'Trilha responsiva',\n component: 'Breadcrumb',\n file: 'components/ui/breadcrumb.tsx',\n variantProps: { variant: 'responsive' },\n whenToUse: 'Dentro do corpo da página: trilha no desktop e botão voltar no celular.',\n isDefault: true,\n },\n {\n code: 'BRD-002',\n name: 'Trilha em texto',\n component: 'Breadcrumb',\n file: 'components/ui/breadcrumb.tsx',\n variantProps: { variant: 'trail' },\n whenToUse: 'No header do AppShell, abaixo do título, sempre em texto pequeno.',\n },\n // ---------------------------------------------------------------- button\n {\n code: 'BTN-001',\n name: 'Botão primário',\n component: 'Button',\n file: 'components/ui/button.tsx',\n variantProps: { variant: 'primary' },\n whenToUse: 'Para a ação principal da tela, do formulário ou da barra de ações.',\n isDefault: true,\n },\n {\n code: 'BTN-002',\n name: 'Botão secundário',\n component: 'Button',\n file: 'components/ui/button.tsx',\n variantProps: { variant: 'secondary' },\n whenToUse:\n 'Para uma segunda cor de destaque da marca, quando a primária já está em uso na tela.',\n },\n {\n code: 'BTN-003',\n name: 'Botão contornado',\n component: 'Button',\n file: 'components/ui/button.tsx',\n variantProps: { variant: 'outline' },\n whenToUse: 'Para a ação de cancelar ou para ações secundárias ao lado de um botão primário.',\n },\n {\n code: 'BTN-004',\n name: 'Botão fantasma',\n component: 'Button',\n file: 'components/ui/button.tsx',\n variantProps: { variant: 'ghost' },\n whenToUse: 'Para ações discretas dentro de cards, linhas de tabela e barras de ferramenta.',\n },\n {\n code: 'BTN-005',\n name: 'Botão destrutivo',\n component: 'Button',\n file: 'components/ui/button.tsx',\n variantProps: { variant: 'destructive' },\n whenToUse: 'Para uma ação irreversível, como excluir ou encerrar.',\n },\n {\n code: 'BTN-006',\n name: 'Botão link',\n component: 'Button',\n file: 'components/ui/button.tsx',\n variantProps: { variant: 'link' },\n whenToUse: 'Para uma ação com aparência de link de texto, dentro de uma frase ou de um rodapé.',\n },\n // ---------------------------------------------------------------- button-group\n {\n code: 'BTNG-001',\n name: 'Grupo de botões',\n component: 'ButtonGroup',\n file: 'components/ui/button-group.tsx',\n variantProps: { orientation: 'horizontal' },\n whenToUse: 'Para botões encostados ou um controle segmentado de escolha única.',\n isDefault: true,\n },\n {\n code: 'BTNG-002',\n name: 'Grupo de botões vertical',\n component: 'ButtonGroup',\n file: 'components/ui/button-group.tsx',\n variantProps: { orientation: 'vertical' },\n whenToUse: 'Para botões de ação empilhados, na largura do grupo, com as bordas unidas.',\n },\n {\n code: 'BTNG-003',\n name: 'Grupo de botões responsivo',\n component: 'ButtonGroup',\n file: 'components/ui/button-group.tsx',\n variantProps: { orientation: 'responsive' },\n whenToUse: 'Para botões que empilham no celular e ficam lado a lado a partir do tablet.',\n },\n // ---------------------------------------------------------------- calendar\n {\n code: 'CAL-001',\n name: 'Calendário',\n component: 'Calendar',\n file: 'components/ui/calendar.tsx',\n variantProps: {},\n whenToUse: 'Para agenda com visão de mês, semana, dia ou lista de eventos.',\n },\n // ---------------------------------------------------------------- card\n {\n code: 'CARD-001',\n name: 'Card',\n component: 'Card',\n file: 'components/ui/card.tsx',\n variantProps: {},\n whenToUse: 'Para agrupar conteúdo de página com borda e sem sombra pesada.',\n },\n // ---------------------------------------------------------------- chart\n {\n code: 'CHT-001',\n name: 'Gráfico de linha',\n component: 'Chart',\n file: 'components/ui/chart.tsx',\n variantProps: { type: 'line' },\n whenToUse: 'Para mostrar a evolução de um valor ao longo do tempo.',\n // A prop `type` do Chart é obrigatória (sem valor padrão no componente): marcado aqui só\n // para satisfazer o teste de integridade (um padrão por componente com mais de uma\n // variante); \"rendra trocar\" nunca encontra um <Chart> sem `type`, porque não compila.\n isDefault: true,\n },\n {\n code: 'CHT-002',\n name: 'Gráfico de barras',\n component: 'Chart',\n file: 'components/ui/chart.tsx',\n variantProps: { type: 'bar' },\n whenToUse: 'Para comparar valores entre categorias.',\n },\n {\n code: 'CHT-003',\n name: 'Gráfico de área',\n component: 'Chart',\n file: 'components/ui/chart.tsx',\n variantProps: { type: 'area' },\n whenToUse: 'Para mostrar volume acumulado ao longo do tempo.',\n },\n {\n code: 'CHT-004',\n name: 'Gráfico de pizza',\n component: 'Chart',\n file: 'components/ui/chart.tsx',\n variantProps: { type: 'pie' },\n whenToUse: 'Para mostrar a proporção de poucas categorias dentro de um total.',\n },\n {\n code: 'CHT-005',\n name: 'Gráfico combinado',\n component: 'Chart',\n file: 'components/ui/chart.tsx',\n variantProps: { type: 'combo' },\n whenToUse: 'Para juntar barras e linha no mesmo gráfico, como receita e meta.',\n },\n {\n code: 'CHT-006',\n name: 'Velocímetro de meta',\n component: 'Chart',\n file: 'components/ui/chart.tsx',\n variantProps: { type: 'gauge' },\n whenToUse: 'Para o percentual de uma meta batida, com faixas de cor.',\n },\n {\n code: 'CHT-007',\n name: 'Funil',\n component: 'Chart',\n file: 'components/ui/chart.tsx',\n variantProps: { type: 'funnel' },\n whenToUse: 'Para etapas que afunilam, com a conversão entre elas.',\n },\n // ---------------------------------------------------------------- chat\n {\n code: 'CHAT-001',\n name: 'Lista de conversas',\n component: 'ConversationList',\n file: 'components/ui/chat.tsx',\n variantProps: {},\n whenToUse: 'Para a coluna de conversas do atendimento.',\n },\n {\n code: 'CHAT-002',\n name: 'Linha do tempo da conversa',\n component: 'ChatThread',\n file: 'components/ui/chat.tsx',\n variantProps: {},\n whenToUse: 'Para o histórico de mensagens de uma conversa aberta.',\n },\n {\n code: 'CHAT-003',\n name: 'Campo de mensagem',\n component: 'ChatComposer',\n file: 'components/ui/chat.tsx',\n variantProps: {},\n whenToUse: 'Para escrever, anexar e enviar uma mensagem no atendimento.',\n },\n // ---------------------------------------------------------------- checkbox\n {\n code: 'CHK-001',\n name: 'Caixa de seleção',\n component: 'Checkbox',\n file: 'components/ui/checkbox.tsx',\n variantProps: {},\n whenToUse: 'Para uma escolha independente, ligada ou desligada (inclusive indeterminada).',\n },\n {\n code: 'CHK-002',\n name: 'Grupo de caixas de seleção',\n component: 'CheckboxGroup',\n file: 'components/ui/checkbox.tsx',\n variantProps: {},\n whenToUse: 'Para uma lista de opções fixas com \"selecionar todos\".',\n },\n // ---------------------------------------------------------------- checklist\n {\n code: 'CKLT-001',\n name: 'Lista de verificação',\n component: 'Checklist',\n file: 'components/ui/checklist.tsx',\n variantProps: {},\n whenToUse:\n 'Para uma lista de itens que a pessoa cria, renomeia, marca e remove, tudo por teclado.',\n },\n // ---------------------------------------------------------------- color-picker\n {\n code: 'COR-001',\n name: 'Seletor de cor',\n component: 'ColorPicker',\n file: 'components/ui/color-picker.tsx',\n variantProps: {},\n whenToUse: 'Para escolher uma cor entre amostras da marca ou uma cor livre por hexadecimal.',\n },\n // ---------------------------------------------------------------- data-toolbar\n {\n code: 'DTB-001',\n name: 'Barra de ferramentas da listagem',\n component: 'DataToolbar',\n file: 'components/ui/data-toolbar.tsx',\n variantProps: {},\n whenToUse: 'Para busca, filtros, colunas e a ação Novo, sempre dentro do card da tabela.',\n },\n // ---------------------------------------------------------------- date-picker\n {\n code: 'DTP-001',\n name: 'Seletor de data',\n component: 'DatePicker',\n file: 'components/ui/date-picker.tsx',\n variantProps: {},\n whenToUse: 'Para escolher uma data, um período ou um horário.',\n },\n // ---------------------------------------------------------------- document-viewer\n {\n code: 'DOC-001',\n name: 'Visualizador de documentos',\n component: 'DocumentViewer',\n file: 'components/ui/document-viewer.tsx',\n variantProps: {},\n whenToUse: 'Para abrir um PDF (contrato, nota fiscal, comprovante) sem sair da tela.',\n },\n // ---------------------------------------------------------------- drawer\n {\n code: 'GAV-001',\n name: 'Gaveta',\n component: 'Drawer',\n file: 'components/ui/drawer.tsx',\n variantProps: {},\n whenToUse: 'Para formulário ou detalhe de volume médio, até cerca de 12 campos.',\n },\n // ---------------------------------------------------------------- dropdown-menu\n {\n code: 'DDM-001',\n name: 'Menu suspenso',\n component: 'DropdownMenuContent',\n file: 'components/ui/dropdown-menu.tsx',\n variantProps: {},\n whenToUse: 'Para uma lista de ações ou opções que abre a partir de um botão ou de um item.',\n },\n // ---------------------------------------------------------------- empty-state\n {\n code: 'VAZ-001',\n name: 'Estado vazio',\n component: 'EmptyState',\n file: 'components/ui/empty-state.tsx',\n variantProps: {},\n whenToUse: 'Para quando uma lista, busca ou seção não tem nenhum dado ainda.',\n },\n // ---------------------------------------------------------------- error-page\n {\n code: 'ERRO-001',\n name: 'Tela de erro',\n component: 'ErrorPage',\n file: 'components/ui/error-page.tsx',\n variantProps: {},\n whenToUse: 'Para página não encontrada (404) ou falha do lado do servidor (500).',\n },\n // ---------------------------------------------------------------- field\n {\n code: 'FLD-001',\n name: 'Campo com rótulo e ajuda',\n component: 'Field',\n file: 'components/ui/field.tsx',\n variantProps: {},\n whenToUse: 'Para envolver qualquer controle de formulário com rótulo, ajuda e erro.',\n },\n {\n code: 'FLD-002',\n name: 'Rótulo',\n component: 'Label',\n file: 'components/ui/field.tsx',\n variantProps: {},\n whenToUse: 'Para um rótulo avulso, quando o Field completo não se aplica.',\n },\n // ---------------------------------------------------------------- form\n {\n code: 'FORM-001',\n name: 'Formulário',\n component: 'Form',\n file: 'components/ui/form.tsx',\n variantProps: {},\n whenToUse: 'Para envolver um formulário inteiro, ligado ao React Hook Form.',\n },\n {\n code: 'FORM-002',\n name: 'Seção de formulário',\n component: 'FormSection',\n file: 'components/ui/form.tsx',\n variantProps: {},\n whenToUse: 'Para agrupar campos relacionados dentro de um card com título.',\n },\n // ---------------------------------------------------------------- image-cropper\n {\n code: 'CROP-001',\n name: 'Recorte de imagem',\n component: 'ImageCropper',\n file: 'components/ui/image-cropper.tsx',\n variantProps: {},\n whenToUse:\n 'Para recortar uma imagem numa proporção fixa antes de enviar (foto de perfil, capa).',\n },\n // ---------------------------------------------------------------- image-viewer\n {\n code: 'IMG-001',\n name: 'Visualizador de imagens',\n component: 'ImageViewer',\n file: 'components/ui/image-viewer.tsx',\n variantProps: {},\n whenToUse: 'Para abrir uma ou mais imagens em tela cheia, com legenda e navegação.',\n },\n // ---------------------------------------------------------------- info-hint\n {\n code: 'INFO-001',\n name: 'Dica de informação',\n component: 'InfoHint',\n file: 'components/ui/info-hint.tsx',\n variantProps: {},\n whenToUse: 'Para texto orientativo que não tem um título de tela, card ou seção ao lado.',\n },\n // ---------------------------------------------------------------- input\n {\n code: 'CAMP-001',\n name: 'Campo de texto',\n component: 'Input',\n file: 'components/ui/input.tsx',\n variantProps: {},\n whenToUse: 'Para texto, número, senha, telefone, moeda ou qualquer valor de uma linha.',\n },\n // ---------------------------------------------------------------- kanban\n {\n code: 'KANB-001',\n name: 'Quadro kanban',\n component: 'Kanban',\n file: 'components/ui/kanban.tsx',\n // variantProps fica vazio de propósito: a diferença para KANB-002 é a prop `dropTargets`\n // (um array de destinos de arraste, cada um com `confirm` também não literal), não um\n // literal de string/número/booleano, e o `rendra trocar` não tem como inventar um array,\n // então ele recusa a troca com uma mensagem clara (\"sem prop que os distinga\"), e a\n // variante certa fica documentada aqui.\n variantProps: {},\n whenToUse:\n 'Para um funil de etapas com cartões que se movem entre colunas, com status por cor ' +\n '(cadência da etapa e próxima atividade), valores empilhados no card e, com `toolbar`, ' +\n 'barra do quadro com busca, filtros, totais e Customizar.',\n isDefault: true,\n },\n {\n code: 'KANB-002',\n name: 'Quadro kanban com destinos de arraste',\n component: 'Kanban',\n file: 'components/ui/kanban.tsx',\n variantProps: { hasDropTargets: true },\n whenToUse:\n 'Quando o card pode ir para uma ação além de outra coluna (ex.: Lixeira, Congelar, Perder, ' +\n 'Ganhar), mostrada num rodapé flutuante durante o arraste e no menu \"Mover para\", com ' +\n 'confirmação opcional por destino (e motivo, ao perder).',\n },\n // ---------------------------------------------------------------- list\n {\n code: 'LIST-001',\n name: 'Lista',\n component: 'List',\n file: 'components/ui/list.tsx',\n // variantProps fica vazio de propósito: a diferença para LIST-002 é a prop `onReorder`\n // (uma função de callback), não um literal de string/número/booleano, e o `rendra trocar`\n // não tem como inventar uma função, então ele recusa a troca com uma mensagem clara (\"sem\n // prop que os distinga\"), e a variante certa fica documentada aqui.\n variantProps: {},\n whenToUse: 'Para linhas simples com início, título, descrição e fim, navegáveis ou não.',\n isDefault: true,\n },\n {\n code: 'LIST-002',\n name: 'Lista reordenável',\n component: 'List',\n file: 'components/ui/list.tsx',\n variantProps: { sortable: true },\n whenToUse: 'Quando a pessoa pode mudar a ordem das linhas, por arraste ou pelas setas da alça.',\n },\n // ---------------------------------------------------------------- modal\n {\n code: 'MOD-001',\n name: 'Modal de confirmação',\n component: 'Modal',\n file: 'components/ui/modal.tsx',\n variantProps: { type: 'confirm' },\n whenToUse:\n 'Para confirmar uma ação com uma principal e uma de cancelar; type=\"destructive\" usa o ' +\n 'mesmo código, porque só muda a cor.',\n isDefault: true,\n },\n {\n code: 'MOD-002',\n name: 'Modal de formulário',\n component: 'Modal',\n file: 'components/ui/modal.tsx',\n variantProps: { type: 'form' },\n whenToUse: 'Para um formulário de até 3 campos simples, sem sair da tela atual.',\n },\n {\n code: 'MOD-003',\n name: 'Modal informativo',\n component: 'Modal',\n file: 'components/ui/modal.tsx',\n variantProps: { type: 'info' },\n whenToUse:\n 'Para só informar algo, sem decisão a tomar: um botão só, de largura total, que fecha o modal.',\n },\n // ---------------------------------------------------------------- otp-input\n {\n code: 'OTP-001',\n name: 'Código de verificação',\n component: 'OtpInput',\n file: 'components/ui/otp-input.tsx',\n variantProps: {},\n whenToUse: 'Para confirmar um código enviado por SMS ou e-mail (2FA).',\n },\n // ---------------------------------------------------------------- pagination\n {\n code: 'PAG-001',\n name: 'Paginação',\n component: 'Pagination',\n file: 'components/ui/pagination.tsx',\n variantProps: {},\n whenToUse: 'Para navegar entre páginas de uma listagem.',\n },\n // ---------------------------------------------------------------- popover\n {\n code: 'POP-001',\n name: 'Popover',\n component: 'PopoverContent',\n file: 'components/ui/popover.tsx',\n variantProps: {},\n whenToUse: 'Para um painel curto que abre perto de um botão, como um filtro.',\n },\n // ---------------------------------------------------------------- progress\n {\n code: 'PROG-001',\n name: 'Barra de progresso',\n component: 'Progress',\n file: 'components/ui/progress.tsx',\n variantProps: {},\n whenToUse: 'Para o andamento de uma tarefa ou de um envio.',\n },\n // ---------------------------------------------------------------- qr-code\n {\n code: 'QRC-001',\n name: 'Código QR',\n component: 'QrCode',\n file: 'components/ui/qr-code.tsx',\n variantProps: {},\n whenToUse: 'Para gerar um código QR (link, código de acesso) sem depender de serviço externo.',\n },\n // ---------------------------------------------------------------- radio-group\n {\n code: 'RDO-001',\n name: 'Opções em lista',\n component: 'RadioGroup',\n file: 'components/ui/radio-group.tsx',\n variantProps: { variant: 'list' },\n whenToUse: 'Para poucas opções simples, uma escolha só, em lista com bolinha e texto.',\n isDefault: true,\n },\n {\n code: 'RDO-002',\n name: 'Opções em cartões',\n component: 'RadioGroup',\n file: 'components/ui/radio-group.tsx',\n variantProps: { variant: 'cards' },\n whenToUse: 'Para opções com ícone e descrição, quando cada uma merece mais destaque.',\n },\n // ---------------------------------------------------------------- rating\n {\n code: 'RTG-001',\n name: 'Avaliação em estrelas',\n component: 'Rating',\n file: 'components/ui/rating.tsx',\n variantProps: { variant: 'stars' },\n whenToUse: 'Para uma nota rápida de satisfação, em estrelas.',\n isDefault: true,\n },\n {\n code: 'RTG-002',\n name: 'Avaliação em escala',\n component: 'Rating',\n file: 'components/ui/rating.tsx',\n variantProps: { variant: 'scale' },\n whenToUse: 'Para uma nota de 0 a 10 (NPS e pesquisas parecidas), com rótulo nas pontas.',\n },\n // ---------------------------------------------------------------- rendra-credit\n {\n code: 'CRED-001',\n name: 'Crédito Feito com Rendra',\n component: 'RendraCredit',\n file: 'components/ui/rendra-credit.tsx',\n variantProps: {},\n whenToUse:\n 'No rodapé da tela de login, discreto; pode ser removido (credit={false}) ou levado para ' +\n 'outro lugar visível, como uma tela Sobre.',\n },\n // ---------------------------------------------------------------- repeatable-field\n {\n code: 'REP-001',\n name: 'Campo repetível',\n component: 'RepeatableField',\n file: 'components/ui/repeatable-field.tsx',\n variantProps: {},\n whenToUse:\n 'Para uma lista de campos do mesmo tipo (telefones, e-mails, endereços), com um principal.',\n },\n // ---------------------------------------------------------------- rich-text-editor\n {\n code: 'RTE-001',\n name: 'Editor de texto rico',\n component: 'RichTextEditor',\n file: 'components/ui/rich-text-editor.tsx',\n variantProps: {},\n whenToUse: 'Para conteúdo com formatação, listas e imagens, como a descrição de um artigo.',\n },\n // ---------------------------------------------------------------- select\n {\n code: 'SEL-001',\n name: 'Select',\n component: 'Select',\n file: 'components/ui/select.tsx',\n variantProps: {},\n whenToUse: 'Para escolher uma ou mais opções de uma lista, com ou sem busca.',\n },\n // ---------------------------------------------------------------- separator\n {\n code: 'SEP-001',\n name: 'Separador',\n component: 'Separator',\n file: 'components/ui/separator.tsx',\n variantProps: {},\n whenToUse: 'Para dividir conteúdo dentro de um card, no lugar de um card dentro de card.',\n },\n // ---------------------------------------------------------------- skeleton\n {\n code: 'SKEL-001',\n name: 'Esqueleto de carregamento',\n component: 'Skeleton',\n file: 'components/ui/skeleton.tsx',\n variantProps: {},\n whenToUse: 'Para o estado de carregamento, com a mesma estrutura do conteúdo final.',\n },\n // ---------------------------------------------------------------- slider\n {\n code: 'SLD-001',\n name: 'Slider',\n component: 'Slider',\n file: 'components/ui/slider.tsx',\n variantProps: {},\n whenToUse: 'Para escolher um número ou uma faixa dentro de um intervalo, arrastando.',\n },\n // ---------------------------------------------------------------- spinner\n {\n code: 'SPIN-001',\n name: 'Indicador de carregamento',\n component: 'Spinner',\n file: 'components/ui/spinner.tsx',\n variantProps: {},\n whenToUse:\n 'Para um carregamento breve dentro de um botão, campo ou lista, sem barra de progresso.',\n },\n // ---------------------------------------------------------------- stat-card\n {\n code: 'STAT-001',\n name: 'Card de indicador',\n component: 'StatCard',\n file: 'components/ui/stat-card.tsx',\n variantProps: {},\n whenToUse: 'Para um número de destaque com variação, num painel ou dashboard.',\n },\n // ---------------------------------------------------------------- switch\n {\n code: 'SWT-001',\n name: 'Switch',\n component: 'Switch',\n file: 'components/ui/switch.tsx',\n variantProps: {},\n whenToUse: 'Para ligar ou desligar uma opção com efeito imediato.',\n },\n // ---------------------------------------------------------------- table\n {\n code: 'TAB-001',\n name: 'Tabela',\n component: 'Table',\n file: 'components/ui/table.tsx',\n variantProps: {},\n whenToUse: 'Para qualquer listagem de registros, com busca, filtros e paginação.',\n },\n // ---------------------------------------------------------------- tabs\n {\n code: 'ABA-001',\n name: 'Abas em linha',\n component: 'Tabs',\n file: 'components/ui/tabs.tsx',\n variantProps: { variant: 'line' },\n whenToUse: 'Padrão para dividir o conteúdo de uma tela em seções, com sublinhado na aba ativa.',\n isDefault: true,\n },\n {\n code: 'ABA-002',\n name: 'Abas em pílula',\n component: 'Tabs',\n file: 'components/ui/tabs.tsx',\n variantProps: { variant: 'pill' },\n whenToUse: 'Quando as abas precisam de mais destaque visual, como pílulas sobre fundo suave.',\n },\n // ---------------------------------------------------------------- textarea\n {\n code: 'TXT-001',\n name: 'Área de texto',\n component: 'Textarea',\n file: 'components/ui/textarea.tsx',\n variantProps: {},\n whenToUse: 'Para texto longo, com contador de caracteres opcional.',\n },\n // ---------------------------------------------------------------- timeline\n {\n code: 'TLN-001',\n name: 'Linha do tempo',\n component: 'Timeline',\n file: 'components/ui/timeline.tsx',\n variantProps: {},\n whenToUse: 'Para uma sequência de eventos em ordem, cada um com um tom semântico.',\n },\n // ---------------------------------------------------------------- toast\n {\n code: 'TST-001',\n name: 'Toast',\n component: 'toast',\n file: 'components/ui/toast.tsx',\n variantProps: {},\n whenToUse: 'Para uma confirmação rápida depois de uma ação, sem interromper a tela.',\n },\n // ---------------------------------------------------------------- tooltip\n {\n code: 'TIP-001',\n name: 'Tooltip',\n component: 'Tooltip',\n file: 'components/ui/tooltip.tsx',\n variantProps: {},\n whenToUse: 'Para informação complementar, nunca essencial, que aparece ao passar o mouse.',\n },\n // ---------------------------------------------------------------- upload\n {\n code: 'UPL-001',\n name: 'Upload',\n component: 'Upload',\n file: 'components/ui/upload.tsx',\n // A prop que distingue de UPL-002 é `layout` ('list' | 'gallery', padrão 'list'): declarar\n // o valor padrão aqui (em vez de {}) é o que permite ao `rendra trocar` inserir\n // layout=\"gallery\" num elemento sem a prop, ao trocar para UPL-002.\n variantProps: { layout: 'list' },\n whenToUse: 'Para arrastar e soltar ou escolher arquivos, com lista e progresso por arquivo.',\n isDefault: true,\n },\n {\n code: 'UPL-002',\n name: 'Upload em galeria',\n component: 'Upload',\n file: 'components/ui/upload.tsx',\n variantProps: { layout: 'gallery' },\n whenToUse: 'Para upload de fotos e vídeos, com miniatura em vez de linha de lista.',\n },\n // ---------------------------------------------------------------- flow\n {\n code: 'FLX-001',\n name: 'Editor de fluxo',\n component: 'FlowEditor',\n file: 'components/ui/flow-editor.tsx',\n variantProps: {},\n whenToUse:\n 'Para montar, ligar, validar e testar um fluxo de automação (gatilhos, mensagens, condição com várias regras, espera, webhooks e tarefa).',\n },\n {\n code: 'FLX-002',\n name: 'Visualizador de fluxo',\n component: 'FlowViewer',\n file: 'components/ui/flow-viewer.tsx',\n variantProps: {},\n whenToUse: 'Para mostrar um fluxo de automação só para ler, sem editar.',\n },\n // ---------------------------------------------------------------- widget-grid\n {\n code: 'WDG-001',\n name: 'Grade de widgets',\n component: 'WidgetGrid',\n file: 'components/ui/widget-grid.tsx',\n variantProps: {},\n whenToUse: 'Para um painel com blocos que a pessoa pode arrastar e redimensionar.',\n },\n // ---------------------------------------------------------------- wizard\n {\n code: 'WIZ-001',\n name: 'Wizard',\n component: 'Wizard',\n file: 'components/ui/wizard.tsx',\n variantProps: {},\n whenToUse: 'Para um cadastro longo dividido em etapas, com validação por etapa.',\n },\n {\n code: 'WIZ-002',\n name: 'Indicador de etapas',\n component: 'Stepper',\n file: 'components/ui/wizard.tsx',\n variantProps: {},\n whenToUse: 'Para mostrar o progresso em etapas por conta própria, sem o Wizard inteiro.',\n },\n]\n\n/** Um código específico do catálogo (ex.: para montar a vitrine ou o registry). */\nexport function getCatalogEntry(code: string): ComponentCatalogEntry | undefined {\n return CATALOG.find((entry) => entry.code === code)\n}\n\n/** Todos os códigos de um componente (ex.: as duas variantes do Tabs), na ordem cadastrada. */\nexport function catalogByComponent(component: string): ComponentCatalogEntry[] {\n return CATALOG.filter((entry) => entry.component === component)\n}\n\n/**\n * Resolve o código de catálogo de um componente a partir das props que definem a variante.\n * Sem variante (um código só, ou nenhuma prop bate), devolve o primeiro código cadastrado\n * para o componente. Usado pelos próprios componentes para calcular o `data-rendra`, sem\n * duplicar a tabela de variantes.\n */\nexport function resolveCatalogCode(component: string, props: Record<string, unknown> = {}): string {\n const entries = catalogByComponent(component)\n if (entries.length === 0) {\n throw new Error(`Catálogo: nenhum código cadastrado para o componente \"${component}\".`)\n }\n const match = entries.find(\n (entry) =>\n Object.keys(entry.variantProps).length > 0 &&\n Object.entries(entry.variantProps).every(([key, value]) => props[key] === value),\n )\n // entries.length > 0 já foi conferido acima: entries[0] sempre existe aqui.\n return (match ?? entries[0]!).code\n}\n\n/*\n * Regras de integridade (usadas pelo teste em components.test.ts e por assertCatalogIntegrity).\n * São funções puras, sem acesso a arquivo: recebem a lista de entradas e devolvem o que\n * está errado, para o teste poder provar a regra com uma lista fabricada, não só com o\n * catálogo real.\n */\n\n/** Código que aparece mais de uma vez na lista. */\nexport function findDuplicateCodes(entries: ComponentCatalogEntry[]): string[] {\n const seen = new Set<string>()\n const duplicates = new Set<string>()\n for (const entry of entries) {\n if (seen.has(entry.code)) duplicates.add(entry.code)\n seen.add(entry.code)\n }\n return [...duplicates]\n}\n\n/** Código fora do formato ^[A-Z]{3,4}-\\d{3}$. */\nexport function findInvalidFormatCodes(entries: ComponentCatalogEntry[]): string[] {\n return entries\n .filter((entry) => !COMPONENT_CODE_PATTERN.test(entry.code))\n .map((entry) => entry.code)\n}\n\n/**\n * Código que colidiria com um código de modelo (T1, C4, M5...) de src/config/presets.ts,\n * cujo padrão é /[TCM]\\d+/ (uma letra T, C ou M seguida direto de dígitos, sem hífen).\n */\nexport function findPresetCollisions(entries: ComponentCatalogEntry[]): string[] {\n return entries.filter((entry) => /[TCM]\\d+/.test(entry.code)).map((entry) => entry.code)\n}\n\n/** Arquivo (caminho relativo a src/) que não tem nenhuma entrada no catálogo. */\nexport function filesMissingCatalogEntry(\n files: string[],\n entries: ComponentCatalogEntry[],\n): string[] {\n const covered = new Set(entries.map((entry) => entry.file))\n return files.filter((file) => !covered.has(file))\n}\n\n/** Componente (nome) com mais de uma variante no catálogo, agrupadas na ordem cadastrada. */\nfunction groupByComponentWithMultipleVariants(\n entries: ComponentCatalogEntry[],\n): Map<string, ComponentCatalogEntry[]> {\n const byComponent = new Map<string, ComponentCatalogEntry[]>()\n for (const entry of entries) {\n const list = byComponent.get(entry.component) ?? []\n list.push(entry)\n byComponent.set(entry.component, list)\n }\n for (const [component, list] of byComponent) if (list.length <= 1) byComponent.delete(component)\n return byComponent\n}\n\n/**\n * Componente com mais de uma variante que não tem nenhuma marcada `isDefault` (fase 3, Lote\n * B: `rendra trocar` precisa saber qual variante um elemento sem a prop representa).\n */\nexport function findComponentsWithoutDefault(entries: ComponentCatalogEntry[]): string[] {\n const groups = groupByComponentWithMultipleVariants(entries)\n return [...groups]\n .filter(([, list]) => !list.some((entry) => entry.isDefault))\n .map(([component]) => component)\n}\n\n/** Componente com mais de uma variante marcada `isDefault` ao mesmo tempo (só pode uma). */\nexport function findComponentsWithMultipleDefaults(entries: ComponentCatalogEntry[]): string[] {\n const groups = groupByComponentWithMultipleVariants(entries)\n return [...groups]\n .filter(([, list]) => list.filter((entry) => entry.isDefault).length > 1)\n .map(([component]) => component)\n}\n\n/**\n * Lança se houver código duplicado, fora do formato, colidindo com um código de modelo, ou\n * componente com mais de uma variante sem exatamente uma marcada `isDefault`.\n */\nexport function assertCatalogIntegrity(): void {\n const duplicates = findDuplicateCodes(CATALOG)\n if (duplicates.length > 0) {\n throw new Error(`Catálogo: código duplicado: ${duplicates.join(', ')}.`)\n }\n const invalid = findInvalidFormatCodes(CATALOG)\n if (invalid.length > 0) {\n throw new Error(`Catálogo: código fora do formato ^[A-Z]{3,4}-\\\\d{3}$: ${invalid.join(', ')}.`)\n }\n const collisions = findPresetCollisions(CATALOG)\n if (collisions.length > 0) {\n throw new Error(\n `Catálogo: código colide com um código de modelo (T/C/M): ${collisions.join(', ')}.`,\n )\n }\n const semPadrao = findComponentsWithoutDefault(CATALOG)\n if (semPadrao.length > 0) {\n throw new Error(\n `Catálogo: componente com mais de uma variante sem nenhuma marcada isDefault: ${semPadrao.join(', ')}.`,\n )\n }\n const padraoDuplicado = findComponentsWithMultipleDefaults(CATALOG)\n if (padraoDuplicado.length > 0) {\n throw new Error(\n `Catálogo: componente com mais de uma variante marcada isDefault: ${padraoDuplicado.join(', ')}.`,\n )\n }\n}\n"],"mappings":"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Ac,EAAE,MAAM,SAAS;EAC/B,WAAW;CACb;CAEA;EACE,MAAM;EACN,MAAM;EACN,WAAW;EACX,MAAM;EACN,cAAc,CAAC;EACf,WAAW;CACb;CACA;EACE,MAAM;EACN,MAAM;EACN,WAAW;EACX,MAAM;EACN,cAAc,CAAC;EACf,WAAW;CACb;CACA;EACE,MAAM;EACN,MAAM;EACN,WAAW;EACX,MAAM;EACN,cAAc,CAAC;EACf,WAAW;CACb;CAEA;EACE,MAAM;EACN,MAAM;EACN,WAAW;EACX,MAAM;EACN,cAAc,CAAC;EACf,WAAW;CACb;CACA;EACE,MAAM;EACN,MAAM;EACN,WAAW;EACX,MAAM;EACN,cAAc,CAAC;EACf,WAAW;CACb;CAEA;EACE,MAAM;EACN,MAAM;EACN,WAAW;EACX,MAAM;EACN,cAAc,CAAC;EACf,WACE;CACJ;CAEA;EACE,MAAM;EACN,MAAM;EACN,WAAW;EACX,MAAM;EACN,cAAc,CAAC;EACf,WAAW;CACb;CAEA;EACE,MAAM;EACN,MAAM;EACN,WAAW;EACX,MAAM;EACN,cAAc,CAAC;EACf,WAAW;CACb;CAEA;EACE,MAAM;EACN,MAAM;EACN,WAAW;EACX,MAAM;EACN,cAAc,CAAC;EACf,WAAW;CACb;CAEA;EACE,MAAM;EACN,MAAM;EACN,WAAW;EACX,MAAM;EACN,cAAc,CAAC;EACf,WAAW;CACb;CAEA;EACE,MAAM;EACN,MAAM;EACN,WAAW;EACX,MAAM;EACN,cAAc,CAAC;EACf,WAAW;CACb;CAEA;EACE,MAAM;EACN,MAAM;EACN,WAAW;EACX,MAAM;EACN,cAAc,CAAC;EACf,WAAW;CACb;CAEA;EACE,MAAM;EACN,MAAM;EACN,WAAW;EACX,MAAM;EACN,cAAc,CAAC;EACf,WAAW;CACb;CAEA;EACE,MAAM;EACN,MAAM;EACN,WAAW;EACX,MAAM;EACN,cAAc,CAAC;EACf,WAAW;CACb;CAEA;EACE,MAAM;EACN,MAAM;EACN,WAAW;EACX,MAAM;EACN,cAAc,CAAC;EACf,WAAW;CACb;CACA;EACE,MAAM;EACN,MAAM;EACN,WAAW;EACX,M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"}
|
package/dist/components.css
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! Rendra Design System v2.
|
|
1
|
+
/*! Rendra Design System v2.9.0 | MIT | © 2026 Bruno Magalhaes | brunomagalhaes.me */
|
|
2
2
|
|
|
3
3
|
@layer properties {
|
|
4
4
|
@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or
|
|
@@ -209,6 +209,9 @@
|
|
|
209
209
|
.top-8 {
|
|
210
210
|
top: 2rem;
|
|
211
211
|
}
|
|
212
|
+
.top-16 {
|
|
213
|
+
top: 4rem;
|
|
214
|
+
}
|
|
212
215
|
.top-full {
|
|
213
216
|
top: 100%;
|
|
214
217
|
}
|
|
@@ -224,9 +227,6 @@
|
|
|
224
227
|
.right-2 {
|
|
225
228
|
right: 0.5rem;
|
|
226
229
|
}
|
|
227
|
-
.right-4 {
|
|
228
|
-
right: 1rem;
|
|
229
|
-
}
|
|
230
230
|
.right-8 {
|
|
231
231
|
right: 2rem;
|
|
232
232
|
}
|
|
@@ -236,9 +236,6 @@
|
|
|
236
236
|
.bottom-0 {
|
|
237
237
|
bottom: 0px;
|
|
238
238
|
}
|
|
239
|
-
.bottom-3 {
|
|
240
|
-
bottom: 0.75rem;
|
|
241
|
-
}
|
|
242
239
|
.bottom-4 {
|
|
243
240
|
bottom: 1rem;
|
|
244
241
|
}
|
|
@@ -314,6 +311,9 @@
|
|
|
314
311
|
.m-0 {
|
|
315
312
|
margin: 0px;
|
|
316
313
|
}
|
|
314
|
+
.m-3 {
|
|
315
|
+
margin: 0.75rem;
|
|
316
|
+
}
|
|
317
317
|
.m-auto {
|
|
318
318
|
margin: auto;
|
|
319
319
|
}
|
|
@@ -347,9 +347,15 @@
|
|
|
347
347
|
.-mt-2 {
|
|
348
348
|
margin-top: calc(0.5rem * -1);
|
|
349
349
|
}
|
|
350
|
+
.-mt-3 {
|
|
351
|
+
margin-top: calc(0.75rem * -1);
|
|
352
|
+
}
|
|
350
353
|
.-mt-6 {
|
|
351
354
|
margin-top: calc(1.5rem * -1);
|
|
352
355
|
}
|
|
356
|
+
.mt-0 {
|
|
357
|
+
margin-top: 0px;
|
|
358
|
+
}
|
|
353
359
|
.mt-1 {
|
|
354
360
|
margin-top: 0.25rem;
|
|
355
361
|
}
|
|
@@ -369,6 +375,9 @@
|
|
|
369
375
|
.-mr-2 {
|
|
370
376
|
margin-right: calc(0.5rem * -1);
|
|
371
377
|
}
|
|
378
|
+
.-mr-3 {
|
|
379
|
+
margin-right: calc(0.75rem * -1);
|
|
380
|
+
}
|
|
372
381
|
.mr-0 {
|
|
373
382
|
margin-right: 0px;
|
|
374
383
|
}
|
|
@@ -388,6 +397,9 @@
|
|
|
388
397
|
.mb-1 {
|
|
389
398
|
margin-bottom: 0.25rem;
|
|
390
399
|
}
|
|
400
|
+
.mb-3 {
|
|
401
|
+
margin-bottom: 0.75rem;
|
|
402
|
+
}
|
|
391
403
|
.-ml-1 {
|
|
392
404
|
margin-left: calc(0.25rem * -1);
|
|
393
405
|
}
|
|
@@ -686,7 +698,10 @@
|
|
|
686
698
|
width: fit-content;
|
|
687
699
|
}
|
|
688
700
|
.w-flow-node {
|
|
689
|
-
width:
|
|
701
|
+
width: 21rem;
|
|
702
|
+
}
|
|
703
|
+
.w-flow-panel {
|
|
704
|
+
width: 21rem;
|
|
690
705
|
}
|
|
691
706
|
.w-full {
|
|
692
707
|
width: 100%;
|
|
@@ -949,9 +964,6 @@
|
|
|
949
964
|
scrollbar-color: var(--rendra-input) transparent;
|
|
950
965
|
}
|
|
951
966
|
}
|
|
952
|
-
.list-disc {
|
|
953
|
-
list-style-type: disc;
|
|
954
|
-
}
|
|
955
967
|
.grid-chat-3 {
|
|
956
968
|
grid-template-columns: minmax(18rem, 24rem) minmax(0, 1fr);
|
|
957
969
|
@media (width >= 80rem) {
|
|
@@ -1399,6 +1411,9 @@
|
|
|
1399
1411
|
background-color: color-mix(in oklab, var(--rendra-primary-soft) 60%, transparent);
|
|
1400
1412
|
}
|
|
1401
1413
|
}
|
|
1414
|
+
.bg-primary-text {
|
|
1415
|
+
background-color: var(--rendra-primary-text);
|
|
1416
|
+
}
|
|
1402
1417
|
.bg-secondary {
|
|
1403
1418
|
background-color: var(--rendra-secondary);
|
|
1404
1419
|
}
|
|
@@ -1547,9 +1562,6 @@
|
|
|
1547
1562
|
.pr-8 {
|
|
1548
1563
|
padding-right: 2rem;
|
|
1549
1564
|
}
|
|
1550
|
-
.pr-12 {
|
|
1551
|
-
padding-right: 3rem;
|
|
1552
|
-
}
|
|
1553
1565
|
.pb-1 {
|
|
1554
1566
|
padding-bottom: 0.25rem;
|
|
1555
1567
|
}
|
|
@@ -1565,9 +1577,6 @@
|
|
|
1565
1577
|
.pb-6 {
|
|
1566
1578
|
padding-bottom: 1.5rem;
|
|
1567
1579
|
}
|
|
1568
|
-
.pb-8 {
|
|
1569
|
-
padding-bottom: 2rem;
|
|
1570
|
-
}
|
|
1571
1580
|
.pb-safe {
|
|
1572
1581
|
padding-bottom: max(1rem, env(safe-area-inset-bottom));
|
|
1573
1582
|
}
|
|
@@ -2075,6 +2084,9 @@
|
|
|
2075
2084
|
calc((1 - var(--bottom, 1)) * 50%) 100%
|
|
2076
2085
|
);
|
|
2077
2086
|
}
|
|
2087
|
+
.ring-inset {
|
|
2088
|
+
--tw-ring-inset: inset;
|
|
2089
|
+
}
|
|
2078
2090
|
.running {
|
|
2079
2091
|
animation-play-state: running;
|
|
2080
2092
|
}
|
|
@@ -2934,6 +2946,9 @@
|
|
|
2934
2946
|
.md\:h-control-sm {
|
|
2935
2947
|
height: var(--rendra-spacing-control-sm);
|
|
2936
2948
|
}
|
|
2949
|
+
.md\:h-viewer {
|
|
2950
|
+
height: 28rem;
|
|
2951
|
+
}
|
|
2937
2952
|
.md\:max-h-command {
|
|
2938
2953
|
max-height: min(24rem, 60dvh);
|
|
2939
2954
|
}
|
|
@@ -3167,9 +3182,6 @@
|
|
|
3167
3182
|
.lg\:w-3xs {
|
|
3168
3183
|
width: 16rem;
|
|
3169
3184
|
}
|
|
3170
|
-
.lg\:w-popover {
|
|
3171
|
-
width: min(22rem, calc(100vw - 2rem));
|
|
3172
|
-
}
|
|
3173
3185
|
.lg\:w-sm {
|
|
3174
3186
|
width: 24rem;
|
|
3175
3187
|
}
|
|
@@ -3188,12 +3200,6 @@
|
|
|
3188
3200
|
.lg\:grid-cols-6 {
|
|
3189
3201
|
grid-template-columns: repeat(6, minmax(0, 1fr));
|
|
3190
3202
|
}
|
|
3191
|
-
.lg\:flex-row {
|
|
3192
|
-
flex-direction: row;
|
|
3193
|
-
}
|
|
3194
|
-
.lg\:items-start {
|
|
3195
|
-
align-items: flex-start;
|
|
3196
|
-
}
|
|
3197
3203
|
.lg\:justify-center {
|
|
3198
3204
|
justify-content: center;
|
|
3199
3205
|
}
|
|
@@ -3349,6 +3355,37 @@
|
|
|
3349
3355
|
grid-template-columns: repeat(6, minmax(0, 1fr));
|
|
3350
3356
|
}
|
|
3351
3357
|
}
|
|
3358
|
+
@container (width >= 64rem) {
|
|
3359
|
+
.\@5xl\:h-board {
|
|
3360
|
+
height: var(--board-h, 32rem);
|
|
3361
|
+
}
|
|
3362
|
+
.\@5xl\:h-full {
|
|
3363
|
+
height: 100%;
|
|
3364
|
+
}
|
|
3365
|
+
.\@5xl\:min-h-viewer {
|
|
3366
|
+
min-height: 28rem;
|
|
3367
|
+
}
|
|
3368
|
+
.\@5xl\:w-flow-panel {
|
|
3369
|
+
width: 21rem;
|
|
3370
|
+
}
|
|
3371
|
+
.\@5xl\:flex-1 {
|
|
3372
|
+
flex: 1;
|
|
3373
|
+
}
|
|
3374
|
+
.\@5xl\:flex-row {
|
|
3375
|
+
flex-direction: row;
|
|
3376
|
+
}
|
|
3377
|
+
.\@5xl\:overflow-y-auto {
|
|
3378
|
+
overflow-y: auto;
|
|
3379
|
+
}
|
|
3380
|
+
.\@5xl\:border-t-0 {
|
|
3381
|
+
border-top-style: var(--tw-border-style);
|
|
3382
|
+
border-top-width: 0px;
|
|
3383
|
+
}
|
|
3384
|
+
.\@5xl\:border-l {
|
|
3385
|
+
border-left-style: var(--tw-border-style);
|
|
3386
|
+
border-left-width: 1px;
|
|
3387
|
+
}
|
|
3388
|
+
}
|
|
3352
3389
|
@container (width >= 72rem) {
|
|
3353
3390
|
.\@6xl\:grid-cols-1 {
|
|
3354
3391
|
grid-template-columns: repeat(1, minmax(0, 1fr));
|
|
@@ -3685,6 +3722,10 @@
|
|
|
3685
3722
|
.flow-surface .react-flow__node {
|
|
3686
3723
|
touch-action: none;
|
|
3687
3724
|
}
|
|
3725
|
+
.flow-surface .react-flow__handle {
|
|
3726
|
+
background-color: transparent !important;
|
|
3727
|
+
border: 0;
|
|
3728
|
+
}
|
|
3688
3729
|
.flow-surface .react-flow__node:focus-visible {
|
|
3689
3730
|
border-radius: var(--rendra-shape-block);
|
|
3690
3731
|
outline: 2px solid var(--rendra-ring);
|
package/dist/document-viewer.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
/*! Rendra Design System v2.
|
|
2
|
-
import { t as cn } from "./cn-
|
|
3
|
-
import { t as Button } from "./button-
|
|
4
|
-
import { t as EmptyState } from "./empty-state-
|
|
1
|
+
/*! Rendra Design System v2.9.0 | MIT | © 2026 Bruno Magalhaes | brunomagalhaes.me */
|
|
2
|
+
import { t as cn } from "./cn-CpdCvlkP.js";
|
|
3
|
+
import { t as Button } from "./button-BcCBrlnt.js";
|
|
4
|
+
import { t as EmptyState } from "./empty-state-Bcx4M0Me.js";
|
|
5
5
|
import { ChevronLeft, ChevronRight, ExternalLink, ZoomIn, ZoomOut } from "lucide-react";
|
|
6
6
|
import { useEffect, useRef, useState } from "react";
|
|
7
7
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|