Splitter - IgniteUI/igniteui-webcomponents GitHub Wiki
- Splitter component specification
Team name: Astrea
Developer name: Bozhidara Pachilova, Monika Kirkova
Designer name: TBD
- Radoslav Karaivanov
- Svilen Dimchevski
- Damyan Petev
- Radoslav Mirchev
| 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 |
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
- 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
- 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).
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.
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.
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.
The igc-splitter component is designed for ease of integration with a declarative API and flexible configuration options.
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.
<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><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><!-- 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><!-- 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));
});<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.
// 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);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.
| 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. |
| 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. |
| Name | Type signature | Description |
|---|---|---|
| toggle | (pane: 'start' | 'end'): void |
Toggles the collapsed state of the given pane. |
| 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;
}| 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. |
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. |
-
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)
-
Orientation
- Setting
orientation="horizontal"renders panes side by side - Setting
orientation="vertical"renders panes stacked vertically - Changing orientation dynamically updates the layout
- Setting
-
Initial sizing
- Setting
startSizeinitializes the start pane to the specified size - Setting
endSizeinitializes 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
- Setting
-
Mouse/pointer resize
- Dragging the splitter bar resizes both panes
- Resize is constrained by
startMinSizeandstartMaxSize - Resize is constrained by
endMinSizeandendMaxSize - Cursor changes appropriately on hover (e.g., col-resize, row-resize)
- Resize works correctly in both orientations
-
Resize events
-
igcResizeStartfires when drag begins -
igcResizingfires during drag operation -
igcResizeEndfires when drag completes - Event detail contains correct
startPanelSizeandendPanelSize - Event detail contains correct
deltaforigcResizingandigcResizeEnd
-
-
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
- Setting
-
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
-
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
-
-
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)
- Setting
-
Hide drag handle
- Setting
hideDragHandle="true"hides the drag handle icon - Splitter bar is still interactive for resizing
- Splitter bar is still focusable
- Setting
-
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
- Setting
-
Focus management
- Splitter bar is focusable with
Tabkey (when interactive) - Splitter bar has visible focus indicator
- Focus is not lost during resize or collapse operations
- Splitter bar is focusable with
-
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
-
Keyboard collapse/expand
-
Ctrl + Arrowcombinations collapse/expand panes - Correct combinations work based on orientation
- Works only when collapse is enabled
-
-
Home/End keys
-
Homekey resizes to start pane minimum size -
Endkey resizes to start pane maximum size - Keys work correctly in both orientations
-
-
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
-
Content slots
- Content slotted into
startrenders in start pane - Content slotted into
endrenders in end pane - Content updates when slot content changes
- Complex content (forms, tables, etc.) renders correctly
- Content slotted into
-
Min/max constraints
- panes respect
startMinSizeduring resize - panes respect
startMaxSizeduring resize - panes respect
endMinSizeduring resize - panes respect
endMaxSizeduring resize - Invalid constraint values are handled gracefully
- Constraints work with different CSS units
- panes respect
-
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
-
ARIA attributes
- Splitter bar has
role="separator" -
aria-orientationmatches component orientation -
tabindex="0"when interactive,-1when not -
aria-valuenow,aria-valuemin,aria-valuemaxare set appropriately
- Splitter bar has
-
Screen reader support
- Screen readers announce splitter bar correctly
- Resize operations are announced
- Collapse/expand state changes are announced
-
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
-
Container resizing
- Component adapts when container size changes
- Relative sizes (percentages) update correctly
- Absolute sizes are maintained when possible
-
Rapid interactions
- Rapid resize operations don't cause visual glitches
- Rapid collapse/expand toggles are handled correctly
- Event throttling/debouncing works as expected
-
Invalid configurations
- Invalid size values are handled gracefully
- Invalid orientation values fall back to default
- Missing slot content doesn't break rendering
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.
Already covered by the relevant section of the specification.
The splitter element should work in Right-to-Left context without additional setup or configuration.