Theme
Version
GitHub PyPI Discord
On this page

Cascader

Use CCascader when a value is meaningful only as a path through related levels. Each CCascaderOption declares a globally unique value and plain label; nested Options create the next column.

Choose a geographic path
Show code
import citry_ui
from citry import Component, citry

citry.register_library(citry_ui)


class CascaderAtAGlance(Component):
    template = """
      <c-CCascader c-value="['europe','czechia','prague']">
        <c-CCascaderOption value="europe" label="Europe">
          <c-CCascaderOption value="czechia" label="Czechia">
            <c-CCascaderOption value="prague" label="Prague" />
          </c-CCascaderOption>
          <c-CCascaderOption value="germany" label="Germany">
            <c-CCascaderOption value="berlin" label="Berlin" />
          </c-CCascaderOption>
        </c-CCascaderOption>
      </c-CCascader>
    """


preview = CascaderAtAGlance()
preview  # noqa: B018

Submit the complete path

Set name to produce one hidden input per accepted segment, in root-to-leaf order. form supports an external native form. Without JavaScript, the initial path remains visible and submits normally.

Submit category segments
Show code
# ruff: noqa: E501 - embedded Citry templates remain readable as authored HTML

import citry_ui
from citry import Component, citry

citry.register_library(citry_ui)


class CascaderForms(Component):
    template = """
      <form>
        <c-CCascader name="category" c-value="['hardware','cameras','mirrorless']">
          <c-CCascaderOption value="hardware" label="Hardware"><c-CCascaderOption value="cameras" label="Cameras"><c-CCascaderOption value="mirrorless" label="Mirrorless" /></c-CCascaderOption></c-CCascaderOption>
        </c-CCascader>
        <button type="submit">Save category</button>
      </form>
    """


preview = CascaderForms()
preview  # noqa: B018

Control selection

Pass value and onValueChange through $c-props for controlled state. The callback receives the path plus labels, previous path, selected Option element, controlled flag, interaction source, and native event. Invalid controlled value or open values are diagnosed once and retain the last valid effective state. Omitting value returns to the retained uncontrolled path; omitting open releases control without changing the current open state.

Own the accepted location
Show code
import citry_ui
from citry import Component, citry

citry.register_library(citry_ui)


class CascaderControlled(Component):
    template = """
      <div x-data="{place:['earth','north'], last:''}">
        <c-CCascader $c-props="{value:place,onValueChange:(value)=>{place=value;last=value.join(' / ')}}">
          <c-CCascaderOption value="earth" label="Earth">
            <c-CCascaderOption value="north" label="Northern hemisphere" />
            <c-CCascaderOption value="south" label="Southern hemisphere" />
          </c-CCascaderOption>
        </c-CCascader>
        <output x-text="last"></output>
      </div>
    """


preview = CascaderControlled()
preview  # noqa: B018

Allow parent paths

The default requires a leaf. Set change_on_select=True when a category at any depth is a complete result. Activating a collapsed branch selects it and opens its children. Activating the expanded branch again collapses its child level.

Select any category depth
Show code
# ruff: noqa: E501 - embedded Citry templates remain readable as authored HTML

import citry_ui
from citry import Component, citry

citry.register_library(citry_ui)


class CascaderParentSelection(Component):
    template = """
      <c-CCascader c-change_on_select="True">
        <c-CCascaderOption value="design" label="Design"><c-CCascaderOption value="research" label="Research" /><c-CCascaderOption value="systems" label="Design systems" /></c-CCascaderOption>
        <c-CCascaderOption value="engineering" label="Engineering"><c-CCascaderOption value="platform" label="Platform" /></c-CCascaderOption>
      </c-CCascader>
    """


preview = CascaderParentSelection()
preview  # noqa: B018

Disable unavailable paths

A disabled Option cannot be opened or selected, and an initial value cannot pass through it. Root disabled also disables form inputs.

Keep unavailable regions visible
Show code
# ruff: noqa: E501 - embedded Citry templates remain readable as authored HTML

import citry_ui
from citry import Component, citry

citry.register_library(citry_ui)


class CascaderDisabled(Component):
    template = """
      <c-CCascader>
        <c-CCascaderOption value="available" label="Available"><c-CCascaderOption value="one" label="Warehouse one" /></c-CCascaderOption>
        <c-CCascaderOption value="maintenance" label="Under maintenance" c-disabled="True"><c-CCascaderOption value="two" label="Warehouse two" /></c-CCascaderOption>
      </c-CCascader>
    """


preview = CascaderDisabled()
preview  # noqa: B018

Support keyboard and constrained layouts

Arrow keys move within and across columns; Home, End, typeahead, Enter, Space, Escape, and Tab follow the popup tree contract. Pointer activation, Enter, and Space toggle a branch's child level without changing an already accepted leaf. Use aria_label or aria_labelledby to give the trigger an application-specific accessible name. Active columns sit side by side whenever their preferred width fits the viewport. Only when they do not fit do they stack vertically at the trigger width, avoiding page-level and nested horizontal scrollbars. While open, the popup also shifts back inside the viewport when its trigger sits near an inline edge. RTL reverses both column progression and branch indicators. The labeled taxonomy deliberately uses wider columns to demonstrate the stacked form in its constrained preview.

