Ir al contenido
uiify

Combobox

Cuadro combinado ARIA con filtrado y uno o varios valores.

Navegadores
Chrome 114+Firefox 125+Safari 17+
Nivel
2
Tamaño comprimido
5.18 kB
Presupuesto de diseño forzado
0 ms
Presupuesto de axe
0
Compatible con SSR
Sí
Contrato publicado
Entorno de pruebas

Zona de pruebas

Combobox

Predeterminado

Manzana
Banana
Cereza
Dátil

Múltiple

ReactUI
React
UI
TypeScript
Accesibilidad
Sistemas de diseño

Abierto

Manzana
Banana
Cereza
Dátil

Grande

"use client";

import { Combobox } from "@gunkin/uiify";

const skills = [
  { label: "React", value: "React" },
  { label: "UI", value: "UI" },
  { label: "TypeScript", value: "TypeScript" },
  { label: "Accessibility", value: "Accessibility" },
];

export default function Example() {
  return (
    <div className="">
      <Combobox.Root multiple defaultValue={["React", "UI"]} items={skills}>
        <Combobox.Control className="">
          <Combobox.Tags className="" />
          <Combobox.Input className="" aria-label="Add tag" placeholder="Add tag" />
        </Combobox.Control>
        <Combobox.Content className="">
          {(items) =>
            items.length === 0 ? (
              <Combobox.Empty>Nothing matched. Try another search.</Combobox.Empty>
            ) : (
              items.map((item) => <Combobox.Item className="" item={item} key={item.value} />)
            )
          }
        </Combobox.Content>
      </Combobox.Root>
    </div>
  );
}
/* Combobox — text input + listbox surface + option rows. The active option is
   tracked via aria-activedescendant, surfaced here as [data-highlighted]. */

