@harshiniravikumar/react-glide-carousel
Version:
A fully featured, customizable, and responsive carousel component with virtual scrolling and touch gestures
421 lines (360 loc) ⢠12.2 kB
Markdown
# UniversalCarousel
A fully featured, customizable, and responsive scrollable carousel component with virtual scrolling, touch gestures, and animations. It's designed for performance and flexibility, supporting any data type with custom rendering.
## ⨠Core Features
- š± **Responsive Layout** ā configurable breakpoints with custom settings
- š¢ **Virtual Scrolling** ā renders only visible items for high performance
- ā **Touch & Mouse Support** ā drag, swipe, and mouse wheel navigation
- š¬ **Animations** ā slide and fade transitions with autoplay
- š **Infinite Loop** ā seamless looping carousel
- šÆ **Customizable Controls** ā arrows, dots, center mode
- āæ **Accessible** ā keyboard navigation & ARIA support
- šØ **Themeable** ā complete visual customization
## š¦ Installation
```bash
npm install "@harshiniravikumar/react-glide-carousel"
```
## š§ Main Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `data` | `T[]` | `[]` | Array of data items to render in the carousel |
| `children` | `(item: T, index: number) => React.ReactNode` | - | Render function for each slide |
| `renderSlide` | `(item: T, index: number) => React.ReactNode` | - | Alternative render function (backward compatibility) |
| `options` | `CarouselOptions` | `{}` | Configuration options for carousel behavior |
| `className` | `string` | `''` | Additional CSS classes |
| `loading` | `boolean` | `false` | Shows loading state |
| `renderLoading` | `() => React.ReactNode` | - | Custom loading component |
| `renderEmpty` | `() => React.ReactNode` | - | Custom empty state component |
| `keyExtractor` | `(item: T, index: number) => string` | - | Custom key extraction function |
| `theme` | `CarouselTheme` | `{}` | Visual theme customization |
## āļø Carousel Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `autoplay` | `boolean` | `false` | Enables automatic sliding |
| `autoplaySpeed` | `number` | `3000` | Delay in ms for autoplay |
| `infinite` | `boolean` | `false` | Enables infinite looping |
| `showArrows` | `boolean` | `true` | Displays navigation arrows |
| `showDots` | `boolean` | `true` | Displays dot indicators |
| `enableMouseWheel` | `boolean` | `false` | Enables mouse wheel navigation |
| `transition` | `"slide" \| "fade"` | `"slide"` | Transition animation type |
| `speed` | `number` | `500` | Transition speed in ms |
| `slidesToShow` | `number` | `1` | Number of slides visible at once |
| `slidesToScroll` | `number` | `1` | Number of slides to scroll at once |
| `gap` | `string` | `"0px"` | Space between slides |
| `centerMode` | `boolean` | `false` | Centers the active slide |
| `responsive` | `ResponsiveSettings` | `{}` | Responsive breakpoint settings |
| `virtualScroll` | `VirtualScrollOptions` | `{}` | Virtual scrolling configuration |
| `touch` | `TouchOptions` | `{}` | Touch gesture settings |
## š± Responsive Configuration
Configure different settings for various screen sizes:
```typescript
const responsiveSettings: ResponsiveSettings = {
1200: { // Desktop
slidesToShow: 4,
slidesToScroll: 2,
arrows: true,
dots: true
},
768: { // Tablet
slidesToShow: 2,
slidesToScroll: 1,
gap: "10px"
},
480: { // Mobile
slidesToShow: 1,
slidesToScroll: 1,
arrows: false,
dots: true
}
};
```
| Responsive Option | Type | Description |
|-------------------|------|-------------|
| `slidesToShow` | `number` | Override slides visible at this breakpoint |
| `slidesToScroll` | `number` | Override slides to scroll at this breakpoint |
| `gap` | `string` | Override gap between slides |
| `arrows` | `boolean` | Show/hide arrows at this breakpoint |
| `dots` | `boolean` | Show/hide dots at this breakpoint |
## š¢ Virtual Scrolling Options
Optimize performance for large datasets:
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `enabled` | `boolean` | `false` | Enable virtual scrolling |
| `itemHeight` | `number` | `200` | Height of each item in pixels |
| `bufferSize` | `number` | `5` | Number of items to render outside viewport |
| `threshold` | `number` | `100` | Scroll threshold before rendering new items |
## š Touch & Gesture Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `enabled` | `boolean` | `true` | Enable touch interactions |
| `threshold` | `number` | `50` | Minimum distance for swipe detection |
| `sensitivity` | `number` | `1` | Swipe sensitivity multiplier |
| `preventDefaultTouchmoveEvent` | `boolean` | `true` | Prevent default touch behavior |
## šØ Theme Customization
| Theme Property | Type | Description |
|----------------|------|-------------|
| `gap` | `string` | Space between slides |
| `borderRadius` | `string` | Border radius for slides |
| `arrowColor` | `string` | Color of navigation arrows |
| `arrowBackgroundColor` | `string` | Background color of arrow buttons |
| `dotColor` | `string` | Color of inactive dots |
| `dotActiveColor` | `string` | Color of active dot |
| `backgroundColor` | `string` | Background color of carousel |
| `shadowColor` | `string` | Shadow color for carousel |
## š Callbacks & Events
| Callback | Type | Description |
|----------|------|-------------|
| `onSlideChange` | `(index: number, item: T) => void` | Called when slide changes |
| `onSlideClick` | `(item: T, index: number) => void` | Called when slide is clicked |
| `onBeforeSlideChange` | `(current: number, next: number) => void` | Called before slide change |
| `onAfterSlideChange` | `(index: number, item: T) => void` | Called after slide change |
| `onReachEnd` | `() => void` | Called when reaching last slide |
| `onReachStart` | `() => void` | Called when reaching first slide |
| `onSwipeStart` | `(direction: 'left' \| 'right') => void` | Called when swipe starts |
| `onSwipeEnd` | `(direction: 'left' \| 'right') => void` | Called when swipe ends |
## š ļø Carousel Reference Methods
Access carousel methods using `useRef`:
| Method | Type | Description |
|--------|------|-------------|
| `goToSlide` | `(index: number) => void` | Navigate to specific slide |
| `next` | `() => void` | Go to next slide |
| `prev` | `() => void` | Go to previous slide |
| `getCurrentIndex` | `() => number` | Get current slide index |
| `getTotalSlides` | `() => number` | Get total number of slides |
| `play` | `() => void` | Start autoplay |
| `pause` | `() => void` | Pause autoplay |
## š¼ļø Basic Usage
```tsx
import { UniversalCarousel } from "scroll-user";
interface Product {
id: number;
name: string;
image: string;
price: number;
}
function ProductCarousel() {
const products: Product[] = [
{ id: 1, name: "Product 1", image: "/img1.jpg", price: 99 },
{ id: 2, name: "Product 2", image: "/img2.jpg", price: 149 },
{ id: 3, name: "Product 3", image: "/img3.jpg", price: 199 },
];
return (
<UniversalCarousel
data={products}
options={{
slidesToShow: 3,
autoplay: true,
infinite: true,
gap: "20px"
}}
>
{(product, index) => (
<div className="product-card">
<img src={product.image} alt={product.name} />
<h3>{product.name}</h3>
<p>${product.price}</p>
</div>
)}
</UniversalCarousel>
);
}
```
## š® Advanced Usage with All Features
```tsx
import { useRef } from 'react';
import { UniversalCarousel, CarouselRef } from "@dharshana333/react-ui-components";
function AdvancedCarousel() {
const carouselRef = useRef<CarouselRef>(null);
const handleSlideChange = (index: number, item: any) => {
console.log('Slide changed to:', index, item);
};
return (
<UniversalCarousel
ref={carouselRef}
data={items}
options={{
autoplay: true,
autoplaySpeed: 4000,
infinite: true,
slidesToShow: 3,
slidesToScroll: 2,
centerMode: true,
transition: "slide",
speed: 600,
gap: "15px",
responsive: {
768: {
slidesToShow: 2,
centerMode: false
},
480: {
slidesToShow: 1,
arrows: false
}
},
virtualScroll: {
enabled: true,
itemHeight: 300,
bufferSize: 3
},
touch: {
enabled: true,
threshold: 75,
sensitivity: 1.2
}
}}
theme={{
gap: "20px",
borderRadius: "12px",
arrowColor: "#fff",
arrowBackgroundColor: "rgba(0,0,0,0.5)",
dotActiveColor: "#007bff",
shadowColor: "rgba(0,0,0,0.1)"
}}
onSlideChange={handleSlideChange}
onReachEnd={() => console.log('Reached end')}
className="my-carousel"
keyExtractor={(item, index) => `${item.id}-${index}`}
>
{(item, index) => (
<YourCustomSlideComponent item={item} index={index} />
)}
</UniversalCarousel>
);
}
```
## šÆ Real-World Examples
### Image Gallery with Fade Transition
```tsx
<UniversalCarousel
data={images}
options={{
transition: "fade",
autoplay: true,
infinite: true,
showDots: true,
showArrows: false
}}
>
{(image, index) => (
<img src={image.url} alt={image.caption} />
)}
</UniversalCarousel>
```
### Testimonials with Center Mode
```tsx
<UniversalCarousel
data={testimonials}
options={{
centerMode: true,
slidesToShow: 3,
infinite: true,
autoplay: true,
gap: "30px"
}}
theme={{
borderRadius: "16px",
backgroundColor: "#f8f9fa"
}}
>
{(testimonial) => (
<TestimonialCard testimonial={testimonial} />
)}
</UniversalCarousel>
```
### Virtual Scrolling for Large Datasets
```tsx
<UniversalCarousel
data={largeDataset} // 10,000+ items
options={{
virtualScroll: {
enabled: true,
itemHeight: 250,
bufferSize: 5
},
slidesToShow: 4
}}
>
{(item, index) => <ItemCard item={item} />}
</UniversalCarousel>
```
## š± Loading & Empty States
```tsx
<UniversalCarousel
data={products}
loading={isLoading}
renderLoading={() => (
<div className="carousel-loading">
<Spinner />
<p>Loading products...</p>
</div>
)}
renderEmpty={() => (
<div className="carousel-empty">
<p>No products found</p>
</div>
)}
>
{(product) => <ProductCard product={product} />}
</UniversalCarousel>
```
## šØ Custom Styling
```css
.my-carousel {
--carousel-arrow-size: 40px;
--carousel-dot-size: 12px;
--carousel-gap: 20px;
}
.my-carousel .carousel-slide {
border-radius: 8px;
overflow: hidden;
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}
.my-carousel .carousel-arrow {
backdrop-filter: blur(10px);
border: 1px solid rgba(255,255,255,0.2);
}
```
## āæ Accessibility Features
- Full keyboard navigation (Arrow keys, Enter, Space)
- ARIA labels and roles for screen readers
- Focus management and indicators
- High contrast mode support
- Reduced motion respect
## š Performance Features
- Virtual scrolling for large datasets
- Lazy loading support
- Optimized re-renders with React.memo
- Hardware-accelerated animations
- Memory efficient rendering
## š TypeScript Support
Full TypeScript support with comprehensive type definitions:
```tsx
import { UniversalCarousel, CarouselRef, CarouselOptions } from "@dharshana333/react-ui-components";
interface MyItem {
id: string;
title: string;
}
const MyCarousel: React.FC = () => {
return (
<UniversalCarousel<MyItem>
data={items}
options={options}
onSlideChange={(index, item) => {
// item is properly typed as MyItem
console.log(item.title);
}}
>
{(item, index) => (
// item is typed as MyItem
<div>{item.title}</div>
)}
</UniversalCarousel>
);
};
```
## š License
MIT License - feel free to use in your projects!
## š¤ Contributing
Contributions are welcome! Please read our contributing guidelines before submitting PRs.
---
⨠**Built with performance, accessibility, and developer experience in mind.**