npm package: @harshiniravikumar/react-glide-carousel
Description: A fully featured, customizable, and responsive carousel component with virtual scrolling and touch gestures
Latest version: 1.1.1

# 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.**