Pular para o conteúdo principal

Status: Approved · v2 · SPEC-UX-COMPONENTS-001

depends_on: SPEC-UX-TOKENS-001, SPEC-UX-VISUAL-001, SPEC-UX-STATES-001, SPEC-UX-A11Y-001

used_by: IS-MVP-17.2, IS-MVP-17.3, IS-MVP-17.4, IS-MVP-19.2

Catálogo de componentes v2 — redesign

Contrato visual e comportamental do capítulo 02 de design/RaizFC Book.dc.html para implementação em packages/ui.

1. Regras transversais

  • Componentes recebem dados/handlers por props e não fazem fetch, autorização ou regra de domínio.
  • Inter é a fonte de interface. Bebas Neue entra apenas em placar, número de stat e título de impacto.
  • Todos os controles têm touch target mínimo 44×44 px, nome acessível, foco visível de 2 px e paridade nos quatro modos.
  • Botões e chips de filtro usam radius 10. Pill fica restrito a switch/toggle, avatar circular e badge de status aprovado.
  • Hooks/adapters de medição são declarados antes de retornos condicionais; componentes não fazem fetch nem importam fixture.
  • Cor é acompanhada por texto/ícone. disabled não depende apenas de opacidade. loading preserva dimensão e bloqueia duplo acionamento.
  • Hover só existe em dispositivo apontador. Focus e teclado não dependem do hover. Reduced motion remove animação decorativa.
  • Props abaixo são conceituais; nomes podem se adaptar à convenção do package sem perder semântica.

2. Botões

  • Anatomia: container 48 px/radius 10, label Inter 650/14, ícone opcional, indicador de loading.
  • Props: label, variant, size, icon, iconPosition, disabled, loading, type, onPress, ariaLabel.
  • Variantes: primary, secondary, tertiary, danger; icon-only somente com nome acessível.
  • Estados: default; hover com contraste de superfície; focus ring 2 px; disabled sem ação e label legível; loading mantém largura, label acessível e substitui/acompanha ícone.
  • Tokens: primary, on-primary, danger, surface, text, text-muted, border, control-height, radius-form.
  • Aceite: não existe primary verde; danger não é usado para ação comum; teclado/Enter/Space funcionam; loading impede duplo submit.

3. Inputs e lista de sugestões

  • Anatomia: label persistente, control 48 px, valor/placeholder, ícone/affordance opcional, helper/erro e lista contextual.
  • Props: label, value, placeholder, helperText, error, required, disabled, loading, leading, trailing, suggestions, onChange, onSelect.
  • Variantes: texto, busca, seleção/autocomplete; lista com identidade + metadata.
  • Estados: default; hover de borda; focus/expanded com borda 2 px primary; disabled legível; loading sem apagar valor; invalid com mensagem e associação acessível.
  • Tokens: background, text, text-muted, border, primary, danger, surface, control-height, radius-form.
  • Aceite: placeholder nunca substitui label; erro fica junto do campo; sugestões usam teclado/ARIA equivalente; valor não some em falha.

4. Chips de estado esportivo

  • Anatomia: pill, label curta e ícone opcional; máximo prático de dois em componente compacto.
  • Props: status, label, icon, emphasis, tooltip.
  • Variantes: vitória/validada, empate/aguardando, derrota/contestada, agendada, provisório, papel/permissão neutro.
  • Estados: default; hover/focus somente se acionável; disabled mantém significado; loading não se aplica — skeleton ocupa seu espaço quando o status não chegou.
  • Tokens: success, accent, danger, chip-overlay, text-muted, border, radius-pill.
  • Aceite: Aguardando validação, Contestada, Validada e Provisório têm texto explícito; cor nunca é o único canal.

Chips de filtro ou ação não usam este componente; usam controle com radius 10 e estado pressionado acessível.

4.1 Primitives editoriais do redesign

  • Section e SectionTitle são a única estrutura para novas seções de conteúdo; assinatura é única no package compartilhado.
  • Tabs de conteúdo são sublinhadas, flexShrink: 0, scrolláveis no mobile e omitidas quando sem conteúdo; nunca são pills.
  • ActionCluster mede a própria largura com adapter/ResizeObserver: linha completa quando cabe, grid sem órfão para quantidade par e ícone-only com accessible name no compacto.
  • AdaptiveTeamLabel nunca usa ellipsis; mede nome e sigla reais, remove colunas de menor prioridade primeiro e preserva a sigla inteira como piso.
  • Gallery usa 4:3/cover, quantidade visível par e +N; captions/credits permanecem no contrato e sua exposição é decisão da spec da tela.
  • IdentityMark resolve escudo/avatar/ícone por entidade sem inventar logo ou promover base64.