@layer components {
  [data-uiify-combobox] {
    position: relative;
    inline-size: 100%;
    max-inline-size: 18rem;
  }

  [data-uiify-combobox] [data-part="control"] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-xs);
    inline-size: 100%;
    min-block-size: 2.5rem;
    padding-block: var(--space-sm);
    padding-inline: var(--space-md);
    border: var(--border-width) solid var(--input);
    border-radius: var(--radius-md);
    corner-shape: squircle;
    background-color: var(--card);
    color: var(--foreground);
    transition: var(--transition-colors);
  }

  [data-uiify-combobox] [data-part="control"]:focus-within {
    border-color: var(--primary);
  }

  [data-uiify-combobox] [data-part="control"][data-disabled],
  [data-uiify-combobox] [data-part="control"]:has([data-part="input"]:disabled) {
    opacity: 0.5;
    cursor: not-allowed;
  }

  [data-uiify-combobox] [data-part="control"] [data-part="tags"] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-xs);
  }

  [data-uiify-combobox] [data-part="control"] [data-part="tag"] {
    display: inline-flex;
    align-items: center;
    gap: var(--space-xs);
    padding-block: var(--space-xs);
    padding-inline: var(--space-sm);
    border-radius: var(--radius-xs);
    corner-shape: squircle;
    background-color: var(--accent);
    color: var(--accent-foreground);
    font-size: var(--text-xs);
    font-weight: var(--weight-medium);
  }

  [data-uiify-combobox] [data-part="control"] [data-part="tag-remove"] {
    display: inline-grid;
    place-items: center;
    inline-size: 1.25rem;
    block-size: 1.25rem;
    flex: 0 0 1.25rem;
    padding: 0;
    border: 0;
    border-radius: var(--radius-xs);
    corner-shape: squircle;
    background: transparent;
    color: inherit;
    font: inherit;
    line-height: 1;
    cursor: pointer;
  }

  [data-uiify-combobox] [data-part="control"] [data-part="tag-remove"]:hover,
  [data-uiify-combobox] [data-part="control"] [data-part="tag-remove"]:focus-visible {
    background-color: var(--primary);
    color: var(--primary-foreground);
  }

  [data-uiify-combobox] [data-part="input"] {
    inline-size: 100%;
    padding-block: var(--space-sm);
    padding-inline: var(--space-md);
    border: var(--border-width) solid var(--input);
    border-radius: var(--radius-md);
    corner-shape: squircle;
    background-color: var(--card);
    color: var(--foreground);
    font-size: var(--uiify-control-text);
    transition: var(--transition-colors);
  }

  [data-uiify-combobox] [data-part="input"]:focus-visible {
    border-color: var(--primary);
  }

  [data-uiify-combobox] [data-part="control"] [data-part="input"] {
    flex: 1 1 5rem;
    min-inline-size: 5rem;
    inline-size: auto;
    padding-block: var(--space-xs);
    padding-inline: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
    outline: none;
    box-shadow: none;
  }

  [data-uiify-combobox] [data-part="content"]:where(:not([popover]), :popover-open) {
    display: flex;
  }

  [data-uiify-combobox] [data-part="content"] {
    flex-direction: column;
    min-inline-size: 12rem;
    max-block-size: min(24rem, calc(100dvb - 2rem));
    overflow-block: auto;
    overscroll-behavior: contain;
    padding: var(--space-xs);
    border: var(--border-width) solid var(--border);
    border-radius: var(--radius-lg);
    corner-shape: squircle;
    background-color: var(--card);
    color: var(--foreground);
    box-shadow: var(--shadow-popover);
    transform-origin: var(--transform-origin, top);
  }

  [data-uiify-combobox] [data-part="content"][data-state="closed"] {
    display: none;
  }

  [data-uiify-combobox] [data-part="item"] {
    display: flex;
    align-items: center;
    inline-size: 100%;
    padding-block: var(--space-sm);
    padding-inline: var(--space-md);
    border: 0;
    border-radius: calc(var(--radius-lg) - var(--space-xs));
    corner-shape: squircle;
    background: transparent;
    color: inherit;
    font: inherit;
    font-size: var(--text-sm);
    line-height: var(--leading-normal);
    text-align: start;
    cursor: pointer;
    user-select: none;
  }

  [data-uiify-combobox] [data-part="item"]:hover,
  [data-uiify-combobox] [data-part="item"]:focus-visible,
  [data-uiify-combobox] [data-part="item"][data-highlighted],
  [data-uiify-combobox] [data-part="item"][aria-selected="true"],
  [data-uiify-combobox] [data-part="item"][data-selected] {
    background-color: var(--accent);
    color: var(--accent-foreground);
    outline: none;
  }

  [data-uiify-combobox] [data-part="item"][aria-disabled="true"],
  [data-uiify-combobox] [data-part="item"][data-disabled] {
    opacity: 0.5;
    pointer-events: none;
  }

  [data-uiify-combobox] [data-part="empty"] {
    padding: var(--space-sm) var(--space-md);
    color: var(--muted-foreground);
    font-size: var(--text-sm);
  }

  @media (prefers-reduced-motion: no-preference) {
    [data-uiify-combobox] [data-part="content"] {
      transition: var(--transition-presence);
    }

    [data-uiify-combobox] [data-part="content"][popover]:not(:popover-open) {
      opacity: 0;
      scale: var(--presence-scale);
    }

    @starting-style {
      [data-uiify-combobox] [data-part="content"]:popover-open {
        opacity: 0;
        scale: var(--presence-scale);
      }
    }
  }
}
"use client";

import { Combobox } from "@gunkin/uiify";

const skills = [
  { label: "React", value: "React" },
  { label: "UI", value: "UI" },
  { label: "TypeScript", value: "TypeScript" },
  { label: "Accessibility", value: "Accessibility" },
];

