nexlide 1.0.4 β†’ 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,7 +2,6 @@
2
2
  <img src="https://nexlide.netlify.app/assets/logo-full.png" width="420"/>
3
3
  </p>
4
4
 
5
-
6
5
  [![GitHub](https://img.shields.io/badge/GitHub-000000?style=flat-square&logo=github&logoColor=white)](https://github.com/ERPalmer/nexlide)
7
6
  [![npm version](https://img.shields.io/npm/v/nexlide?style=flat-square&logo=npm&logoColor=white&color=CB3837)](https://www.npmjs.com/package/nexlide)
8
7
  [![npm downloads](https://img.shields.io/npm/dm/nexlide?style=flat-square&logo=npm&logoColor=white&color=0baa45)](https://www.npmjs.com/package/nexlide)
@@ -12,35 +11,138 @@
12
11
  [![Tailwind CSS v4](https://img.shields.io/badge/Tailwind%20CSS-00bcff?style=flat-square&logo=tailwind-css&logoColor=white)](https://tailwindcss.com/)
13
12
  [![Framer Motion](https://img.shields.io/badge/Framer%20Motion-EF5DA8?style=flat-square&logo=framer&logoColor=white)](https://www.framer.com/motion/)
14
13
 
15
-
16
14
  # Nexlide
17
15
 
18
16
  A modern, lightweight, and fully customizable React carousel component built with **Framer Motion** for smooth animations and **Tailwind CSS** for flexible styling.
19
17
 
20
-
21
18
  ## ✨ Features
22
19
 
23
- - Smooth slide transitions (fade, slide left/right/top/bottom)
24
- - Independent caption animations (title + description)
25
- - Responsive design
26
- - Lazy loading images
27
- - ARIA accessible
28
- - Dark mode compatible
29
- - No external CSS import required (uses Tailwind classes inline)
30
- - Others in development process
31
-
20
+ ### Core
21
+ - **Smooth slide transitions** with 10+ animation variants (fade, slide, zoom, bounce, flip)
22
+ - **Independent caption animations** with customizable delay (0.5s default) and duration (0.8s default)
23
+ - **Full RTL support** 🌐 β€” mirrored navigation, reversed swipe, and proper layout for Arabic, Hebrew, Persian, and other RTL languages
24
+ - **Intelligent autoplay system** with direction control (`forward` | `reverse`) and smart pause behaviors
25
+ - **Advanced touch/swipe gestures** with Framer Motion β€” inertia scrolling and elastic snap-back
26
+ - **Accessibility first** β€” ARIA labels, keyboard navigation, visible focus rings
27
+ - **Performance optimized** β€” lazy loading, image optimizations (`decoding="async"`, `draggable=false`), clean event cleanup
28
+ - **Responsive design** with aspect ratio preservation (default 4:3, fully customizable)
29
+ - **Dark mode compatible** by default
30
+ - **Zero CSS imports** β€” uses Tailwind classes inline
31
+ - **Next.js App Router ready** with `'use client'` directive
32
+
33
+ ### πŸ†• What's New in v1.1.0
34
+
35
+ #### Enhanced Autoplay Control
36
+ - **`autoPlayDirection`** β€” Choose between `"forward"` (next slide) or `"reverse"` (previous slide) for autoplay progression
37
+ - **Smart pause triggers** β€” All default to `true` for optimal UX:
38
+ - `pauseOnHover` β€” Pauses when mouse enters the carousel
39
+ - `pauseOnFocus` β€” Pauses when carousel receives keyboard focus
40
+ - `pauseOnDrag` β€” Pauses during active swipe/drag interactions
41
+ - **Tab visibility awareness** β€” Autoplay automatically pauses when the page/tab is hidden and resumes when visible
42
+
43
+ #### Complete RTL Support
44
+ - **`rtl` prop** β€” Enables full right-to-left mode with:
45
+ - Reversed swipe/drag direction (swipe left β†’ next slide)
46
+ - Swapped navigation arrow positions and functions
47
+ - Default animation switches to `slideRight` (if not overridden)
48
+ - `dir="rtl"` attribute applied to root container
49
+ - Proper ARIA labels for arrows in RTL context
50
+ - Mirror-friendly pagination dots
51
+
52
+ #### Refined Animation System
53
+ - **`captionDuration`** β€” Fine-tune caption animation speed (default: `0.8` seconds)
54
+ - **Independent direction handling** β€” Slide animations automatically respect RTL and autoplay direction
55
+ - **Improved transition logic** β€” Better wrapping in infinite loop mode
56
+
57
+ #### Advanced Interaction
58
+ - **Framer Motion drag enhancements** β€” Inertia-based scrolling with elastic snap-back
59
+ - **Touch-optimized** β€” Removed legacy touch handlers for cleaner, more performant code
60
+ - **Visual polish** β€” Improved focus outlines and pointer-events handling
32
61
 
33
62
  ## 🧩 Supports
34
63
 
35
- - Autoplay with configurable interval
36
- - Infinite loop
37
- - Touch swipe gestures (mobile-friendly)
38
- - Navigation arrows
39
- - Pagination dots
40
- - Multiple animation variants for slides and captions
41
- - Fully customizable styles via className props
42
- - Designed for seamless integration with **Next.js** (App Router) and any React project
43
-
64
+ ### Navigation & Controls
65
+ | Feature | Description |
66
+ |---------|-------------|
67
+ | β¬…οΈβž‘οΈ **Navigation arrows** | Fully customizable via `arrowClassName` |
68
+ | πŸ”˜ **Pagination dots** | Active states with smooth transitions |
69
+ | ⌨️ **Keyboard navigation** | Arrow keys (auto-adapts to RTL) |
70
+ | πŸ‘† **Touch swipe gestures** | Momentum-based with elastic snap-back |
71
+ | πŸ–±οΈ **Drag to slide** | Desktop support with spring physics |
72
+ | ♾️ **Infinite loop** | Seamless wrapping from last to first |
73
+
74
+ ### Autoplay System
75
+ | Feature | Options | Default |
76
+ |---------|---------|---------|
77
+ | ⏯️ **Interval control** | `autoPlayInterval` (ms) | `3000` |
78
+ | πŸ”„ **Direction control** πŸ†• | `"forward"` \| `"reverse"` | `"forward"` |
79
+ | ⏸️ **Pause on hover** πŸ†• | `pauseOnHover` | `true` |
80
+ | ⏸️ **Pause on focus** πŸ†• | `pauseOnFocus` | `true` |
81
+ | ⏸️ **Pause on drag** πŸ†• | `pauseOnDrag` | `true` |
82
+ | πŸ“± **Tab visibility** | Auto-pauses when hidden | Built-in |
83
+
84
+ ### Animation Library
85
+
86
+ #### Slide Animations (`animation` prop)
87
+ | Value | Effect |
88
+ |-------|--------|
89
+ | `slideLeft` | Enters from right, exits to left |
90
+ | `slideRight` | Enters from left, exits to right |
91
+ | `slideTop` | Enters from bottom, exits to top |
92
+ | `slideBottom` | Enters from top, exits to bottom |
93
+ | `fade` | Smooth fade in/out |
94
+ | `fadeIn` | Fade in only (no exit fade) |
95
+ | `zoomIn` | Zooms in from small to full |
96
+ | `zoomOut` | Zooms out from large to normal |
97
+ | `flip` | Flips like a card (horizontal axis) |
98
+ | `bounce` | Bounces in with elastic easing |
99
+
100
+ #### Caption Animations (`captionAnimation` prop)
101
+ - Supports all animation values above
102
+ - **Independent timing**:
103
+ - `captionDelay` (default: `0.5`s) β€” Delay before caption starts
104
+ - `captionDuration` πŸ†• (default: `0.8`s) β€” Animation duration
105
+ - Perfect for creating layered reveal effects
106
+
107
+ ### Internationalization (RTL) πŸ†•
108
+ | Aspect | Behavior in RTL mode |
109
+ |--------|---------------------|
110
+ | **Swipe direction** | Swipe left β†’ next, swipe right β†’ previous |
111
+ | **Arrow positions** | Left arrow becomes "Next", right arrow becomes "Previous" |
112
+ | **Default animation** | Automatically switches to `slideRight` |
113
+ | **Layout** | `dir="rtl"` applied to root container |
114
+ | **Pagination** | Dots display in reverse order visually |
115
+ | **ARIA labels** | Automatically swap for arrows |
116
+
117
+ ### Customization API
118
+ | Prop | Targets |
119
+ |------|---------|
120
+ | `className` | Main container |
121
+ | `slideClassName` | Individual slide wrapper |
122
+ | `captionClassName` | Caption overlay |
123
+ | `arrowClassName` | Navigation arrows (both) |
124
+ | `paginationClassName` | Dots container |
125
+ | `dotClassName` | Individual pagination dots |
126
+
127
+ ### Performance Optimizations
128
+ - ⚑ **Lazy loading** β€” Non-active slides use `loading="lazy"`
129
+ - πŸ–ΌοΈ **Image optimization** β€” `decoding="async"`, `draggable=false`
130
+ - 🧹 **Clean architecture** β€” No legacy touch handlers
131
+ - πŸ”„ **Smart re-renders** β€” Optimized with `useCallback` and `useMemo`
132
+
133
+ ### Accessibility
134
+ - πŸ” **Visible focus ring** β€” Clear keyboard navigation indicators
135
+ - 🏷️ **ARIA labels** β€” Proper roles and descriptions
136
+ - ⌨️ **Full keyboard support** β€” Arrow keys, tab navigation
137
+ - πŸ“’ **Live regions** β€” `aria-live="polite"` (off when autoplay active)
138
+ - 🎯 **Focus management** β€” Container receives focus, maintains context
139
+
140
+ ### Technical Stack
141
+ - βš›οΈ **React 18+** β€” Modern hooks architecture
142
+ - 🎭 **Framer Motion** β€” Production-ready animations
143
+ - 🌬️ **Tailwind CSS v4** β€” Utility-first styling
144
+ - πŸ“¦ **TypeScript** β€” Full type definitions included
145
+ - πŸ”Ό **Next.js** β€” App Router compatible with `'use client'`
44
146
 
45
147
  ## βš™οΈ Installation
46
148
 
@@ -55,11 +157,22 @@ pnpm add nexlide
55
157
 
56
158
  ## πŸ“¦ Peer Dependencies
57
159
 
58
- These dependencies are usually already present in React/Next.js projects:
160
+ These dependencies are usually already present in React / Next.js projects:
161
+
162
+ - react (>=18)
163
+ - framer-motion (required)
164
+
165
+ ### Optional (Styling Utilities)
166
+
167
+ Nexlide uses a `cn()` utility internally for className merging, inspired by the common Tailwind pattern.
59
168
 
60
- - react, react-dom
61
- - framer-motion
62
- - clsx, tailwind-merge, class-variance-authority
169
+ If you are customizing or extending the component and want to reuse this utility, it relies on:
170
+
171
+ - clsx
172
+ - tailwind-merge
173
+ - class-variance-authority
174
+
175
+ > ⚠️ These are already bundled within Nexlide and **do NOT need to be installed manually** unless you plan to use the same utility pattern in your own components.
63
176
 
64
177
 
65
178
  ## πŸš€ Usage (Next.js App Router)
@@ -67,29 +180,38 @@ These dependencies are usually already present in React/Next.js projects:
67
180
  The component is a **Client Component** β€” you **must** use it inside a file that starts with `'use client';`
68
181
 
69
182
  ```tsx
70
- 'use client' // ← Required in Next.js App Router
183
+ 'use client'; // ← Required in Next.js App Router
71
184
 
72
185
  import { Carousel } from 'nexlide'
73
186
 
74
- const slides = [
187
+ const carouselItems = [
188
+ {
189
+ imageUrl: "https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=1200&q=75&fm=webp",
190
+ title: "Incredible Mountains",
191
+ description: "A breathtaking landscape at sunset",
192
+ },
193
+ {
194
+ imageUrl: "https://images.unsplash.com/photo-1507525428034-b723cf961d3e?w=1200&q=75&fm=webp",
195
+ },
196
+ {
197
+ imageUrl: "https://images.unsplash.com/photo-1477959858617-67f85cf4f1df?w=1200&q=75&fm=webp",
198
+ title: "Vibrant Night City",
199
+ },
75
200
  {
76
- imageUrl: 'https://images.unsplash.com/photo-1506905925346-21bda4d32df4',
77
- title: 'Mountain View',
78
- description: 'Breathtaking sunset over the peaks'
201
+ imageUrl: "https://images.unsplash.com/photo-1757843298369-6e5503c14bfd?w=1200&q=75&fm=webp",
202
+ description: "Neon and motion in the city that never sleeps",
79
203
  },
80
204
  {
81
- imageUrl: 'https://images.unsplash.com/photo-1507525428034-b723cf961d3e',
82
- title: 'Tropical Beach',
83
- description: 'Crystal clear waters and white sand'
205
+ imageUrl: "https://images.unsplash.com/photo-1482192505345-5655af888cc4?w=1200&q=75&fm=webp",
84
206
  },
85
- // add more...
86
- ]
207
+ // ...
208
+ ];
87
209
 
88
210
  export default function MyPage() {
89
211
  return (
90
212
  <div className="p-8">
91
213
  <Carousel
92
- items={slides}
214
+ items={carouselItems}
93
215
  autoPlay
94
216
  autoPlayInterval={5000}
95
217
  showPagination
@@ -104,6 +226,8 @@ export default function MyPage() {
104
226
  }
105
227
  ```
106
228
 
229
+ **Note:** If you're using Pages Router or a different React setup without App Router restrictions, you can omit `'use client';`.
230
+
107
231
 
108
232
  ## πŸŒ€ Available Animations
109
233
 
@@ -127,23 +251,71 @@ All animations use smooth easing curves and can be combined freely (e.g., slideL
127
251
 
128
252
  ## πŸ”§ Props
129
253
 
130
- | Prop | Type | Default | Description |
131
- |---------------------|----------------------------------------------------------------------|---------------|-----------------------------------------------------------------------------|
132
- | `items` | `CarouselItem[]` | β€” | **Required**. Array of slides: `{ imageUrl: string, title: string, description: string }` |
133
- | `autoPlay` | `boolean` | `false` | Enable automatic slide transition |
134
- | `autoPlayInterval` | `number` | `3000` | Time (ms) between slides when autoPlay is true |
135
- | `showPagination` | `boolean` | `true` | Show pagination dots |
136
- | `showArrows` | `boolean` | `true` | Show previous/next arrows |
137
- | `infiniteLoop` | `boolean` | `true` | Enable infinite looping |
138
- | `className` | `string` | β€” | Custom Tailwind classes for main container |
139
- | `slideClassName` | `string` | β€” | Custom classes for each slide wrapper |
140
- | `captionClassName` | `string` | β€” | Custom classes for caption (title + description) |
141
- | `arrowClassName` | `string` | β€” | Custom classes for navigation arrows |
142
- | `paginationClassName`| `string` | β€” | Custom classes for pagination container |
143
- | `dotClassName` | `string` | β€” | Custom classes for each pagination dot |
144
- | `animation` | `"bounce" \| "fade" \| "fadeIn" \| "flip" \| "slideLeft" \| "slideRight" \| "slideTop" \| "slideBottom" \| "zoomIn" \| "zoomOut"` | `"slideLeft"` | Animation for image slide transition |
145
- | `captionAnimation` | `"bounce" \| "fade" \| "fadeIn" \| "flip" \| "slideLeft" \| "slideRight" \| "slideTop" \| "slideBottom" \| "zoomIn" \| "zoomOut"` | `"fade"` | Animation for caption appearance |
146
- `captionDelay` | `number` | `0.5` | Custom delay time in seconds |
254
+ | Prop | Type | Default | Description |
255
+ |-------------------|-----------|-------------|-----------------------------------------------------------------------------|
256
+ | `items` | `CarouselItem[]` | β€” **(required)** | Array of carousel items. Each item must include `imageUrl`, while `title` and `description` are optional. |
257
+ | `autoPlay` | `boolean` | `false` | Whether the carousel should automatically advance to the next slide. |
258
+ | `autoPlayInterval`| `number` | `3000` | Interval in milliseconds between automatic slides (only used when `autoPlay` is `true`). |
259
+ | `autoPlayDirection` | `"forward" \| "reverse"` | `"forward"` | Direction of autoplay: `"forward"` (normal) or `"reverse"` (backward). |
260
+ | `infiniteLoop` | `boolean` | `true` | Enable infinite looping (goes back to first slide after last). |
261
+ | `pauseOnHover` πŸ†• | `boolean` | `true` | Pause autoplay when the user hovers over the carousel. |
262
+ | `pauseOnFocus` πŸ†• | `boolean` | `true` | Pause autoplay when the carousel receives focus (improves accessibility). |
263
+ | `pauseOnDrag` πŸ†• | `boolean` | `true` | Pause autoplay while the user is actively dragging/swiping the carousel. |
264
+ | `showPagination` | `boolean` | `true` | Show/hide pagination dots. By default at the bottom. |
265
+ | `showArrows` | `boolean` | `true` | Show/hide navigation arrows on the sides. |
266
+ | `animation` | `AnimationType` | Animation type for slide transitions. |
267
+ | `rtl` πŸ†• | `boolean` | `false` | Enable right-to-left (RTL) mode. Reverses swipe direction, arrow positions, autoplay direction (if not overridden), and default animation. Ideal for Arabic, Hebrew, etc. |
268
+ | `className` | `string` | β€” | Additional Tailwind classes for the main carousel container. |
269
+ | `slideClassName` | `string` | β€” | Additional classes for each slide wrapper. |
270
+ | `captionClassName`| `string` | β€” | Additional classes for the caption overlay container. |
271
+ | `arrowClassName` | `string` | β€” | Additional classes for navigation arrows. |
272
+ | `paginationClassName` | `string` | β€” | Additional classes for the pagination dots container. |
273
+ | `dotClassName` | `string` | β€” | Additional classes for individual pagination dots. |
274
+ | `captionAnimation`| `AnimationType` | Animation type for the caption appearance. |
275
+ | `captionDelay` | `number` | `0.5` | Delay in seconds before the caption animation starts (after slide appears). |
276
+ | `captionDuration` πŸ†• | `number` | `0.8` | Duration in seconds of the caption animation itself. | |
277
+
278
+ #### Type: AnimationType
279
+
280
+ ```tsx
281
+ type AnimationType =
282
+ | "bounce" | "flip" | "fade" | "fadeIn"
283
+ | "slideLeft" | "slideRight" | "slideTop"
284
+ | "slideBottom" | "zoomIn" | "zoomOut";
285
+ ```
286
+
287
+ ### Important Notes
288
+
289
+ **Pause behavior**
290
+ All pause-related props (`pauseOnHover`, `pauseOnFocus`, `pauseOnDrag`) are only active when `autoPlay={true}`. If `autoPlay={false}`, they are ignored.
291
+
292
+ **RTL mode (`rtl` prop)**
293
+ When `rtl={true}`, the carousel automatically adapts for right-to-left languages (Arabic, Hebrew, Persian, etc.):
294
+
295
+ - **Swipe / Drag**: Direction is reversed
296
+ Swipe left β†’ next slide
297
+ Swipe right β†’ previous slide
298
+
299
+ - **Navigation arrows**: Positions and actions are mirrored
300
+ Left arrow becomes "Next"
301
+ Right arrow becomes "Previous"
302
+
303
+ - **Default animation**: Switches to `slideRight` (instead of `slideLeft`) when no `animation` prop is specified
304
+
305
+ - **Layout & direction**: `dir="rtl"` is applied to the root container, ensuring correct text flow, gradient direction, positioning, and CSS mirroring
306
+
307
+ **Example usage in RTL context**:
308
+ ```tsx
309
+ <Carousel
310
+ rtl={true}
311
+ items={items}
312
+ autoPlay
313
+ autoPlayInterval={4000}
314
+ animation="slideRight" // recommended, but optional
315
+ showArrows
316
+ showPagination
317
+ />
318
+ ```
147
319
 
148
320
 
149
321
  ## πŸ› οΈ Development
@@ -1,25 +1,32 @@
1
+ import * as React from "react";
1
2
  import { slideVariants } from "./lib/animations";
2
3
  interface CarouselItem {
3
4
  imageUrl: string;
4
- title: string;
5
- description: string;
5
+ title?: string;
6
+ description?: string;
6
7
  }
7
8
  interface CarouselProps {
8
9
  items: CarouselItem[];
9
10
  autoPlay?: boolean;
10
11
  autoPlayInterval?: number;
12
+ autoPlayDirection?: "forward" | "reverse";
13
+ infiniteLoop?: boolean;
14
+ pauseOnHover?: boolean;
15
+ pauseOnFocus?: boolean;
16
+ pauseOnDrag?: boolean;
11
17
  showPagination?: boolean;
12
18
  showArrows?: boolean;
13
- infiniteLoop?: boolean;
19
+ animation?: keyof typeof slideVariants;
20
+ rtl?: boolean;
14
21
  className?: string;
15
22
  slideClassName?: string;
16
- captionClassName?: string;
17
23
  arrowClassName?: string;
18
24
  paginationClassName?: string;
19
25
  dotClassName?: string;
20
- animation?: keyof typeof slideVariants;
26
+ captionClassName?: string;
21
27
  captionAnimation?: keyof typeof slideVariants;
22
28
  captionDelay?: number;
29
+ captionDuration?: number;
23
30
  }
24
- export default function Carousel({ items, autoPlay, autoPlayInterval, showPagination, showArrows, infiniteLoop, className, slideClassName, captionClassName, arrowClassName, paginationClassName, dotClassName, animation, captionAnimation, captionDelay, }: CarouselProps): import("react/jsx-runtime").JSX.Element | null;
31
+ export default function Carousel(props: CarouselProps): React.ReactElement | null;
25
32
  export {};