@celke/kole-react 0.4.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -145,6 +145,7 @@ Inertia. Para as telas Blade com o mesmo layout, veja o pacote Composer
145
145
  | Dados | `Tabela`, `ListaCards`, `Paginacao`, `Indicador`/`Indicadores`, `Detalhes`, `Status`, `Chip`, `Avatar`, `Placa` |
146
146
  | Feedback | `Alerta`, `Dialogo` (central ou `lateral`), `useConfirmacao` (+ `.remover()`, `.avisar()`), `useToast`, `Vazio`, `Skeleton`, `Carregando` |
147
147
  | Conversa | `Conversa`, `Mensagem`, `CampoMensagem`, `Referencias` |
148
+ | Site público | `EstruturaSite`, `RodapeSite`, `SecaoSite`, `DestaqueSite`, `CabecalhoSecao`, `CampoPesquisa`, `CardConteudo`, `CardRecurso`, `CardDepoimento`, `CardPlano`, `FaixaNumeros`, `FaixaChamada`, `ListaNumerada`, `FiltroPilulas`, `ConteudoArtigo`, `SumarioPagina`, `Newsletter` |
148
149
  | Gráficos | `GraficoLinha`, `GraficoBarras`, `GraficoCombinado`, `GraficoDispersao`, `MapaCalor`, `Minigrafico` (e `tendencia` no `Indicador`), `regressaoLinear` |
149
150
 
150
151
  ### Conversa (chat)
@@ -219,6 +220,111 @@ export function Chat({ mensagens, gerando, enviar, parar }: ChatProps) {
219
220
  }
