Theme
Version
GitHub PyPI Discord
On this page

Accordion

Use CAccordion for a finite group of related sections. Each CAccordionItem renders a native heading and button. Panel content stays in the document when closed, preserving forms, browser-owned values, and nested component state.

Accordion at a glance

Open the field-guide sections to see the complete item pattern in a compact group.

Accordion at a glance
Show code
import citry_ui
from citry import Component, citry

citry.register_library(citry_ui)


class AccordionAtAGlance(Component):
    template = """
      <section class="forest-guide" aria-labelledby="forest-guide-title">
        <header>
          <p>Temperate rainforest</p>
          <h2 id="forest-guide-title">Layers of the forest</h2>
        </header>
        <c-CAccordion value="canopy" variant="separated">
          <c-CAccordionItem value="canopy">
            <c-fill name="title">Canopy</c-fill>
            <c-fill name="default">
              Interlocking crowns collect most sunlight and shelter the layers below.
            </c-fill>
          </c-CAccordionItem>
          <c-CAccordionItem value="understory">
            <c-fill name="title">Understory</c-fill>
            <c-fill name="default">
              Ferns, saplings, and mosses thrive in filtered green light.
            </c-fill>
          </c-CAccordionItem>
          <c-CAccordionItem value="floor">
            <c-fill name="title">Forest floor</c-fill>
            <c-fill name="default">
              Fungi and invertebrates return fallen wood to the soil.
            </c-fill>
          </c-CAccordionItem>
        </c-CAccordion>
      </section>
    """

    css = """
      :where(.forest-guide) {
        display: grid;
        gap: 1rem;
        max-width: 46rem;
        color: CanvasText;
        font-family: ui-sans-serif, system-ui, sans-serif;
      }

      :where(.forest-guide h2, .forest-guide p) {
        margin: 0;
      }

      :where(.forest-guide header > p) {
        color: light-dark(#2f6b45, #86d29e);
        font-size: 0.75rem;
        font-weight: 700;
        letter-spacing: 0.08em;
        text-transform: uppercase;
      }
    """


preview = AccordionAtAGlance()

preview  # noqa: B018

Compose Accordion items

Give every item a stable value, a title fill, and a default panel fill.

Compose an Accordion
Show code
import citry_ui
from citry import Component, citry

citry.register_library(citry_ui)


class BasicAccordion(Component):
    template = """
      <c-CAccordion value="moss">
        <c-CAccordionItem value="moss">
          <c-fill name="title">Moss gardens</c-fill>
          <c-fill name="default">
            Moss retains moisture around roots and fallen logs.
          </c-fill>
        </c-CAccordionItem>
        <c-CAccordionItem value="streams">
          <c-fill name="title">Cold streams</c-fill>
          <c-fill name="default">
            Shaded water stays cool enough for salmon and stoneflies.
          </c-fill>
        </c-CAccordionItem>
        <c-CAccordionItem value="nurse-logs">
          <c-fill name="title">Nurse logs</c-fill>
          <c-fill name="default">
            Seedlings use decaying trunks as raised, nutrient-rich beds.
          </c-fill>
        </c-CAccordionItem>
      </c-CAccordion>
    """


preview = BasicAccordion()

preview  # noqa: B018
<c-CAccordion value="canopy">
  <c-CAccordionItem value="canopy">
    <c-fill name="title">
      Forest canopy
    </c-fill>
    <c-fill name="default">
      The canopy captures most incoming sunlight.
    </c-fill>
  </c-CAccordionItem>
  <c-CAccordionItem value="understory">
    <c-fill name="title">
      Understory
    </c-fill>
    <c-fill name="default">
      Shade-tolerant plants grow beneath the canopy.
    </c-fill>
  </c-CAccordionItem>
</c-CAccordion>

For Python composition, supply one component whose output contains the direct items. This preserves item registration without introducing a DOM wrapper.

from citry import Component
from citry_ui import CAccordion


