Theme
Version
GitHub PyPI Discord
On this page

Splitter

Use CSplitter when adjacent regions need user-adjustable space. Every CSplitterPanel has stable identity, an accessible name, and percentage constraints. Persist accepted sizes in application state through onResizeEnd when a layout should survive navigation.

Splitter at a glance

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

citry.register_library(citry_ui)


class SplitterAtAGlance(Component):
    template = """
      <c-CSplitter c-sizes="[30, 70]" variant="outline">
        <c-CSplitterPanel id="navigation" label="Navigation">
          <strong>Navigation</strong><p>Projects, files, and saved views.</p>
        </c-CSplitterPanel>
        <c-CSplitterPanel id="workspace" label="Workspace">
          <strong>Workspace</strong><p>Resize with the separator or its Arrow keys.</p>
        </c-CSplitterPanel>
      </c-CSplitter>
    """


preview = SplitterAtAGlance()
preview  # noqa: B018

Resize multiple panels

Resize three panels
Show code
import citry_ui
from citry import Component, citry

citry.register_library(citry_ui)


class MultiplePanels(Component):
    template = """
      <c-CSplitter c-sizes="[20, 45, 35]" variant="soft">
        <c-CSplitterPanel id="outline" label="Document outline">Outline</c-CSplitterPanel>
        <c-CSplitterPanel id="editor" label="Document editor">Editor</c-CSplitterPanel>
        <c-CSplitterPanel id="preview" label="Document preview">Preview</c-CSplitterPanel>
      </c-CSplitter>
    """


preview = MultiplePanels()
preview  # noqa: B018

Stack and nest Splitters

Stack and nest Splitters
Show code
import citry_ui
from citry import Component, citry

citry.register_library(citry_ui)


class VerticalNested(Component):
    template = """
      <c-CSplitter orientation="vertical" c-sizes="[35, 65]" variant="outline">
        <c-CSplitterPanel id="header" label="Header preview">Header preview</c-CSplitterPanel>
        <c-CSplitterPanel id="workbench" label="Workbench">
          <c-CSplitter c-sizes="[40, 60]" size="sm">
            <c-CSplitterPanel id="source" label="Source">Source</c-CSplitterPanel>
            <c-CSplitterPanel id="result" label="Result">Result</c-CSplitterPanel>
          </c-CSplitter>
        </c-CSplitterPanel>
      </c-CSplitter>
    """


preview = VerticalNested()
preview  # noqa: B018

Constrain keyboard resizing

Arrow keys move by keyboard_step percentage points, Shift uses four times the step, and Home or End reaches the adjacent pair constraint.

Constrain panel sizes
Show code
import citry_ui
from citry import Component, citry

citry.register_library(citry_ui)


class ConstrainedSplitter(Component):
    template = """
      <c-CSplitter c-sizes="[35, 65]" c-keyboard_step="5" variant="outline">
        <c-CSplitterPanel id="tools" label="Tools" c-min_size="20" c-max_size="50">
          Focus the separator. Arrow keys move 5%; Shift moves 20%; Home and End use the limits.
        </c-CSplitterPanel>
        <c-CSplitterPanel id="canvas" label="Canvas" c-min_size="40">Canvas</c-CSplitterPanel>
      </c-CSplitter>
    """


preview = ConstrainedSplitter()
preview  # noqa: B018

Control and persist sizes

Client sizes is controlled while supplied. The owner accepts resize requests by updating the vector and can persist the final vector from onResizeEnd.

Control Splitter sizes
Show code
import citry_ui
from citry import Component, citry

citry.register_library(citry_ui)


class ControlledSplitter(Component):
    template = """
      <section x-data="{ sizes: [25, 75], saved: '' }">
        <c-CSplitter
          c-sizes="[25, 75]"
          $c-props="{
            sizes,
            onResize: (next) => sizes = next,
            onResizeEnd: (next) => saved = next.map(value => value.toFixed(0)).join(' / ')
          }"
        >
          <c-CSplitterPanel id="filters" label="Filters">Filters</c-CSplitterPanel>
          <c-CSplitterPanel id="results" label="Results">Results</c-CSplitterPanel>
        </c-CSplitter>
        <output x-text="saved ? `Saved: ${saved}` : 'Resize to save the layout'"></output>
      </section>
    """


preview = ControlledSplitter()
preview  # noqa: B018

Disable resizing

Disable Splitter
Show code
import citry_ui
from citry import Component, citry

citry.register_library(citry_ui)


class DisabledSplitter(Component):
    template = """
      <fieldset disabled>
        <legend>Locked layout</legend>
        <c-CSplitter c-sizes="[40, 60]" variant="soft">
          <c-CSplitterPanel id="summary" label="Summary">Summary</c-CSplitterPanel>
          <c-CSplitterPanel id="details" label="Details">Details</c-CSplitterPanel>
        </c-CSplitter>
      </fieldset>
    """