220
221
  ```
221
222
 
223
+ ### Site público
224
+
225
+ Para a parte aberta do sistema (site institucional, loja, portal) há uma moldura
226
+ própria, sem o menu lateral: `EstruturaSite`, com barra de aviso opcional,
227
+ cabeçalho fixo (marca, menu horizontal, botão de tema e as `acoes`), conteúdo e
228
+ `RodapeSite`. No celular, o menu vai para um painel aberto pelo botão Menu. Os
229
+ links são `<a href>` de verdade: dentro da `EstruturaSite`, os cartões, as listas e
230
+ a `Trilha` navegam pelo `aoNavegar`/`renderLink` do app, e Ctrl+clique ou o botão
231
+ do meio abrem em nova aba. A demo tem as páginas modelo de um site genérico (menu
232
+ **Site**): Home (faixa escura ou clara), Sobre, Serviços e planos, Blog, Post (sem
233
+ e com coluna lateral), Contato e as páginas legais (Termos de uso, Política de Privacidade e Política de
234
+ Cookies, com texto de exemplo a ser revisado por um advogado).
235
+
236
+ ```tsx
237
+ import { Link, Outlet, useLocation } from 'react-router-dom';
238
+ import {
239
+ Botao,
240
+ CabecalhoSecao,
241
+ CardConteudo,
242
+ CardDepoimento,
243
+ CardPlano,
244
+ CardRecurso,
245
+ DestaqueSite,
246
+ EstruturaSite,
247
+ FaixaChamada,
248
+ FaixaNumeros,
249
+ ListaNumerada,
250
+ Newsletter,
251
+ RodapeSite,
252
+ SecaoSite,
253
+ } from '@celke/kole-react';
254
+
255
+ export function LayoutSite() {
256
+ const { pathname } = useLocation();
257
+ return (
258
+ <EstruturaSite
259
+ marca={{ nome: 'Sua Marca', href: '/', logo: '/logo.svg' }}
260
+ nav={[
261
+ { rotulo: 'Home', rota: '/' },
262
+ { rotulo: 'Serviços', rota: '/servicos' },
263
+ { rotulo: 'Contato', rota: '/contato' },
264
+ ]}
265
+ rotaAtual={pathname}
266
+ renderLink={(p) => (
267
+ <Link to={p.href} className={p.className} onClick={p.onClick} aria-current={p['aria-current']}>
268
+ {p.children}
269
+ </Link>
270
+ )}
271
+ aviso={<><b>Novidade:</b> conheça a nova versão.</>}
272
+ acoes={<Botao rotulo="Fale conosco" />}
273
+ rodape={
274
+ <RodapeSite
275
+ nome="Sua Marca"
276
+ descricao="O que a empresa faz e para quem."
277
+ extra={<Newsletter aparencia="linha" rotuloBotao="Assinar" aoInscrever={async (email) => { /* envie ao servidor */ }} />}
278
+ colunas={[{ titulo: 'Navegação', links: [{ rotulo: 'Serviços', rota: '/servicos' }] }]}
279
+ copyright="© 2026 Sua Marca"
280
+ redes={[{ rotulo: 'Instagram', rota: 'https://instagram.com/suamarca' }]}
281
+ />
282
+ }
283
+ >
284
+ <Outlet />
285
+ </EstruturaSite>
286
+ );
287
+ }
288
+
289
+ export function Home() {
290
+ return (
291
+ <>
292
+ {/* aparencia="claro" centraliza o texto e põe a `midia` embaixo */}
293
+ <DestaqueSite selo="Seu slogan" titulo="Uma frase forte sobre o seu negócio." realce="negócio" lateral={<img src="/produto.png" alt="" />}>
294
+ <Botao rotulo="Começar agora" severidade="destaque" tamanho="grande" />
295
+ <FaixaNumeros aparencia="simples" itens={[{ valor: '+1.200', rotulo: 'clientes' }]} />
296
+ </DestaqueSite>
297
+ <SecaoSite>
298
+ <CabecalhoSecao sobretitulo="Diferenciais" titulo="Por que escolher a Sua Marca" />
299
+ <CardRecurso icone="shield" titulo="Seguro e confiável">Garantias e cuidados com o cliente.</CardRecurso>
300
+ <ListaNumerada itens={[{ titulo: 'Contato inicial', descricao: 'O cliente conta o que precisa.' }]} />
301
+ <FaixaNumeros itens={[{ valor: '98', sufixo: '%', rotulo: 'de satisfação' }]} />
302
+ <CardDepoimento texto="O atendimento foi rápido e o resultado veio." nome="Nome do Cliente" cargo="Cargo · Empresa" />
303
+ <CardConteudo href="/blog/post" midia={<img src="/post.jpg" alt="" />} titulo="Título do post" />
304
+ <CardPlano nome="Profissional" preco="99" periodo="/mês" itens={['Suporte prioritário']} destaque acao={<Botao rotulo="Assinar" bloco />} />
305
+ <FaixaChamada titulo="Pronto para começar?" acoes={<Botao rotulo="Solicitar contato" severidade="destaque" />} />
306
+ </SecaoSite>
307
+ </>
308
+ );
309
+ }
310
+ ```
311
+
312
+ `CardConteudo` tem cinco formatos: `vertical` (grade de posts), `destaque`,
313
+ `horizontal` (post em destaque), `compacto` e `linha` (listagem com quadro à
314
+ direita). `CardRecurso` serve para diferenciais, serviços (`formato="horizontal"`),
315
+ valores (`numero`) e canais de contato (`sobretitulo`). `ConteudoArtigo` estiliza o
316
+ texto de posts e páginas como termos de uso; HTML vindo de Markdown deve chegar
317
+ sanitizado. `SumarioPagina` lista as seções de uma página longa (pelo `id` dos
318
+ títulos), marca a seção em leitura e rola até ela sem trocar o endereço, então
319
+ funciona também em app com rotas no `#hash`. `Newsletter` confere o e-mail antes de chamar `aoInscrever`. Para
320
+ perguntas frequentes, use o `Acordeao` (`icone="mais"`).
321
+
322
+ Tokens próprios do site: `--site-largura`, `--r-site`, `--r-site-2`,
323
+ `--sombra-site`, `--fs-site-hero`, `--fs-site-titulo`, `--fs-site-secao` e os tons
324
+ sobre o marinho (`--site-escuro-*`). A cor de ação é o `--pri` de sempre: para a cor
325
+ da marca do cliente, redefina `--pri`, `--pri-ink`, `--pri-bg` e `--pri-bd` (veja
326
+ "Tema e tokens").
327
+
222
328
  ### Gráficos