class FieldGuideItems(Component):
    template = """
      <c-CAccordionItem value="canopy">
        <c-fill name="title">Forest canopy</c-fill>
        <c-fill name="default">Upper forest layer</c-fill>
      </c-CAccordionItem>
    """


field_guide = CAccordion(
    value="canopy",
    slots={"default": FieldGuideItems()},
)

CAccordionItem is not standalone. Put it directly inside the nearest Accordion. Transparent components may generate items when they add no wrapper or other output.

Control expansion in the browser

Server inputs are passed in Python through <c-CAccordion ... /> attributes or a CAccordion(...) composition call. Client inputs are passed in the browser through $c-props="{...}".

Control Accordion value
Show code
import citry_ui
from citry import Component, citry

citry.register_library(citry_ui)


class ControlledAccordion(Component):
    template = """
      <section
        class="controlled-accordion"
        x-data="{selected: 'lichen'}"
      >
        <p aria-live="polite">
          Open section: <strong x-text="selected ?? 'none'">lichen</strong>
        </p>
        <c-CAccordion
          value="lichen"
          $c-props="{
            value: selected,
            onValueChange: (value) => selected = value,
          }"
        >
          <c-CAccordionItem value="lichen">
            <c-fill name="title">Lichen</c-fill>
            <c-fill name="default">A partnership between fungi and algae.</c-fill>
          </c-CAccordionItem>
          <c-CAccordionItem value="mushrooms">
            <c-fill name="title">Mushrooms</c-fill>
            <c-fill name="default">Temporary fruiting bodies of hidden fungal networks.</c-fill>
          </c-CAccordionItem>
          <c-CAccordionItem value="ferns">
            <c-fill name="title">Ferns</c-fill>
            <c-fill name="default">Ancient plants that reproduce through spores.</c-fill>
          </c-CAccordionItem>
        </c-CAccordion>
      </section>
    """

    css = """
      :where(.controlled-accordion) {
        display: grid;
        gap: 0.75rem;
        max-width: 44rem;
        color: CanvasText;
        font-family: ui-sans-serif, system-ui, sans-serif;
      }

      :where(.controlled-accordion > p) {
        margin: 0;
        color: light-dark(#356548, #8bcda0);
      }
    """


preview = ControlledAccordion()

preview  # noqa: B018

Single mode uses string | null; multiple mode uses string[] | null. onValueChange receives requests before an uncontrolled commit. When value is supplied, update it in the callback to accept the request. Omit the client value to release control without resetting the current valid browser state.

Choose an expansion policy

The default single mode keeps at most one panel open. Set multiple=True to open several. Set collapsible=False in single mode when an open item should stay open.

Compare expansion modes
Show code
import citry_ui
from citry import Component, citry

citry.register_library(citry_ui)


class ExpansionModes(Component):
    template = """
      <section class="expansion-modes" aria-label="Accordion expansion modes">
        <article>
          <h2>One section, always open</h2>
          <c-CAccordion value="roots" c-collapsible="False" variant="soft">
            <c-CAccordionItem value="roots">
              <c-fill name="title">Root network</c-fill>
              <c-fill name="default">Roots trade nutrients with underground fungi.</c-fill>
            </c-CAccordionItem>
            <c-CAccordionItem value="soil">
              <c-fill name="title">Living soil</c-fill>
              <c-fill name="default">A pinch of soil can hold billions of organisms.</c-fill>
            </c-CAccordionItem>
          </c-CAccordion>
        </article>
        <article>
          <h2>Several sections</h2>
          <c-CAccordion c-value="('cedar', 'hemlock')" multiple variant="soft">
            <c-CAccordionItem value="cedar">
              <c-fill name="title">Western red cedar</c-fill>
              <c-fill name="default">Scale-like leaves stay green through winter.</c-fill>
            </c-CAccordionItem>
            <c-CAccordionItem value="hemlock">
              <c-fill name="title">Western hemlock</c-fill>
              <c-fill name="default">Drooping leaders distinguish its young crowns.</c-fill>
            </c-CAccordionItem>
          </c-CAccordion>
        </article>
      </section>
    """

    css = """
      :where(.expansion-modes) {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
        gap: 1rem;
        color: CanvasText;
        font-family: ui-sans-serif, system-ui, sans-serif;
      }

      :where(.expansion-modes article) {
        min-width: 0;
      }

      :where(.expansion-modes h2) {
        margin-block: 0 0.625rem;
        font-size: 1rem;
      }
    """


