Sistema de componentes sin estilos · Nuevo recurso

Sistema de diseño Bits UI.

Bits UI ofrece componentes headless de Svelte que se componen mediante partes nativas y el estado de Svelte 5. El ejemplo combina una casilla de verificación con estado mixto calculado, secciones de acordeón que se expanden de forma independiente y un diálogo de revisión basado en portal, e incluye toda la configuración de estilos.

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

Vista previa de la interfaz del sistema de diseño Bits UI

Marca una comprobación individual, inspecciona el estado mixto del control general, revisa el progreso incompleto y, luego, completa y guarda la lista de verificación local.

Revisión manual de la interfazAbrir ejemplo completo
Casilla de verificación, acordeón y diálogo de Bits UI 2.19.5 con Svelte 5.57.1. Todo el estilo visual es original. · Referencia de implementación
02

Referencia de diseño del sistema de diseño Bits UI

Bits UI 2.19.5 con Svelte 5.57.1. Bits UI no incluye estilos: todos los valores de color, tipografía y espaciado --app-* son la configuración original y explícita incluida en este ejemplo, no son tokens oficiales de diseño de Bits UI. Los atributos de datos nativos y las propiedades de los componentes se identifican por separado.

Configuración semántica original de CSS

Fuente
Nombre / ReglaValor / ConfiguraciónUso
--app-canvas#f4f3f8 Fondo de página.
--app-surface#ffffff Superficie del panel y del diálogo.
--app-ink#2d2938 Texto principal.
--app-muted#746d80 Texto complementario.
--app-line#e3dfeb Separadores y bordes.
--app-action#604c88 Controles marcados y acciones principales.
--app-on-action#fffTexto de las acciones.
--app-focus#9a80ce Foco visible del teclado.
--app-soft#eee8f7 Rol opcional de superficie suave.

Geometría y espaciado originales

Fuente
Nombre / ReglaValor / ConfiguraciónUso
--app-space-14pxUnidad de espaciado con nombre más pequeña.
--app-space-28pxEspaciado compacto.
--app-space-312pxSeparación entre control y etiqueta.
--app-space-416pxMargen interior estrecho del panel.
--app-space-624pxMargen interior del panel y separación entre columnas en escritorio.
--app-space-832pxMargen interior de la página en escritorio.
Checkbox geometry22×22px; 5px radius; 1px borderEstilo explícito original de los controles.
Focus ring3px solid #9a80ce; 3px offsetSe aplica al foco del botón visible mediante el teclado.
Dialog widthmin(440px, 100% − 28px)Geometría explícita original de la superposición adaptable.
Dialog maximum height100vh − 28px with overflow:autoRestricción de la ventana gráfica solo para la superposición; sin dependencia de la altura de la página.
Type hierarchy34px title / 29px mobile; 16px accordion; 13px checks; 12px guidanceJerarquía original de la fuente del sistema.

Contratos de los componentes nativos

Fuente
Nombre / ReglaValor / ConfiguraciónUso
Checkbox.Root checkedbooleanEstado completado o incompleto.
Checkbox.Root indeterminatebooleanEl control general expone un estado mixto cuando hay algunas comprobaciones marcadas.
Checkbox data-statechecked / unchecked / indeterminateSe utiliza directamente en la hoja de estilos.
Accordion.Root typemultiplePueden permanecer abiertas varias secciones de revisión.
Accordion valuestring[]Lista de identificadores de grupos expandidos enlazada con Svelte.
Dialog.Root openboolean, two-way boundControla la visibilidad de la revisión.
Dialog.Title / DescriptionNative title and description relationshipsNo hacen falta identificadores ARIA duplicados creados manualmente.
Dialog.PortalOverlay and content rendered outside the normal panelEvita el recorte al mantener el panel en el flujo del documento.
03

Guía completa del sistema de diseño Bits UI

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

DESIGN-bits-ui.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 Bits UI: compón partes nativas con el estado de Svelte 5

Compón partes nativas con el estado de Svelte 5

La lista de verificación usa $state para las respuestas individuales, los identificadores de las secciones expandidas y la visibilidad del diálogo. Un recuento de finalización derivado con $derived alimenta tanto el progreso visible como la casilla de verificación general. Así, la fuente de verdad reside en un único modelo de Svelte, mientras que Bits UI proporciona la interacción nativa de cada componente.

