Splitter - IgniteUI/igniteui-webcomponents GitHub Wiki

Splitter component specification

Owned by

Team name: Astrea

Developer name: Bozhidara Pachilova, Monika Kirkova

Designer name: TBD

Requires approval from:

  • Radoslav Karaivanov
  • Svilen Dimchevski

Signed off by:

  • Damyan Petev
  • Radoslav Mirchev

Revision history

Version Author Date Notes
1 Radoslav Karaivanov 2026-01-12 Initial draft
2 Radoslav Karaivanov 2026-02-06 Updated to release draft
3 Bozhidara Pachilova 2026-02-19 Updates slots
4 Bozhidara Pachilova 2026-03-11 Renames panel to pane

Overview

The igc-splitter component is a layout container that displays two adjacent panes separated by a resizable divider bar. It enables users to dynamically adjust the relative sizes of the panes by dragging the divider, and optionally collapse or expand individual panes to maximize workspace efficiency.

The component supports both horizontal (side-by-side) and vertical (stacked) orientations, making it suitable for a variety of layout scenarios such as:

  • Code editors: Source code pane alongside preview or console output
  • File browsers: Directory tree navigation with file content view
  • Email clients: Inbox list with message preview
  • Admin dashboards: Navigation sidebar with main content area
  • Data analysis tools: Dataset view with visualization or properties pane

Key Features

  • Flexible sizing: Configure initial, minimum, and maximum sizes for each pane using any valid CSS length unit
  • Interactive resize: Drag the splitter bar or use keyboard navigation to adjust pane proportions
  • Collapse/expand: Optionally allow users to completely collapse panes to maximize space for the other pane
  • Nested layouts: Compose complex multi-pane layouts by nesting splitters within panes
  • Customization: Control visibility of UI elements (drag handle, collapse buttons)
  • Accessibility-first: Full keyboard navigation and screen reader support following WAI-ARIA guidelines
  • Themeable: Integrates seamlessly with the library's theming system using CSS custom properties and shadow parts

Acceptance criteria

  • The component must render two distinct panes with slotted content support.
  • The splitter bar must be interactive, allowing resize operations via mouse/touch drag and keyboard navigation.
  • Both horizontal and vertical orientations must be fully supported and dynamically switchable.
  • pane sizes must respect configured constraints (min/max) during all resize operations.
  • Collapse/expand functionality must work via UI buttons, keyboard shortcuts, and programmatic API.
  • All resize operations must emit appropriate events with accurate size and delta information.
  • The component must be fully keyboard accessible with proper focus management and ARIA attributes.
  • The element must be integrated and themeable with the theming mechanism of the library.
  • The element must be WAI-ARIA compliant, using the appropriate semantic elements and ARIA roles.
  • The component must support RTL (Right-to-Left) layouts without additional configuration.
  • Nested splitters must function independently without interference.
  • The component must handle edge cases gracefully (invalid sizes, conflicting constraints, rapid interactions).

User stories

End-user stories

As and end-user, I expect to be able to:

  • see two panes of content, side by side, with a divider bar between them.
  • resize the panes by dragging the divider bar.
  • focus the divider bar and use the keyboard to resize the panes.
  • collapse and expand the panes.

Developer stories

As a developer, I expect to be able to:

  • slot arbitrary content inside the panes of the element.
  • slot another splitter inside one of the panes, allowing for more advanced layouts.
  • control the display layout of the panes - either horizontal or vertical.
  • set wether the panes can be resized by the end-user interaction.
  • set wether a pane can be collapsed.
  • set a default size for each pane.
  • set a min and max sizes for a pane.

Functionality

End-user experience

Design Hand-off

The splitter component presents users with a clear, intuitive interface for managing multi-pane layouts:

Visual Structure

  • Two distinct content panes positioned according to the orientation (side-by-side for horizontal, stacked for vertical)
  • A visible divider bar between panes that serves as the resize handle
  • Optional drag handle icon on the divider bar indicating interactivity
  • Optional collapse/expand buttons on each side of the divider bar when collapse functionality is enabled

Resize Interaction

  • Mouse/Touch: Users can click or tap on the splitter bar and drag to resize panes. The cursor changes to indicate the resize direction (↔ for horizontal, ↕ for vertical).
  • Keyboard: When the splitter bar has focus, arrow keys resize panes in 10px increments. The pane sizes update in real-time as the user navigates.
  • Constraints: Resize operations are visually constrained - users cannot drag beyond configured minimum or maximum sizes, providing clear boundaries.
  • Feedback: During resize, both panes update smoothly, giving immediate visual feedback of the size changes.