export default function Example() {
  return (
    <div className="relative w-full max-w-72">
      <Combobox.Root multiple defaultValue={["React", "UI"]} items={skills}>
        <Combobox.Control
          className="
            flex flex-wrap items-center gap-xs w-full min-h-10 py-sm px-md border-[length:var(--border-width)]
            border-solid border-input rounded-md [corner-shape:squircle] bg-card text-foreground
            [transition:var(--transition-colors)] focus-within:border-primary data-[disabled]:opacity-50
            data-[disabled]:cursor-not-allowed has-[[data-part=input]:disabled]:opacity-50
            has-[[data-part=input]:disabled]:cursor-not-allowed
          "
        >
          <Combobox.Tags
            className="
              flex flex-wrap items-center gap-xs [&>[data-part=tag]]:inline-flex [&>[data-part=tag]]:items-center
              [&>[data-part=tag]]:gap-xs [&>[data-part=tag]]:py-xs [&>[data-part=tag]]:px-sm
              [&>[data-part=tag]]:rounded-xs [&>[data-part=tag]]:[corner-shape:squircle] [&>[data-part=tag]]:bg-accent
              [&>[data-part=tag]]:text-accent-foreground [&>[data-part=tag]]:text-xs [&>[data-part=tag]]:font-medium
              [&_[data-part=tag-remove]]:inline-grid [&_[data-part=tag-remove]]:place-items-center
              [&_[data-part=tag-remove]]:size-5 [&_[data-part=tag-remove]]:flex-none [&_[data-part=tag-remove]]:p-0
              [&_[data-part=tag-remove]]:border-0 [&_[data-part=tag-remove]]:rounded-xs
              [&_[data-part=tag-remove]]:bg-transparent [&_[data-part=tag-remove]]:text-inherit
              [&_[data-part=tag-remove]]:[font:inherit] [&_[data-part=tag-remove]]:leading-none
              [&_[data-part=tag-remove]]:cursor-pointer [&_[data-part=tag-remove]:hover]:bg-primary
              [&_[data-part=tag-remove]:hover]:text-primary-foreground
              [&_[data-part=tag-remove]:focus-visible]:bg-primary
              [&_[data-part=tag-remove]:focus-visible]:text-primary-foreground
            "
          />
          <Combobox.Input
            className="
              w-full py-sm px-md border-[length:var(--border-width)] border-solid border-input rounded-md
              [corner-shape:squircle] bg-card text-foreground [font-size:var(--uiify-control-text)]
              [transition:var(--transition-colors)] focus-visible:border-primary [[data-part=control]_&]:flex-[1_1_5rem]
              [[data-part=control]_&]:[min-inline-size:5rem] [[data-part=control]_&]:[inline-size:auto]
              [[data-part=control]_&]:py-xs [[data-part=control]_&]:px-0 [[data-part=control]_&]:border-0
              [[data-part=control]_&]:rounded-none [[data-part=control]_&]:bg-transparent
              [[data-part=control]_&]:[outline:none] [[data-part=control]_&]:[box-shadow:none]
            "
            aria-label="Add tag"
            placeholder="Add tag"
          />
        </Combobox.Control>
        <Combobox.Content
          className="
            [&[data-positioning=native]]:[--uiify-anchor-offset:var(--space-sm)]
            [&_[data-positioning=native]]:[--uiify-anchor-offset:var(--space-sm)]
            [&[popover]:popover-open:not([data-positioning=native])]:[margin:revert]
            [&_[popover]:popover-open:not([data-positioning=native])]:[margin:revert] flex-col [min-inline-size:12rem]
            [max-block-size:min(24rem,calc(100dvb_-_2rem))] overflow-y-auto overscroll-contain p-xs
            border-[length:var(--border-width)] border-solid border-border rounded-lg [corner-shape:squircle] bg-card
            text-foreground shadow-popover [transform-origin:var(--transform-origin,top)] data-[state=closed]:hidden
            [&:where(:not([popover]),:popover-open)]:flex motion-safe:[transition:var(--transition-presence)]
            motion-safe:data-[state=closed]:opacity-0 motion-safe:data-[state=closed]:[scale:var(--presence-scale)]
            motion-safe:starting:[&:popover-open]:opacity-0
            motion-safe:starting:[&:popover-open]:[scale:var(--presence-scale)]
          "
        >
          {(items) =>
            items.length === 0 ? (
              <Combobox.Empty>Nothing matched. Try another search.</Combobox.Empty>
            ) : (
              items.map((item) => (
                <Combobox.Item
                  className="
                    flex items-center w-full py-sm px-md border-0 rounded-[calc(var(--radius-lg)_-_var(--space-xs))]
                    [corner-shape:squircle] bg-transparent text-inherit [font:inherit] text-sm
                    [line-height:var(--leading-normal)] text-start cursor-pointer select-none hover:bg-accent
                    hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground
                    focus-visible:outline-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground
                    aria-[selected=true]:bg-accent aria-[selected=true]:text-accent-foreground data-[selected]:bg-accent
                    data-[selected]:text-accent-foreground aria-[disabled=true]:opacity-50
                    aria-[disabled=true]:pointer-events-none data-[disabled]:opacity-50
                    data-[disabled]:pointer-events-none
                  "
                  item={item}
                  key={item.value}
                />
              ))
            )
          }
        </Combobox.Content>
      </Combobox.Root>
    </div>
  );
}
/* app.css */