De esta guía de OpenDesign

La casilla de verificación, el acordeón y el diálogo se componen a partir de sus propias partes. El diálogo de revisión no necesita gestionar las respuestas de la lista de verificación, y el acordeón no tiene que descartarlas al cerrarse. Esta separación es un punto de partida útil para un formulario con varias secciones: el modelo se mantiene aunque cambien las partes de la interfaz que están visibles.

Consulta la especificación complementaria

Sistema de diseño Bits UI: usa conjuntamente las fuentes de componentes y estilos de Svelte 5

Usa conjuntamente las fuentes de componentes y estilos de Svelte 5

El ejemplo utiliza las runas de Svelte 5: $state para los grupos, las secciones expandidas, la visibilidad del diálogo y el estado guardado; y $derived para el recuento de finalización. Bits UI 2.19.5 se importa directamente. No se necesita ningún complemento de Tailwind, proveedor de temas ni biblioteca de iconos para este tratamiento visual original.

App.svelte y style.css completos funcionan en un proyecto Svelte estándar de Vite. La entrada usa mount de Svelte, en lugar del constructor new App anterior. Al trasladar el ejemplo, conserva juntas la sintaxis de runas del componente y la dependencia Bits UI 2.19.5; los enlaces y las funciones de devolución de llamada que se muestran aquí no corresponden a un API de componentes de Svelte anterior.

Consulta la especificación complementaria

Sistema de diseño Bits UI: deriva un estado mixto real de las casillas individuales

Deriva un estado mixto real de las casillas individuales

Hay seis comprobaciones booleanas distribuidas en tres grupos. El control general solo aparece marcado cuando las seis son verdaderas y muestra el estado indeterminado cuando el recuento está entre una y cinco. Su función onCheckedChange actualiza todas las comprobaciones, de modo que el estado mixto es un resultado calculado y no una marca guardada por separado que pueda desincronizarse.

Los controles individuales llaman a una pequeña función de cambio que actualiza el modelo e invalida los mensajes guardados. La casilla de verificación nativa que se representa expone aria-checked=mixed cuando se selecciona una comprobación. La hoja de estilos responde a data-state=checked y data-state=indeterminate, vinculando el comportamiento y la presentación al mismo estado nativo.

  1. Selecciona la primera comprobación del indicador de foco y observa el guion del control general.
  2. Abre la lista de verificación de la revisión y confirma que Guardar revisión completada esté deshabilitado.
  3. Vuelve, marca todas las comprobaciones y guarda la instantánea local completa.

Consulta la especificación complementaria

Sistema de diseño Bits UI: permite secciones independientes sin perder sus respuestas

Permite secciones independientes sin perder sus respuestas

Accordion.Root usa type=multiple y un array enlazado de identificadores de grupos expandidos. El recorrido con el teclado empieza con una sección expandida, mientras que Corrección del formulario y Comentarios del resultado pueden abrirse de forma independiente. Al contraer una sección, sus casillas no se desmarcan, porque sus valores se guardan en el estado del componente padre.

Cada activador muestra de nuevo su propio recuento de elementos completados, así el progreso sigue visible cuando se contrae el contenido. Las partes nativas Header, Trigger y Content conservan la relación esperada y el comportamiento de teclado. El indicador de suma gira según el data-state del activador y respeta las preferencias de movimiento reducido, en lugar de controlar la expansión mediante un controlador de clic independiente.

Consulta la especificación complementaria

Sistema de diseño Bits UI: compón toda la estructura del diálogo y permite que gestione el foco

Compón toda la estructura del diálogo y deja que gestione el foco

La revisión usa Dialog.Root, Trigger, Portal, Overlay, Content, Title, Description y Close. El título y la descripción son partes nativas reales, lo que permite a Bits UI establecer las relaciones accesibles correspondientes. El portal coloca la capa superpuesta fuera del flujo normal del panel de la lista de verificación.

El contenido tiene un ancho adaptable limitado y una altura máxima relativa a la ventana gráfica que solo se aplica a la capa superpuesta, con desplazamiento para revisiones más largas. Escape cierra el diálogo sin borrar la lista de verificación. Mantén disponible el activador como destino al que devolver el foco, en lugar de quitarlo al abrir la capa superpuesta.