223
329
 
224
330
  Desenhados em SVG próprio, sem biblioteca de gráficos. A largura
@@ -444,10 +550,17 @@ A ponte `@celke/kole-react/tailwind.css` faz duas coisas:
444
550
  `text-t3`, `border-border`, `bg-pri`, `text-ok-fg`, `bg-err-bg`,
445
551
  `rounded-card`, `rounded-pill`… Como apontam para os tokens, trocam de tema
446
552
  junto com o kole. `font-sans` e `font-mono` passam a ser as fontes do kole.
553
+ Para o site público: `max-w-site`, `rounded-site`, `rounded-site-2`,
554
+ `shadow-site`, `text-site-hero`, `text-site-titulo`, `text-site-secao` e, sobre
555
+ o marinho, `bg-navy text-site-escuro-t3`.
447
556
 
448
557
  A densidade não chega aos utilitários: `p-4` e `h-10` são fixos, só os
449
558
  componentes `lp-*` mudam com ela.
450
559
 
560
+ Vale igual para o site e para o sistema: os componentes de site (`EstruturaSite`,
561
+ `DestaqueSite`…) estão no mesmo `estilos.css`, na mesma camada `kole`, então
562
+ `<SecaoSite className="mt-8" />` funciona e o preflight não desfaz o estilo deles.
563
+
451
564
  ## Desenvolvimento
452
565
 