@layer reset, ui, app, tokens, base, demo, components, utilities, theme;

@import "@gunkin/uiify/styles/reset";

@import "@gunkin/uiify/components/behavior.css";

@import "@gunkin/uiify/styles/tokens";

@import "@gunkin/uiify/styles/tailwind";

@import "tailwindcss/utilities.css";

@theme { --spacing: 0.25rem; --font-weight-normal: 400; --font-weight-medium: 500; --font-weight-semibold: 600; --font-weight-bold: 700; }

@source inline('relative w-full max-w-72 flex flex-wrap items-center gap-xs min-h-10 py-sm px-md border-[length:var(--border-width)] border-solid border-input rounded-md [corner-shape:squircle] bg-card text-foreground [transition:var(--transition-colors)] focus-within:border-primary data-[disabled]:opacity-50 data-[disabled]:cursor-not-allowed has-[[data-part=input]:disabled]:opacity-50 has-[[data-part=input]:disabled]:cursor-not-allowed [&>[data-part=tag]]:inline-flex [&>[data-part=tag]]:items-center [&>[data-part=tag]]:gap-xs [&>[data-part=tag]]:py-xs [&>[data-part=tag]]:px-sm [&>[data-part=tag]]:rounded-xs [&>[data-part=tag]]:[corner-shape:squircle] [&>[data-part=tag]]:bg-accent [&>[data-part=tag]]:text-accent-foreground [&>[data-part=tag]]:text-xs [&>[data-part=tag]]:font-medium [&_[data-part=tag-remove]]:inline-grid [&_[data-part=tag-remove]]:place-items-center [&_[data-part=tag-remove]]:size-5 [&_[data-part=tag-remove]]:flex-none [&_[data-part=tag-remove]]:p-0 [&_[data-part=tag-remove]]:border-0 [&_[data-part=tag-remove]]:rounded-xs [&_[data-part=tag-remove]]:bg-transparent [&_[data-part=tag-remove]]:text-inherit [&_[data-part=tag-remove]]:[font:inherit] [&_[data-part=tag-remove]]:leading-none [&_[data-part=tag-remove]]:cursor-pointer [&_[data-part=tag-remove]:hover]:bg-primary [&_[data-part=tag-remove]:hover]:text-primary-foreground [&_[data-part=tag-remove]:focus-visible]:bg-primary [&_[data-part=tag-remove]:focus-visible]:text-primary-foreground [font-size:var(--uiify-control-text)] focus-visible:border-primary [[data-part=control]_&]:flex-[1_1_5rem] [[data-part=control]_&]:[min-inline-size:5rem] [[data-part=control]_&]:[inline-size:auto] [[data-part=control]_&]:py-xs [[data-part=control]_&]:px-0 [[data-part=control]_&]:border-0 [[data-part=control]_&]:rounded-none [[data-part=control]_&]:bg-transparent [[data-part=control]_&]:[outline:none] [[data-part=control]_&]:[box-shadow:none] [&[data-positioning=native]]:[--uiify-anchor-offset:var(--space-sm)] [&_[data-positioning=native]]:[--uiify-anchor-offset:var(--space-sm)] [&[popover]:popover-open:not([data-positioning=native])]:[margin:revert] [&_[popover]:popover-open:not([data-positioning=native])]:[margin:revert] flex-col [min-inline-size:12rem] [max-block-size:min(24rem,calc(100dvb_-_2rem))] overflow-y-auto overscroll-contain p-xs border-border rounded-lg shadow-popover [transform-origin:var(--transform-origin,top)] data-[state=closed]:hidden [&:where(:not([popover]),:popover-open)]:flex motion-safe:[transition:var(--transition-presence)] motion-safe:data-[state=closed]:opacity-0 motion-safe:data-[state=closed]:[scale:var(--presence-scale)] motion-safe:starting:[&:popover-open]:opacity-0 motion-safe:starting:[&:popover-open]:[scale:var(--presence-scale)] border-0 rounded-[calc(var(--radius-lg)_-_var(--space-xs))] bg-transparent text-inherit [font:inherit] text-sm [line-height:var(--leading-normal)] text-start cursor-pointer select-none hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground focus-visible:outline-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground aria-[selected=true]:bg-accent aria-[selected=true]:text-accent-foreground data-[selected]:bg-accent data-[selected]:text-accent-foreground aria-[disabled=true]:opacity-50 aria-[disabled=true]:pointer-events-none data-[disabled]:pointer-events-none');

