
Syncfusion React Splitter
- 387 installs
- 3 repo stars
- Updated July 28, 2026
- syncfusion/react-ui-components-skills
Use syncfusion-react-splitter for development tasks
About
syncfusion-react-splitter: A skill for development. This provides functionality for development workflows.
- syncfusion-react-splitter
Syncfusion React Splitter by the numbers
- 387 all-time installs (skills.sh)
- +52 installs in the week ending Aug 5, 2026 (Skillselion tracking)
- Ranked #1,118 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/syncfusion/react-ui-components-skills --skill syncfusion-react-splitterAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 387 |
|---|---|
| repo stars | ★ 3 |
| Last updated | July 28, 2026 |
| Repository | syncfusion/react-ui-components-skills ↗ |
What it does
Use syncfusion-react-splitter for development tasks
Files
Implementing Syncfusion React Splitter
The Splitter component creates flexible, resizable panel layouts with advanced configuration options. This skill guides you through installation, layout patterns, customization, and accessibility features.
When to Use This Skill
Use the Splitter component when you need to:
- Create flexible layouts with multiple resizable panels
- Build split-screen interfaces (code editors, dashboards, file explorers)
- Allow users to adjust pane sizes dynamically
- Display collapsible panes with expand/collapse functionality
- Support different layout orientations (horizontal, vertical, nested)
- Implement responsive multi-panel layouts
- Add custom content types (HTML, components, selectors) to panes
Component Overview
SplitterComponent provides a container for multiple panes that users can resize by dragging separators. Each pane is defined with <PaneDirective> within <PanesDirective>.
Key Features:
- Multiple layout orientations (horizontal, vertical, nested)
- Dynamic pane resizing with constraints
- Expand/collapse pane functionality
- Multiple content types (HTML, components, CSS selectors)
- Events for resize, expand, collapse operations
- Add/remove panes dynamically at runtime
- Accessibility and RTL support
- Theme customization
Installation: npm install @syncfusion/ej2-react-layouts --save
Documentation and Navigation Guide
Getting Started
📄 Read: references/getting-started.md
- Installation and package setup
- CSS imports and theme configuration
- Basic Splitter initialization with PanesDirective
- First working example
- Import statements and dependencies
API Reference: Properties and Configuration
📄 Read: references/properties-and-configuration.md
- Complete SplitterComponent properties (orientation, height, width, separatorSize, etc.)
- All PaneDirective properties (size, min, max, collapsed, collapsible, resizable, content, cssClass)
- enablePersistence for state persistence
- enableHtmlSanitizer for security
- Common configuration patterns and examples
API Reference: Methods
📄 Read: references/methods-reference.md
- addPane() - Dynamically add new panes with PanePropertiesModel
- removePane() - Remove panes by index
- collapse() - Programmatically collapse panes
- expand() - Programmatically expand panes
- destroy() - Component cleanup and resource release
- Real-world examples with working code
API Reference: Events
📄 Read: references/events-reference.md
- created - Component initialization
- beforeCollapse / collapsed - Collapse events with cancellation
- beforeExpand / expanded - Expand events with data loading
- resizeStart / resizing / resizeStop - Resize lifecycle
- Event handling patterns and state management
Pane Layout Configuration
📄 Read: references/pane-layout-configuration.md
- Horizontal and vertical layouts
- Multiple panes and nested splitters
- Pane properties and configuration
- Layout patterns for common use cases
Pane Sizing and Separation
📄 Read: references/pane-sizing-and-separation.md
- Fixed pane sizing
- Percentage-based sizing
- Min and max size constraints
- Separator styling and customization
- Dynamic size adjustments
Expand and Collapse Functionality
📄 Read: references/expand-collapse-functionality.md
- Collapsed state initialization
- Button integration for expand/collapse
- User-driven vs programmatic collapse
- Event handling patterns
Resize Behavior
📄 Read: references/resize-behavior.md
- Resize events and lifecycle
- Preventing resize on specific panes
- Dynamic resize configuration
- Resize constraints and validation
- Event data and handling
Pane Content and Styling
📄 Read: references/pane-content-and-styling.md
- HTML content in panes
- React component content in panes
- CSS selector-based content
- Pane template usage
- Custom styling and classes
Accessibility and Globalization
📄 Read: references/accessibility-and-globalization.md
- WCAG compliance and keyboard navigation
- ARIA attributes and screen reader support
- RTL (Right-to-Left) support
- Internationalization and locale
- Focus management and accessibility patterns
Style Customization
📄 Read: references/style-customization.md
- CSS customization and custom classes
- Theme variables and CSS imports
- Gripper and separator styling
- Responsive design patterns
- Dark mode and theme switching
Quick Start Example
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from "react";
import './App.css';
function App() {
return (
<div className='App'>
<SplitterComponent>
<PanesDirective>
<PaneDirective size='200px'>
<div>Left Panel</div>
</PaneDirective>
<PaneDirective size='300px'>
<div>Right Panel</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
</div>
);
}
export default App;Common Patterns
Two-Column Layout
<SplitterComponent orientation='Horizontal'>
<PanesDirective>
<PaneDirective size='25%'><div>Left</div></PaneDirective>
<PaneDirective size='75%'><div>Main Content</div></PaneDirective>
</PanesDirective>
</SplitterComponent>Vertical Split with Collapse
<SplitterComponent orientation='Vertical'>
<PanesDirective>
<PaneDirective size='50%' collapsed={true}><div>Top</div></PaneDirective>
<PaneDirective size='50%'><div>Bottom</div></PaneDirective>
</PanesDirective>
</SplitterComponent>Three-Panel Dashboard
<SplitterComponent orientation='Horizontal'>
<PanesDirective>
<PaneDirective size='20%'><div>Sidebar</div></PaneDirective>
<PaneDirective size='60%'><div>Main Content</div></PaneDirective>
<PaneDirective size='20%'><div>Right Panel</div></PaneDirective>
</PanesDirective>
</SplitterComponent>Nested Splitters
Combine horizontal and vertical splitters for complex layouts like code editors with file explorer, editor, and console panels.
Key Props
| Prop | Type | Description | When to Use |
|---|---|---|---|
orientation | 'Horizontal' \ | 'Vertical' | Layout direction |
size | string (PaneDirective) | Pane width/height (px, %) | When setting pane dimensions |
min | string (PaneDirective) | Minimum pane size | When preventing pane from shrinking too small |
max | string (PaneDirective) | Maximum pane size | When limiting pane expansion |
collapsed | boolean (PaneDirective) | Initial collapsed state | When panes should start hidden |
collapsible | boolean (PaneDirective) | Allow user to collapse | When collapsing should be user-driven |
resizable | boolean (PaneDirective) | Allow user to resize | When preventing manual resizing |
Common Use Cases
File Explorer + Editor: Left sidebar (fixed 250px) with collapsible file tree, main editor area with resizing
Dashboard: Top bar (fixed height), left sidebar (collapsible nav), main content, right details panel
Chat Interface: Left contact list (fixed width), chat area (resizable), right info panel
Code Editor: Left explorer (collapsible), center editor (main), bottom console (collapsible)
Email Client: Left folders (fixed), center list (resizable), right preview (resizable)
Accessibility and Globalization
Table of Contents
- WCAG Compliance
- Keyboard Navigation
- ARIA Attributes
- Screen Reader Support
- RTL Support
- Internationalization
- Focus Management
WCAG Compliance
The Splitter component follows WCAG 2.1 Level AA guidelines for accessibility.
Guidelines Met
Perceivable:
- Sufficient color contrast (text vs background)
- Non-color-dependent indicators (icons, text labels)
- Resizable text and components
Operable:
- Keyboard accessible (no mouse required)
- Adjustable timing (no time limits)
- Seizure prevention (no flashing)
Understandable:
- Clear navigation patterns
- Consistent component behavior
- Error prevention and recovery
Robust:
- Valid HTML structure
- ARIA attributes
- Assistive technology compatibility
Accessibility Properties
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from 'react';
function WCAGCompliantSplitter() {
return (
<div role='main' aria-label='Main Content Area'>
<SplitterComponent
orientation='Horizontal'
style={{ height: '400px' }}
aria-label='Two-panel layout splitter'
>
<PanesDirective>
<PaneDirective
size='250px'
aria-label='Navigation sidebar'
>
<nav style={{ padding: '20px' }}>
<h2>Navigation</h2>
<ul role='navigation'>
<li><a href='#home'>Home</a></li>
<li><a href='#about'>About</a></li>
<li><a href='#contact'>Contact</a></li>
</ul>
</nav>
</PaneDirective>
<PaneDirective
size='300px'
aria-label='Main content area'
>
<article style={{ padding: '20px' }}>
<h2>Content</h2>
<p>Main article content here</p>
</article>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
</div>
);
}
export default WCAGCompliantSplitter;Keyboard Navigation
Users can navigate and operate the splitter without a mouse.
Keyboard Shortcuts
| Key | Action | Notes |
|---|---|---|
Tab | Move focus to splitter | Focuses separator bar |
Enter / Space | Toggle collapse (if collapsible) | When separator focused |
Arrow Left | Decrease left pane, increase right | In horizontal layout |
Arrow Right | Increase left pane, decrease right | In horizontal layout |
Arrow Up | Decrease top pane, increase bottom | In vertical layout |
Arrow Down | Increase top pane, decrease bottom | In vertical layout |
Example: Full Keyboard Navigation
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from 'react';
function KeyboardNavigableSplitter() {
const splitterRef = React.useRef<SplitterComponent>(null);
const handleKeyDown = (event: React.KeyboardEvent) => {
if (!splitterRef.current) return;
// Get current sizes
const panes = splitterRef.current.panes;
if (!panes || panes.length < 2) return;
const leftSize = parseInt(panes[0].size || '0');
const rightSize = parseInt(panes[1].size || '0');
const step = 20; // Pixel increment
switch(event.key) {
case 'ArrowLeft':
event.preventDefault();
panes[0].size = `${Math.max(100, leftSize - step)}px`;
panes[1].size = `${rightSize + step}px`;
splitterRef.current.refresh();
break;
case 'ArrowRight':
event.preventDefault();
panes[0].size = `${leftSize + step}px`;
panes[1].size = `${Math.max(100, rightSize - step)}px`;
splitterRef.current.refresh();
break;
}
};
return (
<div onKeyDown={handleKeyDown} tabIndex={0}>
<p><em>Tab to focus, then use Arrow keys to resize</em></p>
<SplitterComponent
ref={splitterRef}
orientation='Horizontal'
style={{ height: '300px' }}
>
<PanesDirective>
<PaneDirective size='200px'>
<div style={{ padding: '20px' }}>
<h3>Left Panel</h3>
</div>
</PaneDirective>
<PaneDirective size='300px'>
<div style={{ padding: '20px' }}>
<h3>Right Panel</h3>
</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
</div>
);
}
export default KeyboardNavigableSplitter;ARIA Attributes
Use ARIA attributes to provide semantic meaning for assistive technologies.
Important ARIA Attributes
<SplitterComponent
aria-label='Main layout splitter'
aria-orientation='horizontal'
role='separator'
>
<PanesDirective>
<PaneDirective
size='250px'
aria-label='Left navigation pane'
aria-expanded={!isCollapsed}
>
{/* Content */}
</PaneDirective>
<PaneDirective
size='300px'
aria-label='Main content pane'
aria-live='polite'
>
{/* Content */}
</PaneDirective>
</PanesDirective>
</SplitterComponent>ARIA Property Descriptions
| Attribute | Value | Purpose |
|---|---|---|
aria-label | string | Human-readable label |
aria-orientation | horizontal/vertical | Layout direction |
role | separator | Component type |
aria-expanded | true/false | Pane collapsed state |
aria-live | polite/assertive | Content changes announcement |
aria-controls | id | Controls relationship |
Screen Reader Support
Ensure content is announced properly to screen reader users.
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from 'react';
function ScreenReaderFriendly() {
const [expandedPane, setExpandedPane] = React.useState<number | null>(null);
const handleBeforeCollapse = (args: any) => {
setExpandedPane(args.paneIndex);
};
return (
<div>
<h1>Document with Accessible Splitter</h1>
<SplitterComponent
orientation='Horizontal'
style={{ height: '400px' }}
beforeCollapse={handleBeforeCollapse}
>
<PanesDirective>
<PaneDirective
size='250px'
collapsible={true}
aria-label='Navigation Panel'
role='navigation'
>
<nav>
<h2>Navigation</h2>
<ul>
<li><a href='#section1'>Section 1</a></li>
<li><a href='#section2'>Section 2</a></li>
</ul>
</nav>
</PaneDirective>
<PaneDirective
size='300px'
aria-label='Main Content'
role='main'
aria-live='polite'
>
<main>
<h2>Main Content</h2>
<p>Content updated dynamically</p>
{expandedPane !== null && (
<p>Panel {expandedPane} was collapsed</p>
)}
</main>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
</div>
);
}
export default ScreenReaderFriendly;Best Practices
1. Use semantic HTML - <nav>, <main>, <article>, <aside> 2. Provide clear labels - Use aria-label for non-obvious components 3. Announce changes - Use aria-live for dynamic updates 4. Maintain headings hierarchy - H1 → H2 → H3 structure 5. Link related items - Use aria-controls for associations
RTL Support
Enable Right-to-Left language support for Arabic, Hebrew, and other RTL languages.
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from 'react';
function RTLSplitter() {
const [isRTL, setIsRTL] = React.useState(false);
return (
<div style={{ direction: isRTL ? 'rtl' : 'ltr' }}>
<button onClick={() => setIsRTL(!isRTL)}>
Toggle RTL: {isRTL ? 'Arabic' : 'English'}
</button>
<SplitterComponent
orientation='Horizontal'
style={{ height: '400px', marginTop: '20px' }}
enableRtl={isRTL}
>
<PanesDirective>
<PaneDirective size='250px'>
<div style={{ padding: '20px' }}>
<h3>{isRTL ? 'الشريط الجانبي' : 'Sidebar'}</h3>
<p>{isRTL ? 'محتوى اللغة العربية' : 'English content'}</p>
</div>
</PaneDirective>
<PaneDirective size='300px'>
<div style={{ padding: '20px' }}>
<h3>{isRTL ? 'المحتوى الرئيسي' : 'Main Content'}</h3>
<p>{isRTL ? 'يتم عرض هذا النص من اليمين إلى اليسار' : 'Text flows left to right'}</p>
</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
</div>
);
}
export default RTLSplitter;RTL Features
- Separator position automatically adjusted
- Text alignment reversed
- Icon mirroring (if applicable)
- Navigation direction reversed
- Collapse/expand icons mirrored
Internationalization
Support multiple languages in the splitter interface.
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from 'react';
const translations = {
en: {
sidebar: 'Navigation',
content: 'Main Content',
placeholder: 'Select an item'
},
es: {
sidebar: 'Navegación',
content: 'Contenido Principal',
placeholder: 'Selecciona un elemento'
},
fr: {
sidebar: 'Navigation',
content: 'Contenu Principal',
placeholder: 'Sélectionnez un élément'
}
};
function InternationalizedSplitter() {
const [lang, setLang] = React.useState('en');
const t = translations[lang as keyof typeof translations];
return (
<div>
<select value={lang} onChange={(e) => setLang(e.target.value)}>
<option value='en'>English</option>
<option value='es'>Español</option>
<option value='fr'>Français</option>
</select>
<SplitterComponent
orientation='Horizontal'
style={{ height: '400px', marginTop: '10px' }}
lang={lang}
>
<PanesDirective>
<PaneDirective size='250px'>
<div style={{ padding: '20px' }}>
<h3>{t.sidebar}</h3>
<p>{t.placeholder}</p>
</div>
</PaneDirective>
<PaneDirective size='300px'>
<div style={{ padding: '20px' }}>
<h3>{t.content}</h3>
</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
</div>
);
}
export default InternationalizedSplitter;Focus Management
Properly manage focus for keyboard navigation.
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from 'react';
function FocusManagement() {
const splitterRef = React.useRef<SplitterComponent>(null);
const sidebarRef = React.useRef<HTMLDivElement>(null);
const contentRef = React.useRef<HTMLDivElement>(null);
const handleFocusNext = () => {
contentRef.current?.focus();
};
const handleFocusPrev = () => {
sidebarRef.current?.focus();
};
return (
<SplitterComponent
ref={splitterRef}
orientation='Horizontal'
style={{ height: '400px' }}
>
<PanesDirective>
<PaneDirective size='250px'>
<div
ref={sidebarRef}
tabIndex={0}
style={{ padding: '20px', outline: 'none' }}
onKeyDown={(e) => {
if (e.key === 'Tab' && !e.shiftKey) {
e.preventDefault();
handleFocusNext();
}
}}
>
<h3>Sidebar</h3>
<p>Focused element</p>
</div>
</PaneDirective>
<PaneDirective size='300px'>
<div
ref={contentRef}
tabIndex={0}
style={{ padding: '20px', outline: 'none' }}
onKeyDown={(e) => {
if (e.key === 'Tab' && e.shiftKey) {
e.preventDefault();
handleFocusPrev();
}
}}
>
<h3>Content</h3>
<p>Tab navigation</p>
</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
);
}
export default FocusManagement;Focus Best Practices
1. Maintain logical tab order - Use tabIndex appropriately 2. Show focus indicators - Visible outline or highlight 3. Skip links - Allow jumping to main content 4. Focus trapping - Keep focus within modal splitters 5. Restore focus - Return focus after collapsing panes
Checklist for Accessible Splitter
- [ ] ARIA labels provided for all panes
- [ ] Keyboard navigation fully functional
- [ ] Color contrast meets WCAG AA
- [ ] Screen reader tested
- [ ] RTL support enabled
- [ ] Focus management implemented
- [ ] Error messages clear and accessible
- [ ] Sufficient target size (44x44px minimum)
- [ ] Tested with assistive technologies
Splitter Events Reference
Table of Contents
- created
- beforeCollapse
- collapsed
- beforeExpand
- expanded
- resizeStart
- resizing
- resizeStop
- beforeSanitizeHtml
- Event Handling Patterns
---
created
Event: created
Description: Fires when the Splitter component is created and initialized. Useful for performing initialization tasks after the component is ready.
Event Arguments: CreateEventArgs
Properties:
element(HTMLElement): The Splitter DOM elementname(string): The name of the event
Example:
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from "react";
function App() {
const onCreated = (args: any) => {
console.log('Splitter created successfully', args.element);
};
return (
<SplitterComponent
height="250px"
width="600px"
created={onCreated}
>
<PanesDirective>
<PaneDirective size='200px'>
<div>Pane 1</div>
</PaneDirective>
<PaneDirective size='200px'>
<div>Pane 2</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
);
}
export default App;When to Use:
- Initialize third-party libraries within panes
- Set up event listeners on pane content
- Perform calculations based on pane dimensions
- Apply initial styling or animations
Common Patterns:
const handleCreated = (args: any) => {
// Access pane dimensions
console.log('Total splitter height:', args.element.offsetHeight);
// Set up content after initialization
const panes = args.element.querySelectorAll('.e-pane');
panes.forEach((pane: HTMLElement) => {
pane.classList.add('initialized');
});
};---
beforeCollapse
Event: beforeCollapse
Description: Fires before a pane is collapsed. You can cancel the collapse operation by setting cancel: true in the event args.
Event Arguments: BeforeCollapseEventArgs
Properties:
index(number): Index of the pane being collapsedelement(HTMLElement): The Splitter elementcancel(boolean): Set to true to prevent collapse
Example - Allow/Prevent Collapse:
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from "react";
function App() {
const onBeforeCollapse = (args: any) => {
// Prevent collapsing pane at index 0
if (args.index === 0) {
args.cancel = true;
console.log('Cannot collapse the first pane');
} else {
console.log(`Collapsing pane at index: ${args.index}`);
}
};
return (
<SplitterComponent
height="300px"
width="600px"
beforeCollapse={onBeforeCollapse}
>
<PanesDirective>
<PaneDirective size='200px' collapsible={true}>
<div>Primary pane (cannot collapse)</div>
</PaneDirective>
<PaneDirective size='200px' collapsible={true}>
<div>Secondary pane (can collapse)</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
);
}
export default App;When to Use:
- Validate data before hiding panes
- Prevent collapse of critical sections
- Show confirmation dialogs before collapse
- Log user interactions for analytics
---
collapsed
Event: collapsed
Description: Fires after a pane is successfully collapsed. Use this event for post-collapse actions.
Event Arguments: CollapsedEventArgs
Properties:
index(number): Index of the collapsed paneelement(HTMLElement): The Splitter element
Example - Update State After Collapse:
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from "react";
function App() {
const [collapsedPanes, setCollapsedPanes] = React.useState<number[]>([]);
const onCollapsed = (args: any) => {
setCollapsedPanes((prev) => [...prev, args.index]);
console.log(`Pane ${args.index} collapsed`);
console.log('All collapsed panes:', [...collapsedPanes, args.index]);
};
return (
<div>
<div>Collapsed panes: {collapsedPanes.join(', ')}</div>
<SplitterComponent
height="300px"
width="600px"
collapsed={onCollapsed}
>
<PanesDirective>
<PaneDirective size='200px' collapsible={true}>
<div>Pane 1</div>
</PaneDirective>
<PaneDirective size='200px' collapsible={true}>
<div>Pane 2</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
</div>
);
}
export default App;When to Use:
- Update UI state after pane collapse
- Trigger dependent actions
- Log analytics events
- Refresh content in remaining panes
---
beforeExpand
Event: beforeExpand
Description: Fires before a pane is expanded. You can cancel the expand operation by setting cancel: true in the event args.
Event Arguments: BeforeExpandEventArgs
Properties:
index(number): Index of the pane being expandedelement(HTMLElement): The Splitter elementcancel(boolean): Set to true to prevent expand
Example - Confirm Expansion:
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from "react";
function App() {
const onBeforeExpand = (args: any) => {
// Show confirmation or validate state before expanding
console.log(`Attempting to expand pane ${args.index}`);
// Example: Only expand if valid state
const isValidState = true; // Your validation logic
if (!isValidState) {
args.cancel = true;
console.log('Cannot expand: Invalid state');
}
};
return (
<SplitterComponent
height="300px"
width="600px"
beforeExpand={onBeforeExpand}
>
<PanesDirective>
<PaneDirective size='200px' collapsed={true} collapsible={true}>
<div>Collapsible pane</div>
</PaneDirective>
<PaneDirective size='200px'>
<div>Content pane</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
);
}
export default App;When to Use:
- Load data before expanding
- Validate state before showing content
- Prevent expansion under certain conditions
- Require confirmation from user
---
expanded
Event: expanded
Description: Fires after a pane is successfully expanded. Use for post-expansion actions and content updates.
Event Arguments: ExpandedEventArgs
Properties:
index(number): Index of the expanded paneelement(HTMLElement): The Splitter element
Example - Load Content on Expand:
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from "react";
function App() {
const [expandedPanes, setExpandedPanes] = React.useState<number[]>([]);
const onExpanded = (args: any) => {
// Load content for expanded pane
const paneElement = args.element.querySelectorAll('.e-pane')[args.index];
console.log(`Pane ${args.index} expanded`);
setExpandedPanes((prev) => [...prev, args.index]);
// Trigger content loading
loadPaneContent(args.index);
};
const loadPaneContent = (index: number) => {
console.log(`Loading content for pane ${index}...`);
// Fetch or render content
};
return (
<SplitterComponent
height="300px"
width="600px"
expanded={onExpanded}
>
<PanesDirective>
<PaneDirective size='200px' collapsed={true} collapsible={true}>
<div>Lazy-loaded pane</div>
</PaneDirective>
<PaneDirective size='200px'>
<div>Content pane</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
);
}
export default App;When to Use:
- Load pane content on-demand
- Update UI state after expansion
- Refresh pane data
- Trigger dependent UI updates
---
resizeStart
Event: resizeStart
Description: Fires when the user starts dragging the separator to resize panes. Use to prepare for resize operations.
Event Arguments: ResizeEventArgs
Properties:
index(number): Index of the pane being resizedelement(HTMLElement): The Splitter elementprevious(number): Previous pane sizecurrent(number): Current pane size
Example - Show Resize Indicator:
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from "react";
function App() {
const [isResizing, setIsResizing] = React.useState(false);
const onResizeStart = (args: any) => {
setIsResizing(true);
console.log(`Resize started for pane ${args.index}`);
console.log(`Previous size: ${args.previous}px`);
};
return (
<div>
{isResizing && <div className="resize-indicator">Resizing...</div>}
<SplitterComponent
height="300px"
width="600px"
resizeStart={onResizeStart}
>
<PanesDirective>
<PaneDirective size='200px'>
<div>Pane 1</div>
</PaneDirective>
<PaneDirective size='200px'>
<div>Pane 2</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
</div>
);
}
export default App;When to Use:
- Show resize handles or indicators
- Disable other interactions during resize
- Log analytics for resize events
- Freeze content updates during drag
---
resizing
Event: resizing
Description: Fires continuously while the user is dragging the separator. Useful for real-time feedback during resize operations.
Event Arguments: ResizingEventArgs
Properties:
index(number): Index of the pane being resizedelement(HTMLElement): The Splitter elementprevious(number): Previous pane sizecurrent(number): Current pane size (changes as user drags)cancel(boolean): Set to true to cancel the resize
Example - Prevent Resize Below Minimum:
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from "react";
function App() {
const [sizes, setSizes] = React.useState({ pane1: 200, pane2: 200 });
const onResizing = (args: any) => {
setSizes({ pane1: args.previous, pane2: args.current });
// Custom validation: prevent pane from going below 100px
if (args.current < 100) {
args.cancel = true;
console.log('Resize cancelled: Below minimum size');
}
};
return (
<div>
<div>Pane 1: {sizes.pane1}px | Pane 2: {sizes.pane2}px</div>
<SplitterComponent
height="300px"
width="600px"
resizing={onResizing}
>
<PanesDirective>
<PaneDirective size='200px' min='100px'>
<div>Pane 1</div>
</PaneDirective>
<PaneDirective size='200px' min='100px'>
<div>Pane 2</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
</div>
);
}
export default App;When to Use:
- Display real-time size feedback
- Validate resize operations
- Update dependent layouts
- Prevent invalid resize operations
---
resizeStop
Event: resizeStop
Description: Fires when the user finishes dragging the separator and releases the mouse. Use for post-resize actions.
Event Arguments: ResizeEventArgs
Properties:
index(number): Index of the pane that was resizedelement(HTMLElement): The Splitter elementprevious(number): Previous pane sizecurrent(number): Final pane size after resize
Example - Save Resize State:
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from "react";
function App() {
const [isResizing, setIsResizing] = React.useState(false);
const onResizeStop = (args: any) => {
setIsResizing(false);
console.log(`Resize completed for pane ${args.index}`);
console.log(`Final size: ${args.current}px (was ${args.previous}px)`);
// Save layout preferences
savePaneSize(args.index, args.current);
};
const savePaneSize = (index: number, size: number) => {
const sizes = JSON.parse(localStorage.getItem('pane-sizes') || '{}');
sizes[`pane-${index}`] = size;
localStorage.setItem('pane-sizes', JSON.stringify(sizes));
console.log('Layout saved to localStorage');
};
return (
<SplitterComponent
height="300px"
width="600px"
resizeStart={() => setIsResizing(true)}
resizeStop={onResizeStop}
>
<PanesDirective>
<PaneDirective size='200px'>
<div>Pane 1</div>
</PaneDirective>
<PaneDirective size='200px'>
<div>Pane 2</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
);
}
export default App;When to Use:
- Save user layout preferences
- Remove resize indicators
- Refresh dependent components
- Perform heavy calculations after resize completes
- Persist state to local storage or database
---
beforeSanitizeHtml
Event: beforeSanitizeHtml
Description: Fires before HTML content is sanitized. This event allows you to customize the sanitization process by modifying attributes or elements that should be removed or preserved. Use this event to whitelist specific HTML elements or attributes that should bypass sanitization.
Event Arguments: BeforeSanitizeHtmlArgs
Properties:
value(string): The HTML content to be sanitizedcancel(boolean): Set to true to prevent default sanitization
Example - Customize Sanitization Rules:
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from "react";
function App() {
const onBeforeSanitizeHtml = (args: any) => {
// Log content before sanitization
console.log('Content before sanitization:', args.value);
// Example: Allow specific data attributes
// The sanitizer will process the content according to your requirements
// You can analyze the content and modify if needed
};
return (
<SplitterComponent
height="300px"
width="600px"
enableHtmlSanitizer={true}
beforeSanitizeHtml={onBeforeSanitizeHtml}
>
<PanesDirective>
<PaneDirective content="<div data-id='123'>Content with data attribute</div>">
<div>Pane 1</div>
</PaneDirective>
<PaneDirective>
<div>Pane 2</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
);
}
export default App;Example - Monitor Sanitization Events:
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from "react";
function App() {
const [sanitizationLog, setSanitizationLog] = React.useState<string[]>([]);
const onBeforeSanitizeHtml = (args: any) => {
const logEntry = `Sanitizing: ${args.value.substring(0, 50)}...`;
setSanitizationLog((prev) => [...prev, logEntry]);
console.log('Sanitization event fired:', args);
};
return (
<div>
<div className="log">
<h4>Sanitization Log:</h4>
<ul>
{sanitizationLog.map((entry, index) => (
<li key={index}>{entry}</li>
))}
</ul>
</div>
<SplitterComponent
height="300px"
width="600px"
enableHtmlSanitizer={true}
beforeSanitizeHtml={onBeforeSanitizeHtml}
>
<PanesDirective>
<PaneDirective content="<div><h3>Safe Content</h3></div>">
<div>Pane 1</div>
</PaneDirective>
<PaneDirective content="<p>Paragraph content</p>">
<div>Pane 2</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
</div>
);
}
export default App;When to Use:
- Monitor which HTML content is being sanitized
- Log sanitization events for debugging
- Implement custom sanitization logic
- Track user-provided content being processed
- Audit security-sensitive operations
Security Considerations:
- Always keep
enableHtmlSanitizer={true}unless you control all content sources - Use beforeSanitizeHtml only for monitoring or logging
- Do not disable sanitization in production for untrusted content
- XSS attacks can compromise your application - sanitization protects users
---
Event Handling Patterns
Pattern 1: Track All Pane State Changes
const [paneState, setPaneState] = React.useState({
collapsed: [false, false],
sizes: [200, 200]
});
const handleBeforeCollapse = (args: any) => {
if (args.index === 0) args.cancel = true;
};
const handleCollapsed = (args: any) => {
setPaneState({
...paneState,
collapsed: paneState.collapsed.map((c, i) => i === args.index ? true : c)
});
};
const handleExpanded = (args: any) => {
setPaneState({
...paneState,
collapsed: paneState.collapsed.map((c, i) => i === args.index ? false : c)
});
};
const handleResizeStop = (args: any) => {
setPaneState({
...paneState,
sizes: paneState.sizes.map((s, i) => i === args.index ? args.current : s)
});
};
return (
<SplitterComponent
beforeCollapse={handleBeforeCollapse}
collapsed={handleCollapsed}
expanded={handleExpanded}
resizeStop={handleResizeStop}
>
{/* Panes */}
</SplitterComponent>
);Pattern 2: Persist and Restore Layout
const STORAGE_KEY = 'splitter-layout';
const saveLayout = (state: any) => {
localStorage.setItem(STORAGE_KEY, JSON.stringify(state));
};
const restoreLayout = () => {
return JSON.parse(localStorage.getItem(STORAGE_KEY) || '{}');
};
const handleCollapsed = (args: any) => {
const state = restoreLayout();
state.collapsed = state.collapsed || [];
state.collapsed[args.index] = true;
saveLayout(state);
};
const handleResizeStop = (args: any) => {
const state = restoreLayout();
state.sizes = state.sizes || [];
state.sizes[args.index] = args.current;
saveLayout(state);
};Pattern 3: Lazy Load Pane Content
const [loadedPanes, setLoadedPanes] = React.useState<Set<number>>(new Set());
const loadPaneContent = async (index: number) => {
if (!loadedPanes.has(index)) {
const data = await fetch(`/api/pane/${index}`);
// Update pane content
setLoadedPanes(new Set([...loadedPanes, index]));
}
};
const handleExpanded = (args: any) => {
loadPaneContent(args.index);
};---
Event Quick Reference
| Event | Fires When | Key Properties | Use Case |
|---|---|---|---|
created | Component initialized | element, name | Initialize content |
beforeCollapse | Before pane collapse | index, cancel | Validate/prevent collapse |
collapsed | After pane collapse | index | Update UI state |
beforeExpand | Before pane expand | index, cancel | Validate/prevent expand |
expanded | After pane expand | index | Load content |
resizeStart | Drag separator starts | index, previous | Show indicators |
resizing | During drag (continuous) | index, current, cancel | Real-time feedback |
resizeStop | Drag separator ends | index, previous, current | Save layout |
beforeSanitizeHtml | Before HTML sanitization | value | Monitor/customize sanitization |
Expand and Collapse Functionality
Table of Contents
- Collapsed State Initialization
- Collapse and Expand Methods
- Expand and Collapse Events
- Button Integration
- Collapsible Configuration
Collapsed State Initialization
Set panes to collapsed (hidden) state on component load using the collapsed property.
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from 'react';
function CollapsedStateInitialization() {
return (
<SplitterComponent orientation='Horizontal' style={{ height: '400px' }}>
<PanesDirective>
{/* This pane is visible initially */}
<PaneDirective size='250px' collapsed={false}>
<div style={{ padding: '20px', backgroundColor: '#e3f2fd' }}>
<h3>Visible Pane</h3>
<p>This pane is expanded by default</p>
</div>
</PaneDirective>
{/* This pane is hidden initially */}
<PaneDirective size='250px' collapsed={true}>
<div style={{ padding: '20px', backgroundColor: '#f3e5f5' }}>
<h3>Hidden Pane</h3>
<p>This pane starts collapsed</p>
</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
);
}
export default CollapsedStateInitialization;Use Cases:
- Hide secondary panels on page load
- Show/hide sidebar by default based on user preference
- Collapsible detail panes in dashboards
- Save user preferences and restore on reload
Collapse and Expand Methods
Programmatically collapse or expand panes using public methods.
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from 'react';
function CollapseExpandMethods() {
const splitterRef = React.useRef<SplitterComponent>(null);
const collapsePane = (index: number) => {
if (splitterRef.current) {
splitterRef.current.collapse(index);
}
};
const expandPane = (index: number) => {
if (splitterRef.current) {
splitterRef.current.expand(index);
}
};
return (
<div>
<div style={{ marginBottom: '15px' }}>
<button onClick={() => collapsePane(0)}>Collapse Left Pane</button>
<button onClick={() => expandPane(0)}>Expand Left Pane</button>
<button onClick={() => collapsePane(1)}>Collapse Right Pane</button>
<button onClick={() => expandPane(1)}>Expand Right Pane</button>
</div>
<SplitterComponent
ref={splitterRef}
orientation='Horizontal'
style={{ height: '400px' }}
>
<PanesDirective>
<PaneDirective size='250px' collapsible={true}>
<div style={{ padding: '20px', backgroundColor: '#e8f5e9' }}>
<h3>Collapsible Pane 1</h3>
<p>Click buttons to collapse/expand</p>
</div>
</PaneDirective>
<PaneDirective size='300px' collapsible={true}>
<div style={{ padding: '20px', backgroundColor: '#fff3e0' }}>
<h3>Collapsible Pane 2</h3>
<p>Can be toggled independently</p>
</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
</div>
);
}
export default CollapseExpandMethods;Method Signatures
collapse(index: number): void
expand(index: number): voidParameters:
index- Zero-based pane index to collapse/expand
Example: Toggle Pane State
const togglePane = (index: number) => {
const pane = splitterRef.current?.panes?.[index];
if (pane?.collapsed) {
splitterRef.current?.expand(index);
} else {
splitterRef.current?.collapse(index);
}
};Expand and Collapse Events
React to collapse and expand actions using events.
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from 'react';
function ExpandCollapseEvents() {
const [eventLog, setEventLog] = React.useState<string[]>([]);
const handleBeforeExpand = (args: any) => {
console.log('Before Expand - Pane Index:', args.index);
setEventLog(prev => [...prev, `Before Expand: Pane ${args.index}`]);
};
const handleExpanded = (args: any) => {
console.log('Expanded - Pane Index:', args.index);
setEventLog(prev => [...prev, `Expanded: Pane ${args.index}`]);
};
const handleBeforeCollapse = (args: any) => {
console.log('Before Collapse - Pane Index:', args.index);
setEventLog(prev => [...prev, `Before Collapse: Pane ${args.index}`]);
};
const handleCollapsed = (args: any) => {
console.log('Collapsed - Pane Index:', args.index);
setEventLog(prev => [...prev, `Collapsed: Pane ${args.index}`]);
};
const clearLog = () => setEventLog([]);
return (
<div>
<div style={{ marginBottom: '10px' }}>
<button onClick={clearLog}>Clear Log</button>
</div>
<SplitterComponent
orientation='Horizontal'
style={{ height: '300px' }}
beforeExpand={handleBeforeExpand}
expanded={handleExpanded}
beforeCollapse={handleBeforeCollapse}
collapsed={handleCollapsed}
>
<PanesDirective>
<PaneDirective size='200px' collapsible={true}>
<div style={{ padding: '20px' }}>
<h3>Pane 1</h3>
<p>Collapse/Expand this pane</p>
</div>
</PaneDirective>
<PaneDirective size='200px' collapsible={true}>
<div style={{ padding: '20px' }}>
<h3>Pane 2</h3>
<p>Watch events in log</p>
</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
<div style={{ marginTop: '15px', padding: '10px', backgroundColor: '#f5f5f5', maxHeight: '150px', overflow: 'auto' }}>
<h4>Event Log:</h4>
{eventLog.map((log, idx) => (
<div key={idx}>{log}</div>
))}
</div>
</div>
);
}
export default ExpandCollapseEvents;Event Types
| Event | Trigger | Cancelable | Use Case |
|---|---|---|---|
beforeExpand | Before pane expands | Yes | Validate before expand, prevent expansion |
expanded | After pane expanded | No | Update UI, refresh content |
beforeCollapse | Before pane collapses | Yes | Save state, confirm action |
collapsed | After pane collapsed | No | Update related components |
Example: Prevent Collapse with Unsaved Changes
const handleBeforeCollapse = (args: any) => {
if (hasUnsavedChanges) {
args.cancel = true; // Prevent collapse
alert('Please save changes before collapsing');
}
};
<SplitterComponent beforeCollapse={handleBeforeCollapse}>
{/* panes */}
</SplitterComponent>Button Integration
Add buttons to trigger collapse/expand programmatically.
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from 'react';
function ButtonIntegration() {
const splitterRef = React.useRef<SplitterComponent>(null);
const [isSidebarCollapsed, setIsSidebarCollapsed] = React.useState(false);
const toggleSidebar = () => {
const sidebarPane = 0; // First pane is sidebar
if (isSidebarCollapsed) {
splitterRef.current?.expand(sidebarPane);
setIsSidebarCollapsed(false);
} else {
splitterRef.current?.collapse(sidebarPane);
setIsSidebarCollapsed(true);
}
};
return (
<div>
<div style={{ marginBottom: '10px', padding: '10px', backgroundColor: '#f0f0f0' }}>
<button
onClick={toggleSidebar}
style={{
padding: '8px 16px',
backgroundColor: '#007bff',
color: 'white',
border: 'none',
borderRadius: '4px',
cursor: 'pointer'
}}
>
{isSidebarCollapsed ? '☰ Show' : '✕ Hide'} Sidebar
</button>
</div>
<SplitterComponent
ref={splitterRef}
orientation='Horizontal'
style={{ height: '400px' }}
>
<PanesDirective>
<PaneDirective size='250px' collapsible={true}>
<div style={{
padding: '20px',
backgroundColor: '#e3f2fd',
height: '100%',
overflowY: 'auto'
}}>
<h3>Navigation</h3>
<ul style={{ listStyle: 'none', padding: 0 }}>
<li style={{ padding: '8px' }}>🏠 Home</li>
<li style={{ padding: '8px' }}>📁 Files</li>
<li style={{ padding: '8px' }}>⚙️ Settings</li>
<li style={{ padding: '8px' }}>ℹ️ About</li>
</ul>
</div>
</PaneDirective>
<PaneDirective size='auto'>
<div style={{ padding: '20px' }}>
<h3>Main Content</h3>
<p>Content area grows when sidebar collapses</p>
</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
</div>
);
}
export default ButtonIntegration;Use Cases:
- Menu toggle button (hamburger menu pattern)
- Collapse all / Expand all buttons
- Panel visibility controls
- Responsive layout switches
Collapsible Configuration
Configure which panes can be collapsed by users.
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from 'react';
function CollapsibleConfiguration() {
return (
<SplitterComponent orientation='Horizontal' style={{ height: '400px' }}>
<PanesDirective>
{/* Collapsible pane - user can collapse */}
<PaneDirective size='200px' collapsible={true}>
<div style={{ padding: '20px', backgroundColor: '#c8e6c9' }}>
<h3>Collapsible Pane</h3>
<p>User can click gripper to collapse</p>
</div>
</PaneDirective>
{/* Non-collapsible pane - user cannot collapse */}
<PaneDirective size='200px' collapsible={false}>
<div style={{ padding: '20px', backgroundColor: '#ffccbc' }}>
<h3>Non-Collapsible Pane</h3>
<p>This pane cannot be collapsed by user</p>
</div>
</PaneDirective>
{/* Collapsible pane */}
<PaneDirective size='200px' collapsible={true}>
<div style={{ padding: '20px', backgroundColor: '#b3e5fc' }}>
<h3>Also Collapsible</h3>
<p>User can toggle this pane</p>
</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
);
}
export default CollapsibleConfiguration;Gripper UI
When collapsible={true}, a gripper icon appears at the pane edge. Users click it to toggle collapse state.
Default Gripper Appearance:
- Vertical bars
|||or chevron</> - Positioned at separator
- Clickable area for collapse/expand
Best Practices
1. Set collapsible strategically - Only for secondary panes 2. Provide feedback - Update button states when pane collapses 3. Save preferences - Store collapse state in localStorage 4. Consider content - Ensure collapsed pane content is not essential 5. Test responsiveness - Collapse behavior on mobile devices
Getting Started with React Splitter
Table of Contents
Installation
The Splitter component is part of the @syncfusion/ej2-react-layouts package. Install it using npm:
npm install @syncfusion/ej2-react-layouts --saveThis automatically installs the required dependencies:
@syncfusion/ej2-base- Base utilities@syncfusion/ej2-layouts- Layout components CSS and logic
Verify Installation
After installation, verify the package in package.json:
{
"dependencies": {
"@syncfusion/ej2-react-layouts": "^latest",
"@syncfusion/ej2-base": "^latest"
}
}CSS Import
The Splitter component requires CSS files for styling. Import these in your main component or App.css:
Tailwind 3 Theme
@import '../../node_modules/@syncfusion/ej2-base/styles/tailwind3.css';
@import '../../node_modules/@syncfusion/ej2-layouts/styles/tailwind3.css';Bootstrap 5 Theme
@import '../../node_modules/@syncfusion/ej2-base/styles/bootstrap5.css';
@import '../../node_modules/@syncfusion/ej2-layouts/styles/bootstrap5.css';Material Theme
@import '../../node_modules/@syncfusion/ej2-base/styles/material.css';
@import '../../node_modules/@syncfusion/ej2-layouts/styles/material.css';Fluent Theme
@import '../../node_modules/@syncfusion/ej2-base/styles/fluent.css';
@import '../../node_modules/@syncfusion/ej2-layouts/styles/fluent.css';Best Practice: Import CSS in your main App component (App.tsx/App.jsx) before rendering Splitter.
Basic Setup
The Splitter requires two child components: 1. PanesDirective - Container for all panes 2. PaneDirective - Individual pane configuration
Minimal Structure
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
function App() {
return (
<SplitterComponent>
<PanesDirective>
<PaneDirective size='300px'>
<div>Left Pane</div>
</PaneDirective>
<PaneDirective size='300px'>
<div>Right Pane</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
);
}Import Statements
// Import components
import {
PaneDirective,
PanesDirective,
SplitterComponent
} from '@syncfusion/ej2-react-layouts';
// Import hooks if needed for refs
import * as React from 'react';First Working Example
Complete working example with two horizontal panes:
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from 'react';
import './App.css';
function App() {
return (
<div className='App'>
<h2>React Splitter - Getting Started</h2>
<SplitterComponent orientation='Horizontal'>
<PanesDirective>
<PaneDirective size='200px'>
<div style={{ padding: '20px', backgroundColor: '#f5f5f5' }}>
<h3>Left Panel</h3>
<p>This is the left panel with fixed size</p>
</div>
</PaneDirective>
<PaneDirective size='300px'>
<div style={{ padding: '20px', backgroundColor: '#ffffff' }}>
<h3>Right Panel</h3>
<p>This panel is resizable. Drag the separator to resize.</p>
</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
</div>
);
}
export default App;CSS for Example
.App {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
.e-splitter {
height: 400px;
border: 1px solid #ddd;
}
.e-pane {
overflow: auto;
}Dependencies
Required Packages
@syncfusion/ej2-react-layouts- React Splitter component@syncfusion/ej2-base- Base utilities and stylesreact- React library (v16.8+)react-dom- React DOM library (v16.8+)
Peer Dependencies
{
"peerDependencies": {
"react": ">=16.8.0",
"react-dom": ">=16.8.0"
}
}Compatibility
- React: 16.8+ (hooks support required)
- TypeScript: 3.5+ (optional, for type definitions)
- Node: 12+
Next Steps
After successful setup: 1. Configure Panes - Move to pane-layout-configuration.md to add multiple panes and nested layouts 2. Adjust Sizing - Use pane-sizing-and-separation.md for size management 3. Add Features - Explore expand-collapse, resize events, and other functionality
Common Setup Issues
Issue: Styles not applying
- Solution: Ensure CSS imports are at the top of your App component
Issue: Components not recognized
- Solution: Verify correct import path:
@syncfusion/ej2-react-layouts
Issue: TypeScript errors
- Solution: Install type definitions:
npm install --save-dev @types/react
Issue: Height not rendering
- Solution: Set explicit height on parent container:
<div style={{height: '500px'}}>
Splitter Methods Reference
Table of Contents
addPane()
Signature: addPane(paneProperties: PanePropertiesModel, index?: number): void
Description: Dynamically adds a new pane to the Splitter at the specified index position.
Parameters:
paneProperties(PanePropertiesModel): Configuration object for the new paneindex(number, optional): Position where the pane should be inserted (0-based). If not specified, pane is added at the end
Returns: void
Example - Add Pane with Full Configuration:
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import { PanePropertiesModel } from '@syncfusion/ej2-react-layouts';
import * as React from "react";
function App() {
let splitterInstance: any;
const paneDetails: PanePropertiesModel = {
content: 'New Pane',
max: '250px',
min: '30px',
size: '150px',
collapsible: true,
resizable: true
};
const addPane = () => {
if (splitterInstance) {
splitterInstance.addPane(paneDetails, 1);
}
};
return (
<>
<button onClick={addPane}>Add Pane</button>
<SplitterComponent
ref={(splitter) => (splitterInstance = splitter)}
height="250px"
width="600px"
>
<PanesDirective>
<PaneDirective size='200px'>
<div>Pane 1</div>
</PaneDirective>
<PaneDirective size='200px'>
<div>Pane 2</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
</>
);
}
export default App;When to Use:
- Creating dynamic layouts where panes are added at runtime
- Building collapsible panel systems
- Implementing tabbed interfaces with pane switching
- Responsive designs that add/remove panels based on screen size
Best Practices:
- Always use
refto access the Splitter instance - Provide complete
PanePropertiesModelconfiguration - Verify pane index is within bounds (0 to total panes)
- Trigger UI updates after adding panes
---
removePane()
Signature: removePane(index: number): void
Description: Removes a pane from the Splitter at the specified index.
Parameters:
index(number): Zero-based index of the pane to remove
Returns: void
Example - Remove Specific Pane:
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from "react";
function App() {
let splitterInstance: any;
const removePane = (paneIndex: number) => {
if (splitterInstance && paneIndex >= 0 && paneIndex < 3) {
splitterInstance.removePane(paneIndex);
}
};
return (
<>
<button onClick={() => removePane(1)}>Remove Middle Pane</button>
<SplitterComponent
ref={(splitter) => (splitterInstance = splitter)}
height="250px"
width="600px"
>
<PanesDirective>
<PaneDirective size='150px'>
<div>Pane 1</div>
</PaneDirective>
<PaneDirective size='150px'>
<div>Pane 2 (removable)</div>
</PaneDirective>
<PaneDirective size='150px'>
<div>Pane 3</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
</>
);
}
export default App;When to Use:
- Removing panes when tabs are closed
- Cleaning up dynamic layouts
- Responding to user preferences
- Resetting layout to default configuration
Best Practices:
- Always validate the index before removing
- Ensure at least one pane remains in the Splitter
- Recalculate remaining pane sizes if needed
- Provide visual feedback when pane is removed
---
collapse()
Signature: collapse(index: number): void
Description: Programmatically collapses a pane at the specified index. The pane becomes hidden and its space is redistributed to adjacent panes.
Parameters:
index(number): Zero-based index of the pane to collapse
Returns: void
Prerequisite: The pane must have collapsible={true} set
Example - Programmatically Collapse Pane:
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from "react";
function App() {
let splitterInstance: any;
const collapseSidebar = () => {
if (splitterInstance) {
splitterInstance.collapse(0);
}
};
return (
<>
<button onClick={collapseSidebar}>Hide Sidebar</button>
<SplitterComponent
ref={(splitter) => (splitterInstance = splitter)}
height="400px"
width="100%"
>
<PanesDirective>
<PaneDirective size='250px' collapsible={true}>
<div>Navigation Sidebar</div>
</PaneDirective>
<PaneDirective size='auto'>
<div>Main Content Area</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
</>
);
}
export default App;When to Use:
- Creating toggle buttons for sidebar visibility
- Implementing responsive layouts
- Saving screen space for focus areas
- Programmatic control of pane visibility
Best Practices:
- Only collapse panes with
collapsible={true} - Provide UI feedback that pane is collapsed
- Keep at least one pane visible
- Consider using with
expand()for toggle functionality
---
expand()
Signature: expand(index: number): void
Description: Programmatically expands a collapsed pane at the specified index, making it visible again.
Parameters:
index(number): Zero-based index of the pane to expand
Returns: void
Example - Programmatically Expand Pane:
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from "react";
function App() {
let splitterInstance: any;
const [collapsed, setCollapsed] = React.useState(false);
const toggleSidebar = () => {
if (splitterInstance) {
if (collapsed) {
splitterInstance.expand(0);
setCollapsed(false);
} else {
splitterInstance.collapse(0);
setCollapsed(true);
}
}
};
return (
<>
<button onClick={toggleSidebar}>
{collapsed ? 'Show' : 'Hide'} Sidebar
</button>
<SplitterComponent
ref={(splitter) => (splitterInstance = splitter)}
height="400px"
width="100%"
>
<PanesDirective>
<PaneDirective size='250px' collapsible={true}>
<div>Navigation Sidebar</div>
</PaneDirective>
<PaneDirective size='auto'>
<div>Main Content Area</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
</>
);
}
export default App;When to Use:
- Restoring hidden panes on demand
- Implementing toggle buttons
- Responding to user preferences
- Programmatic control of pane visibility
Best Practices:
- Use with
collapse()for toggle functionality - Track collapsed state in React state
- Provide clear visual indicators of pane state
- Combine with CSS transitions for smooth animations
---
destroy()
Signature: destroy(): void
Description: Destroys the Splitter component and releases all its resources. Should be called during component cleanup.
Parameters: None
Returns: void
Example - Destroy on Unmount:
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from "react";
function App() {
let splitterInstance: any;
React.useEffect(() => {
return () => {
// Cleanup: destroy splitter when component unmounts
if (splitterInstance) {
splitterInstance.destroy();
}
};
}, []);
return (
<SplitterComponent
ref={(splitter) => (splitterInstance = splitter)}
height="250px"
width="600px"
>
<PanesDirective>
<PaneDirective size='200px'>
<div>Pane 1</div>
</PaneDirective>
<PaneDirective size='200px'>
<div>Pane 2</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
);
}
export default App;When to Use:
- Component unmounting and cleanup
- Preventing memory leaks
- Closing modal dialogs with Splitters
- Conditional rendering scenarios
Best Practices:
- Always call in
useEffectcleanup function - Null-check the instance before destroying
- Release any event listeners before destroying
- Consider framework-specific cleanup patterns
---
Method Patterns
Pattern 1: Add/Remove Dynamic Panes
const [paneCount, setPaneCount] = React.useState(2);
const handleAddPane = () => {
if (splitterInstance) {
const newPane: PanePropertiesModel = {
size: '150px',
min: '100px',
max: '300px',
content: `Pane ${paneCount + 1}`
};
splitterInstance.addPane(newPane);
setPaneCount(paneCount + 1);
}
};
const handleRemovePane = () => {
if (splitterInstance && paneCount > 1) {
splitterInstance.removePane(paneCount - 1);
setPaneCount(paneCount - 1);
}
};
return (
<>
<button onClick={handleAddPane}>Add Pane</button>
<button onClick={handleRemovePane}>Remove Pane</button>
</>
);Pattern 2: Toggle Collapse/Expand
const [expanded, setExpanded] = React.useState({
0: true,
1: true,
2: true
});
const togglePane = (index: number) => {
if (splitterInstance) {
if (expanded[index]) {
splitterInstance.collapse(index);
} else {
splitterInstance.expand(index);
}
setExpanded({
...expanded,
[index]: !expanded[index]
});
}
};
return (
<>
<button onClick={() => togglePane(0)}>
{expanded[0] ? 'Collapse' : 'Expand'} Pane 1
</button>
</>
);Pattern 3: Responsive Pane Management
React.useEffect(() => {
const handleResize = () => {
if (window.innerWidth < 768) {
// Collapse sidebar on small screens
if (splitterInstance && expanded[0]) {
splitterInstance.collapse(0);
setExpanded({ ...expanded, 0: false });
}
}
};
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, [expanded]);---
Method Quick Reference
| Method | Parameters | Use Case |
|---|---|---|
addPane() | PanePropertiesModel, index? | Add panes dynamically |
removePane() | index | Remove panes dynamically |
collapse() | index | Hide pane programmatically |
expand() | index | Show collapsed pane |
destroy() | none | Cleanup on unmount |
Pane Content and Styling
Table of Contents
- HTML Content in Panes
- React Component Content
- CSS Selector-Based Content
- Pane Template Usage
- Custom Styling
HTML Content in Panes
Add simple HTML content directly inside PaneDirective.
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from 'react';
function HTMLContent() {
return (
<SplitterComponent orientation='Horizontal' style={{ height: '400px' }}>
<PanesDirective>
<PaneDirective size='250px'>
<div style={{ padding: '20px' }}>
<h3>Navigation</h3>
<ul>
<li><a href='#'>Home</a></li>
<li><a href='#'>About</a></li>
<li><a href='#'>Contact</a></li>
</ul>
</div>
</PaneDirective>
<PaneDirective size='300px'>
<div style={{ padding: '20px' }}>
<h2>Welcome</h2>
<p>This is a simple HTML content pane.</p>
<button onClick={() => alert('Clicked!')}>Click Me</button>
</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
);
}
export default HTMLContent;Use Cases:
- Navigation menus
- Simple text content
- Static layouts
- Basic lists and forms
React Component Content
Use React components as pane content for complex, interactive panels.
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from 'react';
// Sidebar component
function Sidebar() {
const [activeItem, setActiveItem] = React.useState('home');
const items = [
{ id: 'home', label: '🏠 Home' },
{ id: 'projects', label: '📁 Projects' },
{ id: 'settings', label: '⚙️ Settings' },
{ id: 'help', label: '❓ Help' }
];
return (
<div style={{ padding: '15px', height: '100%', overflowY: 'auto' }}>
<h3>Menu</h3>
{items.map(item => (
<div
key={item.id}
onClick={() => setActiveItem(item.id)}
style={{
padding: '10px',
margin: '5px 0',
backgroundColor: activeItem === item.id ? '#007bff' : '#f0f0f0',
color: activeItem === item.id ? 'white' : 'black',
cursor: 'pointer',
borderRadius: '4px'
}}
>
{item.label}
</div>
))}
</div>
);
}
// Main content component
function MainContent({ title }: { title: string }) {
const [count, setCount] = React.useState(0);
return (
<div style={{ padding: '20px' }}>
<h2>{title}</h2>
<p>Interactive React component content</p>
<p>Counter: {count}</p>
<button
onClick={() => setCount(count + 1)}
style={{
padding: '8px 16px',
backgroundColor: '#28a745',
color: 'white',
border: 'none',
borderRadius: '4px',
cursor: 'pointer'
}}
>
Increment
</button>
</div>
);
}
// Main splitter component
function ComponentContent() {
const [activeSection, setActiveSection] = React.useState('home');
return (
<SplitterComponent orientation='Horizontal' style={{ height: '400px' }}>
<PanesDirective>
<PaneDirective size='200px'>
<Sidebar />
</PaneDirective>
<PaneDirective size='300px'>
<MainContent title={activeSection.toUpperCase()} />
</PaneDirective>
</PanesDirective>
</SplitterComponent>
);
}
export default ComponentContent;Advantages:
- Full React state management
- Event handlers and hooks
- Complex UI logic
- Reusable component patterns
CSS Selector-Based Content
Reference external HTML elements using CSS selectors.
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from 'react';
function SelectorContent() {
return (
<div>
{/* Hidden content elements */}
<div id='sidebar-content' style={{ display: 'none' }}>
<h3>Sidebar Content</h3>
<p>This content is referenced by selector</p>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
<div id='main-content' style={{ display: 'none' }}>
<h2>Main Area</h2>
<p>Content loaded from selector #main-content</p>
</div>
{/* Splitter using selectors */}
<SplitterComponent orientation='Horizontal' style={{ height: '400px' }}>
<PanesDirective>
<PaneDirective
size='250px'
content='#sidebar-content'
>
</PaneDirective>
<PaneDirective
size='300px'
content='#main-content'
>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
</div>
);
}
export default SelectorContent;Use Cases:
- Template-based content
- Server-rendered HTML
- Pre-existing DOM elements
- HTML-first development
Pane Template Usage
Define content templates for dynamic rendering.
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from 'react';
function PaneTemplates() {
const renderSidebarTemplate = () => (
<div style={{ padding: '15px', height: '100%' }}>
<h4>Filter</h4>
<div style={{ marginBottom: '15px' }}>
<label>
<input type='checkbox' defaultChecked /> Active
</label>
</div>
<div style={{ marginBottom: '15px' }}>
<label>
<input type='checkbox' /> Archived
</label>
</div>
<div>
<label>
<input type='checkbox' /> Deleted
</label>
</div>
</div>
);
const renderMainTemplate = () => (
<div style={{ padding: '20px' }}>
<h3>Results</h3>
<table style={{ width: '100%', borderCollapse: 'collapse' }}>
<thead>
<tr style={{ borderBottom: '2px solid #ddd' }}>
<th style={{ padding: '10px', textAlign: 'left' }}>Name</th>
<th style={{ padding: '10px', textAlign: 'left' }}>Status</th>
<th style={{ padding: '10px', textAlign: 'left' }}>Date</th>
</tr>
</thead>
<tbody>
<tr style={{ borderBottom: '1px solid #eee' }}>
<td style={{ padding: '10px' }}>Item 1</td>
<td style={{ padding: '10px' }}>Active</td>
<td style={{ padding: '10px' }}>2026-03-10</td>
</tr>
<tr style={{ borderBottom: '1px solid #eee' }}>
<td style={{ padding: '10px' }}>Item 2</td>
<td style={{ padding: '10px' }}>Active</td>
<td style={{ padding: '10px' }}>2026-03-09</td>
</tr>
</tbody>
</table>
</div>
);
return (
<SplitterComponent orientation='Horizontal' style={{ height: '400px' }}>
<PanesDirective>
<PaneDirective size='200px'>
{renderSidebarTemplate()}
</PaneDirective>
<PaneDirective size='300px'>
{renderMainTemplate()}
</PaneDirective>
</PanesDirective>
</SplitterComponent>
);
}
export default PaneTemplates;Custom Styling
Style panes with CSS classes and inline styles.
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from 'react';
import './custom-styles.css';
function CustomStyling() {
return (
<SplitterComponent
orientation='Horizontal'
style={{ height: '400px' }}
className='custom-splitter'
>
<PanesDirective>
<PaneDirective size='250px' className='sidebar-pane'>
<div style={{ padding: '20px', height: '100%' }}>
<h3>Styled Sidebar</h3>
<p>Custom CSS applied</p>
</div>
</PaneDirective>
<PaneDirective size='300px' className='content-pane'>
<div style={{ padding: '20px', height: '100%' }}>
<h3>Styled Content</h3>
<p>Custom CSS applied</p>
</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
);
}
export default CustomStyling;CSS File: custom-styles.css
/* Splitter container styles */
.custom-splitter {
border: 1px solid #ddd;
border-radius: 4px;
overflow: hidden;
}
/* Sidebar pane styles */
.custom-splitter .sidebar-pane {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.custom-splitter .sidebar-pane > div {
color: white;
}
.custom-splitter .sidebar-pane h3 {
margin-top: 0;
font-size: 18px;
}
/* Content pane styles */
.custom-splitter .content-pane {
background: #f9f9f9;
}
.custom-splitter .content-pane h3 {
color: #333;
border-bottom: 2px solid #007bff;
padding-bottom: 10px;
}
/* Separator styling */
.custom-splitter .e-splitter-bar {
background: linear-gradient(90deg, #e0e0e0, #f0f0f0);
width: 4px;
cursor: col-resize;
transition: all 0.3s ease;
}
.custom-splitter .e-splitter-bar:hover {
background: linear-gradient(90deg, #2196f3, #1976d2);
width: 5px;
}
/* Dark mode styles */
.custom-splitter.dark-theme .sidebar-pane {
background: #1e1e1e;
}
.custom-splitter.dark-theme .content-pane {
background: #2d2d2d;
color: #e0e0e0;
}Example: Theme Switching
function ThemedSplitter() {
const [isDark, setIsDark] = React.useState(false);
return (
<div>
<button onClick={() => setIsDark(!isDark)}>
{isDark ? '☀️ Light' : '🌙 Dark'} Mode
</button>
<SplitterComponent
orientation='Horizontal'
style={{ height: '400px', marginTop: '10px' }}
className={isDark ? 'custom-splitter dark-theme' : 'custom-splitter'}
>
<PanesDirective>
<PaneDirective size='250px' className='sidebar-pane'>
<div style={{ padding: '20px' }}>Sidebar</div>
</PaneDirective>
<PaneDirective size='300px' className='content-pane'>
<div style={{ padding: '20px' }}>Content</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
</div>
);
}Best Practices
1. Match content type to pane purpose - Simple HTML or complex components 2. Optimize rendering - Use React.memo for expensive components 3. Handle overflow - Set appropriate overflow CSS properties 4. Maintain consistency - Apply unified styling across panes 5. Consider accessibility - Ensure content is keyboard accessible 6. Test responsiveness - Verify content fits at minimum pane sizes
Pane Layout Configuration
Table of Contents
- Horizontal Layout
- Vertical Layout
- Multiple Panes
- Nested Splitters
- Dynamic Pane Addition
- Dynamic Pane Removal
- Pane Properties
Horizontal Layout
Horizontal layout displays panes side-by-side, separated by vertical dividers.
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from 'react';
function HorizontalLayout() {
return (
<SplitterComponent orientation='Horizontal'>
<PanesDirective>
<PaneDirective size='300px'>
<div>Left Pane</div>
</PaneDirective>
<PaneDirective size='300px'>
<div>Right Pane</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
);
}
export default HorizontalLayout;Use Case: File explorer with editor, email client with message list and preview, dashboard with sidebar and content.
Size Options
- Pixel size:
size='200px' - Percentage:
size='50%'(each pane gets equal space) - Mixed: First pane 250px, second pane takes remaining space
Vertical Layout
Vertical layout stacks panes top-to-bottom, separated by horizontal dividers.
function VerticalLayout() {
return (
<SplitterComponent orientation='Vertical'>
<PanesDirective>
<PaneDirective size='200px'>
<div>Top Pane</div>
</PaneDirective>
<PaneDirective size='300px'>
<div>Bottom Pane</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
);
}Use Case: Code editor with code area on top and console/output at bottom, dashboard with header and content area.
Multiple Panes
Create layouts with 3 or more panes. Total sizes should equal available space.
function MultiplePanes() {
return (
<SplitterComponent orientation='Horizontal'>
<PanesDirective>
<PaneDirective size='20%'>
<div style={{ padding: '15px' }}>
<h4>Sidebar</h4>
<ul>
<li>Nav 1</li>
<li>Nav 2</li>
</ul>
</div>
</PaneDirective>
<PaneDirective size='60%'>
<div style={{ padding: '15px' }}>
<h4>Main Content</h4>
<p>Primary content area</p>
</div>
</PaneDirective>
<PaneDirective size='20%'>
<div style={{ padding: '15px' }}>
<h4>Details</h4>
<p>Side panel for details</p>
</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
);
}Best Practice: Use percentages for multiple panes to ensure they fit the container.
Nested Splitters
Combine horizontal and vertical splitters for complex layouts like IDE interfaces.
function NestedSplitters() {
return (
<SplitterComponent orientation='Horizontal'>
<PanesDirective>
<PaneDirective size='250px'>
<div style={{ padding: '10px' }}>
<h4>File Explorer</h4>
<div>file1.ts</div>
<div>file2.ts</div>
</div>
</PaneDirective>
{/* Vertical splitter inside horizontal */}
<PaneDirective size='auto'>
<SplitterComponent orientation='Vertical'>
<PanesDirective>
<PaneDirective size='70%'>
<div style={{ padding: '10px' }}>
<h4>Code Editor</h4>
<p>Write code here...</p>
</div>
</PaneDirective>
<PaneDirective size='30%'>
<div style={{ padding: '10px' }}>
<h4>Console</h4>
<p>Output here...</p>
</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
);
}IDE Layout Pattern:
- Outer: Horizontal (Sidebar | Editor Area)
- Inner (Editor Area): Vertical (Code | Console)
Dynamic Pane Addition
Add panes at runtime using the addPane() public method.
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from 'react';
function DynamicPaneAddition() {
const splitterRef = React.useRef<SplitterComponent>(null);
const [paneCount, setPaneCount] = React.useState(2);
const addNewPane = () => {
const newIndex = paneCount;
// Create pane object
const paneObj = {
size: '200px',
content: `<div style="padding: 15px;"><h4>Pane ${newIndex + 1}</h4></div>`,
resizable: true
};
// Add pane using public method
if (splitterRef.current) {
splitterRef.current.addPane(paneObj, newIndex);
setPaneCount(newIndex + 1);
}
};
return (
<div>
<button onClick={addNewPane}>Add Pane</button>
<SplitterComponent
ref={splitterRef}
orientation='Horizontal'
>
<PanesDirective>
<PaneDirective size='200px'>
<div style={{ padding: '15px' }}>Pane 1</div>
</PaneDirective>
<PaneDirective size='200px'>
<div style={{ padding: '15px' }}>Pane 2</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
</div>
);
}
export default DynamicPaneAddition;addPane() Method Signature
addPane(paneProperties, index): voidParameters:
paneProperties- Pane configuration object with properties likesize,content,resizableindex- Position to insert the pane (optional, defaults to end)
Example: Add pane at specific index
const paneObj = {
size: '150px',
content: '<div>New Pane</div>'
};
splitterRef.current.addPane(paneObj, 1); // Insert at position 1Example: Add pane with React component content
const paneObj = {
size: '250px',
contentTemplate: () => (
<div>
<h3>Dynamic Content</h3>
<button>Click Me</button>
</div>
)
};
splitterRef.current.addPane(paneObj);Dynamic Pane Removal
Remove panes at runtime using the removePane() public method.
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from 'react';
function DynamicPaneRemoval() {
const splitterRef = React.useRef<SplitterComponent>(null);
const removePane = (index: number) => {
if (splitterRef.current) {
splitterRef.current.removePane(index);
}
};
return (
<div>
<div style={{ marginBottom: '10px' }}>
<button onClick={() => removePane(0)}>Remove Pane 1</button>
<button onClick={() => removePane(1)}>Remove Pane 2</button>
</div>
<SplitterComponent
ref={splitterRef}
orientation='Horizontal'
>
<PanesDirective>
<PaneDirective size='200px'>
<div style={{ padding: '15px' }}>Pane 1</div>
</PaneDirective>
<PaneDirective size='200px'>
<div style={{ padding: '15px' }}>Pane 2</div>
</PaneDirective>
<PaneDirective size='200px'>
<div style={{ padding: '15px' }}>Pane 3</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
</div>
);
}
export default DynamicPaneRemoval;removePane() Method Signature
removePane(index): voidParameters:
index- The pane index/position to remove (0-based)
Example: Remove specific pane
splitterRef.current.removePane(0); // Remove first pane
splitterRef.current.removePane(2); // Remove third paneExample: Conditional removal with validation
const removePaneIfExists = (index: number) => {
const paneCount = splitterRef.current?.panes?.length || 0;
if (index >= 0 && index < paneCount) {
splitterRef.current?.removePane(index);
} else {
console.warn(`Cannot remove pane at index ${index}`);
}
};Pane Properties
Configure individual panes with these properties:
| Property | Type | Description | Example |
|---|---|---|---|
size | string | Pane width (px or %) | size='300px' |
min | string | Minimum size constraint | min='100px' |
max | string | Maximum size constraint | max='500px' |
collapsed | boolean | Initial collapsed state | collapsed={true} |
collapsible | boolean | Allow user collapse/expand | collapsible={true} |
resizable | boolean | Allow user to resize | resizable={false} |
content | string/JSX | Pane content | content='<div>Text</div>' |
Example: Pane with All Properties
<PaneDirective
size='250px'
min='100px'
max='500px'
collapsed={false}
collapsible={true}
resizable={true}
>
<div style={{ padding: '15px' }}>
<h4>Configurable Pane</h4>
</div>
</PaneDirective>Best Practices for Pane Configuration
1. Always set size - Use px or % consistently 2. Set min/max for resizable panes - Prevent usability issues 3. Use collapsible for space-saving - Hide secondary panels 4. Test responsiveness - Ensure layouts work on mobile 5. Consider content type - Match pane size to content (scrollable vs fixed)
Pane Sizing and Separation
Table of Contents
- Fixed Pane Sizing
- Percentage-Based Sizing
- Min and Max Constraints
- Separator Styling
- Dynamic Size Adjustment
Fixed Pane Sizing
Fixed sizing sets panes to specific pixel dimensions. Useful for sidebars and fixed-width panels.
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from 'react';
function FixedSizing() {
return (
<SplitterComponent orientation='Horizontal' style={{ height: '400px' }}>
<PanesDirective>
<PaneDirective size='250px'>
<div style={{ padding: '20px', backgroundColor: '#f0f0f0' }}>
<h3>Sidebar (Fixed 250px)</h3>
<p>Navigation items here</p>
</div>
</PaneDirective>
<PaneDirective size='300px'>
<div style={{ padding: '20px' }}>
<h3>Content Area (Fixed 300px)</h3>
<p>Main content resizable from right</p>
</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
);
}
export default FixedSizing;When to Use:
- Navigation sidebars (always visible)
- Fixed-width panels with specific content
- Tool panels in IDEs
Best Practices:
- Use fixed sizing for panels that shouldn't shrink (sidebar)
- Set last pane without size to use remaining space
- Ensure total fixed sizes don't exceed container width
Percentage-Based Sizing
Percentage sizing distributes space proportionally. Useful for responsive layouts.
function PercentageSizing() {
return (
<SplitterComponent orientation='Horizontal' style={{ height: '400px' }}>
<PanesDirective>
<PaneDirective size='25%'>
<div style={{ padding: '20px', backgroundColor: '#e8f4f8' }}>
<h3>Sidebar (25%)</h3>
</div>
</PaneDirective>
<PaneDirective size='50%'>
<div style={{ padding: '20px' }}>
<h3>Main (50%)</h3>
</div>
</PaneDirective>
<PaneDirective size='25%'>
<div style={{ padding: '20px', backgroundColor: '#f8e8e8' }}>
<h3>Details (25%)</h3>
</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
);
}Advantages:
- Responsive across screen sizes
- Total should equal 100%
- Resizing updates all percentage-based panes
Example: Unequal Distribution
<PanesDirective>
<PaneDirective size='20%'><div>Sidebar</div></PaneDirective>
<PaneDirective size='60%'><div>Main Content</div></PaneDirective>
<PaneDirective size='20%'><div>Details</div></PaneDirective>
</PanesDirective>Min and Max Constraints
Prevent panes from becoming too small or too large during resizing.
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from 'react';
function SizeConstraints() {
return (
<SplitterComponent orientation='Horizontal' style={{ height: '400px' }}>
<PanesDirective>
<PaneDirective
size='200px'
min='100px'
max='400px'
>
<div style={{ padding: '20px', backgroundColor: '#f0f0f0' }}>
<h3>Constrained Pane</h3>
<p>Min: 100px | Max: 400px</p>
</div>
</PaneDirective>
<PaneDirective size='300px'>
<div style={{ padding: '20px' }}>
<h3>Resizable (No Constraints)</h3>
</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
);
}
export default SizeConstraints;Min Size Purpose
- Prevent content overflow when pane shrinks
- Maintain readability of sidebar navigation
- Ensure minimum button/control visibility
Max Size Purpose
- Prevent excessive expansion
- Maintain balanced layout
- Ensure main content remains visible
Example: Content-Based Constraints
<PaneDirective
size='250px'
min='200px' // Never shrink below 200px (width needed for nav)
max='500px' // Never expand beyond 500px (too wide for sidebar)
>
<div>Navigation Sidebar</div>
</PaneDirective>Separator Styling
Customize the appearance of pane separators (dividers).
import './custom-separator.css';
function CustomSeparatorStyling() {
return (
<SplitterComponent
orientation='Horizontal'
style={{ height: '400px' }}
className='custom-splitter'
>
<PanesDirective>
<PaneDirective size='250px'>
<div style={{ padding: '20px' }}>Pane 1</div>
</PaneDirective>
<PaneDirective size='250px'>
<div style={{ padding: '20px' }}>Pane 2</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
);
}Custom CSS for Separator
/* Hide default separator and add custom styling */
.custom-splitter .e-splitter-bar {
background-color: #007bff;
width: 4px;
cursor: col-resize;
}
/* Hover effect */
.custom-splitter .e-splitter-bar:hover {
background-color: #0056b3;
}
/* Gripper icon customization */
.custom-splitter .e-splitter-bar::before {
content: '|||';
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 12px;
}
/* Vertical splitter bar */
.custom-splitter.e-vertical .e-splitter-bar {
height: 4px;
cursor: row-resize;
}Material Design Separator
.material-splitter .e-splitter-bar {
background-color: #e0e0e0;
width: 2px;
transition: all 0.3s ease;
}
.material-splitter .e-splitter-bar:hover {
background-color: #2196f3;
width: 3px;
}Dynamic Size Adjustment
Programmatically adjust pane sizes after initialization.
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from 'react';
function DynamicSizeAdjustment() {
const splitterRef = React.useRef<SplitterComponent>(null);
const adjustSizes = (ratio: string) => {
if (splitterRef.current && splitterRef.current.panes) {
switch(ratio) {
case 'half':
// Set equal sizes (50-50)
splitterRef.current.panes[0].size = '50%';
splitterRef.current.panes[1].size = '50%';
break;
case 'narrow':
// First pane narrow (30-70)
splitterRef.current.panes[0].size = '30%';
splitterRef.current.panes[1].size = '70%';
break;
case 'wide':
// First pane wide (70-30)
splitterRef.current.panes[0].size = '70%';
splitterRef.current.panes[1].size = '30%';
break;
}
// Refresh to apply changes
splitterRef.current.refresh();
}
};
return (
<div>
<div style={{ marginBottom: '15px' }}>
<button onClick={() => adjustSizes('half')}>50-50 Split</button>
<button onClick={() => adjustSizes('narrow')}>30-70 Split</button>
<button onClick={() => adjustSizes('wide')}>70-30 Split</button>
</div>
<SplitterComponent
ref={splitterRef}
orientation='Horizontal'
style={{ height: '300px' }}
>
<PanesDirective>
<PaneDirective size='50%'>
<div style={{ padding: '20px', backgroundColor: '#e3f2fd' }}>
<h3>Pane 1</h3>
</div>
</PaneDirective>
<PaneDirective size='50%'>
<div style={{ padding: '20px', backgroundColor: '#f3e5f5' }}>
<h3>Pane 2</h3>
</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
</div>
);
}
export default DynamicSizeAdjustment;Refresh Method
The refresh() method redraws the splitter after programmatic changes:
splitterRef.current.refresh();Example: Responsive Size Adjustment
const handleResize = () => {
const width = window.innerWidth;
if (width < 768) {
// Mobile: 40-60 split
splitterRef.current.panes[0].size = '40%';
splitterRef.current.panes[1].size = '60%';
} else if (width < 1024) {
// Tablet: 35-65 split
splitterRef.current.panes[0].size = '35%';
splitterRef.current.panes[1].size = '65%';
} else {
// Desktop: 30-70 split
splitterRef.current.panes[0].size = '30%';
splitterRef.current.panes[1].size = '70%';
}
splitterRef.current.refresh();
};
React.useEffect(() => {
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);Best Practices
1. Mix fixed and percentage: Fixed sidebar + percentage content areas 2. Always set constraints: Apply min/max to resizable panes 3. Test edge cases: Verify layout at minimum container size 4. Consider content: Match pane sizes to typical content dimensions 5. Maintain readability: Ensure minimum size prevents text overflow
Splitter Properties and Configuration
Table of Contents
Splitter Component Properties
The SplitterComponent provides configuration options to customize the layout, behavior, and appearance of the splitter.
orientation
Type: 'Horizontal' | 'Vertical'
Description: Specifies the layout direction of the panes. Use "Horizontal" for left-to-right layout and "Vertical" for top-to-bottom layout.
Example:
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from "react";
function App() {
return (
<SplitterComponent id="splitter" height="250px" width="600px" orientation="Horizontal">
<PanesDirective>
<PaneDirective />
<PaneDirective />
</PanesDirective>
</SplitterComponent>
);
}
export default App;When to Use: Set orientation when initializing the splitter to control the pane arrangement.
---
height and width
Type: string
Description: Specifies the height and width of the Splitter component. Accepts both pixel and percentage values.
Example:
<SplitterComponent height="400px" width="100%">
<PanesDirective>
<PaneDirective size='200px' />
<PaneDirective size='200px' />
</PanesDirective>
</SplitterComponent>When to Use: Always set explicit height for vertical splitters to ensure proper rendering.
---
separatorSize
Type: number
Description: Specifies the size (in pixels) of the separator bar between panes.
Example:
<SplitterComponent height="250px" width="600px" separatorSize={4}>
<PanesDirective>
<PaneDirective size='250px' />
<PaneDirective size='250px' />
</PanesDirective>
</SplitterComponent>Default: 4 pixels When to Use: Customize for better visual separation or to match design specifications.
---
cssClass
Type: string
Description: Specifies one or more CSS class names to customize the Splitter styling.
Example:
<SplitterComponent cssClass="custom-splitter dark-theme" height="250px" width="600px">
<PanesDirective>
<PaneDirective size='250px' />
<PaneDirective size='250px' />
</PanesDirective>
</SplitterComponent>When to Use: Apply custom CSS classes for theme switching and styling customization.
---
enableRtl
Type: boolean
Description: Enables right-to-left rendering for RTL languages (Arabic, Hebrew, etc.).
Example:
<SplitterComponent enableRtl={true} height="250px" width="600px">
<PanesDirective>
<PaneDirective size='250px' />
<PaneDirective size='250px' />
</PanesDirective>
</SplitterComponent>When to Use: Enable RTL for applications supporting RTL languages.
---
enableReversePanes
Type: boolean
Description: Reverses the order of panes in the DOM without reversing the visual order. Useful for accessibility and flexible layouts.
Example:
<SplitterComponent enableReversePanes={true} height="250px" width="600px">
<PanesDirective>
<PaneDirective size='250px' />
<PaneDirective size='250px' />
</PanesDirective>
</SplitterComponent>When to Use: Reorder panes for different screen layouts or accessibility requirements.
---
enabled
Type: boolean
Description: Enables or disables the Splitter component. When disabled, users cannot interact with the component.
Default: true
Example:
<SplitterComponent enabled={false} height="250px" width="600px">
<PanesDirective>
<PaneDirective size='250px' />
<PaneDirective size='250px' />
</PanesDirective>
</SplitterComponent>When to Use: Disable the splitter during data loading or validation states.
---
enablePersistence
Type: boolean
Description: Enables persistence of the Splitter state (pane sizes, collapsed states) between page reloads using browser storage.
Default: false
Example:
<SplitterComponent enablePersistence={true} height="250px" width="600px" id="splitter-persistence">
<PanesDirective>
<PaneDirective size='250px' collapsible={true} />
<PaneDirective size='250px' collapsible={true} />
</PanesDirective>
</SplitterComponent>When to Use: Persist user layout preferences across browser sessions.
Note: Component must have an id attribute for persistence to work.
---
enableHtmlSanitizer
Type: boolean
Description: Defines whether to allow HTML content sanitization. When enabled, prevents cross-site scripting (XSS) attacks by sanitizing HTML content in panes.
Default: true
Example:
<SplitterComponent enableHtmlSanitizer={true} height="250px" width="600px">
<PanesDirective>
<PaneDirective content="<div>Safe HTML Content</div>" />
<PaneDirective content="<p>More content</p>" />
</PanesDirective>
</SplitterComponent>When to Use: Always keep enabled for security. Disable only when you control all content sources.
Security Note: XSS attacks can compromise your application. Only disable sanitization for trusted content sources.
---
locale
Type: string
Description: Overrides the global culture and localization for the Splitter component.
Example:
<SplitterComponent locale="fr-FR" height="250px" width="600px">
<PanesDirective>
<PaneDirective size='250px' />
<PaneDirective size='250px' />
</PanesDirective>
</SplitterComponent>Default: 'en-US' When to Use: Set locale for localized components and text.
---
paneSettings
Type: PanePropertiesModel[]
Description: Specifies an array of pane properties for programmatic pane configuration. This is an alternative to using <PaneDirective> elements, useful when panes are generated dynamically or configured from data structures.
Example - Array-Based Configuration:
import { SplitterComponent, PanesDirective, PaneDirective } from '@syncfusion/ej2-react-layouts';
import { PanePropertiesModel } from '@syncfusion/ej2-react-layouts';
import * as React from "react";
function App() {
const paneSettings: PanePropertiesModel[] = [
{
size: '200px',
min: '100px',
max: '300px',
content: 'Pane 1',
collapsible: true,
resizable: true
},
{
size: '250px',
min: '150px',
max: '400px',
content: 'Pane 2',
collapsible: true,
resizable: true
},
{
size: 'auto',
min: '200px',
content: 'Pane 3',
resizable: true
}
];
return (
<SplitterComponent height="400px" width="100%" paneSettings={paneSettings}>
<PanesDirective>
{paneSettings.map((pane, index) => (
<PaneDirective key={index} {...pane} />
))}
</PanesDirective>
</SplitterComponent>
);
}
export default App;Example - Dynamic Configuration from API:
const [paneSettings, setPaneSettings] = React.useState<PanePropertiesModel[]>([]);
React.useEffect(() => {
// Fetch pane configuration from API
fetchPaneConfig().then(config => {
setPaneSettings(config);
});
}, []);
return (
<SplitterComponent height="400px" width="100%" paneSettings={paneSettings}>
<PanesDirective>
{paneSettings.map((pane, index) => (
<PaneDirective key={index} {...pane} />
))}
</PanesDirective>
</SplitterComponent>
);When to Use:
- When panes are generated dynamically from data
- Loading pane configuration from an API or database
- Programmatic layout configuration
- Data-driven UI patterns
Note: paneSettings array elements follow the same structure as PanePropertiesModel (size, min, max, collapsed, collapsible, resizable, content, cssClass).
---
Pane Properties
Each pane in the Splitter is configured using PaneDirective with the following properties:
size
Type: string
Description: Specifies the size of the pane using pixels (e.g., "200px") or percentage (e.g., "50%").
Example:
<PanesDirective>
<PaneDirective size='250px'>
<div>Fixed 250px pane</div>
</PaneDirective>
<PaneDirective size='50%'>
<div>50% width pane</div>
</PaneDirective>
</PanesDirective>When to Use: Always specify size for all panes or use percentages for responsive layouts.
---
min and max
Type: string
Description: Set minimum and maximum size constraints for resizable panes. Prevents panes from becoming too small or too large.
Example:
<PanesDirective>
<PaneDirective size='200px' min='100px' max='400px'>
<div>Constrained pane (100px - 400px)</div>
</PaneDirective>
</PanesDirective>When to Use: Always set min/max for resizable panes to prevent layout issues.
---
collapsed
Type: boolean
Description: Sets the initial collapsed state of the pane. When true, the pane is hidden at component initialization.
Default: false
Example:
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from "react";
function App() {
return (
<SplitterComponent height="250px" width="600px">
<PanesDirective>
<PaneDirective collapsed={false}>
<div>Visible pane</div>
</PaneDirective>
<PaneDirective collapsed={true}>
<div>Hidden pane (start collapsed)</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
);
}
export default App;When to Use: Hide secondary panes to save space on initial load.
---
collapsible
Type: boolean
Description: Allows users to collapse/expand the pane by clicking the gripper icon on the separator.
Default: false
Example:
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from "react";
function App() {
return (
<SplitterComponent height="250px" width="600px">
<PanesDirective>
<PaneDirective collapsible={true}>
<div>Collapsible pane 1</div>
</PaneDirective>
<PaneDirective collapsible={true}>
<div>Collapsible pane 2</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
);
}
export default App;When to Use: Enable collapsing for optional content areas and secondary panels.
---
resizable
Type: boolean
Description: Controls whether users can manually resize the pane using the separator.
Default: true
Example:
<PanesDirective>
<PaneDirective size='200px' resizable={true}>
<div>Resizable pane</div>
</PaneDirective>
<PaneDirective size='200px' resizable={false}>
<div>Fixed-size pane (cannot resize)</div>
</PaneDirective>
</PanesDirective>When to Use: Set resizable={false} for navigation panes that should maintain fixed width.
---
content
Type: string | HTMLElement | JSX.Element
Description: Specifies the content of the pane as plain text, HTML markup, or a React component.
Example - Text Content:
<PaneDirective content="Simple text content" />Example - HTML Content:
<PaneDirective content="<div><h3>Title</h3><p>Content here</p></div>" />Example - React Component:
const MyComponent = () => <div><h3>React Component</h3></div>;
<PaneDirective content={MyComponent} />When to Use: Use inline JSX for dynamic content, HTML for static markup, and text for simple labels.
---
cssClass
Type: string
Description: Applies custom CSS classes to the individual pane for styling customization.
Example:
<PanesDirective>
<PaneDirective cssClass="sidebar-pane custom-styling">
<div>Styled pane</div>
</PaneDirective>
<PaneDirective cssClass="main-content">
<div>Main area</div>
</PaneDirective>
</PanesDirective>When to Use: Apply different styles to different panes for visual distinction.
---
Common Configuration Patterns
Basic Two-Pane Layout
<SplitterComponent height="400px" width="100%" orientation="Horizontal">
<PanesDirective>
<PaneDirective size='250px'>
<div>Left panel</div>
</PaneDirective>
<PaneDirective size='auto'>
<div>Main content (takes remaining space)</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>Three-Pane Dashboard Layout
<SplitterComponent height="500px" width="100%" orientation="Horizontal">
<PanesDirective>
<PaneDirective size='20%'>
<div>Sidebar</div>
</PaneDirective>
<PaneDirective size='60%' min='40%' max='80%'>
<div>Main content</div>
</PaneDirective>
<PaneDirective size='20%'>
<div>Details panel</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>Collapsible Navigation + Resizable Content
<SplitterComponent height="400px" width="100%">
<PanesDirective>
<PaneDirective size='250px' collapsible={true} resizable={true}>
<div>Navigation (collapsible)</div>
</PaneDirective>
<PaneDirective size='auto' resizable={true} min='200px'>
<div>Content (resizable)</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>Responsive Vertical Layout
<SplitterComponent height="600px" width="100%" orientation="Vertical">
<PanesDirective>
<PaneDirective size='70%'>
<div>Editor area</div>
</PaneDirective>
<PaneDirective size='30%' min='20%' max='50%'>
<div>Output/Console</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>---
Property Quick Reference
| Property | Type | Default | Purpose |
|---|---|---|---|
orientation | string | 'Horizontal' | Pane layout direction |
height | string | '100%' | Component height |
width | string | '100%' | Component width |
separatorSize | number | 4 | Separator thickness |
enabled | boolean | true | Enable/disable component |
enableRtl | boolean | false | RTL language support |
enablePersistence | boolean | false | Save state between reloads |
enableHtmlSanitizer | boolean | true | XSS protection |
locale | string | 'en-US' | Localization |
cssClass | string | '' | Custom CSS classes |
enableReversePanes | boolean | false | Reverse pane order |
| Pane Properties | |||
size | string | 'auto' | Pane size (px or %) |
min | string | '0' | Minimum pane size |
max | string | undefined | Maximum pane size |
collapsed | boolean | false | Initial collapsed state |
collapsible | boolean | false | Allow user collapse |
resizable | boolean | true | Allow user resize |
content | string/JSX | '' | Pane content |
cssClass | string | '' | Pane CSS classes |
Resize Behavior
Table of Contents
Resize Events
The Splitter component fires events before and after pane resizing, allowing you to react to or validate resize operations.
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from 'react';
function ResizeEventsExample() {
const [resizeInfo, setResizeInfo] = React.useState<string>('');
const handleBeforeResize = (args: any) => {
console.log('Before Resize:', {
pane: args.paneIndex,
oldSize: args.oldSize,
newSize: args.newSize
});
setResizeInfo(`Before Resize: Pane ${args.paneIndex} - ${args.oldSize} → ${args.newSize}`);
};
const handleResized = (args: any) => {
console.log('After Resize:', {
pane: args.paneIndex,
size: args.size
});
setResizeInfo(`Resized: Pane ${args.paneIndex} - Final size: ${args.size}`);
};
return (
<div>
<div style={{ marginBottom: '10px', padding: '10px', backgroundColor: '#f5f5f5' }}>
<p><strong>Resize Info:</strong> {resizeInfo || 'Drag separator to resize...'}</p>
</div>
<SplitterComponent
orientation='Horizontal'
style={{ height: '300px' }}
beforeResize={handleBeforeResize}
resized={handleResized}
>
<PanesDirective>
<PaneDirective size='200px'>
<div style={{ padding: '20px', backgroundColor: '#e3f2fd' }}>
<h3>Left Pane</h3>
<p>Resizable</p>
</div>
</PaneDirective>
<PaneDirective size='300px'>
<div style={{ padding: '20px', backgroundColor: '#f3e5f5' }}>
<h3>Right Pane</h3>
<p>Drag separator to see events</p>
</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
</div>
);
}
export default ResizeEventsExample;Event Types
| Event | Trigger | Cancelable | Use Case |
|---|---|---|---|
beforeResize | Before resize starts | Yes | Validate new size, prevent resize |
resized | After resize completes | No | Update related components, save size |
Event Arguments for beforeResize
{
paneIndex: number; // Index of pane being resized
oldSize: string; // Previous size (e.g., "200px")
newSize: string; // Proposed new size (e.g., "250px")
cancel?: boolean; // Set to true to prevent resize
event: Event; // Browser mouse/touch event
}Preventing Resize
Block resize operations conditionally using the beforeResize event.
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from 'react';
function PreventingResize() {
const handleBeforeResize = (args: any) => {
// Prevent first pane from shrinking below 150px
if (args.paneIndex === 0) {
const newSizePixels = parseInt(args.newSize);
if (newSizePixels < 150) {
args.cancel = true;
alert('Left pane minimum size is 150px');
return;
}
}
// Prevent second pane from expanding beyond 400px
if (args.paneIndex === 1) {
const newSizePixels = parseInt(args.newSize);
if (newSizePixels > 400) {
args.cancel = true;
alert('Right pane maximum size is 400px');
return;
}
}
};
return (
<SplitterComponent
orientation='Horizontal'
style={{ height: '300px' }}
beforeResize={handleBeforeResize}
>
<PanesDirective>
<PaneDirective size='200px' min='150px'>
<div style={{ padding: '20px' }}>
<h3>Left (Min 150px)</h3>
</div>
</PaneDirective>
<PaneDirective size='300px' max='400px'>
<div style={{ padding: '20px' }}>
<h3>Right (Max 400px)</h3>
</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
);
}
export default PreventingResize;Using Resizable Property
Completely disable resizing for specific panes:
<PaneDirective size='200px' resizable={false}>
<div>Non-resizable Pane</div>
</PaneDirective>When to Use `resizable={false}`:
- Fixed sidebars that shouldn't change size
- Content that requires specific dimensions
- Read-only or display-only panes
Dynamic Resize Configuration
Configure resizable behavior at runtime.
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from 'react';
function DynamicResizeConfiguration() {
const splitterRef = React.useRef<SplitterComponent>(null);
const [resizeMode, setResizeMode] = React.useState('normal');
const changeResizeMode = (mode: string) => {
setResizeMode(mode);
if (splitterRef.current?.panes) {
switch(mode) {
case 'locked':
// Lock all panes
splitterRef.current.panes.forEach((pane: any) => {
pane.resizable = false;
});
break;
case 'flexible':
// Enable all panes
splitterRef.current.panes.forEach((pane: any) => {
pane.resizable = true;
});
break;
case 'left-only':
// Only first pane resizable
splitterRef.current.panes[0].resizable = true;
if (splitterRef.current.panes[1]) {
splitterRef.current.panes[1].resizable = false;
}
break;
}
splitterRef.current.refresh();
}
};
return (
<div>
<div style={{ marginBottom: '10px' }}>
<button
onClick={() => changeResizeMode('normal')}
style={{
padding: '8px 12px',
marginRight: '5px',
backgroundColor: resizeMode === 'normal' ? '#007bff' : '#ccc',
color: 'white',
border: 'none',
borderRadius: '4px',
cursor: 'pointer'
}}
>
Normal
</button>
<button
onClick={() => changeResizeMode('locked')}
style={{
padding: '8px 12px',
marginRight: '5px',
backgroundColor: resizeMode === 'locked' ? '#007bff' : '#ccc',
color: 'white',
border: 'none',
borderRadius: '4px',
cursor: 'pointer'
}}
>
Locked
</button>
<button
onClick={() => changeResizeMode('flexible')}
style={{
padding: '8px 12px',
marginRight: '5px',
backgroundColor: resizeMode === 'flexible' ? '#007bff' : '#ccc',
color: 'white',
border: 'none',
borderRadius: '4px',
cursor: 'pointer'
}}
>
Flexible
</button>
<button
onClick={() => changeResizeMode('left-only')}
style={{
padding: '8px 12px',
backgroundColor: resizeMode === 'left-only' ? '#007bff' : '#ccc',
color: 'white',
border: 'none',
borderRadius: '4px',
cursor: 'pointer'
}}
>
Left Only
</button>
</div>
<p><em>Current Mode: {resizeMode}</em></p>
<SplitterComponent
ref={splitterRef}
orientation='Horizontal'
style={{ height: '300px' }}
>
<PanesDirective>
<PaneDirective size='250px' resizable={true}>
<div style={{ padding: '20px', backgroundColor: '#e3f2fd' }}>
<h3>Pane 1</h3>
</div>
</PaneDirective>
<PaneDirective size='250px' resizable={true}>
<div style={{ padding: '20px', backgroundColor: '#f3e5f5' }}>
<h3>Pane 2</h3>
</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
</div>
);
}
export default DynamicResizeConfiguration;Resize Constraints
Set minimum and maximum sizes to automatically constrain resizing without event handling.
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from 'react';
function ResizeConstraints() {
return (
<SplitterComponent orientation='Horizontal' style={{ height: '300px' }}>
<PanesDirective>
<PaneDirective
size='200px'
min='100px'
max='400px'
>
<div style={{ padding: '20px', backgroundColor: '#c8e6c9' }}>
<h3>Constrained Pane</h3>
<p>Min: 100px | Max: 400px</p>
<p>Try dragging separator - resize is limited</p>
</div>
</PaneDirective>
<PaneDirective size='250px'>
<div style={{ padding: '20px', backgroundColor: '#fff9c4' }}>
<h3>Normal Pane</h3>
<p>No size constraints</p>
</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
);
}
export default ResizeConstraints;Properties
| Property | Type | Description | Example |
|---|---|---|---|
size | string | Current pane size | size='200px' |
min | string | Minimum size constraint | min='100px' |
max | string | Maximum size constraint | max='500px' |
resizable | boolean | Allow user resize | resizable={false} |
Event Data and Handling
Advanced event handling with detailed data.
import { PaneDirective, PanesDirective, SplitterComponent } from '@syncfusion/ej2-react-layouts';
import * as React from 'react';
function EventDataHandling() {
const [events, setEvents] = React.useState<any[]>([]);
const handleBeforeResize = (args: any) => {
const oldSizeNum = parseInt(args.oldSize);
const newSizeNum = parseInt(args.newSize);
const change = newSizeNum - oldSizeNum;
const percentChange = ((change / oldSizeNum) * 100).toFixed(2);
const eventData = {
type: 'beforeResize',
pane: args.paneIndex,
oldSize: args.oldSize,
newSize: args.newSize,
change: `${change}px (${percentChange}%)`,
timestamp: new Date().toLocaleTimeString()
};
setEvents(prev => [eventData, ...prev.slice(0, 9)]);
};
const handleResized = (args: any) => {
const eventData = {
type: 'resized',
pane: args.paneIndex,
finalSize: args.size,
timestamp: new Date().toLocaleTimeString()
};
setEvents(prev => [eventData, ...prev.slice(0, 9)]);
};
return (
<div>
<SplitterComponent
orientation='Horizontal'
style={{ height: '250px', marginBottom: '20px' }}
beforeResize={handleBeforeResize}
resized={handleResized}
>
<PanesDirective>
<PaneDirective size='200px'>
<div style={{ padding: '20px' }}>
<h3>Left</h3>
<p>Drag to resize</p>
</div>
</PaneDirective>
<PaneDirective size='300px'>
<div style={{ padding: '20px' }}>
<h3>Right</h3>
<p>Watch events below</p>
</div>
</PaneDirective>
</PanesDirective>
</SplitterComponent>
<div style={{
padding: '10px',
backgroundColor: '#f5f5f5',
border: '1px solid #ddd',
maxHeight: '200px',
overflowY: 'auto'
}}>
<h4>Event Log</h4>
{events.length === 0 ? (
<p style={{ color: '#999' }}>Resize to see events...</p>
) : (
events.map((event, idx) => (
<div key={idx} style={{
padding: '8px',
borderBottom: '1px solid #eee',
fontSize: '12px'
}}>
<strong>{event.type}</strong> - Pane {event.pane} @ {event.timestamp}
{event.change && <div>Change: {event.change}</div>}
{event.newSize && <div>New: {event.newSize}</div>}
</div>
))
)}
</div>
</div>
);
}
export default EventDataHandling;Best Practices
1. Always set min/max - Prevent layout breakage 2. Validate in beforeResize - Cancel invalid resizes 3. Save state in resized - Persist user preferences 4. Consider content type - Match size constraints to content 5. Test edge cases - Verify extreme sizes don't break UI