@celke/kole-react 0.0.0-stage → 0.2.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/LICENSE +22 -0
- package/README.md +370 -3
- package/dist/components/Abas/Abas.d.ts +55 -0
- package/dist/components/AcaoLinha/AcaoLinha.d.ts +12 -0
- package/dist/components/Acordeao/Acordeao.d.ts +42 -0
- package/dist/components/Alerta/Alerta.d.ts +39 -0
- package/dist/components/Arquivo/CampoAnexo.d.ts +27 -0
- package/dist/components/Arquivo/DialogoArquivo.d.ts +11 -0
- package/dist/components/Arquivo/Foto.d.ts +29 -0
- package/dist/components/Arquivo/VisualizadorArquivo.d.ts +12 -0
- package/dist/components/Avaliacao/Avaliacao.d.ts +30 -0
- package/dist/components/Avatar/Avatar.d.ts +12 -0
- package/dist/components/Badge/Badge.d.ts +43 -0
- package/dist/components/Balao/Balao.d.ts +30 -0
- package/dist/components/BoasVindas/BoasVindas.d.ts +19 -0
- package/dist/components/Botao/Botao.d.ts +40 -0
- package/dist/components/BotaoFechar/BotaoFechar.d.ts +10 -0
- package/dist/components/Busca/Busca.d.ts +27 -0
- package/dist/components/CabecalhoPagina/CabecalhoPagina.d.ts +21 -0
- package/dist/components/Campo/Campo.d.ts +63 -0
- package/dist/components/CampoBusca/CampoBusca.d.ts +28 -0
- package/dist/components/CampoBusca/CampoCidade.d.ts +25 -0
- package/dist/components/CampoDominio/CampoDominio.d.ts +17 -0
- package/dist/components/CampoMarcacao/CampoMarcacao.d.ts +13 -0
- package/dist/components/CampoMensagem/CampoMensagem.d.ts +31 -0
- package/dist/components/CampoSelect/CampoSelect.d.ts +25 -0
- package/dist/components/CampoSenha/CampoSenha.d.ts +16 -0
- package/dist/components/CampoTextarea/CampoTextarea.d.ts +11 -0
- package/dist/components/CampoTexto/CampoTexto.d.ts +63 -0
- package/dist/components/Card/Card.d.ts +51 -0
- package/dist/components/Carregando/Carregando.d.ts +10 -0
- package/dist/components/Carrossel/Carrossel.d.ts +33 -0
- package/dist/components/Chip/Chip.d.ts +11 -0
- package/dist/components/Citacao/Citacao.d.ts +20 -0
- package/dist/components/Confirmacao/Confirmacao.d.ts +35 -0
- package/dist/components/Conversa/Conversa.d.ts +21 -0
- package/dist/components/Detalhes/Detalhes.d.ts +12 -0
- package/dist/components/Dialogo/Dialogo.d.ts +37 -0
- package/dist/components/Dialogo/Sobreposicao.d.ts +19 -0
- package/dist/components/Dica/Dica.d.ts +15 -0
- package/dist/components/Escolha/Escolha.d.ts +14 -0
- package/dist/components/Estrutura/Estrutura.d.ts +106 -0
- package/dist/components/Filtros/Filtros.d.ts +22 -0
- package/dist/components/Form/Form.d.ts +85 -0
- package/dist/components/Girador/Girador.d.ts +15 -0
- package/dist/components/GrupoBotoes/GrupoBotoes.d.ts +56 -0
- package/dist/components/Imagem/Imagem.d.ts +40 -0
- package/dist/components/Indicador/Indicador.d.ts +29 -0
- package/dist/components/Lista/Lista.d.ts +47 -0
- package/dist/components/ListaCards/ListaCards.d.ts +28 -0
- package/dist/components/Mensagem/Mensagem.d.ts +40 -0
- package/dist/components/MenuSuspenso/MenuSuspenso.d.ts +79 -0
- package/dist/components/Paginacao/Paginacao.d.ts +13 -0
- package/dist/components/Picklist/Picklist.d.ts +28 -0
- package/dist/components/Placa/Placa.d.ts +9 -0
- package/dist/components/Preferencias/Preferencias.d.ts +43 -0
- package/dist/components/Progresso/Progresso.d.ts +42 -0
- package/dist/components/QuadroArrastavel/QuadroArrastavel.d.ts +27 -0
- package/dist/components/Recolhivel/Recolhivel.d.ts +14 -0
- package/dist/components/Referencias/Referencias.d.ts +24 -0
- package/dist/components/Skeleton/Skeleton.d.ts +8 -0
- package/dist/components/Status/Status.d.ts +10 -0
- package/dist/components/Tabela/Tabela.d.ts +57 -0
- package/dist/components/TelaErro/TelaErro.d.ts +25 -0
- package/dist/components/TelaLogin/TelaLogin.d.ts +66 -0
- package/dist/components/Toast/Toast.d.ts +62 -0
- package/dist/components/Trilha/Trilha.d.ts +60 -0
- package/dist/components/Vazio/Vazio.d.ts +12 -0
- package/dist/css.d.ts +1 -0
- package/dist/estilos.css +72 -0
- package/dist/fonts/LICENSE +93 -0
- package/dist/fonts/inter-cyrillic-ext-wght-normal.woff2 +0 -0
- package/dist/fonts/inter-cyrillic-wght-normal.woff2 +0 -0
- package/dist/fonts/inter-greek-ext-wght-normal.woff2 +0 -0
- package/dist/fonts/inter-greek-wght-normal.woff2 +0 -0
- package/dist/fonts/inter-latin-ext-wght-normal.woff2 +0 -0
- package/dist/fonts/inter-latin-wght-normal.woff2 +0 -0
- package/dist/fonts/inter-vietnamese-wght-normal.woff2 +0 -0
- package/dist/index.d.ts +81 -0
- package/dist/index.js +6938 -0
- package/dist/index.js.map +1 -0
- package/dist/tailwind.css +82 -0
- package/dist/tokens.css +407 -0
- package/dist/utils/Icone.d.ts +22 -0
- package/dist/utils/anexos.d.ts +20 -0
- package/dist/utils/constantes.d.ts +14 -0
- package/dist/utils/cx.d.ts +2 -0
- package/dist/utils/datas.d.ts +17 -0
- package/dist/utils/entidade.d.ts +19 -0
- package/dist/utils/jwt.d.ts +11 -0
- package/dist/utils/mascara.d.ts +19 -0
- package/dist/utils/picklist.d.ts +15 -0
- package/dist/utils/portal.d.ts +8 -0
- package/dist/utils/senha.d.ts +21 -0
- package/dist/utils/severidade.d.ts +7 -0
- package/dist/utils/texto.d.ts +28 -0
- package/dist/utils/tipos.d.ts +8 -0
- package/dist/utils/tiposCampo.d.ts +12 -0
- package/dist/utils/useBuscaAssincrona.d.ts +22 -0
- package/dist/utils/useCliqueFora.d.ts +3 -0
- package/dist/utils/usePosicaoFlutuante.d.ts +13 -0
- package/dist/utils/validadores.d.ts +42 -0
- package/package.json +91 -6
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/* ============================================================
|
|
2
|
+
Celke Kole — ponte com o Tailwind 4 (opcional).
|
|
3
|
+
Importe no CSS do app, DEPOIS do Tailwind:
|
|
4
|
+
|
|
5
|
+
@layer theme, base, kole, components, utilities;
|
|
6
|
+
@import 'tailwindcss';
|
|
7
|
+
@import '@celke/kole-react/tailwind.css';
|
|
8
|
+
|
|
9
|
+
- `dark:` passa a seguir o tema do kole (<html data-theme>), não o do
|
|
10
|
+
sistema — com `data-theme="system"`, segue o sistema.
|
|
11
|
+
- Os tokens viram utilitários com o MESMO nome: --pri → bg-pri,
|
|
12
|
+
--ink → text-ink, --border → border-border, --r-card → rounded-card.
|
|
13
|
+
São `var(--token)`, então trocam de tema junto com o kole.
|
|
14
|
+
============================================================ */
|
|
15
|
+
|
|
16
|
+
@custom-variant dark {
|
|
17
|
+
&:where([data-theme='dark'], [data-theme='dark'] *, .theme-dark, .theme-dark *) {
|
|
18
|
+
@slot;
|
|
19
|
+
}
|
|
20
|
+
@media (prefers-color-scheme: dark) {
|
|
21
|
+
&:where([data-theme='system'], [data-theme='system'] *) {
|
|
22
|
+
@slot;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
@theme inline {
|
|
28
|
+
/* superfícies e texto */
|
|
29
|
+
--color-bg: var(--bg);
|
|
30
|
+
--color-surface: var(--surface);
|
|
31
|
+
--color-surf-2: var(--surf-2);
|
|
32
|
+
--color-surf-3: var(--surf-3);
|
|
33
|
+
--color-surf-raised: var(--surf-raised);
|
|
34
|
+
--color-border: var(--border);
|
|
35
|
+
--color-border-2: var(--border-2);
|
|
36
|
+
--color-ink: var(--ink);
|
|
37
|
+
--color-t2: var(--t2);
|
|
38
|
+
--color-t3: var(--t3);
|
|
39
|
+
--color-t4: var(--t4);
|
|
40
|
+
--color-t5: var(--t5);
|
|
41
|
+
--color-tdis: var(--tdis);
|
|
42
|
+
|
|
43
|
+
/* marca e ação */
|
|
44
|
+
--color-pri: var(--pri);
|
|
45
|
+
--color-pri-bg: var(--pri-bg);
|
|
46
|
+
--color-pri-bd: var(--pri-bd);
|
|
47
|
+
--color-pri-ink: var(--pri-ink);
|
|
48
|
+
--color-on-pri: var(--on-pri);
|
|
49
|
+
--color-navy: var(--navy);
|
|
50
|
+
--color-acento: var(--acento);
|
|
51
|
+
--color-destaque-ink: var(--destaque-ink);
|
|
52
|
+
--color-destaque-fg: var(--destaque-fg);
|
|
53
|
+
|
|
54
|
+
/* severidades */
|
|
55
|
+
--color-ok-fg: var(--ok-fg);
|
|
56
|
+
--color-ok-bg: var(--ok-bg);
|
|
57
|
+
--color-ok-bd: var(--ok-bd);
|
|
58
|
+
--color-ok-solid: var(--ok-solid);
|
|
59
|
+
--color-warn-fg: var(--warn-fg);
|
|
60
|
+
--color-warn-bg: var(--warn-bg);
|
|
61
|
+
--color-warn-bd: var(--warn-bd);
|
|
62
|
+
--color-warn-solid: var(--warn-solid);
|
|
63
|
+
--color-err-fg: var(--err-fg);
|
|
64
|
+
--color-err-bg: var(--err-bg);
|
|
65
|
+
--color-err-bd: var(--err-bd);
|
|
66
|
+
--color-err-solid: var(--err-solid);
|
|
67
|
+
--color-info-fg: var(--info-fg);
|
|
68
|
+
--color-info-bg: var(--info-bg);
|
|
69
|
+
--color-info-bd: var(--info-bd);
|
|
70
|
+
--color-info-solid: var(--info-solid);
|
|
71
|
+
|
|
72
|
+
/* raios */
|
|
73
|
+
--radius-field: var(--r-field);
|
|
74
|
+
--radius-btn: var(--r-btn);
|
|
75
|
+
--radius-card: var(--r-card);
|
|
76
|
+
--radius-dialog: var(--r-dialog);
|
|
77
|
+
--radius-pill: var(--r-pill);
|
|
78
|
+
|
|
79
|
+
/* fontes: o font-sans/font-mono do Tailwind viram as do kole */
|
|
80
|
+
--font-sans: var(--font-ui);
|
|
81
|
+
--font-mono: var(--lp-font-mono);
|
|
82
|
+
}
|
package/dist/tokens.css
ADDED
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
@layer kole {
|
|
2
|
+
/* ============================================================
|
|
3
|
+
Celke Kole — Design Tokens
|
|
4
|
+
Fonte única de verdade. NÃO usar hex/px solto em componente.
|
|
5
|
+
Já é importado por `@celke/kole-react/estilos.css`.
|
|
6
|
+
============================================================ */
|
|
7
|
+
|
|
8
|
+
:root {
|
|
9
|
+
/* ---- Marca (paleta Celke: marinho + azul elétrico + laranja) ----
|
|
10
|
+
`--acento*` = o LARANJA de destaque (item ativo, barra de aba, spinner). */
|
|
11
|
+
--acento: #f7931e;
|
|
12
|
+
--acento-claro: #ff9a2e;
|
|
13
|
+
--acento-borda: #e07b0c; /* borda do tile do ativo (sidebar) */
|
|
14
|
+
--acento-tint: rgba(255, 154, 46, .16); /* laranja translúcido (grupo aberto, recolhido) */
|
|
15
|
+
--acento-suave: #ffb057; /* sub-item ativo (texto) — 9,5:1 sobre o marinho */
|
|
16
|
+
/* laranja como TINTA sobre superfície (ícone de ação "Editar"): o laranja
|
|
17
|
+
da marca dá 2,3:1 no branco — este tom escurecido passa dos 3:1 de ícone */
|
|
18
|
+
--destaque-ink: #d97706;
|
|
19
|
+
/* laranja como TEXTO (alerta de destaque): 4,7:1 no fundo laranja-claro e
|
|
20
|
+
5,2:1 no branco — o --destaque-ink (3:1) só serve para ícone */
|
|
21
|
+
--destaque-fg: #c2410c;
|
|
22
|
+
|
|
23
|
+
/* ---- Superfícies / texto (TEMA CLARO = padrão) ---- */
|
|
24
|
+
--bg: #f2f5fa;
|
|
25
|
+
--surface: #ffffff;
|
|
26
|
+
--surf-2: #f8fafd;
|
|
27
|
+
--surf-3: #f1f4f9;
|
|
28
|
+
/* superfície FLUTUANTE (modal/painel de select/calendário) e o degrau de
|
|
29
|
+
apoio sobre ela (faixa do footer, hover de opção). No claro empatam com
|
|
30
|
+
surface/surf-2 (a sombra recorta); no escuro sobem um degrau de LUZ —
|
|
31
|
+
elevação escura se comunica clareando, não sombreando. */
|
|
32
|
+
--surf-raised: #ffffff;
|
|
33
|
+
--surf-raised-2: #f8fafd;
|
|
34
|
+
/* chão do diálogo que carrega SEÇÕES (Form em modal). No claro é o
|
|
35
|
+
canvas da página: a seção (--surface) vira o mesmo card branco do form em
|
|
36
|
+
página. Sem ele, seção e corpo eram o mesmo branco (--surf-raised empata
|
|
37
|
+
com --surface no claro) e o grupo ficava só no contorno — mais fraco que a
|
|
38
|
+
borda dos campos dentro dele. */
|
|
39
|
+
--dlg-canvas: var(--bg);
|
|
40
|
+
--border: #e0e6ef;
|
|
41
|
+
--border-2: #c9d2e0;
|
|
42
|
+
|
|
43
|
+
--ink: #0e1726; /* texto principal */
|
|
44
|
+
--t2: #334055; /* texto forte */
|
|
45
|
+
--t3: #55627a; /* texto de apoio */
|
|
46
|
+
--t4: #7a879c; /* rótulos / secundário */
|
|
47
|
+
--t5: #9ca7b8; /* placeholder */
|
|
48
|
+
--tdis: #bfc8d5; /* desabilitado */
|
|
49
|
+
|
|
50
|
+
/* ---- Ação (azul elétrico da marca) ----
|
|
51
|
+
A cor de AÇÃO é o azul da capa, separado do marinho da sidebar: botão,
|
|
52
|
+
link, ícone e anel de foco têm cor própria e se distinguem do texto.
|
|
53
|
+
Trocar o azul de ação = trocar ESTAS linhas.
|
|
54
|
+
Contraste (medido): branco sobre --pri 5,57:1; --pri sobre --pri-bg 4,91:1. */
|
|
55
|
+
--pri: #1f5fe0;
|
|
56
|
+
--pri-bg: #eaf1ff; /* azul a ~6% — halo de foco, tile, faixa, item ativo */
|
|
57
|
+
--pri-bd: #c3d6fb; /* borda sobre --pri-bg */
|
|
58
|
+
/* `--pri-ink` = tinta sobre `--pri-bg` E o passo de HOVER do botão sólido:
|
|
59
|
+
com tinta branca, o hover ESCURECE (7,68:1). */
|
|
60
|
+
--pri-ink: #174bb8;
|
|
61
|
+
--on-pri: #ffffff; /* texto/ícone sobre o azul sólido */
|
|
62
|
+
|
|
63
|
+
/* ---- Cor institucional da marca (marinho) ----
|
|
64
|
+
`--navy` é o token semântico da marca; sidebar/thead/backdrop/avatar/form
|
|
65
|
+
derivam dele via var(--navy). */
|
|
66
|
+
--navy: #0b1a36; /* marinho da capa */
|
|
67
|
+
--brand-ink: #0b1a36; /* marinho (wordmark do sistema na topbar) */
|
|
68
|
+
|
|
69
|
+
/* ---- Sidebar / cores da sidebar (navy) (Variação D do anexo de sidebar; constante nos
|
|
70
|
+
dois temas — o sidebar é superfície escura sempre) ---- */
|
|
71
|
+
--sidebar-bg: var(--navy); /* fundo do sidebar (= --navy) */
|
|
72
|
+
--sidebar-ink-strong: #ffffff; /* texto branco (marca/ativo) */
|
|
73
|
+
--sidebar-ink: #d6e2f5; /* texto forte (item ativo/marca) */
|
|
74
|
+
--sidebar-ink-2: #a9bcda; /* texto/ícone de item inativo */
|
|
75
|
+
--sidebar-ink-muted: #6f86ad; /* rótulos de grupo / ícones 2ºrios */
|
|
76
|
+
--sidebar-tile: rgba(255, 255, 255, .06); /* tile do ícone (inativo) */
|
|
77
|
+
--sidebar-tile-hover: rgba(255, 255, 255, .12); /* tile no hover */
|
|
78
|
+
--sidebar-item-hover: rgba(255, 255, 255, .06); /* fundo do item no hover */
|
|
79
|
+
--sidebar-item-active: rgba(255, 255, 255, .04); /* fundo do item ativo */
|
|
80
|
+
--sidebar-item-open: rgba(255, 255, 255, .03); /* fundo do grupo aberto (expandido) */
|
|
81
|
+
--sidebar-item-open-c: rgba(255, 255, 255, .05); /* fundo do grupo aberto (recolhido) */
|
|
82
|
+
--sidebar-active-tile: var(--acento-claro); /* tile do ativo (laranja) */
|
|
83
|
+
--sidebar-active-icon: var(--navy); /* ícone sobre o tile laranja (8,2:1) */
|
|
84
|
+
--sidebar-active-bar: var(--acento-claro); /* barra inset 3px do ativo */
|
|
85
|
+
--sidebar-guide: rgba(255, 255, 255, .10); /* guia à esquerda do submenu */
|
|
86
|
+
--sidebar-grp-line: rgba(255, 255, 255, .07); /* linha do rótulo de grupo */
|
|
87
|
+
--sidebar-divider: rgba(255, 255, 255, .08); /* divisórias do sidebar */
|
|
88
|
+
--sidebar-edge: rgba(255, 255, 255, .08); /* aresta externa (costura com o
|
|
89
|
+
conteúdo) — no escuro navy ≈ surface e a separação
|
|
90
|
+
se comunica com LUZ, não com contraste de fundo */
|
|
91
|
+
--sidebar-flyout: #12264a; /* fundo do flyout (recolhido) */
|
|
92
|
+
--sidebar-flyout-bd: #1f3a6b; /* borda do flyout */
|
|
93
|
+
--sidebar-shadow: rgba(8, 18, 40, .28); /* sombra do sidebar flutuante */
|
|
94
|
+
--sidebar-flyout-shadow: rgba(0, 0, 0, .42); /* sombra do flyout */
|
|
95
|
+
|
|
96
|
+
/* ---- Status ----
|
|
97
|
+
-fg calibrado ≥ 4.5:1 sobre o -bg par (DoD; medido: ok 5.53, warn 5.06) */
|
|
98
|
+
--ok-fg: #136f36; --ok-bg: #e7f4ec; --ok-bd: #bfe3cd; --ok-solid: #15803d;
|
|
99
|
+
--warn-fg:#a54c08; --warn-bg:#fbeede; --warn-bd:#f3d5a8; --warn-solid:#b45309;
|
|
100
|
+
--err-fg: #b42318; --err-bg: #fbeae8; --err-bd: #f1c3bd; --err-solid: #b42318;
|
|
101
|
+
/* info = azul próprio (≠ --pri, puxado para o ciano): severidade
|
|
102
|
+
token-backed de "informativo/em análise". */
|
|
103
|
+
--info-fg:#0b6b9e; --info-bg:#e8f6fd; --info-bd:#b3e0f5; --info-solid:#0b72aa;
|
|
104
|
+
/* Tinta sobre cor SÓLIDA saturada (--navy, --err-solid dos campos inválidos):
|
|
105
|
+
branca. Vale onde o fundo é escuro nos DOIS temas. */
|
|
106
|
+
--ink-on-solid: #ffffff;
|
|
107
|
+
|
|
108
|
+
/* ---- Botão sólido por severidade: tinta + passo de hover ----
|
|
109
|
+
A premissa antiga ("branco serve nos dois temas") não se sustenta: no dark
|
|
110
|
+
os sólidos CLAREIAM, e branco sobre o verde dava 3,42:1 e sobre o âmbar
|
|
111
|
+
3,71:1 — reprovados. Aqui cada severidade declara a própria tinta, e o
|
|
112
|
+
hover é TOKEN (não `color-mix` no CSS do componente): o número volta pro
|
|
113
|
+
tokens.css e o contraste fica auditável estado a estado.
|
|
114
|
+
Direção do hover: ele se afasta da TINTA. Tinta branca → escurece; tinta
|
|
115
|
+
escura → clareia (a mesma doutrina de "no escuro, elevação é luz"). */
|
|
116
|
+
--ink-on-ok: #ffffff;
|
|
117
|
+
--ink-on-warn: #ffffff;
|
|
118
|
+
--ink-on-err: #ffffff;
|
|
119
|
+
--ink-on-info: #ffffff;
|
|
120
|
+
--ok-solid-hover: #146d3a;
|
|
121
|
+
--warn-solid-hover: #96480f;
|
|
122
|
+
--err-solid-hover: #96211b;
|
|
123
|
+
--info-solid-hover: #095f8e;
|
|
124
|
+
|
|
125
|
+
/* ---- Cabeçalho de listagem — aliases SEMÂNTICOS. Traje "marca diluída":
|
|
126
|
+
tinta da marca a 18% sobre a superfície — um degrau ACIMA do hover das
|
|
127
|
+
linhas (--pri-bg) e visivelmente mais fundo que o fundo do sistema
|
|
128
|
+
(--bg #f2f4f6; a 12% os dois quase empatavam), escala monotônica
|
|
129
|
+
cabeçalho > hover > zebra. ---- */
|
|
130
|
+
--thead-bg: color-mix(in srgb, var(--pri) 9%, var(--surface));
|
|
131
|
+
--thead-ink: var(--pri);
|
|
132
|
+
--thead-ink-2: var(--pri);
|
|
133
|
+
--thead-ink-muted: color-mix(in srgb, var(--pri) 55%, transparent);
|
|
134
|
+
/* divisória que FECHA a faixa: tinta da marca a 35%, 1px. Em --pri puro
|
|
135
|
+
(2px) era o traço mais forte da tela (12:1 contra a faixa); a 35% fica na
|
|
136
|
+
família das verticais do cabeçalho (22%), um degrau acima delas. */
|
|
137
|
+
--thead-divisor: color-mix(in srgb, var(--pri) 35%, transparent);
|
|
138
|
+
|
|
139
|
+
/* ---- Traço ---- */
|
|
140
|
+
--hairline: 0.0625rem; /* filete de 1px em rem (divisórias, bordas finas) */
|
|
141
|
+
|
|
142
|
+
/* ---- Raio ---- */
|
|
143
|
+
--r-field: 6px;
|
|
144
|
+
--r-btn: 8px; /* retângulo padrão de controles/superfícies (alerta, paginação,
|
|
145
|
+
diálogo, cards de listagem…) — botão de AÇÃO usa --r-pill
|
|
146
|
+
desde a inversão ação×situação (2026-07-17) */
|
|
147
|
+
--r-card: 9px;
|
|
148
|
+
--r-dialog:12px;
|
|
149
|
+
--r-pill: 100rem; /* "infinito": fecha pílula em QUALQUER altura — 20px fixos
|
|
150
|
+
deixavam flancos retos acima de 40px (mordeu no login, cozy
|
|
151
|
+
--d-h 44px; o clamp do CSS só reduz raio EXCEDENTE) */
|
|
152
|
+
|
|
153
|
+
/* ---- Overlays (máscara + recorte de superfície flutuante) ----
|
|
154
|
+
No claro, a máscara navy dima o conteúdo atrás e a SOMBRA recorta o
|
|
155
|
+
modal. No escuro navy ≈ fundo (a máscara não dima nada) e sombra some
|
|
156
|
+
sobre preto — a máscara vira preto e o recorte passa a ser uma hairline
|
|
157
|
+
(elevação no escuro se comunica com luz/borda, não com sombra). */
|
|
158
|
+
--backdrop: color-mix(in srgb, var(--navy) 45%, transparent);
|
|
159
|
+
--overlay-edge: transparent;
|
|
160
|
+
/* sombra padrão de superfície flutuante (painel de select/calendário,
|
|
161
|
+
toast, dialog) — semântica própria, NÃO reusar a --sidebar-shadow do layout */
|
|
162
|
+
--overlay-shadow: rgba(8, 18, 40, .28);
|
|
163
|
+
|
|
164
|
+
/* superfície da DICA (tooltip) — balão de TINTA: alto contraste e efêmero,
|
|
165
|
+
DISTINTO dos painéis flutuantes claros (select/calendário). No claro a
|
|
166
|
+
tinta é escura (texto claro). No escuro clareia um degrau (elevação = luz)
|
|
167
|
+
p/ não sumir no fundo. Contraste ≥ 4.5:1 nos dois temas (DoD). */
|
|
168
|
+
--dica-bg: #12264a;
|
|
169
|
+
--dica-ink: #f4f6f8;
|
|
170
|
+
--dica-edge: transparent;
|
|
171
|
+
|
|
172
|
+
/* ---- Camadas ----
|
|
173
|
+
Sidebar E topbar criam stacking context: os menus internos (--z-flyout)
|
|
174
|
+
valem o z da PRÓPRIA moldura contra o resto da tela; topbar < sidebar para
|
|
175
|
+
o drawer/backdrop mobile (--z-sidebar) cobrir a topbar. Conteúdo de página
|
|
176
|
+
não entra na escala: o form em página vive NO FLUXO (sticky local), não
|
|
177
|
+
como overlay.
|
|
178
|
+
Obs.: overlay do CDK (select/calendário/dialog) é `popover` — vive na TOP
|
|
179
|
+
LAYER do browser, ACIMA de toda esta escala e sem depender dela (z-index
|
|
180
|
+
de documento não ordena a top layer). Quem precisa passar por cima de um
|
|
181
|
+
modal entra na top layer também: é o que o host do toast faz (feedback é
|
|
182
|
+
a última palavra da tela e nunca nasce atrás do backdrop). Já o
|
|
183
|
+
Carregando bloqueante usa --z-dialog de propósito: é espera de
|
|
184
|
+
PÁGINA, não cobre modal aberto. O --z-toast segue como o degrau do toast
|
|
185
|
+
no documento — fallback de browser sem Popover API. */
|
|
186
|
+
--z-topbar: 25;
|
|
187
|
+
--z-sidebar: 30;
|
|
188
|
+
--z-flyout: 40;
|
|
189
|
+
--z-dialog: 70;
|
|
190
|
+
--z-toast: 1100;
|
|
191
|
+
|
|
192
|
+
/* Pouso do toast: abaixo da topbar do layout (3rem) + respiro — toast não
|
|
193
|
+
cobre sino/perfil/tema. A altura da topbar é var LOCAL da Estrutura
|
|
194
|
+
(:host); o host do toast vive na RAIZ do app e não a herda — por isso o
|
|
195
|
+
valor é token global. App com moldura própria (altura outra) sobrepõe. */
|
|
196
|
+
--toast-top: 4rem;
|
|
197
|
+
|
|
198
|
+
/* ---- Densidade (sobrescrita pelas classes .density-*) — default confortável ---- */
|
|
199
|
+
--d-h: 36px; /* altura de controle */
|
|
200
|
+
--d-px: 11px; /* padding horizontal de campo */
|
|
201
|
+
--d-bpx: 16px; /* padding horizontal de botão */
|
|
202
|
+
--d-fs: 14px; /* corpo denso (input/célula/botão) */
|
|
203
|
+
--d-row: 8px; /* padding de linha */
|
|
204
|
+
--d-gap: 13px; /* gap de grid de form */
|
|
205
|
+
--d-card:16px; /* padding de cartão */
|
|
206
|
+
|
|
207
|
+
/* ---- Tipografia ---- */
|
|
208
|
+
/* Inter (variável, do @fontsource) = fonte da interface. Mono NÃO baixa
|
|
209
|
+
fonte: o papel "código/identificador" (CPF, placa, n/total) fica com a mono
|
|
210
|
+
do SISTEMA — 1 fonte no bundle, e 0/O · 1/l seguem distinguíveis. */
|
|
211
|
+
--font-ui: 'Inter Variable', 'Inter', system-ui, -apple-system, sans-serif;
|
|
212
|
+
--lp-font-mono: ui-monospace, 'Cascadia Mono', 'Segoe UI Mono', 'Roboto Mono', monospace;
|
|
213
|
+
|
|
214
|
+
/* ---- Escala tipográfica (padronização 2026-07-06) ----
|
|
215
|
+
TEXTO SÓ NASCE DESTES TOKENS (ou de --d-fs, o corpo denso por
|
|
216
|
+
densidade). Ancorada no consenso enterprise-denso (Carbon/Fluent/
|
|
217
|
+
Ant/Fiori: corpo 14, secundário 12): PISO informativo = caption
|
|
218
|
+
(12px); micro (11px) SÓ para caps estruturais com tracking (rótulo
|
|
219
|
+
de grupo do sidebar, título de índice). Exceções documentadas fora da
|
|
220
|
+
escala: glifo de ícone (geometria), pt de impressão, display do
|
|
221
|
+
login, artwork de dado (placa Mercosul, iniciais de avatar). */
|
|
222
|
+
--fs-micro: 0.6875rem; /* 11px — caps estruturais, contadores */
|
|
223
|
+
--fs-caption: 0.75rem; /* 12px — label de campo, hint/erro, th,
|
|
224
|
+
metadados, paginação */
|
|
225
|
+
--fs-corpo-2: 0.8125rem; /* 13px — secundário denso (item de nav,
|
|
226
|
+
menus, subtítulo de card) */
|
|
227
|
+
--fs-corpo: 0.875rem; /* 14px — corpo de leitura do app */
|
|
228
|
+
--fs-titulo-secao: 1rem; /* 16px — seção de form, título de diálogo */
|
|
229
|
+
--fs-titulo: 1.25rem; /* 20px — título de página (ÚNICO) */
|
|
230
|
+
--fs-display: 1.5rem; /* 24px — números/heros de dashboards */
|
|
231
|
+
--fs-display-2: 2.125rem; /* 34px — hero (saudação do login) */
|
|
232
|
+
|
|
233
|
+
color-scheme: light;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/* ============================================================
|
|
237
|
+
TEMA ESCURO — mesmos nomes, valores dessaturados.
|
|
238
|
+
Ative com <html data-theme="dark"> (ou .theme-dark). Com
|
|
239
|
+
<html data-theme="system">, segue o modo do sistema operacional:
|
|
240
|
+
o build copia ESTE bloco para um @media (prefers-color-scheme: dark)
|
|
241
|
+
(scripts/css-kole.mjs) — mantenha só declarações aqui, sem regras aninhadas.
|
|
242
|
+
SÓ NA TELA (@media screen): papel é sempre claro — sem isso,
|
|
243
|
+
imprimir no escuro sai tinta quase-branca sobre papel branco.
|
|
244
|
+
============================================================ */
|
|
245
|
+
@media screen {
|
|
246
|
+
[data-theme="dark"], .theme-dark {
|
|
247
|
+
--bg: #070d1a;
|
|
248
|
+
--surface: #0f1729;
|
|
249
|
+
--surf-2: #141e33;
|
|
250
|
+
--surf-3: #19243c;
|
|
251
|
+
/* flutuante sobe um degrau de luz; o apoio sobe outro (hover visível) */
|
|
252
|
+
--surf-raised: #141e33;
|
|
253
|
+
--surf-raised-2: #19243c;
|
|
254
|
+
/* o chão do diálogo com seções é a própria elevação: a seção (--surface)
|
|
255
|
+
afunda um degrau nela. O --bg da página abriria um buraco no modal. */
|
|
256
|
+
--dlg-canvas: var(--surf-raised);
|
|
257
|
+
--border: #223152;
|
|
258
|
+
--border-2: #2e3f63;
|
|
259
|
+
|
|
260
|
+
--ink: #e8eef8;
|
|
261
|
+
--t2: #b4c0d4;
|
|
262
|
+
--t3: #8a98b0;
|
|
263
|
+
--t4: #6e7c95;
|
|
264
|
+
--t5: #56637b;
|
|
265
|
+
--tdis: #3f4a60;
|
|
266
|
+
|
|
267
|
+
/* No escuro o azul de ação CLAREIA para manter contraste com o fundo
|
|
268
|
+
marinho (5,59:1 sobre --surface); a tinta sobre ele fica escura (5,96:1)
|
|
269
|
+
e o hover segue clareando, coerente com "elevação = luz". */
|
|
270
|
+
--pri: #4d8dff;
|
|
271
|
+
--pri-bg: #13254a;
|
|
272
|
+
--pri-bd: #24427a;
|
|
273
|
+
--pri-ink: #77a8ff;
|
|
274
|
+
--on-pri: #06101f; /* texto/ícone sobre o azul claro do tema escuro */
|
|
275
|
+
|
|
276
|
+
--navy: #0a1428;
|
|
277
|
+
--destaque-ink: #ff9a2e; /* 8,4:1 sobre --surface */
|
|
278
|
+
--destaque-fg: #ffb057; /* 8,1:1 sobre o fundo do alerta de destaque */
|
|
279
|
+
--brand-ink: #e8eef8;
|
|
280
|
+
|
|
281
|
+
/* thead "marinho diluído": no escuro a mix da marca empataria com a própria
|
|
282
|
+
superfície (navy escuro sobre fundo escuro) — elevação aqui é LUZ, um
|
|
283
|
+
degrau acima (mesma régua dos overlays). Tintas seguem dos aliases
|
|
284
|
+
(--pri já vira claro neste tema). */
|
|
285
|
+
--thead-bg: var(--surf-raised-2);
|
|
286
|
+
|
|
287
|
+
--ok-fg:#59d98c; --ok-bg:#14301f; --ok-bd:#235639; --ok-solid:#2f9e54;
|
|
288
|
+
--warn-fg:#f0b057; --warn-bg:#2e2208; --warn-bd:#564214; --warn-solid:#c2710c;
|
|
289
|
+
--err-fg:#f47369; --err-bg:#331513; --err-bd:#5a2620; --err-solid:#cf4034;
|
|
290
|
+
--info-fg:#6fd0ff; --info-bg:#0b2233; --info-bd:#1d4a66; --info-solid:#2aa8e6;
|
|
291
|
+
|
|
292
|
+
/* Verde e âmbar CLAREIAM no escuro: branco por cima reprovava (3,42:1 e
|
|
293
|
+
3,71:1) — a tinta vira escura e o hover CLAREIA (afasta-se da tinta).
|
|
294
|
+
O vermelho continua escuro o bastante p/ tinta branca (4,73:1), então
|
|
295
|
+
segue branco e escurecendo — é a exceção, e é por isso que a tinta é
|
|
296
|
+
declarada POR severidade em vez de uma regra só. */
|
|
297
|
+
--ink-on-ok: #0d1117;
|
|
298
|
+
--ink-on-warn: #0d1117;
|
|
299
|
+
--ink-on-err: #ffffff;
|
|
300
|
+
--ink-on-info: #0d1117;
|
|
301
|
+
--ok-solid-hover: #54af73;
|
|
302
|
+
--warn-solid-hover: #cd8b38;
|
|
303
|
+
--err-solid-hover: #ac3a33;
|
|
304
|
+
--info-solid-hover: #5cbdee;
|
|
305
|
+
|
|
306
|
+
/* overlays: navy 45% não dima nada aqui (navy ≈ fundo) e sombra não
|
|
307
|
+
existe sobre preto — máscara vira preto e o recorte vira hairline */
|
|
308
|
+
--backdrop: rgb(0 0 0 / 0.6);
|
|
309
|
+
--overlay-edge: var(--border-2);
|
|
310
|
+
|
|
311
|
+
/* dica: no escuro a tinta CLAREIA (elevação = luz) p/ destacar do fundo,
|
|
312
|
+
com aresta sutil como os demais flutuantes */
|
|
313
|
+
--dica-bg: #24314d;
|
|
314
|
+
--dica-ink: #eef2f8;
|
|
315
|
+
--dica-edge: var(--border-2);
|
|
316
|
+
|
|
317
|
+
color-scheme: dark;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/* ============================================================
|
|
322
|
+
DENSIDADE — aplique a classe no layout (ex.: <body class="density-compact">)
|
|
323
|
+
============================================================ */
|
|
324
|
+
.density-compact { --d-h:30px; --d-px:9px; --d-bpx:14px; --d-fs:13px; --d-row:5px; --d-gap:10px; --d-card:12px; }
|
|
325
|
+
.density-comfortable { --d-h:36px; --d-px:11px; --d-bpx:16px; --d-fs:14px; --d-row:8px; --d-gap:13px; --d-card:16px; }
|
|
326
|
+
.density-cozy { --d-h:44px; --d-px:13px; --d-bpx:18px; --d-fs:15px; --d-row:11px; --d-gap:16px; --d-card:20px; }
|
|
327
|
+
|
|
328
|
+
/* Base recomendada */
|
|
329
|
+
body { background: var(--bg); color: var(--ink); font-family: var(--font-ui); }
|
|
330
|
+
|
|
331
|
+
/* tema "sistema": gerado do bloco escuro acima (scripts/css-kole.mjs) */
|
|
332
|
+
@media screen and (prefers-color-scheme: dark) {
|
|
333
|
+
[data-theme="system"] {
|
|
334
|
+
--bg: #070d1a;
|
|
335
|
+
--surface: #0f1729;
|
|
336
|
+
--surf-2: #141e33;
|
|
337
|
+
--surf-3: #19243c;
|
|
338
|
+
/* flutuante sobe um degrau de luz; o apoio sobe outro (hover visível) */
|
|
339
|
+
--surf-raised: #141e33;
|
|
340
|
+
--surf-raised-2: #19243c;
|
|
341
|
+
/* o chão do diálogo com seções é a própria elevação: a seção (--surface)
|
|
342
|
+
afunda um degrau nela. O --bg da página abriria um buraco no modal. */
|
|
343
|
+
--dlg-canvas: var(--surf-raised);
|
|
344
|
+
--border: #223152;
|
|
345
|
+
--border-2: #2e3f63;
|
|
346
|
+
|
|
347
|
+
--ink: #e8eef8;
|
|
348
|
+
--t2: #b4c0d4;
|
|
349
|
+
--t3: #8a98b0;
|
|
350
|
+
--t4: #6e7c95;
|
|
351
|
+
--t5: #56637b;
|
|
352
|
+
--tdis: #3f4a60;
|
|
353
|
+
|
|
354
|
+
/* No escuro o azul de ação CLAREIA para manter contraste com o fundo
|
|
355
|
+
marinho (5,59:1 sobre --surface); a tinta sobre ele fica escura (5,96:1)
|
|
356
|
+
e o hover segue clareando, coerente com "elevação = luz". */
|
|
357
|
+
--pri: #4d8dff;
|
|
358
|
+
--pri-bg: #13254a;
|
|
359
|
+
--pri-bd: #24427a;
|
|
360
|
+
--pri-ink: #77a8ff;
|
|
361
|
+
--on-pri: #06101f; /* texto/ícone sobre o azul claro do tema escuro */
|
|
362
|
+
|
|
363
|
+
--navy: #0a1428;
|
|
364
|
+
--destaque-ink: #ff9a2e; /* 8,4:1 sobre --surface */
|
|
365
|
+
--destaque-fg: #ffb057; /* 8,1:1 sobre o fundo do alerta de destaque */
|
|
366
|
+
--brand-ink: #e8eef8;
|
|
367
|
+
|
|
368
|
+
/* thead "marinho diluído": no escuro a mix da marca empataria com a própria
|
|
369
|
+
superfície (navy escuro sobre fundo escuro) — elevação aqui é LUZ, um
|
|
370
|
+
degrau acima (mesma régua dos overlays). Tintas seguem dos aliases
|
|
371
|
+
(--pri já vira claro neste tema). */
|
|
372
|
+
--thead-bg: var(--surf-raised-2);
|
|
373
|
+
|
|
374
|
+
--ok-fg:#59d98c; --ok-bg:#14301f; --ok-bd:#235639; --ok-solid:#2f9e54;
|
|
375
|
+
--warn-fg:#f0b057; --warn-bg:#2e2208; --warn-bd:#564214; --warn-solid:#c2710c;
|
|
376
|
+
--err-fg:#f47369; --err-bg:#331513; --err-bd:#5a2620; --err-solid:#cf4034;
|
|
377
|
+
--info-fg:#6fd0ff; --info-bg:#0b2233; --info-bd:#1d4a66; --info-solid:#2aa8e6;
|
|
378
|
+
|
|
379
|
+
/* Verde e âmbar CLAREIAM no escuro: branco por cima reprovava (3,42:1 e
|
|
380
|
+
3,71:1) — a tinta vira escura e o hover CLAREIA (afasta-se da tinta).
|
|
381
|
+
O vermelho continua escuro o bastante p/ tinta branca (4,73:1), então
|
|
382
|
+
segue branco e escurecendo — é a exceção, e é por isso que a tinta é
|
|
383
|
+
declarada POR severidade em vez de uma regra só. */
|
|
384
|
+
--ink-on-ok: #0d1117;
|
|
385
|
+
--ink-on-warn: #0d1117;
|
|
386
|
+
--ink-on-err: #ffffff;
|
|
387
|
+
--ink-on-info: #0d1117;
|
|
388
|
+
--ok-solid-hover: #54af73;
|
|
389
|
+
--warn-solid-hover: #cd8b38;
|
|
390
|
+
--err-solid-hover: #ac3a33;
|
|
391
|
+
--info-solid-hover: #5cbdee;
|
|
392
|
+
|
|
393
|
+
/* overlays: navy 45% não dima nada aqui (navy ≈ fundo) e sombra não
|
|
394
|
+
existe sobre preto — máscara vira preto e o recorte vira hairline */
|
|
395
|
+
--backdrop: rgb(0 0 0 / 0.6);
|
|
396
|
+
--overlay-edge: var(--border-2);
|
|
397
|
+
|
|
398
|
+
/* dica: no escuro a tinta CLAREIA (elevação = luz) p/ destacar do fundo,
|
|
399
|
+
com aresta sutil como os demais flutuantes */
|
|
400
|
+
--dica-bg: #24314d;
|
|
401
|
+
--dica-ink: #eef2f8;
|
|
402
|
+
--dica-edge: var(--border-2);
|
|
403
|
+
|
|
404
|
+
color-scheme: dark;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import { type LucideIcon } from 'lucide-react';
|
|
3
|
+
/**
|
|
4
|
+
* Ícones registrados, pelo nome do Lucide (https://lucide.dev/icons).
|
|
5
|
+
* Só estes entram no pacote; o app registra outros com `registrarIcones`
|
|
6
|
+
* ou passa o componente direto: `icone={<Rocket />}`.
|
|
7
|
+
*/
|
|
8
|
+
declare const ICONES: Record<string, LucideIcon>;
|
|
9
|
+
/** Nome de ícone registrado (ou qualquer outro, depois de `registrarIcones`). */
|
|
10
|
+
export type NomeIcone = keyof typeof ICONES | (string & {});
|
|
11
|
+
/** Ícone aceito pelos componentes: nome do Lucide (`'save'`) ou um nó React (`<Rocket />`). */
|
|
12
|
+
export type IconeProp = NomeIcone | ReactNode;
|
|
13
|
+
/** Acrescenta ícones ao registro: `registrarIcones({ rocket: Rocket })`. */
|
|
14
|
+
export declare function registrarIcones(icones: Record<string, LucideIcon>): void;
|
|
15
|
+
export interface IconeProps {
|
|
16
|
+
icone?: IconeProp;
|
|
17
|
+
className?: string;
|
|
18
|
+
/** Gira continuamente (indicador de carregamento). */
|
|
19
|
+
girar?: boolean;
|
|
20
|
+
}
|
|
21
|
+
export declare function Icone({ icone, className, girar }: IconeProps): import("react").JSX.Element | null;
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/** Metadados de anexo — serializável, sem o `File` (que vive só na sessão). */
|
|
2
|
+
export interface Anexo {
|
|
3
|
+
nome: string;
|
|
4
|
+
/** Tamanho em bytes. */
|
|
5
|
+
tamanho: number;
|
|
6
|
+
/** MIME (pode chegar vazio do navegador). */
|
|
7
|
+
tipo: string;
|
|
8
|
+
/** Endereço do arquivo já armazenado (abrir/baixar). */
|
|
9
|
+
url?: string;
|
|
10
|
+
/** Miniatura da MESMA imagem, quando o backend serve dois tamanhos. */
|
|
11
|
+
miniatura?: string;
|
|
12
|
+
}
|
|
13
|
+
/** Como o anexo pode ser EXIBIDO pelo navegador. */
|
|
14
|
+
export type TipoArquivo = 'imagem' | 'pdf' | 'video' | 'audio' | 'outro';
|
|
15
|
+
/** `1536` → `1.5 KB` · uma casa decimal abaixo de 10. */
|
|
16
|
+
export declare function formatBytes(bytes: number): string;
|
|
17
|
+
/** Classifica pelo MIME e, na falta, pela extensão do nome. */
|
|
18
|
+
export declare function tipoDeArquivo(tipo: string, nome?: string): TipoArquivo;
|
|
19
|
+
/** Nome do ícone (Lucide) do anexo, pela família do documento. */
|
|
20
|
+
export declare function iconeArquivo(tipo: string, nome?: string): string;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Opcao } from './tipos.js';
|
|
2
|
+
/** Unidade federativa: sigla + nome. */
|
|
3
|
+
export interface Uf {
|
|
4
|
+
uf: string;
|
|
5
|
+
descricao: string;
|
|
6
|
+
}
|
|
7
|
+
/** Os 26 estados + o Distrito Federal, em ordem alfabética da sigla. */
|
|
8
|
+
export declare const ESTADOS: readonly Uf[];
|
|
9
|
+
/** Só as siglas, derivadas de `ESTADOS`. */
|
|
10
|
+
export declare const UF_SIGLAS: readonly string[];
|
|
11
|
+
/** Opções prontas para select: valor = sigla, rótulo = "PR — Paraná". */
|
|
12
|
+
export declare const OPCOES_ESTADOS: readonly Opcao[];
|
|
13
|
+
/** Tipo de pessoa no formato rótulo/valor. `F`/`J` é a convenção comum dos backends. */
|
|
14
|
+
export declare const TIPOS_PESSOA: readonly Opcao<'F' | 'J'>[];
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ponte entre texto pt-BR (`dd/mm/aaaa`, `HH:mm`) e `Date`.
|
|
3
|
+
* A validação é por ida e volta: `31/04/2026` vira `null`, não 1º de maio.
|
|
4
|
+
*/
|
|
5
|
+
/** `dd/mm/aaaa` → `Date`, ou `null` se malformado ou inexistente no calendário. */
|
|
6
|
+
export declare function parseDataBr(s: string): Date | null;
|
|
7
|
+
export declare function formatDataBr(d: Date): string;
|
|
8
|
+
/** `HH:mm` → `Date` de HOJE com esse horário. */
|
|
9
|
+
export declare function parseHoraBr(s: string): Date | null;
|
|
10
|
+
export declare function formatHoraBr(d: Date): string;
|
|
11
|
+
/** `dd/mm/aaaa[ HH:mm]` → `Date` (sem hora = 00:00). */
|
|
12
|
+
export declare function parseDataHoraBr(s: string): Date | null;
|
|
13
|
+
export declare function formatDataHoraBr(d: Date): string;
|
|
14
|
+
/** ISO `aaaa-mm-dd` (valor do `CampoData`) → `dd/mm/aaaa`. Vazio se não for ISO. */
|
|
15
|
+
export declare function isoParaDataBr(iso: string): string;
|
|
16
|
+
/** `dd/mm/aaaa` → ISO `aaaa-mm-dd` (para o `CampoData`). Vazio se a data não existir. */
|
|
17
|
+
export declare function dataBrParaIso(s: string): string;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vocabulário de entidade e títulos de tela: verbo no infinitivo + substantivo
|
|
3
|
+
* (`Cadastrar veículo`), sem artigo — nunca precisa saber o gênero.
|
|
4
|
+
* Quando a regra não serve (verbo do domínio, substantivo deverbal), a
|
|
5
|
+
* entidade declara a frase INTEIRA do modo.
|
|
6
|
+
*/
|
|
7
|
+
export type Modo = 'novo' | 'editar' | 'leitura';
|
|
8
|
+
export interface Entidade {
|
|
9
|
+
/** Substantivo em minúsculas, como entra na frase (`veículo`). */
|
|
10
|
+
readonly nome: string;
|
|
11
|
+
/** Frases completas para os modos que fogem da regra (ex.: `Firmar contrato`). */
|
|
12
|
+
readonly novo?: string;
|
|
13
|
+
readonly editar?: string;
|
|
14
|
+
readonly leitura?: string;
|
|
15
|
+
}
|
|
16
|
+
/** Título da tela: a frase declarada do modo ou `Verbo nome`. */
|
|
17
|
+
export declare function tituloDeEntidade(entidade: string | Entidade, modo: Modo): string;
|
|
18
|
+
/** Troca `\ / : * ? " < > |` por `-` e junta espaços — nome seguro para "Salvar como PDF". */
|
|
19
|
+
export declare function nomeDeArquivo(texto: string): string;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Utilitários de JWT (só leitura do payload — NÃO confere assinatura). */
|
|
2
|
+
/** Decodifica o payload (Base64Url, aceita acentos); `null` se malformado. */
|
|
3
|
+
export declare function decodificarJwt<T = Record<string, unknown>>(token: string): T | null;
|
|
4
|
+
/** Data de expiração (`exp`), ou `null`. */
|
|
5
|
+
export declare function expiracaoJwt(token: string): Date | null;
|
|
6
|
+
/** `true` se inválido ou se expira em menos de `margemSegundos` (renovação proativa). */
|
|
7
|
+
export declare function jwtExpirado(token: string, margemSegundos?: number): boolean;
|
|
8
|
+
/** Limita a margem de renovação à metade da vida do token. */
|
|
9
|
+
export declare function margemRefreshJwt(token: string, margemSegundos: number): number;
|
|
10
|
+
/** Convenção de ambiente: `'#'` marca uma API não configurada. */
|
|
11
|
+
export declare function apiDefinida(url: string | null | undefined): url is string;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Máscara de digitação simples, sem dependências.
|
|
3
|
+
*
|
|
4
|
+
* Coringas do padrão: `0` dígito · `A` letra · `S` letra ou dígito · `*` qualquer.
|
|
5
|
+
* Qualquer outro caractere é literal e entra sozinho.
|
|
6
|
+
* Vários padrões (array) = o primeiro que comporta o texto digitado vence
|
|
7
|
+
* (ex.: telefone fixo × celular).
|
|
8
|
+
*/
|
|
9
|
+
export type Mascara = string | string[];
|
|
10
|
+
/** Remove os literais da máscara, deixando só o que o usuário digitou. */
|
|
11
|
+
export declare function semMascara(valor: string): string;
|
|
12
|
+
export declare function aplicarMascara(valor: string, mascara: Mascara): string;
|
|
13
|
+
export declare const MASCARAS: {
|
|
14
|
+
readonly cpf: "000.000.000-00";
|
|
15
|
+
readonly cnpj: "00.000.000/0000-00";
|
|
16
|
+
readonly cep: "00000-000";
|
|
17
|
+
readonly telefone: readonly ["(00) 0000-0000", "(00) 00000-0000"];
|
|
18
|
+
readonly placa: "AAA0S00";
|
|
19
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Valor do picklist: o par disponíveis (`fonte`) × escolhidos (`alvo`). */
|
|
2
|
+
export interface PicklistValor<T> {
|
|
3
|
+
fonte: T[];
|
|
4
|
+
alvo: T[];
|
|
5
|
+
}
|
|
6
|
+
export declare const PICKLIST_VAZIO: PicklistValor<never>;
|
|
7
|
+
export declare function normalizarPicklistValor<T>(v: PicklistValor<T> | null | undefined): PicklistValor<T>;
|
|
8
|
+
export declare function moverParaAlvo<T>(v: PicklistValor<T>, itens: readonly T[]): PicklistValor<T>;
|
|
9
|
+
export declare function moverParaFonte<T>(v: PicklistValor<T>, itens: readonly T[]): PicklistValor<T>;
|
|
10
|
+
export declare function moverTudoParaAlvo<T>(v: PicklistValor<T>, apenas?: readonly T[]): PicklistValor<T>;
|
|
11
|
+
export declare function moverTudoParaFonte<T>(v: PicklistValor<T>, apenas?: readonly T[]): PicklistValor<T>;
|
|
12
|
+
/** Move o item de `de` para `para` (índices limitados; nunca lança). */
|
|
13
|
+
export declare function reordenarLista<T>(lista: readonly T[], de: number, para: number): T[];
|
|
14
|
+
/** Filtro sem acento/caixa; termo vazio devolve tudo (cópia). */
|
|
15
|
+
export declare function filtrarItens<T>(itens: readonly T[], termo: string, texto: (item: T) => string): T[];
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* `true` só no navegador depois da hidratação. No servidor (SSR/Next.js) e no
|
|
4
|
+
* render de hidratação fica `false`, sem render extra num app só cliente.
|
|
5
|
+
*/
|
|
6
|
+
export declare function useNoNavegador(): boolean;
|
|
7
|
+
/** `createPortal(no, document.body)` que não quebra no SSR (lá não existe `document`). */
|
|
8
|
+
export declare function portal(no: ReactNode): import("react").JSX.Element;
|