@layer base { :root { --uiify-control-text: var(--text-sm); } @media (pointer: coarse) { :root { --uiify-control-text: var(--text-base); } } }

/* Authored animation and registered properties used by the Tailwind skin.
 * Visual rules belong in utility recipes; only at-rule definitions live here. */
@layer components {
  @keyframes uiify-presence-in {
    from {
      opacity: 0;
      scale: var(--presence-scale);
    }
  }
}

@layer components {
  @keyframes uiify-presence-out {
    to {
      opacity: 0;
      scale: var(--presence-scale);
    }
  }
}

@property --uiify-spinner-tail {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}

@property --uiify-spinner-length {
  syntax: "<angle>";
  inherits: false;
  initial-value: 36deg;
}

@layer components {
  @keyframes uiify-spinner-rotate {
    to {
      transform: rotate(360deg);
    }
  }
}

@layer components {
  @keyframes uiify-spinner-orbit {
    0% {
      --uiify-spinner-tail: 0deg;
      --uiify-spinner-length: 36deg;
    }

    50% {
      --uiify-spinner-tail: 90deg;
      --uiify-spinner-length: 324deg;
    }

    100% {
      --uiify-spinner-tail: 360deg;
      --uiify-spinner-length: 36deg;
    }
  }
}

@layer components {
  @keyframes uiify-skeleton-pulse {
    50% {
      opacity: 0.45;
    }
  }
}

@layer components {
  @keyframes uiify-skeleton-shimmer {
    to {
      background-position: -200% 0;
    }
  }
}

@layer components {
  @keyframes uiify-skeleton-reveal {
    from {
      opacity: 0;
    }
    to {
      opacity: 1;
    }
  }
}

@property --candle-body-height {
  syntax: "<percentage>";
  inherits: true;
  initial-value: 0%;
}

@property --candle-body-top {
  syntax: "<percentage>";
  inherits: true;
  initial-value: 50%;
}

@property --candle-slot {
  syntax: "<percentage>";
  inherits: true;
  initial-value: 100%;
}

@property --candle-wick-height {
  syntax: "<percentage>";
  inherits: true;
  initial-value: 0%;
}

@property --candle-wick-top {
  syntax: "<percentage>";
  inherits: true;
  initial-value: 50%;
}

@property --candle-x {
  syntax: "<percentage>";
  inherits: true;
  initial-value: 0%;
}

@property --candle-scale {
  syntax: "<number>";
  inherits: true;
  initial-value: 1;
}

@property --line-y {
  syntax: "<percentage>";
  inherits: true;
  initial-value: 50%;
}

@property --line-prev-y {
  syntax: "<percentage>";
  inherits: true;
  initial-value: 50%;
}

@property --line-count {
  syntax: "<integer>";
  inherits: false;
  initial-value: 1;
}

@property --line-scale {
  syntax: "<number>";
  inherits: true;
  initial-value: 1;
}

@layer components {
  @keyframes uiify-otp-input-caret-blink {
    50% {
      opacity: 0;
    }
  }
}

API

Combobox.Root

