nexlide 1.0.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/LICENSE +21 -0
- package/README.md +141 -0
- package/dist/Carousel.d.ts +25 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.esm.js +110 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.js +112 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/animations.d.ts +2 -0
- package/dist/lib/utils.d.ts +2 -0
- package/package.json +63 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026, Nexlide.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# Nexlide
|
|
2
|
+
|
|
3
|
+
A modern, lightweight, and fully customizable React carousel component built with **Framer Motion** for smooth animations and **Tailwind CSS** for flexible styling.
|
|
4
|
+
|
|
5
|
+
## Supports
|
|
6
|
+
|
|
7
|
+
- Autoplay with configurable interval
|
|
8
|
+
- Infinite loop
|
|
9
|
+
- Touch swipe gestures (mobile-friendly)
|
|
10
|
+
- Navigation arrows
|
|
11
|
+
- Pagination dots
|
|
12
|
+
- Multiple animation variants for slides and captions
|
|
13
|
+
- Fully customizable styles via className props
|
|
14
|
+
- Designed for seamless integration with **Next.js** (App Router) and any React project
|
|
15
|
+
|
|
16
|
+
## Features
|
|
17
|
+
|
|
18
|
+
- Smooth slide transitions (fade, slide left/right/top/bottom)
|
|
19
|
+
- Independent caption animations (title + description)
|
|
20
|
+
- Responsive design
|
|
21
|
+
- Lazy loading images
|
|
22
|
+
- ARIA accessible
|
|
23
|
+
- Dark mode compatible
|
|
24
|
+
- No external CSS import required (uses Tailwind classes inline)
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install nexlide
|
|
30
|
+
# or
|
|
31
|
+
yarn add nexlide
|
|
32
|
+
# or
|
|
33
|
+
pnpm add nexlide
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Peer Dependencies
|
|
37
|
+
|
|
38
|
+
These dependencies are usually already present in React/Next.js projects:
|
|
39
|
+
|
|
40
|
+
- react, react-dom
|
|
41
|
+
- framer-motion
|
|
42
|
+
- clsx, tailwind-merge, class-variance-authority
|
|
43
|
+
|
|
44
|
+
## Usage (Next.js App Router)
|
|
45
|
+
|
|
46
|
+
The component is a **Client Component** — you **must** use it inside a file that starts with `'use client';`
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
'use client' // ← Required in Next.js App Router
|
|
50
|
+
|
|
51
|
+
import { Carousel } from 'nexlide'
|
|
52
|
+
|
|
53
|
+
const slides = [
|
|
54
|
+
{
|
|
55
|
+
imageUrl: 'https://images.unsplash.com/photo-1506905925346-21bda4d32df4',
|
|
56
|
+
title: 'Mountain View',
|
|
57
|
+
description: 'Breathtaking sunset over the peaks'
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
imageUrl: 'https://images.unsplash.com/photo-1507525428034-b723cf961d3e',
|
|
61
|
+
title: 'Tropical Beach',
|
|
62
|
+
description: 'Crystal clear waters and white sand'
|
|
63
|
+
},
|
|
64
|
+
// add more...
|
|
65
|
+
]
|
|
66
|
+
|
|
67
|
+
export default function MyPage() {
|
|
68
|
+
return (
|
|
69
|
+
<div className="p-8">
|
|
70
|
+
<Carousel
|
|
71
|
+
items={slides}
|
|
72
|
+
autoPlay
|
|
73
|
+
autoPlayInterval={5000}
|
|
74
|
+
showPagination
|
|
75
|
+
showArrows
|
|
76
|
+
infiniteLoop
|
|
77
|
+
animation="slideLeft"
|
|
78
|
+
captionAnimation="fade"
|
|
79
|
+
className="rounded-2xl shadow-2xl"
|
|
80
|
+
/>
|
|
81
|
+
</div>
|
|
82
|
+
)
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Available Animations
|
|
87
|
+
|
|
88
|
+
Use `animation` for image slide transition and `captionAnimation` for title/description appearance.
|
|
89
|
+
|
|
90
|
+
| Value | Image Slide Effect | Caption Effect |
|
|
91
|
+
|--------------|----------------------------------------|---------------------------------------|
|
|
92
|
+
| `fade` | Smooth fade in/out | Smooth fade in/out |
|
|
93
|
+
| `fadeIn` | Fade in only (no exit fade) | Fade in only |
|
|
94
|
+
| `slideLeft` | Enters from right, exits to left | Enters from right, exits to left |
|
|
95
|
+
| `slideRight` | Enters from left, exits to right | Enters from left, exits to right |
|
|
96
|
+
| `slideTop` | Enters from bottom, exits to top | Enters from bottom, exits to top |
|
|
97
|
+
| `slideBottom`| Enters from top, exits to bottom | Enters from top, exits to bottom |
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
## Props
|
|
101
|
+
|
|
102
|
+
| Prop | Type | Default | Description |
|
|
103
|
+
|---------------------|----------------------------------------------------------------------|---------------|-----------------------------------------------------------------------------|
|
|
104
|
+
| `items` | `CarouselItem[]` | — | **Required**. Array of slides: `{ imageUrl: string, title: string, description: string }` |
|
|
105
|
+
| `autoPlay` | `boolean` | `false` | Enable automatic slide transition |
|
|
106
|
+
| `autoPlayInterval` | `number` | `3000` | Time (ms) between slides when autoPlay is true |
|
|
107
|
+
| `showPagination` | `boolean` | `true` | Show pagination dots |
|
|
108
|
+
| `showArrows` | `boolean` | `true` | Show previous/next arrows |
|
|
109
|
+
| `infiniteLoop` | `boolean` | `true` | Enable infinite looping |
|
|
110
|
+
| `className` | `string` | — | Custom Tailwind classes for main container |
|
|
111
|
+
| `slideClassName` | `string` | — | Custom classes for each slide wrapper |
|
|
112
|
+
| `captionClassName` | `string` | — | Custom classes for caption (title + description) |
|
|
113
|
+
| `arrowClassName` | `string` | — | Custom classes for navigation arrows |
|
|
114
|
+
| `paginationClassName`| `string` | — | Custom classes for pagination container |
|
|
115
|
+
| `dotClassName` | `string` | — | Custom classes for each pagination dot |
|
|
116
|
+
| `animation` | `"bounce" \| "fade" \| "fadeIn" \| "flip" \| "slideLeft" \| "slideRight" \| "slideTop" \| "slideBottom" \| "zoomIn" \| "zoomOut"` | `"slideLeft"` | Animation for image slide transition |
|
|
117
|
+
| `captionAnimation` | `"bounce" \| "fade" \| "fadeIn" \| "flip" \| "slideLeft" \| "slideRight" \| "slideTop" \| "slideBottom" \| "zoomIn" \| "zoomOut"` | `"fade"` | Animation for caption appearance |
|
|
118
|
+
`captionDelay` | `number` | `0.5` | Custom delay time in seconds |
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
## Development
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
# Clone repo
|
|
125
|
+
git clone https://github.com/ERPalmer/nexlide.git
|
|
126
|
+
cd nexlide
|
|
127
|
+
|
|
128
|
+
# Install dependencies
|
|
129
|
+
npm install
|
|
130
|
+
|
|
131
|
+
# Build package
|
|
132
|
+
npm run build
|
|
133
|
+
|
|
134
|
+
# Test locally (from another project)
|
|
135
|
+
npm pack
|
|
136
|
+
# Then in your test project: npm install ../nexlide/nexlide-1.0.0.tgz
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## License
|
|
140
|
+
|
|
141
|
+
MIT License. See LICENSE for details.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { slideVariants } from "./lib/animations";
|
|
2
|
+
interface CarouselItem {
|
|
3
|
+
imageUrl: string;
|
|
4
|
+
title: string;
|
|
5
|
+
description: string;
|
|
6
|
+
}
|
|
7
|
+
interface CarouselProps {
|
|
8
|
+
items: CarouselItem[];
|
|
9
|
+
autoPlay?: boolean;
|
|
10
|
+
autoPlayInterval?: number;
|
|
11
|
+
showPagination?: boolean;
|
|
12
|
+
showArrows?: boolean;
|
|
13
|
+
infiniteLoop?: boolean;
|
|
14
|
+
className?: string;
|
|
15
|
+
slideClassName?: string;
|
|
16
|
+
captionClassName?: string;
|
|
17
|
+
arrowClassName?: string;
|
|
18
|
+
paginationClassName?: string;
|
|
19
|
+
dotClassName?: string;
|
|
20
|
+
animation?: keyof typeof slideVariants;
|
|
21
|
+
captionAnimation?: keyof typeof slideVariants;
|
|
22
|
+
captionDelay?: number;
|
|
23
|
+
}
|
|
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;
|
|
25
|
+
export {};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Carousel } from './Carousel';
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
2
|
+
import { useState, useRef, useEffect } from 'react';
|
|
3
|
+
import { AnimatePresence, motion } from 'framer-motion';
|
|
4
|
+
import { clsx } from 'clsx';
|
|
5
|
+
import { twMerge } from 'tailwind-merge';
|
|
6
|
+
|
|
7
|
+
const slideVariants = {
|
|
8
|
+
fade: {
|
|
9
|
+
initial: { opacity: 0 },
|
|
10
|
+
animate: { opacity: 1, transition: { duration: 0.6, ease: "easeInOut" } },
|
|
11
|
+
exit: { opacity: 0 },
|
|
12
|
+
},
|
|
13
|
+
fadeIn: {
|
|
14
|
+
initial: { opacity: 0 },
|
|
15
|
+
animate: { opacity: 1, transition: { duration: 0.6 } },
|
|
16
|
+
exit: { opacity: 0 },
|
|
17
|
+
},
|
|
18
|
+
slideLeft: {
|
|
19
|
+
initial: { opacity: 0, x: "100%" },
|
|
20
|
+
animate: { opacity: 1, x: 0, transition: { duration: 0.5, ease: "easeInOut" } },
|
|
21
|
+
exit: { opacity: 0, x: "-100%" },
|
|
22
|
+
},
|
|
23
|
+
slideRight: {
|
|
24
|
+
initial: { opacity: 0, x: "-100%" },
|
|
25
|
+
animate: { opacity: 1, x: 0, transition: { duration: 0.5, ease: "easeInOut" } },
|
|
26
|
+
exit: { opacity: 0, x: "100%" },
|
|
27
|
+
},
|
|
28
|
+
slideTop: {
|
|
29
|
+
initial: { opacity: 0, y: "-100%" },
|
|
30
|
+
animate: { opacity: 1, y: 0, transition: { duration: 0.5, ease: "easeInOut" } },
|
|
31
|
+
exit: { opacity: 0, y: "100%" },
|
|
32
|
+
},
|
|
33
|
+
slideBottom: {
|
|
34
|
+
initial: { opacity: 0, y: "100%" },
|
|
35
|
+
animate: { opacity: 1, y: 0, transition: { duration: 0.5, ease: "easeInOut" } },
|
|
36
|
+
exit: { opacity: 0, y: "-100%" },
|
|
37
|
+
},
|
|
38
|
+
bounce: {
|
|
39
|
+
initial: { opacity: 0, y: 40, scale: 0.9 },
|
|
40
|
+
animate: { opacity: 1, y: 0, scale: 1, transition: { duration: 0.7, ease: [0.68, -0.55, 0.265, 1.55] } }, // bounce fuerte
|
|
41
|
+
exit: { opacity: 0, y: -40, scale: 0.9 },
|
|
42
|
+
},
|
|
43
|
+
zoomIn: {
|
|
44
|
+
initial: { opacity: 0, scale: 0.7 },
|
|
45
|
+
animate: { opacity: 1, scale: 1, transition: { duration: 0.6, ease: "easeOut" } },
|
|
46
|
+
exit: { opacity: 0, scale: 0.7 },
|
|
47
|
+
},
|
|
48
|
+
zoomOut: {
|
|
49
|
+
initial: { opacity: 0, scale: 1.3 },
|
|
50
|
+
animate: { opacity: 1, scale: 1, transition: { duration: 0.6, ease: "easeOut" } },
|
|
51
|
+
exit: { opacity: 0, scale: 1.3 },
|
|
52
|
+
},
|
|
53
|
+
flip: {
|
|
54
|
+
initial: { opacity: 0, rotateY: 90 },
|
|
55
|
+
animate: { opacity: 1, rotateY: 0, transition: { duration: 0.7, ease: "easeInOut" } },
|
|
56
|
+
exit: { opacity: 0, rotateY: -90 },
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
function cn(...inputs) {
|
|
61
|
+
return twMerge(clsx(inputs));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function Carousel({ items, autoPlay = false, autoPlayInterval = 3000, showPagination = true, showArrows = true, infiniteLoop = true, className, slideClassName, captionClassName, arrowClassName, paginationClassName, dotClassName, animation = "slideLeft", captionAnimation = "fade", captionDelay = 0.5, }) {
|
|
65
|
+
var _a, _b;
|
|
66
|
+
const [currentIndex, setCurrentIndex] = useState(0);
|
|
67
|
+
const touchStartX = useRef(0);
|
|
68
|
+
const goToIndex = (index) => {
|
|
69
|
+
let newIndex = index;
|
|
70
|
+
if (infiniteLoop) {
|
|
71
|
+
newIndex = (index + items.length) % items.length;
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
newIndex = Math.max(0, Math.min(index, items.length - 1));
|
|
75
|
+
}
|
|
76
|
+
setCurrentIndex(newIndex);
|
|
77
|
+
};
|
|
78
|
+
const next = () => goToIndex(currentIndex + 1);
|
|
79
|
+
const prev = () => goToIndex(currentIndex - 1);
|
|
80
|
+
useEffect(() => {
|
|
81
|
+
if (!autoPlay)
|
|
82
|
+
return;
|
|
83
|
+
const interval = setInterval(next, autoPlayInterval);
|
|
84
|
+
return () => clearInterval(interval);
|
|
85
|
+
}, [currentIndex, autoPlay, autoPlayInterval]);
|
|
86
|
+
const handleTouchStart = (e) => {
|
|
87
|
+
touchStartX.current = e.touches[0].clientX;
|
|
88
|
+
};
|
|
89
|
+
const handleTouchMove = (e) => {
|
|
90
|
+
const diff = touchStartX.current - e.touches[0].clientX;
|
|
91
|
+
if (Math.abs(diff) > 50) {
|
|
92
|
+
if (diff > 0)
|
|
93
|
+
next();
|
|
94
|
+
else
|
|
95
|
+
prev();
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
if (items.length === 0)
|
|
99
|
+
return null;
|
|
100
|
+
return (jsxs("div", { className: cn("relative overflow-hidden w-full max-w-4xl mx-auto aspect-[4/3] rounded-xl shadow-2xl bg-gray-900", className), onTouchStart: handleTouchStart, onTouchMove: handleTouchMove, role: "region", "aria-label": "Image carousel", children: [jsx(AnimatePresence, { initial: false, mode: "wait", children: jsxs(motion.div, { className: cn("absolute inset-0", slideClassName), variants: (_a = slideVariants[animation]) !== null && _a !== void 0 ? _a : slideVariants.slideLeft, initial: "initial", animate: "animate", exit: "exit", children: [jsx("img", { src: items[currentIndex].imageUrl, alt: items[currentIndex].title || "Carousel image", className: "w-full h-full object-cover", loading: "lazy" }), jsx(AnimatePresence, { children: jsxs(motion.div, { className: cn("absolute bottom-6 left-6 right-6 bg-gradient-to-t from-black/80 to-transparent p-6 rounded-b-xl", captionClassName), variants: (_b = slideVariants[captionAnimation]) !== null && _b !== void 0 ? _b : slideVariants.fade, initial: "initial", animate: "animate", exit: "exit", transition: {
|
|
101
|
+
delay: captionDelay,
|
|
102
|
+
duration: 0.7,
|
|
103
|
+
ease: "easeOut",
|
|
104
|
+
}, children: [jsx("h3", { className: "text-2xl font-bold text-white drop-shadow-md", children: items[currentIndex].title }), jsx("p", { className: "mt-2 text-white/90 text-lg drop-shadow-sm", children: items[currentIndex].description })] }, currentIndex) })] }, currentIndex) }), showArrows && items.length > 1 && (jsxs(Fragment, { children: [jsx("button", { onClick: prev, className: cn("absolute left-4 top-1/2 -translate-y-1/2 z-10 w-12 h-12 flex items-center justify-center rounded-full bg-black/50 text-white text-3xl hover:bg-black/70 transition-all duration-200 shadow-lg", arrowClassName), "aria-label": "Previous", children: "\u2039" }), jsx("button", { onClick: next, className: cn("absolute right-4 top-1/2 -translate-y-1/2 z-10 w-12 h-12 flex items-center justify-center rounded-full bg-black/50 text-white text-3xl hover:bg-black/70 transition-all duration-200 shadow-lg", arrowClassName), "aria-label": "Next", children: "\u203A" })] })), showPagination && items.length > 1 && (jsx("div", { className: cn("absolute bottom-4 left-1/2 -translate-x-1/2 z-10 flex gap-3", paginationClassName), children: items.map((_, idx) => (jsx("button", { onClick: () => goToIndex(idx), className: cn("w-3 h-3 rounded-full transition-all duration-300 shadow-md", idx === currentIndex
|
|
105
|
+
? "bg-white scale-125 shadow-white/50"
|
|
106
|
+
: "bg-white/50 hover:bg-white/80", dotClassName), "aria-label": `Go to slide ${idx + 1}` }, idx))) }))] }));
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export { Carousel };
|
|
110
|
+
//# sourceMappingURL=index.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":["../src/lib/animations.ts","../src/lib/utils.ts","../src/Carousel.tsx"],"sourcesContent":["import { Variants } from \"framer-motion\";\r\n\r\nexport const slideVariants: Record<string, Variants> = {\r\n fade: {\r\n initial: { opacity: 0 },\r\n animate: { opacity: 1, transition: { duration: 0.6, ease: \"easeInOut\" } },\r\n exit: { opacity: 0 },\r\n },\r\n fadeIn: {\r\n initial: { opacity: 0 },\r\n animate: { opacity: 1, transition: { duration: 0.6 } },\r\n exit: { opacity: 0 },\r\n },\r\n slideLeft: {\r\n initial: { opacity: 0, x: \"100%\" },\r\n animate: { opacity: 1, x: 0, transition: { duration: 0.5, ease: \"easeInOut\" } },\r\n exit: { opacity: 0, x: \"-100%\" },\r\n },\r\n slideRight: {\r\n initial: { opacity: 0, x: \"-100%\" },\r\n animate: { opacity: 1, x: 0, transition: { duration: 0.5, ease: \"easeInOut\" } },\r\n exit: { opacity: 0, x: \"100%\" },\r\n },\r\n slideTop: {\r\n initial: { opacity: 0, y: \"-100%\" },\r\n animate: { opacity: 1, y: 0, transition: { duration: 0.5, ease: \"easeInOut\" } },\r\n exit: { opacity: 0, y: \"100%\" },\r\n },\r\n slideBottom: {\r\n initial: { opacity: 0, y: \"100%\" },\r\n animate: { opacity: 1, y: 0, transition: { duration: 0.5, ease: \"easeInOut\" } },\r\n exit: { opacity: 0, y: \"-100%\" },\r\n },\r\n bounce: {\r\n initial: { opacity: 0, y: 40, scale: 0.9 },\r\n animate: { opacity: 1, y: 0, scale: 1, transition: { duration: 0.7, ease: [0.68, -0.55, 0.265, 1.55] } }, // bounce fuerte\r\n exit: { opacity: 0, y: -40, scale: 0.9 },\r\n },\r\n zoomIn: {\r\n initial: { opacity: 0, scale: 0.7 },\r\n animate: { opacity: 1, scale: 1, transition: { duration: 0.6, ease: \"easeOut\" } },\r\n exit: { opacity: 0, scale: 0.7 },\r\n },\r\n zoomOut: {\r\n initial: { opacity: 0, scale: 1.3 },\r\n animate: { opacity: 1, scale: 1, transition: { duration: 0.6, ease: \"easeOut\" } },\r\n exit: { opacity: 0, scale: 1.3 },\r\n },\r\n flip: {\r\n initial: { opacity: 0, rotateY: 90 },\r\n animate: { opacity: 1, rotateY: 0, transition: { duration: 0.7, ease: \"easeInOut\" } },\r\n exit: { opacity: 0, rotateY: -90 },\r\n },\r\n};","import { clsx, type ClassValue } from \"clsx\";\r\nimport { twMerge } from \"tailwind-merge\";\r\n\r\nexport function cn(...inputs: ClassValue[]) {\r\n return twMerge(clsx(inputs));\r\n}","\"use client\";\r\n\r\nimport React, { useState, useEffect, useRef } from \"react\";\r\nimport { motion, AnimatePresence } from \"framer-motion\";\r\nimport { slideVariants } from \"./lib/animations\";\r\nimport { cn } from \"./lib/utils\";\r\n\r\ninterface CarouselItem {\r\n imageUrl: string;\r\n title: string;\r\n description: string;\r\n}\r\n\r\ninterface CarouselProps {\r\n items: CarouselItem[];\r\n autoPlay?: boolean;\r\n autoPlayInterval?: number;\r\n showPagination?: boolean;\r\n showArrows?: boolean;\r\n infiniteLoop?: boolean;\r\n className?: string;\r\n slideClassName?: string;\r\n captionClassName?: string;\r\n arrowClassName?: string;\r\n paginationClassName?: string;\r\n dotClassName?: string;\r\n animation?: keyof typeof slideVariants;\r\n captionAnimation?: keyof typeof slideVariants;\r\n captionDelay?: number;\r\n}\r\n\r\nexport default function Carousel({\r\n items,\r\n autoPlay = false,\r\n autoPlayInterval = 3000,\r\n showPagination = true,\r\n showArrows = true,\r\n infiniteLoop = true,\r\n className,\r\n slideClassName,\r\n captionClassName,\r\n arrowClassName,\r\n paginationClassName,\r\n dotClassName,\r\n animation = \"slideLeft\",\r\n captionAnimation = \"fade\",\r\n captionDelay = 0.5,\r\n}: CarouselProps) {\r\n const [currentIndex, setCurrentIndex] = useState(0);\r\n const touchStartX = useRef(0);\r\n\r\n const goToIndex = (index: number) => {\r\n let newIndex = index;\r\n if (infiniteLoop) {\r\n newIndex = (index + items.length) % items.length;\r\n } else {\r\n newIndex = Math.max(0, Math.min(index, items.length - 1));\r\n }\r\n setCurrentIndex(newIndex);\r\n };\r\n\r\n const next = () => goToIndex(currentIndex + 1);\r\n const prev = () => goToIndex(currentIndex - 1);\r\n\r\n useEffect(() => {\r\n if (!autoPlay) return;\r\n const interval = setInterval(next, autoPlayInterval);\r\n return () => clearInterval(interval);\r\n }, [currentIndex, autoPlay, autoPlayInterval]);\r\n\r\n const handleTouchStart = (e: React.TouchEvent) => {\r\n touchStartX.current = e.touches[0].clientX;\r\n };\r\n\r\n const handleTouchMove = (e: React.TouchEvent) => {\r\n const diff = touchStartX.current - e.touches[0].clientX;\r\n if (Math.abs(diff) > 50) {\r\n if (diff > 0) next();\r\n else prev();\r\n }\r\n };\r\n\r\n if (items.length === 0) return null;\r\n\r\n return (\r\n <div\r\n className={cn(\r\n \"relative overflow-hidden w-full max-w-4xl mx-auto aspect-[4/3] rounded-xl shadow-2xl bg-gray-900\",\r\n className\r\n )}\r\n onTouchStart={handleTouchStart}\r\n onTouchMove={handleTouchMove}\r\n role=\"region\"\r\n aria-label=\"Image carousel\"\r\n >\r\n <AnimatePresence initial={false} mode=\"wait\">\r\n <motion.div\r\n key={currentIndex}\r\n className={cn(\"absolute inset-0\", slideClassName)}\r\n variants={slideVariants[animation] ?? slideVariants.slideLeft}\r\n initial=\"initial\"\r\n animate=\"animate\"\r\n exit=\"exit\"\r\n >\r\n <img\r\n src={items[currentIndex].imageUrl}\r\n alt={items[currentIndex].title || \"Carousel image\"}\r\n className=\"w-full h-full object-cover\"\r\n loading=\"lazy\"\r\n />\r\n <AnimatePresence>\r\n <motion.div\r\n key={currentIndex}\r\n className={cn(\r\n \"absolute bottom-6 left-6 right-6 bg-gradient-to-t from-black/80 to-transparent p-6 rounded-b-xl\",\r\n captionClassName\r\n )}\r\n variants={slideVariants[captionAnimation] ?? slideVariants.fade}\r\n initial=\"initial\"\r\n animate=\"animate\"\r\n exit=\"exit\"\r\n transition={{\r\n delay: captionDelay,\r\n duration: 0.7,\r\n ease: \"easeOut\",\r\n }}\r\n >\r\n <h3 className=\"text-2xl font-bold text-white drop-shadow-md\">\r\n {items[currentIndex].title}\r\n </h3>\r\n <p className=\"mt-2 text-white/90 text-lg drop-shadow-sm\">\r\n {items[currentIndex].description}\r\n </p>\r\n </motion.div>\r\n </AnimatePresence>\r\n </motion.div>\r\n </AnimatePresence>\r\n\r\n {showArrows && items.length > 1 && (\r\n <>\r\n <button\r\n onClick={prev}\r\n className={cn(\r\n \"absolute left-4 top-1/2 -translate-y-1/2 z-10 w-12 h-12 flex items-center justify-center rounded-full bg-black/50 text-white text-3xl hover:bg-black/70 transition-all duration-200 shadow-lg\",\r\n arrowClassName\r\n )}\r\n aria-label=\"Previous\"\r\n >\r\n ‹\r\n </button>\r\n\r\n <button\r\n onClick={next}\r\n className={cn(\r\n \"absolute right-4 top-1/2 -translate-y-1/2 z-10 w-12 h-12 flex items-center justify-center rounded-full bg-black/50 text-white text-3xl hover:bg-black/70 transition-all duration-200 shadow-lg\",\r\n arrowClassName\r\n )}\r\n aria-label=\"Next\"\r\n >\r\n ›\r\n </button>\r\n </>\r\n )}\r\n\r\n {showPagination && items.length > 1 && (\r\n <div\r\n className={cn(\r\n \"absolute bottom-4 left-1/2 -translate-x-1/2 z-10 flex gap-3\",\r\n paginationClassName\r\n )}\r\n >\r\n {items.map((_, idx) => (\r\n <button\r\n key={idx}\r\n onClick={() => goToIndex(idx)}\r\n className={cn(\r\n \"w-3 h-3 rounded-full transition-all duration-300 shadow-md\",\r\n idx === currentIndex\r\n ? \"bg-white scale-125 shadow-white/50\"\r\n : \"bg-white/50 hover:bg-white/80\",\r\n dotClassName\r\n )}\r\n aria-label={`Go to slide ${idx + 1}`}\r\n />\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n"],"names":["_jsxs","_jsx","_Fragment"],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var react = require('react');
|
|
5
|
+
var framerMotion = require('framer-motion');
|
|
6
|
+
var clsx = require('clsx');
|
|
7
|
+
var tailwindMerge = require('tailwind-merge');
|
|
8
|
+
|
|
9
|
+
const slideVariants = {
|
|
10
|
+
fade: {
|
|
11
|
+
initial: { opacity: 0 },
|
|
12
|
+
animate: { opacity: 1, transition: { duration: 0.6, ease: "easeInOut" } },
|
|
13
|
+
exit: { opacity: 0 },
|
|
14
|
+
},
|
|
15
|
+
fadeIn: {
|
|
16
|
+
initial: { opacity: 0 },
|
|
17
|
+
animate: { opacity: 1, transition: { duration: 0.6 } },
|
|
18
|
+
exit: { opacity: 0 },
|
|
19
|
+
},
|
|
20
|
+
slideLeft: {
|
|
21
|
+
initial: { opacity: 0, x: "100%" },
|
|
22
|
+
animate: { opacity: 1, x: 0, transition: { duration: 0.5, ease: "easeInOut" } },
|
|
23
|
+
exit: { opacity: 0, x: "-100%" },
|
|
24
|
+
},
|
|
25
|
+
slideRight: {
|
|
26
|
+
initial: { opacity: 0, x: "-100%" },
|
|
27
|
+
animate: { opacity: 1, x: 0, transition: { duration: 0.5, ease: "easeInOut" } },
|
|
28
|
+
exit: { opacity: 0, x: "100%" },
|
|
29
|
+
},
|
|
30
|
+
slideTop: {
|
|
31
|
+
initial: { opacity: 0, y: "-100%" },
|
|
32
|
+
animate: { opacity: 1, y: 0, transition: { duration: 0.5, ease: "easeInOut" } },
|
|
33
|
+
exit: { opacity: 0, y: "100%" },
|
|
34
|
+
},
|
|
35
|
+
slideBottom: {
|
|
36
|
+
initial: { opacity: 0, y: "100%" },
|
|
37
|
+
animate: { opacity: 1, y: 0, transition: { duration: 0.5, ease: "easeInOut" } },
|
|
38
|
+
exit: { opacity: 0, y: "-100%" },
|
|
39
|
+
},
|
|
40
|
+
bounce: {
|
|
41
|
+
initial: { opacity: 0, y: 40, scale: 0.9 },
|
|
42
|
+
animate: { opacity: 1, y: 0, scale: 1, transition: { duration: 0.7, ease: [0.68, -0.55, 0.265, 1.55] } }, // bounce fuerte
|
|
43
|
+
exit: { opacity: 0, y: -40, scale: 0.9 },
|
|
44
|
+
},
|
|
45
|
+
zoomIn: {
|
|
46
|
+
initial: { opacity: 0, scale: 0.7 },
|
|
47
|
+
animate: { opacity: 1, scale: 1, transition: { duration: 0.6, ease: "easeOut" } },
|
|
48
|
+
exit: { opacity: 0, scale: 0.7 },
|
|
49
|
+
},
|
|
50
|
+
zoomOut: {
|
|
51
|
+
initial: { opacity: 0, scale: 1.3 },
|
|
52
|
+
animate: { opacity: 1, scale: 1, transition: { duration: 0.6, ease: "easeOut" } },
|
|
53
|
+
exit: { opacity: 0, scale: 1.3 },
|
|
54
|
+
},
|
|
55
|
+
flip: {
|
|
56
|
+
initial: { opacity: 0, rotateY: 90 },
|
|
57
|
+
animate: { opacity: 1, rotateY: 0, transition: { duration: 0.7, ease: "easeInOut" } },
|
|
58
|
+
exit: { opacity: 0, rotateY: -90 },
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
function cn(...inputs) {
|
|
63
|
+
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function Carousel({ items, autoPlay = false, autoPlayInterval = 3000, showPagination = true, showArrows = true, infiniteLoop = true, className, slideClassName, captionClassName, arrowClassName, paginationClassName, dotClassName, animation = "slideLeft", captionAnimation = "fade", captionDelay = 0.5, }) {
|
|
67
|
+
var _a, _b;
|
|
68
|
+
const [currentIndex, setCurrentIndex] = react.useState(0);
|
|
69
|
+
const touchStartX = react.useRef(0);
|
|
70
|
+
const goToIndex = (index) => {
|
|
71
|
+
let newIndex = index;
|
|
72
|
+
if (infiniteLoop) {
|
|
73
|
+
newIndex = (index + items.length) % items.length;
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
newIndex = Math.max(0, Math.min(index, items.length - 1));
|
|
77
|
+
}
|
|
78
|
+
setCurrentIndex(newIndex);
|
|
79
|
+
};
|
|
80
|
+
const next = () => goToIndex(currentIndex + 1);
|
|
81
|
+
const prev = () => goToIndex(currentIndex - 1);
|
|
82
|
+
react.useEffect(() => {
|
|
83
|
+
if (!autoPlay)
|
|
84
|
+
return;
|
|
85
|
+
const interval = setInterval(next, autoPlayInterval);
|
|
86
|
+
return () => clearInterval(interval);
|
|
87
|
+
}, [currentIndex, autoPlay, autoPlayInterval]);
|
|
88
|
+
const handleTouchStart = (e) => {
|
|
89
|
+
touchStartX.current = e.touches[0].clientX;
|
|
90
|
+
};
|
|
91
|
+
const handleTouchMove = (e) => {
|
|
92
|
+
const diff = touchStartX.current - e.touches[0].clientX;
|
|
93
|
+
if (Math.abs(diff) > 50) {
|
|
94
|
+
if (diff > 0)
|
|
95
|
+
next();
|
|
96
|
+
else
|
|
97
|
+
prev();
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
if (items.length === 0)
|
|
101
|
+
return null;
|
|
102
|
+
return (jsxRuntime.jsxs("div", { className: cn("relative overflow-hidden w-full max-w-4xl mx-auto aspect-[4/3] rounded-xl shadow-2xl bg-gray-900", className), onTouchStart: handleTouchStart, onTouchMove: handleTouchMove, role: "region", "aria-label": "Image carousel", children: [jsxRuntime.jsx(framerMotion.AnimatePresence, { initial: false, mode: "wait", children: jsxRuntime.jsxs(framerMotion.motion.div, { className: cn("absolute inset-0", slideClassName), variants: (_a = slideVariants[animation]) !== null && _a !== void 0 ? _a : slideVariants.slideLeft, initial: "initial", animate: "animate", exit: "exit", children: [jsxRuntime.jsx("img", { src: items[currentIndex].imageUrl, alt: items[currentIndex].title || "Carousel image", className: "w-full h-full object-cover", loading: "lazy" }), jsxRuntime.jsx(framerMotion.AnimatePresence, { children: jsxRuntime.jsxs(framerMotion.motion.div, { className: cn("absolute bottom-6 left-6 right-6 bg-gradient-to-t from-black/80 to-transparent p-6 rounded-b-xl", captionClassName), variants: (_b = slideVariants[captionAnimation]) !== null && _b !== void 0 ? _b : slideVariants.fade, initial: "initial", animate: "animate", exit: "exit", transition: {
|
|
103
|
+
delay: captionDelay,
|
|
104
|
+
duration: 0.7,
|
|
105
|
+
ease: "easeOut",
|
|
106
|
+
}, children: [jsxRuntime.jsx("h3", { className: "text-2xl font-bold text-white drop-shadow-md", children: items[currentIndex].title }), jsxRuntime.jsx("p", { className: "mt-2 text-white/90 text-lg drop-shadow-sm", children: items[currentIndex].description })] }, currentIndex) })] }, currentIndex) }), showArrows && items.length > 1 && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("button", { onClick: prev, className: cn("absolute left-4 top-1/2 -translate-y-1/2 z-10 w-12 h-12 flex items-center justify-center rounded-full bg-black/50 text-white text-3xl hover:bg-black/70 transition-all duration-200 shadow-lg", arrowClassName), "aria-label": "Previous", children: "\u2039" }), jsxRuntime.jsx("button", { onClick: next, className: cn("absolute right-4 top-1/2 -translate-y-1/2 z-10 w-12 h-12 flex items-center justify-center rounded-full bg-black/50 text-white text-3xl hover:bg-black/70 transition-all duration-200 shadow-lg", arrowClassName), "aria-label": "Next", children: "\u203A" })] })), showPagination && items.length > 1 && (jsxRuntime.jsx("div", { className: cn("absolute bottom-4 left-1/2 -translate-x-1/2 z-10 flex gap-3", paginationClassName), children: items.map((_, idx) => (jsxRuntime.jsx("button", { onClick: () => goToIndex(idx), className: cn("w-3 h-3 rounded-full transition-all duration-300 shadow-md", idx === currentIndex
|
|
107
|
+
? "bg-white scale-125 shadow-white/50"
|
|
108
|
+
: "bg-white/50 hover:bg-white/80", dotClassName), "aria-label": `Go to slide ${idx + 1}` }, idx))) }))] }));
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
exports.Carousel = Carousel;
|
|
112
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/lib/animations.ts","../src/lib/utils.ts","../src/Carousel.tsx"],"sourcesContent":["import { Variants } from \"framer-motion\";\r\n\r\nexport const slideVariants: Record<string, Variants> = {\r\n fade: {\r\n initial: { opacity: 0 },\r\n animate: { opacity: 1, transition: { duration: 0.6, ease: \"easeInOut\" } },\r\n exit: { opacity: 0 },\r\n },\r\n fadeIn: {\r\n initial: { opacity: 0 },\r\n animate: { opacity: 1, transition: { duration: 0.6 } },\r\n exit: { opacity: 0 },\r\n },\r\n slideLeft: {\r\n initial: { opacity: 0, x: \"100%\" },\r\n animate: { opacity: 1, x: 0, transition: { duration: 0.5, ease: \"easeInOut\" } },\r\n exit: { opacity: 0, x: \"-100%\" },\r\n },\r\n slideRight: {\r\n initial: { opacity: 0, x: \"-100%\" },\r\n animate: { opacity: 1, x: 0, transition: { duration: 0.5, ease: \"easeInOut\" } },\r\n exit: { opacity: 0, x: \"100%\" },\r\n },\r\n slideTop: {\r\n initial: { opacity: 0, y: \"-100%\" },\r\n animate: { opacity: 1, y: 0, transition: { duration: 0.5, ease: \"easeInOut\" } },\r\n exit: { opacity: 0, y: \"100%\" },\r\n },\r\n slideBottom: {\r\n initial: { opacity: 0, y: \"100%\" },\r\n animate: { opacity: 1, y: 0, transition: { duration: 0.5, ease: \"easeInOut\" } },\r\n exit: { opacity: 0, y: \"-100%\" },\r\n },\r\n bounce: {\r\n initial: { opacity: 0, y: 40, scale: 0.9 },\r\n animate: { opacity: 1, y: 0, scale: 1, transition: { duration: 0.7, ease: [0.68, -0.55, 0.265, 1.55] } }, // bounce fuerte\r\n exit: { opacity: 0, y: -40, scale: 0.9 },\r\n },\r\n zoomIn: {\r\n initial: { opacity: 0, scale: 0.7 },\r\n animate: { opacity: 1, scale: 1, transition: { duration: 0.6, ease: \"easeOut\" } },\r\n exit: { opacity: 0, scale: 0.7 },\r\n },\r\n zoomOut: {\r\n initial: { opacity: 0, scale: 1.3 },\r\n animate: { opacity: 1, scale: 1, transition: { duration: 0.6, ease: \"easeOut\" } },\r\n exit: { opacity: 0, scale: 1.3 },\r\n },\r\n flip: {\r\n initial: { opacity: 0, rotateY: 90 },\r\n animate: { opacity: 1, rotateY: 0, transition: { duration: 0.7, ease: \"easeInOut\" } },\r\n exit: { opacity: 0, rotateY: -90 },\r\n },\r\n};","import { clsx, type ClassValue } from \"clsx\";\r\nimport { twMerge } from \"tailwind-merge\";\r\n\r\nexport function cn(...inputs: ClassValue[]) {\r\n return twMerge(clsx(inputs));\r\n}","\"use client\";\r\n\r\nimport React, { useState, useEffect, useRef } from \"react\";\r\nimport { motion, AnimatePresence } from \"framer-motion\";\r\nimport { slideVariants } from \"./lib/animations\";\r\nimport { cn } from \"./lib/utils\";\r\n\r\ninterface CarouselItem {\r\n imageUrl: string;\r\n title: string;\r\n description: string;\r\n}\r\n\r\ninterface CarouselProps {\r\n items: CarouselItem[];\r\n autoPlay?: boolean;\r\n autoPlayInterval?: number;\r\n showPagination?: boolean;\r\n showArrows?: boolean;\r\n infiniteLoop?: boolean;\r\n className?: string;\r\n slideClassName?: string;\r\n captionClassName?: string;\r\n arrowClassName?: string;\r\n paginationClassName?: string;\r\n dotClassName?: string;\r\n animation?: keyof typeof slideVariants;\r\n captionAnimation?: keyof typeof slideVariants;\r\n captionDelay?: number;\r\n}\r\n\r\nexport default function Carousel({\r\n items,\r\n autoPlay = false,\r\n autoPlayInterval = 3000,\r\n showPagination = true,\r\n showArrows = true,\r\n infiniteLoop = true,\r\n className,\r\n slideClassName,\r\n captionClassName,\r\n arrowClassName,\r\n paginationClassName,\r\n dotClassName,\r\n animation = \"slideLeft\",\r\n captionAnimation = \"fade\",\r\n captionDelay = 0.5,\r\n}: CarouselProps) {\r\n const [currentIndex, setCurrentIndex] = useState(0);\r\n const touchStartX = useRef(0);\r\n\r\n const goToIndex = (index: number) => {\r\n let newIndex = index;\r\n if (infiniteLoop) {\r\n newIndex = (index + items.length) % items.length;\r\n } else {\r\n newIndex = Math.max(0, Math.min(index, items.length - 1));\r\n }\r\n setCurrentIndex(newIndex);\r\n };\r\n\r\n const next = () => goToIndex(currentIndex + 1);\r\n const prev = () => goToIndex(currentIndex - 1);\r\n\r\n useEffect(() => {\r\n if (!autoPlay) return;\r\n const interval = setInterval(next, autoPlayInterval);\r\n return () => clearInterval(interval);\r\n }, [currentIndex, autoPlay, autoPlayInterval]);\r\n\r\n const handleTouchStart = (e: React.TouchEvent) => {\r\n touchStartX.current = e.touches[0].clientX;\r\n };\r\n\r\n const handleTouchMove = (e: React.TouchEvent) => {\r\n const diff = touchStartX.current - e.touches[0].clientX;\r\n if (Math.abs(diff) > 50) {\r\n if (diff > 0) next();\r\n else prev();\r\n }\r\n };\r\n\r\n if (items.length === 0) return null;\r\n\r\n return (\r\n <div\r\n className={cn(\r\n \"relative overflow-hidden w-full max-w-4xl mx-auto aspect-[4/3] rounded-xl shadow-2xl bg-gray-900\",\r\n className\r\n )}\r\n onTouchStart={handleTouchStart}\r\n onTouchMove={handleTouchMove}\r\n role=\"region\"\r\n aria-label=\"Image carousel\"\r\n >\r\n <AnimatePresence initial={false} mode=\"wait\">\r\n <motion.div\r\n key={currentIndex}\r\n className={cn(\"absolute inset-0\", slideClassName)}\r\n variants={slideVariants[animation] ?? slideVariants.slideLeft}\r\n initial=\"initial\"\r\n animate=\"animate\"\r\n exit=\"exit\"\r\n >\r\n <img\r\n src={items[currentIndex].imageUrl}\r\n alt={items[currentIndex].title || \"Carousel image\"}\r\n className=\"w-full h-full object-cover\"\r\n loading=\"lazy\"\r\n />\r\n <AnimatePresence>\r\n <motion.div\r\n key={currentIndex}\r\n className={cn(\r\n \"absolute bottom-6 left-6 right-6 bg-gradient-to-t from-black/80 to-transparent p-6 rounded-b-xl\",\r\n captionClassName\r\n )}\r\n variants={slideVariants[captionAnimation] ?? slideVariants.fade}\r\n initial=\"initial\"\r\n animate=\"animate\"\r\n exit=\"exit\"\r\n transition={{\r\n delay: captionDelay,\r\n duration: 0.7,\r\n ease: \"easeOut\",\r\n }}\r\n >\r\n <h3 className=\"text-2xl font-bold text-white drop-shadow-md\">\r\n {items[currentIndex].title}\r\n </h3>\r\n <p className=\"mt-2 text-white/90 text-lg drop-shadow-sm\">\r\n {items[currentIndex].description}\r\n </p>\r\n </motion.div>\r\n </AnimatePresence>\r\n </motion.div>\r\n </AnimatePresence>\r\n\r\n {showArrows && items.length > 1 && (\r\n <>\r\n <button\r\n onClick={prev}\r\n className={cn(\r\n \"absolute left-4 top-1/2 -translate-y-1/2 z-10 w-12 h-12 flex items-center justify-center rounded-full bg-black/50 text-white text-3xl hover:bg-black/70 transition-all duration-200 shadow-lg\",\r\n arrowClassName\r\n )}\r\n aria-label=\"Previous\"\r\n >\r\n ‹\r\n </button>\r\n\r\n <button\r\n onClick={next}\r\n className={cn(\r\n \"absolute right-4 top-1/2 -translate-y-1/2 z-10 w-12 h-12 flex items-center justify-center rounded-full bg-black/50 text-white text-3xl hover:bg-black/70 transition-all duration-200 shadow-lg\",\r\n arrowClassName\r\n )}\r\n aria-label=\"Next\"\r\n >\r\n ›\r\n </button>\r\n </>\r\n )}\r\n\r\n {showPagination && items.length > 1 && (\r\n <div\r\n className={cn(\r\n \"absolute bottom-4 left-1/2 -translate-x-1/2 z-10 flex gap-3\",\r\n paginationClassName\r\n )}\r\n >\r\n {items.map((_, idx) => (\r\n <button\r\n key={idx}\r\n onClick={() => goToIndex(idx)}\r\n className={cn(\r\n \"w-3 h-3 rounded-full transition-all duration-300 shadow-md\",\r\n idx === currentIndex\r\n ? \"bg-white scale-125 shadow-white/50\"\r\n : \"bg-white/50 hover:bg-white/80\",\r\n dotClassName\r\n )}\r\n aria-label={`Go to slide ${idx + 1}`}\r\n />\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n"],"names":["twMerge","clsx","useState","useRef","useEffect","_jsxs","_jsx","AnimatePresence","motion","_Fragment"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "nexlide",
|
|
3
|
+
"description": "Nexlide is a modern, lightweight, and fully customizable React carousel component built with Framer Motion for smooth animations and Tailwind CSS for flexible styling.",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"author": "Nexlide Team",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"private": false,
|
|
8
|
+
"keywords": [
|
|
9
|
+
"react",
|
|
10
|
+
"carousel",
|
|
11
|
+
"nextjs",
|
|
12
|
+
"tailwindcss",
|
|
13
|
+
"framer-motion",
|
|
14
|
+
"image-carousel",
|
|
15
|
+
"react-component"
|
|
16
|
+
],
|
|
17
|
+
"homepage": "https://github.com/ERPalmer/nexlide#readme",
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/ERPalmer/nexlide.git"
|
|
21
|
+
},
|
|
22
|
+
"bugs": {
|
|
23
|
+
"url": "https://github.com/ERPalmer/nexlide/issues"
|
|
24
|
+
},
|
|
25
|
+
"main": "dist/index.js",
|
|
26
|
+
"module": "dist/index.esm.js",
|
|
27
|
+
"types": "dist/index.d.ts",
|
|
28
|
+
"files": [
|
|
29
|
+
"dist"
|
|
30
|
+
],
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "rollup -c rollup.config.mjs",
|
|
33
|
+
"prepublishOnly": "npm run build"
|
|
34
|
+
},
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public"
|
|
37
|
+
},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"class-variance-authority": "^0.7.0",
|
|
40
|
+
"clsx": "^2.1.0",
|
|
41
|
+
"framer-motion": "^11.0.0 || ^12.0.0",
|
|
42
|
+
"react": "^18.0.0 || ^19.0.0-rc",
|
|
43
|
+
"react-dom": "^18.0.0 || ^19.0.0-rc",
|
|
44
|
+
"tailwind-merge": "^2.0.0"
|
|
45
|
+
},
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"class-variance-authority": "^0.7.0",
|
|
48
|
+
"clsx": "^2.1.0",
|
|
49
|
+
"framer-motion": "^11.0.0 || ^12.0.0",
|
|
50
|
+
"tailwind-merge": "^2.0.0"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@rollup/plugin-commonjs": "^28.0.0",
|
|
54
|
+
"@rollup/plugin-node-resolve": "^15.3.0",
|
|
55
|
+
"@rollup/plugin-typescript": "^12.1.0",
|
|
56
|
+
"@types/react": "^18.3.11",
|
|
57
|
+
"@types/react-dom": "^18.3.1",
|
|
58
|
+
"rollup": "^4.24.0",
|
|
59
|
+
"rollup-plugin-peer-deps-external": "^2.2.4",
|
|
60
|
+
"tslib": "^2.7.0",
|
|
61
|
+
"typescript": "^5.6.3"
|
|
62
|
+
}
|
|
63
|
+
}
|