453
566
  ```bash
@@ -0,0 +1,18 @@
1
+ import type { ReactNode } from 'react';
2
+ export interface CabecalhoSecaoProps {
3
+ titulo: string;
4
+ /** Texto curto acima do título, em maiúsculas e laranja (ex.: "Novidades"). */
5
+ sobretitulo?: string;
6
+ descricao?: ReactNode;
7
+ /** À direita (ex.: um link "Ver todos →"). */
8
+ acao?: ReactNode;
9
+ /** Nível do título. Padrão: `2`. */
10
+ nivel?: 1 | 2 | 3;
11
+ /** `titulo` de página (maior) ou de `secao` (padrão). */
12
+ tamanho?: 'pagina' | 'secao';
13
+ /** `centro` para seções centralizadas (FAQ, planos). */
14
+ alinhamento?: 'inicio' | 'centro';
15
+ className?: string;
16
+ }
17
+ /** Título de seção ou de página do site, com sobretítulo e ação. */
18
+ export declare function CabecalhoSecao({ titulo, sobretitulo, descricao, acao, nivel, tamanho, alinhamento, className }: CabecalhoSecaoProps): import("react").JSX.Element;
@@ -0,0 +1,15 @@
1
+ export interface CampoPesquisaProps {
2
+ valor: string;
3
+ aoMudar: (valor: string) => void;
4
+ /** Enter ou o botão. Recebe o termo sem espaços nas pontas. */
5
+ aoPesquisar?: (termo: string) => void;
6
+ placeholder?: string;
7
+ /** Nome do campo para leitor de tela. Padrão: o `placeholder`. */
8
+ rotulo?: string;
9
+ rotuloBotao?: string;
10
+ /** `padrao` = pílula clara · `destaque` = pílula branca grande com botão laranja, para a faixa marinha. */
11
+ aparencia?: 'padrao' | 'destaque';
12
+ className?: string;
13
+ }
14
+ /** Busca em pílula com botão (`role="search"`), como nas faixas e listagens do site. */
15
+ export declare function CampoPesquisa({ valor, aoMudar, aoPesquisar, placeholder, rotulo, rotuloBotao, aparencia, className }: CampoPesquisaProps): import("react").JSX.Element;
@@ -0,0 +1,28 @@
1
+ import type { ReactNode } from 'react';
2
+ export interface CardConteudoProps {
3
+ titulo: string;
4
+ /**
5
+ * `vertical` = mídia 16:9 no topo (grade de posts) · `destaque` = mídia no topo e título grande ·
6
+ * `horizontal` = mídia à esquerda (post em destaque) · `compacto` = miniatura quadrada à esquerda ·
7
+ * `linha` = item de listagem, com um quadro à direita (`lateral`).
8
+ */
9
+ formato?: 'vertical' | 'destaque' | 'horizontal' | 'compacto' | 'linha';
10
+ resumo?: ReactNode;
11
+ /** Linha acima do título: `Badge`s, categoria, data. */
12
+ etiquetas?: ReactNode;
13
+ /** Imagem (ou qualquer nó) do cartão. */
14
+ midia?: ReactNode;
15
+ /** Linha miúda no fim (ex.: "Autor · 05/11/2026 · 6 min de leitura"). */
16
+ rodape?: ReactNode;
17
+ /** `linha`: quadro à direita (ex.: preço, quantidade). */
18
+ lateral?: ReactNode;
19
+ /** O cartão inteiro vira um link (o do título, esticado: o leitor de tela lê só o título). */
20
+ href?: string;
21
+ /** Sem `href`: o cartão inteiro vira um botão. */
22
+ aoClicar?: () => void;
23
+ /** Nível do título. Padrão: `3`. */
24
+ nivel?: 2 | 3 | 4;
25
+ className?: string;
26
+ }
27
+ /** Cartão de post, notícia, produto ou pessoa do site, em cinco formatos. */
28
+ export declare function CardConteudo({ titulo, formato, resumo, etiquetas, midia, rodape, lateral, href, aoClicar, nivel, className }: CardConteudoProps): import("react").JSX.Element;
@@ -0,0 +1,14 @@
1
+ export interface CardDepoimentoProps {
2
+ /** O depoimento, sem aspas (o cartão põe). */
3
+ texto: string;
4
+ nome: string;
5
+ /** Linha abaixo do nome (ex.: "Cargo · Empresa"). */
6
+ cargo?: string;
7
+ /** URL da foto. Sem ela, as iniciais do `nome`. */
8
+ foto?: string;
9
+ /** De 0 a 5 estrelas. Padrão: `5`; `0` esconde. */
10
+ nota?: number;
11
+ className?: string;
12
+ }
13
+ /** Depoimento de cliente: estrelas, citação e quem disse. */
14
+ export declare function CardDepoimento({ texto, nome, cargo, foto, nota, className }: CardDepoimentoProps): import("react").JSX.Element;
@@ -0,0 +1,22 @@
1
+ import type { ReactNode } from 'react';
2
+ export interface CardPlanoProps {
3
+ nome: string;
4
+ descricao?: string;
5
+ /** Preço já formatado, sem a moeda (ex.: "99"). */
6
+ preco: string;
7
+ /** Padrão: "R$". */
8
+ moeda?: string;
9
+ /** Depois do preço (ex.: "/mês"). */
10
+ periodo?: string;
11
+ /** O que o plano inclui. */
12
+ itens: string[];
13
+ /** Plano recomendado: cartão marinho e selo no alto. */
14
+ destaque?: boolean;
15
+ /** Texto do selo do `destaque`. Padrão: "Mais escolhido". */
16
+ rotuloDestaque?: string;
17
+ /** Botão no pé do cartão (ex.: `<Botao bloco …>`). */
18
+ acao?: ReactNode;
19
+ className?: string;
20
+ }
21
+ /** Cartão de plano ou preço: nome, valor, lista do que inclui e o botão de contratar. */
22
+ export declare function CardPlano({ nome, descricao, preco, moeda, periodo, itens, destaque, rotuloDestaque, acao, className }: CardPlanoProps): import("react").JSX.Element;
@@ -0,0 +1,22 @@
1
+ import type { ReactNode } from 'react';
2
+ import { type IconeProp } from '../../utils/Icone.js';
3
+ export interface CardRecursoProps {
4
+ titulo: ReactNode;
5
+ /** Texto de apoio. */
6
+ children?: ReactNode;
7
+ /** Ícone num quadrado azul-claro. */
8
+ icone?: IconeProp;
9
+ /** No lugar do ícone, um número em laranja (ex.: "01" nos valores da empresa). */
10
+ numero?: string;
11
+ /** Texto miúdo acima do título (ex.: "Telefone" no cartão de contato). */
12
+ sobretitulo?: string;
13
+ /** Abaixo do texto (ex.: um link "Saiba mais →"). */
14
+ acao?: ReactNode;
15
+ /** `vertical` = ícone em cima · `horizontal` = ícone à esquerda. */
16
+ formato?: 'vertical' | 'horizontal';
17
+ /** Nível do título. Padrão: `3`. */
18
+ nivel?: 2 | 3 | 4;
19
+ className?: string;
20
+ }
21
+ /** Cartão de diferencial, serviço, valor ou canal de contato: ícone (ou número), título e texto. */
22
+ export declare function CardRecurso({ titulo, children, icone, numero, sobretitulo, acao, formato, nivel, className }: CardRecursoProps): import("react").JSX.Element;
@@ -0,0 +1,12 @@
1
+ import type { ReactNode } from 'react';
2
+ export interface ConteudoArtigoProps {
3
+ /** HTML comum do texto: `p`, `h2`, `h3`, `ul`, `ol`, `blockquote`, `a`, `img`, `figure`. */
4
+ children: ReactNode;
5
+ className?: string;
6
+ }
7
+ /**
8
+ * Área de leitura de posts e páginas de texto (termos, privacidade): largura de
9
+ * cerca de 70 caracteres e o estilo dos elementos comuns. Markdown convertido em
10
+ * HTML pelo app deve chegar já sanitizado.
11
+ */
12
+ export declare function ConteudoArtigo({ children, className }: ConteudoArtigoProps): import("react").JSX.Element;
@@ -0,0 +1,27 @@
1
+ import type { ReactNode } from 'react';
2
+ export interface DestaqueSiteProps {
3
+ /** Título principal (vira o `<h1>` da página). */
4
+ titulo: string;
5
+ /** Trecho do título pintado em laranja (ex.: "melhor preço"). */
6
+ realce?: string;
7
+ /** Acima de tudo (ex.: uma `Trilha` nas páginas internas). */
8
+ topo?: ReactNode;
9
+ /** Selo acima do título (ex.: "Atualizado hoje"). */
10
+ selo?: ReactNode;
11
+ /** Texto curto acima do título, em maiúsculas (alternativa ao selo). */
12
+ sobretitulo?: string;
13
+ descricao?: ReactNode;
14
+ /** Abaixo do texto: normalmente um `CampoPesquisa aparencia="destaque"` ou botões. */
15
+ children?: ReactNode;
16
+ /** `escuro` (padrão) = faixa marinha com coluna à direita · `claro` = fundo claro, texto centralizado e `midia` embaixo. */
17
+ aparencia?: 'escuro' | 'claro';
18
+ /** Coluna da direita, no `escuro` (ex.: imagem do produto). */
19
+ lateral?: ReactNode;
20
+ /** Imagem larga abaixo do texto, no `claro` (cantos de cima arredondados, encostada na borda de baixo). */
21
+ midia?: ReactNode;
22
+ /** Nível do título. Padrão: `1`. */
23
+ nivel?: 1 | 2;
24
+ className?: string;
25
+ }
26
+ /** Faixa marinha de abertura (hero): selo, título com realce, texto, busca e uma coluna livre. */
27
+ export declare function DestaqueSite({ topo, titulo, realce, selo, sobretitulo, descricao, children, aparencia, lateral, midia, nivel, className }: DestaqueSiteProps): import("react").JSX.Element;
@@ -0,0 +1,60 @@
1
+ import { type ReactNode } from 'react';
2
+ import type { Marca, PropsLink } from '../Estrutura/Estrutura.js';
3
+ export interface ItemSite {
4
+ rotulo: string;
5
+ rota: string;
6
+ }
7
+ export interface EstruturaSiteProps {
8
+ marca: Marca;
9
+ /** Itens do menu horizontal (no celular, vão para o painel do botão Menu). */
10
+ nav: ItemSite[];
11
+ /**
12
+ * Rota atual: marca o item ativo (`/blog` também vale para `/blog/post`; vence a rota mais
13
+ * longa). A página inicial (o `href` da marca) só é marcada nela mesma.
14
+ */
15
+ rotaAtual?: string;
16
+ /** Navegação do roteador do app. Ctrl+clique e o botão do meio continuam abrindo em nova aba. */
17
+ aoNavegar?: (rota: string) => void;
18
+ /** Link do roteador (ex.: o `Link` do React Router); recebe `href`, `className`, `onClick` e `children`. */
19
+ renderLink?: (props: PropsLink) => ReactNode;
20
+ /** À direita do menu (ex.: "Entrar" e "Criar conta"). No celular, também vão para o painel. */
21
+ acoes?: ReactNode;
22
+ /** Botão de tema claro/escuro (precisa do `ProvedorUi`). Padrão: `true`. */
23
+ alternarTema?: boolean;
24
+ /** Barra marinha fina acima do cabeçalho (novidade, telefone, e-mail). Some no celular a parte da direita. */
25
+ aviso?: ReactNode;
26
+ /** À direita da barra de aviso (ex.: telefone e e-mail). */
27
+ avisoLateral?: ReactNode;
28
+ /** Normalmente um `RodapeSite`. */
29
+ rodape?: ReactNode;
30
+ children: ReactNode;
31
+ className?: string;
32
+ }
33
+ /**
34
+ * Moldura de site público: cabeçalho fixo com marca, menu horizontal e ações,
35
+ * conteúdo e rodapé. Para sistemas internos, use a `Estrutura`.
36
+ */
37
+ export declare function EstruturaSite({ marca, nav, rotaAtual, aoNavegar, renderLink, acoes, alternarTema, aviso, avisoLateral, rodape, children, className }: EstruturaSiteProps): import("react").JSX.Element;
38
+ export interface LinkRodape {
39
+ rotulo: string;
40
+ rota: string;
41
+ }
42
+ export interface ColunaRodape {
43
+ titulo: string;
44
+ links: LinkRodape[];
45
+ }
46
+ export interface RodapeSiteProps {
47
+ /** Nome em destaque na primeira coluna. */
48
+ nome: string;
49
+ descricao?: ReactNode;
50
+ colunas?: ColunaRodape[];
51
+ /** Abaixo da descrição (ex.: um `Newsletter aparencia="linha"`). A coluna da marca fica mais larga. */
52
+ extra?: ReactNode;
53
+ /** Linha de baixo (ex.: "© 2026 Empresa"). */
54
+ copyright?: ReactNode;
55
+ /** À direita da linha de baixo (ex.: links das redes sociais). */
56
+ redes?: LinkRodape[];
57
+ className?: string;
58
+ }
59
+ /** Rodapé marinho do site: marca, colunas de links e a linha de direitos. */
60
+ export declare function RodapeSite({ nome, descricao, colunas, extra, copyright, redes, className }: RodapeSiteProps): import("react").JSX.Element;
@@ -0,0 +1,14 @@
1
+ import type { ReactNode } from 'react';
2
+ export interface FaixaChamadaProps {
3
+ titulo: string;
4
+ descricao?: ReactNode;
5
+ /** Botões à direita. */
6
+ acoes?: ReactNode;
7
+ /** `pri` = azul da marca (padrão) · `escuro` = marinho. */
8
+ cor?: 'pri' | 'escuro';
9
+ /** Nível do título. Padrão: `2`. */
10
+ nivel?: 2 | 3;
11
+ className?: string;
12
+ }
13
+ /** Faixa de chamada para ação ("Pronto para começar?"), com botões. */
14
+ export declare function FaixaChamada({ titulo, descricao, acoes, cor, nivel, className }: FaixaChamadaProps): import("react").JSX.Element;
@@ -0,0 +1,20 @@
1
+ export interface NumeroSite {
2
+ /** O número já formatado (ex.: "1.200", "4,9/5"). */
3
+ valor: string;
4
+ /** Em laranja, logo depois (ex.: "+", "%", "h"). */
5
+ sufixo?: string;
6
+ rotulo: string;
7
+ }
8
+ export interface FaixaNumerosProps {
9
+ itens: NumeroSite[];
10
+ /**
11
+ * `faixa` = bloco marinho arredondado, números grandes · `cartoes` = um cartão claro por número ·
12
+ * `simples` = só os números, para ficar sobre a faixa de abertura.
13
+ */
14
+ aparencia?: 'faixa' | 'cartoes' | 'simples';
15
+ /** Nome da lista para leitor de tela (ex.: "Números da empresa"). */
16
+ rotulo?: string;
17
+ className?: string;
18
+ }
19
+ /** Números de destaque (clientes, satisfação, anos de mercado). */
20
+ export declare function FaixaNumeros({ itens, aparencia, rotulo, className }: FaixaNumerosProps): import("react").JSX.Element;
@@ -0,0 +1,17 @@
1
+ export interface OpcaoFiltroPilulas<V extends string = string> {
2
+ valor: V;
3
+ rotulo: string;
4
+ }
5
+ export interface FiltroPilulasProps<V extends string = string> {
6
+ opcoes: OpcaoFiltroPilulas<V>[];
7
+ valor: V;
8
+ aoMudar: (valor: V) => void;
9
+ /** Nome do filtro para leitor de tela (ex.: "Categoria"). */
10
+ rotulo: string;
11
+ /** `quebrar` = várias linhas (padrão) · `rolar` = uma linha só, rolando para o lado. */
12
+ disposicao?: 'quebrar' | 'rolar';
13
+ alinhamento?: 'inicio' | 'centro';
14
+ className?: string;
15
+ }
16
+ /** Filtro de uma escolha só em pílulas (categorias, regiões, UFs). A escolhida fica escura. */
17
+ export declare function FiltroPilulas<V extends string = string>({ opcoes, valor, aoMudar, rotulo, disposicao, alinhamento, className }: FiltroPilulasProps<V>): import("react").JSX.Element;
@@ -0,0 +1,21 @@
1
+ import type { ReactNode } from 'react';
2
+ export interface ItemListaNumerada {
3
+ /** Chave do item (padrão: o título). */
4
+ id?: string;
5
+ titulo: string;
6
+ /** Linha miúda abaixo (ex.: data, quantidade). */
7
+ detalhe?: ReactNode;
8
+ /** Texto abaixo do título, em tamanho de leitura (ex.: passos de "Como funciona"). */
9
+ descricao?: ReactNode;
10
+ href?: string;
11
+ }
12
+ export interface ListaNumeradaProps {
13
+ itens: ItemListaNumerada[];
14
+ /** `padrao` = números grandes (ranking da semana) · `compacto` = para colunas laterais. */
15
+ tamanho?: 'padrao' | 'compacto';
16
+ /** Nome da lista para leitor de tela. */
17
+ rotulo?: string;
18
+ className?: string;
19
+ }
20
+ /** Lista numerada (01, 02…) com os números em laranja: mais lidos, ranking, passos de um processo. */
21
+ export declare function ListaNumerada({ itens, tamanho, rotulo, className }: ListaNumeradaProps): import("react").JSX.Element;
@@ -0,0 +1,16 @@
1
+ export interface NewsletterProps {
2
+ /** Recebe o e-mail já conferido. Pode devolver uma Promise (o botão espera). */
3
+ aoInscrever: (email: string) => void | Promise<void>;
4
+ /** Com `aparencia="cartao"`: título do cartão. */
5
+ titulo?: string;
6
+ descricao?: string;
7
+ placeholder?: string;
8
+ rotuloBotao?: string;
9
+ /** Mensagem depois de inscrever. */
10
+ mensagemSucesso?: string;
11
+ /** `cartao` = bloco marinho com título (coluna lateral) · `linha` = campo e botão numa pílula (rodapé). */
12
+ aparencia?: 'cartao' | 'linha';
13
+ className?: string;
14
+ }
15
+ /** Inscrição por e-mail (newsletter), para fundo marinho: rodapé ou coluna lateral. */
16
+ export declare function Newsletter({ aoInscrever, titulo, descricao, placeholder, rotuloBotao, mensagemSucesso, aparencia, className, }: NewsletterProps): import("react").JSX.Element;
@@ -0,0 +1,15 @@
1
+ import type { ReactNode } from 'react';
2
+ export interface SecaoSiteProps {
3
+ children: ReactNode;
4
+ /** `padrao` = fundo da página · `superficie` = faixa branca com linha embaixo · `escuro` = faixa marinha. */
5
+ fundo?: 'padrao' | 'superficie' | 'escuro';
6
+ /** `estreita` = 55rem, para FAQ, texto e formulários centralizados. Padrão: `padrao` (largura do site). */
7
+ largura?: 'padrao' | 'estreita';
8
+ /** Espaço acima e abaixo. Padrão: `medio`. */
9
+ espaco?: 'compacto' | 'medio' | 'amplo';
10
+ /** Nome da região para leitor de tela (vira um `<section>` com `aria-label`). */
11
+ rotulo?: string;
12
+ className?: string;
13
+ }
14
+ /** Faixa do site com o conteúdo centralizado na largura `--site-largura`. */
15
+ export declare function SecaoSite({ children, fundo, largura, espaco, rotulo, className }: SecaoSiteProps): import("react").JSX.Element;
@@ -0,0 +1,17 @@
1
+ export interface ItemSumario {
2
+ /** `id` do título da seção na página. */
3
+ id: string;
4
+ rotulo: string;
5
+ }
6
+ export interface SumarioPaginaProps {
7
+ itens: ItemSumario[];
8
+ /** Padrão: "Nesta página". */
9
+ titulo?: string;
10
+ className?: string;
11
+ }
12
+ /**
13
+ * Sumário de página longa (termos, política, documentação): links para as
14
+ * seções, com a seção em leitura marcada. Rola até a seção sem trocar o
15
+ * endereço, então funciona também em app com rotas no `#hash`.
16
+ */
17
+ export declare function SumarioPagina({ itens, titulo, className }: SumarioPaginaProps): import("react").JSX.Element;
@@ -0,0 +1,18 @@
1
+ import { type ReactNode } from 'react';
2
+ import type { PropsLink } from '../Estrutura/Estrutura.js';
3
+ export interface ContextoLinkSite {
4
+ aoNavegar?: (rota: string) => void;
5
+ renderLink?: (props: PropsLink) => ReactNode;
6
+ /** Chamado depois de cada navegação (a `EstruturaSite` fecha o menu do celular). */
7
+ aoNavegou?: () => void;
8
+ }
9
+ export declare const ProvedorLinkSite: import("react").Provider<ContextoLinkSite>;
10
+ /**
11
+ * Link de verdade (`<a href>`) que, dentro da `EstruturaSite`, navega pelo roteador
12
+ * do app (`aoNavegar` ou `renderLink`). Fora dela, é um link comum.
13
+ */
14
+ export declare function useLinkSite(): (href: string, conteudo: ReactNode, className: string, extra?: {
15
+ atual?: boolean;
16
+ aoClicar?: () => void;
17
+ rotulo?: string;
18
+ }) => string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | import("react").JSX.Element | null | undefined;