Tema
BaseDiff
Compara um valor antes e depois de uma mudança, como um aditivo de contrato. Mostra a diferença em reais e em porcentagem e, quando a tela informa um limite, quanto dele já foi usado.
Antes (valor após o 2º aditivo, só com acréscimos): R$ 13.657.980,40. Depois: R$ 14.862.310,40. Aumento de R$ 1.204.330,00, 8,82%. Limite legal usado · reforma: 46% de 50%.
Reforma de edifício: acréscimos de até 50% do valor inicial (Lei 14.133, art. 125).
Uso
- Use em aditivos, reajustes e revisões, quando a pessoa precisa ver o antes, o depois e o tamanho da mudança de uma vez.
- Os valores entram em centavos inteiros (
before,after), como no resto do sistema. O componente nunca faz conta com número quebrado de reais: um centavo fracionado é arredondado, e a comparação com o limite usa inteiros exatos mesmo acima de R$ 9 bilhões. - O componente não conhece lei nem regra de negócio. O limite (
limit-percent), o título do medidor (limit-label) e a explicação (limit-text) vêm da tela, que sabe qual regra vale para aquele contrato. - Quando o limite é medido sobre outro valor, como o valor inicial do contrato depois de vários aditivos, informe esse valor em
limit-base. Sem ele, o limite é medido sobre o valor de antes. - O componente compara um valor líquido (depois menos a base) com um limite só, que vale para os dois lados: uma redução maior que o limite também é sinalizada.
- Quando a regra trata acréscimos e supressões de jeitos diferentes, com limites próprios ou sem compensar um com o outro, a tela soma cada lado e mostra um
BaseDiffpara os acréscimos e outro para as supressões, cada um com o seulimit-percent. Não junte os dois num valor líquido só. Veja o exemplo abaixo. - O limite tem precisão de duas casas decimais: 0,57 vale como 0,57%, e uma terceira casa é arredondada (12,345 vira 12,35%). A conta e o número mostrado usam o mesmo valor arredondado, e uma mudança exatamente igual ao limite nunca é sinalizada.
- Sem
limit-percent(ou com valor negativo), não há limite nem medidor. Comlimit-percentigual a 0, nenhuma mudança é permitida: qualquer diferença passa do limite. - Se o valor de antes for zero, não existe porcentagem de variação: o componente mostra só a diferença em reais e esconde o medidor, a menos que
limit-baseseja informado. - Acima do limite, as porcentagens são arredondadas para cima. Assim, 25,0001% aparece como 25,01%, e não como 25%, ao lado do selo.
Acréscimos e supressões separados
Um BaseDiff para cada lado, cada um com o limite que a regra da tela define. Os valores somam só os acréscimos, ou só as supressões, sobre o valor inicial.
Valor inicial: R$ 10.180.000,00. Com os acréscimos: R$ 13.420.000,00. Aumento de R$ 3.240.000,00, 31,83%. Limite usado · acréscimos: 31,83% de 50%.
Limite de acréscimos informado pela tela.
Valor inicial: R$ 10.180.000,00. Com as supressões: R$ 9.000.000,00. Redução de R$ 1.180.000,00, 11,59%. Limite usado · supressões: 11,59% de 25%.
Limite de supressões informado pela tela.
Estados
Antes (valor inicial): R$ 10.000.000,00. Depois: R$ 11.200.000,00. Aumento de R$ 1.200.000,00, 12%. Limite usado · construção: 12% de 25%.
Explicação do limite, escrita pela tela.
Antes: R$ 10.000.000,00. Depois: R$ 13.100.000,00. Aumento de R$ 3.100.000,00, 31%. Limite usado · construção: 31% de 25%.
Acima do limite
O acréscimo passa do limite: a tela explica o que fazer.
Antes: R$ 4.800.000,00. Depois (com a supressão do item 4.2): R$ 4.560.000,00. Redução de R$ 240.000,00, 5%.
Antes (sem valor anterior): R$ 0,00. Depois: R$ 12.500,00. Aumento de R$ 12.500,00.
Estilo
| Propriedade | Token |
|---|---|
| Fundo do lado "antes" | --tj-layer-02, borda --tj-border-subtle-02 |
| Fundo do lado "depois" | --tj-layer-selected-01, borda --tj-border-selected-subtle |
| Valor | --tj-text-xl, --tj-weight-bold, algarismos tabulares |
| Diferença e rótulo do "depois" | --tj-text-brand |
| Legenda | --tj-text-helper, --tj-text-sm |
| Trilho do medidor | --tj-layer-accent-01, 10 px, --tj-radius-pill |
| Preenchimento | --tj-border-interactive; acima do limite --tj-support-warning com borda interna --tj-support-warning-text |
| Marca do limite | --tj-support-error-text, 2 px |
| Selo acima do limite | BaseBadge com tom warning |
| Animação do preenchimento | --tj-duration-moderate-01, --tj-easing-standard |
| Espaços | --tj-space-2 a --tj-space-4; raio --tj-radius-md |
Em telas estreitas (até 575 px) os dois lados ficam um embaixo do outro e a seta aponta para baixo.
Diferenças em relação ao protótipo v3:
- Dentro do limite, o preenchimento é azul (
--tj-border-interactive) e só fica amarelo quando passa do limite. No protótipo ele é sempre amarelo; aqui o amarelo fica reservado para o alerta, junto com o selo. O azul de borda, e não--tj-interactive, mantém contraste de 3:1 com o trilho no tema escuro. - A diferença mostra até duas casas decimais (+8,82%), e não uma (+8,8%), para bater com a frase lida pelo leitor de tela e com a conta do limite.
- O rótulo "Depois" e a diferença usam
--tj-text-brand, e não o azul de link do protótipo (.tj-text-primary, que é--tj-link-primary-hover), porque o sistema só usa tokens de papel de texto. No tema claro o tom é o azul-marinho da marca; no tema escuro ele fica igual ao texto principal, e o lado "depois" se distingue pelo fundo e pela borda selecionados, não pela cor do texto. - Com limite de 0%, a legenda mostra só "0% · limite", alinhado à marca do limite, em vez de repetir 0%.
Código
vue
<BaseDiff
label="Valor do contrato"
:before="contract.currentAmountCents"
:after="amendment.newAmountCents"
:limit-percent="rule.limitPercent"
:limit-base="contract.initialAmountCents"
:limit-label="`Limite legal usado · ${rule.name}`"
:limit-text="rule.explanation"
/>| Propriedade | Tipo | Padrão | Descrição |
|---|---|---|---|
before | number | — | Valor antes, em centavos (obrigatório) |
after | number | — | Valor depois, em centavos (obrigatório) |
limitPercent | number | — | Mudança máxima em porcentagem, com até duas casas decimais, para aumento ou redução do valor líquido; sem ele (ou negativo), não há medidor; 0 não permite mudança |
limitBase | number | before | Valor, em centavos, sobre o qual o limite é medido |
label | string | — | Nome acessível da comparação; com ele, o bloco vira um grupo nomeado |
beforeLabel / afterLabel | string | 'Antes' / 'Depois' | Título de cada lado |
beforeCaption / afterCaption | string | — | Nota curta abaixo de cada valor |
limitLabel | string | 'Limite usado' | Título do medidor |
limitText | string | — | Explicação do limite, abaixo do medidor |
overLimitLabel | string | 'Acima do limite' | Texto do selo quando a mudança passa do limite |
limitMarkLabel | string | 'limite' | Palavra ao lado do limite no fim da legenda do medidor, como em "25% · limite" |
Sem eventos: o componente só mostra valores.
Acessibilidade
- Com
label, o bloco é umrole="group"com esse nome. Semlabel(ou com umlabelvazio ou só de espaços), não há grupo nemaria-label, para o leitor de tela não anunciar um grupo sem nome. - O leitor de tela ouve uma frase só, em vez de caixas soltas: "Antes (valor após o 2º aditivo, só com acréscimos): R$ 13.657.980,40. Depois: R$ 14.862.310,40. Aumento de R$ 1.204.330,00, 8,82%. Limite legal usado · reforma: 46% de 50%." O desenho dos dois lados, a seta e o medidor ficam escondidos dele (
aria-hidden), para nada ser lido duas vezes. - O selo "Acima do limite" e a explicação do limite são texto comum e são lidos depois da frase.
- A cor nunca é o único sinal: a diferença tem sinal (+ ou −) e a palavra "Aumento" ou "Redução" na frase, e passar do limite mostra um selo com texto.
- O componente não recebe foco: não há nada para acionar.
- Se os valores mudam enquanto a pessoa está na tela (por exemplo, digitando o novo valor), avise a passagem do limite com uma região
aria-livena tela, não no componente. - A animação do medidor é desligada com
prefers-reduced-motion. Em alto contraste (forced-colors), o trilho ganha borda e o preenchimento usa a cor de destaque do sistema (Highlight) em todos os estados, inclusive acima do limite. - Funciona nos temas claro e escuro: todas as cores são tokens de papel.
- Testado com axe em todos os estados: sem limite, dentro do limite, exatamente no limite (0,57%), acima do limite (aumento, redução e só pelo arredondamento para cima), acima do limite com explicação e com textos próprios, sem variação, limite de 0% com e sem mudança, e valor de antes zero, com e sem
limit-base.