Skip to content

Splitter

Radoslav Karaivanov edited this page Feb 6, 2026 · 5 revisions

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

Overview

The igc-splitter component is a layout container that displays two adjacent panels (panes) separated by a resizable divider bar. It enables users to dynamically adjust the relative sizes of the panels by dragging the divider, and optionally collapse or expand individual panels 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 panel 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 panel

Key Features

  • Flexible sizing: Configure initial, minimum, and maximum sizes for each panel using any valid CSS length unit
  • Interactive resize: Drag the splitter bar or use keyboard navigation to adjust panel proportions
  • Collapse/expand: Optionally allow users to completely collapse panels to maximize space for the other panel
  • Nested layouts: Compose complex multi-panel layouts by nesting splitters within panels
  • Full customization: Control visibility of UI elements (drag handle, collapse buttons) and customize icons via slots
  • 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 panels 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.
  • Panel 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 panels of content, side by side, with a divider bar between them.
  • resize the panels by dragging the divider bar.
  • focus the divider bar and use the keyboard to resize the panels.
  • collapse and expand the panels.

Developer stories

As a developer, I expect to be able to:

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

Functionality

End-user experience

Design Hand-off

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

Visual Structure

  • Two distinct content panels positioned according to the orientation (side-by-side for horizontal, stacked for vertical)
  • A visible divider bar between panels 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 panels. The cursor changes to indicate the resize direction (↔ for horizontal, ↕ for vertical).
  • Keyboard: When the splitter bar has focus, arrow keys resize panels in 10px increments. The panel 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 panels update smoothly, giving immediate visual feedback of the size changes.

Collapse/Expand Interaction

  • UI Buttons: Clicking a collapse button completely hides the associated panel, maximizing space for the other panel. An expand button appears to restore the panel to its previous size.
  • Keyboard Shortcuts: Users can press Ctrl + Arrow keys to quickly collapse or expand panels without leaving keyboard navigation.
  • Single Panel Constraint: Only one panel 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 panel 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 panels:

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

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

Configuring orientation and sizes

<igc-splitter orientation="vertical" start-size="300px">
  <div slot="start">Top panel (300px)</div>
  <div slot="end">Bottom panel (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 panel</div>
  <div slot="end">Other panel</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>

<!-- Custom icons via slots -->
<igc-splitter>
  <div slot="start">Panel 1</div>
  <div slot="end">Panel 2</div>
  <igc-icon slot="drag-handle" name="drag_indicator"></igc-icon>
  <igc-icon slot="start-collapse" name="chevron_left"></igc-icon>
  <igc-icon slot="start-expand" name="chevron_right"></igc-icon>
</igc-splitter>

Programmatic control

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

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

// 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 panel 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 panel -->
    <div slot="end">
      <h3>Console Output</h3>
      <pre>Log messages...</pre>
    </div>
  </igc-splitter>
</igc-splitter>

This creates a three-panel layout: a fixed sidebar on the left, main content on top-right, and a console panel 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 panel size by 10px (increases end panel).
Arrow Down In vertical orientation, increases the start panel size by 10px (decreases end panel).
Arrow Left In horizontal orientation, decreases the start panel size by 10px (increases end panel).
Arrow Right In horizontal orientation, increases the start panel size by 10px (decreases end panel).
Ctrl + Arrow Up In vertical orientation, collapses/expands the start panel (if collapse is enabled).
Ctrl + Arrow Down In vertical orientation, collapses/expands the end panel (if collapse is enabled).
Ctrl + Arrow Left In horizontal orientation, collapses/expands the start panel (if collapse is enabled).
Ctrl + Arrow Right In horizontal orientation, collapses/expands the end panel (if collapse is enabled).
Home Resizes to the minimum size of the start panel.
End Resizes to the maximum size of the start panel.

API

Properties and attributes

Property Attribute Reflected Type Default Description
orientation orientation Yes horizontal | vertical horizontal Orientation layout for the splitter panels.
disableCollapse disable-collapse Yes boolean false Wether the user can collapse the panels of the splitter.
disableResize disable-resize Yes boolean false Wether the user can resize the panels 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 panel.
endSize end-size No string | undefined - The initial display size of the end panel.
startMinSize start-min-size No string | undefined - The minimum display size for the start panel.
startMaxSize start-max-size No string | undefined - The maximum display size for the start panel.
endMinSize end-min-size No string | undefined - The minimum display size for the end panel.
endMaxSize end-max-size No string | undefined - The maximum display size for the end panel.

Methods

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

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 panel in pixels */
  startPanelSize: number;
  /** The current size of the end panel 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 panel ot the the splitter. In horizontal layout this is the leftmost panel and in vertical layout it is the topmost.
end The end panel of the splitter. In horizontal layout this is the rightmost panel and in vertical layout it is the bottom one.
drag-handle Optional slot to customize the drag handle icon/content on the splitter bar.
start-expand Optional slot to customize the icon for expanding the start panel.
start-collapse Optional slot to customize the icon for collapsing the start panel.
end-expand Optional slot to customize the icon for expanding the end panel.
end-collapse Optional slot to customize the icon for collapsing the end panel.

CSS Shadow parts

Note

This is a subject to change.

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

Test scenarios

Rendering and Initialization

  1. Default rendering

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

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

    • Setting startSize initializes the start panel to the specified size
    • Setting endSize initializes the end panel 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 panel fills remaining space

Resize Functionality

  1. Mouse/pointer resize

    • Dragging the splitter bar resizes both panels
    • 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 panel collapses it
    • Clicking collapse button on end panel collapses it
    • Expand button appears when panel is collapsed
    • Clicking expand button restores the panel to previous size
    • Only one panel can be collapsed at a time
  2. Collapse/expand via API

    • toggle('start') toggles the collapsed state of start panel
    • toggle('end') toggles the collapsed state of end panel
    • 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 panels 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 panels
    • Correct combinations work based on orientation
    • Works only when collapse is enabled
  4. Home/End keys

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

Nested Splitters

  1. Nesting behavior
    • Splitter can be nested inside another splitter's panel
    • 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 panel
    • Content slotted into end renders in end panel
    • Content updates when slot content changes
    • Complex content (forms, tables, etc.) renders correctly
  2. Custom icons

    • Custom drag handle via drag-handle slot
    • Custom expand icons via start-expand and end-expand slots
    • Custom collapse icons via start-collapse and end-collapse slots
    • Default icons used when slots are empty

Size Constraints

  1. Min/max constraints

    • Panels respect startMinSize during resize
    • Panels respect startMaxSize during resize
    • Panels respect endMinSize during resize
    • Panels 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 panels 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
    • Collapse buttons have appropriate aria-label
  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.

Clone this wiki locally