Chip

Pronto

Tag clicável e/ou removível. Diferente de Badge: chip é interativo (click filtra, X remove).

Usar quando

Tags em processo/contato, filtros aplicados (com X para remover), seleção múltipla compacta, tokens de busca, áreas vinculadas.

Não usar quando

Selo de status estático (use Badge). Botão de ação principal (use Button). Texto longo (use Card).

Variantes

Removível (X)
CívelTrabalhistaTributárioFamília
Selecionável (toggle)
Action chip (com ícone)
Cores funcionais (sinal)
Direito CivilDireito TrabalhistaDireito TributárioDireito PenalSem categoria
Tamanhos
PequenoMédio

Microinterações

MicrointeraçãoDisparada porComportamentoTiming
Mount inchip aparece (após filter add)opacity 0→1 + scale 0.85→1200ms cubic-bezier(0.32,0.72,0,1)
Remove outclick Xscale 1→0.85 + opacity 1→0 + width collapse200ms ease
HovermouseenterBackground +5% saturated, X aparece destacado150ms ease
Toggle selectclick no chipBorda + background invertem (ink ↔ surface)150ms ease
Tap haptic (mobile)tapVibration 10ms + visual scale 0.95100ms

Acessibilidade

Acessibilidade — checklist

Teclado
TabFoco no chip
Enter / SpaceAtiva (toggle ou click)
Backspace / DeleteRemove (se removível)
Tab → XFoco no X
ARIA esperado
  • Chip selecionável: <button aria-pressed="true|false" />
  • Chip removível: <span> + <button aria-label="Remover X" />
  • Action chip: <button> normal
  • Em filtros: aria-label="Filtro: <X> aplicado, clique para remover"
Notas
  • Backspace/Delete deve remover quando focado.
  • Em filtros aplicados, anuncie via aria-live="polite" qual foi removido.
  • Combine bem com Tags Input — chips são output dele.
  • Cor é sinal, mas sempre acompanha de texto.

Código

'use client';
import { X } from 'lucide-react';
import { T, RADIUS, MOTION, transition } from '@/lib/tokens';

interface ChipProps {
  children: React.ReactNode;
  removable?: boolean;
  selected?: boolean;
  onClick?: () => void;
  onRemove?: () => void;
  color?: 'neutral' | 'brass' | 'selo' | 'verde' | 'carmim';
}

export function Chip({ children, removable, selected, onClick, onRemove, color = 'neutral' }: ChipProps) {
  return (
    <span
      onClick={onClick}
      style={{
        display: 'inline-flex', alignItems: 'center', gap: 4,
        background: selected ? T.ink : T[`${color}Tint`] ?? T.surface3,
        color: selected ? T.surface : T[color] ?? T.ink2,
        border: `1px solid ${selected ? T.ink : T.border}`,
        borderRadius: RADIUS.pill,
        padding: '4px 12px',
        fontSize: 12,
        fontWeight: 500,
        cursor: onClick ? 'pointer' : 'default',
        transition: transition('all', 'fast'),
      }}
    >
      {children}
      {removable && (
        <button onClick={(e) => { e.stopPropagation(); onRemove?.(); }} aria-label="Remover">
          <X size={11} />
        </button>
      )}
    </span>
  );
}

Regras

Faça

  • Use removável (X) em filtros aplicados.
  • Use selecionável (toggle) em multi-seleção compacta.
  • Cor por sinal — brass para destaque, neutral default.
  • Mount/remove com animação (300ms max).
  • Combine bem com Tags Input (chips são saída dele).

Não faça

  • Não use chip como botão primário de página (use Button).
  • Não use texto longo (>20 caracteres — use Card ou paragraph).
  • Não force cor brass em chips genéricos (brass é sinal).
  • Não esconda o X (sempre visível em hover, opcional em rest).
  • Não esqueça keyboard delete.

Tokens usados

TokenValorPapel
T.ink#0A0A0Abackground quando selected
T.surface3#F3F0E6background neutral
T.brassTintrgba(164,124,43,0.08)background brass
T.border#E3DFD2borda default
RADIUS.pill980forma
MOTION.fast150mstransition