Tema
Trava do design system
A trava é um comando do pacote, ds-guard, que roda no pipeline de cada projeto. Ela conta o código de tela fora do padrão do design system e reprova o pull request quando essa conta sobe. A conta só pode descer.
Cada projeto guarda a conta de hoje num arquivo, a linha de base (ds-guard-baseline.json). Um projeto antigo não precisa corrigir tudo de uma vez: o que já existe fica anotado na linha de base, e o código novo entra no padrão.
Por que existe
Uma tela com <button> cru, cor em hexadecimal ou margem de 13 px funciona, mas fica fora do tema escuro, do contraste medido, do foco e da escala de espaços. A revisão de código nem sempre percebe isso; a trava confere todo pull request com as mesmas regras.
O que ela barra
A trava lê os arquivos .vue, .ts, .css e .scss da pasta src do projeto. Ficam de fora os testes (*.test.ts, *.spec.ts, pastas e2e, test, tests, __tests__ e __mocks__), as declarações de tipo (*.d.ts), o node_modules e o próprio design system. Comentários não contam.
São quatro regras:
| Regra | O que conta | O que usar no lugar |
|---|---|---|
raw-element | Elemento HTML no template quando o design system tem o componente. | <button>: BaseButton. <select>: BaseSelect ou BaseCombobox. <table>: BaseDataTable. <input type="radio">: BaseRadio ou BaseRadioGroup. <input type="checkbox">: BaseCheckbox ou BaseSwitch. <input type="file">: BaseFileUpload. <input type="date">: BaseDateInput. <input type="search">: BaseSearch. Outro <input>: BaseInput ou BaseMoneyInput. <a>: BaseLink. <h1> a <h6>: BaseHeading (o h1 da tela vem do BasePage). <progress>: BaseProgress. <dialog>: BaseModal ou BaseConfirmModal. <fieldset>: BaseFieldset. <textarea>: BaseTextarea. |
raw-color | Cor escrita direto: hexadecimal, rgb(), hsl() e afins, ou nome de cor (red, white) numa propriedade de cor. Vale no CSS, no atributo style e nos textos do TypeScript. | Um papel de cor, como var(--tj-text-primary) ou var(--tj-support-error-text). Veja Tokens e temas. |
raw-length | Valor em px, rem ou em em margem, espaço interno, gap, tamanho de fonte ou raio. Vale no CSS, no atributo style e em objetos de estilo do TypeScript ({ fontSize: '13px' }). | O token da escala: var(--tj-space-*), var(--tj-text-*) ou var(--tj-radius-*). Quando o valor bate com um token, a mensagem diz qual. O espaço entre blocos vem do BasePage, do BaseStack e do BaseCardGrid. |
bootstrap-class | Classe do Bootstrap que passa por cima dos tokens: de cor (text-danger, bg-light, border-success), de espaço (mt-3, p-2, gap-2, g-3), de tamanho de texto (fs-2, display-4) e de raio fora da escala (rounded-4, rounded-5). | O tom do componente (tone do BaseText, BaseBadge, BaseTag), o papel de cor no CSS, o BaseStack ou o token de espaço, e o variant do BaseText e do BaseHeading. |
O que a trava aceita:
0em qualquer medida, e as classes de espaço com0(mb-0).- Tokens, inclusive dentro de
calc(), e cor feita dos canais de um token, comorgba(var(--tj-navy-900-rgb), .48). transparent,currentColoreinherit.- Medidas que não são espaço, fonte nem raio: largura, altura, borda, contorno e
@media.
Quando ela reprova
A trava compara a conta de cada arquivo, regra por regra, com a linha de base. Ela reprova em três casos:
A conta subiu num arquivo, ou apareceu arquivo novo com violação. A mensagem diz o arquivo, a linha, a regra e o componente ou token que deve entrar no lugar:
textsrc/features/contracts/ContractForm.vue raw-element: 0 na linha de base, 1 agora linha 42: <button> cru: use BaseButton.A conta desceu e a linha de base não foi gravada de novo. Quem corrigiu grava a conta nova, e a trava fica mais apertada para o próximo.
O projeto não tem linha de base.
Como corrigir
Troque cada linha que a mensagem aponta pelo componente ou token indicado. Para conferir na sua máquina, na pasta frontend do projeto:
sh
npx ds-guardA saída ok mostra a conta de cada regra.
Como atualizar a linha de base
Depois de corrigir violações antigas, grave a conta nova e inclua o arquivo no mesmo commit:
sh
npx ds-guard --update-baselineO comando recusa gravar se alguma conta subiu: a linha de base só desce. Se uma exceção for mesmo necessária, edite o ds-guard-baseline.json à mão e explique o motivo no pull request, para a revisão ver.
Na primeira vez, o mesmo comando cria o arquivo com a conta de hoje.
Uma versão nova do design system pode passar a contar algo que antes não contava. O CHANGELOG.md avisa quando isso acontece. No pull request que sobe a versão, apague o ds-guard-baseline.json, rode npx ds-guard --update-baseline e diga no pull request quanto a conta mudou.
No pipeline
O kit tjes-base-web já traz a trava como um passo do job quick-checks. Um projeto que nasceu antes do kit adiciona o passo no mesmo job, sem criar job novo:
yaml
quick-checks:
permissions:
contents: read
packages: read
steps:
# ... os passos que já existem
- name: "ds-guard: install"
id: ds-guard-install
if: ${{ !cancelled() }}
working-directory: frontend
run: npm ci --ignore-scripts --no-audit --no-fund
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: "ds-guard: design system"
if: ${{ !cancelled() && steps.ds-guard-install.outcome == 'success' }}
working-directory: frontend
run: npx ds-guardO token do workflow fica só no passo que instala, e a trava roda sem ele.
O que ela não vê
<nav>,<details>,<img>e listas: não há um componente que troque cada um sem dúvida.- Estilo montado em
:styleou em funçõesh(), e classes montadas em código fora do template. - Classes de componente do Bootstrap, como
btnouform-control, num elemento que não é o do componente. - Tokens da paleta (
var(--tj-blue-500)) usados no lugar de um papel.
Para esses casos vale a revisão do pull request e as páginas de cada componente.