# Stat

O número de painel: rótulo, valor, variação e tendência, na hierarquia que todo
painel reinventa na mão.

O valor chega formatado porque formatar é decisão de domínio: dinheiro sai
abreviado do `currencyShort`, contagem sai crua, percentual traz o sinal.

`delta` é a variação, com `deltaLabel` dizendo contra o quê ("sobre julho").
Quando subir é ruim (vencidas, custo, inadimplência), passe
`invert`: a seta continua apontando para onde o número foi, o que inverte é o
julgamento da cor. A direção também é falada para leitor de tela, não só
pintada.

A tendência entra pelo slot `chart`, com a `Sparkline` de `@rivocode/ui/chart`:

```tsx
<Stat
  label="Faturado em agosto"
  value={currencyShort(246_700)}
  delta={20}
  deltaLabel="sobre julho"
  chart={<Sparkline data={TREND} variant="area" trend="auto" className="h-8 w-full" />}
/>
```

O núcleo não importa a `Sparkline` de propósito: ela traz o recharts junto, e
um painel sem gráfico não deveria pagar por ele.

## A variação nem sempre é porcentagem

O `%` era cravado no JSX, e o `Stat` era a única peça de número da casa fora do
vocabulário de formatação que `Progress`, `Meter` e `Slider` já falam. Um delta
em reais ou em pontos-base saía com um por-cento que não era verdade.

`deltaFormat` é o mesmo `format` das irmãs, nome de formatador da casa ou
função própria:

```tsx
<Stat label="Faturado" value={currencyShort(246_700)} delta={12_400}
      deltaFormat="currencyShort" deltaLabel="sobre julho" />
```

Sem ele, `percent`, que é o que sempre saiu. O `percent` da casa arredonda para
inteiro; para casa decimal, passe a função: `deltaFormat={(value) => percent(value, 1)}`.

O que chega ao formatador é o **módulo** do `delta`: quem carrega o sinal é a
seta, e o "alta de"/"queda de" que o leitor de tela ouve antes do número.

## Movimento

O conteúdo do cartão esmaece na montagem (`animate-appear`, `--rc-duration-base`), e a moldura fica parada: o número chega, o cartão já estava ali. Os dígitos não contam do zero, de propósito: número que corre até o valor é ilegível enquanto corre, e é ele que a pessoa veio ler.

## No React Native

Traduz: o `@rivocode/ui-native` exporta `Stat` - `value` já formatado, `delta` numérico, e o slot `chart` que a `Sparkline` nativa preenche. A API não é a mesma do web (no nativo tudo é controlado), e a [tabela de paridade](/react-native) diz o que muda peça a peça.

## Importação

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

## Exemplos

### Padrão

```tsx
import { Stat } from '@rivocode/ui'
import { Sparkline, currencyShort, percent } from '@rivocode/ui/chart'

export function Default() {
  return (
    <Stat
      label="Faturado em agosto"
      value={currencyShort(246_700)}
      delta={20}
      deltaLabel="sobre julho"
      className="w-64"
    />
  )
}
```

### Com tendência

```tsx
import { Stat } from '@rivocode/ui'
import { Sparkline, currencyShort, percent } from '@rivocode/ui/chart'

const TREND = [128, 154, 142, 188, 205, 246]

export function WithTrend() {
  return (
    <Stat
      label="Faturado em agosto"
      value={currencyShort(246_700)}
      delta={20}
      deltaLabel="sobre julho"
      hint="Tudo que foi emitido no mês, pago ou não."
      chart={<Sparkline data={TREND} variant="area" trend="auto" className="h-8 w-full" />}
      className="w-64"
    />
  )
}
```

### Subir é ruim

```tsx
import { Stat } from '@rivocode/ui'
import { Sparkline, currencyShort, percent } from '@rivocode/ui/chart'

const OVERDUE = [2, 3, 3, 5, 4, 6]

export function Inverted() {
  return (
    <Stat
      label="Vencidas"
      value="6"
      delta={50}
      deltaLabel="sobre julho"
      invert
      hint="Notas com vencimento passado e sem baixa."
      chart={
        <Sparkline
          data={OVERDUE.map((point) => -point)}
          variant="area"
          trend="auto"
          className="h-8 w-full"
        />
      }
      className="w-64"
    />
  )
}
```

