Sistema de componentes sem estilos · Novo recurso

Sistema de design Ariakit.

Ariakit oferece componentes React sem estilo, com estado compartilhado explícito e partes acessíveis que podem ser compostas. Seu combobox separa o texto digitado da seleção confirmada, sendo útil para seletores com busca; o localizador de referências abaixo demonstra essa distinção com resultados agrupados e indisponíveis.

Guia OpenDesign9 capítulos29 entradas de referênciaGuia de aplicação original
01

Pré-visualização da interface do sistema de design Ariakit

Filtre referências agrupadas, escolha com seta para baixo/Enter, confira o resultado e adicione-o a uma lista de leitura local.

Localizador de referências acessívelAbrir exemplo completo
@ariakit/react 0.4.40 nativo e React 19. Todos os tokens visuais e o conteúdo de referência de exemplo são originais. · Referência de implementação
02

Referência de design do sistema de design Ariakit

Ariakit React 0.4.40 é um conjunto de ferramentas de acessibilidade sem estilos. Ele não oferece a paleta da página, a escala tipográfica nem o espaçamento abaixo como tema de design nativo. Todos os valores --app-* são configurações originais explícitas, usadas neste exemplo executável; os nomes dos componentes e os atributos de estado são APIs de Ariakit.

Configuração original de cores semânticas

Fonte
Nome / RegraValor / ConfiguraçãoUso
--app-canvas#f5f3ee Plano de fundo da página.
--app-surface#fffPopover da caixa de combinação e cartão de referência.
--app-text#292e29 Texto principal de leitura.
--app-muted#657064 Rótulos secundários e dicas.
--app-border#d8ddd4 Contornos do campo de entrada e do cartão.
--app-action#285f48 Ação principal e indicador de foco.
--app-on-action#fffTexto da ação principal.
--app-active#e3eee4 Fundo da opção ativa e da ação selecionada.

Geometria e espaçamento originais

Fonte
Nome / RegraValor / ConfiguraçãoUso
--app-radius10pxArredondamento dos cantos do campo de entrada, do popover e do cartão de referência.
--app-space-18pxEscala de espaçamento original declarada.
--app-space-216pxEscala de espaçamento original declarada.
--app-space-324pxEscala de espaçamento original declarada.
--app-space-432pxEscala de espaçamento original declarada.
Combobox padding13px 48px 13px 14pxReserva espaço para o controle de abertura.
Popover maximum height340pxRolagem local para listas de resultados mais longas.
Popover gutter8pxEspaçamento real definido pela propriedade gutter entre o campo de entrada e as sugestões.

Tipografia original

Fonte
Nome / RegraValor / ConfiguraçãoUso
Font familysystem-ui, sans-serifNão é necessário baixar fontes nem usar uma fonte específica de Ariakit.
Page heading36px / 1.1; 30px mobileHierarquia original da página.
Input text15pxTamanho original do texto da caixa de combinação.
Option text14pxTamanho original dos rótulos dos resultados.
Group label11px, uppercase, 700Estilo original de agrupamento visível.
Supporting hint12px / 1.7Ritmo das instruções de teclado.

Composição e estados nativos

Fonte
Nome / RegraValor / ConfiguraçãoUso
ComboboxProvider.inputValueControlled query stringEstado atual do campo de entrada em 0.4.40 API; setInputValue atualiza o filtro.
ComboboxProvider.selectedValueControlled reference nameA seleção confirmada é independente da consulta.
ComboboxGroup / ComboboxGroupLabelFoundations / ComponentsGrupos nativos de opções com rótulos.
ComboboxPopover.sameWidthtrueAcompanha a largura da âncora.
ComboboxItem.disabledtrue for Experimental gridNão é possível selecionar um registro indisponível.
[data-active-item]CSS state selectorEstiliza a opção ativa pelo teclado, independentemente da seleção.
Combobox autoSelectNot enabled in this specimenA seta para baixo move o foco para a lista antes que Enter escolha uma opção.
03

Guia completo do sistema de design Ariakit

Um guia prático para escolher, aplicar e avaliar este sistema em uma interface real.

DESIGN-ariakit.md

Orientações completas, um ponto de partida para a implementação e links para o código-fonte.

