@ffid-br/tailor-ui 0.6.0 → 0.7.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
@@ -35,6 +35,7 @@ A fonte Raleway (e a Roboto, para números) é carregada pelo app.
35
35
  <TailorLoader /> {/* inline: "Carregando..." */}
36
36
  <TailorLoader variant="overlay" label="Entrando" /> {/* tela inteira, bloqueia a interação */}
37
37
  <TailorLoader variant="compact" label="Salvando" /> {/* uma linha, para botão ou célula */}
38
+ <TailorLoader sucesso label="Relatório pronto" /> {/* depois de carregar: malha verde e check */}
38
39
  <TailorLoader detail="3 de 5 contas" />
39
40
  ```
40
41
 
@@ -48,8 +49,7 @@ Sempre expõe `role="status"` com o rótulo.
48
49
  <CinematicIntro
49
50
  onComplete={() => setMostrarIntro(false)}
50
51
  produto="Pilot" // opcional, aparece abaixo da marca
51
- overline="Alfaiataria digital"
52
- slogan="Tecnologia sob medida para a sua operação"
52
+ slogan="Sua operação em outro nível"
53
53
  skipLabel="Pular"
54
54
  />
55
55
  )}
@@ -209,35 +209,104 @@ Notas para quem migra:
209
209
  ### `TailorPageHeader` e a marca do cliente
210
210
 
211
211
  ```tsx
212
- import { TailorMarca, TailorPageHeader, temaDoWhitelabel } from '@ffid-br/tailor-ui';
212
+ import { TailorBrand, TailorPageHeader, themeFromWhitelabel } from '@ffid-br/tailor-ui';
213
213
 
214
- const { tema, escuro } = temaDoWhitelabel(cliente.account_info?.whitelabel);
214
+ const { theme, dark } = themeFromWhitelabel(client.account_info?.whitelabel);
215
215
 
216
- <TailorMarca tema={tema} escuro={escuro}>
216
+ <TailorBrand theme={theme} dark={dark}>
217
217
  <TailorPageHeader
218
- sobretitulo="Comercial"
219
- titulo="Leads"
220
- descricao="Quem chegou esta semana e o que falta para cada um avançar."
221
- trilha={[{ rotulo: 'Início', href: '/' }, { rotulo: 'Leads' }]}
222
- voltar={{ rotulo: 'Voltar', onClick: () => navigate(-1) }}
223
- etiqueta={<Badge>Beta</Badge>}
224
- indicadores={[{ rotulo: 'novos', valor: 128 }]}
225
- acoes={<Botao>Novo lead</Botao>}
218
+ eyebrow="Comercial"
219
+ title="Leads"
220
+ description="Quem chegou esta semana e o que falta para cada um avançar."
221
+ breadcrumbs={[{ label: 'Início', href: '/' }, { label: 'Leads' }]}
222
+ back={{ label: 'Voltar', onClick: () => navigate(-1) }}
223
+ badge={<Badge>Beta</Badge>}
224
+ stats={[{ label: 'novos', value: 128 }]}
225
+ actions={<Button>Novo lead</Button>}
226
226
  renderLink={({ href, ...p }) => <NavLink to={href} {...p} />}
227
227
  >
228
- <Abas /> {/* abaixo, na largura toda */}
228
+ <Tabs /> {/* abaixo, na largura toda */}
229
229
  </TailorPageHeader>