### A fileira de painel

```tsx
import { Stat } from '@rivocode/ui'
import { Sparkline, currencyShort, percent } from '@rivocode/ui/chart'

export function Row() {
  return (
    <div className="grid w-full gap-4 sm:grid-cols-3">
      <Stat label="Faturado" value={currencyShort(246_700)} delta={20} deltaLabel="sobre julho" />
      <Stat label="Recebido" value={currencyShort(198_300)} delta={3} deltaLabel="sobre julho" />
      <Stat label="Vencidas" value="6" delta={50} deltaLabel="sobre julho" invert />
    </div>
  )
}
```

### A variação que não é porcentagem

```tsx
import { Stat } from '@rivocode/ui'
import { Sparkline, currencyShort, percent } from '@rivocode/ui/chart'

export function DeltaFormat() {
  /*
   * O delta fala o mesmo vocabulário de formatação do Progress, do Meter e do
   * eixo do gráfico. Sem `deltaFormat` ele sai em `percent`, que é o padrão;
   * com ele, sai na unidade que o número realmente tem.
   */
  return (
    <div className="grid w-full gap-4 sm:grid-cols-3">
      <Stat
        label="Faturado"
        value={currencyShort(246_700)}
        delta={12_400}
        deltaFormat="currencyShort"
        deltaLabel="sobre julho"
      />
      <Stat
        label="Notas emitidas"
        value="1.240"
        delta={86}
        deltaFormat="integer"
        deltaLabel="sobre julho"
      />
      <Stat
        label="Inadimplência"
        value="4,2%"
        delta={0.8}
        deltaFormat={(value) => percent(value, 1)}
        deltaLabel="sobre julho"
        invert
      />
    </div>
  )
}
```

## Props

| Prop | Tipo | Obrigatória | Desde | O que faz |
| --- | --- | --- | --- | --- |
| `label` | `string` | sim | 0.4.0 | O que o numero mede: "Faturado em agosto". |
| `value` | `ReactNode` | sim | 0.4.0 | O numero, ja formatado: `currencyShort(246_700)`. |
| `actions` | `ReactNode` |  | 0.5.0 | O canto direito do cartao: o menu de tres pontos, um botao de acao. |
| `chart` | `ReactNode` |  | 0.4.0 | A tendencia embaixo do numero. |
| `delta` | `number` |  | 0.4.0 | A variacao. |
| `deltaFormat` | `Format` |  | - | Como a variacao e escrita: nome de formatador da casa (`percent`, `currencyShort`, `integer`...) ou funcao propria. |
| `deltaLabel` | `string` |  | 0.4.0 | Contra o que se compara: "sobre julho". |
| `deltaVariant` | `"pill" \| "text"` |  | 0.5.0 | A variacao como pastilha preenchida, que e a convencao dominante em painel, ou como texto com seta, que e o padrao daqui. |
| `footer` | `ReactNode` |  | 0.5.0 | A faixa de baixo: meta com barra, comparacao, texto de apoio. |
| `hint` | `string` |  | 0.4.0 | Explicacao curta atras de um botao de informacao. |
| `icon` | `ReactNode` |  | 0.5.0 | O icone em caixa, a esquerda do rotulo. |
| `invert` | `boolean` |  | 0.4.0 | Subir e ruim aqui: vencidas, custo, inadimplencia. |

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

## Ver também

- [Accordion](/componentes/accordion.md)
- [AspectRatio](/componentes/aspect-ratio.md)
- [Avatar](/componentes/avatar.md)
- [Card](/componentes/card.md)
- [Collapsible](/componentes/collapsible.md)
- [DataTable](/componentes/data-table.md)
- [Convenções da biblioteca](/convencoes.md): Provider, tokens e as regras que valem para toda peça
- [Índice completo](/llms.txt)