preview = DisabledSplitter()
preview  # noqa: B018

Customize Splitter

Customize Splitter
Show code
import citry_ui
from citry import Component, citry

citry.register_library(citry_ui)


class CustomizedSplitter(Component):
    template = """
      <div class="brand-splitter">
        <style>
          .brand-splitter {
            --cui-splitter-radius: 1.25rem;
            --cui-splitter-handle-active-color: rebeccapurple;
            --cui-splitter-background: color-mix(in srgb, rebeccapurple 7%, Canvas);
          }
          .brand-splitter [data-citry-ui-part="panel"] { overflow-wrap: anywhere; }
        </style>
        <c-CSplitter c-sizes="[38, 62]" variant="outline" size="lg">
          <c-CSplitterPanel id="index" label="Index">Branded index</c-CSplitterPanel>
          <c-CSplitterPanel id="article" label="Article">Branded article</c-CSplitterPanel>
        </c-CSplitter>
      </div>
    """


preview = CustomizedSplitter()
preview  # noqa: B018

Accessibility and behavior

Each resize handle is a focusable ARIA separator with its current percentage, allowed range, physical orientation, and the IDs of its adjacent panels. Side-by-side layouts use Left and Right; stacked layouts use Up and Down. Pointer and keyboard interaction change only the adjacent pair, preserving its combined size. Controls inside panels retain their ordinary form behavior.

API reference

Inputs

CSplitter server inputs

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

InputTypeDefaultEffect
sizesSequence[int | float] | NoneNoneSets initial percentage sizes totaling 100; omission divides space equally.
orientation"horizontal" | "vertical" (CSplitterOrientation)"horizontal"Places panels side by side or stacked.
disabledboolFalseDisables every resize handle.
keyboard_stepfloat2Sets Arrow-key movement in percentage points.
variant"plain" | "soft" | "outline" (CSplitterVariant)"plain"Selects surface treatment.
size"sm" | "md" | "lg" (CSplitterSize)"md"Selects handle geometry.
class_CClassValue | None (CClassValue)NoneAdds root classes.
styleCStyleValue | None (CStyleValue)NoneAdds root inline styles.
attrsMapping[str, object] | NoneNoneAdds trusted root attributes without replacing owned structure state or runtime.

CSplitter client inputs

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

InputTypeOmitted behaviorEffect
sizesnumber[] | nullUses uncontrolled committed sizes.Controls percentages while supplied; null releases control.
orientation"horizontal" | "vertical" (CSplitterOrientation)Uses the server value.Reactively changes layout and keyboard axis.
disabledboolUses the server value.Reactively disables resizing.
keyboardStepnumberUses the server value.Reactively changes Arrow-key movement.
variant"plain" | "soft" | "outline" (CSplitterVariant)Uses the server value.Reactively changes surface treatment.
size"sm" | "md" | "lg" (CSplitterSize)Uses the server value.Reactively changes handle geometry.
onResizeStart((detail: CSplitterResizeDetail) => void) | undefinedNo component callback runs.Receives the beginning of a pointer or keyboard transaction.
onResize((sizes: number[], detail: CSplitterResizeDetail) => void) | undefinedNo component callback runs.Receives each valid adjacent-pair resize request.
onResizeEnd((sizes: number[], detail: CSplitterResizeDetail) => void) | undefinedNo component callback runs.Receives the settled end of a resize transaction.

CSplitterPanel server inputs

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

InputTypeDefaultEffect
idstrrequiredSupplies stable panel identity and relationship targets.
labelstrrequiredSupplies the panel and adjacent separator accessible names.
min_sizefloat10Sets the minimum percentage.
max_sizefloat100Sets the maximum percentage.
class_CClassValue | None (CClassValue)NoneAdds classes to the concrete panel.
styleCStyleValue | None (CStyleValue)NoneAdds inline styles to the concrete panel.
attrsMapping[str, object] | NoneNoneAdds trusted panel attributes without replacing owned semantics identity or sizing.

Slots

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

CSplitter slots

SlotRequiredDataFallback
defaultyes{} (CSplitterDefaultSlotData)None. Requires two or more direct CSplitterPanel declarations.

CSplitterPanel slots

SlotRequiredDataFallback
defaultyes{id, index, size, is_first, is_last} (CSplitterPanelDefaultSlotData)None. Supplies panel content.

Events

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

CSplitter events

