Skip to main content

rc-splitter

Resizable pane splitter with pointer, keyboard, and collapse/restore controls, following the WAI-ARIA Window Splitter pattern.

Package
@rcarls/rc-splitter
Element
<rc-splitter>
Native dependency
Pane content slots
State model
Controlled or uncontrolled pane size
Main events
rc-splitter-change

Installation

npm install @rcarls/rc-splitter
import '@rcarls/rc-splitter/define';

Live demo

Theming

The default demo mode shows the component without a package theme. Use the shared preview controls on this page to compare inherited, light, and dark color schemes or to apply the optional Material theme only inside the demo frames.

Collapsible panes

Set the collapsible attribute to render a toggle button on the separator that collapses or expands the primary pane:

<rc-splitter collapsible>
<div>Primary</div>
<div slot="secondary">Secondary</div>
</rc-splitter>

The button is also keyboard-accessible: while the separator handle has focus, Ctrl+Arrow (left/right for horizontal, up/down for vertical) toggles collapse. The Enter key on the handle itself also toggles collapse independently of the collapsible attribute.

Style the button via ::part(collapse-button). Its position and size are configurable through --rc-splitter-collapse-button-size (default 20px), --rc-splitter-collapse-button-offset, and the button color/background tokens.

Touch targets

A 24 px diameter transparent circle is always present on the drag handle as a ::after pseudo-element. It is non-interactive for mouse and keyboard. On touch devices (any-pointer: coarse) it becomes hittable, providing a WCAG 2.5.8-compliant touch target without widening the visual separator. The visual indicator and touch target are intentionally decoupled.

The #separator uses z-index: 1 so the touch target circle stacks above pane content when it extends past the separator strip edge, ensuring touch events are captured correctly.

Visual indicator

The default drag indicator is a 3-dot grip, rendered as a ::before pseudo-element inside the handle so the touch target (the handle element itself) and the visual remain independent. Hover highlights are scoped to the visual indicator only — they do not highlight the full separator strip.

Customise the indicator via CSS custom properties:

rc-splitter {
/* Switch from dots to a solid line or pill */
--rc-splitter-handle-pattern: none;
--rc-splitter-handle-fill: ButtonBorder;
--rc-splitter-handle-border-radius: 999px; /* pill shape */
--rc-splitter-handle-hover-fill: Highlight; /* hover state on indicator only */
--rc-splitter-handle-transition: 150ms ease;
}

Material 3 theme

When rc-theme-material is applied, the splitter uses an M3-style drag indicator modelled after the M3 bottom sheet drag handle:

  • Strip width: 24 px (1.5rem) — meets WCAG 2.5.8 in the cross axis (combined with the 24 px touch target circle on touch devices)
  • Indicator: 4 px × 32 px fully-rounded pill (--rc-splitter-handle-pattern: none, --rc-splitter-handle-fill, --rc-splitter-handle-border-radius: 999px)
  • Color: on-surface-variant at 40 % opacity
  • Hover: primary at 8 % opacity — on the pill only, not the strip
  • Transition: 150 ms with M3 standard easing

All tokens are CSS custom properties so individual values can be overridden without replacing the whole theme layer.

API

Properties

PropertyMarkupTypeDefaultDescription
labellabelstring"Splitter"Accessible label for this splitter. Default label is 'Splitter'.
orientationorientationSplitterOrientation"horizontal"Splitter orientation, for keyboard navigation and initial sizing.
modemodeSplitterMode"length"Determines length units for min, max and step attributes, one of either `length` (default) or `percent`
stepstepnumber1The step size for resizing, in either pixels or percentage points depending on `mode`.
minminnumber0Minimum size of the primary pane in current mode units. Defaults to 0.
maxmaxnumber | undefinedundefinedMaximum size of the primary pane in current mode units. Defaults to the full container size.
valuevalueUnknownNot specifiedThe current splitter value, corresponding to the separator position, in either pixels or percentage points depending on `mode`.
defaultValuedefault-valueUnknownNot specifiedInitial uncontrolled splitter value.
fixedfixedbooleanfalseToggles resizing ability
collapsiblecollapsiblebooleanfalseRenders a collapse/expand toggle button on the separator.
valueTextJS property onlyUnknownNot specifiedA human-readable string representation of the value.

Methods

No public methods are documented in the custom elements manifest.

Events

EventDetail typeDescription
rc-splitter-changeCustomEventNo description provided.

Slots

NameDescription
(default)Primary pane contents
secondarySecondary pane contents (optional)

CSS Custom Properties

PropertyDefaultDescription
--rc-splitter-separator-size6pxThickness of the separator bar
--rc-splitter-separator-handle-size100%Length of the drag handle area within the separator (also the length of the visible indicator)
--rc-splitter-separator-colorcolor-mix(in srgb, ButtonBorder 35%, Canvas 65%)Separator background color
--rc-splitter-keyline1px solid ButtonBorderShared separator keyline border
--rc-splitter-handle-colorButtonBorderColor of the dot grip indicators (default visual)
--rc-splitter-handle-thickness4pxCross-axis size of the visual indicator (dot column width or pill/line thickness)
--rc-splitter-handle-border-radius0Border-radius of the visual indicator; set to a large value (e.g. 999px) for a pill shape
--rc-splitter-handle-pattern<3-dot radial-gradient>background-image for the visual indicator; set to `none` to use a solid fill via --rc-splitter-handle-fill instead
--rc-splitter-handle-filltransparentbackground-color of the visual indicator; effective when --rc-splitter-handle-pattern is none (e.g. for a solid pill)
--rc-splitter-handle-hover-filltransparentbackground-color of the visual indicator on hover; scoped to the indicator element only, not the full separator strip
--rc-splitter-handle-transition0msCSS transition duration/easing for the visual indicator's background-color changes
--rc-splitter-collapse-button-size20pxDiameter of the collapse/expand toggle button
--rc-splitter-collapse-button-offset8pxDistance from the start edge of the separator to the collapse button center
--rc-splitter-collapse-button-bgCanvasCollapse button background color
--rc-splitter-collapse-button-hover-bgButtonFaceCollapse button background color on hover
--rc-splitter-collapse-button-borderButtonBorderCollapse button border color
--rc-splitter-collapse-button-colorButtonTextCollapse button icon color
--rc-splitter-separator-border-inline-start1px solid ButtonBorderInline-start border
--rc-splitter-separator-border-inline-end1px solid ButtonBorderInline-end border
--rc-splitter-separator-border-block-start1px solid ButtonBorderBlock-start border (vertical orientation)
--rc-splitter-separator-border-block-end1px solid ButtonBorderBlock-end border (vertical orientation)

CSS Parts

PartDescription
primaryPrimary pane container
secondarySecondary pane container
separatorThe separator bar
separator-handleThe focusable drag handle
collapse-buttonThe collapse/expand toggle button (only rendered when `collapsible` is set)