Navigate a labeled taxonomy
Show code
# ruff: noqa: E501 - embedded Citry templates remain readable as authored HTML

import citry_ui
from citry import Component, citry

citry.register_library(citry_ui)


class CascaderAccessibility(Component):
    template = """
      <label id="team-label">Owning team</label>
      <c-CCascader aria_labelledby="team-label" c-value="['product','experience','research']" size="lg" variant="soft" c-style="{'--cui-cascader-column-width': '14rem'}">
        <c-CCascaderOption value="product" label="Product">
          <c-CCascaderOption value="experience" label="Customer experience">
            <c-CCascaderOption value="research" label="Customer research" />
          </c-CCascaderOption>
        </c-CCascaderOption>
        <c-CCascaderOption value="operations" label="Operations">
          <c-CCascaderOption value="support" label="Customer support">
            <c-CCascaderOption value="priority" label="Priority support" />
          </c-CCascaderOption>
        </c-CCascaderOption>
      </c-CCascader>
    """


preview = CascaderAccessibility()
preview  # noqa: B018

Search, multiple paths, async child loading, and virtualized levels are not silent modes of this API; they remain separate future contracts.

API reference

Inputs

CCascader server inputs

Server inputs are passed in a template through <c-CCascader ... /> or in Python through CCascader(...).

InputTypeDefaultEffect
valueSequence[str]"()"Supplies the accepted continuous root-to-Option path.
idstr | NonegeneratedSets root and related popup IDs.
aria_labelstr | NoneNoneGives the trigger an explicit accessible name.
aria_labelledbystr | NoneNoneAssociates the trigger with external labeling elements.
namestr | NoneNoneEmits one hidden input per accepted path segment.
formstr | NoneNoneAssociates hidden inputs with an external form.
placeholderstr"Choose an option"Supplies empty trigger text or overrides its catalog message.
separatorstr" / "Joins application Option labels in the trigger.
change_on_selectboolFalseAllows branches as complete selected paths.
openboolFalseSupplies initial uncontrolled popup state.
disabledboolFalseDisables selection and form output.
sizeCCascaderSize (CCascaderSize)"md"Selects trigger height.
variantCCascaderVariant (CCascaderVariant)"outline"Selects trigger presentation.
empty_labelstr"No options"Overrides empty-hierarchy text.
selected_labelstr"Selected {path}"Overrides selected-path announcement and must retain path.
class_CClassValue | None (CClassValue)NoneAdds root classes.
styleCStyleValue | None (CStyleValue)NoneAdds root styles.
attrsMapping[str, object] | NoneNoneAdds copied allowed root attributes.

CCascader client inputs

Client inputs are passed in the browser through the $c-props="{ ... }" attribute on <c-CCascader />.

InputTypeOmitted behaviorEffect
valuestring[]Uncontrolled server path.Controls the accepted path.
openbooleanUncontrolled server open state.Controls popup visibility.
disabledbooleanUses the server value.Reactively disables interaction and form inputs.
onValueChangefunctionNo component callback runs.Receives selection requests.
onOpenChangefunctionNo component callback runs.Receives popup requests.

CCascaderOption server inputs

Server inputs are passed in a template through <c-CCascaderOption ... /> or in Python through CCascaderOption(...).

InputTypeDefaultEffect
valuestrrequiredSupplies globally unique stable Option identity.
labelstrrequiredSupplies visible plain application-localized text.
disabledboolFalsePrevents opening or selecting this path.
class_CClassValue | None (CClassValue)NoneAdds Option classes.
styleCStyleValue | None (CStyleValue)NoneAdds Option styles.
attrsMapping[str, object] | NoneNoneAdds copied allowed Option attributes.

Slots

Slots are passed as nested content or <c-fill> tags in a template, or through the slots={...} argument in Python.

CCascader slots

SlotRequiredDataFallback
defaultno{} (CCascaderDefaultSlotData)Empty hierarchy status; accepts root Option declarations only.

CCascaderOption slots

SlotRequiredDataFallback
defaultno{parent_value, level} (CCascaderOptionDefaultSlotData)Leaf Option; accepts child Option declarations only.

Events

Component events are callback inputs supplied through $c-props. Native browser events remain available through Alpine @... attributes.

CCascader events

EventSignatureTrigger and timingDetailControlled and cancellation behavior
onValueChange(value: string[], detail: CCascaderValueChangeDetail) => void (CCascaderValueChangeDetail)An allowed Option is activated.{value, labels, previousValue, controlled, source, option, sourceEvent} (CCascaderValueChangeDetail)Commits only while uncontrolled.
onOpenChange(open: boolean, detail: CCascaderOpenChangeDetail) => void (CCascaderOpenChangeDetail)The popup is requested open or closed.{open, reason, sourceEvent} (CCascaderOpenChangeDetail)Commits only while uncontrolled.

Methods

-