Collapse/Expand Interaction

  • UI Buttons: Clicking a collapse button completely hides the associated pane, maximizing space for the other pane. An expand button appears to restore the pane to its previous size.
  • Keyboard Shortcuts: Users can press Ctrl + Arrow keys to quickly collapse or expand panes without leaving keyboard navigation.
  • Single pane Constraint: Only one pane can be collapsed at a time, ensuring content is always visible.

Accessibility Experience

  • Focus Indicators: The splitter bar displays a clear focus ring when navigated to via keyboard.
  • Screen Reader Announcements: Screen readers announce the splitter's current state, including pane sizes and collapse/expand actions.
  • Predictable Navigation: Tab order flows naturally, and keyboard shortcuts follow standard conventions.

Developer experience

The igc-splitter component is designed for ease of integration with a declarative API and flexible configuration options.

Basic initialization

The simplest splitter requires only slotted content for the two panes:

<igc-splitter>
  <div slot="start">Start pane content</div>
  <div slot="end">End pane content</div>
</igc-splitter>

By default, this creates a horizontal splitter with equal-sized panes.

Configuring orientation and sizes

<igc-splitter orientation="vertical" start-size="300px">
  <div slot="start">Top pane (300px)</div>
  <div slot="end">Bottom pane (fills remaining space)</div>
</igc-splitter>

Setting size constraints

<igc-splitter
  start-size="250px"
  start-min-size="200px"
  start-max-size="400px"
  end-min-size="300px"
>
  <nav slot="start">Navigation (200-400px)</nav>
  <main slot="end">Main content (min 300px)</main>
</igc-splitter>

Disabling user interactions

<!-- Disable resizing but allow collapsing -->
<igc-splitter disable-resize>
  <div slot="start">Fixed-size pane</div>
  <div slot="end">Other pane</div>
</igc-splitter>

<!-- Disable both resize and collapse -->
<igc-splitter disable-resize disable-collapse>
  <div slot="start">Completely static layout</div>
  <div slot="end">No user interaction</div>
</igc-splitter>

Customizing visual elements

<!-- Hide drag handle -->
<igc-splitter hide-drag-handle>
  <div slot="start">Clean look</div>
  <div slot="end">No drag icon</div>
</igc-splitter>

<!-- Hide collapse buttons but keep keyboard support -->
<igc-splitter hide-collapse-buttons>
  <div slot="start">Collapse via Ctrl+Arrow only</div>
  <div slot="end">No visible buttons</div>
</igc-splitter>

#### Programmatic control