5. Forma recente V/E/D

  • Anatomia: sequência ordenada de células 26×26/radius 7, letra e descrição acessível por item.
  • Props: results, maxItems, label, compact.
  • Variantes: V, E, D; tamanho de exportação pode escalar proporcionalmente.
  • Estados: default; hover/focus mostra contexto somente se item interativo; disabled não se aplica; loading usa o mesmo número de células skeleton.
  • Tokens: success, accent, danger, text; texto de contraste validado.
  • Aceite: ordem temporal é documentada/legível; leitor de tela recebe “vitória/empate/derrota”, não apenas letras.

6. Scoreboard

  • Anatomia: participante mandante, centro com placar/VS e status, participante visitante; escudos e nomes têm peso equivalente.
  • Props: home, away, score, status, context, orientation, compact, actions.
  • Variantes: agendada (VS/hora), em andamento, aguardando validação, validada, contestada, provisória.
  • Estados: default; hover/focus somente quando o bloco abre a partida; disabled para ação, nunca para o placar; loading preserva três colunas e não mostra 0–0.
  • Tokens: text, text-muted, accent, success, danger, border, surface; stat-md/Bebas para placar.
  • Aceite: status fica junto do placar; nome longo e escudo ausente têm fallback; nenhum lado recebe destaque injustificado.

7. Switch

  • Anatomia: label/descrição + trilho 44×26 pill + thumb 20 px.
  • Props: label, description, checked, disabled, loading, onChange.
  • Variantes: on/off; com descrição; uso de tema deve anunciar destino/estado atual de forma inequívoca.
  • Estados: default; hover no trilho; focus ring; disabled sem mutação; loading mantém estado e bloqueia mudança.
  • Tokens: primary, on-primary, surface-alt, border, text, text-muted, radius-pill.
  • Aceite: teclado alterna com Space; label aciona o controle; estado persiste quando a feature exigir.

8. Checkbox

  • Anatomia: caixa 20×20/radius 6, check/indeterminado, label e helper/erro.
  • Props: label, checked, indeterminate, required, disabled, loading, error, onChange.
  • Variantes: unchecked, checked, indeterminate.
  • Estados: default; hover; focus ring; disabled; loading bloqueado sem perder valor; invalid com mensagem.
  • Tokens: primary, surface, border, text, text-muted, danger.
  • Aceite: label clicável; estado não depende do check visual; uso em aceite de regulamento registra a intenção sem pré-marcar.

9. Stepper numérico

  • Anatomia: label, botão menos 32×32 dentro de alvo 44, valor Bebas 20, botão mais equivalente.
  • Props: label, value, min, max, step, disabled, loading, onChange.
  • Variantes: inteiro; unidade opcional fora do número.
  • Estados: default; hover por botão; focus individual; disabled global/no limite; loading mantém valor e bloqueia ações.
  • Tokens: text, text-muted, accent, border, surface, radius-form, impact-sm.
  • Aceite: min/max impedem valor inválido; teclado e leitor de tela anunciam valor e limites.

10. Segmented control

  • Anatomia: container surface-alt/radius 10 + segmentos com label; um selecionado.
  • Props: options, value, disabled, loading, onChange, ariaLabel.
  • Variantes: 2–4 opções curtas; largura igual ou baseada em conteúdo quando documentado.
  • Estados: default; hover por opção; focus roving; disabled; loading skeleton; selected com primary.
  • Tokens: surface-alt, border, primary, on-primary, text, text-muted, radius-form.
  • Aceite: setas movem seleção/foco conforme padrão; não quebrar em labels longas — usar controle alternativo.

11. Toasts

  • Anatomia: ícone, mensagem curta, ação opcional e dismiss; radius 11.
  • Props: tone, message, actionLabel, duration, dismissible, onAction, onDismiss.
  • Variantes: success, error/offline, neutral.
  • Estados: default/enter/exit; hover pausa timeout; focus alcança ação/dismiss; disabled não se aplica; loading só na ação e sem fechar prematuramente.
  • Tokens: surface-alt, border, success, danger, accent, text, text-muted, radius-feedback.
  • Aceite: live region adequada; erro persistente não some antes de ser entendido; Sem conexão. Salvamos seu rascunho. só aparece se o rascunho foi realmente salvo.

12. Banners

  • Anatomia: título/label, descrição, ação/retry opcional e dismiss quando permitido.
  • Props: tone, title, description, action, dismissible, requestId.
  • Variantes: prazo/attention, partial error, success, under-review.
  • Estados: default; hover/focus nas ações; disabled só na ação; loading no retry preserva conteúdo.
  • Tokens: accent, danger, success, surface, text, text-muted, border, radius-feedback.
  • Aceite: prazo vem do domínio; falha parcial diz que o restante permanece; banner não substitui status junto do placar.