Baixar o guia

Sistema de design Ariakit: comece pelo modelo de estado da caixa de combinação

Comece pelo modelo de estado da caixa de combinação

ComboboxProvider de Ariakit conecta o rótulo, o campo de entrada editável, o controle de abertura, o pop-up e as opções. O provedor gerencia o estado compartilhado de interação, enquanto cada componente compõe sua parte da estrutura. Assim, o campo de busca e o painel de detalhes da seleção podem ser organizados separadamente, sem tratar cada tecla digitada como uma nova seleção.

Com base neste guia de OpenDesign

O localizador de referências mostra seis registros em dois grupos identificados. A filtragem cabe à coleção da aplicação; a navegação e a seleção de opções cabem à caixa de combinação nativa. Deixar essa separação explícita é útil ao substituir registros estáticos por outra fonte de dados: o conjunto filtrado de resultados e o item atualmente confirmado não são necessariamente iguais.

Consulte a especificação de apoio

Sistema de design Ariakit: o texto de busca e a seleção confirmada são estados diferentes

O texto de busca e a seleção confirmada são estados diferentes

O exemplo controla inputValue e setInputValue para o texto digitado e selectedValue e setSelectedValue para a referência escolhida. Na versão 0.4.40 verificada do API, inputValue é o nome atual do estado do campo de entrada; exemplos mais antigos podem mostrar os aliases obsoletos value/setValue. O código completo usa os nomes atuais.

Digitar “color” restringe as sugestões, mas não substitui imediatamente o cartão de detalhes exibido. Ao escolher Color roles, esse item é confirmado e o painel é atualizado. Da mesma forma, limpar a busca mantém a última referência selecionada. Tratar cada consulta parcial como um valor confirmado faria a visualização de detalhes saltar para registros inválidos ou inexistentes.

Consulte a especificação de apoio

Sistema de design Ariakit: conecte o rótulo, o campo de entrada, o controle de abertura e o popover

Conecte o rótulo, o campo de entrada, o controle de abertura e o popover

ComboboxProvider fornece estado compartilhado a ComboboxLabel, Combobox, ComboboxDisclosure e ComboboxPopover. O rótulo visível identifica o campo de entrada. O botão de abertura é um botão separado, com um nome acessível explícito, enquanto o popover usa sameWidth e um espaçamento de oito pixels para permanecer alinhado à âncora.

Cada resultado é um ComboboxItem com um valor estável. Foundations e Components são seções nativas de ComboboxGroup, com títulos ComboboxGroupLabel. Inserir um título em negrito visual em uma lista sem estrutura não expressaria a mesma relação de agrupamento; a anatomia nativa transmite essa relação junto com seu modelo de navegação por teclado.

Consulte a especificação de apoio

Sistema de design Ariakit Filtre os dados antes de renderizar os itens nativos

Filtre os dados antes de renderizar os itens nativos

A coleção de exemplo contém cinco referências disponíveis e uma grade Experimental intencionalmente indisponível. A filtragem é uma correspondência parcial, sem distinção entre maiúsculas e minúsculas, feita no nível da aplicação em relação ao nome de cada referência. Os dois grupos só são renderizados quando contêm registros correspondentes, evitando títulos vazios entre os resultados.

Uma consulta sem resultados exibe uma mensagem específica, que sugere limpar a pesquisa ou tentar “color”. A mensagem não se transforma em uma opção selecionável. O registro desativado permanece visível quando relevante e recebe o rótulo Unavailable, enquanto a propriedade nativa disabled impede que ele se torne uma seleção confirmada.

Consulte a especificação de apoio

Sistema de design Ariakit Verifique o fluxo real de pressionar Down e Enter

Verifique o percurso real com as teclas de seta para baixo e Enter

O exemplo mantém autoSelect desativado. Depois de digitar uma consulta, Down abre a lista de sugestões e Enter seleciona o item ativo. Escape fecha o popover. Esse comportamento corresponde às instruções visíveis e foi verificado pelo título dos detalhes selecionados, não apenas pela abertura de uma lista suspensa.