preview = ExpansionModes()

preview  # noqa: B018

collapsible=False does not force an initial selection. After a section opens, its trigger remains focusable and exposes aria-disabled="true" while it is the item that cannot close.

Add adjacent actions

Put related Buttons, links, or menus in the actions slot. They render beside the heading, never inside its trigger. actions_label creates one named group for the controls.

Add item actions
Show code
import citry_ui
from citry import Component, citry

citry.register_library(citry_ui)


class AccordionActions(Component):
    template = """
      <c-CAccordion value="trail" variant="separated">
        <c-CAccordionItem
          value="trail"
          actions_label="Trail actions"
        >
          <c-fill name="title">River trail</c-fill>
          <c-fill name="actions">
            <a href="#river-map">Map</a>
            <button type="button">Save</button>
          </c-fill>
          <c-fill name="default">
            A shaded six-kilometre route follows the river upstream.
          </c-fill>
        </c-CAccordionItem>
        <c-CAccordionItem
          value="ridge"
          actions_label="Ridge actions"
        >
          <c-fill name="title">Ridge trail</c-fill>
          <c-fill name="actions">
            <a href="#ridge-map">Map</a>
          </c-fill>
          <c-fill name="default">
            An exposed climb reaches the old fire lookout.
          </c-fill>
        </c-CAccordionItem>
      </c-CAccordion>
    """


preview = AccordionActions()

preview  # noqa: B018

Title content is inside a native button. Keep it to noninteractive phrasing content. Links, form controls, nested headings, and another Accordion belong in the panel or actions slot.

Disable groups or items

Group disabled blocks every trigger. Item disabled blocks only that item. An open disabled item stays open.

Disable Accordion items
Show code
import citry_ui
from citry import Component, citry

citry.register_library(citry_ui)


class DisabledItems(Component):
    template = """
      <c-CAccordion value="open-trail">
        <c-CAccordionItem value="open-trail">
          <c-fill name="title">Fern loop</c-fill>
          <c-fill name="default">Open from dawn until dusk.</c-fill>
        </c-CAccordionItem>
        <c-CAccordionItem value="closed-trail" disabled>
          <c-fill name="title">Cedar crossing — temporarily closed</c-fill>
          <c-fill name="default">High water has covered the footbridge.</c-fill>
        </c-CAccordionItem>
        <c-CAccordionItem value="accessible-trail">
          <c-fill name="title">Wetland boardwalk</c-fill>
          <c-fill name="default">A level route through reeds and alder groves.</c-fill>
        </c-CAccordionItem>
      </c-CAccordion>
    """


preview = DisabledItems()

preview  # noqa: B018

An enclosing disabled native fieldset, including CForm's fieldset, remains authoritative. Client disabled=False cannot re-enable its descendant buttons.

Nest Accordion

Put a nested CAccordion in a panel. Do not place it in a title or action area. The nested root becomes a new registration and keyboard boundary.

Nest Accordion groups
Show code
import citry_ui
from citry import Component, citry

citry.register_library(citry_ui)