Consulta la especificación complementaria

Sistema de diseño Bits UI: define reglas visuales explícitas y reutilizables para la aplicación

Define de forma explícita y reutilizable las reglas visuales de la aplicación

CSS asigna los estados nativo de marcado e indeterminado al mismo rol de acción, pero usa glifos distintos para cada uno. El rol de foco corresponde a la posición del teclado, por lo que un control puede seguir apareciendo seleccionado y, a la vez, mostrar dónde tendrá lugar la siguiente acción con el teclado.

La escala de espaciado con nombre incluye cuatro, ocho, doce, dieciséis, veinticuatro y treinta y dos píxeles. En escritorio, los paneles usan el valor de veinticuatro píxeles; en pantallas estrechas, el de dieciséis. La tabla de especificaciones documenta esas decisiones concretas como configuración original para que los lectores puedan reproducirlas o sustituirlas sin confundir los estilos de demostración con una garantía del paquete.

Consulta la especificación complementaria

Sistema de diseño Bits UI: separa una marca manual del resultado de una prueba automatizada

Separa una marca manual del resultado de una prueba automatizada

La lista de verificación registra lo que el lector ha marcado. No inspecciona otra página, ejecuta pruebas de teclado ni determina el cumplimiento de los requisitos de accesibilidad. Tanto el texto introductorio como la descripción de la revisión dejan claro este alcance, algo necesario porque las seis comprobaciones se refieren a comportamientos de accesibilidad reales.

Guardar permanece desactivado hasta que se marquen las seis casillas. El mensaje de confirmación indica que el lector marcó las seis y que el resultado es local. Aun así, se puede abrir una revisión parcial para comprobar el trabajo pendiente, pero no se mostrará un mensaje de revisión completada. Esa distinción da sentido a los cambios de estado del ejemplo.

Consulta la especificación complementaria

Sistema de diseño Bits UI: actualiza los mensajes de finalización cuando cambien las pruebas

Borra los mensajes de finalización cuando cambien las evidencias

Cualquier cambio individual o masivo borra el estado guardado. Así se evita que una confirmación de finalización siga apareciendo después de desmarcar una casilla. La acción Borrar todo también restaura la sección expandida inicial y cierra el diálogo de revisión, para que todos los estados relacionados vuelvan a un punto de partida conocido.

La región de estado está fuera de la capa superpuesta, por lo que el mensaje guardado permanece en el documento cuando se cierra el diálogo. Describe el estado local de la página y no da a entender que se haya enviado un informe. Al recargar la página se descarta la lista de verificación, lo cual es apropiado para esta demostración independiente.

Consulta la especificación complementaria

Sistema de diseño Bits UI: vincula las partes de los componentes con las etiquetas visibles

Vincula las partes de los componentes con las etiquetas visibles

Cada casilla tiene un ID estable y una etiqueta visible asociada. El estado marcado o indeterminado se representa mediante el control nativo; la marca de verificación y el guion son decorativos. Mantén tanto el valor booleano checked como el valor indeterminate derivado vinculados al control general, para que una selección parcial no se anuncie como un elemento sin marcar normal.

Dialog.Title y Dialog.Description proporcionan el nombre y la explicación de la revisión mediante la estructura nativa. El portal separa la capa superpuesta del diseño del acordeón, mientras que Dialog.Close sigue siendo la acción explícita para cerrar. La región de estado externa conserva el resultado guardado cuando se cierra la capa superpuesta, para que no se pierda con el contenido del diálogo.

  • Vincula la etiqueta visible con su control.
  • Conserva un anillo de foco visible bien definido después de aplicar estilos personalizados.
  • No elimines las partes de título ni de descripción al cambiar los estilos de un diálogo.

Consulta la especificación complementaria

Bits UI Ejemplos de componentes del sistema de diseño

Lista de verificación completa para Svelte 5

Composición nativa de Bits UI con modelos $state/$derived, casillas controladas y un diálogo de revisión basado en un portal.