13. Progresso de wizard

  • Anatomia: sequência de barras de 4 px/radius 2 + label textual de passo fora da barra quando necessário.
  • Props: currentStep, totalSteps, labels, ariaLabel.
  • Variantes: compacta visual; com labels para fluxos longos.
  • Estados: concluído/atual em primary, futuro em border; hover/focus apenas se navegável; disabled/loading não alteram progresso confirmado.
  • Tokens: primary, border, text-muted.
  • Aceite: leitor de tela recebe “passo X de Y”; barra não é o único indicador; voltar não apaga dados sem aviso.

14. Upload

  • Anatomia: dropzone tracejada/radius 11, instrução, formatos/limites, botão, progresso/arquivo e erro.
  • Props: label, accept, maxSize, multiple, files, disabled, loading, error, onSelect, onRemove.
  • Variantes: vazio, com arquivo, uploading, concluído, erro.
  • Estados: default; hover/drag-active; focus ring; disabled; loading/progress com cancelamento quando suportado.
  • Tokens: surface, border, primary, text, text-muted, danger, success, radius-feedback.
  • Aceite: click/teclado equivalem a drag; validação informa formato/tamanho; não afirmar upload concluído antes da confirmação.

15. Modal

  • Anatomia: overlay, surface/radius 14, título, descrição/conteúdo, ações e close.
  • Props: open, title, description, actions, dismissible, initialFocus, onClose.
  • Variantes: confirmação, destrutivo, formulário curto.
  • Estados: default/open/closing; hover/focus em controles; disabled/loading nas ações; submit loading impede dismiss acidental quando inseguro.
  • Tokens: background, surface, border, text, text-muted, danger, primary, radius-card.
  • Aceite: focus trap/restore, Escape conforme dismissible, scroll lock, título acessível; contestação explica mediação e efeito sobre rankings.

16. Bottom sheet

  • Anatomia: overlay, sheet com radius 16 superior, handle decorativo, título opcional e lista de ações.
  • Props: open, title, actions, snapPoint, dismissible, onClose.
  • Variantes: menu de ações; conteúdo curto mobile; ação danger separada visualmente.
  • Estados: default/open/drag; hover não aplicável no touch; focus nos controles; disabled/loading por ação.
  • Tokens: background, surface, border, text, text-muted, danger, radius-sheet.
  • Aceite: gesto não é a única forma de fechar; teclado/leitor de tela têm comportamento de dialog; safe area inferior respeitada.

17. Chips de papel e permissão

  • Anatomia: pill textual, sem ação implícita.
  • Props: role, label, status, tooltip.
  • Variantes: gestor, organizador, jogador, torcedor, árbitro credenciado e outras chaves canônicas.
  • Estados: default; hover/focus somente para tooltip/ação explícita; disabled/loading não se aplicam ao papel já conhecido.
  • Tokens: primary, accent, success, chip-overlay, text-muted, border.
  • Aceite: chip descreve papel, não concede permissão; nomes vêm do domínio; cor nunca é prova de autorização.

18. Avatar stack

  • Anatomia: avatares 32 px com borda surface e overlap 10 px, contador +N e label de total.
  • Props: items, maxVisible, total, label, size, onPress.
  • Variantes: pessoas, entidades; placeholder de iniciais.
  • Estados: default; hover/focus se abre lista; disabled conserva leitura; loading mantém quantidade aproximada de círculos.
  • Tokens: surface, surface-alt, border, text-muted.
  • Aceite: total não é inferido pelo número visível; alt/nome acessível sem repetir informação excessiva.

19. Dropdown/menu de opções

  • Anatomia: trigger, popover surface/radius 11, opções, seleção/check e divisores.
  • Props: label, options, value, open, disabled, loading, onChange, onOpenChange.
  • Variantes: single-select, action menu; não usar para seleção múltipla complexa.
  • Estados: default/closed; hover por opção; focus roving; disabled por trigger/opção; loading bloqueia seleção e preserva valor.
  • Tokens: background, surface-alt, border, text, text-muted, accent, radius-feedback.
  • Aceite: setas/Enter/Escape funcionam; trigger anuncia estado expandido; menu não corta fora da viewport.

20. Paginação

  • Anatomia: anterior, páginas, elipse contextual e próximo; controles visuais 30 px dentro de alvo 44.
  • Props: page, pageCount, siblingCount, disabled, loading, onPageChange.
  • Variantes: páginas numeradas; compacta anterior/próximo no mobile.
  • Estados: default; hover; focus; disabled nos limites; loading preserva página atual e bloqueia repetição; current com primary.
  • Tokens: primary, border, text, text-muted, accent, radius-form.
  • Aceite: aria-current equivalente; voltar/avançar não perdem filtros; scroll/focus após troca é previsível.