class NestedAccordion(Component):
    template = """
      <c-CAccordion value="trees" variant="separated">
        <c-CAccordionItem value="trees">
          <c-fill name="title">Trees</c-fill>
          <c-fill name="default">
            <p>Compare two trees found along the valley trail.</p>
            <c-CAccordion value="cedar" variant="plain" size="sm">
              <c-CAccordionItem value="cedar">
                <c-fill name="title">Western red cedar</c-fill>
                <c-fill name="default">A long-lived tree of moist lowland forests.</c-fill>
              </c-CAccordionItem>
              <c-CAccordionItem value="maple">
                <c-fill name="title">Bigleaf maple</c-fill>
                <c-fill name="default">Broad leaves support hanging gardens of moss.</c-fill>
              </c-CAccordionItem>
            </c-CAccordion>
          </c-fill>
        </c-CAccordionItem>
        <c-CAccordionItem value="wildflowers">
          <c-fill name="title">Wildflowers</c-fill>
          <c-fill name="default">Trillium and violets bloom before the canopy closes.</c-fill>
        </c-CAccordionItem>
      </c-CAccordion>
    """

    css = """
      :where([data-citry-ui-part="accordion-body"] > p:first-child) {
        margin-block-start: 0;
      }
    """


preview = NestedAccordion()

preview  # noqa: B018

Choose variant and size

outline, soft, separated, and plain cover connected and independent surfaces. sm, md, and lg change trigger, action, indicator, and panel geometry.

Compare variants and sizes
Show code
import citry_ui
from citry import Component, citry

citry.register_library(citry_ui)


class AccordionVariants(Component):
    class Kwargs:
        pass

    class Slots:
        pass

    template = """
      <section class="accordion-variants" aria-label="Accordion variants">
        <c-for each="variant in variants">
          <article>
            <h2>{{ variant }}</h2>
            <c-CAccordion c-variant="variant" value="rain">
              <c-CAccordionItem value="rain">
                <c-fill name="title">Rainfall</c-fill>
                <c-fill name="default">Frequent mist keeps the forest green.</c-fill>
              </c-CAccordionItem>
              <c-CAccordionItem value="light">
                <c-fill name="title">Filtered light</c-fill>
                <c-fill name="default">Sunflecks move across the understory.</c-fill>
              </c-CAccordionItem>
            </c-CAccordion>
          </article>
        </c-for>
        <article class="accordion-variants__sizes">
          <h2>Sizes</h2>
          <div class="accordion-variants__size-grid">
            <c-for each="size in sizes">
              <div>
                <h3>{{ size }}</h3>
                <c-CAccordion c-size="size" value="moss" variant="soft">
                  <c-CAccordionItem value="moss">
                    <c-fill name="title">Moss cover</c-fill>
                    <c-fill name="default">Soft ground holds overnight rain.</c-fill>
                  </c-CAccordionItem>
                </c-CAccordion>
              </div>
            </c-for>
          </div>
        </article>
      </section>
    """

    def template_data(
        self,
        kwargs: Kwargs,  # noqa: ARG002
        slots: Slots,  # noqa: ARG002
    ) -> dict[str, object]:
        return {
            "variants": ("outline", "soft", "separated", "plain"),
            "sizes": ("sm", "md", "lg"),
        }

    css = """
      :where(.accordion-variants) {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
        gap: 1.25rem;
        color: CanvasText;
        font-family: ui-sans-serif, system-ui, sans-serif;
      }

      :where(.accordion-variants article) {
        min-width: 0;
      }

      :where(.accordion-variants__sizes) {
        grid-column: 1 / -1;
      }

      :where(.accordion-variants__size-grid) {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr));
        gap: 1rem;
      }

      :where(.accordion-variants h2) {
        margin-block: 0 0.625rem;
        font-size: 0.875rem;
        text-transform: capitalize;
      }

      :where(.accordion-variants h3) {
        margin-block: 0 0.5rem;
        font-size: 0.75rem;
        text-transform: uppercase;
      }
    """


preview = AccordionVariants()

preview  # noqa: B018

Customize Accordion

Override public variables on an ancestor or one root. Stable part selectors target item anatomy. Browser inputs can change variant, size, indicator, and indicatorPosition without a server render.

Theme a field guide
Customize example
Show code
import citry_ui
from citry import Component, citry

citry.register_library(citry_ui)