O destaque automático pode ser adequado em outro produto, mas altera o ponto de partida da navegação pelas setas. Quando há apenas um resultado já ativo, pressionar Down novamente pode devolver o foco ao campo de entrada. O exemplo evita essa incompatibilidade e estiliza o item ativo por meio de data-active-item, mantendo a posição do teclado distinta da presença do item salvo na lista de leitura.

  1. Digite “color” e aguarde a opção correspondente.
  2. Pressione Down e depois Enter; confira o painel de detalhes Color roles.
  3. Pesquise uma referência indisponível ou inexistente e confirme que nenhuma seleção indesejada é registrada.

Consulte a especificação de apoio

Sistema de design Ariakit A opção ativa, o contorno de foco e o estado salvo têm indicadores diferentes

A opção ativa, o indicador de foco e o estado salvo têm sinais distintos

O campo de entrada e o botão de abertura exibem contornos de foco visíveis. A opção ativa recebe um fundo verde-claro e um contorno interno de um pixel por meio do atributo nativo data-active-item. As opções desativadas têm menos destaque e mantêm seu rótulo textual explícito. Esses estilos não dependem apenas do estado de hover.

O botão Add é desativado e seu texto muda quando a referência selecionada já está na lista de leitura. Esse estado salvo pertence à aplicação e é diferente do resultado atualmente ativo no combobox. Um fundo verde-claro para a ação salva evita representar uma ação desativada como outro botão primário habilitado.

Consulte a especificação de apoio

Sistema de design Ariakit A lista de leitura não substitui a referência atual

Uma lista de leitura não substitui a referência atual

Adicionar uma referência acrescenta seu nome a um array local, sem duplicá-lo; a referência atual continua visível para que a pessoa usuária possa consultar suas notas. Cada item da lista de leitura tem um botão Remove com nome específico. Remover um item reativa Add se essa referência ainda estiver selecionada. A contagem é derivada do tamanho do array.

O conteúdo de exemplo dos detalhes inclui orientações sobre tipografia, espaçamento e componentes para tornar útil a exploração do localizador. Seus valores são claramente identificados como conteúdo original de exemplo. A pessoa que consulta não deve confundir “Display 36px” no registro Type scale com um token de tipografia de Ariakit; Ariakit não fornece essa linguagem visual.

Consulte a especificação de apoio

Sistema de design Ariakit O popover precisa de espaço sem redimensionar a página inteira

O popover precisa de espaço sem redimensionar a página inteira

O popover acompanha a largura do campo de entrada e limita a própria altura a 340px. Uma coleção maior de resultados rola dentro desse limite, enquanto o cartão de detalhes selecionados permanece no fluxo normal do documento. Mantenha o campo de entrada, o botão de abertura e o pop-up de opções conectados, mesmo que o cartão de detalhes passe para outra coluna; confirmar um item ainda deve atualizar o mesmo registro selecionado.

No ponto de interrupção original de 700px, o localizador e o cartão de detalhes ficam empilhados. Os controles de pesquisa, a dica de teclado e a lista de leitura permanecem antes do cartão selecionado na ordem do documento. A ilustração decorativa das referências fica oculta para tecnologias assistivas, pois o título e as notas transmitem o significado real.

  • Limite localmente uma lista longa de opções, preservando um espaçamento confortável entre os itens.
  • Mantenha o painel de detalhes confirmados fora do popover temporário.
  • Mantenha os rótulos visíveis dos campos de entrada e as dicas de teclado em dispositivos móveis.

Consulte a especificação de apoio

Sistema de design Ariakit Conecte o Provider, a coleção e a folha de estilos

Conecte o Provider, a coleção e a folha de estilos

Instale @ariakit/react 0.4.40 no projeto React e mantenha a composição completa de provider e componentes de App.jsx. O exemplo atual usa inputValue/setInputValue e selectedValue/setSelectedValue como pares controlados separados. Mantenha o registro selecionado disponível mesmo quando a consulta atual do campo de entrada o filtrar para fora do pop-up.

Importe o style.css fornecido junto com o componente. A regra data-active-item acompanha a posição do teclado no combobox, enquanto os estilos da lista de itens salvos acompanham o estado da aplicação. Ao substituir os resultados por dados carregados de forma assíncrona, preserve esses dois canais de estado e as relações entre grupos e opções; não substitua o painel de detalhes confirmados por uma string de consulta intermediária.