svelte
<script>
import {Accordion,Checkbox,Dialog} from 'bits-ui';
let groups=$state([{id:'keyboard',name:'Keyboard flow',description:'Move through the interface without a pointer.',checks:[{id:'focus',label:'Every action has a visible focus indicator.',done:false},{id:'order',label:'Focus follows the visual reading order.',done:false}]},{id:'forms',name:'Form correction',description:'Make a mistake and recover from it.',checks:[{id:'labels',label:'Each input has a persistent visible label.',done:false},{id:'errors',label:'Errors identify the field and explain the correction.',done:false}]},{id:'feedback',name:'Result feedback',description:'Confirm that the outcome is understandable.',checks:[{id:'status',label:'A status message describes the completed action.',done:false},{id:'color',label:'Meaning remains clear without color alone.',done:false}]}]);
let expanded=$state(['keyboard']),open=$state(false),saved=$state(false);
const complete=$derived(groups.reduce((sum,g)=>sum+g.checks.filter(c=>c.done).length,0));
function change(check,value){check.done=value;saved=false}
function all(value){groups.forEach(g=>g.checks.forEach(c=>c.done=value));saved=false}
function reset(){all(false);expanded=['keyboard'];open=false}
</script>
<main class="check-shell"><header><p class="eyebrow">INTERFACE REVIEW · MANUAL CHECKLIST</p><h1>Check the experience between the screens.</h1><p>Work through six practical checks, then review what you have marked. This is a personal checklist, not an automated accessibility test.</p></header><div class="check-layout"><section class="check-panel"><div class="bulk"><Checkbox.Root id="all-checks" checked={complete===6} indeterminate={complete>0&&complete<6} onCheckedChange={all} class="checkbox"><span aria-hidden="true">{complete===6?'✓':complete>0?'−':''}</span></Checkbox.Root><label for="all-checks">Mark all checks</label><span class="count">{complete}/6</span></div><Accordion.Root type="multiple" bind:value={expanded} class="accordion">{#each groups as group}<Accordion.Item value={group.id} class="accordion-item"><Accordion.Header class="accordion-heading"><Accordion.Trigger class="accordion-trigger"><span>{group.name}<small>{group.checks.filter(c=>c.done).length} of 2 checked</small></span><span class="plus" aria-hidden="true">+</span></Accordion.Trigger></Accordion.Header><Accordion.Content class="accordion-content"><p class="group-description">{group.description}</p>{#each group.checks as check}<div class="check-row"><Checkbox.Root id={check.id} checked={check.done} onCheckedChange={value=>change(check,value)} class="checkbox"><span aria-hidden="true">{check.done?'✓':''}</span></Checkbox.Root><label for={check.id}>{check.label}</label></div>{/each}</Accordion.Content></Accordion.Item>{/each}</Accordion.Root><Dialog.Root bind:open><Dialog.Trigger class="primary">Review checklist</Dialog.Trigger><Dialog.Portal><Dialog.Overlay class="overlay"/><Dialog.Content class="dialog"><Dialog.Title class="dialog-title">Your review snapshot</Dialog.Title><Dialog.Description class="dialog-description">{complete} of 6 checks are marked. Saving records your own review state; it does not certify the interface.</Dialog.Description><ul class="review-summary">{#each groups as group}<li><strong>{group.name}</strong><span>{group.checks.filter(c=>c.done).length} / 2</span></li>{/each}</ul>{#if complete<6}<p class="remaining">Return to the checklist to finish the remaining {6-complete} checks.</p>{/if}<div class="dialog-actions"><Dialog.Close class="secondary">Back to checks</Dialog.Close><button class="primary" disabled={complete<6} onclick={()=>{saved=true;open=false}}>Save completed review</button></div></Dialog.Content></Dialog.Portal></Dialog.Root><button class="reset" onclick={reset}>Clear all checks</button><p class="result" role="status">{saved?'Completed review saved locally. All six checks were marked by you.':'Progress stays in this preview until you reload.'}</p></section><aside class="check-notes"><div class="focus-art" aria-hidden="true"><span></span><i></i><b></b></div><p class="eyebrow">WHAT TO LOOK FOR</p><h2>Make the next action clear.</h2><p>A good check leaves evidence: where focus moved, what an error said, or how a result was announced.</p><dl><div><dt>Keyboard</dt><dd>Tab, Shift+Tab, Enter and Escape should support the relevant task.</dd></div><div><dt>Correction</dt><dd>Keep the user’s input and point to a specific next step.</dd></div><div><dt>Feedback</dt><dd>Describe the outcome in words as well as visual styling.</dd></div></dl></aside></div></main>

Referencia de código

  • El control general deriva los estados checked e indeterminate de las seis comprobaciones individuales.
  • Guardar depende de que se completen todas las comprobaciones, no de que el diálogo esté abierto.
  • Esta hoja de trabajo manual no ejecuta una auditoría de accesibilidad.

Configuración visual original completa

Colores semánticos con nombre, escala de espaciado, selectores nativos data-state y estilos adaptables para la capa superpuesta.

css
:root{--app-canvas:#f4f3f8;--app-surface:#ffffff;--app-ink:#2d2938;--app-muted:#746d80;--app-line:#e3dfeb;--app-action:#604c88;--app-on-action:#fff;--app-focus:#9a80ce;--app-soft:#eee8f7;--app-radius:12px;--app-space-1:4px;--app-space-2:8px;--app-space-3:12px;--app-space-4:16px;--app-space-6:24px;--app-space-8:32px}html,body,#app{height:auto;min-height:0;margin:0}*{box-sizing:border-box}body{font-family:system-ui,sans-serif;background:var(--app-canvas);color:var(--app-ink)}button{font:inherit;cursor:pointer}button:disabled{opacity:.45;cursor:default}button:focus-visible{outline:3px solid var(--app-focus);outline-offset:3px}.check-shell{max-width:1080px;margin:auto;padding:var(--app-space-8)}.eyebrow{font-size:10px;letter-spacing:.14em;font-weight:700;color:var(--app-muted)}h1{font-size:34px;line-height:1.15;max-width:710px;margin:12px 0}header>p:last-child{font-size:14px;line-height:1.7;max-width:640px;color:var(--app-muted)}.check-layout{display:grid;grid-template-columns:minmax(0,1fr) 270px;gap:var(--app-space-6);margin-top:28px}.check-panel{background:var(--app-surface);border:1px solid var(--app-line);border-radius:16px;padding:var(--app-space-6);min-width:0}.bulk{display:flex;align-items:center;gap:12px;font-size:14px;font-weight:600;padding-bottom:24px}.count{margin-left:auto;color:var(--app-muted);font-size:12px}.checkbox{width:22px;height:22px;flex-shrink:0;border:1px solid #aaa1ba;background:white;border-radius:5px;display:inline-flex;align-items:center;justify-content:center;padding:0;line-height:1}.checkbox[data-state=checked],.checkbox[data-state=indeterminate]{background:var(--app-action);border-color:var(--app-action);color:var(--app-on-action)}.accordion{margin-bottom:24px}.accordion-item{border-top:1px solid var(--app-line)}.accordion-item:last-child{border-bottom:1px solid var(--app-line)}.accordion-heading{margin:0;font-size:16px}.accordion-trigger{width:100%;border:0;background:transparent;display:flex;align-items:center;justify-content:space-between;text-align:left;padding:20px 0;color:var(--app-ink);font-weight:600}.accordion-trigger small{display:block;font-weight:400;font-size:11px;color:var(--app-muted);margin-top:6px}.plus{font-size:23px;font-weight:400;transition:transform .15s}.accordion-trigger[data-state=open] .plus{transform:rotate(45deg)}.accordion-content{padding:0 0 20px}.group-description{font-size:12px;line-height:1.6;color:var(--app-muted);margin:0 0 16px}.check-row{display:flex;align-items:flex-start;gap:12px;margin-top:14px}.check-row label{font-size:13px;line-height:1.6;cursor:pointer}.primary,.secondary{border:1px solid transparent;border-radius:8px;padding:12px 16px;font-size:13px;font-weight:600}.primary{background:var(--app-action);color:var(--app-on-action)}.secondary{background:white;color:var(--app-ink);border-color:var(--app-line)}.reset{border:0;background:transparent;color:var(--app-muted);font-size:12px;padding:12px}.result{font-size:12px;line-height:1.6;color:var(--app-muted);margin:18px 0 0}.check-notes{min-width:0;padding:0 4px}.check-notes h2{font:400 29px/1.2 Georgia,serif}.check-notes>p:not(.eyebrow){font-size:13px;line-height:1.7;color:var(--app-muted)}.check-notes dl>div{padding:14px 0;border-top:1px solid var(--app-line)}.check-notes dt{font-size:13px;font-weight:600}.check-notes dd{font-size:12px;line-height:1.7;color:var(--app-muted);margin:5px 0 0}.focus-art{height:165px;background:#e6e0ef;border-radius:12px;position:relative;overflow:hidden;margin-bottom:24px}.focus-art span{position:absolute;width:140px;height:85px;left:35px;top:44px;background:white;border-radius:8px;transform:rotate(-9deg);box-shadow:0 0 0 6px #b3a3cd}.focus-art i{position:absolute;width:75px;height:13px;background:#b7adc6;left:60px;top:61px;transform:rotate(-9deg)}.focus-art b{position:absolute;width:72px;height:28px;background:#695587;left:87px;top:91px;border-radius:5px;transform:rotate(-9deg)}.overlay{position:fixed;inset:0;background:#21193180;z-index:20}.dialog{position:fixed;z-index:21;left:50%;top:50%;transform:translate(-50%,-50%);width:min(440px,calc(100% - 28px));max-height:calc(100vh - 28px);overflow:auto;background:white;padding:24px;border-radius:14px;box-shadow:0 20px 80px #23193640}.dialog-title{font-size:23px;margin:0 0 12px}.dialog-description,.remaining{font-size:13px;line-height:1.7;color:var(--app-muted)}.review-summary{padding:0;list-style:none}.review-summary li{display:flex;justify-content:space-between;gap:12px;padding:12px 0;border-bottom:1px solid var(--app-line);font-size:13px}.dialog-actions{display:flex;gap:10px;flex-wrap:wrap;margin-top:22px}@media(max-width:740px){.check-layout{grid-template-columns:minmax(0,1fr)}.check-shell{padding:20px}h1{font-size:29px}}@media(max-width:360px){.check-shell{padding:14px}.check-panel,.dialog{padding:16px}.check-panel>.primary,.dialog-actions>*{width:100%}}@media(prefers-reduced-motion:reduce){.plus{transition:none}}

Referencia de código

  • Estas son variables --app-* originales, no una paleta oficial de Bits.
  • Se incluyen estilos para el foco y el movimiento reducido.
  • Solo la capa superpuesta usa una altura máxima relativa a la ventana gráfica.
04

Sistema de diseño Bits UI Configuración del agente de IA

Punto de partida para la implementación

Verificado con Bits UI 2.19.5 y Svelte 5.57.1. Se requiere la hoja de estilos original completa; Bits UI no proporciona colores ni diseño de página predeterminados.

javascript
// npm create vite@latest bits-review -- --template svelte
// cd bits-review && npm install
// npm install [email protected] [email protected]
// Save the complete examples as src/App.svelte and src/style.css.
// src/main.js:
import {mount} from 'svelte';
import App from './App.svelte';
import './style.css';
mount(App, {target:document.querySelector('#app')});
// index.html: <div id="app"></div><script type="module" src="/src/main.js"></script>
// npm run dev

Una instrucción para tu proyecto

Instrucción para el agente
Usa Bits UI 2.19.5 y Svelte 5 para crear la revisión manual de interfaz proporcionada. Mantén seis comprobaciones en tres secciones Accordion, deriva los estados checked/indeterminate del control general a partir de las respuestas individuales y conserva las respuestas al contraer las secciones. Compón todas las partes de Dialog para la revisión; permite inspeccionar una revisión incompleta, pero mantén Guardar desactivado hasta que se marquen las seis casillas. Cualquier cambio en las respuestas invalida los comentarios guardados; Borrar todo restaura la expansión inicial y cierra la revisión. Incluye el CSS completo y describe los resultados como comprobaciones locales marcadas por el lector, no como una certificación automatizada de accesibilidad.
05

Bits UI Fuentes y alcance del sistema de diseño

Bits UI 2.19.5 con Svelte 5.57.1. Tokens e ilustraciones originales de la aplicación. Esta es una lista de verificación manual con estado local, no una auditoría ni una certificación automatizadas de accesibilidad.