```typescript
const splitter = document.querySelector('igc-splitter');

// Toggle pane collapse state
splitter.toggle('start'); // Collapse or expand start pane
splitter.toggle('end'); // Collapse or expand end pane

// Listen to resize events
splitter.addEventListener('igcResizing', (event) => {
  const { startPanelSize, endPanelSize, delta } = event.detail;
  console.log(
    `Start: ${startPanelSize}px, End: ${endPanelSize}px, Delta: ${delta}px`
  );
});

splitter.addEventListener('igcResizeEnd', (event) => {
  // Save final pane sizes to localStorage
  localStorage.setItem('panelSizes', JSON.stringify(event.detail));
});

Nested splitters for complex layouts

<igc-splitter orientation="horizontal" start-size="250px">
  <!-- Left sidebar -->
  <aside slot="start">
    <h2>Sidebar</h2>
    <nav>Navigation items...</nav>
  </aside>

  <!-- Right side with vertical splitter -->
  <igc-splitter slot="end" orientation="vertical" start-size="60%">
    <!-- Main content area -->
    <main slot="start">
      <h1>Main Content</h1>
      <p>Primary workspace...</p>
    </main>

    <!-- Bottom pane -->
    <div slot="end">
      <h3>Console Output</h3>
      <pre>Log messages...</pre>
    </div>
  </igc-splitter>
</igc-splitter>

This creates a three-pane layout: a fixed sidebar on the left, main content on top-right, and a console pane on bottom-right.

Responsive design patterns

// Switch to vertical orientation on mobile
const splitter = document.querySelector('igc-splitter');
const mediaQuery = window.matchMedia('(max-width: 768px)');

function handleViewportChange(e) {
  splitter.orientation = e.matches ? 'vertical' : 'horizontal';
  if (e.matches) {
    // Adjust sizes for mobile
    splitter.startSize = '40%';
  }
}

mediaQuery.addEventListener('change', handleViewportChange);
handleViewportChange(mediaQuery);

Localization

The splitter component does not contain any text content that requires localization. All visual elements are icon-based, and developers can provide localized aria-label attributes for collapse/expand buttons through shadow parts if needed.

Keyboard interactions

Key combination Result
Arrow Up In vertical orientation, decreases the start pane size by 10px (increases end pane).
Arrow Down In vertical orientation, increases the start pane size by 10px (decreases end pane).
Arrow Left In horizontal orientation, decreases the start pane size by 10px (increases end pane).
Arrow Right In horizontal orientation, increases the start pane size by 10px (decreases end pane).
Ctrl + Arrow Up In vertical orientation, collapses/expands the start pane (if collapse is enabled).
Ctrl + Arrow Down In vertical orientation, collapses/expands the end pane (if collapse is enabled).
Ctrl + Arrow Left In horizontal orientation, collapses/expands the start pane (if collapse is enabled).
Ctrl + Arrow Right In horizontal orientation, collapses/expands the end pane (if collapse is enabled).
Home Resizes to the minimum size of the start pane.
End Resizes to the maximum size of the start pane.

API

Properties and attributes

Property Attribute Reflected Type Default Description
orientation orientation Yes horizontal | vertical horizontal Orientation layout for the splitter panes.
disableCollapse disable-collapse Yes boolean false Wether the user can collapse the panes of the splitter.
disableResize disable-resize Yes boolean false Wether the user can resize the panes by interacting with the splitter bar.
hideDragHandle hide-drag-handle Yes boolean false Controls the visibility of the drag handle on the splitter bar.
hideCollapseButtons hide-collapse-buttons Yes boolean false Controls the visibility of the expand/collapse buttons on the splitter bar.
startSize start-size No string | undefined - The initial display size of the start pane.
endSize end-size No string | undefined - The initial display size of the end pane.
startMinSize start-min-size No string | undefined - The minimum display size for the start pane.
startMaxSize start-max-size No string | undefined - The maximum display size for the start pane.
endMinSize end-min-size No string | undefined - The minimum display size for the end pane.
endMaxSize end-max-size No string | undefined - The maximum display size for the end pane.

Methods

Name Type signature Description
toggle (pane: 'start' | 'end'): void Toggles the collapsed state of the given pane.

Events

Name Cancellable Description
igcResizeStart false Fired when a user start resizing with the splitter bar.
igcResizing false Fired during user resizing.
igcResizeEnd false Fired when the user stops resizing.

Event Details:

All resize events emit the following detail object:

Note

This is a subject to change.

interface IgcSplitterResizeEventDetail {
  /** The current size of the start pane in pixels */
  startPanelSize: number;
  /** The current size of the end pane in pixels */
  endPanelSize: number;
  /** The change in size since the resize operation started (only for igcResizing and igcResizeEnd) */
  delta?: number;
}

Slots

Name Description
start The start pane ot the the splitter. In horizontal layout this is the leftmost pane and in vertical layout it is the topmost.
end The end pane of the splitter. In horizontal layout this is the rightmost pane and in vertical layout it is the bottom one.

CSS Shadow parts

Note

This is a subject to change.

Part Description
splitter-bar The resizable bar element between the two panes.
drag-handle The drag handle icon/element on the splitter bar.
start-pane The container for the start pane content.
end-pane The container for the end pane content.
start-collapse-btn The button to collapse the start pane.
end-collapse-btn The button to collapse the end pane.
start-expand-btn The button to expand the start pane when collapsed.
end-expand-btn The button to expand the end pane when collapsed.

Test scenarios

Rendering and Initialization

  1. Default rendering

    • Component renders with default horizontal orientation
    • Both panes are visible with equal sizes (if no explicit sizes set)
    • Splitter bar is rendered between panes
    • Drag handle is visible on the splitter bar
    • Collapse buttons are visible (if collapse is not disabled)
  2. Orientation

    • Setting orientation="horizontal" renders panes side by side
    • Setting orientation="vertical" renders panes stacked vertically
    • Changing orientation dynamically updates the layout
  3. Initial sizing

    • Setting startSize initializes the start pane to the specified size
    • Setting endSize initializes the end pane to the specified size
    • Sizes accept valid CSS length values (px, %, em, etc.)
    • When both sizes are set, they should be respected (within container constraints)
    • When only one size is set, the other pane fills remaining space

Resize Functionality

  1. Mouse/pointer resize

    • Dragging the splitter bar resizes both panes
    • Resize is constrained by startMinSize and startMaxSize
    • Resize is constrained by endMinSize and endMaxSize
    • Cursor changes appropriately on hover (e.g., col-resize, row-resize)
    • Resize works correctly in both orientations
  2. Resize events

    • igcResizeStart fires when drag begins
    • igcResizing fires during drag operation
    • igcResizeEnd fires when drag completes
    • Event detail contains correct startPanelSize and endPanelSize
    • Event detail contains correct delta for igcResizing and igcResizeEnd
  3. Disable resize

    • Setting disableResize="true" prevents user resizing
    • Splitter bar is still visible but non-interactive
    • Cursor does not change on hover when resize is disabled
    • Keyboard resize is also disabled

Collapse/Expand Functionality

  1. Collapse/expand via UI

    • Clicking collapse button on start pane collapses it
    • Clicking collapse button on end pane collapses it
    • Expand button appears when pane is collapsed
    • Clicking expand button restores the pane to previous size
    • Only one pane can be collapsed at a time
  2. Collapse/expand via API

    • toggle('start') toggles the collapsed state of start pane
    • toggle('end') toggles the collapsed state of end pane
    • Method works correctly when called programmatically
  3. Disable collapse

    • Setting disableCollapse="true" hides collapse/expand buttons
    • Collapse is not possible via keyboard when disabled
    • API method toggle() should still work (or be a no-op depending on design decision)

Visual Control Properties

  1. Hide drag handle

    • Setting hideDragHandle="true" hides the drag handle icon
    • Splitter bar is still interactive for resizing
    • Splitter bar is still focusable
  2. Hide collapse buttons

    • Setting hideCollapseButtons="true" hides all collapse/expand buttons
    • Collapse is still possible via keyboard (if not disabled)
    • Collapse is still possible via API method

Keyboard Navigation

  1. Focus management

    • Splitter bar is focusable with Tab key (when interactive)
    • Splitter bar has visible focus indicator
    • Focus is not lost during resize or collapse operations
  2. Arrow key resize

    • Arrow keys resize panes by 10px increments
    • Correct arrow keys work based on orientation
    • Resize respects min/max constraints
    • Resize triggers appropriate events
  3. Keyboard collapse/expand

    • Ctrl + Arrow combinations collapse/expand panes
    • Correct combinations work based on orientation
    • Works only when collapse is enabled
  4. Home/End keys

    • Home key resizes to start pane minimum size
    • End key resizes to start pane maximum size
    • Keys work correctly in both orientations

Nested Splitters

  1. Nesting behavior
    • Splitter can be nested inside another splitter's pane
    • Nested splitters maintain independent state
    • Resize operations don't interfere with parent/child splitters
    • Focus management works correctly with nested splitters

Slotted Content

  1. Content slots
    • Content slotted into start renders in start pane
    • Content slotted into end renders in end pane
    • Content updates when slot content changes
    • Complex content (forms, tables, etc.) renders correctly

Size Constraints

  1. Min/max constraints

    • panes respect startMinSize during resize
    • panes respect startMaxSize during resize
    • panes respect endMinSize during resize
    • panes respect endMaxSize during resize
    • Invalid constraint values are handled gracefully
    • Constraints work with different CSS units
  2. Constraint conflicts

    • Component handles conflicting constraints gracefully
    • When min sizes exceed container, behavior is predictable
    • When both panes have max sizes smaller than container, behavior is predictable

Accessibility

  1. ARIA attributes

    • Splitter bar has role="separator"
    • aria-orientation matches component orientation
    • tabindex="0" when interactive, -1 when not
    • aria-valuenow, aria-valuemin, aria-valuemax are set appropriately
  2. Screen reader support

    • Screen readers announce splitter bar correctly
    • Resize operations are announced
    • Collapse/expand state changes are announced

RTL Support

  1. Right-to-Left
    • Splitter works correctly in RTL context
    • Horizontal orientation is mirrored in RTL
    • Arrow key navigation is reversed appropriately in RTL
    • Visual elements (buttons, handles) are positioned correctly

Edge Cases

  1. Container resizing

    • Component adapts when container size changes
    • Relative sizes (percentages) update correctly
    • Absolute sizes are maintained when possible
  2. Rapid interactions

    • Rapid resize operations don't cause visual glitches
    • Rapid collapse/expand toggles are handled correctly
    • Event throttling/debouncing works as expected
  3. Invalid configurations

    • Invalid size values are handled gracefully
    • Invalid orientation values fall back to default
    • Missing slot content doesn't break rendering

Accessibility

ARIA roles and properties

Following the official guidelines the following ARIA properties must be present on the splitter's bar:

  • it must have an ARIA role of separator.
  • it must have aria-orientation equal to the orientation value of the splitter element.
  • if the splitter is interactive (i.e. resizable or collapsible), it must have a tabindex of 0, otherwise it must be set to -1.
  • Nice to have: consider using aria-value|now|min|max if appropriate.

Keyboard support

Already covered by the relevant section of the specification.

Right to Left support

The splitter element should work in Right-to-Left context without additional setup or configuration.

⚠️ **GitHub.com Fallback** ⚠️