Sistema de componentes sin estilos · Nuevo recurso

Sistema de diseño Ariakit.

Ariakit ofrece componentes React sin estilos, con un estado compartido explícito y partes accesibles que se pueden combinar. Su combobox separa el texto introducido de la selección confirmada, por lo que resulta útil para selectores basados en búsquedas; el buscador de referencias de abajo muestra esa diferencia con resultados agrupados y no disponibles.

Guía de OpenDesign9 capítulos29 entradas de referenciaGuía de aplicación original
01

Vista previa de la interfaz del sistema de diseño Ariakit

Filtra referencias agrupadas, elige con Abajo/Entrar, consulta el resultado y añádelo a una lista de lectura local.

Buscador accesible de referenciasAbrir ejemplo completo
Paquetes nativos @ariakit/react 0.4.40 y React 19. Todos los tokens visuales y el contenido de las referencias de muestra son originales. · Referencia de implementación
02

Ariakit: referencia de diseño del sistema de diseño

Ariakit React 0.4.40 es un conjunto de herramientas de accesibilidad sin estilos. No publica la paleta de colores, la escala tipográfica ni el espaciado de esta página como tema de diseño nativo. Todos los valores --app-* son una configuración original explícita que se utiliza en este ejemplo ejecutable; los nombres de los componentes y los atributos de estado son API de Ariakit.

Configuración original de colores semánticos

Fuente
Nombre / ReglaValor / ConfiguraciónUso
--app-canvas#f5f3ee Fondo de página.
--app-surface#fffPanel emergente de Combobox y tarjeta de referencia.
--app-text#292e29 Texto principal legible.
--app-muted#657064 Etiquetas secundarias y sugerencias.
--app-border#d8ddd4 Límites del campo de entrada y de la tarjeta.
--app-action#285f48 Acción principal e indicador de foco.
--app-on-action#fffTexto de la acción principal.
--app-active#e3eee4 Superficie de la opción activa y de la acción seleccionada.

Geometría y espaciado originales

Fuente
Nombre / ReglaValor / ConfiguraciónUso
--app-radius10pxRadio del campo de entrada, del panel emergente y de la tarjeta de referencia.
--app-space-18pxEscala de espaciado original declarada.
--app-space-216pxEscala de espaciado original declarada.
--app-space-324pxEscala de espaciado original declarada.
--app-space-432pxEscala de espaciado original declarada.
Combobox padding13px 48px 13px 14pxDeja espacio para el control de apertura.
Popover maximum height340pxDesplazamiento local para listas de resultados más largas.
Popover gutter8pxPropiedad gutter que separa realmente el campo de entrada de las sugerencias.

Tipografía original

Fuente
Nombre / ReglaValor / ConfiguraciónUso
Font familysystem-ui, sans-serifNo se necesita descargar fuentes ni usar una fuente específica de Ariakit.
Page heading36px / 1.1; 30px mobileJerarquía original de la página.
Input text15pxTamaño original del texto de Combobox.
Option text14pxTamaño original de las etiquetas de resultados.
Group label11px, uppercase, 700Estilo original de agrupación visible.
Supporting hint12px / 1.7Ritmo de las instrucciones de teclado.

Composición y estado nativos

Fuente
Nombre / ReglaValor / ConfiguraciónUso
ComboboxProvider.inputValueControlled query stringEstado actual del campo de entrada en 0.4.40 de API; setInputValue actualiza el filtrado.
ComboboxProvider.selectedValueControlled reference nameLa selección confirmada es independiente de la consulta.
ComboboxGroup / ComboboxGroupLabelFoundations / ComponentsGrupos de opciones nativos con etiquetas.
ComboboxPopover.sameWidthtrueSe ajusta al ancho del elemento de referencia.
ComboboxItem.disabledtrue for Experimental gridEl registro no disponible no se puede seleccionar.
[data-active-item]CSS state selectorAplica estilos a la opción activa por teclado, independientemente de la selección.
Combobox autoSelectNot enabled in this specimenLa tecla Abajo lleva a la lista antes de que Entrar elija una opción.
03

Ariakit: guía completa del sistema de diseño

Una guía práctica para elegir, aplicar y revisar este sistema en una interfaz real.

DESIGN-ariakit.md

Orientación completa, un punto de partida para la implementación y enlaces al código fuente.

Descargar la guía

Sistema de diseño Ariakit: empieza con el modelo de estado de Combobox

Empieza con el modelo de estado de Combobox

ComboboxProvider de Ariakit conecta la etiqueta, el campo de entrada editable, el control de apertura, la ventana emergente y las opciones. El proveedor mantiene el estado de interacción compartido, mientras cada componente aporta su parte de la estructura. Así, el campo de búsqueda y el panel con los detalles de la selección se pueden organizar de forma independiente, sin tratar cada pulsación como una nueva selección.

De esta guía de OpenDesign

El buscador de referencias muestra seis registros en dos grupos con nombre. El filtrado corresponde a la colección de la aplicación; la navegación y la selección de opciones, al Combobox nativo. Mantener explícito este límite resulta útil al sustituir los registros estáticos por otra fuente de datos: el conjunto de resultados filtrados y el elemento confirmado actual no tienen por qué ser el mismo.

