@ffid-br/tailor-ui 0.2.0 → 0.4.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/dist/style.css CHANGED
@@ -18,17 +18,19 @@
18
18
  --tailor-ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
19
19
  }
20
20
 
21
- /* TailorLoader — a fita métrica. Ciclo de φ (1,618s): o verde mede a fita e recolhe. */
22
- .tailor-fita__medida {
23
- width: 0;
24
- animation: tailor-medir 1.618s var(--tailor-ease-in-out) infinite;
21
+ /* TailorLoader — a malha pequena se desenha a partir do ponto e some, em 2φ (3,236s). */
22
+ .tailor-malha__linha {
23
+ stroke-dasharray: 1;
24
+ stroke-dashoffset: 1;
25
+ animation: tailor-malha 3.236s var(--tailor-ease-in-out) infinite;
25
26
  }
26
- @keyframes tailor-medir {
27
- 0% { width: 0; left: 0; }
28
- 61.8% { width: 100%; left: 0; }
29
- 100% { width: 0; left: 100%; }
27
+ @keyframes tailor-malha {
28
+ 0% { stroke-dashoffset: 1; opacity: 1; }
29
+ 38.2% { stroke-dashoffset: 0; opacity: 1; }
30
+ 80% { stroke-dashoffset: 0; opacity: 1; }
31
+ 100% { stroke-dashoffset: 0; opacity: 0; }
30
32
  }
31
- .tailor-fita__reticencias::after {
33
+ .tailor-loader__reticencias::after {
32
34
  content: '';
33
35
  animation: tailor-reticencias 1.618s steps(4, end) infinite;
34
36
  }
@@ -69,9 +71,42 @@
69
71
  to { opacity: 1; transform: none; }
70
72
  }
71
73
 
74
+ /* AgenteMascote — personagem 8x8 (QD-0426). Movimento em degraus, como pixel. */
75
+ .tailor-mascote { --tailor-mascote-tinta: var(--tailor-black); }
76
+ .tailor-mascote__corpo { grid-auto-rows: var(--tailor-celula, 4px); }
77
+ .tailor-mascote__pixel { width: var(--tailor-celula, 4px); height: var(--tailor-celula, 4px); }
78
+ .tailor-mascote__tinta { background: var(--tailor-mascote-tinta); }
79
+ .tailor-mascote__verde { background: var(--tailor-green); }
80
+ .tailor-mascote__selo {
81
+ min-width: 16px; height: 16px; padding: 0 4px; box-sizing: border-box;
82
+ display: flex; align-items: center; justify-content: center;
83
+ background: var(--tailor-black); color: var(--tailor-white); font-size: 10px; line-height: 1;
84
+ }
85
+ .tailor-mascote--desligado { --tailor-mascote-tinta: #999999; }
86
+ .tailor-mascote--desligado .tailor-mascote__verde { background: #999999; }
87
+ .tailor-mascote__corpo { animation: tailor-mascote-bob 1.6s steps(2, end) infinite; }
88
+ .tailor-mascote--analisando .tailor-mascote__corpo,
89
+ .tailor-mascote--subiu .tailor-mascote__corpo { animation-duration: 0.6s; }
90
+ .tailor-mascote--desligado .tailor-mascote__corpo { animation: none; }
91
+ .tailor-mascote__olho { animation: tailor-mascote-piscar 4s infinite; }
92
+ .tailor-mascote__verde { animation: tailor-mascote-pulso 2.4s steps(1, end) infinite; }
93
+ .tailor-mascote--analisando .tailor-mascote__verde { animation-duration: 1s; }
94
+ @keyframes tailor-mascote-bob { 0%, 100% { transform: none; } 50% { transform: translateY(calc(var(--tailor-celula, 4px) * -0.5)); } }
95
+ @keyframes tailor-mascote-piscar { 0%, 90%, 100% { transform: none; } 94% { transform: scaleY(0.15); } }
96
+ @keyframes tailor-mascote-pulso { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0.25; } }
97
+
98
+ /* Ponto do estado: quadrado, sempre ao lado do texto. */
99
+ .tailor-estado__ponto { display: inline-block; width: 8px; height: 8px; }
100
+ .tailor-estado__ponto--analisando { background: var(--tailor-green); }
101
+ .tailor-estado__ponto--esperando { background: #FF9033; }
102
+ .tailor-estado__ponto--feito { background: #008548; }
103
+ .tailor-estado__ponto--subiu { background: #0040FF; }
104
+ .tailor-estado__ponto--desligado { background: #999999; }
105
+
72
106
  /* Menos movimento: a informação continua, o movimento sai. */
73
107
  @media (prefers-reduced-motion: reduce) {
74
- .tailor-fita__medida { animation: none; width: 61.8%; }
75
- .tailor-fita__reticencias::after { animation: none; content: '...'; }
108
+ .tailor-malha__linha { animation: none; stroke-dashoffset: 0; }
109
+ .tailor-loader__reticencias::after { animation: none; content: '...'; }
76
110
  .tailor-ponto-pisca { animation: none; }
111
+ .tailor-mascote__corpo, .tailor-mascote__olho, .tailor-mascote__verde { animation: none; }
77
112
  }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Mapas 8x8 dos agentes (QD-0426, estilo Dots). `k` tinta, `e` olho (pisca),
3
+ * `g` o único verde do personagem (pulsa), `.` vazio. Desenho aprovado em
4
+ * https://claude.ai/artifact/HoWCZX7aFiKPEqwhXyzm5k
5
+ */
6
+ declare const MAPAS: {
7
+ readonly desk: readonly ["...gg...", "...kk...", ".kkkkkk.", ".ke..ek.", "kk....kk", ".k.kk.k.", ".kkkkkk.", "........"];
8
+ readonly pergunte: readonly [".......g", "kkkkkkk.", "k.....k.", "k.e.e.k.", "k.....k.", "kkkkkkk.", ".kk.....", ".k......"];
9
+ readonly pm: readonly ["..gggg..", "kkkkkkkk", "k......k", "k.e..e.k", "k......k", "k.kkkk.k", "k......k", "kkkkkkkk"];
10
+ readonly diretor: readonly [".kkkkkk.", ".k....k.", "kkkkkkkk", ".kk..kk.", ".k....k.", ".k.kk.k.", ".kkkkkk.", "...gg..."];
11
+ };
12
+ export type ChaveDoMascote = keyof typeof MAPAS;
13
+ export type EstadoDoMascote = 'analisando' | 'esperando' | 'feito' | 'subiu' | 'desligado';
14
+ /** Texto do estado: a cor nunca fala sozinha. */
15
+ export declare const ROTULO_DO_ESTADO: Record<EstadoDoMascote, string>;
16
+ export type AgenteMascoteProps = {
17
+ agente: ChaveDoMascote;
18
+ /** Nome exibido (a conta pode renomear). Vai no rótulo acessível. */
19
+ nome: string;
20
+ estado?: EstadoDoMascote;
21
+ /** Quantas coisas esperam a pessoa. Só aparece acima de zero. */
22
+ selo?: number;
23
+ /** Lado de cada quadradinho, em px. Padrão: 4 (32px no total). */
24
+ celula?: number;
25
+ /** Mostra o ponto e o texto do estado ao lado. */
26
+ mostrarEstado?: boolean;
27
+ className?: string;
28
+ };
29
+ /**
30
+ * O personagem do agente na grade 8x8 da marca, com o estado em ponto + texto.
31
+ * Animação em degraus (bob, piscar, pulso do verde); com menos movimento, para.
32
+ */
33
+ export declare function AgenteMascote({ agente, nome, estado, selo, celula, mostrarEstado, className, }: AgenteMascoteProps): import("react").JSX.Element;
34
+ export {};
@@ -0,0 +1,23 @@
1
+ import { default as React } from 'react';
2
+ import { ChaveDoMascote, EstadoDoMascote } from './AgenteMascote';
3
+ export type AgenteDaEquipe = {
4
+ chave: ChaveDoMascote;
5
+ nome: string;
6
+ estado?: EstadoDoMascote;
7
+ selo?: number;
8
+ /** O que a aba mostra (feed, pergunta...). Sem conteúdo, a aba diz "Em breve". */
9
+ conteudo?: React.ReactNode;
10
+ };
11
+ export type EquipeDockProps = {
12
+ /** O primeiro é o que aparece no botão flutuante. */
13
+ agentes: AgenteDaEquipe[];
14
+ abertoInicial?: boolean;
15
+ /** Título do painel. Padrão: "Equipe". */
16
+ titulo?: string;
17
+ className?: string;
18
+ };
19
+ /**
20
+ * A equipe de agentes num canto da tela: botão com o mascote principal e o selo
21
+ * de pendências somado; abre um painel com uma aba por agente.
22
+ */
23
+ export declare function EquipeDock({ agentes, abertoInicial, titulo, className }: EquipeDockProps): React.JSX.Element | null;
@@ -1,13 +1,13 @@
1
1
  import { default as React } from 'react';
2
2
  export type TailorLoaderProps = {
3
- /** Rótulo principal. Padrão: "Tirando as medidas". */
3
+ /** Rótulo principal. Padrão: "Carregando". */
4
4
  label?: string;
5
5
  /** Linha de apoio abaixo do rótulo (o que está sendo carregado, ou quanto falta). */
6
6
  detail?: string;
7
7
  /**
8
8
  * `inline`: no lugar do conteúdo. `overlay`: tela inteira, bloqueia.
9
- * `compact`: uma linha (fio curto + rótulo), para botões e listas.
10
- * `caixa`: a régua numa caixa própria de 377px, com fundo e borda — para painéis
9
+ * `compact`: uma linha (ponto + rótulo), para botões e listas.
10
+ * `caixa`: numa caixa própria de 377px, com fundo e borda — para painéis
11
11
  * estreitos e fundos com estampa (chat), onde o inline ficaria transparente.
12
12
  */
13
13
  variant?: 'inline' | 'overlay' | 'compact' | 'caixa';
@@ -15,5 +15,5 @@ export type TailorLoaderProps = {
15
15
  semRespiro?: boolean;
16
16
  className?: string;
17
17
  };
18
- /** Loader da marca (fita métrica). Sempre expõe `role="status"` com o rótulo. */
18
+ /** Loader da marca (ponto verde e malha Fibonacci). Sempre expõe `role="status"` com o rótulo. */
19
19
  export declare const TailorLoader: React.FC<TailorLoaderProps>;
@@ -11,3 +11,7 @@ export type { EntrarOverlayProps } from './components/entrada';
11
11
  export { logoTailor, logoTailorBranco } from './logos';
12
12
  export { TailorSidebar, SidebarGroup, SidebarItem, TailorUserMenu, TailorMobileBar } from './components/TailorSidebar';
13
13
  export type { TailorSidebarProps, TailorSidebarItem, TailorSidebarGrupo, TailorSidebarLinkProps, TailorSidebarRenderLink, SuperficieSidebar, BreakpointSidebar, SidebarGroupProps, SidebarItemProps, TailorUserMenuProps, TailorUserMenuAcao, TailorMobileBarProps, } from './components/TailorSidebar';
14
+ export { AgenteMascote, ROTULO_DO_ESTADO } from './components/AgenteMascote';
15
+ export type { AgenteMascoteProps, ChaveDoMascote, EstadoDoMascote } from './components/AgenteMascote';
16
+ export { EquipeDock } from './components/EquipeDock';
17
+ export type { EquipeDockProps, AgenteDaEquipe } from './components/EquipeDock';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ffid-br/tailor-ui",
3
3
  "private": false,
4
- "version": "0.2.0",
4
+ "version": "0.4.0",
5
5
  "description": "Primitivos de marca Tailor.ia em React: loader, intro, transição de login, lockup e barra lateral.",
6
6
  "type": "module",
7
7
  "main": "dist/index.umd.js",