Listbox
Use CListbox when the choices should remain visible while people compare and select them. Use Select or MultiSelect when the choices should open from a compact form control.
Listbox at a glance
Show code
import citry_ui
from citry import Component, citry
citry.register_library(citry_ui)
class ListboxAtAGlance(Component):
template = """
<c-CListbox label="Choose a workspace" value="atlas" variant="soft">
<c-CListboxOption value="atlas">
<c-fill name="default">Atlas research</c-fill>
<c-fill name="description">12 collaborators</c-fill>
<c-fill name="end">Active</c-fill>
</c-CListboxOption>
<c-CListboxOption value="aurora">
<c-fill name="default">Aurora field notes</c-fill>
<c-fill name="description">7 collaborators</c-fill>
</c-CListboxOption>
<c-CListboxOption value="archive" disabled>Archived studies</c-CListboxOption>
</c-CListbox>
"""
preview = ListboxAtAGlance()
preview # noqa: B018
Select one value
Show code
import citry_ui
from citry import Component, citry
citry.register_library(citry_ui)
class SingleSelection(Component):
template = """
<c-CListbox label="Density" value="comfortable" mandatory variant="outline">
<c-CListboxOption value="compact">Compact</c-CListboxOption>
<c-CListboxOption value="comfortable">Comfortable</c-CListboxOption>
<c-CListboxOption value="spacious">Spacious</c-CListboxOption>
</c-CListbox>
"""
preview = SingleSelection()
preview # noqa: B018
Select several values
Show code
import citry_ui
from citry import Component, citry
citry.register_library(citry_ui)
class MultipleSelection(Component):
template = """
<c-CListbox label="Include signals" multiple c-value="['temperature', 'humidity']" variant="outline">
<c-CListboxOption value="temperature">Temperature</c-CListboxOption>
<c-CListboxOption value="humidity">Humidity</c-CListboxOption>
<c-CListboxOption value="pressure">Pressure</c-CListboxOption>
<c-CListboxOption value="wind">Wind speed</c-CListboxOption>
</c-CListbox>
"""
preview = MultipleSelection()
preview # noqa: B018
Group related options
Show code
import citry_ui
from citry import Component, citry
citry.register_library(citry_ui)
class GroupedOptions(Component):
template = """
<c-CListbox label="Choose a destination" value="prague">
<c-CListboxGroup label="Europe">
<c-CListboxOption value="prague">Prague</c-CListboxOption>
<c-CListboxOption value="lisbon">Lisbon</c-CListboxOption>
</c-CListboxGroup>
<c-CListboxGroup label="Asia Pacific">
<c-CListboxOption value="kyoto">Kyoto</c-CListboxOption>
<c-CListboxOption value="wellington">Wellington</c-CListboxOption>
</c-CListboxGroup>
</c-CListbox>
"""
preview = GroupedOptions()
preview # noqa: B018
Control selection
Show code
import citry_ui
from citry import Component, citry
citry.register_library(citry_ui)
class ControlledListbox(Component):
template = """
<div x-data>
<c-CListbox
label="Review status"
value="draft"
$c-props="{
value: $store.listboxExample.value,
onValueChange: (next) => $store.listboxExample.value = next,
}"
>
<c-CListboxOption value="draft">Draft</c-CListboxOption>
<c-CListboxOption value="review">Ready for review</c-CListboxOption>
<c-CListboxOption value="approved">Approved</c-CListboxOption>
</c-CListbox>
<p>Current: <strong x-text="$store.listboxExample.value"></strong></p>
</div>
"""
js = """
Alpine.store('listboxExample', {value: 'draft'});
"""
preview = ControlledListbox()
preview # noqa: B018
Disabled collections and options
Show code
import citry_ui
from citry import Component, citry
citry.register_library(citry_ui)
class DisabledListbox(Component):
template = """
<c-CStack gap="lg">
<c-CListbox label="Deployment region" value="eu" variant="outline">
<c-CListboxOption value="eu">Europe</c-CListboxOption>
<c-CListboxOption value="us" disabled>United States β unavailable</c-CListboxOption>
<c-CListboxOption value="apac">Asia Pacific</c-CListboxOption>
</c-CListbox>
<c-CListbox label="Locked policy" value="strict" disabled variant="soft">
<c-CListboxOption value="standard">Standard</c-CListboxOption>
<c-CListboxOption value="strict">Strict</c-CListboxOption>
</c-CListbox>
</c-CStack>
"""
preview = DisabledListbox()
preview # noqa: B018
Keyboard navigation
Down and Up move between enabled Options. Home and End jump to the collection edges, printable text performs buffered typeahead, Enter or Space selects, and Escape clears a non-mandatory selection.
Show code
import citry_ui
from citry import Component, citry
citry.register_library(citry_ui)
class KeyboardListbox(Component):
template = """
<c-CListbox label="Jump to a city" value="brno" loop variant="outline">
<c-CListboxOption value="brno">Brno</c-CListboxOption>
<c-CListboxOption value="budapest">Budapest</c-CListboxOption>
<c-CListboxOption value="krakow">KrakΓ³w</c-CListboxOption>
<c-CListboxOption value="prague">Prague</c-CListboxOption>
<c-CListboxOption value="vienna">Vienna</c-CListboxOption>
</c-CListbox>
"""
preview = KeyboardListbox()
preview # noqa: B018
Customize Listbox
Show code
import citry_ui
from citry import Component, citry
citry.register_library(citry_ui)
class CustomizedListbox(Component):
css = """
.copper-listbox {
--cui-listbox-radius: 1.1rem;
--cui-listbox-selected-background: light-dark(#7c2d12, #fed7aa);
--cui-listbox-selected-foreground: light-dark(#fff7ed, #431407);
--cui-listbox-border-color: light-dark(#c2410c, #fdba74);
--cui-listbox-option-padding: 0.7rem 0.8rem;
}
"""
template = """
<c-CListbox label="Finish" value="copper" class_="copper-listbox" variant="outline">
<c-CListboxOption value="copper">
<c-fill name="start"><span aria-hidden="true">β</span></c-fill>
<c-fill name="default">Burnished copper</c-fill>
<c-fill name="description">Warm and tactile</c-fill>
</c-CListboxOption>
<c-CListboxOption value="slate">Deep slate</c-CListboxOption>
<c-CListboxOption value="linen">Soft linen</c-CListboxOption>
</c-CListbox>
"""
preview = CustomizedListbox()
preview # noqa: B018
Accessibility and behavior
The named collection uses role="listbox"; Options use role="option", and visible group labels name role="group" collections. One enabled Option is in the Tab order. Focus and selection remain separate, and disabled Options are skipped by keyboard navigation.
CListbox is a persistent application selection surface, not a form control. Use Select or MultiSelect when native form submission, reset, validity, or a compact popup is required.
API reference
Inputs
CListbox server inputs
Server inputs are passed in a template through <c-CListbox ... /> or in Python through CListbox(...).
| Input | Type | Default | Effect |
|---|---|---|---|
label | str | required | Supplies the visible accessible Listbox name. |
value | str | None | Sequence[str] (CListboxValue) | None | Sets initial single or multiple selection. |
multiple | bool | False | Enables independent multiple selection. |
mandatory | bool | False | Prevents user interaction from clearing the final selected Option. |
disabled | bool | False | Disables focus and selection throughout the collection. |
loop | bool | False | Wraps arrow navigation at collection edges. |
variant | "plain" | "soft" | "outline" (CListboxVariant) | "outline" | Selects surface treatment. |
size | "sm" | "md" | "lg" (CListboxSize) | "md" | Selects Option geometry. |
class_ | CClassValue | None (CClassValue) | None | Adds root classes. |
style | CStyleValue | None (CStyleValue) | None | Adds root inline styles. |
attrs | Mapping[str, object] | None | None | Adds trusted root attributes without replacing owned state structure or runtime. |
listbox_attrs | Mapping[str, object] | None | None | Adds trusted attributes to the role listbox surface without replacing owned semantics or focus. |
CListbox client inputs
Client inputs are passed in the browser through the $c-props="{ ... }" attribute on <c-CListbox />.
| Input | Type | Omitted behavior | Effect |
|---|---|---|---|
value | string | string[] | null | Releases control to committed selection. | Controls single or multiple selection while supplied. |
mandatory | bool | Uses the server value. | Reactively prevents the final user-selected value from clearing. |
disabled | bool | Uses the server value. | Reactively disables collection interaction. |
loop | bool | Uses the server value. | Reactively changes arrow wrapping. |
variant | "plain" | "soft" | "outline" (CListboxVariant) | Uses the server value. | Reactively changes surface treatment. |
size | "sm" | "md" | "lg" (CListboxSize) | Uses the server value. | Reactively changes Option geometry. |
onValueChange | ((value: string | string[] | null, detail: CListboxValueChangeDetail) => void) | undefined | No component callback runs. | Receives selection and structural-recovery requests. |
CListboxOption server inputs
Server inputs are passed in a template through <c-CListboxOption ... /> or in Python through CListboxOption(...).
| Input | Type | Default | Effect |
|---|---|---|---|
value | str | required | Supplies stable unique Option identity. |
disabled | bool | False | Prevents focus and selection for this Option. |
text_value | str | None | None | Overrides normalized visible label text for typeahead. |
class_ | CClassValue | None (CClassValue) | None | Adds classes to the concrete Option. |
style | CStyleValue | None (CStyleValue) | None | Adds inline styles to the concrete Option. |
attrs | Mapping[str, object] | None | None | Adds trusted Option attributes without replacing semantics identity focus or state. |
CListboxOption client inputs
Client inputs are passed in the browser through the $c-props="{ ... }" attribute on <c-CListboxOption />.
| Input | Type | Omitted behavior | Effect |
|---|---|---|---|
disabled | bool | Uses the server value. | Reactively disables this Option. |
textValue | string | null | Uses the server value or visible label. | Reactively changes typeahead text. |
CListboxGroup server inputs
Server inputs are passed in a template through <c-CListboxGroup ... /> or in Python through CListboxGroup(...).
| Input | Type | Default | Effect |
|---|---|---|---|
label | str | required | Supplies the visible accessible group name. |
class_ | CClassValue | None (CClassValue) | None | Adds classes to the group. |
style | CStyleValue | None (CStyleValue) | None | Adds inline styles to the group. |
attrs | Mapping[str, object] | None | None | Adds trusted group attributes without replacing owned semantics or label relationship. |
Slots
Slots are passed as nested content or <c-fill> tags in a template, or through the slots={...} argument in Python.
CListbox slots
| Slot | Required | Data | Fallback |
|---|---|---|---|
default | yes | {} (CListboxDefaultSlotData) | None. Accepts direct CListboxOption or CListboxGroup declarations. |
CListboxOption slots
| Slot | Required | Data | Fallback |
|---|---|---|---|
default | yes | {value} (CListboxOptionDefaultSlotData) | None. Supplies visible accessible label content. |
start | no | {value, selected, disabled} (CListboxOptionStateSlotData) | Omitted. Decorative leading content. |
description | no | {value} (CListboxOptionDescriptionSlotData) | Omitted. Supplies separately described supporting text. |
end | no | {value, selected, disabled} (CListboxOptionStateSlotData) | Omitted. Decorative trailing content. |
CListboxGroup slots
| Slot | Required | Data | Fallback |
|---|---|---|---|
default | yes | {} (CListboxGroupDefaultSlotData) | None. Accepts one or more direct CListboxOption declarations. |
Events
Component events are callback inputs supplied through $c-props. Native browser events remain available through Alpine @... attributes.
CListbox events
| Event | Signature | Trigger and timing | Detail | Controlled and cancellation behavior |
|---|---|---|---|---|
onValueChange | (value: string | string[] | null, detail: CListboxValueChangeDetail) => void (CListboxValueChangeDetail) | Enabled pointer or keyboard selection request or settled structural recovery. | {value, previousValue, option, selected, controlled, source, sourceEvent} (CListboxValueChangeDetail) | Commits immediately when uncontrolled and waits for owner acceptance when controlled. |
Methods
-
CSS
CSS variables to theme the components. Set them on an ancestor or the component itself.
CListbox CSS variables
Apply these variables to CListbox or one of its ancestors.
| Variable | Type | Purpose | Default |
|---|---|---|---|
--cui-listbox-gap | length | Gap between label and collection. | 0.375rem |
--cui-listbox-max-block-size | length | Maximum scrollable collection height. | 18rem |
--cui-listbox-background | color | Collection background. | variant-derived Canvas surface |
--cui-listbox-foreground | color | Collection foreground. | CanvasText |
--cui-listbox-muted-color | color | Disabled and secondary foreground. | light #667085; dark #a4a7ae |
--cui-listbox-border-color | color | Outline border. | light #d0d5dd; dark #535862 |
--cui-listbox-hover-background | color | Enabled hover surface. | 7% CanvasText mix |
--cui-listbox-selected-background | color | Selected Option surface. | light #dbeafe; dark #1e3a5f |
--cui-listbox-selected-foreground | color | Selected Option foreground. | light #1849a9; dark #d1e9ff |
--cui-listbox-focus-color | color | Roving focus outline. | Highlight |
--cui-listbox-radius | length | Collection corner radius. | 0.625rem |
--cui-listbox-option-padding | length | Option block and inline padding. | size-derived |
Attributes
HTML attributes defined on the components that you can refer to for CSS, inspection, and testing. Read-only.
CListbox attributes
| Attribute | Element | Type | Meaning |
|---|---|---|---|
role | Collection div | listbox | Declares the persistent selection widget. |
role | Option div | option | Declares each selectable value. |
role | Group div | group | Groups related Options under a visible label. |
aria-labelledby | Collection Option or Group div | IDREF | Connects each semantic owner to its visible label. |
aria-selected | Option div | true | false | Reflects effective selection. |
aria-disabled | Collection or Option div | true | false | Reflects effective unavailability. |
aria-multiselectable | Collection div | true | Present only in multiple mode. |
tabindex | Option div | 0 | -1 | Implements one enabled roving Tab stop. |
data-selected | Option div | present-or-absent | Mirrors selected styling state. |
data-active | Option div | present-or-absent | Mirrors roving focus identity. |
data-disabled | Root or Option div | present-or-absent | Mirrors effective unavailability. |
data-value | Option div | string | Exposes canonical Option identity. |
data-multiple | Root div | present-or-absent | Mirrors multiple selection mode. |
data-mandatory | Root div | present-or-absent | Mirrors final-selection protection. |
data-variant | Root div | plain | soft | outline | Mirrors effective surface treatment. |
data-size | Root div | sm | md | lg | Mirrors effective geometry. |
Selectors
Selectors for the DOM nodes in the components that you can use for CSS, inspection, and testing.
CListbox selectors
| Selector | Element | Purpose |
|---|---|---|
[data-citry-ui-part="listbox-root"] | Root div | Stable root attrs and state surface. |
[data-citry-ui-part="listbox-label"] | Label span | Visible collection label. |
[data-citry-ui-part="listbox"] | Collection div | Semantic and scrolling selection surface. |
[data-citry-ui-part="listbox-option"] | Option div | Stable Option attrs focus and state surface. |
[data-citry-ui-part="listbox-indicator"] | Indicator span | Decorative selected-state mark. |
[data-citry-ui-part="listbox-option-start"] | Start span | Decorative leading content wrapper. |
[data-citry-ui-part="listbox-option-copy"] | Copy span | Stable label and description layout wrapper. |
[data-citry-ui-part="listbox-option-label"] | Label span | Visible Option name and default typeahead source. |
[data-citry-ui-part="listbox-option-description"] | Description span | Separately described supporting text. |
[data-citry-ui-part="listbox-option-end"] | End span | Decorative trailing content wrapper. |
[data-citry-ui-part="listbox-group"] | Group div | Stable semantic grouping surface. |
[data-citry-ui-part="listbox-group-label"] | Group label span | Visible group name. |
Interfaces
Aliases and data shapes referenced above.
Input type aliases
| Interface | Definition |
|---|---|
CClassValue | str | Mapping[str, bool] | Sequence[CClassValue] |
CStyleValue | str | Mapping[str, object] | Sequence[CStyleValue] |
CListboxValue | str | None | Sequence[str] |
CListboxVariant | Literal["plain", "soft", "outline"] |
CListboxSize | Literal["sm", "md", "lg"] |
CListboxChangeSource | Literal["pointer", "keyboard", "structure"] |
CListboxDefaultSlotData
Empty dataclass: {}.
CListboxGroupDefaultSlotData
Empty dataclass: {}.
CListboxOptionDefaultSlotData
| Field | Type | Default | Meaning |
|---|---|---|---|
value | str | - | Canonical Option identity. |
CListboxOptionStateSlotData
| Field | Type | Default | Meaning |
|---|---|---|---|
value | str | - | Canonical Option identity. |
selected | bool | - | Server-rendered initial selected state. |
disabled | bool | - | Server-rendered initial Option disabled state. |
CListboxOptionDescriptionSlotData
| Field | Type | Default | Meaning |
|---|---|---|---|
value | str | - | Canonical Option identity. |
CListboxValueChangeDetail
| Field | Type | Default | Meaning |
|---|---|---|---|
value | str | list[str] | None | - | Requested next effective value. |
previousValue | str | list[str] | None | - | Prior effective value. |
option | HTMLElement | None | - | Changed Option or None for structural recovery. |
selected | bool | - | Whether the Option is requested selected. |
controlled | bool | - | Whether the client value currently controls selection. |
source | "pointer" | "keyboard" | "structure" (CListboxChangeSource) | - | Request source. |
sourceEvent | Event | None | - | Native source event or None for structure. |
Translation keys
-