Consulte a especificação de apoio

Ariakit Exemplos de componentes do sistema de design

Localizador de referências totalmente controlado

Provider, rótulo, campo de entrada, botão de abertura, itens agrupados do popover e ações locais da lista de leitura.

jsx
import React,{useState} from 'react';
import * as Ariakit from '@ariakit/react';
const resources=[{name:'Type scale',group:'Foundations',code:'Aa',description:'A compact editorial hierarchy for headings, supporting text and labels.',notes:['Display · 36px / 1.1','Section · 24px / 1.25','Body · 16px / 1.6'],color:'#f0dbc3'},{name:'Color roles',group:'Foundations',code:'◐',description:'Separate surface, text, boundary and action roles before naming brand colors.',notes:['Canvas and raised surface','Primary and muted text','Action and on-action pair'],color:'#d6e5d8'},{name:'Spacing rhythm',group:'Foundations',code:'▥',description:'Use a small set of intervals to show relationships between content groups.',notes:['8px within a compact group','16px between related controls','32px between sections'],color:'#d6dfee'},{name:'Form field',group:'Components',code:'⌑',description:'Keep the label, hint, input and error message in one understandable group.',notes:['Persistent visible label','Hint before an error exists','Error connected to the input'],color:'#e9d8de'},{name:'Navigation menu',group:'Components',code:'☷',description:'A small set of destinations with a visible current location and keyboard access.',notes:['Destination labels describe content','Current item has a text/state cue','Collapsed layout keeps names'],color:'#e7e0c5'},{name:'Experimental grid',group:'Components',code:'▦',description:'Unavailable in this sample collection.',notes:[],color:'#e3e3e3',disabled:true}];
export default function App(){const[query,setQuery]=useState(''),[chosen,setChosen]=useState('Type scale'),[saved,setSaved]=useState([]);const selected=resources.find(x=>x.name===chosen)||resources[0],matches=resources.filter(x=>x.name.toLowerCase().includes(query.toLowerCase()));return <main className="resource-finder"><header><p className="eyebrow">ARIAKIT · ACCESSIBLE PRIMITIVES</p><h1>A reference, within reach.</h1><p>Search a small collection with the keyboard, inspect the result and keep a local reading list.</p></header><div className="finder-grid"><section className="search-area"><Ariakit.ComboboxProvider inputValue={query} setInputValue={setQuery} selectedValue={chosen} setSelectedValue={setChosen}><Ariakit.ComboboxLabel className="label">Find a reference</Ariakit.ComboboxLabel><div className="input-row"><Ariakit.Combobox className="combobox" placeholder="Try type, color or form" /><Ariakit.ComboboxDisclosure className="disclosure" aria-label="Show reference suggestions">⌄</Ariakit.ComboboxDisclosure></div><Ariakit.ComboboxPopover gutter={8} sameWidth className="popover">{['Foundations','Components'].map(group=>{const items=matches.filter(x=>x.group===group);return items.length?<Ariakit.ComboboxGroup key={group}><Ariakit.ComboboxGroupLabel className="group-label">{group}</Ariakit.ComboboxGroupLabel>{items.map(x=><Ariakit.ComboboxItem key={x.name} value={x.name} disabled={x.disabled} className="combo-item"><span>{x.name}</span><small>{x.disabled?'Unavailable':x.group==='Foundations'?'Guide':'Pattern'}</small></Ariakit.ComboboxItem>)}</Ariakit.ComboboxGroup>:null})}{!matches.length&&<p className="empty" role="status">No matching reference. Try “color” or clear the search.</p>}</Ariakit.ComboboxPopover></Ariakit.ComboboxProvider><p className="hint">Type to filter. Use ↓ and ↑ to browse, Enter to choose, Escape to close.</p><div className="collection-note"><span>06</span><div><strong>Sample references</strong><p>Five available, one deliberately disabled to show an unavailable item.</p></div></div><section className="reading-list"><h2>Your reading list <small>{saved.length}</small></h2>{saved.length?<ul>{saved.map(name=><li key={name}><span>{name}</span><Ariakit.Button className="remove" onClick={()=>setSaved(saved.filter(x=>x!==name))} aria-label={`Remove ${name}`}>Remove</Ariakit.Button></li>)}</ul>:<p className="muted">Choose a reference, then add it here.</p>}<p className="local-note">This list stays in memory and clears on reload.</p></section></section><section className="reference-card" aria-label="Selected reference"><div className="reference-art" style={{background:selected.color}} aria-hidden="true"><span>{selected.code}</span><i></i></div><div className="reference-body"><p className="eyebrow">{selected.group} · SAMPLE CONTENT</p><h2>{selected.name}</h2><p>{selected.description}</p><ul className="note-list">{selected.notes.map(note=><li key={note}>{note}</li>)}</ul><Ariakit.Button className="primary" disabled={saved.includes(selected.name)} onClick={()=>setSaved([...saved,selected.name])}>{saved.includes(selected.name)?'Added to reading list':'Add to reading list'}</Ariakit.Button><p className="scope-note">These sample reference values are original content, not Ariakit design tokens.</p></div></section></div><p className="selection-status" role="status">Selected reference: {selected.name}</p></main>}