CSS

CSS variables to theme the components. Set them on an ancestor or the component itself.

CCascader CSS variables

Apply these variables to CCascader or one of its ancestors.

VariableTypePurposeDefault
--cui-cascader-widthlengthTrigger inline size.18rem
--cui-cascader-column-widthlengthPreferred width of one hierarchy column before measured-fit stacking.11rem
--cui-cascader-max-heightlengthMaximum column height.18rem
--cui-cascader-bordercomplete borderTrigger popup and column boundaries.Adaptive 1px neutral
--cui-cascader-surfacecolorTrigger and popup surface.Canvas
--cui-cascader-active-surfacecolorActive branch and selected Option.Adaptive indigo
--cui-cascader-radiuslengthTrigger and popup corners.0.625rem
--cui-cascader-shadowshadowPopup elevation.Soft elevation
--cui-cascader-focuscolorTrigger and Option focus.Highlight

Attributes

HTML attributes defined on the components that you can refer to for CSS, inspection, and testing. Read-only.

CCascader attributes

AttributeElementTypeMeaning
data-openRootpresent | absentReflects effective popup visibility.
data-disabledRoot and Optionpresent | absentReflects unavailable interaction.
data-sizeRootCCascaderSize (CCascaderSize)Reflects presentation size.
data-variantRootCCascaderVariant (CCascaderVariant)Reflects presentation variant.
data-activeOptionpresent | absentMarks the branch whose child column is visible.
data-selectedOptionpresent | absentMarks the accepted path endpoint.
data-valueOptionstringExposes stable Option identity.
data-levelOptionpositive integer stringExposes one-based hierarchy depth.
aria-levelOptionpositive integer stringPreserves hierarchy depth while visual columns are siblings.
aria-posinsetOptionpositive integer stringExposes the Option position in its logical group.
aria-setsizeOptionpositive integer stringExposes the number of Options in its logical group.
aria-ownsBranch OptionID referenceOwns the sibling visual group that contains its children.

Selectors

Selectors for the DOM nodes in the components that you can use for CSS, inspection, and testing.

CCascader selectors

SelectorElementPurpose
[data-citry-ui-part="cascader"]RootState and theme destination.
[data-citry-ui-part="trigger"]Native buttonAccepted value and popup control.
[data-citry-ui-part="value"]SpanSelected path or placeholder.
[data-citry-ui-part="indicator"]Decorative spanIndicates popup disclosure.
[data-citry-ui-part="popup"]Popup divResponsive visual-column container.
[data-citry-ui-part="tree"]Root treeComposite keyboard owner.
[data-citry-ui-part="group"]Logically owned sibling groupOne child column.
[data-citry-ui-part="option"]TreeitemFocus branch and selection unit.
[data-citry-ui-part="option-row"]DivVisible Option surface.
[data-citry-ui-part="option-label"]SpanApplication Option label.
[data-citry-ui-part="option-indicator"]Decorative spanIndicates children in the current inline direction.
[data-citry-ui-part="empty"]ParagraphEmpty-hierarchy status.
[data-citry-ui-part="inputs"]Hidden spanNative ordered path controls.
[data-citry-ui-part="status"]Polite statusSelection announcement.

Interfaces

Aliases and data shapes referenced above.

Input type aliases

InterfaceDefinition
CCascaderSizeLiteral["sm", "md", "lg"]
CCascaderVariantLiteral["outline", "soft", "plain"]
CCascaderChangeSourceLiteral["pointer", "keyboard", "reset"]
CClassValuestr | Mapping[str, bool] | Sequence[CClassValue]
CStyleValuestr | Mapping[str, object] | Sequence[CStyleValue]

CCascaderDefaultSlotData

Empty dataclass: {}.

CCascaderOptionDefaultSlotData

FieldTypeDefaultMeaning
parent_valuestr-Parent Option value.
levelint-One-based parent level.

CCascaderValueChangeDetail

FieldTypeDefaultMeaning
valuelist[str]-Requested path.
labelslist[str]-Application labels for that path.
previousValuelist[str]-Previously accepted path.
controlledbool-Whether value was supplied as a client prop.
sourceCCascaderChangeSource (CCascaderChangeSource)-Request interaction source.
optionobject-Requested treeitem element.
sourceEventobject-Native source Event.

CCascaderOpenChangeDetail

FieldTypeDefaultMeaning
openbool-Requested popup visibility.
reasonstr-Trigger selection escape tab or outside.
sourceEventobject-Native source Event.

Translation keys

Catalog keys used by this family. An explicit component input or slot listed in Override takes precedence over the catalog for that instance.

CCascader translation keys

KeyPurposeVariablesOverrideBrowser updates
citry-ui-cascader-placeholderLabels an empty trigger.None.placeholderRuntime i18n.bind() while the accepted path is empty.
citry-ui-cascader-emptyLabels an empty hierarchy.None.empty_labelStable $c-tr text.
citry-ui-cascader-selectedAnnounces an accepted path.path: strselected_label with {path}Browser one-shot i18n.tr() with a server-localized fallback pattern.