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
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
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
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.
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.
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
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
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(...).
| Input | Type | Default | Effect |
|---|---|---|---|
sizes | Sequence[int | float] | None | None | Sets initial percentage sizes totaling 100; omission divides space equally. |
orientation | "horizontal" | "vertical" (CSplitterOrientation) | "horizontal" | Places panels side by side or stacked. |
disabled | bool | False | Disables every resize handle. |
keyboard_step | float | 2 | Sets 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) | 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 structure state or runtime. |
CSplitter client inputs
Client inputs are passed in the browser through the $c-props="{ ... }" attribute on <c-CSplitter />.
| Input | Type | Omitted behavior | Effect |
|---|---|---|---|
sizes | number[] | null | Uses uncontrolled committed sizes. | Controls percentages while supplied; null releases control. |
orientation | "horizontal" | "vertical" (CSplitterOrientation) | Uses the server value. | Reactively changes layout and keyboard axis. |
disabled | bool | Uses the server value. | Reactively disables resizing. |
keyboardStep | number | Uses 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) | undefined | No component callback runs. | Receives the beginning of a pointer or keyboard transaction. |
onResize | ((sizes: number[], detail: CSplitterResizeDetail) => void) | undefined | No component callback runs. | Receives each valid adjacent-pair resize request. |
onResizeEnd | ((sizes: number[], detail: CSplitterResizeDetail) => void) | undefined | No 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(...).
| Input | Type | Default | Effect |
|---|---|---|---|
id | str | required | Supplies stable panel identity and relationship targets. |
label | str | required | Supplies the panel and adjacent separator accessible names. |
min_size | float | 10 | Sets the minimum percentage. |
max_size | float | 100 | Sets the maximum percentage. |
class_ | CClassValue | None (CClassValue) | None | Adds classes to the concrete panel. |
style | CStyleValue | None (CStyleValue) | None | Adds inline styles to the concrete panel. |
attrs | Mapping[str, object] | None | None | Adds 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
| Slot | Required | Data | Fallback |
|---|---|---|---|
default | yes | {} (CSplitterDefaultSlotData) | None. Requires two or more direct CSplitterPanel declarations. |
CSplitterPanel slots
| Slot | Required | Data | Fallback |
|---|---|---|---|
default | yes | {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
| Event | Signature | Trigger and timing | Detail | Controlled 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.
| Variable | Type | Purpose | Default |
|---|---|---|---|
--cui-splitter-min-block-size | length | Minimum root block size. | 12rem |
--cui-splitter-radius | length | Root corner radius. | 0.75rem |
--cui-splitter-background | color | Root background. | plain and outline transparent; soft subtle CanvasText mix |
--cui-splitter-border-color | color | Outline root border. | light #d0d5dd; dark #535862 |
--cui-splitter-handle-size | length | Handle hit-area thickness. | sm 0.5rem; md 0.75rem; lg 1rem |
--cui-splitter-handle-color | color | Inactive line and grip. | light #98a2b3; dark #717680 |
--cui-splitter-handle-active-color | color | Hover and active grip. | light #175cd3; dark #84adff |
--cui-splitter-focus-color | color | Keyboard focus outline. | Highlight |
Attributes
HTML attributes defined on the components that you can refer to for CSS, inspection, and testing. Read-only.
CSplitter attributes
| Attribute | Element | Type | Meaning |
|---|---|---|---|
role | Panel or separator div | group | separator | Gives panels and resize handles their owned semantics. |
tabindex | Separator div | 0 | -1 | Includes enabled handles in Tab order and removes disabled handles. |
aria-label | Panel or separator div | string | Names each panel and each adjacent-pair handle. |
aria-disabled | Separator div | true | false | Reflects effective resize availability. |
data-orientation | Root div | horizontal | vertical | Mirrors effective layout. |
data-disabled | Root or handle | present-or-absent | Reflects effective resizing unavailability. |
data-resizing | Root div | present-or-absent | Present during pointer resizing. |
data-variant | Root div | plain | soft | outline | Mirrors effective surface treatment. |
data-size | Root div | sm | md | lg | Mirrors effective geometry. |
data-panel-id | Panel div | string | Exposes canonical panel identity. |
data-index | Panel div | nonnegative-integer-string | Exposes settled order. |
data-size-percent | Panel div | number-string | Mirrors effective percentage. |
data-min-size | Panel div | number-string | Exposes minimum percentage. |
data-max-size | Panel div | number-string | Exposes maximum percentage. |
data-handle-index | Separator div | nonnegative-integer-string | Identifies the adjacent pair. |
data-active | Separator div | present-or-absent | Present during its pointer transaction. |
aria-controls | Separator div | IDREF-list | Identifies both adjacent panels. |
aria-orientation | Separator div | vertical | horizontal | Exposes physical separator orientation. |
aria-valuemin | Separator div | number-string | Exposes pair minimum. |
aria-valuemax | Separator div | number-string | Exposes pair maximum. |
aria-valuenow | Separator div | number-string | Exposes the preceding panel percentage. |
Selectors
Selectors for the DOM nodes in the components that you can use for CSS, inspection, and testing.
CSplitter selectors
| Selector | Element | Purpose |
|---|---|---|
[data-citry-ui-part="splitter"] | Root div | Stable root and attrs destination. |
[data-citry-ui-part="panel"] | Panel div | Stable content and panel attrs destination. |
[data-citry-ui-part="handle"] | Separator div | Stable focusable resize control. |
[data-citry-ui-part="handle-line"] | Decorative span | Stable separator line. |
[data-citry-ui-part="handle-grip"] | Decorative span | Stable resize affordance. |
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] |
CSplitterOrientation | Literal["horizontal", "vertical"] |
CSplitterVariant | Literal["plain", "soft", "outline"] |
CSplitterSize | Literal["sm", "md", "lg"] |
CSplitterResizeSource | Literal["pointer", "keyboard"] |
CSplitterDefaultSlotData
Empty dataclass: {}.
CSplitterPanelDefaultSlotData
| Field | Type | Default | Meaning |
|---|---|---|---|
id | str | - | Canonical panel identity. |
index | int | - | Zero-based settled panel index. |
size | float | - | Server-rendered percentage. |
is_first | bool | - | Whether this is the first panel. |
is_last | bool | - | Whether this is the last panel. |
CSplitterResizeDetail
| Field | Type | Default | Meaning |
|---|---|---|---|
sizes | number[] | - | Requested effective vector. |
previousSizes | number[] | - | Vector before this transaction step. |
handleIndex | int | - | Zero-based changed separator index. |
controlled | bool | - | Whether client sizes currently controls state. |
source | "pointer" | "keyboard" (CSplitterResizeSource) | - | Interaction source. |
sourceEvent | Event | - | Native PointerEvent or KeyboardEvent. |
Translation keys
-