@ffid-br/tailor-ui 0.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.
- package/README.md +144 -0
- package/dist/index.es.js +361 -0
- package/dist/index.umd.js +1 -0
- package/dist/style.css +76 -0
- package/dist/tailor-logo-branco.png +0 -0
- package/dist/tailor-logo.png +0 -0
- package/dist/theme.css +14 -0
- package/dist/types/cn.d.ts +2 -0
- package/dist/types/components/CinematicIntro.d.ts +21 -0
- package/dist/types/components/PontoMalha.d.ts +11 -0
- package/dist/types/components/TailorBrandMark.d.ts +23 -0
- package/dist/types/components/TailorLoader.d.ts +11 -0
- package/dist/types/components/entrada.d.ts +25 -0
- package/dist/types/index.d.ts +11 -0
- package/dist/types/logos.d.ts +4 -0
- package/package.json +67 -0
package/README.md
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# @ffid-br/tailor-ui
|
|
2
|
+
|
|
3
|
+
Primitivos de marca da Tailor.ia em React: a fita métrica de carregamento, a abertura cinematográfica, o ponto com a malha Fibonacci, a transição login → app e o lockup do produto. Antes, cada app mantinha uma cópia desses componentes. Agora todos vêm deste pacote.
|
|
4
|
+
|
|
5
|
+
## Instalação
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @ffid-br/tailor-ui
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Dependências de pares (peer): `react`, `react-dom` e `framer-motion` (10, 11 ou 12). Na prática o framer-motion 10+ exige React 18.
|
|
12
|
+
|
|
13
|
+
## Configuração no app (Tailwind v4)
|
|
14
|
+
|
|
15
|
+
No CSS de entrada do app, logo depois de `@import "tailwindcss";`:
|
|
16
|
+
|
|
17
|
+
```css
|
|
18
|
+
@import "tailwindcss";
|
|
19
|
+
@import "@ffid-br/tailor-ui/theme.css"; /* tokens: tailor-green, tailor-ink, font-tailor... */
|
|
20
|
+
@import "@ffid-br/tailor-ui/style.css"; /* animações: fita, ponto, entrada */
|
|
21
|
+
@source "../node_modules/@ffid-br/tailor-ui/dist";
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
- `theme.css` é um bloco `@theme` que cria as classes nomeadas (`bg-tailor-green`, `text-tailor-ink`, `fill-tailor-green`, `font-tailor`, `font-tailor-num`). Se o app já define esses tokens, pode pular esta linha.
|
|
25
|
+
- `style.css` traz só os tokens como variáveis CSS (`--tailor-green`...) e os keyframes dos componentes, todos respeitando `prefers-reduced-motion`.
|
|
26
|
+
- `@source` faz o Tailwind do app ler as classes usadas nos componentes. O caminho é relativo ao arquivo CSS: ajuste se ele não estiver em `src/`.
|
|
27
|
+
|
|
28
|
+
A fonte Raleway (e a Roboto, para números) é carregada pelo app.
|
|
29
|
+
|
|
30
|
+
## Componentes
|
|
31
|
+
|
|
32
|
+
### `TailorLoader`
|
|
33
|
+
|
|
34
|
+
```tsx
|
|
35
|
+
<TailorLoader /> {/* inline: "Tirando as medidas..." */}
|
|
36
|
+
<TailorLoader variant="overlay" label="Entrando" /> {/* tela inteira, bloqueia a interação */}
|
|
37
|
+
<TailorLoader variant="compact" label="Salvando" /> {/* uma linha, para botão ou célula */}
|
|
38
|
+
<TailorLoader detail="3 de 5 contas" />
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Sempre expõe `role="status"` com o rótulo.
|
|
42
|
+
|
|
43
|
+
### `CinematicIntro`
|
|
44
|
+
|
|
45
|
+
```tsx
|
|
46
|
+
<AnimatePresence>
|
|
47
|
+
{mostrarIntro && (
|
|
48
|
+
<CinematicIntro
|
|
49
|
+
onComplete={() => setMostrarIntro(false)}
|
|
50
|
+
produto="Pilot" // opcional, aparece abaixo da marca
|
|
51
|
+
overline="Alfaiataria digital"
|
|
52
|
+
slogan="Tecnologia sob medida para a sua operação"
|
|
53
|
+
skipLabel="Pular"
|
|
54
|
+
/>
|
|
55
|
+
)}
|
|
56
|
+
</AnimatePresence>
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Se o usuário pediu menos movimento, chama `onComplete` na hora e não renderiza nada. `logo` troca o wordmark (whitelabel).
|
|
60
|
+
|
|
61
|
+
### `PontoMalha`
|
|
62
|
+
|
|
63
|
+
O ponto verde piscando com a malha Fibonacci. Ocupa o contêiner posicionado mais próximo e o fundo preto fica por conta de quem usa. `malha={false}` mostra só o ponto.
|
|
64
|
+
|
|
65
|
+
```tsx
|
|
66
|
+
<div className="relative h-[377px] bg-black"><PontoMalha /></div>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### `TailorBrandMark`
|
|
70
|
+
|
|
71
|
+
Lockup: wordmark com 21px de arte e o nome do produto em 18px semibold (tailor-ink no claro, branco no escuro). As logos padrão já vêm embutidas no pacote, então nada precisa ser copiado para o `public/`.
|
|
72
|
+
|
|
73
|
+
```tsx
|
|
74
|
+
<TailorBrandMark produto="Conta" />
|
|
75
|
+
<TailorBrandMark produto="Conta" compact /> {/* barra recolhida: só a palavra */}
|
|
76
|
+
<TailorBrandMark produto="Conta" onDark /> {/* menu sempre preto, independe do tema */}
|
|
77
|
+
<TailorBrandMark produto="Pilot" logoClaro={cliente.logo} logoEscuro={cliente.logoBranca} />
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
`logoTailor` e `logoTailorBranco` também são exportados (data URI) para outros usos.
|
|
81
|
+
|
|
82
|
+
## Receita: transição login → app
|
|
83
|
+
|
|
84
|
+
1. **No login**: marque a entrada ao enviar, desmarque se der erro e mostre o preto crescendo do botão.
|
|
85
|
+
|
|
86
|
+
```tsx
|
|
87
|
+
import { EntrarOverlay, marcarEntradaPendente, limparEntradaPendente } from '@ffid-br/tailor-ui';
|
|
88
|
+
|
|
89
|
+
const botaoRef = useRef<HTMLButtonElement>(null);
|
|
90
|
+
|
|
91
|
+
async function entrar(e: React.FormEvent) {
|
|
92
|
+
e.preventDefault();
|
|
93
|
+
setEntrando(true);
|
|
94
|
+
marcarEntradaPendente();
|
|
95
|
+
try {
|
|
96
|
+
await login(email, senha);
|
|
97
|
+
navigate('/'); // o preto continua na EntradaApp
|
|
98
|
+
} catch {
|
|
99
|
+
limparEntradaPendente();
|
|
100
|
+
setEntrando(false); // o círculo recolhe
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return (
|
|
105
|
+
<>
|
|
106
|
+
<EntrarOverlay ativo={entrando} origemRef={botaoRef} />
|
|
107
|
+
<form onSubmit={entrar}>
|
|
108
|
+
...
|
|
109
|
+
<button ref={botaoRef} type="submit">Entrar</button>
|
|
110
|
+
</form>
|
|
111
|
+
</>
|
|
112
|
+
);
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
2. **No layout logado**: monte a `EntradaApp` uma vez e marque o contêiner cujos filhos devem entrar em sequência.
|
|
116
|
+
|
|
117
|
+
```tsx
|
|
118
|
+
import { EntradaApp } from '@ffid-br/tailor-ui';
|
|
119
|
+
|
|
120
|
+
<>
|
|
121
|
+
<EntradaApp />
|
|
122
|
+
<main>
|
|
123
|
+
<div data-tailor-entrada-alvo className="grid ...">
|
|
124
|
+
<Card /> <Card /> <Card />
|
|
125
|
+
</div>
|
|
126
|
+
</main>
|
|
127
|
+
</>
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
A `EntradaApp` aparece quando há entrada pendente (`sessionStorage['tailor_entrada_pendente']`) ou na primeira visita da aba. São 1,618s de preto com o ponto piscando e 0,618s recolhendo de baixo para cima. Durante esse tempo, `<html data-entrada>` faz os filhos de `[data-tailor-entrada-alvo]` subirem 21px, um depois do outro. Com menos movimento, o app aparece direto.
|
|
131
|
+
|
|
132
|
+
## Por que não embutimos Tailwind
|
|
133
|
+
|
|
134
|
+
O `style.css` deste pacote não traz preflight nem utilitários do Tailwind, e isso é proposital. No `account-selector-component` o CSS publicado levava um build inteiro do Tailwind. Esse CSS carregava depois do CSS do app, então os utilitários do pacote venciam os responsivos do host (`.hidden` derrubava `lg:flex`), redefiniam tokens e o preflight resetava a página (ver [ffid-br/account-selector-component#2](https://github.com/ffid-br/account-selector-component/issues/2)). Aqui os componentes só usam classes, e quem gera o CSS delas é o Tailwind do próprio app, via `@source`. Assim existe uma única versão do Tailwind na página.
|
|
135
|
+
|
|
136
|
+
Cores só por tokens nomeados (`tailor-green`, `tailor-ink`, `black`, `white`, `neutral-*`). Nada de `[#hex]`.
|
|
137
|
+
|
|
138
|
+
## Desenvolvimento
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
npm install
|
|
142
|
+
npm test # vitest + testing-library
|
|
143
|
+
npm run build # dist/: index.es.js, index.umd.js, types/, style.css, theme.css, logos
|
|
144
|
+
```
|