Consulta la especificación complementaria

Sistema de diseño Ariakit: el texto de búsqueda y la selección confirmada son estados distintos

El texto de búsqueda y la selección confirmada son estados distintos

El ejemplo controla inputValue y setInputValue para el texto que se escribe, y selectedValue y setSelectedValue para la referencia elegida. En API 0.4.40, cuya versión se ha verificado, inputValue es el nombre actual del estado del campo de entrada; en ejemplos anteriores pueden aparecer los alias obsoletos value/setValue. El código completo utiliza los nombres actuales.

Escribir «color» reduce las sugerencias, pero no reemplaza inmediatamente la tarjeta con los detalles mostrados. Al elegir «Funciones del color», se confirma ese elemento y se actualiza el panel. Del mismo modo, al borrar la búsqueda, la última referencia seleccionada permanece intacta. Si cada consulta parcial se tratara como un valor confirmado, la vista de detalles saltaría a registros inválidos o inexistentes.

Consulta la especificación complementaria

Sistema de diseño Ariakit: conecta la etiqueta, el campo de entrada, el control de apertura y el panel emergente

Conecta la etiqueta, el campo de entrada, el control de apertura y el panel emergente

ComboboxProvider proporciona estado compartido a ComboboxLabel, Combobox, ComboboxDisclosure y ComboboxPopover. La etiqueta visible identifica el campo de entrada. El botón de divulgación es un botón independiente con un nombre accesible explícito, mientras que el panel emergente usa sameWidth y un margen de ocho píxeles para mantenerse alineado con el elemento de anclaje.

Cada resultado es un ComboboxItem con un valor estable. Foundations y Components son secciones ComboboxGroup nativas con encabezados ComboboxGroupLabel. Un encabezado en negrita insertado en una lista sin estructura no expresaría la misma relación de agrupación; la estructura nativa incorpora esa relación y su modelo de teclado.

Consulta la especificación complementaria

Sistema de diseño Ariakit: filtra los datos antes de representar los elementos nativos

Filtra los datos antes de mostrar los elementos nativos

La colección de ejemplo contiene cinco referencias disponibles y una cuadrícula Experimental marcada deliberadamente como no disponible. El filtrado se realiza en la aplicación mediante una coincidencia de subcadena sin distinguir mayúsculas de minúsculas con el nombre de cada referencia. Los dos grupos solo se representan cuando contienen registros coincidentes, evitando encabezados vacíos entre los resultados.

Una búsqueda sin resultados muestra un mensaje específico que sugiere borrar la búsqueda o probar con «color». El mensaje no se convierte en una opción seleccionable. El registro deshabilitado sigue visible cuando corresponde y lleva la etiqueta «No disponible», mientras que la propiedad nativa disabled impide que se convierta en una selección confirmada.

Consulta la especificación complementaria

Sistema de diseño Ariakit: verifica la secuencia real de Flecha abajo y Enter

Verifica el recorrido real con las teclas Abajo y Entrar

El ejemplo deja autoSelect desactivado. Después de escribir una búsqueda, Flecha abajo lleva a la lista de sugerencias y Enter selecciona el elemento activo. Escape cierra el panel emergente. Esto coincide con las instrucciones visibles y se verificó con el título del detalle seleccionado, no solo comprobando si aparecía un menú desplegable.

El resaltado automático puede ser adecuado para otro producto, pero cambia el punto de partida de la navegación con las flechas. Si ya hay un único resultado activo, otra pulsación de Flecha abajo puede devolver el foco al campo de entrada. El ejemplo evita esa discrepancia y aplica estilos al elemento activo mediante data-active-item, para mantener diferenciada la posición del teclado de la pertenencia a la lista de lectura guardada.

  1. Escribe «color» y espera a que aparezca la opción correspondiente.
  2. Pulsa Flecha abajo y luego Enter; inspecciona el panel de detalle de Roles de color.
  3. Busca una referencia no disponible o inexistente y confirma que no se guarde ninguna selección por error.

Consulta la especificación complementaria

Sistema de diseño Ariakit: el elemento activo, el anillo de foco y el estado guardado tienen indicadores distintos

La opción activa, el indicador de foco y el estado guardado tienen señales distintas

El campo de entrada y el botón de divulgación muestran contornos de foco visibles. La opción activa recibe un fondo verde pálido y un contorno interno de un píxel mediante el atributo nativo data-active-item. Las opciones deshabilitadas tienen menos énfasis y conservan su etiqueta de texto explícita. Estos estilos no dependen únicamente del estado de hover.

El botón Añadir se deshabilita y cambia de texto cuando la referencia seleccionada ya está en la lista de lectura. Ese estado guardado pertenece a la aplicación y es independiente del resultado activo actual del combobox. Un fondo verde pálido para la acción guardada evita representar una acción deshabilitada como otro botón principal habilitado.

Consulta la especificación complementaria

Sistema de diseño Ariakit: una lista de lectura no sustituye la referencia actual

Una lista de lectura no sustituye la referencia actual