class CustomizeAccordion(Component):
    template = """
      <section
        class="accordion-configurator"
        x-data="{
          variant: 'separated',
          size: 'md',
          indicator: true,
          indicator_position: 'end',
        }"
        @citry-ui-preview-controls.window="Object.assign($data, $event.detail)"
      >
        <header>
          <p>Live configuration</p>
          <h2>Forest field guide</h2>
        </header>
        <c-CAccordion
          value="watershed"
          class_="accordion-configurator__group"
          $c-props="{
            variant,
            size,
            indicator,
            indicatorPosition: indicator_position,
          }"
        >
          <c-CAccordionItem value="watershed">
            <c-fill name="title">Watershed</c-fill>
            <c-fill name="default">Every hillside stream eventually meets the river.</c-fill>
          </c-CAccordionItem>
          <c-CAccordionItem value="wildlife">
            <c-fill name="title">Wildlife corridor</c-fill>
            <c-fill name="default">Connected forest lets animals move between habitats.</c-fill>
          </c-CAccordionItem>
        </c-CAccordion>
      </section>
    """

    css = """
      :where(.accordion-configurator) {
        display: grid;
        gap: 1rem;
        max-width: 48rem;
        color: CanvasText;
        font-family: ui-sans-serif, system-ui, sans-serif;
      }

      :where(.accordion-configurator h2, .accordion-configurator p) {
        margin: 0;
      }

      :where(.accordion-configurator header > p) {
        color: light-dark(#39724e, #8fd4a6);
        font-size: 0.75rem;
        font-weight: 700;
        letter-spacing: 0.08em;
        text-transform: uppercase;
      }

      :where(.accordion-configurator__group) {
        --cui-accordion-radius: 1rem;
        --cui-accordion-trigger-open-color: light-dark(#1f6b3c, #8fe0aa);
        --cui-accordion-focus-color: light-dark(#2f855a, #70d397);
      }
    """


preview_controls = (
    {
        "name": "variant",
        "label": "Variant",
        "type": "select",
        "default": "separated",
        "options": (
            ("outline", "Outline"),
            ("soft", "Soft"),
            ("separated", "Separated"),
            ("plain", "Plain"),
        ),
    },
    {
        "name": "size",
        "label": "Size",
        "type": "select",
        "default": "md",
        "options": (("sm", "Small"), ("md", "Medium"), ("lg", "Large")),
    },
    {
        "name": "indicator_position",
        "label": "Indicator position",
        "type": "select",
        "default": "end",
        "options": (("start", "Start"), ("end", "End")),
    },
    {
        "name": "indicator",
        "label": "Show indicator",
        "type": "checkbox",
        "default": True,
    },
)

preview = CustomizeAccordion()

preview  # noqa: B018

class_, style, and attrs target the Accordion root. An item has its own class_, style, and attrs, plus exact maps for its native heading, trigger, panel, and optional actions wrapper. Unlayered consumer CSS overrides Citry UI defaults; named layers follow the site-wide layer-order contract.

Keyboard and accessibility

Every enabled trigger remains in normal Tab order. Enter and Space use native button activation. Arrow Up, Arrow Down, Home, and End move focus among enabled triggers without opening them; loop controls wrapping.

Choose heading_level to fit the page outline. Panels are neutral by default. Set region=True only when the panels benefit from landmarks; this adds role="region" and trigger-based naming as one pair.

Closing a panel that contains focus moves focus to its trigger before the panel becomes inert. A structural update that removes the focused item moves focus to the nearest enabled surviving trigger. If none survives, the update owner must choose an external destination.

Forms, animation, and content lifetime

Closed panel content remains mounted. Uncontrolled edits, successful controls, and nested component state survive close and reopen. Closed controls still belong to FormData and native constraint validation. A hidden required control can therefore block submission; applications must open the relevant panel before moving focus to it.

Rapid expansion requests replace the active animation instead of being ignored. Reduced-motion users receive an immediate commit. Settled panels do not clip overlays; a panel clips its contents only during the bounded height transition. Print shows every panel.