Referência de código

  • inputValue é a string de pesquisa; selectedValue é a referência confirmada.
  • Os itens desativados permanecem visíveis quando correspondem à consulta.
  • Os valores originais de tipografia e espaçamento do exemplo não são padrões de Ariakit.

Configuração visual original completa

Variáveis semânticas da aplicação, contornos de foco, estilos da opção ativa e layout responsivo.

css
:root{--app-canvas:#f5f3ee;--app-surface:#fff;--app-text:#292e29;--app-muted:#657064;--app-border:#d8ddd4;--app-action:#285f48;--app-on-action:#fff;--app-active:#e3eee4;--app-radius:10px;--app-space-1:8px;--app-space-2:16px;--app-space-3:24px;--app-space-4:32px;font-family:system-ui,sans-serif}*{box-sizing:border-box}body{margin:0;background:var(--app-canvas);color:var(--app-text)}button,input{font:inherit}.resource-finder{max-width:1080px;padding:32px;margin:auto}.eyebrow{font-size:11px;font-weight:700;letter-spacing:.13em;color:var(--app-muted)}h1{font-size:36px;line-height:1.1;margin:16px 0}header>p:last-child{font-size:15px;line-height:1.7;max-width:620px;color:var(--app-muted)}.finder-grid{display:grid;grid-template-columns:1fr 1.1fr;gap:40px;margin-top:32px}.label{display:block;font-size:14px;font-weight:650;margin-bottom:10px}.input-row{position:relative;display:flex}.combobox{width:100%;padding:13px 48px 13px 14px;border:1px solid var(--app-border);border-radius:var(--app-radius);background:var(--app-surface);color:var(--app-text);font-size:15px}.disclosure{position:absolute;right:4px;top:4px;bottom:4px;width:36px;border:0;background:transparent;border-radius:6px;cursor:pointer}.combobox:focus,.disclosure:focus-visible,button:focus-visible{outline:3px solid var(--app-action);outline-offset:3px}.popover{z-index:50;max-height:340px;overflow:auto;background:var(--app-surface);border:1px solid var(--app-border);border-radius:var(--app-radius);box-shadow:0 8px 28px #243c2420;padding:8px}.group-label{font-size:11px;letter-spacing:.06em;text-transform:uppercase;font-weight:700;color:var(--app-muted);padding:10px}.combo-item{display:flex;justify-content:space-between;gap:16px;align-items:center;padding:12px 10px;border-radius:6px;cursor:default;font-size:14px;scroll-margin:8px}.combo-item small{font-size:11px;color:var(--app-muted)}.combo-item[data-active-item]{background:var(--app-active);outline:1px solid var(--app-action);outline-offset:-1px}.combo-item[aria-disabled=true]{opacity:.45}.empty{padding:12px;font-size:14px;line-height:1.6}.hint{font-size:12px;line-height:1.7;color:var(--app-muted);margin-top:12px}.collection-note{display:flex;gap:16px;align-items:flex-start;border-block:1px solid var(--app-border);padding:24px 0;margin:28px 0}.collection-note>span{font-size:40px;line-height:1;color:var(--app-action)}.collection-note strong{font-size:14px}.collection-note p{font-size:13px;line-height:1.6;color:var(--app-muted);margin:8px 0 0}.reading-list h2{font-size:17px;display:flex;justify-content:space-between}.reading-list h2 small{background:var(--app-active);border-radius:30px;padding:3px 8px}.reading-list ul{padding:0;list-style:none}.reading-list li{display:flex;justify-content:space-between;gap:12px;padding:12px 0;border-bottom:1px solid var(--app-border);font-size:14px}.remove{background:none;border:0;text-decoration:underline;color:var(--app-action);font-size:12px;cursor:pointer}.muted,.local-note,.scope-note{color:var(--app-muted);font-size:12px;line-height:1.7}.reference-card{border:1px solid var(--app-border);border-radius:var(--app-radius);overflow:hidden;background:var(--app-surface)}.reference-art{height:160px;position:relative;display:flex;align-items:center;justify-content:center;overflow:hidden}.reference-art span{font-size:96px;font-family:Georgia,serif;line-height:1;position:relative;z-index:1}.reference-art i{position:absolute;width:190px;height:190px;border:1px solid currentColor;opacity:.2;border-radius:50%;left:50%;top:35%}.reference-body{padding:24px}.reference-body h2{font-size:28px;margin:12px 0}.reference-body>p{line-height:1.65;font-size:14px}.note-list{list-style:none;padding:0;margin:24px 0}.note-list li{padding:10px 0;border-bottom:1px solid var(--app-border);font-size:13px}.primary{padding:12px 18px;border:1px solid var(--app-action);background:var(--app-action);color:var(--app-on-action);border-radius:6px;cursor:pointer;font-weight:600;font-size:14px}.primary:disabled{background:var(--app-active);color:var(--app-action);cursor:default}.scope-note{margin-top:16px}.selection-status{font-size:12px;color:var(--app-muted);margin-top:24px}@media(max-width:700px){.resource-finder{padding:24px 16px}h1{font-size:30px}.finder-grid{grid-template-columns:1fr;gap:28px}.reference-art{height:135px}}

Referência de código

  • Ariakit fornece comportamento e semântica, não este sistema de cores ou espaçamento.
  • O resultado ativo é estilizado por meio de data-active-item.
  • O pop-over tem sua própria altura máxima e área de rolagem.
04

Configuração do agente do sistema de design Ariakit

Ponto de partida para implementação

Verificado com @ariakit/react 0.4.40 e React 19. Usa os nomes atuais inputValue/setInputValue e um selectedValue controlado.

jsx
// Create the project first:
// npm create vite@latest ariakit-specimen -- --template react
// cd ariakit-specimen && npm install
// In a Vite React project:
// npm install @ariakit/[email protected] react@19 react-dom@19
// Save the complete component as App.jsx and the visual configuration as style.css.
import React from 'react';
import {createRoot} from 'react-dom/client';
import App from './App.jsx';
import './style.css';
createRoot(document.getElementById('root')).render(<App />);
// index.html contains <div id="root"></div>.
// No Ariakit theme stylesheet is required; style.css is this example's original theme.
// Keep the template index.html and replace its entry with the code above.
// npm run dev

Um prompt para seu projeto

Prompt para agente de IA
Use o localizador de referências fornecido para Ariakit 0.4.40 em React. Mantenha inputValue/setInputValue de ComboboxProvider independentes de selectedValue/setSelectedValue, preserve os grupos nativos com rótulos e a opção de grade Experimental desativada, e filtre os dados antes de renderizar os itens. Preserve o fluxo verificado de pressionar Down e depois Enter com autoSelect desativado, e estilize data-active-item separadamente dos itens salvos. Adicione a referência confirmada a uma lista de leitura local sem duplicatas e permita removê-la sem descartar os detalhes atuais. Inclua a folha de estilos original completa.
05

Fontes e escopo do sistema de design Ariakit

Ariakit React 0.4.40. Todos os tokens visuais, ilustrações e valores de referência de exemplo são configurações originais; não se afirma que sejam a paleta ou a escala tipográfica oficial de Ariakit. O estado da lista de leitura é local.