PropTipoPredeterminadoDescripción
childrenReactNode—Partes de Combobox: control, etiquetas, input, activador y contenido.
items*ComboboxItemData[]—Lista completa de opciones que filtra el input.
defaultInputValuestring—Texto inicial del input cuando su valor es no controlado.
defaultOpenboolean—Indica si la lista comienza abierta cuando el estado de apertura es no controlado.
defaultValuestring | readonly string[]—Valor o valores seleccionados en el primer renderizado cuando la selección es no controlada.
multiplebooleanfalsePermite seleccionar y quitar varios valores como etiquetas.
allowCustomValuebooleanfalsePermite convertir texto escrito que no está en items en un valor seleccionado.
addOnPastebooleantrueAñade varios valores delimitados a partir de texto pegado en modo múltiple.
delimitersreadonly string[][","]Caracteres que confirman o separan los valores escritos en modo múltiple.
maxValuesnumber—Número máximo de valores que se pueden seleccionar en modo múltiple.
validateValue(value: string) => boolean—Rechaza un valor personalizado cuando devuelve false.
filterFn(items: ComboboxItemData[], inputValue: string) => ComboboxItemData[]—Reemplaza el filtro integrado que reduce los elementos a medida que el usuario escribe.
inputValuestring—Texto del input; hace que el valor escrito sea controlado.
onInputValueChange(value: string) => void—Se llama con el nuevo texto cada vez que cambia el input.
onOpenChange(open: boolean, details: OpenChangeDetails) => void—Se llama al abrir o cerrar la lista, con el motivo del cambio.
onValueChange((value: string) => void) | ((value: string[]) => void)—Se llama con el valor seleccionado o con el arreglo completo de valores seleccionados.
openboolean—Indica si la lista está abierta; hace que el estado de apertura sea controlado.
valuestring | readonly string[]—Valor o valores seleccionados; hace que la selección sea controlada.

Combobox.Control

PropTipoPredeterminadoDescripción
childrenReactNode—Etiquetas e input renderizados dentro del control visual compartido.
classNamestring—Clase aplicada al elemento de control.
renderReactElement | ((props, state) => ReactElement)—Reemplaza el elemento renderizado y conserva las conexiones de comportamiento y accesibilidad.

Combobox.Tags

PropTipoPredeterminadoDescripción
childrenReactNode—Contenido añadido después de las etiquetas generadas que se pueden quitar.
classNamestring—Clase aplicada al contenedor de etiquetas generadas.
renderReactElement | ((props, state) => ReactElement)—Reemplaza el elemento renderizado y conserva las conexiones de comportamiento y accesibilidad.

Combobox.Input

PropTipoPredeterminadoDescripción
classNamestring—Clase aplicada al input de texto.
renderReactElement | ((props, state) => ReactElement)—Reemplaza el elemento renderizado y conserva las conexiones de comportamiento y accesibilidad.

Combobox.Trigger

PropTipoPredeterminadoDescripción
childrenReactNode—Contenido del botón que abre la lista, como un ícono.
classNamestring—Clase aplicada al botón activador.
renderReactElement | ((props, state) => ReactElement)—Reemplaza el elemento renderizado y conserva las conexiones de comportamiento y accesibilidad.

Combobox.Content

PropTipoPredeterminadoDescripción
align"start" | "center" | "end"—Alineación de la lista respecto al input sobre el lado elegido.
children*(filteredItems: ComboboxItemData[]) => ReactNode—Función de renderizado que se llama con los elementos que quedan tras filtrar.
classNamestring—Clase aplicada a la ventana emergente de la lista.
side"top" | "right" | "bottom" | "left"—Lado del input en el que se coloca la lista.

Combobox.Item

PropTipoPredeterminadoDescripción
classNamestring—Clase aplicada al elemento de opción.
item*ComboboxItemData—Elemento que renderiza esta opción, normalmente obtenido del callback de contenido.

Combobox.Empty

PropTipoPredeterminadoDescripción
childrenReactNode—Contenido que se muestra cuando el filtrado no deja elementos.
classNamestring—Clase aplicada al elemento de estado vacío.

ComboboxItemData

PropTipoPredeterminadoDescripción
disabledboolean—Impide seleccionar este elemento.
label*string—Texto que se muestra para el elemento y con el que compara el filtro.
value*string—Valor que se comunica al seleccionar el elemento.

Teclado

TeclaAcción
↓ / ↑Abrir y recorrer las opciones
EnterSeleccionar
EscapeCerrar
a–zEscribir para filtrar opciones

Accesibilidad

Combobox ARIA + listbox. La opción activa se anuncia mediante aria-activedescendant. Content expone el estado abierto/cerrado; las opciones exponen los estados resaltado, desactivado y, en modo múltiple, seleccionado. Usa Empty para explicar que ninguna opción coincide. La animación de presencia de Popup se desactiva si se prefiere el movimiento reducido.

Puntos de estilo

data-statedata-highlighteddata-disableddata-selected
Esta página se tradujo automáticamente y aún no se ha revisado.