@rendra-ui/web 2.1.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 (150) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +433 -0
  3. package/bin/rendra.mjs +114 -0
  4. package/dist/base.css +246 -0
  5. package/dist/button-DIcpJwK9.js +143 -0
  6. package/dist/button-DIcpJwK9.js.map +1 -0
  7. package/dist/chart.js +520 -0
  8. package/dist/chart.js.map +1 -0
  9. package/dist/cli/auditar.js +125 -0
  10. package/dist/cli/auditar.js.map +1 -0
  11. package/dist/cli/codigos.js +15 -0
  12. package/dist/cli/codigos.js.map +1 -0
  13. package/dist/cli/help.js +17 -0
  14. package/dist/cli/help.js.map +1 -0
  15. package/dist/cli/trocar.js +242 -0
  16. package/dist/cli/trocar.js.map +1 -0
  17. package/dist/cli/typescript-loader.js +27 -0
  18. package/dist/cli/typescript-loader.js.map +1 -0
  19. package/dist/cn-DVPheE99.js +22 -0
  20. package/dist/cn-DVPheE99.js.map +1 -0
  21. package/dist/components-Cm2ezlPT.js +800 -0
  22. package/dist/components-Cm2ezlPT.js.map +1 -0
  23. package/dist/components.css +3365 -0
  24. package/dist/document-viewer.js +204 -0
  25. package/dist/document-viewer.js.map +1 -0
  26. package/dist/empty-state-DtyZAfYb.js +168 -0
  27. package/dist/empty-state-DtyZAfYb.js.map +1 -0
  28. package/dist/index.js +10530 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/rendra-provider-cCnquOZy.js +88 -0
  31. package/dist/rendra-provider-cCnquOZy.js.map +1 -0
  32. package/dist/rich-text-editor.js +439 -0
  33. package/dist/rich-text-editor.js.map +1 -0
  34. package/dist/router-bridge.js +51 -0
  35. package/dist/router-bridge.js.map +1 -0
  36. package/dist/tokens.css +732 -0
  37. package/dist/tooltip-DyeuGPCc.js +105 -0
  38. package/dist/tooltip-DyeuGPCc.js.map +1 -0
  39. package/dist/types/brand/apply-theme.d.ts +9 -0
  40. package/dist/types/brand/brand-context.d.ts +21 -0
  41. package/dist/types/brand/brand-provider.d.ts +49 -0
  42. package/dist/types/brand/palette.d.ts +63 -0
  43. package/dist/types/brand/public.d.ts +6 -0
  44. package/dist/types/brand/theme.d.ts +80 -0
  45. package/dist/types/brand/types.d.ts +54 -0
  46. package/dist/types/brand/use-brand.d.ts +1 -0
  47. package/dist/types/catalog/components.d.ts +81 -0
  48. package/dist/types/chart.d.ts +1 -0
  49. package/dist/types/components/app-shell/app-shell.d.ts +36 -0
  50. package/dist/types/components/app-shell/command-search.d.ts +1 -0
  51. package/dist/types/components/app-shell/header.d.ts +1 -0
  52. package/dist/types/components/app-shell/layout.d.ts +53 -0
  53. package/dist/types/components/app-shell/mega-menu.d.ts +1 -0
  54. package/dist/types/components/app-shell/navigation-utils.d.ts +18 -0
  55. package/dist/types/components/app-shell/notifications.d.ts +6 -0
  56. package/dist/types/components/app-shell/shell-context.d.ts +48 -0
  57. package/dist/types/components/app-shell/sidebar.d.ts +1 -0
  58. package/dist/types/components/app-shell/types.d.ts +53 -0
  59. package/dist/types/components/layout/index.d.ts +4 -0
  60. package/dist/types/components/layout/page-header.d.ts +38 -0
  61. package/dist/types/components/layout/primitives.d.ts +71 -0
  62. package/dist/types/components/layout/tokens.d.ts +43 -0
  63. package/dist/types/components/rendra-provider.d.ts +48 -0
  64. package/dist/types/components/rendra-router-bridge.d.ts +18 -0
  65. package/dist/types/components/ui/accordion.d.ts +16 -0
  66. package/dist/types/components/ui/action-bar.d.ts +35 -0
  67. package/dist/types/components/ui/alert.d.ts +26 -0
  68. package/dist/types/components/ui/avatar.d.ts +23 -0
  69. package/dist/types/components/ui/badge.d.ts +15 -0
  70. package/dist/types/components/ui/brand-feedback-icon.d.ts +26 -0
  71. package/dist/types/components/ui/brand-logo.d.ts +8 -0
  72. package/dist/types/components/ui/breadcrumb.d.ts +19 -0
  73. package/dist/types/components/ui/button-group.d.ts +27 -0
  74. package/dist/types/components/ui/button.d.ts +30 -0
  75. package/dist/types/components/ui/calendar.d.ts +34 -0
  76. package/dist/types/components/ui/card.d.ts +32 -0
  77. package/dist/types/components/ui/chart.d.ts +57 -0
  78. package/dist/types/components/ui/chat.d.ts +137 -0
  79. package/dist/types/components/ui/checkbox.d.ts +37 -0
  80. package/dist/types/components/ui/checklist.d.ts +16 -0
  81. package/dist/types/components/ui/color-picker.d.ts +13 -0
  82. package/dist/types/components/ui/data-toolbar.d.ts +37 -0
  83. package/dist/types/components/ui/date-picker.d.ts +41 -0
  84. package/dist/types/components/ui/document-viewer.d.ts +19 -0
  85. package/dist/types/components/ui/drawer.d.ts +30 -0
  86. package/dist/types/components/ui/dropdown-menu.d.ts +20 -0
  87. package/dist/types/components/ui/empty-state.d.ts +15 -0
  88. package/dist/types/components/ui/error-page.d.ts +13 -0
  89. package/dist/types/components/ui/field.d.ts +42 -0
  90. package/dist/types/components/ui/form.d.ts +42 -0
  91. package/dist/types/components/ui/image-cropper.d.ts +55 -0
  92. package/dist/types/components/ui/image-viewer.d.ts +14 -0
  93. package/dist/types/components/ui/info-hint.d.ts +9 -0
  94. package/dist/types/components/ui/input.d.ts +91 -0
  95. package/dist/types/components/ui/kanban.d.ts +98 -0
  96. package/dist/types/components/ui/list.d.ts +31 -0
  97. package/dist/types/components/ui/modal.d.ts +27 -0
  98. package/dist/types/components/ui/otp-input.d.ts +17 -0
  99. package/dist/types/components/ui/overlay-shell.d.ts +14 -0
  100. package/dist/types/components/ui/pagination.d.ts +18 -0
  101. package/dist/types/components/ui/picker-panel.d.ts +24 -0
  102. package/dist/types/components/ui/popover.d.ts +12 -0
  103. package/dist/types/components/ui/progress.d.ts +16 -0
  104. package/dist/types/components/ui/qr-code.d.ts +13 -0
  105. package/dist/types/components/ui/radio-group.d.ts +27 -0
  106. package/dist/types/components/ui/rating.d.ts +19 -0
  107. package/dist/types/components/ui/rendra-credit.d.ts +12 -0
  108. package/dist/types/components/ui/repeatable-field.d.ts +22 -0
  109. package/dist/types/components/ui/rich-text-editor.d.ts +21 -0
  110. package/dist/types/components/ui/select.d.ts +65 -0
  111. package/dist/types/components/ui/separator.d.ts +7 -0
  112. package/dist/types/components/ui/skeleton.d.ts +3 -0
  113. package/dist/types/components/ui/slider.d.ts +18 -0
  114. package/dist/types/components/ui/sortable-handle.d.ts +16 -0
  115. package/dist/types/components/ui/spinner.d.ts +7 -0
  116. package/dist/types/components/ui/stat-card.d.ts +20 -0
  117. package/dist/types/components/ui/switch.d.ts +15 -0
  118. package/dist/types/components/ui/table.d.ts +134 -0
  119. package/dist/types/components/ui/tabs.d.ts +25 -0
  120. package/dist/types/components/ui/textarea.d.ts +10 -0
  121. package/dist/types/components/ui/timeline.d.ts +18 -0
  122. package/dist/types/components/ui/toast.d.ts +18 -0
  123. package/dist/types/components/ui/tooltip.d.ts +17 -0
  124. package/dist/types/components/ui/upload.d.ts +50 -0
  125. package/dist/types/components/ui/widget-grid.d.ts +22 -0
  126. package/dist/types/components/ui/wizard.d.ts +38 -0
  127. package/dist/types/document-viewer.d.ts +1 -0
  128. package/dist/types/hooks/use-breakpoint.d.ts +21 -0
  129. package/dist/types/hooks/use-debounced-value.d.ts +5 -0
  130. package/dist/types/hooks/use-fill-height.d.ts +6 -0
  131. package/dist/types/hooks/use-lookup.d.ts +30 -0
  132. package/dist/types/hooks/use-reduced-motion.d.ts +1 -0
  133. package/dist/types/index.d.ts +76 -0
  134. package/dist/types/lib/cn.d.ts +2 -0
  135. package/dist/types/lib/contrast.d.ts +2 -0
  136. package/dist/types/lib/control.d.ts +20 -0
  137. package/dist/types/lib/lookup.d.ts +22 -0
  138. package/dist/types/lib/masks.d.ts +46 -0
  139. package/dist/types/lib/qr-encode.d.ts +48 -0
  140. package/dist/types/lib/shape.d.ts +8 -0
  141. package/dist/types/lib/sortable.d.ts +72 -0
  142. package/dist/types/lib/validators.d.ts +14 -0
  143. package/dist/types/rendra-router-bridge.d.ts +1 -0
  144. package/dist/types/rich-text-editor.d.ts +1 -0
  145. package/dist/types/widget-grid.d.ts +1 -0
  146. package/dist/use-breakpoint-BmXOZtF9.js +49 -0
  147. package/dist/use-breakpoint-BmXOZtF9.js.map +1 -0
  148. package/dist/widget-grid.js +118 -0
  149. package/dist/widget-grid.js.map +1 -0
  150. package/package.json +182 -0