EventSignatureTrigger and timingDetailControlled and cancellation behavior
onResizeStart(detail: CSplitterResizeDetail) => void (CSplitterResizeDetail)Pointerdown or an accepted keyboard resize.{sizes, previousSizes, handleIndex, controlled, source, sourceEvent} (CSplitterResizeDetail)Begins a resize transaction.
onResize(sizes: number[], detail: CSplitterResizeDetail) => void (CSplitterResizeDetail)Each accepted pointer or keyboard resize request.{sizes, previousSizes, handleIndex, controlled, source, sourceEvent} (CSplitterResizeDetail)Commits immediately when uncontrolled and waits for owner acceptance when controlled.
onResizeEnd(sizes: number[], detail: CSplitterResizeDetail) => void (CSplitterResizeDetail)Pointerup pointercancel disability or an accepted keyboard resize.{sizes, previousSizes, handleIndex, controlled, source, sourceEvent} (CSplitterResizeDetail)Ends the transaction and is the persistence composition point.

Methods

-

CSS

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

CSplitter CSS variables

Apply these variables to CSplitter or one of its ancestors.

VariableTypePurposeDefault
--cui-splitter-min-block-sizelengthMinimum root block size.12rem
--cui-splitter-radiuslengthRoot corner radius.0.75rem
--cui-splitter-backgroundcolorRoot background.plain and outline transparent; soft subtle CanvasText mix
--cui-splitter-border-colorcolorOutline root border.light #d0d5dd; dark #535862
--cui-splitter-handle-sizelengthHandle hit-area thickness.sm 0.5rem; md 0.75rem; lg 1rem
--cui-splitter-handle-colorcolorInactive line and grip.light #98a2b3; dark #717680
--cui-splitter-handle-active-colorcolorHover and active grip.light #175cd3; dark #84adff
--cui-splitter-focus-colorcolorKeyboard focus outline.Highlight

Attributes

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

CSplitter attributes

AttributeElementTypeMeaning
rolePanel or separator divgroup | separatorGives panels and resize handles their owned semantics.
tabindexSeparator div0 | -1Includes enabled handles in Tab order and removes disabled handles.
aria-labelPanel or separator divstringNames each panel and each adjacent-pair handle.
aria-disabledSeparator divtrue | falseReflects effective resize availability.
data-orientationRoot divhorizontal | verticalMirrors effective layout.
data-disabledRoot or handlepresent-or-absentReflects effective resizing unavailability.
data-resizingRoot divpresent-or-absentPresent during pointer resizing.
data-variantRoot divplain | soft | outlineMirrors effective surface treatment.
data-sizeRoot divsm | md | lgMirrors effective geometry.
data-panel-idPanel divstringExposes canonical panel identity.
data-indexPanel divnonnegative-integer-stringExposes settled order.
data-size-percentPanel divnumber-stringMirrors effective percentage.
data-min-sizePanel divnumber-stringExposes minimum percentage.
data-max-sizePanel divnumber-stringExposes maximum percentage.
data-handle-indexSeparator divnonnegative-integer-stringIdentifies the adjacent pair.
data-activeSeparator divpresent-or-absentPresent during its pointer transaction.
aria-controlsSeparator divIDREF-listIdentifies both adjacent panels.
aria-orientationSeparator divvertical | horizontalExposes physical separator orientation.
aria-valueminSeparator divnumber-stringExposes pair minimum.
aria-valuemaxSeparator divnumber-stringExposes pair maximum.
aria-valuenowSeparator divnumber-stringExposes the preceding panel percentage.

Selectors

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

CSplitter selectors

SelectorElementPurpose
[data-citry-ui-part="splitter"]Root divStable root and attrs destination.
[data-citry-ui-part="panel"]Panel divStable content and panel attrs destination.
[data-citry-ui-part="handle"]Separator divStable focusable resize control.
[data-citry-ui-part="handle-line"]Decorative spanStable separator line.
[data-citry-ui-part="handle-grip"]Decorative spanStable resize affordance.

Interfaces

Aliases and data shapes referenced above.

Input type aliases

InterfaceDefinition
CClassValuestr | Mapping[str, bool] | Sequence[CClassValue]
CStyleValuestr | Mapping[str, object] | Sequence[CStyleValue]
CSplitterOrientationLiteral["horizontal", "vertical"]
CSplitterVariantLiteral["plain", "soft", "outline"]
CSplitterSizeLiteral["sm", "md", "lg"]
CSplitterResizeSourceLiteral["pointer", "keyboard"]

CSplitterDefaultSlotData

Empty dataclass: {}.

CSplitterPanelDefaultSlotData

FieldTypeDefaultMeaning
idstr-Canonical panel identity.
indexint-Zero-based settled panel index.
sizefloat-Server-rendered percentage.
is_firstbool-Whether this is the first panel.
is_lastbool-Whether this is the last panel.

CSplitterResizeDetail

FieldTypeDefaultMeaning
sizesnumber[]-Requested effective vector.
previousSizesnumber[]-Vector before this transaction step.
handleIndexint-Zero-based changed separator index.
controlledbool-Whether client sizes currently controls state.
source"pointer" | "keyboard" (CSplitterResizeSource)-Interaction source.
sourceEventEvent-Native PointerEvent or KeyboardEvent.

Translation keys

-