230
- </TailorMarca>
230
+ </TailorBrand>
231
231
  ```
232
232
 
233
233
  O visual vem só de variáveis CSS. Sem tema, vale o padrão Tailor; com tema, o cabeçalho veste a marca do cliente.
234
234
 
235
- - `--tailor-marca-*` (todas as peças que aceitam marca): `primaria`, `primaria-texto`, `texto`, `texto-suave`, `borda`, `fundo`, `fonte-titulo`, `fonte-texto`, `peso-titulo`, `caixa-titulo`, `raio`. Os padrões ficam em `:where()`, então qualquer CSS do app sobrescreve.
236
- - `--tailor-cabecalho-*` (só o cabeçalho): `fundo`, `padding`, `regua`, `tamanho-titulo`.
237
- - `TailorMarca` aplica um `TailorTema` (e o `escuro`, sob `.dark` ou `[data-theme="dark"]`) sem mexer no layout.
238
- - `temaDoWhitelabel` traduz `account_info.whitelabel` do Mongo. Ignora o azul padrão do cadastro (`#007bff`, que 107 clientes têm sem ter escolhido) e o que não for hex. A primária só vira cor de texto com contraste AA sobre o fundo. Lê também os campos propostos `colors.text_muted`, `colors.border`, `colors.dark.*`, `fonts.heading/body/heading_weight/heading_case` e `shape.radius`.
235
+ - `--tailor-brand-*` (todas as peças que aceitam marca): `primary`, `primary-text`, `text`, `text-muted`, `border`, `background`, `heading-font`, `body-font`, `heading-weight`, `heading-case`, `radius`. Os padrões ficam em `:where()`, então qualquer CSS do app sobrescreve.
236
+ - `--tailor-header-*` (só o cabeçalho): `background`, `padding`, `rule`, `title-size`.
237
+ - `TailorBrand` aplica um `TailorTheme` (e o `dark`, sob `.dark` ou `[data-theme="dark"]`) sem mexer no layout.
238
+ - `themeFromWhitelabel` traduz `account_info.whitelabel` do Mongo. Ignora o azul padrão do cadastro (`#007bff`, que 107 clientes têm sem ter escolhido) e o que não for hex. A primária só vira cor de texto com contraste AA sobre o fundo. Lê também os campos propostos `colors.text_muted`, `colors.border`, `colors.dark.*`, `fonts.heading/body/heading_weight/heading_case` e `shape.radius`.
239
239
  - A fonte do cliente é carregada pelo app (ex.: link do Google Fonts).
240
240
 
241
+ ### `TailorTable`
242
+
243
+ ```tsx
244
+ import { TailorTable, sumBy, type TailorTableColumn } from '@ffid-br/tailor-ui';
245
+
246
+ const columns: TailorTableColumn<Agent>[] = [
247
+ { key: 'id', header: 'ID', type: 'id' },
248
+ { key: 'name', header: 'Corretor', sortable: true },
249
+ { key: 'leads', header: 'Leads', type: 'number', sortable: true, total: sumBy((a) => a.leads) },
250
+ { key: 'revenue', header: 'Receita', type: 'currency', sortable: true, total: sumBy((a) => a.revenue) },
251
+ { key: 'conversion', header: 'Conversão', type: 'percent' },
252
+ { key: 'status', header: 'Status', cell: (a) => <Badge>{a.status}</Badge> },
253
+ ];
254
+
255
+ <TailorTable caption="Desempenho por corretor" columns={columns} rows={agents}
256
+ rowKey={(a) => a.id} defaultSort={{ key: 'revenue', direction: 'desc' }} pageSize={20} />
257
+ ```
258
+
259
+ Tabela de relatório. `type` formata e alinha: `number`, `currency` e `percent` (recebe fração: 0,125 = 12,5%) vão à direita com números tabulares; `date` no formato do idioma; `id` em mono; vazio vira traço.
260
+
261
+ - Ordenação: sozinha no navegador (`defaultSort`), ou controlada pelo servidor com `sort` + `onSortChange`. `aria-sort` no cabeçalho.
262
+ - Paginação: `pageSize` (navegador) ou `pagination={{ page, totalPages, onPageChange, totalRows }}` (servidor).
263
+ - `total` por coluna monta a linha de total, calculada sobre todas as linhas, não só a página. `sumBy` ajuda.
264
+ - `loading` mostra o esqueleto da tabela; `empty` troca o texto de vazio; `onRowClick` deixa a linha clicável (Enter também); `stickyHeader` prende o cabeçalho.
265
+ - Visual por `--tailor-brand-*` e `--tailor-table-*` (`font`, `padding`, `header-padding`, `header`, `sticky-top`, `top`, `background`).
266
+
267
+ ## Idioma e moeda
268
+
269
+ Os textos dos componentes ("Carregando", "Página 1 de 2", "Próxima") e a formatação de número, moeda e data seguem o `TailorLocaleProvider`. Sem ele: pt-BR e BRL.
270
+
271
+ ```tsx
272
+ <TailorLocaleProvider locale="en" currency="USD">
273
+ <App />
274
+ </TailorLocaleProvider>
275
+
276
+ // trocar um texto só
277
+ <TailorLocaleProvider locale="pt-BR" messages={{ empty: 'Nada por aqui.' }}>
278
+ ```
279
+
280
+ Vêm `pt-BR` e `en`; outro idioma usa os textos em inglês e formata números e datas no próprio idioma.
281
+
282
+ ## Retorno padrão: esqueleto, loader, sucesso e avisos
283
+
284
+ Um jeito só em todo app:
285
+
286
+ | Momento | Use |
287
+ |---|---|
288
+ | Tela ou bloco chegando | `<TailorSkeleton />` com `shape` `text`, `table`, `cards` ou `block` |
289
+ | Carregamento sem forma conhecida | `<TailorLoader />` |
290
+ | Campo obrigatório vazio ou inválido | `<TailorField label="Nome" required error="Preencha o nome."><input /></TailorField>`: borda e ponto vermelhos, mensagem ligada ao campo |
291
+ | Botão salvando | `<TailorLoader variant="compact" label="Salvando" />` dentro do botão |
292
+ | Formulário salvo | `<TailorLoader success label="Contato salvo" />` no lugar do formulário + `toast.success(...)` |
293
+ | Modal concluído (ou falhou) | `<TailorResult status="success" title="Contato salvo" onClose={close} />` dentro do painel (`position: relative`) |
294
+ | Relatório de parceiro carregando | `<TailorLoader logo={...} logoDark={...} progress={p} steps={[...]} messages={[...]} />` |
295
+ | Retorno de ação em qualquer tela | `toast.success`, `toast.error`, `toast.info` |
296
+
297
+ ```tsx
298
+ // uma vez, perto da raiz
299
+ <TailorToaster />
300
+
301
+ // em qualquer lugar, até fora de componente
302
+ toast.success('Contato salvo', { description: 'Maria Souza entrou no funil Vendas' });
303
+ toast.error('Não deu para salvar', { description: 'Sem conexão. Tente de novo.' }); // fica 8s, role="alert"
304
+ ```
305
+
306
+ `<TailorTypewriter texts={[...]} />` é o efeito do ponto escrevendo, solto, para usar onde quiser.
307
+
308
+ Num botão da cor da marca, troque a cor do ponto do loader: `className="[--tailor-loader-dot:#000]"`.
309
+
241
310
  ## Receita: transição login → app