@@ -0,0 +1,91 @@
1
+ import { type InputHTMLAttributes, type ReactNode } from 'react';
2
+ import { type LookupResult } from '../../hooks/use-lookup';
3
+ import { type ControlSize } from '../../lib/control';
4
+ import { type MaskName, type PhoneCountry } from '../../lib/masks';
5
+ /** Uma unidade do seletor embutido do Input (A9). */
6
+ export interface InputUnitOption {
7
+ /** "percent" e "currency" ligam a máscara de percentual e de moeda automaticamente. */
8
+ id: string;
9
+ label: string;
10
+ }
11
+ export interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'onChange'> {
12
+ size?: ControlSize;
13
+ /** Máscara brasileira. Define também o teclado do celular (inputMode). */
14
+ mask?: MaskName;
15
+ /** Ícone à esquerda. */
16
+ icon?: ReactNode;
17
+ /** Conteúdo fixo à direita (ex.: "kg", "dias"). Ignorado quando `units` está presente. */
18
+ suffix?: ReactNode;
19
+ /** Mostra botão para limpar quando há valor. */
20
+ clearable?: boolean;
21
+ /** Estado de erro (normalmente vem do Field). */
22
+ invalid?: boolean;
23
+ value?: string;
24
+ /** Recebe o valor como aparece no campo (com máscara). */
25
+ onChange?: (value: string) => void;
26
+ /** Recebe o valor sem máscara (só dígitos, ou número para moeda e percentual). */
27
+ onValueChange?: (unmasked: string, masked: string) => void;
28
+ /**
29
+ * Telefone (mask="phone"): DDI escolhido no seletor embutido à esquerda, sem o "+".
30
+ * Padrão "55". Com +55 a máscara é a brasileira; com outro DDI, só dígitos.
31
+ * O valor do campo continua sendo o número nacional; o completo sai de toE164(ddi, valor).
32
+ */
33
+ ddi?: string;
34
+ onDdiChange?: (ddi: string) => void;
35
+ /** Países do seletor de DDI. Padrão: phoneCountries (Brasil primeiro). */
36
+ ddiOptions?: PhoneCountry[];
37
+ /** Esconde o seletor de DDI do telefone (só números brasileiros). */
38
+ hideDdi?: boolean;
39
+ /**
40
+ * Moeda (mask="currency"): recebe o valor em centavos inteiros (R$ 1.250,50 -> 125050),
41
+ * ou null quando vazio. Guarde e some dinheiro sempre em centavos.
42
+ */
43
+ onCentsChange?: (cents: number | null) => void;
44
+ /**
45
+ * CEP, CNPJ e CPF ou CNPJ (mask="cep", "cnpj" ou "cpfCnpj"): busca os dados assim que o
46
+ * campo fica completo (ViaCEP e BrasilAPI), mostra o carregamento no campo e entrega o
47
+ * resultado. A tela decide o que preencher; use `result.message` como ajuda do Field.
48
+ */
49
+ onLookup?: (result: LookupResult) => void;
50
+ /**
51
+ * Unidades (A9): seletor embutido à direita, no mesmo padrão do seletor de DDI. O id
52
+ * "percent" liga a máscara de percentual (teto configurável por `percentMax`); "currency"
53
+ * liga a máscara de moeda (R$ 1.250,00). Qualquer outro id não aplica máscara, só rótulo.
54
+ * Trocar de unidade sempre limpa o valor do campo.
55
+ */
56
+ units?: InputUnitOption[];
57
+ /** Unidade escolhida (controlada). Sem ela, usa a primeira de `units`. */
58
+ unit?: string;
59
+ onUnitChange?: (unit: string) => void;
60
+ /** Teto do percentual quando a unidade escolhida é "percent". Padrão 100. */
61
+ percentMax?: number;
62
+ /**
63
+ * Variante de valor guardado (A10): mostra `maskedHint` no lugar do valor real, que nunca
64
+ * chega a existir no DOM. "Trocar" abre um campo vazio (`isEditing`); cancelar volta à
65
+ * máscara. O componente é controlado pela tela: `isEditing`, `onStartEdit`, `onCancelEdit`.
66
+ */
67
+ variant?: 'secret';
68
+ /** Há um valor salvo (mesmo sem mostrá-lo). */
69
+ hasValue?: boolean;
70
+ /** Texto mascarado mostrado no lugar do valor, ex.: "••••••a1b2c3". */
71
+ maskedHint?: string;
72
+ /** Campo aberto para digitar um valor novo. */
73
+ isEditing?: boolean;
74
+ onStartEdit?: () => void;
75
+ onCancelEdit?: () => void;
76
+ /** Remove o valor salvo. Sem essa prop, o botão "Remover" não aparece. */
77
+ onRemove?: () => void;
78
+ /** Remoção em andamento: desabilita e mostra o carregamento no botão "Remover". */
79
+ removing?: boolean;
80
+ className?: string;
81
+ /**
82
+ * Classe extra no próprio elemento `<input>` (className vai no quadro em volta). Uso raro:
83
+ * hoje só o texto riscado de um item marcado no Checklist.
84
+ */
85
+ inputClassName?: string;
86
+ }
87
+ /**
88
+ * Input único. Tipos, máscaras, ícone, limpar, senha, unidades e valor guardado são props:
89
+ * nunca crie InputCPF, InputTelefone, InputSenha ou InputSegredo.
90
+ */
91
+ export declare const Input: import("react").ForwardRefExoticComponent<InputProps & import("react").RefAttributes<HTMLInputElement>>;
@@ -0,0 +1,98 @@
1
+ import { type ReactNode } from 'react';
2
+ import { type BadgeProps } from './badge';
3
+ export interface KanbanColumn {
4
+ id: string;
5
+ title: string;
6
+ /** Cor do marcador da coluna. */
7
+ tone?: BadgeProps['tone'];
8
+ /** Limite de cards (WIP). Passando dele, o contador fica em alerta. */
9
+ limit?: number;
10
+ }
11
+ export interface KanbanCard {
12
+ id: string;
13
+ columnId: string;
14
+ /** Empresa ou pessoa. */
15
+ title: string;
16
+ /** Linha abaixo do título: CNPJ da empresa ou CPF da pessoa. */
17
+ subtitle?: string;
18
+ description?: string;
19
+ /** Pessoa de contato: nome, telefone e e-mail. */
20
+ contact?: {
21
+ name?: string;
22
+ phone?: string;
23
+ email?: string;
24
+ };
25
+ tags?: {
26
+ label: string;
27
+ tone?: BadgeProps['tone'];
28
+ }[];
29
+ /** Nome do responsável (vira avatar com iniciais). */
30
+ assignee?: string;
31
+ dueDate?: Date;
32
+ /** Valor ou informação curta à direita do rodapé (ex.: "R$ 12.500,00"). */
33
+ meta?: string;
34
+ /** Valores numéricos do card, pelas chaves de valueFields (ex.: { ps: 4800, mrr: 590 }). */
35
+ values?: Record<string, number>;
36
+ }
37
+ /** Valor somado no cabeçalho da coluna e mostrado no card (ex.: P&S e MRR). */
38
+ export interface KanbanValueField {
39
+ key: string;
40
+ label: string;
41
+ }
42
+ /**
43
+ * Destino de arraste (etapa A14): uma ação para onde o card vai, diferente de "outra
44
+ * coluna" (ex.: "Marcar como ganho", "Arquivar"). Aparece numa barra durante o arraste e
45
+ * como opção do menu "Mover para" (equivalente por teclado, sempre disponível).
46
+ */
47
+ export interface KanbanDropTarget {
48
+ id: string;
49
+ label: string;
50
+ /** Texto curto de apoio, mostrado abaixo do rótulo na barra. */
51
+ hint?: string;
52
+ icon?: ReactNode;
53
+ tone?: BadgeProps['tone'];
54
+ disabled?: boolean;
55
+ /** Motivo mostrado quando desabilitado; o destino recusa o solto. */
56
+ disabledReason?: string;
57
+ }
58
+ export interface KanbanProps {
59
+ columns: KanbanColumn[];
60
+ cards: KanbanCard[];
61
+ /** Card movido: coluna de destino e posição dentro dela (0 = topo). */
62
+ onCardMove?: (cardId: string, toColumnId: string, toIndex: number) => void;
63
+ onCardClick?: (card: KanbanCard) => void;
64
+ /** Botão (+) no título de cada etapa. */
65
+ onAddCard?: (columnId: string) => void;
66
+ /** Cards mostrados por vez em cada etapa; ao rolar até o fim, mostra mais. Padrão: 20. */
67
+ pageSize?: number;
68
+ /**
69
+ * Busca mais cards no servidor quando a etapa chega ao fim do que já foi carregado.
70
+ * Sem ela, a rolagem infinita só vai revelando os cards recebidos em cards.
71
+ */
72
+ onLoadMore?: (columnId: string) => void;
73
+ /** A etapa ainda tem cards no servidor (usado com onLoadMore). */
74
+ hasMore?: (columnId: string) => boolean;
75
+ /** Etapas visíveis por vez no desktop; as demais pela rolagem lateral. Padrão: 5. */
76
+ visibleColumns?: number;
77
+ /** Conteúdo próprio do card, no lugar do padrão. */
78
+ renderCard?: (card: KanbanCard) => ReactNode;
79
+ /**
80
+ * Valores do card (até 2, lado a lado com divisória) e o total de cada um na coluna.
81
+ * Ex.: [{ key: 'ps', label: 'P&S' }, { key: 'mrr', label: 'MRR' }].
82
+ */
83
+ valueFields?: KanbanValueField[];
84
+ /** Formato dos valores. Padrão: moeda (R$ 1.250,00). */
85
+ formatValue?: (n: number) => string;
86
+ /**
87
+ * Destinos de arraste além das colunas (ex.: "Marcar como ganho"). Com eles, mostra uma
88
+ * barra durante o arraste e o menu "Mover para" passa a listar estes destinos.
89
+ */
90
+ dropTargets?: KanbanDropTarget[];
91
+ /** Card solto num destino da barra (ou escolhido no menu "Mover para"). */
92
+ onDropTarget?: (cardId: string, targetId: string) => void;
93
+ 'aria-label'?: string;
94
+ className?: string;
95
+ }
96
+ export declare function Kanban({ columns, cards, onCardMove, onCardClick, onAddCard, renderCard, valueFields, formatValue, pageSize, visibleColumns, onLoadMore, hasMore, dropTargets, onDropTarget, className, ...aria }: KanbanProps): import("react").JSX.Element;
97
+ /** Move um card na lista (para usar no onCardMove): devolve a lista nova. */
98
+ export declare function moveKanbanCard(cards: KanbanCard[], cardId: string, toColumnId: string, toIndex: number): KanbanCard[];
@@ -0,0 +1,31 @@
1
+ import type { ReactNode } from 'react';
2
+ export interface ListItem {
3
+ id: string;
4
+ title: ReactNode;
5
+ description?: ReactNode;
6
+ /** Avatar, ícone ou imagem à esquerda. */
7
+ leading?: ReactNode;
8
+ /** Valor, badge ou ação à direita. */
9
+ trailing?: ReactNode;
10
+ /** Torna a linha navegável. */
11
+ to?: string;
12
+ onClick?: () => void;
13
+ /** Selo textual de status da linha, com contraste AA (nunca só cor). */
14
+ tone?: 'success' | 'error' | 'warning' | 'neutral';
15
+ }
16
+ export interface ListProps {
17
+ items: ListItem[];
18
+ /** Linhas separadas por borda (padrão) ou sem divisória. */
19
+ divided?: boolean;
20
+ empty?: ReactNode;
21
+ className?: string;
22
+ /**
23
+ * Reordena os itens por arraste (mouse e toque) e por teclado (setas ↑/↓ na alça).
24
+ * Sem ela a lista é só leitura e a alça de arraste não aparece.
25
+ */
26
+ onReorder?: (items: ListItem[]) => void;
27
+ /** Nome acessível de cada item para a alça de arraste (ex.: "Cliente A"). Padrão: o título, em texto. */
28
+ itemLabel?: (item: ListItem) => string;
29
+ }
30
+ /** Lista única: linhas com início, título, descrição e fim; navegável por prop; reordenável por prop. */
31
+ export declare function List({ items, divided, empty, className, onReorder, itemLabel, }: ListProps): import("react").JSX.Element;
@@ -0,0 +1,27 @@
1
+ import { type ReactNode } from 'react';
2
+ export type ModalType = 'confirm' | 'destructive' | 'info' | 'form';
3
+ declare const sizes: {
4
+ readonly sm: "md:max-w-sm";
5
+ readonly md: "md:max-w-lg";
6
+ readonly lg: "md:max-w-2xl";
7
+ };
8
+ export interface ModalProps {
9
+ open: boolean;
10
+ onOpenChange: (open: boolean) => void;
11
+ title: string;
12
+ description?: ReactNode;
13
+ type?: ModalType;
14
+ size?: keyof typeof sizes;
15
+ /** Conteúdo do body (em form, os campos). */
16
+ children?: ReactNode;
17
+ confirmLabel?: string;
18
+ cancelLabel?: string;
19
+ /** Pode ser assíncrono: o botão mostra carregamento até terminar. */
20
+ onConfirm?: () => void | Promise<void>;
21
+ /** id do <form> quando type="form" (o botão principal vira submit dele). */
22
+ formId?: string;
23
+ /** Estado de envio controlado de fora (ex.: isSubmitting do React Hook Form). */
24
+ loading?: boolean;
25
+ }
26
+ export declare function Modal({ open, onOpenChange, title, description, type, size, children, confirmLabel, cancelLabel, onConfirm, formId, loading, }: ModalProps): import("react").JSX.Element;
27
+ export {};
@@ -0,0 +1,17 @@
1
+ export interface OtpInputProps {
2
+ /** Quantidade de dígitos. Padrão 6. */
3
+ length?: number;
4
+ value: string;
5
+ onChange: (value: string) => void;
6
+ /** Chamado quando todos os dígitos foram preenchidos. */
7
+ onComplete?: (value: string) => void;
8
+ invalid?: boolean;
9
+ disabled?: boolean;
10
+ id?: string;
11
+ 'aria-describedby'?: string;
12
+ }
13
+ /**
14
+ * Código de verificação (2FA, confirmação de e-mail). Uma caixa por dígito, aceita colar
15
+ * o código inteiro, teclado numérico no celular e preenchimento automático por SMS.
16
+ */
17
+ export declare function OtpInput({ length, value, onChange, onComplete, invalid, disabled, id, ...aria }: OtpInputProps): import("react").JSX.Element;
@@ -0,0 +1,14 @@
1
+ import type { ReactNode } from 'react';
2
+ interface OverlayShellProps {
3
+ title: ReactNode;
4
+ description?: ReactNode;
5
+ icon?: ReactNode;
6
+ children: ReactNode;
7
+ footer?: ReactNode;
8
+ /** Esconde o header visualmente (o título continua para leitores de tela). */
9
+ hideHeader?: boolean;
10
+ onRequestClose: () => void;
11
+ bodyClassName?: string;
12
+ }
13
+ export declare function OverlayShell({ title, description, icon, children, footer, hideHeader, onRequestClose, bodyClassName, }: OverlayShellProps): import("react").JSX.Element;
14
+ export {};
@@ -0,0 +1,18 @@
1
+ export interface PaginationProps {
2
+ /** Página atual, começando em 1. */
3
+ page: number;
4
+ pageSize: number;
5
+ total: number;
6
+ onPageChange: (page: number) => void;
7
+ onPageSizeChange?: (size: number) => void;
8
+ pageSizes?: number[];
9
+ /**
10
+ * Mobile: 'pages' mostra anterior e próxima com "Página 2 de 25";
11
+ * 'loadMore' troca por um botão "Carregar mais".
12
+ */
13
+ mobileMode?: 'pages' | 'loadMore';
14
+ loading?: boolean;
15
+ className?: string;
16
+ }
17
+ /** Paginação única: completa no desktop, compacta ou "carregar mais" no mobile. */
18
+ export declare function Pagination({ page, pageSize, total, onPageChange, onPageSizeChange, pageSizes, mobileMode, loading, className, }: PaginationProps): import("react").JSX.Element;
@@ -0,0 +1,24 @@
1
+ import type { ReactNode } from 'react';
2
+ interface PickerPanelProps {
3
+ open: boolean;
4
+ onOpenChange: (open: boolean) => void;
5
+ /** O gatilho (renderizado com asChild). */
6
+ trigger: ReactNode;
7
+ /** Título do bottom sheet no mobile (normalmente o rótulo do campo). */
8
+ title: string;
9
+ /** Topo fixo (ex.: campo de busca). */
10
+ header?: ReactNode;
11
+ children: ReactNode;
12
+ /** Rodapé fixo (ex.: Limpar / Aplicar). */
13
+ footer?: ReactNode;
14
+ /** Largura no desktop: do gatilho ou automática (calendário). */
15
+ width?: 'trigger' | 'auto';
16
+ /**
17
+ * Botão sobreposto ao gatilho (ex.: limpar). Fica como irmão do gatilho, nunca dentro
18
+ * dele: botão dentro de botão é HTML inválido e confunde leitores de tela.
19
+ */
20
+ adornment?: ReactNode;
21
+ align?: 'start' | 'center' | 'end';
22
+ }
23
+ export declare function PickerPanel({ open, onOpenChange, trigger, title, header, children, footer, width, adornment, align, }: PickerPanelProps): import("react").JSX.Element;
24
+ export {};
@@ -0,0 +1,12 @@
1
+ import { Popover as P } from 'radix-ui';
2
+ import type { ComponentProps } from 'react';
3
+ export declare const Popover: import("react").FC<P.PopoverProps>;
4
+ export declare const PopoverTrigger: import("react").ForwardRefExoticComponent<P.PopoverTriggerProps & import("react").RefAttributes<HTMLButtonElement>>;
5
+ export declare const PopoverClose: import("react").ForwardRefExoticComponent<P.PopoverCloseProps & import("react").RefAttributes<HTMLButtonElement>>;
6
+ export declare const PopoverAnchor: import("react").ForwardRefExoticComponent<P.PopoverAnchorProps & import("react").RefAttributes<HTMLDivElement>>;
7
+ interface PopoverContentProps extends ComponentProps<typeof P.Content> {
8
+ /** Largura: sm (16rem) ou md (22rem). Sempre limitada à tela menos 32px. */
9
+ width?: 'sm' | 'md';
10
+ }
11
+ export declare function PopoverContent({ className, align, sideOffset, width, ...props }: PopoverContentProps): import("react").JSX.Element;
12
+ export {};
@@ -0,0 +1,16 @@
1
+ import { type VariantProps } from 'class-variance-authority';
2
+ declare const bar: (props?: ({
3
+ tone?: "success" | "error" | "warning" | "primary" | "brand" | null | undefined;
4
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
5
+ export interface ProgressProps extends VariantProps<typeof bar> {
6
+ /** 0 a 100. Sem valor: indeterminado (animado). */
7
+ value?: number | null;
8
+ size?: 'sm' | 'md';
9
+ /** Mostra o percentual à direita. */
10
+ showValue?: boolean;
11
+ label?: string;
12
+ className?: string;
13
+ }
14
+ /** Barra de progresso única. tone="brand" usa o degradê de detalhe do template. */
15
+ export declare function Progress({ value, size, tone, showValue, label, className }: ProgressProps): import("react").JSX.Element;
16
+ export {};
@@ -0,0 +1,13 @@
1
+ import { type ErrorCorrectionLevel } from '../../lib/qr-encode';
2
+ export interface QrCodeProps {
3
+ value: string;
4
+ /** Lado do quadrado, em pixels. */
5
+ size?: number;
6
+ errorCorrection?: ErrorCorrectionLevel;
7
+ className?: string;
8
+ 'aria-label'?: string;
9
+ emptyLabel?: string;
10
+ errorLabel?: string;
11
+ }
12
+ /** Um único QR Code por tela; nunca crie um segundo componente parecido para outro tamanho. */
13
+ export declare function QrCode({ value, size, errorCorrection, className, emptyLabel, errorLabel, ...aria }: QrCodeProps): import("react").JSX.Element;
@@ -0,0 +1,27 @@
1
+ import type { ReactNode } from 'react';
2
+ export interface RadioOption {
3
+ value: string;
4
+ label: ReactNode;
5
+ description?: ReactNode;
6
+ icon?: ReactNode;
7
+ disabled?: boolean;
8
+ }
9
+ export interface RadioGroupProps {
10
+ options: RadioOption[];
11
+ value?: string;
12
+ defaultValue?: string;
13
+ onChange?: (value: string) => void;
14
+ /** list: bolinha e texto; cards: cartões selecionáveis com ícone e descrição. */
15
+ variant?: 'list' | 'cards';
16
+ /** Colunas dos cards a partir de md (no mobile sempre 1). */
17
+ columns?: 1 | 2 | 3;
18
+ orientation?: 'vertical' | 'horizontal';
19
+ invalid?: boolean;
20
+ disabled?: boolean;
21
+ id?: string;
22
+ name?: string;
23
+ 'aria-describedby'?: string;
24
+ 'aria-label'?: string;
25
+ }
26
+ /** Radio único: em lista ou em cards, por prop. */
27
+ export declare function RadioGroup({ options, value, defaultValue, onChange, variant, columns, orientation, invalid, disabled, id, name, ...aria }: RadioGroupProps): import("react").JSX.Element;
@@ -0,0 +1,19 @@
1
+ export interface RatingProps {
2
+ variant?: 'stars' | 'scale';
3
+ value: number | null;
4
+ onChange?: (value: number | null) => void;
5
+ /** stars: total de estrelas (padrão 5). scale: valor máximo (padrão 10, até 10). */
6
+ max?: number;
7
+ /** Só a escala: valor mínimo (padrão 1). */
8
+ min?: number;
9
+ /** Só a escala: rótulo da ponta de baixo. */
10
+ lowLabel?: string;
11
+ /** Só a escala: rótulo da ponta de cima. */
12
+ highLabel?: string;
13
+ disabled?: boolean;
14
+ invalid?: boolean;
15
+ id?: string;
16
+ 'aria-label'?: string;
17
+ 'aria-describedby'?: string;
18
+ }
19
+ export declare function Rating({ variant, value, onChange, max, min, lowLabel, highLabel, disabled, invalid, id, ...aria }: RatingProps): import("react").JSX.Element;
@@ -0,0 +1,12 @@
1
+ export declare const RENDRA_CREDIT_TEXT = "Feito com Rendra";
2
+ export declare const RENDRA_CREDIT_HREF = "https://github.com/bsmagalhaes/rendra-design-system";
3
+ export interface RendraCreditProps {
4
+ /** Padrão true; false remove o crédito. */
5
+ credit?: boolean;
6
+ /** Padrão "Feito com Rendra". */
7
+ text?: string;
8
+ /** Padrão: o repositório do Rendra Design System. */
9
+ href?: string;
10
+ className?: string;
11
+ }
12
+ export declare function RendraCredit({ credit, text, href, className, }: RendraCreditProps): import("react").JSX.Element | null;
@@ -0,0 +1,22 @@
1
+ import type { ReactNode } from 'react';
2
+ export interface RepeatableItem {
3
+ id: string;
4
+ isPrimary?: boolean;
5
+ }
6
+ export interface RepeatableFieldProps<T extends RepeatableItem> {
7
+ items: T[];
8
+ onChange: (items: T[]) => void;
9
+ /** Cria um item novo (com id próprio) quando a pessoa clica em "Adicionar". */
10
+ createItem: () => T;
11
+ /** Desenha os campos de um item; update aplica um patch parcial nesse item. */
12
+ renderField: (item: T, update: (patch: Partial<T>) => void, index: number) => ReactNode;
13
+ /** Mostra o controle de "marcar como principal" em cada item. */
14
+ showPrimary?: boolean;
15
+ maxItems?: number;
16
+ addLabel?: string;
17
+ emptyLabel?: string;
18
+ disabled?: boolean;
19
+ className?: string;
20
+ }
21
+ /** Uma lista repetível por finalidade: telefones, e-mails, endereços e afins usam este componente. */
22
+ export declare function RepeatableField<T extends RepeatableItem>({ items, onChange, createItem, renderField, showPrimary, maxItems, addLabel, emptyLabel, disabled, className, }: RepeatableFieldProps<T>): import("react").JSX.Element;
@@ -0,0 +1,21 @@
1
+ export interface RichTextEditorProps {
2
+ /** Conteúdo em HTML. */
3
+ value?: string;
4
+ defaultValue?: string;
5
+ onChange?: (html: string) => void;
6
+ placeholder?: string;
7
+ /**
8
+ * Envia a imagem e devolve a URL pública. Sem ela, a imagem entra no conteúdo em base64
9
+ * (bom para demonstração; em produção, envie ao servidor).
10
+ */
11
+ onImageUpload?: (file: File) => Promise<string>;
12
+ /** Altura mínima da área de texto. */
13
+ minHeight?: 'sm' | 'md' | 'lg';
14
+ invalid?: boolean;
15
+ disabled?: boolean;
16
+ id?: string;
17
+ 'aria-label'?: string;
18
+ 'aria-describedby'?: string;
19
+ className?: string;
20
+ }
21
+ export declare function RichTextEditor({ value, defaultValue, onChange, placeholder, onImageUpload, minHeight, invalid, disabled, id, className, ...aria }: RichTextEditorProps): import("react").JSX.Element;
@@ -0,0 +1,65 @@
1
+ import { type ReactNode } from 'react';
2
+ import { type ControlSize } from '../../lib/control';
3
+ export interface SelectOption {
4
+ value: string;
5
+ label: string;
6
+ description?: string;
7
+ icon?: ReactNode;
8
+ disabled?: boolean;
9
+ /** Agrupa opções sob um título. */
10
+ group?: string;
11
+ }
12
+ interface BaseProps {
13
+ options?: SelectOption[];
14
+ placeholder?: string;
15
+ /**
16
+ * Nome do campo: título do painel no mobile e, quando o Select não está dentro de um
17
+ * Field (sem id ligado a um rótulo visível), nome acessível do gatilho.
18
+ */
19
+ label?: string;
20
+ size?: ControlSize;
21
+ invalid?: boolean;
22
+ disabled?: boolean;
23
+ /** Campo de busca no topo da lista. */
24
+ searchable?: boolean;
25
+ /** Permite criar uma opção nova a partir do texto buscado. */
26
+ creatable?: boolean;
27
+ onCreate?: (label: string) => SelectOption | Promise<SelectOption>;
28
+ /** Busca remota: recebe o texto e devolve as opções. Liga a busca automaticamente. */
29
+ loadOptions?: (query: string) => Promise<SelectOption[]>;
30
+ /** Mostra indicador de carregamento na lista. */
31
+ loading?: boolean;
32
+ /** Botão de limpar no campo. */
33
+ clearable?: boolean;
34
+ emptyText?: string;
35
+ id?: string;
36
+ className?: string;
37
+ 'aria-describedby'?: string;
38
+ }
39
+ interface SingleProps extends BaseProps {
40
+ multiple?: false;
41
+ value?: string | null;
42
+ onChange?: (value: string | null) => void;
43
+ selectAll?: never;
44
+ showCount?: never;
45
+ maxChips?: never;
46
+ }
47
+ interface MultipleProps extends BaseProps {
48
+ /** Seleção múltipla com checkbox e chips. */
49
+ multiple: true;
50
+ value?: string[];
51
+ onChange?: (value: string[]) => void;
52
+ /** Opção "Selecionar todos" no topo da lista. */
53
+ selectAll?: boolean;
54
+ /** Mostra "3 selecionados" no lugar dos chips. */
55
+ showCount?: boolean;
56
+ /** Máximo de chips visíveis antes de "+N". */
57
+ maxChips?: number;
58
+ }
59
+ export type SelectProps = SingleProps | MultipleProps;
60
+ /**
61
+ * Select único do sistema. Busca, múltiplo, selecionar todos, contador, criar opção,
62
+ * busca remota e carregamento são props. No mobile abre como bottom sheet.
63
+ */
64
+ export declare const Select: import("react").ForwardRefExoticComponent<SelectProps & import("react").RefAttributes<HTMLButtonElement>>;
65
+ export {};
@@ -0,0 +1,7 @@
1
+ /** Separador: hierarquia dentro de um card (no lugar de card dentro de card). */
2
+ export declare function Separator({ orientation, label, className, }: {
3
+ orientation?: 'horizontal' | 'vertical';
4
+ /** Texto no meio da linha (ex.: "ou"). */
5
+ label?: string;
6
+ className?: string;
7
+ }): import("react").JSX.Element;
@@ -0,0 +1,3 @@
1
+ import type { HTMLAttributes } from 'react';
2
+ /** Bloco de carregamento. Monte o skeleton com a mesma estrutura do conteúdo final. */
3
+ export declare function Skeleton({ className, ...props }: HTMLAttributes<HTMLDivElement>): import("react").JSX.Element;
@@ -0,0 +1,18 @@
1
+ export interface SliderProps {
2
+ /** Um número, ou dois para faixa (mínimo e máximo). */
3
+ value?: number[];
4
+ defaultValue?: number[];
5
+ onChange?: (value: number[]) => void;
6
+ min?: number;
7
+ max?: number;
8
+ step?: number;
9
+ disabled?: boolean;
10
+ /** Mostra o valor atual acima da trilha. */
11
+ showValue?: boolean;
12
+ formatValue?: (n: number) => string;
13
+ id?: string;
14
+ 'aria-label'?: string;
15
+ 'aria-describedby'?: string;
16
+ }
17
+ /** Slider único: valor simples ou faixa. Alça com área de toque de 44px. */
18
+ export declare function Slider({ value, defaultValue, onChange, min, max, step, disabled, showValue, formatValue, id, ...aria }: SliderProps): import("react").JSX.Element;
@@ -0,0 +1,16 @@
1
+ import type { UseSortableResult } from '../../lib/sortable';
2
+ export interface SortableHandleProps {
3
+ id: string;
4
+ /** Nome acessível da alça (ex.: "Reordenar Cliente A"). */
5
+ label: string;
6
+ /** O resultado de useSortable (motor de src/lib/sortable.ts). */
7
+ sortable: Pick<UseSortableResult, 'handleProps'>;
8
+ className?: string;
9
+ }
10
+ /**
11
+ * Alça de arraste única, reaproveitada pela List e pelo Upload (o Kanban tem alça própria,
12
+ * por ser posicionada dentro do card e não ter movimento por seta): pointer down inicia o
13
+ * arraste (mouse e toque) e as setas ↑/↓ movem uma posição pelo teclado, tudo vindo do
14
+ * motor (useSortable), sem duplicar aqui a lógica de mover.
15
+ */
16
+ export declare function SortableHandle({ id, label, sortable, className }: SortableHandleProps): import("react").JSX.Element;
@@ -0,0 +1,7 @@
1
+ export interface SpinnerProps {
2
+ size?: 'sm' | 'md' | 'lg';
3
+ /** Nome do que está carregando. Vazio (padrão): decorativo, sem anúncio de leitor de tela. */
4
+ label?: string;
5
+ className?: string;
6
+ }
7
+ export declare function Spinner({ size, label, className }: SpinnerProps): import("react").JSX.Element;
@@ -0,0 +1,20 @@
1
+ import type { ReactNode } from 'react';
2
+ export interface StatCardProps {
3
+ label: string;
4
+ value: ReactNode;
5
+ /** Variação em %, positiva ou negativa. */
6
+ change?: number;
7
+ /** Texto ao lado da variação (ex.: "vs. mês anterior"). */
8
+ changeLabel?: string;
9
+ /** Quando cair é bom (ex.: custo), inverte as cores da variação. */
10
+ inverse?: boolean;
11
+ icon?: ReactNode;
12
+ /** Destaque com o degradê suave do template. Use em no máximo um card por tela. */
13
+ highlight?: boolean;
14
+ loading?: boolean;
15
+ /** Conteúdo extra no rodapé (ex.: mini gráfico). */
16
+ footer?: ReactNode;
17
+ className?: string;
18
+ }
19
+ /** Card de indicador. Em grid: 1 coluna no mobile, 2 para cards pequenos. */
20
+ export declare function StatCard({ label, value, change, changeLabel, inverse, icon, highlight, loading, footer, className, }: StatCardProps): import("react").JSX.Element;
@@ -0,0 +1,15 @@
1
+ import { type ReactNode } from 'react';
2
+ export interface SwitchProps {
3
+ checked?: boolean;
4
+ defaultChecked?: boolean;
5
+ onCheckedChange?: (checked: boolean) => void;
6
+ label?: ReactNode;
7
+ description?: ReactNode;
8
+ disabled?: boolean;
9
+ id?: string;
10
+ name?: string;
11
+ className?: string;
12
+ 'aria-label'?: string;
13
+ }
14
+ /** Switch único, com rótulo e descrição à esquerda e a chave à direita. */
15
+ export declare function Switch({ checked, defaultChecked, onCheckedChange, label, description, disabled, id, name, className, ...aria }: SwitchProps): import("react").JSX.Element;