Trust boundaries

Item values and generated IDs are plain text. Raw values appear only in the public data-value; generated trigger/panel IDs use a stable hash. Title and panel content use ordinary Citry escaping. The chevron comes from the packaged icon allowlist.

Attribute maps are trusted authoring surfaces for unowned values. Accordion rejects attributes and Alpine directives that could replace native semantics, children, expansion visibility, focus ownership, a second popover/command activation owner, public mirrors, or Citry runtime markers.

API reference

Inputs

CAccordion server inputs

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

InputTypeDefaultEffect
valuestr | Sequence[str] | NoneNoneSets initial expansion. Single mode accepts one value; multiple mode accepts a duplicate-free sequence.
multipleboolFalseUses an ordered array value and allows several panels to remain open.
collapsibleboolTrueAllows the open item to close in single mode. Multiple mode always remains collapsible.
disabledboolFalseDisables every trigger without closing panels. An enclosing disabled Form or fieldset remains dominant.
loopboolTrueWraps optional Arrow Up and Arrow Down focus navigation.
variant"outline" | "soft" | "separated" | "plain" (CAccordionVariant)"outline"Selects connected border, quiet surface, separated card, or divider treatment.
size"sm" | "md" | "lg" (CAccordionSize)"md"Selects title, indicator, action, and panel geometry.
indicatorboolTrueShows the owned decorative chevron.
indicator_pos"start" | "end" (CAccordionIndicatorPos)"end"Places the chevron at the logical start or end of every trigger.
heading_levelLiteral[2, 3, 4, 5, 6] (CAccordionHeadingLevel)3Chooses the native heading level for every direct item.
regionboolFalseAdds role="region" and trigger-based naming to every panel. Use selectively to avoid landmark proliferation.
idstr | NoneNoneSets the root ID and stable trigger/panel ID prefix.
class_str | Mapping[str, bool] | Sequence[CClassValue] | None (CClassValue)NoneAdds root classes and merges them with attrs.
stylestr | Mapping[str, str | int | float | bool | None] | Sequence[CStyleValue] | None (CStyleValue)NoneAdds root inline styles and merges them with attrs.
attrsMapping[str, object] | NoneNoneAdds trusted unowned root attributes. Accordion semantics, focus, alternate visibility or overlay ownership, public mirrors, structure, and runtime namespaces are reserved.

CAccordion client inputs

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

InputTypeOmitted behaviorEffect
valuestring | null; string[] | null in multiple modeReleases client control and preserves the current valid browser state.Controls expansion with the mode-dependent public shape.
onValueChangefunctionNo callback.Receives accepted activation and structural-removal requests.
collapsiblebooleanUses the server input.Controls whether the open single item may close.
disabledbooleanUses the server input.Controls group disabledness below native Form or fieldset ownership.
loopbooleanUses the server input.Controls Arrow-key wrapping.
variant"outline" | "soft" | "separated" | "plain" (CAccordionVariant)Uses the server input.Controls visual treatment.
size"sm" | "md" | "lg" (CAccordionSize)Uses the server input.Controls geometry.
indicatorbooleanUses the server input.Controls chevron visibility.
indicatorPosition"start" | "end" (CAccordionIndicatorPos)Uses the server input.Controls logical chevron placement.

CAccordionItem server inputs

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