Al añadir una referencia, su nombre se agrega una sola vez a una matriz local; la referencia actual permanece visible para que el usuario pueda consultar sus notas. Cada fila de la lista de lectura tiene un botón Quitar con un nombre específico. Quitar una entrada vuelve a habilitar Añadir si esa referencia sigue seleccionada. El recuento se calcula a partir de la longitud de la matriz.

El contenido de detalle de ejemplo incluye recomendaciones sobre tipografía, espaciado y componentes para que resulte útil explorar el buscador. Sus valores están claramente identificados como contenido de ejemplo original. No se debe confundir «Pantalla 36px» en el registro de escala tipográfica con un token tipográfico de Ariakit; Ariakit no proporciona ese lenguaje de diseño.

Consulta la especificación complementaria

Sistema de diseño Ariakit: un panel emergente necesita espacio sin cambiar el tamaño de toda la página

Un panel emergente necesita espacio sin cambiar el tamaño de toda la página

El panel emergente sigue el ancho del campo de entrada y limita su propia altura a 340px. Si hay más resultados, estos se desplazan dentro de ese límite, mientras que la tarjeta de detalle seleccionado permanece como contenido normal del documento. Mantén conectados el campo de entrada, el botón de divulgación y el panel de opciones, aunque la tarjeta de detalle se mueva a otra columna; confirmar un elemento debe seguir actualizando el mismo registro seleccionado.

En el punto de quiebre original de 700px, el buscador y la tarjeta de detalle se apilan. Los controles de búsqueda, la indicación del teclado y la lista de lectura permanecen antes de la tarjeta seleccionada en el orden del documento. El arte decorativo de las referencias se oculta a las tecnologías de asistencia porque el título y las notas aportan el significado real.

  • Limita localmente una lista larga de opciones y conserva un espaciado legible entre elementos.
  • Mantén el panel de detalle confirmado fuera del panel emergente transitorio.
  • Conserva las etiquetas visibles del campo de entrada y las indicaciones del teclado en dispositivos móviles.

Consulta la especificación complementaria

Sistema de diseño Ariakit: conecta el proveedor, la colección y la hoja de estilos

Conecta el proveedor, la colección y la hoja de estilos

Instala @ariakit/react 0.4.40 en el proyecto de React y conserva la composición completa de proveedor y componentes de App.jsx. El ejemplo actual usa inputValue/setInputValue y selectedValue/setSelectedValue como pares controlados independientes. Mantén disponible el registro seleccionado aunque la búsqueda actual lo excluya de los resultados del panel emergente.

Importa el style.css proporcionado junto con el componente. Su regla data-active-item refleja la posición del teclado en el combobox, mientras que los estilos de la lista guardada reflejan el estado de la aplicación. Al sustituir los resultados por otros cargados de forma asíncrona, conserva esos dos canales de estado y las relaciones entre grupos y opciones; no reemplaces el panel de detalle confirmado por una cadena de búsqueda intermedia.

Consulta la especificación complementaria

Sistema de diseño Ariakit Ejemplos de componentes

Buscador de referencias controlado completo

Proveedor, etiqueta, campo de entrada, botón de divulgación, elementos agrupados del panel emergente y acciones locales de la lista de lectura.

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>}

Referencia de código

  • inputValue es la cadena de búsqueda; selectedValue es la referencia confirmada.
  • Los elementos deshabilitados permanecen visibles cuando coinciden con la búsqueda.
  • Los valores originales de tipografía y espaciado del ejemplo no son valores predeterminados de Ariakit.

Configuración visual original completa

Variables semánticas de la aplicación, anillos de foco, estilos de opciones activas y diseño adaptable.

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}}

Referencia de código

  • Ariakit proporciona comportamiento y semántica, no este sistema de colores ni de espaciado.
  • El resultado activo se estiliza mediante data-active-item.
  • El popover tiene una altura máxima y una región de desplazamiento propias.
04

Configuración del agente del sistema de diseño de Ariakit

Punto de partida para la implementación

Verificado con @ariakit/react 0.4.40 y React 19. Usa los nombres actuales inputValue/setInputValue y un 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

Una instrucción para tu proyecto

Instrucción para el agente
Usa el buscador de referencias suministrado de Ariakit 0.4.40 en React. Mantén inputValue/setInputValue de ComboboxProvider independientes de selectedValue/setSelectedValue, conserva los grupos nativos con etiquetas y la opción de cuadrícula Experimental deshabilitada, y filtra los datos antes de representar los elementos. Conserva la secuencia verificada de pulsar Abajo y luego Intro con autoSelect desactivado, y aplica estilos por separado a data-active-item y a la pertenencia a elementos guardados. Añade la referencia confirmada a una lista de lectura local sin duplicados y permite eliminarla sin descartar el detalle actual. Incluye la hoja de estilos original completa.
05

Fuentes y alcance del sistema de diseño de Ariakit

Ariakit React 0.4.40. Todos los tokens visuales, las ilustraciones y los valores de referencia de ejemplo son configuraciones originales; no se afirma que sean una paleta ni una escala tipográfica oficial de Ariakit. El estado de la lista de lectura es local.