@ffid-br/tailor-ui 0.1.2 → 0.3.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
@@ -1,6 +1,6 @@
1
1
  # @ffid-br/tailor-ui
2
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.
3
+ Primitivos de marca da Tailor.ia em React: o loader com o ponto verde e a malha Fibonacci, a abertura cinematográfica, o ponto com a malha Fibonacci, a transição login → app, o lockup do produto e a barra lateral padrão dos apps. Antes, cada app mantinha uma cópia desses componentes. Agora todos vêm deste pacote.
4
4
 
5
5
  ## Instalação
6
6
 
@@ -17,7 +17,7 @@ No CSS de entrada do app, logo depois de `@import "tailwindcss";`:
17
17
  ```css
18
18
  @import "tailwindcss";
19
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 */
20
+ @import "@ffid-br/tailor-ui/style.css"; /* animações: loader, ponto, entrada */
21
21
  @source "../node_modules/@ffid-br/tailor-ui/dist";
22
22
  ```
23
23
 
@@ -32,7 +32,7 @@ A fonte Raleway (e a Roboto, para números) é carregada pelo app.
32
32
  ### `TailorLoader`
33
33
 
34
34
  ```tsx
35
- <TailorLoader /> {/* inline: "Tirando as medidas..." */}
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
38
  <TailorLoader detail="3 de 5 contas" />
@@ -79,6 +79,93 @@ Lockup: wordmark com 21px de arte e o nome do produto em 18px semibold (tailor-i
79
79
 
80
80
  `logoTailor` e `logoTailorBranco` também são exportados (data URI) para outros usos.
81
81
 
82
+ ### `TailorSidebar`
83
+
84
+ Barra lateral padrão do accounts, CRM, BI e Pilot. **Uma lista de itens desenha as duas formas**: a barra fixa a partir do breakpoint (expandida com 288px ou recolhida em trilho de 80px, só ícones) e a gaveta no celular. O app não mantém mais uma nav para o `<aside>` e outra para o drawer.
85
+
86
+ - Estrutura: marca + recolher (55px) · seletor de contas + apps · grupos · `rodape` · "Powered by" opcional.
87
+ - Item com 34px de altura (44px na gaveta, alvo de toque), ícone de linha 18px (traço 1,5), texto 14px. Ativo: fundo `neutral-100`, barra verde de 2px à esquerda e texto preto; no escuro, `white/10` e texto branco. Ícone não ganha cor.
88
+ - Badge: chip quadrado preto (branco no escuro) com números tabulares; `badgeTom: 'alerta'` pinta de vermelho. Acima de 99 vira `99+`. No trilho vira um ponto e a contagem vai para o `aria-label`.
89
+ - `filhos`: o item pai vira um botão que abre e fecha a lista (abre sozinho se um filho está ativo). Quer link para a página do pai? Ponha um filho "Visão geral". No trilho, clicar no pai expande a barra.
90
+ - `superficie`: `auto` (branco no claro, `neutral-950` no escuro), `clara` ou `escura` (preto fixo, para o admin do accounts).
91
+ - A barra fixa usa `max-lg:hidden!` e a gaveta/barra do celular `lg:hidden!` (ou `md`, via `breakpoint`). O `!` é de propósito: o CSS do account-selector-component carrega depois do app e o `.flex` dele venceria um `hidden` comum.
92
+ - O `<aside>` é `sticky top-0 h-screen`: funciona num layout `flex` com a página ao lado. Quem usa `fixed` + `ml-72` passa a posição por `className`.
93
+ - Acessibilidade: `<nav aria-label>`, `aria-current="page"` no ativo, `title` + `aria-label` no trilho, anel de foco `tailor-green/60`, `motion-reduce`. A gaveta é um `role="dialog"`: prende o foco, fecha no Esc, no fundo (preto 55%) e ao navegar, e devolve o foco a quem abriu.
94
+
95
+ ```tsx
96
+ import { NavLink, useLocation } from 'react-router-dom';
97
+ import { Home, MessageCircle, LayoutDashboard, LogOut, UserCog } from 'lucide-react';
98
+ import { TailorSidebar, TailorMobileBar, TailorUserMenu, type TailorSidebarGrupo } from '@ffid-br/tailor-ui';
99
+
100
+ function Layout() {
101
+ const { pathname } = useLocation();
102
+ const [aberto, setAberto] = useState(false);
103
+ const [recolhido, setRecolhido] = useState(() => localStorage.getItem('sidebar_collapsed') === '1');
104
+ const recolher = (v: boolean) => { setRecolhido(v); localStorage.setItem('sidebar_collapsed', v ? '1' : '0'); };
105
+
106
+ const grupos: TailorSidebarGrupo[] = [
107
+ {
108
+ rotulo: 'Geral',
109
+ itens: [
110
+ { id: 'inicio', rotulo: 'Início', icone: Home, href: '/', ativo: pathname === '/' },
111
+ { id: 'msg', rotulo: 'Mensagens', icone: MessageCircle, href: '/mensagens', ativo: pathname.startsWith('/mensagens'), badge: pendentes },
112
+ {
113
+ id: 'painel', rotulo: 'Painel', icone: LayoutDashboard,
114
+ filhos: [{ id: 'painel-geral', rotulo: 'Visão geral', icone: LayoutDashboard, href: '/painel', ativo: pathname === '/painel' }],
115
+ },
116
+ ],
117
+ },
118
+ ];
119
+
120
+ return (
121
+ <div className="flex min-h-screen">
122
+ <TailorSidebar
123
+ produto="Conta"
124
+ logoClaro={logos?.claro} // whitelabel: substitui o wordmark...
125
+ logoEscuro={logos?.escuro}
126
+ poweredBy={Boolean(logos)} // ...e aí o "Powered by Tailor.ia" aparece
127
+ superficie={pathname.startsWith('/admin') ? 'escura' : 'auto'}
128
+ grupos={grupos}
129
+ accountSelector={<AccountSelector {...} />}
130
+ apps={<AppLauncher />}
131
+ recolhido={recolhido}
132
+ onRecolher={recolher}
133
+ aberto={aberto}
134
+ onFechar={() => setAberto(false)}
135
+ renderLink={(item, props) => <NavLink to={item.href!} {...props} />}
136
+ rodape={
137
+ <TailorUserMenu
138
+ nome={usuario.nome}
139
+ detalhe={usuario.email}
140
+ papel="Administrador"
141
+ avatarUrl={usuario.avatar}
142
+ acoes={[
143
+ { rotulo: 'Meu perfil', icone: UserCog, href: '/perfil' },
144
+ { rotulo: 'Sair', icone: LogOut, tom: 'perigo', onSelect: sair },
145
+ ]}
146
+ >
147
+ <ThemeToggle /> {/* conteúdo livre: tema, notificações push */}
148
+ </TailorUserMenu>
149
+ }
150
+ />
151
+ <div className="min-w-0 flex-1">
152
+ <TailorMobileBar produto="Conta" onAbrirMenu={() => setAberto(true)} menuAberto={aberto} apps={<AppLauncher />} />
153
+ <main>...</main>
154
+ </div>
155
+ </div>
156
+ );
157
+ }
158
+ ```
159
+
160
+ Notas para quem migra:
161
+
162
+ - `renderLink` recebe `className`, `children`, `aria-current`, `onClick` (fecha a gaveta) e, no trilho, `title`/`aria-label`. Repasse tudo. `ativo` continua vindo do app (ele sabe a regra de rota, ex.: `startsWith`). Sem `renderLink`, sai um `<a href>`.
163
+ - Item sem `href` e com `onSelect` vira botão de ação. `desabilitado` mostra o item apagado e sem clique (o "Em breve" do Pilot).
164
+ - Casos especiais (a sub-nav do Orchestrator, o aviso de status) entram como `grupos` próprios ou como `children`, montados com `SidebarGroup` e `SidebarItem`, que também são exportados.
165
+ - `marca` troca o lockup inteiro (ex.: logo do cliente com link para o início). `marcaRecolhida` aparece no trilho, acima do botão de expandir.
166
+ - Sem `onRecolher`, o botão de recolher não aparece.
167
+ - As classes novas estão no `dist`, então o `@source` da configuração já as cobre.
168
+
82
169
  ## Receita: transição login → app
83
170
 
84
171
  1. **No login**: marque a entrada ao enviar, desmarque se der erro e mostre o preto crescendo do botão.
@@ -146,6 +233,12 @@ npm run build # dist/: index.es.js, index.umd.js, types/, style.css, theme.cs
146
233
 
147
234
  ## Mudanças
148
235
 
236
+ ### 0.2.0
237
+ - `TailorSidebar`: barra lateral padrão (marca, seletor de contas + apps, grupos, badges, subitens, trilho recolhido, gaveta no celular com a mesma lista, superfície `auto`/`clara`/`escura`, `renderLink` para o roteador).
238
+ - `TailorUserMenu`: menu do usuário para o rodapé, com conteúdo livre (tema) e ações.
239
+ - `TailorMobileBar`: barra do topo no celular (hambúrguer, marca, apps).
240
+ - `SidebarGroup` e `SidebarItem` exportados para montar navs especiais.
241
+
149
242
  ### 0.1.2
150
243
  - `EntradaApp` toca sempre depois de um login e só depois de um login (marca pendente). Saiu o disparo na primeira visita da aba: reload e link direto entram sem o preto. A `CinematicIntro` segue sendo uma vez só, por cookie no app.
151
244