Skip to main content
Glama
listbox.md9.54 kB
# Catalyst Listbox Components - HTML & Tailwind CSS Examples This document provides HTML structure and Tailwind CSS class examples derived from the React-based Catalyst UI Kit's `Listbox`, `ListboxOption`, `ListboxLabel`, and `ListboxDescription` components. These examples are intended for AI consumption and may need adaptation. These components are built upon Headless UI's Listbox components. ## Overview The Catalyst Listbox is a custom-styled select dropdown, allowing users to choose a single option from a list. It consists of: - `Listbox`: The main container, wrapping `Headless.Listbox`. - `ListboxButton`: The button element that displays the currently selected value (or a placeholder) and toggles the dropdown. - `ListboxOptions`: The floating panel that displays the list of selectable options. - `ListboxOption`: An individual item within the options list. - `ListboxLabel`: Used within a `ListboxOption` for the primary display text. - `ListboxDescription`: Used within a `ListboxOption` for secondary, descriptive text. ## HTML Structure Example (Conceptual) Significant JavaScript (from Headless UI) is required for functionality (state management, keyboard navigation, ARIA attributes, transitions). ```html <!-- Listbox container (from Headless.Listbox) --> <div class="relative"> <!-- ListboxButton (Headless.ListboxButton) --> <button type="button" data-slot="control" aria-haspopup="listbox" aria-expanded="false" class="group relative block w-full before:absolute before:inset-px before:rounded-[calc(var(--radius-lg)-1px)] before:bg-white before:shadow-sm dark:before:hidden focus:outline-hidden after:pointer-events-none after:absolute after:inset-0 after:rounded-lg after:ring-transparent after:ring-inset data-focus:after:ring-2 data-focus:after:ring-blue-500 ..." > <!-- Selected Option Display (Headless.ListboxSelectedOption) --> <span class="relative block w-full appearance-none rounded-lg py-[calc(var(--spacing-2-5)-1px)] sm:py-[calc(var(--spacing-1-5)-1px)] min-h-11 sm:min-h-9 pr-[calc(var(--spacing-7)-1px)] pl-[calc(var(--spacing-3-5)-1px)] sm:pl-[calc(var(--spacing-3)-1px)] text-left text-base/6 text-zinc-950 placeholder:text-zinc-500 sm:text-sm/6 dark:text-white forced-colors:text-[CanvasText] border border-zinc-950/10 group-data-active:border-zinc-950/20 group-data-hover:border-zinc-950/20 dark:border-white/10 dark:group-data-active:border-white/20 dark:group-data-hover:border-white/20 bg-transparent dark:bg-white/5 ..."> <!-- Selected value or placeholder --> <span class="block truncate">Selected Value</span> <!-- Placeholder example: <span class="block truncate text-zinc-500">Select an option</span> --> </span> <span class="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2"> <svg class="size-5 stroke-zinc-500 group-data-disabled:stroke-zinc-600 sm:size-4 dark:stroke-zinc-400 forced-colors:stroke-[CanvasText]" viewBox="0 0 16 16" aria-hidden="true" fill="none"> <path d="M5.75 10.75L8 13L10.25 10.75" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /> <path d="M10.25 5.25L8 3L5.75 5.25" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /> </svg> </span> </button> <!-- ListboxOptions (Headless.ListboxOptions panel) - shown/hidden by JS --> <ul class="isolate w-max min-w-[calc(var(--button-width)+1.75rem)] scroll-py-1 rounded-xl p-1 select-none outline outline-transparent focus:outline-hidden overflow-y-scroll overscroll-contain bg-white/75 backdrop-blur-xl dark:bg-zinc-800/75 shadow-lg ring-1 ring-zinc-950/10 dark:ring-white/10 dark:ring-inset transition-opacity duration-100 ease-in data-closed:data-leave:opacity-0 ..." role="listbox" tabindex="-1" style="position: absolute; ... (positioning styles from Headless UI) ..."> <!-- ListboxOption 1 --> <li class="group/option grid cursor-default grid-cols-[var(--spacing-5)_1fr] items-baseline gap-x-2 rounded-lg py-2.5 pr-3.5 pl-2 sm:grid-cols-[var(--spacing-4)_1fr] sm:py-1.5 sm:pr-3 sm:pl-1.5 text-base/6 text-zinc-950 sm:text-sm/6 dark:text-white forced-colors:text-[CanvasText] outline-hidden data-focus:bg-blue-500 data-focus:text-white ..." role="option" tabindex="-1" aria-selected="true"> <!-- aria-selected dynamically set --> <svg class="relative hidden size-5 self-center stroke-current group-data-selected/option:inline sm:size-4" viewBox="0 0 16 16" fill="none" aria-hidden="true"> <path d="M4 8.5l3 3L12 4" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" /> </svg> <span class="flex min-w-0 items-center col-start-2 ... (shared option classes) ..."> <span class="ml-2.5 truncate first:ml-0 sm:ml-2 sm:first:ml-0">Option Text 1</span> <!-- Optional description --> </span> </li> <!-- More ListboxOption elements... --> </ul> </div> ``` ## Tailwind CSS Classes ### `ListboxButton` (`<button data-slot="control">`) Outer button element: ```plaintext group relative block w-full before:absolute before:inset-px before:rounded-[calc(var(--radius-lg)-1px)] before:bg-white before:shadow-sm dark:before:hidden focus:outline-hidden after:pointer-events-none after:absolute after:inset-0 after:rounded-lg after:ring-transparent after:ring-inset data-focus:after:ring-2 data-focus:after:ring-blue-500 data-disabled:opacity-50 data-disabled:before:bg-zinc-950/5 data-disabled:before:shadow-none ``` Inner `<span>` for selected option display (`Headless.ListboxSelectedOption`): ```plaintext relative block w-full appearance-none rounded-lg py-[calc(var(--spacing-2-5)-1px)] sm:py-[calc(var(--spacing-1-5)-1px)] min-h-11 sm:min-h-9 pr-[calc(var(--spacing-7)-1px)] pl-[calc(var(--spacing-3-5)-1px)] sm:pl-[calc(var(--spacing-3)-1px)] text-left text-base/6 text-zinc-950 placeholder:text-zinc-500 sm:text-sm/6 dark:text-white forced-colors:text-[CanvasText] border border-zinc-950/10 group-data-active:border-zinc-950/20 group-data-hover:border-zinc-950/20 dark:border-white/10 dark:group-data-active:border-white/20 dark:group-data-hover:border-white/20 bg-transparent dark:bg-white/5 group-data-invalid:border-red-500 group-data-hover:group-data-invalid:border-red-500 dark:group-data-invalid:border-red-600 dark:data-hover:group-data-invalid:border-red-600 group-data-disabled:border-zinc-950/20 group-data-disabled:opacity-100 dark:group-data-disabled:border-white/15 dark:group-data-disabled:bg-white/[2.5%] dark:group-data-disabled:data-hover:border-white/15 ``` Dropdown arrow `<span>` and `<svg>`: ```plaintext pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2 size-5 stroke-zinc-500 group-data-disabled:stroke-zinc-600 sm:size-4 dark:stroke-zinc-400 forced-colors:stroke-[CanvasText] ``` ### `ListboxOptions` (Dropdown Panel `<ul>`) ```plaintext [--anchor-offset:-1.625rem] [--anchor-padding:var(--spacing(4))] sm:[--anchor-offset:-1.375rem] isolate w-max min-w-[calc(var(--button-width)+1.75rem)] scroll-py-1 rounded-xl p-1 select-none outline outline-transparent focus:outline-hidden overflow-y-scroll overscroll-contain bg-white/75 backdrop-blur-xl dark:bg-zinc-800/75 shadow-lg ring-1 ring-zinc-950/10 dark:ring-white/10 dark:ring-inset transition-opacity duration-100 ease-in data-closed:data-leave:opacity-0 data-transition:pointer-events-none ``` ### `ListboxOption` (`<li>` or `<div>`) Base classes for each option: ```plaintext group/option grid cursor-default grid-cols-[var(--spacing-5)_1fr] items-baseline gap-x-2 rounded-lg py-2.5 pr-3.5 pl-2 sm:grid-cols-[var(--spacing-4)_1fr] sm:py-1.5 sm:pr-3 sm:pl-1.5 text-base/6 text-zinc-950 sm:text-sm/6 dark:text-white forced-colors:text-[CanvasText] outline-hidden data-focus:bg-blue-500 data-focus:text-white forced-color-adjust-none forced-colors:data-focus:bg-[Highlight] forced-colors:data-focus:text-[HighlightText] data-disabled:opacity-50 ``` Shared classes for content wrapper `<span>` inside option: ```plaintext flex min-w-0 items-center *:data-[slot=icon]:size-5 *:data-[slot=icon]:shrink-0 sm:*:data-[slot=icon]:size-4 *:data-[slot=icon]:text-zinc-500 group-data-focus/option:*:data-[slot=icon]:text-white dark:*:data-[slot=icon]:text-zinc-400 forced-colors:*:data-[slot=icon]:text-[CanvasText] forced-colors:group-data-focus/option:*:data-[slot=icon]:text-[Canvas] *:data-[slot=avatar]:-mx-0.5 *:data-[slot=avatar]:size-6 sm:*:data-[slot=avatar]:size-5 ``` Selected checkmark SVG (inside option): ```plaintext relative hidden size-5 self-center stroke-current group-data-selected/option:inline sm:size-4 ``` ### `ListboxLabel` (`<span>`) ```plaintext ml-2.5 truncate first:ml-0 sm:ml-2 sm:first:ml-0 ``` ### `ListboxDescription` (`<span>`) Outer span: ```plaintext flex flex-1 overflow-hidden text-zinc-500 group-data-focus/option:text-white before:w-2 before:min-w-0 before:shrink dark:text-zinc-400 ``` Inner span for truncation: ```plaintext flex-1 truncate ``` ## Notes for Usage * **JavaScript Essential:** Functionality is heavily dependent on JavaScript (Headless UI). * **Data Attributes:** Styling relies on `data-` attributes (e.g., `data-focus`, `data-selected`, `data-disabled`, `data-open` on the button, `data-closed` on options panel) set by Headless UI. * **CSS Variables:** Uses Catalyst-specific CSS variables (e.g., `var(--radius-lg)`, `var(--spacing-...)`, `var(--button-width)`). This Markdown file provides the HTML structure and class details from Catalyst's Listbox components for analysis and adaptation.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/CaullenOmdahl/Tailwind-Svelte-Assistant'

If you have feedback or need assistance with the MCP directory API, please join our Discord server