21. Card de jogo — três estados

  • Anatomia: dois times, centro temporal/placar, contexto e chip de estado.
  • Props: match, state, compact, onPress, actions.
  • Variantes: agendada, em andamento, final/validada; waiting/contested usam status explícito quando presentes.
  • Estados: default; hover/focus quando navegável; disabled somente para ação; loading reproduz grid e status.
  • Tokens: surface, border, text, text-muted, accent, success, danger, radius-game; Bebas para placar.
  • Aceite: em andamento depende de snapshot canônico; validada mostra status junto do placar; agendada não mostra placar falso.

22. Card de pendência

  • Anatomia: indicador, título contextual, prazo/status, responsável opcional e ação Resolver.
  • Props: title, description, deadline, tone, assignee, action, disabled, loading.
  • Variantes: urgente/danger, atenção/accent, neutra.
  • Estados: default; hover/focus na ação/card; disabled explica indisponibilidade; loading na resolução mantém contexto.
  • Tokens: surface, border, danger, accent, text, text-muted, primary, radius-game.
  • Aceite: prazo vem do domínio; não usar badge genérico “novidade”; ação leva à resolução específica.

23. Tabs sublinhadas

  • Anatomia: tablist, tabs com label/contador opcional e underline de 2 px na ativa, painel associado.
  • Props: tabs, value, disabled, loading, onChange.
  • Variantes: scrollável mobile; fixa web.
  • Estados: default; hover; focus roving; disabled por tab; loading preserva tab ativa; selected com text + primary underline.
  • Tokens: text, text-muted, primary, border.
  • Aceite: setas navegam; painel/aria associados; trocar tab não apaga estado sem necessidade.

24. Breadcrumb

  • Anatomia: links ancestrais, separadores e item atual.
  • Props: items, maxItems, ariaLabel.
  • Variantes: completa web; colapsada com menu quando longa; não substitui back mobile.
  • Estados: default; hover/focus nos links; disabled não se aplica; loading usa linha estável sem links falsos.
  • Tokens: accent, text, text-muted.
  • Aceite: item atual não é link e usa aria-current; nomes longos truncam visualmente sem perder nome acessível.

25. Bottom navigation

  • Anatomia: cinco destinos canônicos com ícone + label; active em primary; safe area inferior.
  • Props: items, activeRoute, badges, disabled, onNavigate.
  • Variantes: visitante/autenticado/gestor alteram destino permitido via shell, não dentro do componente.
  • Estados: default; press/hover; focus; disabled com motivo acessível; loading do destino não remove active atual.
  • Tokens: surface, border, primary, text-muted.
  • Aceite: máximo cinco destinos, label sempre visível, rota ativa inequívoca; respeita SPEC-UX-SHELL-001.

26. Busca com escopo

  • Anatomia: campo 44–48 px, chip de escopo, texto/valor, limpar e lista/resultados quando aberta.
  • Props: query, scope, scopes, placeholder, disabled, loading, error, onQueryChange, onScopeChange, onSubmit.
  • Variantes: território, tipo de entidade, global; chip abre seleção acessível.
  • Estados: default; hover; focus/expanded; disabled; loading preserva query/escopo; error com retry sem limpar entrada.
  • Tokens: background, surface, chip-overlay, border, primary, text, text-muted, danger, radius-form.
  • Aceite: escopo está sempre visível e faz parte do anúncio acessível; mudar escopo não dispara perda silenciosa da query.

27. Matriz de fixtures e estados

Cada componente deve possuir stories/fixtures determinísticas cobrindo, quando aplicável:

  • Raiz/Neutro × dark/light;
  • default, hover, focus, disabled e loading;
  • erro/invalid/selected/expanded;
  • texto curto e longo, asset ausente, fonte ampliada;
  • teclado, screen reader semantics, touch target e reduced motion;
  • status esportivos canônicos e ausência de dados sem valor fictício.

Mocks existentes podem fornecer entidades e partidas, mas packages/ui não importa packages/mocks; stories/fixtures recebem props ou adapters respeitando SPEC-ARCH-BOUNDARIES-001.

  • Todos os blocos desta spec têm componente exportado, documentação e fixture/story.
  • API usa tokens v3 sem hex local e sem dependência proibida.
  • Testes de interação cobrem teclado, focus, disabled/loading e callbacks.
  • Testes visuais/fixtures cobrem os quatro modos e casos longos.
  • Scoreboard, chips e cards respeitam estado do domínio sem inferência.
  • Loading/empty/error seguem SPEC-UX-STATES-001.
  • Review compara o resultado com o capítulo 02 do Book em mobile e web.