# Indicator

A contagem por cima de outra coisa: avisos no sino, itens na aba, mensagens no
menu.

Existe como peça porque a alternativa é cada tela posicionar um `Badge` com
`absolute` na mão, e as cinco telas acabam com cinco deslocamentos diferentes,
todas com o mesmo defeito: a contagem existindo só para quem vê. Aqui o número
é escondido do leitor de tela e o `label` inteiro entra no lugar dele, porque
"7" não diz o que são sete.

Zero não desenha nada. Uma pastilha com "0" chama atenção para dizer que não há
nada, que é o contrário do trabalho dela.

Acima de `max` sai "99+", em vez de a pastilha esticar e empurrar o que está ao
lado. Com `dot`, sai só o ponto, para "tem algo novo aqui", quando o número
não importa.

A pastilha fica **por cima** do filho, e não ao lado: ela não reserva espaço.
Isso serve para alvo pequeno (o botão do sino, o item da barra, o avatar), e
sempre cobre texto quando o filho é largo. Acima de 48px de largura, que é o
maior alvo legítimo do catálogo (`Avatar` grande e controle `lg` na densidade
confortável medem exatamente isso), a peça avisa no console em desenvolvimento.
Para marcar uma linha inteira, ponha a contagem ao lado, com um `Badge`.

## Movimento

A pastilha cresce de 60% esmaecendo quando aparece (`animate-pop`, `--rc-duration-fast`): ela avisa que chegou algo, e o movimento curto puxa o olho sem virar alarme. A troca de número não repete a entrada.

## No React Native

Traduz, e o que muda é quem carrega o nome acessível. No web o número é escondido do leitor e um texto só para ele entra ao lado; no nativo a pastilha inteira é UM elemento de acessibilidade, e o `label` (aqui obrigatório) é o que ele anuncia. O leitor lê o filho ("Notificações, botão") e a pastilha em seguida ("3 notificações"), e nunca um "3" solto entre os dois. Embrulhar filho e pastilha num elemento só resolveria a leitura e quebraria o toque, porque o botão de dentro deixaria de ser alcançável. O anel que separa a pastilha do que está embaixo vira borda da cor do fundo: `ring` não existe no React Native, e borda ali ocupa por dentro da caixa.

## Importação

```tsx
import { Indicator } from '@rivocode/ui'
```

## Exemplos

### Avisos não lidos

```tsx
import { Bell } from 'lucide-react'
import { Button, Indicator } from '@rivocode/ui'

export function UnreadNotifications() {
  return (
    <div className="flex items-center gap-6">
      <Indicator count={7} label="7 avisos não lidos">
        <Button variant="ghost" size="icon" aria-label="Avisos">
          <Bell size={18} aria-hidden="true" />
        </Button>
      </Indicator>

      <Indicator count={150} max={99} label="150 avisos não lidos">
        <Button variant="ghost" size="icon" aria-label="Avisos">
          <Bell size={18} aria-hidden="true" />
        </Button>
      </Indicator>

      <Indicator dot label="Há algo novo">
        <Button variant="ghost" size="icon" aria-label="Avisos">
          <Bell size={18} aria-hidden="true" />
        </Button>
      </Indicator>
    </div>
  )
}
```

## Props

| Prop | Tipo | Obrigatória | Desde | O que faz |
| --- | --- | --- | --- | --- |
| `classNames` | `Partial<Record<"badge", string>>` |  | 0.5.0 | Classe por parte: `badge`. |
| `count` | `number` |  | 0.5.0 | Quantos. |
| `dot` | `boolean` |  | 0.5.0 | Sem contagem: so o ponto, para "tem algo novo aqui". |
| `label` | `string` |  | 0.5.0 | O que o leitor de tela ouve. |
| `max` | `number` |  | 0.5.0 | O teto: acima dele sai "99+", em vez de a pastilha esticar. |

Além dessas: repassa `className`, `style`, `id` e os demais atributos do elemento raiz.

## Ver também

- [Alert](/componentes/alert.md)
- [Badge](/componentes/badge.md)
- [EmptyState](/componentes/empty-state.md)
- [Kbd](/componentes/kbd.md)
- [Meter](/componentes/meter.md)
- [Progress](/componentes/progress.md)
- [Convenções da biblioteca](/convencoes.md): Provider, tokens e as regras que valem para toda peça
- [Índice completo](/llms.txt)
