Tema
BaseTabs
Divide o conteúdo de uma tela em seções do mesmo nível, uma visível por vez. Para trocar de página, use links ou o menu lateral.
Planilha com os 48 itens medidos no mês.
Fotos e relatório do fiscal.
Quem abriu, revisou e aprovou a medição.
Aba selecionada: items
Uso
- Use abas para seções que a pessoa consulta uma de cada vez, como itens, anexos e histórico de uma medição.
- O rótulo é curto, de uma ou duas palavras, e diz o que a seção contém: "Aditivos", não "Ver aditivos".
- Ponha o contador quando a quantidade ajuda a decidir para onde ir: "Anexos 2".
- Não use abas para passos em sequência, como um cadastro em etapas; o conteúdo de uma aba não pode depender de outra.
- Para filtrar uma mesma lista, use botões de filtro; as abas trocam de seção, não de recorte.
Estados
Medição 29 em revisão.
Três aditivos de prazo.
Contrato assinado em 12/03/2022.
- Selecionada: texto em negrito e barra azul embaixo. A barra e o peso da fonte marcam a aba, além da cor.
- Passar o mouse: o texto escurece e aparece uma barra cinza.
- Foco: contorno azul sólido de 2 px por dentro da aba.
- Desabilitada: texto cinza claro. As setas passam por ela e o leitor de tela anuncia "indisponível", mas nem a seta nem o clique a selecionam. Prefira esconder a aba quando ela nunca vai abrir para essa pessoa; desabilite só quando ela vai abrir depois, como "Garantias" antes do primeiro empenho.
Sem v-model, ou com um id que não existe ou está desabilitado, a primeira aba habilitada aparece. O componente não reescreve o v-model nesse caso: quem lê o valor continua vendo o id recebido.
Com todas as abas desabilitadas, nenhum painel aparece. A primeira aba continua no Tab, para que a pessoa encontre a lista e ouça que as abas estão indisponíveis; explique o motivo num texto fora do componente.
Tamanhos
Use sm dentro de cartões e tabelas, md no corpo da tela e lg só no topo de uma página com poucas seções.
Sem linha
Dentro de um cartão ou tabela que já tem a própria borda embaixo das abas, use class="is-flush" para tirar a linha da lista.
Estilo
| Propriedade | Token |
|---|---|
| Texto da aba | --tj-text-helper, hover e selecionada --tj-text-primary |
| Peso | --tj-weight-medium, selecionada --tj-weight-semibold |
| Barra da selecionada | --tj-interactive, 2 px |
| Barra no hover | --tj-border-strong-01, pressionada --tj-border-strong-02 |
| Linha da lista | --tj-border-subtle-02, 1 px; nenhuma com is-flush |
| Barra de rolagem | --tj-border-strong-01, fina |
| Contador da selecionada | fundo --tj-layer-selected-01, texto --tj-link-primary-hover |
| Desabilitada | --tj-icon-secondary |
| Foco | contorno de 2 px em --tj-border-interactive |
| Fonte | --tj-text-sm, --tj-text-md e --tj-text-lg por tamanho |
| Espaçamento | --tj-space-2, --tj-space-3 e --tj-space-4 acima e abaixo; 24 px entre rótulos; --tj-space-1 dos lados, para o contorno de foco |
| Transição | --tj-duration-fast-02, --tj-easing-standard |
O espaço reservado para o negrito impede que as abas vizinhas mudem de lugar quando a seleção troca. Em tela estreita, a lista rola para o lado e mostra uma barra de rolagem fina. A aba selecionada entra na área visível ao abrir a tela e a cada troca, pelo clique, pelo teclado ou pelo v-model; só a lista rola, a página fica parada.
Código
vue
<script setup lang="ts">
import { ref } from 'vue'
import { BaseTabs, type TabItem } from '@lab-inovacao/design-system'
const tabs: TabItem[] = [
{ id: 'items', label: 'Itens medidos', count: 48 },
{ id: 'attachments', label: 'Anexos', count: 2 },
{ id: 'history', label: 'Histórico' },
]
const selected = ref('items')
</script>
<template>
<BaseTabs v-model="selected" :tabs="tabs" label="Seções da medição">
<template #items><MeasurementItems /></template>
<template #attachments><AttachmentList /></template>
<template #history><MeasurementHistory /></template>
</BaseTabs>
</template>| Propriedade | Tipo | Padrão | Descrição |
|---|---|---|---|
tabs | readonly TabItem[] | — | Abas em ordem: { id, label, count?, disabled? } |
label | string | — | O que as abas dividem; nome acessível da lista |
v-model | string | primeira habilitada | Id da aba selecionada |
size | 'sm' | 'md' | 'lg' | 'md' | Tamanho do texto e do espaçamento |
focusablePanels | boolean | true | Põe cada painel na ordem do Tab; veja Acessibilidade |
TabItem | Tipo | Descrição |
|---|---|---|
id | string | Identifica a aba e dá nome ao slot do painel |
label | string | Texto da aba |
count | number | Quantidade num BaseCount depois do rótulo |
disabled | boolean | A aba recebe foco pelas setas, mas não é selecionada |
Slots: um por aba, com o nome igual ao id. Todos os painéis ficam montados e só o selecionado aparece, então um formulário preenchido numa aba não perde o que foi digitado ao trocar de aba.
Evento: update:modelValue, com o id da aba nova. Não é emitido ao montar nem quando o id recebido é corrigido para a primeira aba habilitada.
Classe: is-flush tira a linha embaixo da lista.
Acessibilidade
- Segue o padrão de abas do WAI-ARIA APG:
role="tablist"comaria-label, cada aba é um<button role="tab">comaria-selectedearia-controls, e cada painel é umrole="tabpanel"nomeado pela aba. - Ativação automática: as setas para a direita e para a esquerda movem o foco e já selecionam a aba, voltando ao início depois da última. Home e End vão para a primeira e a última aba. Com Alt, Ctrl ou Cmd, as teclas ficam com o navegador, como Alt+seta para voltar a página.
- Abas desabilitadas usam
aria-disabled: continuam na ordem das setas, para que quem usa leitor de tela saiba que elas existem, mas recebem só o foco, sem seleção. O clique nelas não faz nada. - Só uma aba entra na ordem do Tab: a selecionada, ou a que tem o foco enquanto ele está na lista. Ao sair da lista, o Tab volta para a selecionada. Com todas desabilitadas, a primeira fica no Tab.
- O próximo Tab vai para o painel, que recebe foco para o leitor de tela começar a ler o conteúdo. Quando todo painel começa com um elemento focável, como o primeiro campo de um formulário, use
:focusable-panels="false": o Tab vai direto para esse elemento, sem uma parada a mais. - O contador entra no nome da aba: o leitor de tela ouve "Anexos 2, aba, 2 de 3".
- A aba selecionada se distingue pelo negrito e pela barra, não só pela cor. No modo de alto contraste do Windows, a barra e o foco usam as cores do sistema.
- Com movimento reduzido no sistema, as transições de cor são desligadas.
- Com contador acima de 99, a pílula mostra "99+" e o leitor de tela ouve o valor real.
- Testado com axe nos três tamanhos, com contadores, com contador acima do limite, com aba desabilitada com e sem foco, com todas as abas desabilitadas, com outra aba selecionada desde o início e depois de trocar de aba pelo teclado.