InputTypeDefaultEffect
valuenon-empty strrequiredSupplies stable item identity. Values must be unique within the nearest Accordion.
disabledboolFalseDisables this trigger without closing its panel.
actions_labelnon-whitespace str | NoneNoneNames the optional action group and emits its owned group role; requires actions.
class_str | Mapping[str, bool] | Sequence[CClassValue] | None (CClassValue)NoneAdds item-root classes and merges them with attrs.
stylestr | Mapping[str, str | int | float | bool | None] | Sequence[CStyleValue] | None (CStyleValue)NoneAdds item-root inline styles and merges them with attrs.
attrsMapping[str, object] | NoneNoneAdds trusted unowned item-root attributes.
heading_attrsMapping[str, object] | NoneNoneAdds trusted unowned native-heading attributes.
trigger_attrsMapping[str, object] | NoneNoneAdds trusted unowned native-button attributes and event listeners. Button semantics, activation ownership, and state are reserved.
panel_attrsMapping[str, object] | NoneNoneAdds trusted unowned panel attributes. Visibility, region semantics, ID, and state are reserved.
actions_attrsMapping[str, object] | NoneNoneAdds trusted unowned action-wrapper attributes. Requires actions; group naming and focus/live-region ownership are reserved.

CAccordionItem client inputs

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

InputTypeOmitted behaviorEffect
disabledbooleanUses the server input.Controls this item's disabledness below group and native fieldset ownership.

Slots

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

CAccordion slots

SlotRequiredDataFallback
defaultyes{} (CAccordionDefaultSlotData)None. Requires one or more direct CAccordionItem components.

CAccordionItem slots

SlotRequiredDataFallback
titleyes{} (CAccordionItemTitleSlotData)None. Renders inside the native trigger and accepts noninteractive phrasing content.
defaultyes{} (CAccordionItemDefaultSlotData)None. Renders as always-mounted panel flow content.
actionsno{} (CAccordionItemActionsSlotData)No adjacent action wrapper.

Events

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

CAccordion events

EventSignatureTrigger and timingDetailControlled and cancellation behavior
onValueChange(value: string | null | string[], detail: CAccordionValueChangeDetail) => voidAccepted trigger activation or one batched structural-removal fallback. Initial state and owner prop updates are excluded.{value, previousValue, itemValue: string | null, removedValues: string[], expanded: boolean, source: "activation" | "removal"}Runs before an uncontrolled commit. Controlled Accordion waits for value; return values do not cancel the request.

Methods

-

CSS

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

CAccordion CSS variables

Apply these variables to CAccordion or one of its ancestors.

VariableTypePurposeDefault
--cui-accordion-backgroundcolorConnected root and item surface.Canvas
--cui-accordion-foregroundcolorTitle and panel foreground.CanvasText
--cui-accordion-border-colorcolorRoot item and divider boundary.22% current-color mix.
--cui-accordion-border-widthlengthStable border geometry.1px
--cui-accordion-radiuslengthGroup and separated-item corners.0.75rem
--cui-accordion-gaplengthSeparated-item gap.0.75rem
--cui-accordion-shadowshadowSeparated-item elevation.Scheme-derived shadow.
--cui-accordion-trigger-backgroundcolorResting trigger background.transparent
--cui-accordion-trigger-hover-backgroundcolorEnabled hover background.8% current-color mix.
--cui-accordion-trigger-open-backgroundcolorExpanded trigger background.9% LinkText mix.
--cui-accordion-trigger-open-colorcolorExpanded title and chevron foreground.LinkText
--cui-accordion-focus-colorcolorTrigger focus ring.Highlight
--cui-accordion-indicator-colorcolorChevron foreground.currentColor
--cui-accordion-trigger-padding-inlinelengthTrigger inline inset.Size-derived.
--cui-accordion-trigger-padding-blocklengthTrigger block inset.Size-derived.
--cui-accordion-panel-padding-inlinelengthPanel-body inline inset.Size-derived.
--cui-accordion-panel-padding-blocklengthPanel-body block inset.Size-derived.
--cui-accordion-actions-gaplengthAdjacent action spacing.0.5rem
--cui-accordion-durationtimePanel and chevron transition duration.180ms
--cui-accordion-easingeasingPanel and chevron transition curve.ease-out

Attributes

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

CAccordion attributes

