Use os tokens ax reais da versão 8 de Aksel, a densidade nativa da tabela e uma estrutura semântica de cabeçalho. Ordene e selecione registros fictícios de acompanhamento enquanto compara os temas claro e escuro.
Tabela nativa do Aksel 8.18.0, CSS e tokens com HTML semântico; código local para ordenação/seleção e fallback explícito para Arial. · Referência de implementação
02
Referência de design do sistema de design Aksel
Folha de estilos nativa de @navikt/ds-css 8.18.0 inspecionada e documentação atual da v8. Os valores dos modos claro e escuro são definidos por escopo; a prévia substitui as fontes remotas por Arial e usa os registros originais do exemplo.
Sistema de design Aksel: comece pelo contrato da v8
Não misture classes antigas com tokens novos
A v8 de Aksel usa tokens --ax-* e classes de componentes .aksel. O guia de migração informa que as antigas classes .navds não funcionam mais e que os tokens específicos de componentes foram removidos. Por isso, um tutorial baseado em uma captura de tela antiga pode parecer plausível e, ainda assim, oferecer orientações de implementação incorretas.
Esta página fixa o CSS nativo na versão 8.18.0 e fornece a instalação correspondente de React. A prévia usa classes nativas de tabela inspecionadas com HTML comuns; a aplicação JavaScript é responsável pela seleção e ordenação. Ela não afirma que baixar uma folha de estilos instancia uma Tabela de React.
Sistema de design Aksel: funções tipográficas e carregamento de fontes
Use 600 para o token de negrito
A referência de tokens define Source Sans 3, Source Sans Pro, Arial e sans-serif como a pilha de fontes. O peso regular é 400 e o token de negrito nominal é 600. Os tamanhos de texto incluem 14, 16, 18 e 20px; as funções de título vão até 24, 28, 32 e 40px.
A prévia local define o token de fonte como Arial e substitui explicitamente o uso herdado de fontes, evitando solicitações a fontes remotas. Essa é uma decisão de fallback declarada, não uma afirmação de que Arial seja a fonte tipográfica principal de Aksel. O dimensionamento do texto dos componentes continua sendo fornecido por CSS.
Sistema de design Aksel: espaçamento, raio e layout
Tokens nomeados em pixels são convertidos para rem
--ax-space-16 equivale a 1rem e --ax-space-24 a 1.5rem. A sintaxe de primitivas da v8 segue esses nomes: padding="space-16" e gap={{xs:"space-8",md:"space-16"}}. Não substitua uma propriedade numérica antiga de espaçamento sem antes consultar as orientações de migração.
As funções de raio documentadas incluem 2, 4, 8, 12 e 16px, além de full. A prévia mantém a geometria nativa da tabela e usa space-24 ao redor dos controles da aplicação. A largura de leitura de 64rem é uma escolha local; os valores dos pontos de interrupção vêm da folha de estilos inspecionada.
Sistema de design Aksel: cores semânticas adaptadas ao tema
Preserve a função, não um único valor hexadecimal
A folha de estilos nativa resolve --ax-text-neutral como neutral-1000: #202733 no modo claro e #dfe1e5 no modo escuro. --ax-bg-default muda de branco para #0e151f. Fixar o valor do texto claro em um contêiner escuro anularia o mapeamento de funções.
A prévia alterna a classe de tema .light/.dark e permite que as cores de listras, bordas e linhas selecionadas da tabela sigam os tokens oficiais. A seleção continua indicada por uma caixa de seleção marcada e uma contagem visível. Apenas colorir uma linha não constitui uma interface de seleção.
Sistema de design Aksel: anatomia semântica da tabela
Cabeçalhos não são células comuns
A tabela nativa tem classes distintas para cabeçalho, corpo, linha, célula de cabeçalho e célula de dados. O equivalente em React usa Table.Header, Table.Body, Table.Row, Table.HeaderCell e Table.DataCell. A coluna de referência é um cabeçalho de linha, e cada cabeçalho de coluna tem scope=col.
A legenda nomeia o conjunto. Os dias de espera são valores quantitativos e ficam alinhados à direita; os identificadores de referência permanecem alinhados à esquerda. Em larguras menores, a prévia mantém a rolagem horizontal dentro de uma região identificada e acessível pelo teclado, em vez de destruir as relações da tabela para transformar as linhas em cartões.
Use células de cabeçalho tanto para os rótulos das colunas quanto para os identificadores das linhas.
Alinhe valores quantitativos à direita, mas não códigos postais nem identificadores.
Inclua uma legenda para dar um nome significativo à tabela.
Na versão nativa de CSS inspecionada, as células médias usam space-12 na vertical e space-8 na horizontal. As pequenas usam space-4 na vertical, e as grandes usam space-16 na vertical. O seletor de densidade altera a classe modificadora nativa; não reduz o tamanho da fonte do corpo para forçar mais informações na área visível.
O cabeçalho Waiting days é um botão de ordenação no estilo nativo. Seu manipulador ordena os valores numéricos e atualiza aria-sort nesse cabeçalho. A aplicação controla essa transformação: o React API também expõe o estado de ordenação e onSortChange, em vez de ordenar automaticamente registros arbitrários do domínio.
Sistema de design do Aksel: seleção de linhas acessível pelo teclado
Inclua um controle explícito em cada linha
A documentação de Table alerta que onRowClick, por si só, não é acessível pelo teclado. Por isso, o exemplo inclui uma caixa de seleção identificada para cada referência e uma caixa para selecionar tudo. A caixa agregada fica em estado indeterminado quando apenas algumas linhas estão selecionadas.
A ordenação mantém a seleção com base no identificador de referência estável. Ela nunca usa o índice atual da linha como chave da seleção, pois isso faria a marcação passar para outro registro quando a ordem mudasse. A contagem de selecionados é atualizada em uma região de status com anúncio educado. Nenhum registro selecionado é enviado a lugar algum.
Sistema de design do Aksel: carregar CSS e React compatíveis
Mantenha as versões dos pacotes sincronizadas
Instale @navikt/ds-react e @navikt/ds-css na mesma versão e importe o CSS uma vez, próximo à raiz da aplicação. O pacote já inclui tokens. O guia oficial de importação do CSS também oferece suporte a arquivos globais e de componentes importados seletivamente, mas o baseline é obrigatório, e as fontes e os tokens precisam ser fornecidos ou substituídos explicitamente.
O Aksel usa camadas CSS. Evite seletores amplos fora de camadas, que podem sobrescrever acidentalmente os estilos dos componentes. O layout personalizado da aplicação deve usar suas próprias classes. A prévia independente tem CSS locais versionados e uma fonte substituída intencionalmente; o exemplo de React é um caminho de integração separado, verificado na fonte.
Fixe juntos os pacotes React e CSS.
Importe a folha de estilos uma vez e renderize filhos semânticos de Table.
Mantenha a ordenação e a seleção no estado da aplicação.
Verifique a troca de tema, os controles de teclado e a região de rolagem estreita.
O documento completo inclui layout, controles e inicialização. Extraia o arquivo de exemplo indicado para obter os recursos do fornecedor no caminho relativo exato e, em seguida, disponibilize-o por HTTP.
html
<!doctype html><html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Aksel table workbench</title><link rel="stylesheet" href="vendor/aksel-8.18.0/index.css"><style>:root{--ax-font-family:Arial,sans-serif}body,body *,body *:before,body *:after{font-family:Arial,sans-serif!important}body{background:var(--ax-bg-default);color:var(--ax-text-neutral);font-size:18px;line-height:1.5}main{max-width:64rem;padding:32px 24px;margin:auto}h1{font-size:32px;font-weight:600;line-height:1.25;margin:16px 0 24px}p{margin:16px 0}.toolbar{display:flex;gap:24px;flex-wrap:wrap;padding:24px;background:var(--ax-bg-sunken);margin:24px 0}select{font-size:16px;padding:8px;background:var(--ax-bg-input);color:var(--ax-text-neutral);border:1px solid var(--ax-border-neutral)}label{font-size:16px;display:flex;gap:8px;align-items:center}.scroll{overflow-x:auto}table{min-width:38rem}caption{text-align:left;font-weight:600;margin-bottom:16px}input[type=checkbox]{width:20px;height:20px;accent-color:var(--ax-bg-accent-strong);cursor:pointer}small{font-size:14px;display:block;margin-top:24px;color:var(--ax-text-neutral-subtle)}:focus-visible{outline:3px solid var(--ax-border-focus);outline-offset:3px}@media(max-width:767px){main{padding:24px 16px}.toolbar{padding:16px;gap:16px}h1{font-size:28px}}</style><body class="light"><main><p>AKSEL v8 · NATIVE TABLE CSS</p><h1>Follow-up record workbench</h1><p>Compare density and theme while sorting and selecting fictional records. Selection follows each reference when the rows move.</p><div class="toolbar"><label>Density <select id="density"><option value="medium">Medium</option><option value="small">Small</option><option value="large">Large</option></select></label><label>Theme <select id="theme"><option value="light">Light</option><option value="dark">Dark</option></select></label></div><p id="selection" role="status">0 records selected</p><div class="scroll" tabindex="0" role="region" aria-label="Fictional follow-up records, horizontally scrollable"><table class="aksel-table aksel-table--zebra-stripes" id="records"><caption>Fictional follow-up records</caption><thead class="aksel-table__header"><tr class="aksel-table__row"><th class="aksel-table__header-cell" scope="col"><input id="all" type="checkbox" aria-label="Select all records"></th><th class="aksel-table__header-cell" scope="col">Reference</th><th class="aksel-table__header-cell" scope="col">Next activity</th><th class="aksel-table__header-cell" id="sort-header" scope="col" aria-sort="ascending"><button id="sort" type="button" class="aksel-table__sort-button">Waiting days ↑</button></th></tr></thead><tbody class="aksel-table__body" id="rows"></tbody></table></div><small>OpenDesign specimen using native Aksel 8.18.0 CSS and an explicit Arial fallback. Fictional data, no NAV identity or external actions.</small></main><script>const data=[{id:'DEMO-204',activity:'Confirm appointment preference',days:4},{id:'DEMO-218',activity:'Read the submitted example note',days:12},{id:'DEMO-231',activity:'Arrange an example callback',days:7}];let ascending=true;const selected=new Set(),all=document.querySelector('#all');function render(){const body=document.querySelector('#rows');body.replaceChildren();for(const r of [...data].sort((a,b)=>ascending?a.days-b.days:b.days-a.days)){const tr=document.createElement('tr');tr.className='aksel-table__row'+(selected.has(r.id)?' aksel-table__row--selected':'');const td=document.createElement('td');td.className='aksel-table__data-cell';const c=document.createElement('input');c.type='checkbox';c.setAttribute('aria-label','Select '+r.id);c.checked=selected.has(r.id);c.onchange=()=>{c.checked?selected.add(r.id):selected.delete(r.id);updateSelection();tr.classList.toggle('aksel-table__row--selected',c.checked)};td.append(c);const th=document.createElement('th');th.scope='row';th.className='aksel-table__header-cell';th.textContent=r.id;const activity=document.createElement('td');activity.className='aksel-table__data-cell';activity.textContent=r.activity;const days=document.createElement('td');days.className='aksel-table__data-cell aksel-table__data-cell--align-right';days.textContent=r.days;tr.append(td,th,activity,days);body.append(tr)}updateSelection()}function updateSelection(){all.checked=selected.size===data.length;all.indeterminate=selected.size>0&&selected.size<data.length;document.querySelector('#selection').textContent=selected.size+' records selected'}all.onchange=()=>{selected.clear();if(all.checked)data.forEach(r=>selected.add(r.id));render()};document.querySelector('#sort').onclick=()=>{ascending=!ascending;document.querySelector('#sort-header').setAttribute('aria-sort',ascending?'ascending':'descending');document.querySelector('#sort').textContent='Waiting days '+(ascending?'↑':'↓');render()};document.querySelector('#density').onchange=e=>document.querySelector('table').className='aksel-table aksel-table--zebra-stripes aksel-table--'+e.target.value;document.querySelector('#theme').onchange=e=>document.body.className=e.target.value;render();</script></body></html>
Baixe o exemplo completo em Fontes. O README informa o comando exato para iniciá-lo localmente.
Mantenha os caminhos do fornecedor relativos a este documento; o arquivo inclui todos os recursos usados nesta prévia.
04
Configuração do agente do sistema de design do Aksel
Ponto de partida para implementação
A versão nativa do CSS 8.18.0 é renderizada localmente na prévia. A composição de React foi verificada na fonte, mas não foi compilada separadamente. Mantenha as versões alinhadas; não combine classes navds da v7 com CSS v8. O ZIP completo do exemplo funcional em Sources também fornece as dependências exatas da prévia e o documento completo. Extraia-o, execute python3 -m http.server 8080 nesse diretório e abra http://localhost:8080/nav-aksel.html. Não abra exemplos baseados em módulos usando file://.
Crie uma tabela semântica Aksel v8 usando os pacotes CSS/React correspondentes, na versão 8.18.0. Mantenha a legenda, os cabeçalhos de coluna e os cabeçalhos de linha de referência. Use tokens ax reais e propriedades de primitivas space-*. Ofereça ordenação numérica com aria-sort, seleção por caixas de seleção com IDs estáveis e a opção de selecionar tudo em estado indeterminado. Não dependa de onRowClick para a interação por teclado. Ofereça suporte a tokens de papéis claro/escuro e a uma região identificada de rolagem horizontal em telas estreitas.
05
Fontes e escopo do sistema de design do Aksel
Registros de exemplo independentes e sem identidade NAV. A folha de estilos nativa é usada com uma fonte alternativa informada. Ordenação, seleção e layout são comportamentos da aplicação; nenhum dado real de benefícios ou casos é exibido.