
Syncfusion React Carousel
- 337 installs
- 3 repo stars
- Updated July 28, 2026
- syncfusion/react-ui-components-skills
Use syncfusion-react-carousel for development tasks
About
syncfusion-react-carousel: A skill for development. This provides functionality for development workflows.
- syncfusion-react-carousel
Syncfusion React Carousel by the numbers
- 337 all-time installs (skills.sh)
- +23 installs in the week ending Jul 27, 2026 (Skillselion tracking)
- Ranked #1,193 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
- Data as of Jul 29, 2026 (Skillselion catalog sync)
npx skills add https://github.com/syncfusion/react-ui-components-skills --skill syncfusion-react-carouselAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 337 |
|---|---|
| repo stars | ★ 3 |
| Last updated | July 28, 2026 |
| Repository | syncfusion/react-ui-components-skills ↗ |
What it does
Use syncfusion-react-carousel for development tasks
Files
Implementing the Syncfusion React Carousel Component
Table of Contents
- Overview
- Getting Started
- Populating Items and Selection
- Navigation and Indicators
- Animations and Transitions
- API Properties
- API Methods
- API Events
- Styling and Appearance
- Accessibility
- Image Optimization
- Common Patterns
- Use Cases
The Syncfusion React Carousel component is a powerful, fully-featured carousel for displaying images, content, or any sequential items with automatic or manual transitions. It supports multiple animation effects, customizable indicators and navigators, keyboard navigation, and comprehensive accessibility features.
When to Use This Skill
Implement the Carousel component when you need to:
- Create rotating image galleries with smooth transitions
- Build slideshow presentations with navigation controls
- Display product carousels for e-commerce sites
- Implement testimonial sliders with indicators
- Build content carousels with auto-play functionality
- Support touch/swipe navigation on mobile devices
- Display items with accessibility compliance (WCAG 2.2, Section 508)
Component Overview
The Carousel component manages:
- Visual Display: Renders one active slide with customizable templates
- Navigation: Previous/next buttons with multiple visibility modes
- Indicators: Show current position with multiple indicator types (dots, fractions, progress bars)
- Animations: Smooth slide transitions with fade, slide, or custom effects
- Interaction: Auto-play, manual swipe, keyboard navigation
- Accessibility: Full ARIA support, keyboard shortcuts, screen reader compatibility
Core imports:
import { CarouselComponent, CarouselItemsDirective, CarouselItemDirective } from "@syncfusion/ej2-react-navigations";Documentation and Navigation Guide
Getting Started
📄 Read: references/getting-started.md
- Installation and package dependencies
- Development environment setup with Vite or Create React App
- CSS imports and theme configuration (Tailwind, Bootstrap, Fluent, Material)
- Basic carousel component setup
- First working example with items
- Common setup issues and solutions
When to read: First time setting up Carousel or troubleshooting initial setup problems.
Populating Items and Selection
📄 Read: references/populating-items.md
- Populating slides using CarouselItem directives
- Data source binding with itemTemplate
- Setting initial slide with selectedIndex
- Navigation with prev() and next() methods
- Partial visible slides (showing adjacent slides)
- Programmatic vs. declarative slide rendering
When to read: Building slide content, handling dynamic data, or implementing navigation controls.
Navigators and Indicators
📄 Read: references/navigators-and-indicators.md
- Previous/next navigator button visibility modes
- Custom navigator button templates
- Showing/hiding indicators (progress dots)
- Four indicator types: Default, Dynamic, Fraction, Progress
- Indicator templates with preview images
- Play/pause button control and templates
When to read: Customizing navigation UI, changing indicator style, or implementing play controls.
Animations and Transitions
📄 Read: references/animations-and-transitions.md
- Animation effects (Fade, Slide, Custom CSS)
- Setting slide transition intervals per item
- Auto-play configuration and timing
- Pause on hover behavior
- Looping and non-looping behavior
- Touch swipe modes and disabled interactions
- Slide changing events (slideChanging, slideChanged)
When to read: Implementing smooth transitions, configuring auto-play, or adding custom animations.
Styling and Appearance
📄 Read: references/styling-and-appearance.md
- CSS class structure for customization
- Customizing indicator appearance and spacing
- Navigator button positioning and styling
- Partial slide area customization
- Theme Studio integration for visual theming
- Dark mode and custom color schemes
When to read: Styling indicators/navigators, positioning elements, or creating custom themes.
Accessibility
📄 Read: references/accessibility.md
- WCAG 2.2 and Section 508 compliance
- ARIA attributes and roles
- Keyboard interaction shortcuts (arrows, Home, End, Space, Enter)
- Screen reader support
- Focus management and mobile accessibility
When to read: Building accessible carousels or implementing keyboard navigation.
Image Optimization
📄 Read: references/image-optimization.md
- Loading carousel images in WebP format
- Performance benefits and file size reduction
- Image format conversion techniques
- Implementation with carousel items
When to read: Optimizing carousel performance or implementing modern image formats.
Quick Start Example
Minimal working carousel with 5 images:
import { CarouselComponent, CarouselItemsDirective, CarouselItemDirective } from "@syncfusion/ej2-react-navigations";
import * as React from "react";
const App = () => {
return (
<div className='control-container'>
<CarouselComponent>
<CarouselItemsDirective>
<CarouselItemDirective template='<figure class="img-container"><img src="url" alt="cardinal" style="height:100%;width:100%;" /><figcaption class="img-caption">Cardinal</figcaption></figure>' />
<CarouselItemDirective template='<figure class="img-container"><img src="url" alt="kingfisher" style="height:100%;width:100%;" /><figcaption class="img-caption">Kingfisher</figcaption></figure>' />
<CarouselItemDirective template='<figure class="img-container"><img src="url" alt="toucan" style="height:100%;width:100%;" /><figcaption class="img-caption">Toucan</figcaption></figure>' />
<CarouselItemDirective template='<figure class="img-container"><img src="url" alt="warbler" style="height:100%;width:100%;" /><figcaption class="img-caption">Warbler</figcaption></figure>' />
<CarouselItemDirective template='<figure class="img-container"><img src="url" alt="bee-eater" style="height:100%;width:100%;" /><figcaption class="img-caption">Bee-eater</figcaption></figure>' />
</CarouselItemsDirective>
</CarouselComponent>
</div>
);
}
export default App;Common Patterns
Pattern 1: Auto-Play Gallery with Indicators and Navigators
<CarouselComponent autoPlay={true} showIndicators={true} buttonsVisibility="Visible">
<CarouselItemsDirective>
{/* items */}
</CarouselItemsDirective>
</CarouselComponent>Pattern 2: Data-Driven Carousel with Dynamic Content
const itemTemplate = (props: any): JSX.Element => {
return <img src={props.imageUrl} alt={props.title} />;
}
<CarouselComponent dataSource={carouselData} itemTemplate={itemTemplate} />Pattern 3: Carousel with Custom Navigation Buttons
const nextButtonTemplate = (props: any): JSX.Element => {
return <ButtonComponent iconCss="e-icons e-chevron-right" />;
}
<CarouselComponent nextButtonTemplate={nextButtonTemplate} />Pattern 4: Touch-Enabled Mobile Carousel
<CarouselComponent
enableTouchSwipe={true}
swipeMode={CarouselSwipeMode.Touch & CarouselSwipeMode.Mouse}
pauseOnHover={true}
>
{/* items */}
</CarouselComponent>API Properties Overview
Core Display Properties:
dataSource- Bind carousel to external dataitemTemplate- Template for data-bound itemsitems- Collection of CarouselItemModelselectedIndex- Current slide index
Animation & Behavior:
animationEffect- Animation type (None, Slide, Fade, Custom)interval- Transition delay in milliseconds (default: 5000)autoPlay- Enable auto-play (default: false)loop- Loop slides infinitely (default: true)pauseOnHover- Pause on hover (default: true)enableTouchSwipe- Enable touch swiping (default: true)swipeMode- Touch/mouse swipe modes (Touch, Mouse)
UI Controls:
buttonsVisibility- Navigator buttons (Hidden, Visible, VisibleOnHover)showIndicators- Show indicators (default: true)showPlayButton- Show play/pause button (default: false)indicatorsType- Indicator style (Default, Dynamic, Fraction, Progress)
Customization:
previousButtonTemplate- Previous button UInextButtonTemplate- Next button UIplayButtonTemplate- Play/pause button UIindicatorsTemplate- Indicators UIcssClass- Custom CSS classespartialVisible- Show adjacent slides (default: false)allowKeyboardInteraction- Keyboard navigation (default: true)
Layout & Localization:
height- Component height (pixels/percentage)width- Component width (pixels/percentage)enableRtl- Right-to-left supportenablePersistence- Persist state between reloadslocale- Culture/localization settinghtmlAttributes- Custom HTML attributes
Common Use Cases
1. Product Gallery (E-Commerce)
- Display product images with fade animation
- Show indicators to indicate available images
- Enable swipe for mobile users
- See: populating-items.md + animations-and-transitions.md
2. Testimonial/Review Carousel
- Auto-play testimonials with 10-second intervals
- Custom testimonial template
- Pause on hover to allow reading
- See: populating-items.md + animations-and-transitions.md
3. Accessible Banner Carousel
- Keyboard navigation with Home/End/Arrow keys
- WCAG 2.2 compliant structure
- Screen reader friendly labels
- See: accessibility.md
4. Styled Hero Carousel
- Custom navigator and indicator styling
- Partial visible slides for context
- Theme Studio customization
- See: styling-and-appearance.md + navigators-and-indicators.md
5. Data-Bound Carousel
- Bind carousel to REST API data
- Dynamic templates based on item properties
- Real-time updates
- See: populating-items.md
Complete API Reference
API Properties Reference
📄 Read: references/api-properties.md
Comprehensive documentation for all 28+ carousel properties organized by functionality:
- Core Data & Selection: dataSource, itemTemplate, items, selectedIndex
- Animation & Timing: animationEffect, interval, autoPlay, loop, pauseOnHover
- Navigation & Indicators: buttonsVisibility, showIndicators, indicatorsType, showPlayButton
- Template & Customization: Button/indicator templates, cssClass, partialVisible
- Interaction & Accessibility: enableTouchSwipe, swipeMode, allowKeyboardInteraction
- Layout & Localization: height, width, enableRtl, enablePersistence, locale, htmlAttributes
Each property includes type information, default values, and practical code examples.
API Methods Reference
📄 Read: references/api-methods.md
Complete documentation for all carousel control methods:
- `next()` - Navigate to next slide with loop support
- `prev()` - Navigate to previous slide with loop support
- `getHostElement()` - Access underlying carousel DOM element
Includes method signatures, use cases, practical examples, and advanced patterns like skip multiple slides, go to specific slide, and scroll-to-carousel functionality.
API Events Reference
📄 Read: references/api-events.md
Comprehensive event documentation with complete event arguments:
- `slideChanging` - Fires BEFORE transition (cancelable)
- Arguments: cancel, currentIndex, currentSlide, nextIndex, nextSlide, isSwiped, name, slideDirection
- Use cases: Validation, confirmation dialogs, preventing access to specific slides
- `slideChanged` - Fires AFTER transition (not cancelable)
- Arguments: currentIndex, currentSlide, previousIndex, previousSlide, isSwiped, name, slideDirection
- Use cases: Analytics tracking, updating UI counters, loading content, triggering animations
Includes practical examples for rate limiting, history tracking, analytics integration, and event pattern library.
Next Steps
1. Start here: Read getting-started.md to install and configure 2. Add content: Follow populating-items.md for your data 3. Customize UI: Use navigators-and-indicators.md for controls 4. Enhance behavior: Reference animations-and-transitions.md for effects 5. Polish design: Apply styling-and-appearance.md for styling 6. Ensure access: Implement accessibility.md for compliance 7. Optimize images: Use image-optimization.md for performance
Accessibility
The Carousel component is built with accessibility standards in mind, following WAI-ARIA specifications and providing comprehensive keyboard navigation support.
Table of Contents
- Accessibility Compliance
- ARIA Attributes
- Keyboard Interaction
- Keyboard Shortcuts Reference
- Screen Reader Support
- Setting Up Application-Level Keyboard Focus
- Right-to-Left (RTL) Support
- Color Contrast
- Mobile Device Accessibility
- Example: Fully Accessible Carousel
- Testing for Accessibility
- Common Accessibility Issues and Solutions
Accessibility Compliance
| Accessibility Criteria | Support |
|---|---|
| WCAG 2.2 | ✓ Full |
| Section 508 | ✓ Full |
| Screen Reader Support | ✓ Full |
| Right-To-Left (RTL) Support | ✓ Full |
| Color Contrast | ✓ Full |
| Mobile Device Support | ✓ Full |
| Keyboard Navigation | ✓ Full |
| Accessibility Checker Validation | ✓ Full |
| Axe-core Accessibility Validation | ✓ Full |
ARIA Attributes
The Carousel component automatically includes the following ARIA attributes for assistive technology support:
| Attribute | Usage |
|---|---|
aria-roledescription | Describes the Carousel role and each slide as "slide" |
aria-label | Labels for previous, next, and play/pause buttons |
aria-current | Set to true for the active slide indicator |
aria-hidden | Set to true for non-visible slides |
aria-live | Set to off when autoPlay is enabled; polite when disabled |
aria-role | Set to "group" for Carousel slide items |
These attributes are automatically applied—no additional configuration needed.
Keyboard Interaction
All Carousel actions are fully controllable via keyboard. Enable or disable keyboard interaction with the allowKeyboardInteraction property:
// Enable keyboard navigation (default)
<CarouselComponent allowKeyboardInteraction={true}>
{/* items */}
</CarouselComponent>
// Disable if carousel contains form inputs
<CarouselComponent allowKeyboardInteraction={false}>
{/* items */}
</CarouselComponent>Disable keyboard interaction when: Your carousel contains text inputs or form controls, as arrow keys might trigger unwanted navigation.
Keyboard Shortcuts Reference
Once the Carousel element has focus, use these keyboard shortcuts:
| Key | Action |
|---|---|
| <kbd>Alt + J</kbd> | Focus the Carousel component (set up at application level) |
| <kbd>←</kbd> Arrow Left | Navigate to previous slide |
| <kbd>→</kbd> Arrow Right | Navigate to next slide |
| <kbd>Home</kbd> | Jump to first slide |
| <kbd>End</kbd> | Jump to last slide |
| <kbd>Space</kbd> | Toggle play/pause auto-play |
| <kbd>Enter</kbd> | Perform action on focused element |
| <kbd>Tab</kbd> | Move focus to next interactive element |
| <kbd>Shift + Tab</kbd> | Move focus to previous interactive element |
Screen Reader Support
The Carousel announces:
- Slide position when auto-play is disabled
- Current slide changes
- Navigator and indicator button purposes
- All interactive elements with appropriate labels
Best practices for screen reader users:
- Always include descriptive alt text in slide images
- Use semantic HTML in slide templates
- Provide meaningful button labels
- Test with NVDA (Windows), JAWS, or VoiceOver (Mac)
Setting Up Application-Level Keyboard Focus
Configure Alt + J to focus the Carousel at the application level:
import { CarouselComponent, CarouselItemsDirective, CarouselItemDirective } from "@syncfusion/ej2-react-navigations";
import { useRef } from "react";
import * as React from "react";
const App = () => {
const carouselRef = useRef<CarouselComponent>(null);
React.useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => {
if (e.altKey && e.key === 'j') {
// Focus carousel on Alt + J
const carouselElement = carouselRef.current?.getHostElement();
carouselElement?.focus();
}
};
window.addEventListener('keydown', handleKeyDown);
return () => window.removeEventListener('keydown', handleKeyDown);
}, []);
return (
<div>
<CarouselComponent ref={carouselRef} tabIndex={0}>
<CarouselItemsDirective>
<CarouselItemDirective template='<h3>Slide 1</h3>' />
<CarouselItemDirective template='<h3>Slide 2</h3>' />
<CarouselItemDirective template='<h3>Slide 3</h3>' />
</CarouselItemsDirective>
</CarouselComponent>
</div>
);
}
export default App;Right-to-Left (RTL) Support
The Carousel automatically adapts to RTL languages. Enable RTL at the component or application level:
Component-Level RTL
<CarouselComponent enableRtl={true}>
{/* items */}
</CarouselComponent>Application-Level RTL
document.documentElement.dir = 'rtl';RTL Behavior:
- Arrow keys reverse (← moves right, → moves left)
- Previous button appears on right, next on left
- Indicators remain centered but flow right-to-left
- Text direction reverses within slide templates
Color Contrast
The Carousel uses sufficient color contrast (4.5:1 or higher) for all text and interactive elements by default. When customizing colors, ensure:
/* ✓ Good contrast (4.5:1) */
.e-carousel-indicators .e-indicator {
background-color: rgba(0, 0, 0, 0.5); /* Dark background */
color: white; /* Light text */
}
/* ✗ Poor contrast (2:1) */
.e-carousel-indicators .e-indicator {
background-color: #999; /* Medium gray */
color: #bbb; /* Light gray - insufficient contrast */
}Use tools like WebAIM Contrast Checker to verify custom colors.
Mobile Device Accessibility
The Carousel supports touch-based navigation for mobile users:
<CarouselComponent
enableTouchSwipe={true} // Allow swipe gestures
buttonsVisibility="Visible" // Large buttons for touch
swipeMode={CarouselSwipeMode.Touch & CarouselSwipeMode.Mouse}
>
{/* items */}
</CarouselComponent>Mobile considerations:
- Use larger touch targets (min 44×44 pixels)
- Provide visible navigation buttons (VisibleOnHover doesn't work on touch)
- Test with mobile screen readers (VoiceOver on iOS, TalkBack on Android)
Example: Fully Accessible Carousel
import { CarouselComponent, CarouselItemsDirective, CarouselItemDirective } from "@syncfusion/ej2-react-navigations";
import { useRef } from "react";
import * as React from "react";
const AccessibleCarousel = () => {
const carouselRef = useRef<CarouselComponent>(null);
return (
<div>
<h2>Image Gallery</h2>
<CarouselComponent
ref={carouselRef}
tabIndex={0}
allowKeyboardInteraction={true}
enableRtl={false}
enableTouchSwipe={true}
buttonsVisibility="Visible"
showIndicators={true}
showPlayButton={false} // Simplifies for screen readers
>
<CarouselItemsDirective>
<CarouselItemDirective
template='<figure><img src="image1.jpg" alt="Mountain landscape at sunset" style="width:100%;height:100%;" /><figcaption>Mountain Landscape</figcaption></figure>'
/>
<CarouselItemDirective
template='<figure><img src="image2.jpg" alt="Ocean waves with seagulls" style="width:100%;height:100%;" /><figcaption>Ocean Waves</figcaption></figure>'
/>
<CarouselItemDirective
template='<figure><img src="image3.jpg" alt="Forest path with tall trees" style="width:100%;height:100%;" /><figcaption>Forest Path</figcaption></figure>'
/>
</CarouselItemsDirective>
</CarouselComponent>
<p>Use arrow keys or tab to navigate. Press Enter to interact.</p>
</div>
);
}
export default AccessibleCarousel;Testing for Accessibility
Manual Testing Checklist
- [ ] Tab through all interactive elements (buttons, indicators)
- [ ] Keyboard navigation works (arrows, Home, End, Space)
- [ ] Focus indicator clearly visible
- [ ] Screen reader announces slide changes
- [ ] Color contrast passes WCAG AA (4.5:1)
- [ ] Touch targets min 44×44 pixels on mobile
Automated Testing Tools
- axe-core: Browser extension for accessibility scanning
- Accessibility Checker: Chrome extension
- WAVE: Web accessibility evaluation tool
- Lighthouse: Chrome DevTools built-in audit
Common Accessibility Issues and Solutions
| Issue | Cause | Solution |
|---|---|---|
| Keyboard focus lost | Focus not managed | Use tabIndex={0} on Carousel |
| Screen reader silent | ARIA attributes missing | Use component defaults; don't override |
| Low contrast buttons | Custom CSS override | Verify 4.5:1 ratio with WCAG tool |
| Touch targets too small | CSS sizing | Min 44×44 pixels on mobile |
| Auto-play too fast | autoPlay with short interval | Use 5+ second intervals |
Animations and Transitions
Table of Contents
- Animation Effects
- Setting Intervals Between Slides
- Auto Play Configuration
- Pause on Hover
- Looping Slides
- Slide Changing Events
- Touch Swipe Control
- Swipe Modes
Animation Effects
The animationEffect property controls the visual transition between slides.
Fade Animation
Slides fade out and fade in for a smooth transition:
import { CarouselComponent, CarouselItemsDirective, CarouselItemDirective } from "@syncfusion/ej2-react-navigations";
import * as React from "react";
const App = () => {
return (
<div className='control-container'>
<CarouselComponent animationEffect="Fade">
<CarouselItemsDirective>
<CarouselItemDirective template='<h3>Slide 1</h3>' />
<CarouselItemDirective template='<h3>Slide 2</h3>' />
<CarouselItemDirective template='<h3>Slide 3</h3>' />
<CarouselItemDirective template='<h3>Slide 4</h3>' />
<CarouselItemDirective template='<h3>Slide 5</h3>' />
</CarouselItemsDirective>
</CarouselComponent>
</div>
);
}
export default App;Slide Animation (Default)
Slides move horizontally across the carousel area (default behavior):
<CarouselComponent animationEffect="Slide">
{/* items */}
</CarouselComponent>Or omit the prop entirely since "Slide" is the default.
Custom Animation
Define custom CSS animations using the Custom effect with CSS class:
<CarouselComponent animationEffect="Custom" cssClass="parallax">
<CarouselItemsDirective>
<CarouselItemDirective template='<h3>Slide 1</h3>' />
<CarouselItemDirective template='<h3>Slide 2</h3>' />
<CarouselItemDirective template='<h3>Slide 3</h3>' />
</CarouselItemsDirective>
</CarouselComponent>Define your CSS animations in your stylesheet:
.e-carousel.parallax .e-carousel-item {
animation: parallaxMove 0.5s ease-in-out;
}
@keyframes parallaxMove {
0% {
transform: translateX(100%) rotateY(30deg);
opacity: 0;
}
100% {
transform: translateX(0) rotateY(0);
opacity: 1;
}
}Setting Intervals Between Slides
Control how long each slide displays before transitioning. Intervals are specified in milliseconds.
Different Intervals Per Item
When using CarouselItem binding, each item can have its own interval:
<CarouselComponent>
<CarouselItemsDirective>
<CarouselItemDirective template='<h3>Slide 1 - 3 seconds</h3>' interval={3000} />
<CarouselItemDirective template='<h3>Slide 2 - 1 second</h3>' interval={1000} />
<CarouselItemDirective template='<h3>Slide 3 - 2 seconds</h3>' interval={2000} />
<CarouselItemDirective template='<h3>Slide 4 - 5 seconds</h3>' interval={5000} />
<CarouselItemDirective template='<h3>Slide 5 - 6 seconds</h3>' interval={6000} />
</CarouselItemsDirective>
</CarouselComponent>Default interval: 5000 ms (5 seconds)
Auto Play Configuration
Enable Auto Play
Slides transition automatically using the autoPlay property:
import { CarouselComponent, CarouselItemsDirective, CarouselItemDirective } from "@syncfusion/ej2-react-navigations";
import * as React from "react";
const App = () => {
return (
<div className='control-container'>
<CarouselComponent autoPlay={true}>
<CarouselItemsDirective>
<CarouselItemDirective template='<h3>Slide 1</h3>' />
<CarouselItemDirective template='<h3>Slide 2</h3>' />
<CarouselItemDirective template='<h3>Slide 3</h3>' />
<CarouselItemDirective template='<h3>Slide 4</h3>' />
<CarouselItemDirective template='<h3>Slide 5</h3>' />
</CarouselItemsDirective>
</CarouselComponent>
</div>
);
}
export default App;Default: autoPlay={false}
Disable Auto Play
<CarouselComponent autoPlay={false}>
{/* Manual navigation only */}
</CarouselComponent>Pause on Hover
By default, auto-play pauses when the user hovers over the carousel. Control this with pauseOnHover:
Enable Pause on Hover (Default)
<CarouselComponent autoPlay={true} pauseOnHover={true}>
{/* Auto-play stops on hover, resumes when mouse leaves */}
</CarouselComponent>Disable Pause on Hover
Keep auto-play running even when hovering:
import { CarouselComponent, CarouselItemsDirective, CarouselItemDirective } from "@syncfusion/ej2-react-navigations";
import * as React from "react";
const App = () => {
return (
<div className='control-container'>
<CarouselComponent pauseOnHover={false}>
<CarouselItemsDirective>
<CarouselItemDirective template='<h3>Slide 1</h3>' />
<CarouselItemDirective template='<h3>Slide 2</h3>' />
<CarouselItemDirective template='<h3>Slide 3</h3>' />
<CarouselItemDirective template='<h3>Slide 4</h3>' />
<CarouselItemDirective template='<h3>Slide 5</h3>' />
</CarouselItemsDirective>
</CarouselComponent>
</div>
);
}
export default App;Looping Slides
Control whether slides repeat infinitely or stop at the end.
Enable Loop (Default)
<CarouselComponent loop={true}>
{/* After last slide, returns to first slide */}
</CarouselComponent>Disable Loop
import { CarouselComponent, CarouselItemsDirective, CarouselItemDirective } from "@syncfusion/ej2-react-navigations";
import * as React from "react";
const App = () => {
return (
<div className='control-container'>
<CarouselComponent loop={false}>
<CarouselItemsDirective>
<CarouselItemDirective template='<h3>Slide 1</h3>' />
<CarouselItemDirective template='<h3>Slide 2</h3>' />
<CarouselItemDirective template='<h3>Slide 3</h3>' />
</CarouselItemsDirective>
</CarouselComponent>
</div>
);
}
export default App;Behavior:
- With
loop={true}: Next button on last slide goes to first slide - With
loop={false}: Next button disabled on last slide; auto-play stops
Slide Changing Events
Listen to slide transitions using slideChanging and slideChanged events:
import { CarouselComponent, CarouselItemsDirective, CarouselItemDirective, SlideChangingEventArgs, SlideChangedEventArgs } from '@syncfusion/ej2-react-navigations';
import * as React from 'react';
const App = () => {
const onSlideChanging = (args: SlideChangingEventArgs): void => {
console.log('About to change to slide:', args.nextSlide);
// Perform actions before slide change (preload images, etc.)
}
const onSlideChanged = (args: SlideChangedEventArgs): void => {
console.log('Changed to slide:', args.currentSlide);
// Perform actions after slide change (update UI, log analytics, etc.)
}
return (
<div className='control-container'>
<CarouselComponent slideChanging={onSlideChanging} slideChanged={onSlideChanged}>
<CarouselItemsDirective>
<CarouselItemDirective template='<h3>Slide 1</h3>' />
<CarouselItemDirective template='<h3>Slide 2</h3>' />
<CarouselItemDirective template='<h3>Slide 3</h3>' />
<CarouselItemDirective template='<h3>Slide 4</h3>' />
<CarouselItemDirective template='<h3>Slide 5</h3>' />
</CarouselItemsDirective>
</CarouselComponent>
</div>
);
}
export default App;Event Properties:
args.currentSlide- Current slide indexargs.nextSlide- Next slide index (in slideChanging)
Touch Swipe Control
Enable or disable touch swipe gestures using the enableTouchSwipe property:
Enable Touch Swipe (Default)
<CarouselComponent enableTouchSwipe={true}>
{/* Users can swipe left/right to navigate */}
</CarouselComponent>Disable Touch Swipe
import { CarouselComponent, CarouselItemsDirective, CarouselItemDirective } from "@syncfusion/ej2-react-navigations";
import * as React from "react";
const App = () => {
return (
<div className='control-container'>
<CarouselComponent enableTouchSwipe={false}>
<CarouselItemsDirective>
<CarouselItemDirective template='<h3>Slide 1</h3>' />
<CarouselItemDirective template='<h3>Slide 2</h3>' />
<CarouselItemDirective template='<h3>Slide 3</h3>' />
<CarouselItemDirective template='<h3>Slide 4</h3>' />
<CarouselItemDirective template='<h3>Slide 5</h3>' />
</CarouselItemsDirective>
</CarouselComponent>
</div>
);
}
export default App;Swipe Modes
The swipeMode property defines which input types trigger slide transitions using bitwise operators:
Touch Only
import { CarouselComponent, CarouselItemsDirective, CarouselItemDirective, CarouselSwipeMode } from "@syncfusion/ej2-react-navigations";
import * as React from "react";
const App = () => {
return (
<div className='control-container'>
<CarouselComponent swipeMode={CarouselSwipeMode.Touch}>
{/* Touch gestures work, mouse drag does not */}
</CarouselComponent>
</div>
);
}
export default App;Mouse Only
<CarouselComponent swipeMode={CarouselSwipeMode.Mouse}>
{/* Mouse drag works, touch gestures do not */}
</CarouselComponent>Touch and Mouse
<CarouselComponent swipeMode={CarouselSwipeMode.Touch & CarouselSwipeMode.Mouse}>
{/* Both touch and mouse drag work */}
</CarouselComponent>Disable Both
<CarouselComponent swipeMode={~CarouselSwipeMode.Touch & ~CarouselSwipeMode.Mouse}>
{/* No swipe/drag navigation */}
</CarouselComponent>Note: Swipe mode is separate from button navigation. Disabling swipe modes doesn't affect prev/next buttons or keyboard navigation.
Best Practices
- Auto-play: Use 5-10 seconds per slide for readability
- Animations: Fade for clean transitions, Slide for directional clarity
- Mobile: Enable touch swipe with "Touch" or "Touch & Mouse" mode
- Events: Use slideChanged for analytics, slideChanging for validation
- Loop: Disable for ordered content; enable for decorative galleries
Carousel API Events
Complete reference for carousel events that fire during slide transitions and user interactions.
Table of Contents
---
slideChanging Event
Fires BEFORE a slide transition occurs. This event is cancelable - you can prevent the transition by setting args.cancel = true.
Use Cases:
- Validate before allowing slide change
- Show confirmation dialogs
- Prevent certain slides from being accessed
- Log slide change attempts
- Disable transitions during animations
Event Signature:
slideChanging?(args: SlideChangingEventArgs): voidEvent Arguments (SlideChangingEventArgs):
| Property | Type | Description |
|---|---|---|
| cancel | boolean | Set to true to prevent the transition (cancelable) |
| currentIndex | number | Index of the currently displayed slide |
| currentSlide | HTMLElement | HTML element of the current slide |
| nextIndex | number | Index of the slide about to be displayed |
| nextSlide | HTMLElement | HTML element of the next slide |
| isSwiped | boolean | true if transition triggered by swipe gesture, false if button/keyboard |
| name | string | Event name: 'slideChanging' |
| slideDirection | CarouselSlideDirection | Direction of transition: 'Previous' or 'Next' |
Basic Example:
import { CarouselComponent, CarouselItemsDirective, CarouselItemDirective,
SlideChangingEventArgs } from '@syncfusion/ej2-react-navigations';
import * as React from 'react';
const App = () => {
const onSlideChanging = (args: SlideChangingEventArgs): void => {
console.log(`About to change from slide ${args.currentIndex} to ${args.nextIndex}`);
console.log(`Direction: ${args.slideDirection}`);
console.log(`From swipe: ${args.isSwiped}`);
};
return (
<CarouselComponent slideChanging={onSlideChanging}>
<CarouselItemsDirective>
<CarouselItemDirective template='<h3>Slide 1</h3>' />
<CarouselItemDirective template='<h3>Slide 2</h3>' />
<CarouselItemDirective template='<h3>Slide 3</h3>' />
</CarouselItemsDirective>
</CarouselComponent>
);
};
export default App;Example - Prevent transition to specific slide:
const onSlideChanging = (args: SlideChangingEventArgs): void => {
// Don't allow transition to slide 3 (index 2)
if (args.nextIndex === 2) {
args.cancel = true;
alert('This slide is currently disabled');
}
};Example - Confirm before advancing:
const onSlideChanging = (args: SlideChangingEventArgs): void => {
// Only when swiping, not button clicks
if (args.isSwiped && args.slideDirection === 'Next') {
const confirmed = window.confirm(
`Move from slide ${args.currentIndex + 1} to ${args.nextIndex + 1}?`
);
if (!confirmed) {
args.cancel = true;
}
}
};Example - Disable swipe but allow buttons:
const onSlideChanging = (args: SlideChangingEventArgs): void => {
// Prevent swipe navigation only
if (args.isSwiped) {
args.cancel = true;
}
};Example - Rate limiting transitions:
const [isTransitioning, setIsTransitioning] = React.useState(false);
const onSlideChanging = (args: SlideChangingEventArgs): void => {
if (isTransitioning) {
args.cancel = true; // Prevent rapid transitions
return;
}
setIsTransitioning(true);
// Allow transition to complete
setTimeout(() => {
setIsTransitioning(false);
}, 500);
};---
slideChanged Event
Fires AFTER a slide transition is complete. This event is not cancelable - the slide has already changed.
Use Cases:
- Track slide view analytics
- Update external UI elements (page counter, indicators)
- Load additional content for the slide
- Trigger animations or effects
- Update page title/URL
- Auto-play related content
Event Signature:
slideChanged?(args: SlideChangedEventArgs): voidEvent Arguments (SlideChangedEventArgs):
| Property | Type | Description |
|---|---|---|
| currentIndex | number | Index of the newly displayed slide |
| currentSlide | HTMLElement | HTML element of the currently displayed slide |
| previousIndex | number | Index of the slide that was just left |
| previousSlide | HTMLElement | HTML element of the previous slide |
| isSwiped | boolean | true if transition was a swipe gesture, false if button/keyboard |
| name | string | Event name: 'slideChanged' |
| slideDirection | CarouselSlideDirection | Direction of transition: 'Previous' or 'Next' |
Basic Example:
import { CarouselComponent, CarouselItemsDirective, CarouselItemDirective,
SlideChangedEventArgs } from '@syncfusion/ej2-react-navigations';
import * as React from 'react';
const App = () => {
const onSlideChanged = (args: SlideChangedEventArgs): void => {
console.log(`Now viewing slide ${args.currentIndex}`);
console.log(`Previous was slide ${args.previousIndex}`);
console.log(`Navigation type: ${args.isSwiped ? 'Swipe' : 'Button/Keyboard'}`);
};
return (
<CarouselComponent slideChanged={onSlideChanged}>
<CarouselItemsDirective>
<CarouselItemDirective template='<h3>Slide 1</h3>' />
<CarouselItemDirective template='<h3>Slide 2</h3>' />
<CarouselItemDirective template='<h3>Slide 3</h3>' />
</CarouselItemsDirective>
</CarouselComponent>
);
};
export default App;Example - Update slide counter:
const [slideCount, setSlideCount] = React.useState('1/3');
const onSlideChanged = (args: SlideChangedEventArgs): void => {
const totalSlides = 3; // or get from carousel
setSlideCount(`${args.currentIndex + 1}/${totalSlides}`);
};
return (
<>
<div className="slide-counter">{slideCount}</div>
<CarouselComponent slideChanged={onSlideChanged}>
{/* items */}
</CarouselComponent>
</>
);Example - Track analytics:
const onSlideChanged = (args: SlideChangedEventArgs): void => {
// Log to analytics service
trackEvent('carousel_slide_viewed', {
slideIndex: args.currentIndex,
previousIndex: args.previousIndex,
direction: args.slideDirection,
interactionType: args.isSwiped ? 'swipe' : 'button'
});
};Example - Load additional content for slide:
const onSlideChanged = (args: SlideChangedEventArgs): void => {
// Preload content for next slide
const nextIndex = (args.currentIndex + 1) % 3;
loadSlideContent(nextIndex);
// Lazy load images in current slide
const images = args.currentSlide.querySelectorAll('img[data-src]');
images.forEach(img => {
img.src = img.getAttribute('data-src');
});
};Example - Trigger animations:
const onSlideChanged = (args: SlideChangedEventArgs): void => {
// Add animation class to current slide
args.currentSlide.classList.add('fade-in-animation');
// Remove animation from previous slide
args.previousSlide.classList.remove('fade-in-animation');
args.previousSlide.classList.add('fade-out-animation');
};---
Event Arguments
SlideChangingEventArgs
Structure for slideChanging event:
interface SlideChangingEventArgs {
cancel: boolean; // Set true to prevent transition
currentIndex: number; // Currently displayed slide index
currentSlide: HTMLElement; // Current slide element
nextIndex: number; // Next slide index (about to display)
nextSlide: HTMLElement; // Next slide element
isSwiped: boolean; // true = swipe, false = button/keyboard
name: string; // 'slideChanging'
slideDirection: CarouselSlideDirection; // 'Previous' or 'Next'
}SlideChangedEventArgs
Structure for slideChanged event:
interface SlideChangedEventArgs {
currentIndex: number; // New slide index (now displayed)
currentSlide: HTMLElement; // Current slide element
previousIndex: number; // Previous slide index (just left)
previousSlide: HTMLElement; // Previous slide element
isSwiped: boolean; // true = swipe, false = button/keyboard
name: string; // 'slideChanged'
slideDirection: CarouselSlideDirection; // 'Previous' or 'Next'
}CarouselSlideDirection
Enum for slide transition direction:
type CarouselSlideDirection = 'Previous' | 'Next';---
Complete Event Example
Full working example demonstrating both events:
import { CarouselComponent, CarouselItemsDirective, CarouselItemDirective,
SlideChangingEventArgs, SlideChangedEventArgs } from '@syncfusion/ej2-react-navigations';
import * as React from 'react';
import './carousel-events.css';
interface SlideHistory {
timestamp: string;
from: number;
to: number;
direction: string;
type: string;
}
const CarouselEventsDemo = () => {
const carouselRef = React.useRef<CarouselComponent>(null);
const [currentSlide, setCurrentSlide] = React.useState(1);
const [totalSlides] = React.useState(5);
const [history, setHistory] = React.useState<SlideHistory[]>([]);
const [status, setStatus] = React.useState('Ready');
const [allowTransition, setAllowTransition] = React.useState(true);
const onSlideChanging = (args: SlideChangingEventArgs): void => {
const timestamp = new Date().toLocaleTimeString();
// Example 1: Rate limiting - prevent rapid transitions
if (!allowTransition) {
args.cancel = true;
setStatus('⏱️ Please wait for transition to complete');
return;
}
// Example 2: Prevent specific slides
if (args.nextIndex === 4) {
args.cancel = true;
setStatus('❌ Slide 5 is currently disabled');
return;
}
setStatus(`🔄 Changing from slide ${args.currentIndex + 1} to ${args.nextIndex + 1}...`);
// Disable transitions during animation
setAllowTransition(false);
};
const onSlideChanged = (args: SlideChangedEventArgs): void => {
const timestamp = new Date().toLocaleTimeString();
// Update slide counter
setCurrentSlide(args.currentIndex + 1);
// Update status
const navType = args.isSwiped ? 'Swipe' : args.slideDirection === 'Next' ? 'Next Button' : 'Prev Button';
setStatus(`✅ Now viewing slide ${args.currentIndex + 1} (${navType})`);
// Add to history
const newEntry: SlideHistory = {
timestamp,
from: args.previousIndex,
to: args.currentIndex,
direction: args.slideDirection,
type: args.isSwiped ? 'Swipe' : 'Button'
};
setHistory(prev => [newEntry, ...prev.slice(0, 9)]);
// Re-enable transitions
setTimeout(() => {
setAllowTransition(true);
}, 500);
};
return (
<div className="carousel-events-demo">
<div className="header">
<h2>Carousel Events Demo</h2>
<p className="status">{status}</p>
</div>
<div className="carousel-section">
<CarouselComponent
ref={carouselRef}
loop={true}
showIndicators={true}
buttonsVisibility="Visible"
slideChanging={onSlideChanging}
slideChanged={onSlideChanged}
>
<CarouselItemsDirective>
<CarouselItemDirective template='<div class="slide slide-1"><h3>Slide 1</h3><p>Navigate forward</p></div>' />
<CarouselItemDirective template='<div class="slide slide-2"><h3>Slide 2</h3><p>Go to next</p></div>' />
<CarouselItemDirective template='<div class="slide slide-3"><h3>Slide 3</h3><p>Continue</p></div>' />
<CarouselItemDirective template='<div class="slide slide-4"><h3>Slide 4</h3><p>Almost there</p></div>' />
<CarouselItemDirective template='<div class="slide slide-5"><h3>Slide 5</h3><p>This slide is disabled</p></div>' />
</CarouselItemsDirective>
</CarouselComponent>
</div>
<div className="info-panel">
<div className="slide-counter">
<h3>Current Position</h3>
<p className="counter">{currentSlide} / {totalSlides}</p>
</div>
<div className="history-panel">
<h3>Navigation History (Last 10)</h3>
<div className="history-list">
{history.length === 0 ? (
<p className="no-history">No navigation yet</p>
) : (
<table className="history-table">
<thead>
<tr>
<th>Time</th>
<th>From</th>
<th>To</th>
<th>Direction</th>
<th>Type</th>
</tr>
</thead>
<tbody>
{history.map((entry, idx) => (
<tr key={idx}>
<td>{entry.timestamp}</td>
<td>{entry.from + 1}</td>
<td>{entry.to + 1}</td>
<td>{entry.direction}</td>
<td><span className={`type-badge ${entry.type.toLowerCase()}`}>{entry.type}</span></td>
</tr>
))}
</tbody>
</table>
)}
</div>
</div>
</div>
<div className="notes">
<h4>Event Demo Features:</h4>
<ul>
<li><strong>slideChanging event:</strong> Fires before transition - can cancel slide 5</li>
<li><strong>slideChanged event:</strong> Fires after transition - updates history</li>
<li><strong>Rate limiting:</strong> Waits 500ms between transitions</li>
<li><strong>Navigation tracking:</strong> Records swipes vs button clicks</li>
<li><strong>History logging:</strong> Shows last 10 navigation events</li>
</ul>
</div>
</div>
);
};
export default CarouselEventsDemo;CSS (carousel-events.css):
.carousel-events-demo {
padding: 20px;
max-width: 1000px;
margin: 0 auto;
font-family: Arial, sans-serif;
}
.header {
text-align: center;
margin-bottom: 30px;
}
.header h2 {
margin: 0 0 10px 0;
color: #333;
}
.status {
font-size: 16px;
color: #666;
padding: 10px;
background: #f0f0f0;
border-radius: 4px;
min-height: 20px;
}
.carousel-section {
margin: 30px 0;
border: 2px solid #ddd;
border-radius: 8px;
overflow: hidden;
}
.slide {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 300px;
color: white;
font-size: 20px;
text-align: center;
}
.slide-1 { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); }
.slide-2 { background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); }
.slide-3 { background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); }
.slide-4 { background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%); }
.slide-5 { background: linear-gradient(135deg, #fa709a 0%, #fee140 100%); }
.slide h3 {
margin: 0 0 10px 0;
font-size: 32px;
}
.slide p {
margin: 0;
font-size: 14px;
opacity: 0.9;
}
.info-panel {
display: grid;
grid-template-columns: 200px 1fr;
gap: 20px;
margin-top: 30px;
}
.slide-counter {
background: #f9f9f9;
border: 1px solid #ddd;
border-radius: 4px;
padding: 20px;
text-align: center;
}
.slide-counter h3 {
margin: 0 0 10px 0;
color: #333;
font-size: 14px;
}
.counter {
font-size: 48px;
font-weight: bold;
color: #007bff;
margin: 0;
}
.history-panel {
background: #f9f9f9;
border: 1px solid #ddd;
border-radius: 4px;
padding: 20px;
}
.history-panel h3 {
margin: 0 0 15px 0;
color: #333;
font-size: 14px;
}
.history-table {
width: 100%;
border-collapse: collapse;
font-size: 13px;
}
.history-table thead {
background: #f0f0f0;
border-bottom: 2px solid #ddd;
}
.history-table th {
padding: 10px;
text-align: left;
font-weight: bold;
color: #333;
}
.history-table td {
padding: 8px 10px;
border-bottom: 1px solid #eee;
}
.history-table tr:hover {
background: #fff;
}
.type-badge {
display: inline-block;
padding: 3px 8px;
border-radius: 3px;
font-size: 12px;
font-weight: bold;
}
.type-badge.button {
background: #007bff;
color: white;
}
.type-badge.swipe {
background: #28a745;
color: white;
}
.no-history {
color: #999;
text-align: center;
padding: 20px;
}
.notes {
background: #fffacd;
border: 1px solid #ddd;
border-radius: 4px;
padding: 20px;
margin-top: 30px;
}
.notes h4 {
margin: 0 0 15px 0;
color: #333;
}
.notes ul {
margin: 0;
padding-left: 20px;
}
.notes li {
margin: 8px 0;
color: #666;
}
@media (max-width: 768px) {
.info-panel {
grid-template-columns: 1fr;
}
.history-table {
font-size: 11px;
}
.history-table th,
.history-table td {
padding: 6px 8px;
}
}---
Common Event Patterns
Pattern 1: Validation Before Slide Change
const onSlideChanging = (args: SlideChangingEventArgs): void => {
// Example: Don't allow going back from slide 3
if (args.slideDirection === 'Previous' && args.currentIndex === 2) {
args.cancel = true;
alert('Cannot go back from this slide');
}
};Pattern 2: Loading State Management
const [isLoading, setIsLoading] = React.useState(false);
const onSlideChanging = (args: SlideChangingEventArgs): void => {
setIsLoading(true);
};
const onSlideChanged = (args: SlideChangedEventArgs): void => {
setIsLoading(false);
};Pattern 3: Analytics Tracking
const onSlideChanged = (args: SlideChangedEventArgs): void => {
// Track slide views
gtag.event('slide_view', {
slide_number: args.currentIndex + 1,
total_slides: 5,
navigation_method: args.isSwiped ? 'swipe' : 'button',
direction: args.slideDirection
});
};Pattern 4: Content Preloading
const onSlideChanged = (args: SlideChangedEventArgs): void => {
// Preload images for next slide
const nextIndex = (args.currentIndex + 1) % totalSlides;
const nextSlideImages = document.querySelectorAll(
`.carousel-item:nth-child(${nextIndex + 1}) img`
);
nextSlideImages.forEach(img => {
new Image().src = img.src; // Preload
});
};Pattern 5: Disabling Swipe Only
const onSlideChanging = (args: SlideChangingEventArgs): void => {
// Allow buttons but disable swipe
if (args.isSwiped) {
args.cancel = true;
}
};Carousel API Methods
Complete reference for all available methods to control the Carousel component programmatically.
Table of Contents
---
next() - Navigate to Next Slide
Move carousel to the next slide in sequence. Respects the loop property when reaching the last slide.
Signature:
next(): voidWhen to use:
- Custom navigation buttons
- External controls outside carousel
- Event-driven navigation
- Programmatic slide advancement
Example:
import { CarouselComponent } from '@syncfusion/ej2-react-navigations';
import * as React from 'react';
const App = () => {
const carouselRef = React.useRef<CarouselComponent>(null);
const handleNextClick = () => {
carouselRef.current?.next();
};
return (
<>
<button onClick={handleNextClick}>Next Slide</button>
<CarouselComponent ref={carouselRef}>
<CarouselItemsDirective>
<CarouselItemDirective template='<h3>Slide 1</h3>' />
<CarouselItemDirective template='<h3>Slide 2</h3>' />
<CarouselItemDirective template='<h3>Slide 3</h3>' />
</CarouselItemsDirective>
</CarouselComponent>
</>
);
};
export default App;With loop enabled (default):
// Last slide + next() → First slide
<CarouselComponent ref={carouselRef} loop={true}>
{/* next() on slide 3 goes to slide 1 */}
</CarouselComponent>With loop disabled:
// Last slide + next() → No change (stays on last slide)
<CarouselComponent ref={carouselRef} loop={false}>
{/* next() on slide 3 has no effect */}
</CarouselComponent>Advanced example - Skip to specific slide:
const goToSlide = (slideIndex: number) => {
const carouselComponent = carouselRef.current;
const currentIndex = carouselComponent?.selectedIndex || 0;
if (slideIndex > currentIndex) {
// Advance multiple slides
for (let i = currentIndex; i < slideIndex; i++) {
carouselComponent?.next();
}
}
};---
prev() - Navigate to Previous Slide
Move carousel to the previous slide in sequence. Respects the loop property when reaching the first slide.
Signature:
prev(): voidWhen to use:
- Custom back/previous buttons
- External controls outside carousel
- Event-driven backwards navigation
- Undo slide advancement
Example:
import { CarouselComponent } from '@syncfusion/ej2-react-navigations';
import * as React from 'react';
const App = () => {
const carouselRef = React.useRef<CarouselComponent>(null);
const handlePrevClick = () => {
carouselRef.current?.prev();
};
return (
<>
<button onClick={handlePrevClick}>Previous Slide</button>
<CarouselComponent ref={carouselRef}>
<CarouselItemsDirective>
<CarouselItemDirective template='<h3>Slide 1</h3>' />
<CarouselItemDirective template='<h3>Slide 2</h3>' />
<CarouselItemDirective template='<h3>Slide 3</h3>' />
</CarouselItemsDirective>
</CarouselComponent>
</>
);
};
export default App;With loop enabled (default):
// First slide + prev() → Last slide
<CarouselComponent ref={carouselRef} loop={true}>
{/* prev() on slide 1 goes to slide 3 */}
</CarouselComponent>With loop disabled:
// First slide + prev() → No change (stays on first slide)
<CarouselComponent ref={carouselRef} loop={false}>
{/* prev() on slide 1 has no effect */}
</CarouselComponent>Advanced example - Go back multiple slides:
const goBackSlides = (count: number) => {
const carouselComponent = carouselRef.current;
for (let i = 0; i < count; i++) {
carouselComponent?.prev();
}
};
// Usage
<button onClick={() => goBackSlides(3)}>Back 3 Slides</button>---
play() - Play Slides Programmatically
Resume automatic slide transitions if they are paused. Starts the carousel auto-play functionality.
Signature:
play(): voidWhen to use:
- Resume auto-play after pause
- Start slideshow programmatically
- Control auto-play with custom buttons
- Resume carousel in event handlers
Example:
import { CarouselComponent } from '@syncfusion/ej2-react-navigations';
import * as React from 'react';
const App = () => {
const carouselRef = React.useRef<CarouselComponent>(null);
const handlePlay = () => {
carouselRef.current?.play();
};
return (
<>
<button onClick={handlePlay}>Play Slideshow</button>
<CarouselComponent ref={carouselRef} autoPlay={false}>
<CarouselItemsDirective>
<CarouselItemDirective template='<h3>Slide 1</h3>' />
<CarouselItemDirective template='<h3>Slide 2</h3>' />
<CarouselItemDirective template='<h3>Slide 3</h3>' />
</CarouselItemsDirective>
</CarouselComponent>
</>
);
};
export default App;Example - Auto-start with delay:
React.useEffect(() => {
const timer = setTimeout(() => {
carouselRef.current?.play();
}, 2000); // Start after 2 seconds
return () => clearTimeout(timer);
}, []);---
pause() - Pause Slides Programmatically
Pause automatic slide transitions. Stops the carousel auto-play functionality without destroying the component.
Signature:
pause(): voidWhen to use:
- Pause on user interaction
- Pause during loading
- Stop auto-play for user interaction
- Control auto-play with custom buttons
Example:
import { CarouselComponent } from '@syncfusion/ej2-react-navigations';
import * as React from 'react';
const App = () => {
const carouselRef = React.useRef<CarouselComponent>(null);
const handlePause = () => {
carouselRef.current?.pause();
};
return (
<>
<button onClick={handlePause}>Pause Slideshow</button>
<CarouselComponent ref={carouselRef} autoPlay={true}>
<CarouselItemsDirective>
<CarouselItemDirective template='<h3>Slide 1</h3>' />
<CarouselItemDirective template='<h3>Slide 2</h3>' />
<CarouselItemDirective template='<h3>Slide 3</h3>' />
</CarouselItemsDirective>
</CarouselComponent>
</>
);
};
export default App;Example - Pause on hover (with custom logic):
const handleMouseEnter = () => {
carouselRef.current?.pause();
};
const handleMouseLeave = () => {
carouselRef.current?.play();
};
<div onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave}>
<CarouselComponent ref={carouselRef} autoPlay={true}>
{/* items */}
</CarouselComponent>
</div>---
destroy() - Destroy the Carousel Component
Cleanup and destroy the carousel component instance. Removes all event listeners and DOM elements associated with the carousel.
Signature:
destroy(): voidWhen to use:
- Component unmounting
- Cleanup in useEffect return
- Memory management
- Removing carousel from DOM
Example:
import { CarouselComponent } from '@syncfusion/ej2-react-navigations';
import * as React from 'react';
const App = () => {
const carouselRef = React.useRef<CarouselComponent>(null);
React.useEffect(() => {
return () => {
// Cleanup on unmount
carouselRef.current?.destroy();
};
}, []);
return (
<CarouselComponent ref={carouselRef}>
<CarouselItemsDirective>
<CarouselItemDirective template='<h3>Slide 1</h3>' />
<CarouselItemDirective template='<h3>Slide 2</h3>' />
<CarouselItemDirective template='<h3>Slide 3</h3>' />
</CarouselItemsDirective>
</CarouselComponent>
);
};
export default App;Example - Destroy on specific event:
const handleDestroy = () => {
carouselRef.current?.destroy();
console.log('Carousel destroyed');
};
<button onClick={handleDestroy}>Destroy Carousel</button>Example - Conditional destroy:
React.useEffect(() => {
return () => {
if (carouselRef.current) {
carouselRef.current.destroy();
}
};
}, []);---
Complete Method Example
Full working example demonstrating all five methods together:
import { CarouselComponent, CarouselItemsDirective, CarouselItemDirective } from '@syncfusion/ej2-react-navigations';
import * as React from 'react';
import './carousel-methods.css';
const CarouselMethodsDemo = () => {
const carouselRef = React.useRef<CarouselComponent>(null);
const [isPlaying, setIsPlaying] = React.useState(true);
const [slideIndex, setSlideIndex] = React.useState(0);
// Navigate to next slide
const handleNext = () => {
carouselRef.current?.next();
};
// Navigate to previous slide
const handlePrev = () => {
carouselRef.current?.prev();
};
// Play slides programmatically
const handlePlay = () => {
carouselRef.current?.play();
setIsPlaying(true);
};
// Pause slides programmatically
const handlePause = () => {
carouselRef.current?.pause();
setIsPlaying(false);
};
// Destroy carousel
const handleDestroy = () => {
carouselRef.current?.destroy();
alert('Carousel destroyed');
};
// Jump to specific slide
const goToSlide = (index: number) => {
const current = slideIndex;
if (index > current) {
for (let i = 0; i < index - current; i++) {
carouselRef.current?.next();
}
} else if (index < current) {
for (let i = 0; i < current - index; i++) {
carouselRef.current?.prev();
}
}
};
// Handle slide change
const onSlideChanged = (args: any) => {
setSlideIndex(args.currentIndex);
};
return (
<div className="carousel-demo">
<div className="controls">
{/* Navigation Controls */}
<button onClick={handlePrev} className="btn btn-prev">
← Prev
</button>
<button onClick={handleNext} className="btn btn-next">
Next →
</button>
<div className="spacer"></div>
{/* Play/Pause Controls */}
<button
onClick={isPlaying ? handlePause : handlePlay}
className={`btn ${isPlaying ? 'btn-pause' : 'btn-play'}`}
>
{isPlaying ? '⏸ Pause' : '▶ Play'}
</button>
<div className="spacer"></div>
{/* Slide Selectors */}
<button onClick={() => goToSlide(0)} className="btn btn-slide">
Slide 1
</button>
<button onClick={() => goToSlide(1)} className="btn btn-slide">
Slide 2
</button>
<button onClick={() => goToSlide(2)} className="btn btn-slide">
Slide 3
</button>
<button onClick={() => goToSlide(3)} className="btn btn-slide">
Slide 4
</button>
<button onClick={() => goToSlide(4)} className="btn btn-slide">
Slide 5
</button>
<div className="spacer"></div>
{/* Destroy Button */}
<button onClick={handleDestroy} className="btn btn-destroy">
Destroy
</button>
</div>
<div className="carousel-container">
<CarouselComponent
ref={carouselRef}
loop={true}
autoPlay={true}
slideChanged={onSlideChanged}
>
<CarouselItemsDirective>
<CarouselItemDirective template='<div class="slide slide-1"><h3>Slide 1</h3></div>' />
<CarouselItemDirective template='<div class="slide slide-2"><h3>Slide 2</h3></div>' />
<CarouselItemDirective template='<div class="slide slide-3"><h3>Slide 3</h3></div>' />
<CarouselItemDirective template='<div class="slide slide-4"><h3>Slide 4</h3></div>' />
<CarouselItemDirective template='<div class="slide slide-5"><h3>Slide 5</h3></div>' />
</CarouselItemsDirective>
</CarouselComponent>
</div>
<div className="info-panel">
<h4>Carousel Status:</h4>
<p>Current Slide: <strong>{slideIndex + 1}</strong> / 5</p>
<p>Auto-Play: <strong>{isPlaying ? '🟢 Playing' : '⏸ Paused'}</strong></p>
<p className="methods-info">
Available Methods: next() | prev() | play() | pause() | destroy()
</p>
</div>
</div>
);
};
export default CarouselMethodsDemo;CSS styling (carousel-methods.css):
.carousel-demo {
padding: 20px;
font-family: Arial, sans-serif;
}
.controls {
display: flex;
gap: 10px;
margin-bottom: 20px;
flex-wrap: wrap;
align-items: center;
}
.spacer {
flex: 1;
}
.btn {
padding: 10px 15px;
border: 1px solid #ccc;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
background: white;
transition: all 0.3s ease;
}
.btn:hover {
background: #f0f0f0;
border-color: #999;
}
.btn-prev, .btn-next {
background: #007bff;
color: white;
border-color: #007bff;
}
.btn-prev:hover, .btn-next:hover {
background: #0056b3;
border-color: #0056b3;
}
.btn-slide {
background: #28a745;
color: white;
border-color: #28a745;
min-width: 80px;
}
.btn-slide:hover {
background: #218838;
border-color: #218838;
}
.btn-play, .btn-pause {
background: #ff9800;
color: white;
border-color: #ff9800;
}
.btn-play:hover, .btn-pause:hover {
background: #f57c00;
border-color: #f57c00;
}
.btn-destroy {
background: #dc3545;
color: white;
border-color: #dc3545;
}
.btn-destroy:hover {
background: #c82333;
border-color: #c82333;
}
.carousel-container {
margin: 30px 0;
border: 2px solid #ddd;
border-radius: 8px;
overflow: hidden;
}
.slide {
display: flex;
align-items: center;
justify-content: center;
height: 300px;
font-size: 24px;
font-weight: bold;
color: white;
}
.slide-1 { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); }
.slide-2 { background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); }
.slide-3 { background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); }
.slide-4 { background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%); }
.slide-5 { background: linear-gradient(135deg, #fa709a 0%, #fee140 100%); }
.info-panel {
background: #f9f9f9;
border: 1px solid #ddd;
border-radius: 4px;
padding: 15px;
margin-top: 20px;
}
.info-panel h4 {
margin-top: 0;
color: #333;
}
.info-panel p {
margin: 8px 0;
color: #666;
}
.info-panel strong {
color: #007bff;
}
.methods-info {
margin-top: 15px;
padding-top: 10px;
border-top: 1px solid #ddd;
font-size: 12px;
color: #999;
font-weight: bold;
}---
Method Usage Patterns
Pattern 1: Navigate and Control Play/Pause
const [isPlaying, setIsPlaying] = React.useState(true);
const togglePlayPause = () => {
if (isPlaying) {
carouselRef.current?.pause();
} else {
carouselRef.current?.play();
}
setIsPlaying(!isPlaying);
};
<>
<button onClick={() => carouselRef.current?.prev()}>Prev</button>
<button onClick={togglePlayPause}>{isPlaying ? 'Pause' : 'Play'}</button>
<button onClick={() => carouselRef.current?.next()}>Next</button>
</>Pattern 2: Go to Specific Slide
const goToSlide = (targetIndex: number) => {
const current = carouselRef.current?.selectedIndex || 0;
const diff = targetIndex - current;
if (diff > 0) {
for (let i = 0; i < diff; i++) carouselRef.current?.next();
} else if (diff < 0) {
for (let i = 0; i < Math.abs(diff); i++) carouselRef.current?.prev();
}
};
<button onClick={() => goToSlide(2)}>Go to Slide 3</button>Pattern 3: Pause on Hover, Play on Leave
<div
onMouseEnter={() => carouselRef.current?.pause()}
onMouseLeave={() => carouselRef.current?.play()}
>
<CarouselComponent ref={carouselRef} autoPlay={true}>
{/* items */}
</CarouselComponent>
</div>Pattern 4: Keyboard Shortcuts
React.useEffect(() => {
const handleKeyPress = (e: KeyboardEvent) => {
if (e.key === 'ArrowRight') carouselRef.current?.next();
if (e.key === 'ArrowLeft') carouselRef.current?.prev();
if (e.key === ' ') {
e.preventDefault();
// Toggle play/pause on spacebar
isPlaying ? carouselRef.current?.pause() : carouselRef.current?.play();
}
};
window.addEventListener('keydown', handleKeyPress);
return () => window.removeEventListener('keydown', handleKeyPress);
}, [isPlaying]);Pattern 5: Auto-Pause During Interaction
const [pausedByUser, setPausedByUser] = React.useState(false);
const handleUserInteraction = () => {
carouselRef.current?.pause();
setPausedByUser(true);
// Resume after 5 seconds
setTimeout(() => {
carouselRef.current?.play();
setPausedByUser(false);
}, 5000);
};Pattern 6: Cleanup on Unmount
React.useEffect(() => {
return () => {
// Cleanup: Pause and destroy on component unmount
carouselRef.current?.pause();
carouselRef.current?.destroy();
};
}, []);Carousel API Properties
Comprehensive reference for all available Carousel component properties organized by functionality.
Table of Contents
- Core Data & Selection Properties
- Animation & Timing Properties
- Navigation & Indicator Properties
- Template & Customization Properties
- Interaction & Accessibility Properties
- Layout & Localization Properties
Core Data & Selection Properties
dataSource
External data source for carousel items. Pairs with itemTemplate for data-driven carousels.
Type: any[]
Example:
const carouselData = [
{ id: 1, imageUrl: '/img1.jpg', title: 'Image 1' },
{ id: 2, imageUrl: '/img2.jpg', title: 'Image 2' },
{ id: 3, imageUrl: '/img3.jpg', title: 'Image 3' }
];
<CarouselComponent dataSource={carouselData} itemTemplate={itemTemplate} />itemTemplate
Template for rendering data-bound carousel items. Function receives item data as parameter.
Type: (props: any) => JSX.Element | string
Example:
const itemTemplate = (props: any): JSX.Element => (
<div className="carousel-item">
<img src={props.imageUrl} alt={props.title} style={{width: '100%', height: '100%'}} />
<h3>{props.title}</h3>
</div>
);
<CarouselComponent dataSource={data} itemTemplate={itemTemplate} />items
Collection of CarouselItemModel for declarative item definition (alternative to dataSource).
Type: CarouselItemModel[]
Example:
<CarouselComponent>
<CarouselItemsDirective>
<CarouselItemDirective template='<h3>Slide 1</h3>' />
<CarouselItemDirective template='<h3>Slide 2</h3>' />
<CarouselItemDirective template='<h3>Slide 3</h3>' />
</CarouselItemsDirective>
</CarouselComponent>selectedIndex
Get or set the currently displayed slide by zero-based index. Updates when slide changes.
Type: number
Default: 0
Example:
// Set initial slide to 3rd item
<CarouselComponent selectedIndex={2}>
{/* Carousel starts at index 2 */}
</CarouselComponent>
// Change slide programmatically
const [index, setIndex] = React.useState(0);
<>
<CarouselComponent selectedIndex={index} />
<button onClick={() => setIndex(2)}>Go to Slide 3</button>
</>---
Animation & Timing Properties
animationEffect
Type of transition animation between slides.
Type: 'None' | 'Slide' | 'Fade' | 'Custom'
Default: 'Slide'
Example:
// Fade animation
<CarouselComponent animationEffect="Fade">
{/* Slides fade in/out */}
</CarouselComponent>
// Slide animation (default)
<CarouselComponent animationEffect="Slide">
{/* Slides slide left/right */}
</CarouselComponent>
// No animation
<CarouselComponent animationEffect="None">
{/* Instant transition */}
</CarouselComponent>
// Custom animation with CSS class
<CarouselComponent animationEffect="Custom" cssClass="parallax-carousel">
{/* Apply custom CSS animations */}
</CarouselComponent>interval
Milliseconds each slide displays before auto-transitioning. Can be set globally or per-item.
Type: number
Default: 5000
Example:
// Global interval: all slides display for 3 seconds
<CarouselComponent interval={3000} autoPlay={true}>
{/* All slides shown for 3000ms */}
</CarouselComponent>
// Per-item intervals (item binding only)
<CarouselComponent autoPlay={true}>
<CarouselItemsDirective>
<CarouselItemDirective template='<h3>Fast (1s)</h3>' interval={1000} />
<CarouselItemDirective template='<h3>Normal (3s)</h3>' interval={3000} />
<CarouselItemDirective template='<h3>Slow (5s)</h3>' interval={5000} />
</CarouselItemsDirective>
</CarouselComponent>autoPlay
Enable automatic slide transitions at specified interval.
Type: boolean
Default: false
Example:
// Enable auto-play: slides advance every 4 seconds
<CarouselComponent autoPlay={true} interval={4000}>
{/* Automatic transitions */}
</CarouselComponent>
// Disable auto-play: manual navigation only
<CarouselComponent autoPlay={false}>
{/* User must click buttons or swipe */}
</CarouselComponent>loop
Enable looping: return to first slide after last slide, or stop at end.
Type: boolean
Default: true
Example:
// Loop enabled (default)
<CarouselComponent loop={true}>
{/* Clicking next on last slide goes to first slide */}
</CarouselComponent>
// Loop disabled
<CarouselComponent loop={false}>
{/* Clicking next on last slide does nothing */}
{/* Next button disabled on last slide */}
</CarouselComponent>pauseOnHover
Pause automatic slide transitions when user hovers over carousel.
Type: boolean
Default: true
Example:
// Pause on hover (default)
<CarouselComponent autoPlay={true} pauseOnHover={true}>
{/* Auto-play stops when hovering over carousel */}
</CarouselComponent>
// Continue during hover
<CarouselComponent autoPlay={true} pauseOnHover={false}>
{/* Auto-play continues even when hovering */}
</CarouselComponent>---
Navigation & Indicator Properties
buttonsVisibility
Control when previous/next navigator buttons are displayed.
Type: 'Hidden' | 'Visible' | 'VisibleOnHover'
Default: 'VisibleOnHover'
Example:
// Always hidden
<CarouselComponent buttonsVisibility="Hidden">
{/* No navigation buttons visible */}
</CarouselComponent>
// Always visible
<CarouselComponent buttonsVisibility="Visible">
{/* Navigation buttons always shown */}
</CarouselComponent>
// Only visible on hover
<CarouselComponent buttonsVisibility="VisibleOnHover">
{/* Buttons appear on hover (or always on mobile) */}
</CarouselComponent>showIndicators
Display slide position indicators (dots/progress bar).
Type: boolean
Default: true
Example:
// Show indicators
<CarouselComponent showIndicators={true}>
{/* Indicators visible at bottom */}
</CarouselComponent>
// Hide indicators
<CarouselComponent showIndicators={false}>
{/* No position indicators */}
</CarouselComponent>indicatorsType
Style and type of slide position indicators.
Type: 'Default' | 'Dynamic' | 'Fraction' | 'Progress'
Default: 'Default'
Example:
// Default: Bullet style dots
<CarouselComponent indicatorsType="Default" showIndicators={true}>
{/* Displays as filled/empty circles */}
</CarouselComponent>
// Dynamic: Animated indicators
<CarouselComponent indicatorsType="Dynamic" showIndicators={true}>
{/* Indicators animate on slide change */}
</CarouselComponent>
// Fraction: Numeric display
<CarouselComponent indicatorsType="Fraction" showIndicators={true}>
{/* Shows "2/5", "3/5" format */}
</CarouselComponent>
// Progress: Progress bar
<CarouselComponent indicatorsType="Progress" showIndicators={true}>
{/* Shows progress bar at bottom */}
</CarouselComponent>showPlayButton
Display play/pause button for controlling auto-play.
Type: boolean
Default: false
Example:
// Show play/pause button
<CarouselComponent showPlayButton={true} autoPlay={true} buttonsVisibility="Visible">
{/* Play/pause button appears with navigation buttons */}
</CarouselComponent>
// Hide play button
<CarouselComponent showPlayButton={false}>
{/* No play/pause button */}
</CarouselComponent>---
Template & Customization Properties
previousButtonTemplate
Custom template for previous navigation button.
Type: (props: any) => JSX.Element | string
Example:
const prevButtonTemplate = (props: any): JSX.Element => (
<button className="custom-prev-btn">
<span className="e-icons e-chevron-left"></span> Prev
</button>
);
<CarouselComponent previousButtonTemplate={prevButtonTemplate} buttonsVisibility="Visible">
{/* Custom previous button rendered */}
</CarouselComponent>nextButtonTemplate
Custom template for next navigation button.
Type: (props: any) => JSX.Element | string
Example:
const nextButtonTemplate = (props: any): JSX.Element => (
<button className="custom-next-btn">
Next <span className="e-icons e-chevron-right"></span>
</button>
);
<CarouselComponent nextButtonTemplate={nextButtonTemplate} buttonsVisibility="Visible">
{/* Custom next button rendered */}
</CarouselComponent>playButtonTemplate
Custom template for play/pause button.
Type: (props: any) => JSX.Element | string
Example:
const playButtonTemplate = (props: any): JSX.Element => (
<button className="custom-play-btn">
{props.isPlaying ? '⏸ Pause' : '▶ Play'}
</button>
);
<CarouselComponent playButtonTemplate={playButtonTemplate} showPlayButton={true}>
{/* Custom play/pause button rendered */}
</CarouselComponent>indicatorsTemplate
Custom template for slide position indicators.
Type: (props: any) => JSX.Element | string
Example:
const indicatorTemplate = (props: any): JSX.Element => (
<span
className={`custom-indicator ${props.isActive ? 'active' : ''}`}
data-slide-index={props.index}
>
{props.index + 1}
</span>
);
<CarouselComponent indicatorsTemplate={indicatorTemplate} showIndicators={true}>
{/* Custom indicators rendered */}
</CarouselComponent>cssClass
Apply one or more custom CSS classes to the carousel element.
Type: string
Example:
// Single class
<CarouselComponent cssClass="custom-carousel">
{/* 'custom-carousel' class applied */}
</CarouselComponent>
// Multiple classes
<CarouselComponent cssClass="custom-carousel dark-theme wide-mode">
{/* All three classes applied */}
</CarouselComponent>partialVisible
Display adjacent slides partially visible for context.
Type: boolean
Default: false
Example:
// Partial visible disabled (default)
<CarouselComponent partialVisible={false}>
{/* Only current slide shown */}
</CarouselComponent>
// Partial visible enabled
<CarouselComponent partialVisible={true}>
{/* Current + partial prev + partial next shown */}
</CarouselComponent>
// With loop disabled
<CarouselComponent partialVisible={true} loop={false}>
{/* No partial on edges (first/last slides) */}
</CarouselComponent>---
Interaction & Accessibility Properties
enableTouchSwipe
Allow users to navigate with touch swipe gestures on touch devices.
Type: boolean
Default: true
Example:
// Touch swipe enabled (default)
<CarouselComponent enableTouchSwipe={true}>
{/* Users can swipe left/right on mobile */}
</CarouselComponent>
// Touch swipe disabled
<CarouselComponent enableTouchSwipe={false}>
{/* Only buttons/keyboard navigation */}
</CarouselComponent>swipeMode
Configure which input types trigger slide transitions (touch, mouse).
Type: CarouselSwipeMode (bitwise flags: Touch | Mouse)
Default: Touch | Mouse
Example:
import { CarouselSwipeMode } from "@syncfusion/ej2-react-navigations";
// Touch swipe only
<CarouselComponent swipeMode={CarouselSwipeMode.Touch} enableTouchSwipe={true}>
{/* Touch swipe enabled, mouse drag disabled */}
</CarouselComponent>
// Mouse drag only
<CarouselComponent swipeMode={CarouselSwipeMode.Mouse} enableTouchSwipe={true}>
{/* Mouse drag enabled, touch swipe disabled */}
</CarouselComponent>
// Both touch and mouse (default)
<CarouselComponent
swipeMode={CarouselSwipeMode.Touch | CarouselSwipeMode.Mouse}
enableTouchSwipe={true}
>
{/* Both enabled */}
</CarouselComponent>allowKeyboardInteraction
Enable keyboard navigation (arrow keys, Home, End, Space, Enter).
Type: boolean
Default: true
Example:
// Keyboard navigation enabled (default)
<CarouselComponent allowKeyboardInteraction={true}>
{/* Arrow keys, Home, End work */}
</CarouselComponent>
// Keyboard navigation disabled
<CarouselComponent allowKeyboardInteraction={false}>
{/* Keyboard navigation disabled (useful for forms inside carousel) */}
</CarouselComponent>---
Layout & Localization Properties
height
Component height in pixels or percentage string.
Type: number | string
Example:
// Fixed pixel height
<CarouselComponent height={400}>
{/* 400px tall */}
</CarouselComponent>
// Percentage height
<CarouselComponent height="100%">
{/* Full parent height */}
</CarouselComponent>
// String with unit
<CarouselComponent height="500px">
{/* 500 pixels tall */}
</CarouselComponent>width
Component width in pixels or percentage string.
Type: number | string
Example:
// Fixed pixel width
<CarouselComponent width={800}>
{/* 800px wide */}
</CarouselComponent>
// Percentage width
<CarouselComponent width="100%">
{/* Full parent width */}
</CarouselComponent>
// String with unit
<CarouselComponent width="1000px">
{/* 1000 pixels wide */}
</CarouselComponent>enableRtl
Enable right-to-left (RTL) text direction and layout mirroring.
Type: boolean
Default: false
Example:
// RTL disabled (default)
<CarouselComponent enableRtl={false}>
{/* Left-to-right layout */}
</CarouselComponent>
// RTL enabled
<CarouselComponent enableRtl={true}>
{/* Arrows reverse, buttons mirror, layout flips */}
</CarouselComponent>enablePersistence
Persist carousel state (selected slide) between page reloads using localStorage.
Type: boolean
Default: false
Example:
// Persistence disabled (default)
<CarouselComponent enablePersistence={false}>
{/* Resets to first slide on reload */}
</CarouselComponent>
// Persistence enabled
<CarouselComponent enablePersistence={true} id="carousel-1">
{/* Current slide saved and restored on reload */}
</CarouselComponent>locale
Set language/culture for localization (e.g., 'fr-FR', 'de-DE', 'es-ES').
Type: string
Default: Global locale
Example:
// Override global locale for this carousel
<CarouselComponent locale="fr-FR">
{/* Uses French localization if available */}
</CarouselComponent>
// Default locale
<CarouselComponent locale="en-US">
{/* Uses English localization */}
</CarouselComponent>htmlAttributes
Set custom HTML attributes on the carousel element.
Type: { [key: string]: any }
Example:
const customAttributes = {
'data-carousel-id': 'product-gallery',
'role': 'region',
'aria-label': 'Product carousel',
'data-theme': 'dark'
};
<CarouselComponent htmlAttributes={customAttributes}>
{/* Custom attributes added to carousel element */}
</CarouselComponent>---
Properties Quick Reference Table
| Property | Type | Default | Purpose |
|---|---|---|---|
| dataSource | any[] | - | External data array for carousel items |
| itemTemplate | Function | - | Render template for data-bound items |
| items | CarouselItemModel[] | - | Declarative collection of carousel items |
| selectedIndex | number | 0 | Current slide index (0-based) |
| animationEffect | string | 'Slide' | Transition animation type |
| interval | number | 5000 | Milliseconds per slide |
| autoPlay | boolean | false | Enable auto-transitions |
| loop | boolean | true | Enable slide looping |
| pauseOnHover | boolean | true | Pause auto-play on hover |
| buttonsVisibility | string | 'VisibleOnHover' | Navigation button visibility |
| showIndicators | boolean | true | Show position indicators |
| indicatorsType | string | 'Default' | Indicator style (Default, Dynamic, Fraction, Progress) |
| showPlayButton | boolean | false | Show play/pause button |
| previousButtonTemplate | Function | - | Custom previous button UI |
| nextButtonTemplate | Function | - | Custom next button UI |
| playButtonTemplate | Function | - | Custom play button UI |
| indicatorsTemplate | Function | - | Custom indicators UI |
| cssClass | string | - | Custom CSS classes |
| partialVisible | boolean | false | Show adjacent slides partially |
| enableTouchSwipe | boolean | true | Allow touch swipe |
| swipeMode | CarouselSwipeMode | `Touch \ | Mouse` |
| allowKeyboardInteraction | boolean | true | Enable keyboard navigation |
| height | `number \ | string` | - |
| width | `number \ | string` | - |
| enableRtl | boolean | false | Right-to-left layout |
| enablePersistence | boolean | false | Persist state between reloads |
| locale | string | - | Language/culture setting |
| htmlAttributes | object | - | Custom HTML attributes |
Getting Started with React Carousel
Table of Contents
- Installation and Dependencies
- Package Dependencies
- Install via npm
- Development Environment Setup
- Option 1: Create React App with Vite (Recommended)
- Option 2: Create React App (Traditional)
- CSS Imports and Theme Configuration
- Tailwind 3 Theme
- Bootstrap 5.3 Theme
- Material 3 Theme
- Fluent 2 Theme
- Basic Carousel Component Setup
- Component Import
- Minimal Component Structure
- First Working Example: Image Gallery
- Common Setup Issues
- Running the Application
- Video Tutorial
Installation and Dependencies
Package Dependencies
The Carousel component requires the following packages:
|-- @syncfusion/ej2-react-navigations
|-- @syncfusion/ej2-react-base
|-- @syncfusion/ej2-navigations
|-- @syncfusion/ej2-base
|-- @syncfusion/ej2-buttonsInstall via npm
npm install @syncfusion/ej2-react-navigations --saveThis command installs all required dependencies including base and button components.
Development Environment Setup
Option 1: Create React App with Vite (Recommended)
Vite provides faster development and smaller bundle sizes:
npm create vite@latest my-carousel-app -- --template react-ts
cd my-carousel-app
npm run devFor JavaScript (without TypeScript):
npm create vite@latest my-carousel-app -- --template react
cd my-carousel-app
npm run devOption 2: Create React App (Traditional)
npx create-react-app my-carousel-app
cd my-carousel-app
npm startCSS Imports and Theme Configuration
Add Carousel styles to App.css or your main stylesheet. Choose your preferred theme:
Tailwind 3 Theme
@import "../node_modules/@syncfusion/ej2-base/styles/tailwind3.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/tailwind3.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/tailwind3.css";Bootstrap 5.3 Theme
@import "../node_modules/@syncfusion/ej2-base/styles/bootstrap5.3.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/bootstrap5.3.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/bootstrap5.3.css";Material 3 Theme
@import "../node_modules/@syncfusion/ej2-base/styles/material3.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/material3.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/material3.css";Fluent 2 Theme
@import "../node_modules/@syncfusion/ej2-base/styles/fluent2.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/fluent2.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/fluent2.css";Basic Carousel Component Setup
Component Import
import { CarouselComponent, CarouselItemsDirective, CarouselItemDirective } from "@syncfusion/ej2-react-navigations";
import * as React from "react";Minimal Component Structure
const App = () => {
return (
<div className='control-container'>
<CarouselComponent>
<CarouselItemsDirective>
<CarouselItemDirective template='<h3>Slide 1</h3>' />
<CarouselItemDirective template='<h3>Slide 2</h3>' />
<CarouselItemDirective template='<h3>Slide 3</h3>' />
</CarouselItemsDirective>
</CarouselComponent>
</div>
);
}
export default App;First Working Example: Image Gallery
This complete example displays a carousel with five images:
import { CarouselComponent, CarouselItemsDirective, CarouselItemDirective } from "@syncfusion/ej2-react-navigations";
import * as React from "react";
import * as ReactDOM from "react-dom";
const App = () => {
return (
<div className='control-container'>
<CarouselComponent>
<CarouselItemsDirective>
<CarouselItemDirective template='<figure class="img-container"><img src="url" alt="cardinal" style="height:100%;width:100%;" /><figcaption class="img-caption">Cardinal</figcaption></figure>' />
<CarouselItemDirective template='<figure class="img-container"><img src="url" alt="kingfisher" style="height:100%;width:100%;" /><figcaption class="img-caption">Kingfisher</figcaption></figure>' />
<CarouselItemDirective template='<figure class="img-container"><img src="url" alt="keel-billed-toucan" style="height:100%;width:100%;" /><figcaption class="img-caption">Keel-billed-toucan</figcaption></figure>' />
<CarouselItemDirective template='<figure class="img-container"><img src="url" alt="yellow-warbler" style="height:100%;width:100%;" /><figcaption class="img-caption">Yellow-warbler</figcaption></figure>' />
<CarouselItemDirective template='<figure class="img-container"><img src="url" alt="bee-eater" style="height:100%;width:100%;" /><figcaption class="img-caption">Bee-eater</figcaption></figure>' />
</CarouselItemsDirective>
</CarouselComponent>
</div>
);
}
const root = ReactDOM.createRoot(document.getElementById('element'));
root.render(<App />);Common Setup Issues
Issue: Styles not applying
- Cause: CSS import paths incorrect or missing theme file
- Solution: Verify CSS import statements match your
node_modulesstructure. Runnpm list @syncfusion/ej2-baseto verify installation.
Issue: Components not found
- Cause: Package not installed or import path wrong
- Solution: Run
npm install @syncfusion/ej2-react-navigationsand verify import paths use exact component names.
Issue: Carousel not displaying
- Cause: Missing items or container styling
- Solution: Ensure container has explicit height:
<div style="height:400px;">and carousel has at least one CarouselItemDirective child.
Running the Application
After setup, start your development server:
With Vite:
npm run devWith Create React App:
npm startThe carousel will render in your browser, typically at http://localhost:5173 (Vite) or http://localhost:3000 (CRA).
Video Tutorial
For a visual walkthrough of setup and configuration, refer to the official Syncfusion React Carousel getting started video.
Image Optimization
Table of Contents
- Loading Images in WebP Format
- Performance Benefits
- File Size Comparison
- Performance Impact
- WebP Format Implementation
- Basic Carousel with WebP Images
- Fallback for Legacy Browsers
- Image Format Conversion
- Using Online Converters
- Command-Line Conversion
- Batch Conversion
- Responsive Image Optimization
- Lazy Loading Images
- Image Compression Best Practices
- Quality Settings
- Recommended Workflow
- Example Script
- Testing Image Performance
- Browser DevTools
- Lighthouse Audit
- WebPageTest
- Browser Support
- Summary
Loading Images in WebP Format
The WebP format provides superior compression and file size reduction compared to JPEG and PNG while maintaining excellent image quality. Using WebP images in your Carousel significantly improves performance.
Performance Benefits
File Size Comparison
| Format | File Size | Relative Size |
|---|---|---|
| JPEG | 150 KB | 100% (baseline) |
| PNG | 200 KB | 133% |
| WebP | 45 KB | 30% |
WebP achieves 70% size reduction compared to JPEG with equivalent visual quality.
Performance Impact
Smaller images mean:
- Faster page load: Reduced bandwidth consumption
- Better mobile experience: Quicker rendering on 4G/5G networks
- Lower data usage: Important for users with limited data plans
- Improved Core Web Vitals: Faster Largest Contentful Paint (LCP)
WebP Format Implementation
Basic Carousel with WebP Images
import { CarouselComponent, CarouselItemsDirective, CarouselItemDirective } from "@syncfusion/ej2-react-navigations";
import * as React from "react";
const App = () => {
return (
<div className='control-container'>
<CarouselComponent>
<CarouselItemsDirective>
<CarouselItemDirective template='<figure class="img-container"><img src="/images/cardinal.webp" alt="cardinal" style="height:100%;width:100%;" /><figcaption class="img-caption">Cardinal</figcaption></figure>' />
<CarouselItemDirective template='<figure class="img-container"><img src="/images/kingfisher.webp" alt="kingfisher" style="height:100%;width:100%;" /><figcaption class="img-caption">Kingfisher</figcaption></figure>' />
<CarouselItemDirective template='<figure class="img-container"><img src="/images/toucan.webp" alt="toucan" style="height:100%;width:100%;" /><figcaption class="img-caption">Toucan</figcaption></figure>' />
</CarouselItemsDirective>
</CarouselComponent>
</div>
);
}
export default App;Fallback for Legacy Browsers
Use <picture> element in templates for browser compatibility:
const itemTemplate = (props: any): JSX.Element => {
return (
<figure className="img-container">
<picture>
<source srcSet={props.webpUrl} type="image/webp" />
<img
src={props.jpegUrl}
alt={props.title}
style={{ height: '100%', width: '100%' }}
/>
</picture>
<figcaption className="img-caption">{props.title}</figcaption>
</figure>
);
}
const carouselData = [
{
title: "Cardinal",
webpUrl: "/images/cardinal.webp",
jpegUrl: "/images/cardinal.jpg"
},
{
title: "Kingfisher",
webpUrl: "/images/kingfisher.webp",
jpegUrl: "/images/kingfisher.jpg"
}
];
return (
<CarouselComponent
dataSource={carouselData}
itemTemplate={itemTemplate}
/>
);This uses WebP in supported browsers and automatically falls back to JPEG in older browsers.
Image Format Conversion
Using Online Converters
1. Convertio - url
- Upload JPEG/PNG
- Select WebP format
- Download converted file
2. CloudConvert - url
- Supports batch conversion
- API available for automation
3. Squoosh - url
- Browser-based with no account needed
- Real-time quality preview
Command-Line Conversion
Using ImageMagick:
convert image.jpg image.webpUsing cwebp (Google WebP tool):
cwebp -q 80 image.jpg -o image.webpOptions:
-q 80- Quality setting (1-100, default 75)- Higher quality = larger file but better visuals
Batch Conversion
Convert all JPEG files in a folder:
Linux/Mac:
for img in *.jpg; do cwebp -q 80 "$img" -o "${img%.jpg}.webp"; doneWindows PowerShell:
Get-ChildItem *.jpg | ForEach-Object { & cwebp -q 80 $_ -o $($_.Name -replace '\.jpg$', '.webp') }Responsive Image Optimization
Different Resolutions for Different Devices
const itemTemplate = (props: any): JSX.Element => {
return (
<figure className="img-container">
<picture>
{/* Desktop (1920px) */}
<source
media="(min-width: 1200px)"
srcSet={props.webpLarge}
type="image/webp"
/>
<source
media="(min-width: 1200px)"
srcSet={props.jpegLarge}
/>
{/* Tablet (768px) */}
<source
media="(min-width: 768px)"
srcSet={props.webpMedium}
type="image/webp"
/>
<source
media="(min-width: 768px)"
srcSet={props.jpegMedium}
/>
{/* Mobile (default) */}
<source srcSet={props.webpSmall} type="image/webp" />
<img
src={props.jpegSmall}
alt={props.title}
style={{ height: '100%', width: '100%' }}
/>
</picture>
<figcaption className="img-caption">{props.title}</figcaption>
</figure>
);
}
const carouselData = [
{
title: "Mountain",
webpSmall: "/images/mountain-400w.webp",
jpegSmall: "/images/mountain-400w.jpg",
webpMedium: "/images/mountain-800w.webp",
jpegMedium: "/images/mountain-800w.jpg",
webpLarge: "/images/mountain-1200w.webp",
jpegLarge: "/images/mountain-1200w.jpg"
}
];
return (
<CarouselComponent
dataSource={carouselData}
itemTemplate={itemTemplate}
/>
);Lazy Loading Images
Improve initial page load by lazy-loading carousel images:
import { CarouselComponent, CarouselItemsDirective, CarouselItemDirective } from "@syncfusion/ej2-react-navigations";
import * as React from "react";
const App = () => {
const itemTemplate = (props: any): JSX.Element => {
return (
<figure className="img-container">
<img
src={props.imageUrl}
alt={props.title}
loading="lazy" // Enable lazy loading
style={{ height: '100%', width: '100%' }}
/>
<figcaption className="img-caption">{props.title}</figcaption>
</figure>
);
}
const carouselData = [
{ title: "Image 1", imageUrl: "/images/img1.webp" },
{ title: "Image 2", imageUrl: "/images/img2.webp" },
{ title: "Image 3", imageUrl: "/images/img3.webp" }
];
return (
<CarouselComponent
dataSource={carouselData}
itemTemplate={itemTemplate}
/>
);
}
export default App;Note: Lazy loading works best with auto-play disabled or slow intervals, as users may not see preloaded images.
Image Compression Best Practices
Quality Settings
| Quality | Use Case | File Size |
|---|---|---|
| 85-95 | Photography, high detail | Larger |
| 75-85 | General web use | Medium |
| 65-75 | Thumbnails, backgrounds | Smaller |
| <65 | Not recommended | Too small |
Recommended Workflow
1. Original image: High resolution PNG or TIFF 2. Convert to JPEG: Optimize at quality 85 3. Convert to WebP: Optimize at quality 75-80 4. Deploy: Use <picture> with WebP + JPEG fallback
Example Script
#!/bin/bash
# Optimize all images in images/ folder
for img in images/*.jpg; do
# Create WebP version
cwebp -q 78 "$img" -o "${img%.jpg}.webp"
# Create compressed JPEG version
ffmpeg -i "$img" -q:v 2 "${img%.jpg}-opt.jpg"
done
echo "Optimization complete!"Testing Image Performance
Browser DevTools
1. Open DevTools (F12) 2. Go to Network tab 3. Check:
- File size: Should be <100 KB per image
- Load time: Should be <500ms per image
- Format: Should show WebP for modern browsers
Lighthouse Audit
1. Open DevTools → Lighthouse 2. Run Audit 3. Check "Opportunities" for image optimization suggestions
WebPageTest
Visit webpagetest.org to test carousel performance with your images.
Browser Support
WebP is supported in all modern browsers:
- Chrome 23+
- Firefox 65+
- Safari 14+
- Edge 18+
Legacy support: Use <picture> element with JPEG fallback for Internet Explorer 11.
Summary
- WebP reduces file size by 70% compared to JPEG
- Use
<picture>element for automatic fallback to JPEG - Implement responsive images for different screen sizes
- Consider lazy loading for large carousels
- Test with Lighthouse and WebPageTest for performance validation
Navigators and Indicators
Table of Contents
- Navigators Overview
- Navigator Button Visibility Modes
- Custom Navigator Templates
- Indicators Overview
- Indicator Types
- Indicator Templates
- Play Button Control
Navigators Overview
The navigators are previous and next buttons that allow users to manually transition between slides. Control their visibility and appearance using the buttonsVisibility property and template customization.
Navigator Button Visibility Modes
The buttonsVisibility property controls when the previous/next buttons appear:
Mode 1: Always Hidden
import { CarouselComponent, CarouselItemsDirective, CarouselItemDirective, CarouselButtonVisibility } from "@syncfusion/ej2-react-navigations";
import * as React from "react";
const App = () => {
const showButtons: CarouselButtonVisibility = "Hidden";
return (
<div className='control-container'>
<CarouselComponent buttonsVisibility={showButtons}>
<CarouselItemsDirective>
<CarouselItemDirective template='<h3>Slide 1</h3>' />
<CarouselItemDirective template='<h3>Slide 2</h3>' />
<CarouselItemDirective template='<h3>Slide 3</h3>' />
<CarouselItemDirective template='<h3>Slide 4</h3>' />
<CarouselItemDirective template='<h3>Slide 5</h3>' />
</CarouselItemsDirective>
</CarouselComponent>
</div>
);
}
export default App;Mode 2: Always Visible
const showButtons: CarouselButtonVisibility = "Visible";
return (
<CarouselComponent buttonsVisibility={showButtons}>
{/* items */}
</CarouselComponent>
);Buttons remain visible at all times, allowing continuous manual navigation.
Mode 3: Visible on Hover
const showButtons: CarouselButtonVisibility = "VisibleOnHover";
return (
<CarouselComponent buttonsVisibility={showButtons}>
{/* items */}
</CarouselComponent>
);Buttons only appear when the user hovers over the carousel, reducing visual clutter on desktop while keeping navigation available on mobile (pseudo-hover).
Custom Navigator Templates
Customize the appearance of previous and next buttons using the previousButtonTemplate and nextButtonTemplate props:
import { CarouselComponent, CarouselItemsDirective, CarouselItemDirective } from "@syncfusion/ej2-react-navigations";
import { ButtonComponent } from "@syncfusion/ej2-react-buttons";
import * as React from "react";
const App = () => {
const previousButtonTemplate = (props: any): JSX.Element => {
return (
<ButtonComponent
className="e-btn"
cssClass="e-flat e-round"
iconCss="e-icons e-chevron-left-double"
/>
);
}
const nextButtonTemplate = (props: any): JSX.Element => {
return (
<ButtonComponent
className="e-btn"
cssClass="e-flat e-round"
iconCss="e-icons e-chevron-right-double"
/>
);
}
return (
<div className='control-container'>
<CarouselComponent
previousButtonTemplate={previousButtonTemplate}
nextButtonTemplate={nextButtonTemplate}
>
<CarouselItemsDirective>
<CarouselItemDirective template='<h3>Slide 1</h3>' />
<CarouselItemDirective template='<h3>Slide 2</h3>' />
<CarouselItemDirective template='<h3>Slide 3</h3>' />
<CarouselItemDirective template='<h3>Slide 4</h3>' />
<CarouselItemDirective template='<h3>Slide 5</h3>' />
</CarouselItemsDirective>
</CarouselComponent>
</div>
);
}
export default App;Available icons: Use Syncfusion icon classes like e-chevron-left, e-arrow-left, e-chevron-right, e-arrow-right, or any custom SVG.
Indicators Overview
Indicators show the current slide position and allow click-to-navigate to specific slides. Control indicators with showIndicators property (default: true).
Show or Hide Indicators
<CarouselComponent showIndicators={true}>
<CarouselItemsDirective>
{/* items */}
</CarouselItemsDirective>
</CarouselComponent>Set showIndicators={false} to hide indicators completely.
Indicator Types
Choose from four indicator types using the indicatorsType property:
Type 1: Default Indicator
A set of dots representing each slide:
<CarouselComponent indicatorsType="Default">
<CarouselItemsDirective>
<CarouselItemDirective template='<h3>Slide 1</h3>' />
<CarouselItemDirective template='<h3>Slide 2</h3>' />
<CarouselItemDirective template='<h3>Slide 3</h3>' />
<CarouselItemDirective template='<h3>Slide 4</h3>' />
<CarouselItemDirective template='<h3>Slide 5</h3>' />
</CarouselItemsDirective>
</CarouselComponent>Type 2: Dynamic Indicator
Dynamically styled dots that visually respond to slide position:
<CarouselComponent indicatorsType="Dynamic">
<CarouselItemsDirective>
{/* items */}
</CarouselItemsDirective>
</CarouselComponent>Type 3: Fraction Indicator
Displays current slide and total count as a fraction (e.g., "2/5"):
<CarouselComponent indicatorsType="Fraction">
<CarouselItemsDirective>
{/* items */}
</CarouselItemsDirective>
</CarouselComponent>Type 4: Progress Indicator
Shows a progress bar representing completion through slides:
<CarouselComponent indicatorsType="Progress">
<CarouselItemsDirective>
{/* items */}
</CarouselItemsDirective>
</CarouselComponent>Indicator Templates
Custom Indicator Template
Customize indicator appearance using the indicatorsTemplate prop:
import { CarouselComponent, CarouselItemsDirective, CarouselItemDirective } from "@syncfusion/ej2-react-navigations";
import { useMemo } from "react";
import * as React from "react";
const App = () => {
const indicatorTemplate = useMemo(() => {
return (props: any) => <div className="indicator" indicator-index={props.index}></div>;
}, []);
return (
<div className='control-container'>
<CarouselComponent indicatorsTemplate={indicatorTemplate}>
<CarouselItemsDirective>
<CarouselItemDirective template='<h3>Slide 1</h3>' />
<CarouselItemDirective template='<h3>Slide 2</h3>' />
<CarouselItemDirective template='<h3>Slide 3</h3>' />
<CarouselItemDirective template='<h3>Slide 4</h3>' />
<CarouselItemDirective template='<h3>Slide 5</h3>' />
</CarouselItemsDirective>
</CarouselComponent>
</div>
);
}
export default App;Template Props:
props.index- Zero-based slide index
Indicator Template with Preview Images
Show thumbnail previews in indicators:
import { CarouselComponent, CarouselItemsDirective, CarouselItemDirective } from "@syncfusion/ej2-react-navigations";
import { useState } from "react";
import * as React from "react";
const App = () => {
const [slides] = useState(["Slide 1", "Slide 2", "Slide 3", "Slide 4", "Slide 5"]);
const getContent = (index: number) => {
return slides[index];
}
const indicatorTemplate = (props: any): JSX.Element => {
return (
<div className="indicator" indicator-index={props.index}>
<div className="preview-content">{getContent(props.index)}</div>
</div>
);
}
return (
<div className="control-container">
<CarouselComponent indicatorsTemplate={indicatorTemplate}>
<CarouselItemsDirective>
<CarouselItemDirective template="<div class='slide-content'>Slide 1</div>" />
<CarouselItemDirective template="<div class='slide-content'>Slide 2</div>" />
<CarouselItemDirective template="<div class='slide-content'>Slide 3</div>" />
<CarouselItemDirective template="<div class='slide-content'>Slide 4</div>" />
<CarouselItemDirective template="<div class='slide-content'>Slide 5</div>" />
</CarouselItemsDirective>
</CarouselComponent>
</div>
);
}
export default App;Play Button Control
Show or Hide Play Button
The showPlayButton property adds a play/pause button to control auto-play:
import { CarouselComponent, CarouselItemsDirective, CarouselItemDirective } from "@syncfusion/ej2-react-navigations";
import * as React from "react";
const App = () => {
return (
<div className='control-container'>
<CarouselComponent showPlayButton={true}>
<CarouselItemsDirective>
<CarouselItemDirective template='<h3>Slide 1</h3>' />
<CarouselItemDirective template='<h3>Slide 2</h3>' />
<CarouselItemDirective template='<h3>Slide 3</h3>' />
<CarouselItemDirective template='<h3>Slide 4</h3>' />
<CarouselItemDirective template='<h3>Slide 5</h3>' />
</CarouselItemsDirective>
</CarouselComponent>
</div>
);
}
export default App;Note: Requires buttonsVisibility to be set (at least "Visible" or "VisibleOnHover").
Custom Play Button Template
Customize the play/pause button:
import { CarouselComponent, CarouselItemsDirective, CarouselItemDirective } from "@syncfusion/ej2-react-navigations";
import { ButtonComponent } from "@syncfusion/ej2-react-buttons";
import { useState } from "react";
import * as React from "react";
const App = () => {
const [buttonContent, setButtonContent] = useState<string>('Pause');
const [autoPlay, setAutoPlay] = useState<boolean>(true);
const btnClick = () => {
if (autoPlay) {
setButtonContent('Play');
setAutoPlay(false);
} else {
setButtonContent('Pause');
setAutoPlay(true);
}
}
const playButtonTemplate = (props: any): JSX.Element => {
return (
<ButtonComponent
className="e-btn"
cssClass="e-info playBtn"
content={buttonContent}
onClick={btnClick}
/>
);
}
return (
<div className='control-container'>
<CarouselComponent
showPlayButton={true}
playButtonTemplate={playButtonTemplate}
autoPlay={autoPlay}
>
<CarouselItemsDirective>
<CarouselItemDirective template='<h3>Slide 1</h3>' />
<CarouselItemDirective template='<h3>Slide 2</h3>' />
<CarouselItemDirective template='<h3>Slide 3</h3>' />
<CarouselItemDirective template='<h3>Slide 4</h3>' />
<CarouselItemDirective template='<h3>Slide 5</h3>' />
</CarouselItemsDirective>
</CarouselComponent>
</div>
);
}
export default App;Best Practices
- Desktop: Use "VisibleOnHover" to keep interface clean while providing navigation
- Mobile: Use "Visible" since hover doesn't work on touch devices
- Accessibility: Always include either indicators or play button for non-disabled users
- Customization: Templates allow complete UI control while maintaining functionality
Populating Items and Selection
Table of Contents
- Item Binding with CarouselItem
- Data Source Binding
- Selection with Property
- Selection with Methods
- Partial Visible Slides
Item Binding with CarouselItem
When rendering the Carousel with item binding, you can assign individual templates to each item or use a common template. Each item can also have its own transition interval.
Basic Item Binding
Each CarouselItemDirective defines one slide. The template prop contains the HTML to render:
import { CarouselComponent, CarouselItemsDirective, CarouselItemDirective } from "@syncfusion/ej2-react-navigations";
import * as React from "react";
const App = () => {
return (
<div className='control-container'>
<CarouselComponent>
<CarouselItemsDirective>
<CarouselItemDirective template='<figure class="img-container"><img src="url" alt="cardinal" style="height:100%;width:100%;" /><figcaption class="img-caption">Cardinal</figcaption></figure>' />
<CarouselItemDirective template='<figure class="img-container"><img src="url" alt="kingfisher" style="height:100%;width:100%;" /><figcaption class="img-caption">Kingfisher</figcaption></figure>' />
<CarouselItemDirective template='<figure class="img-container"><img src="url" alt="keel-billed-toucan" style="height:100%;width:100%;" /><figcaption class="img-caption">Keel-billed-toucan</figcaption></figure>' />
<CarouselItemDirective template='<figure class="img-container"><img src="url" alt="yellow-warbler" style="height:100%;width:100%;" /><figcaption class="img-caption">Yellow-warbler</figcaption></figure>' />
<CarouselItemDirective template='<figure class="img-container"><img src="url" alt="bee-eater" style="height:100%;width:100%;" /><figcaption class="img-caption">Bee-eater</figcaption></figure>' />
</CarouselItemsDirective>
</CarouselComponent>
</div>
);
}
export default App;Custom Intervals Per Item
Set different transition intervals for each item using the interval prop (milliseconds):
<CarouselComponent>
<CarouselItemsDirective>
<CarouselItemDirective template='<h3>Slide 1 - 3 seconds</h3>' interval={3000} />
<CarouselItemDirective template='<h3>Slide 2 - 1 second</h3>' interval={1000} />
<CarouselItemDirective template='<h3>Slide 3 - 2 seconds</h3>' interval={2000} />
<CarouselItemDirective template='<h3>Slide 4 - 5 seconds</h3>' interval={5000} />
<CarouselItemDirective template='<h3>Slide 5 - 6 seconds</h3>' interval={6000} />
</CarouselItemsDirective>
</CarouselComponent>Note: Custom intervals only work with CarouselItem binding, not with dataSource binding.
Data Source Binding
When using data source binding, you define a common template applied to all items. This approach is ideal for:
- Large dynamic datasets
- Items fetched from APIs
- Templates based on data properties
Using itemTemplate
import { CarouselComponent } from "@syncfusion/ej2-react-navigations";
import { useMemo } from "react";
import * as React from "react";
const App = () => {
const productItems = useMemo(() => [
{ ID: 1, Name: "Cardinal", imageName: 'cardinal' },
{ ID: 2, Name: "Kingfisher", imageName: 'hunei' },
{ ID: 3, Name: "Keel-billed-toucan", imageName: 'costa-rica' },
{ ID: 4, Name: "Yellow-warbler", imageName: 'kaohsiung' },
{ ID: 5, Name: "Bee-eater", imageName: 'bee-eater' }
], []);
const itemTemplate = (props: any): JSX.Element => {
return (
<figure className="img-container">
<img
src={":url" + props.imageName + ".png"}
alt={props.Name}
style={{ height: "100%", width: "100%" }}
/>
<figcaption className="img-caption">{props.Name}</figcaption>
</figure>
);
}
return (
<div className='control-container'>
<CarouselComponent dataSource={productItems} itemTemplate={itemTemplate} />
</div>
);
}
export default App;Fetching Data from API
const [carouselData, setCarouselData] = React.useState([]);
React.useEffect(() => {
fetch('url')
.then(res => res.json())
.then(data => setCarouselData(data))
.catch(err => console.error('Failed to load carousel data:', err));
}, []);
const itemTemplate = (props: any): JSX.Element => {
return <img src={props.imageUrl} alt={props.title} style={{ width: '100%', height: '100%' }} />;
}
return <CarouselComponent dataSource={carouselData} itemTemplate={itemTemplate} />;Selection with Property
Set Initial Slide with selectedIndex
The selectedIndex property specifies which slide displays when the carousel initializes (0-indexed):
<CarouselComponent selectedIndex={3}>
<CarouselItemsDirective>
<CarouselItemDirective template='<h3>Slide 1</h3>' />
<CarouselItemDirective template='<h3>Slide 2</h3>' />
<CarouselItemDirective template='<h3>Slide 3</h3>' />
<CarouselItemDirective template='<h3>Slide 4</h3>' />
<CarouselItemDirective template='<h3>Slide 5</h3>' />
</CarouselItemsDirective>
</CarouselComponent>This renders with Slide 4 (index 3) displayed initially.
Update Slide Programmatically
Change the selected slide after initial render using state:
const [selectedIndex, setSelectedIndex] = React.useState(0);
const goToSlide = (index: number) => {
setSelectedIndex(index);
}
return (
<div>
<CarouselComponent selectedIndex={selectedIndex}>
{/* items */}
</CarouselComponent>
<button onClick={() => goToSlide(2)}>Go to Slide 3</button>
</div>
);Selection with Methods
Using prev() and next() Methods
Access the carousel instance via useRef to call navigation methods:
import { CarouselComponent, CarouselItemsDirective, CarouselItemDirective } from "@syncfusion/ej2-react-navigations";
import { ButtonComponent } from "@syncfusion/ej2-react-buttons";
import { useRef } from "react";
import * as React from "react";
const App = () => {
const carouselRef = useRef<CarouselComponent>(null);
const prevBtnClick = (): void => {
carouselRef.current?.prev();
}
const nextBtnClick = (): void => {
carouselRef.current?.next();
}
return (
<div>
<div>
<ButtonComponent className="e-btn" cssClass="e-info" onClick={prevBtnClick}>Previous</ButtonComponent>
<ButtonComponent className="e-btn" cssClass="e-info" onClick={nextBtnClick}>Next</ButtonComponent>
</div>
<div className='control-container'>
<CarouselComponent ref={carouselRef}>
<CarouselItemsDirective>
<CarouselItemDirective template='<figure class="img-container"><img src="url" alt="cardinal" style="height:100%;width:100%;" /><figcaption class="img-caption">Cardinal</figcaption></figure>' />
<CarouselItemDirective template='<figure class="img-container"><img src="url" alt="kingfisher" style="height:100%;width:100%;" /><figcaption class="img-caption">Kingfisher</figcaption></figure>' />
<CarouselItemDirective template='<figure class="img-container"><img src="url" alt="keel-billed-toucan" style="height:100%;width:100%;" /><figcaption class="img-caption">Keel-billed-toucan</figcaption></figure>' />
<CarouselItemDirective template='<figure class="img-container"><img src="url" alt="yellow-warbler" style="height:100%;width:100%;" /><figcaption class="img-caption">Yellow-warbler</figcaption></figure>' />
<CarouselItemDirective template='<figure class="img-container"><img src="url" alt="bee-eater" style="height:100%;width:100%;" /><figcaption class="img-caption">Bee-eater</figcaption></figure>' />
</CarouselItemsDirective>
</CarouselComponent>
</div>
</div>
);
}
export default App;Methods:
prev()- Navigate to previous slidenext()- Navigate to next slide
Partial Visible Slides
Enable Adjacent Slide Previews
Show one complete slide plus partial views of previous and next slides using the partialVisible property:
<CarouselComponent partialVisible={true}>
<CarouselItemsDirective>
<CarouselItemDirective template='<h3>Slide 1</h3>' />
<CarouselItemDirective template='<h3>Slide 2</h3>' />
<CarouselItemDirective template='<h3>Slide 3</h3>' />
<CarouselItemDirective template='<h3>Slide 4</h3>' />
<CarouselItemDirective template='<h3>Slide 5</h3>' />
</CarouselItemsDirective>
</CarouselComponent>Partial Visible Without Loop
When loop={false}, the carousel stops at the last slide without wrapping:
<CarouselComponent partialVisible={true} loop={false}>
<CarouselItemsDirective>
<CarouselItemDirective template='<h3>Slide 1</h3>' />
<CarouselItemDirective template='<h3>Slide 2</h3>' />
<CarouselItemDirective template='<h3>Slide 3</h3>' />
</CarouselItemsDirective>
</CarouselComponent>Behavior:
- With
loop={true}: Last slide displays with previous slide as partial - With
loop={false}: Previous slide not shown at initial render
Customizing Partial Slide Size
See styling-and-appearance.md for CSS customization of partial slide area.
Edge Cases
No items defined:
- Carousel renders with empty container
- Navigator and indicator buttons still appear but are non-functional
Single item:
- Carousel displays the single item
- Navigation buttons and indicators appear but have no effect
- Loop has no visible impact
Large datasets:
- Consider using dataSource with itemTemplate for 50+ items
- Avoid rendering 100+ CarouselItemDirective elements in JSX