AttributeElementTypeMeaning
data-variantRoot"outline" | "soft" | "separated" | "plain"Mirrors effective visual treatment.
data-sizeRoot"sm" | "md" | "lg"Mirrors effective geometry.
data-multipleRootpresent | absentPresent in structural multiple mode.
data-collapsibleRootpresent | absentPresent while open items may close; always present in multiple mode.
data-disabledRootpresent | absentMirrors browser-effective group disabledness.
data-loopRootpresent | absentPresent while Arrow navigation wraps.
data-indicatorRootpresent | absentPresent while chevrons are visible.
data-indicator-posRoot"start" | "end"Mirrors logical chevron placement.
idRootstrUses the supplied root ID or a generated instance ID.

CAccordionItem attributes

AttributeElementTypeMeaning
data-stateItem, trigger, and panel"open" | "closed"Mirrors committed expansion.
data-disabledItem and triggerpresent | absentMirrors browser-effective item disabledness.
data-valueItemstrExposes canonical item identity for styling and inspection.
aria-expandedTrigger"true" | "false"Exposes native expansion state.
aria-disabledTriggerabsent | "true"Marks an otherwise enabled open trigger that cannot collapse.
disabledTriggerpresent | absentPresent for component-owned group or item disabledness. A native fieldset can also disable the trigger without adding this attribute.
idTrigger and panelgenerated strDerives a stable relationship pair from the root ID and canonical item value.
aria-controlsTriggerpanel IDREFIdentifies the panel controlled by this trigger.
aria-labelledbyPanelabsent | trigger IDREFNames a region panel from its trigger only when region mode is enabled.
aria-hiddenPanelabsent | "true"Present while the panel is collapsed.
inertPanelpresent | absentRemoves collapsed panel descendants from focus and interaction.
hiddenPanelpresent | absentRemoves a settled collapsed panel from rendering.
hiddenIndicator wrapperpresent | absentRemoves the chevron when indicator is disabled.
rolePanelabsent | "region"Present with aria-labelledby only when region mode is enabled.

Selectors

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

CAccordion selectors

SelectorElementPurpose
[data-citry-ui-part="accordion"]Root divGroup surface and class/style/attrs destination.
[data-citry-ui-part="accordion-item"]Item root divKeyed item surface and item attrs destination.
[data-citry-ui-part="accordion-header"]Header row divHeading and adjacent-action layout.
[data-citry-ui-part="accordion-heading"]Native h2-h6Document-outline heading and heading_attrs destination.
[data-citry-ui-part="accordion-trigger"]Native buttonExpansion control and trigger_attrs destination.
[data-citry-ui-part="accordion-title"]Trigger title spanVisible title and accessible-name content.
[data-citry-ui-part="accordion-indicator"]Decorative spanOwned chevron wrapper.
[data-citry-ui-part="accordion-actions"]Optional adjacent-action divAction layout naming and actions_attrs destination.
[data-citry-ui-part="accordion-panel"]Controlled panel divVisibility region semantics and panel_attrs destination.
[data-citry-ui-part="accordion-body"]Panel-body divContent inset and overflow-neutral surface.

Interfaces

Aliases and data shapes referenced above.

Input type aliases

InterfaceDefinition
CClassValuestr | Mapping[str, bool] | Sequence[CClassValue]
CStyleValuestr | Mapping[str, str | int | float | bool | None] | Sequence[CStyleValue]
CAccordionVariantLiteral["outline", "soft", "separated", "plain"]
CAccordionSizeLiteral["sm", "md", "lg"]
CAccordionIndicatorPosLiteral["start", "end"]
CAccordionHeadingLevelLiteral[2, 3, 4, 5, 6]
CAccordionValueChangeDetail{value: string | null | string[], previousValue: string | null | string[], itemValue: string | null, removedValues: string[], expanded: boolean, source: "activation" | "removal"}

CAccordionDefaultSlotData

Empty dataclass: {}.

CAccordionItemTitleSlotData

Empty dataclass: {}.

CAccordionItemDefaultSlotData

Empty dataclass: {}.

CAccordionItemActionsSlotData

Empty dataclass: {}.

Translation keys

-