242
311
 
243
312
  1. **No login**: marque a entrada ao enviar, desmarque se der erro e mostre o preto crescendo do botão.
@@ -308,6 +377,19 @@ Página pública: https://ffid-br.github.io/tailor-ui/ (publicada pelo workflow
308
377
 
309
378
  ## Mudanças
310
379
 
380
+ ### 0.7.0
381
+ API em inglês, pensando na internacionalização. O que saiu na 0.6.0 mudou de nome sem alias (nenhum app usava ainda); o que os apps já usam ganhou nome em inglês e o antigo segue funcionando até a 1.0.
382
+ - `TailorLocaleProvider`: idioma, moeda e textos dos componentes (`pt-BR` e `en`).
383
+ - `TailorTable`: tabela de relatório com formatação por tipo, ordenação, paginação, linha de total e marca do cliente.
384
+ - `TailorSkeleton`: esqueleto de texto, bloco, tabela e cartões com a linha verde varrendo.
385
+ - `TailorToaster` + `toast.success/error/info`: avisos da marca; o ponto escreve o título e vira check ou X.
386
+ - `TailorResult`: fim de modal ou formulário. O ponto do botão (`origin`) cresce até cobrir o painel com a cor do resultado, o título é escrito, e tudo recolhe no ponto antes de `onClose`.
387
+ - `TailorField`: rótulo, campo e mensagem; com `error`, borda e ponto vermelhos, um empurrão curto e `aria-invalid`/`aria-describedby`.
388
+ - `TailorTypewriter`: o ponto da marca como cursor; escreve, apaga e escreve a próxima frase.
389
+ - `TailorLoader`: o ponto corre uma espiral Fibonacci com rastro verde; `success`, `logo`/`logoDark`, `progress`, `steps`, `messages`; `variant="box"` e `noPadding` (os antigos `caixa` e `semRespiro` seguem valendo).
390
+ - 0.6.0 renomeada: `TailorMarca` → `TailorBrand`, `temaDoWhitelabel` → `themeFromWhitelabel`, `temaParaVariaveis` → `themeToVars`, `contraste` → `contrast`; props do `TailorPageHeader` em inglês; variáveis `--tailor-marca-*` → `--tailor-brand-*`, `--tailor-cabecalho-*` → `--tailor-header-*`.
391
+ - `CinematicIntro`: `overline` e `slogan` sem texto padrão.
392
+
311
393
  ### 0.6.0
312
394
  - `TailorPageHeader`, `TailorMarca`, `temaDoWhitelabel`: cabeçalho de página que veste a marca do cliente por variáveis CSS. Segue `--color-tailor-green`/`-ink` do app quando definidos.
313
395
  - Simulador de mascotes na página de exemplos (`#simulador`).