awesome-coverflow-carousel 0.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/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 AwesomeCoverflowCarousel Contributors
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.
22
+
package/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) [2026-27] [Pravinkumar Dabade]
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,437 @@
1
+ # AwesomeCoverflowCarousel
2
+
3
+ A beautiful, interactive 3D Coverflowcarousel component for React with smooth animations, multiple themes, and flexible data handling. Perfect for showcasing products, portfolios, or any collection of items in an eye-catching carousel format.
4
+
5
+ ## Features
6
+
7
+ - **3D CoverflowCarousel** - Visually stunning 3D perspective effects
8
+ - **4 Built-in Themes** - Dark, Light, Neon, and Glass themes
9
+ - **Multiple Control Methods** - Mouse drag, keyboard arrows, touch & programmatic
10
+ - **Auto-Rotate** - Automatic carousel rotation with customizable speed
11
+ - **Responsive** - Works seamlessly on different screen sizes
12
+ - **Smooth Physics** - Realistic inertia and friction animations
13
+ - **Glow Effects** - Beautiful focus glow for the active item
14
+ - **Highly Customizable** - Full control over speed, friction, perspective, and more
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm install awesome-coverflow-carousel
20
+ ```
21
+
22
+ Or with pnpm:
23
+
24
+ ```bash
25
+ pnpm add awesome-coverflow-carousel
26
+ ```
27
+
28
+ Or with yarn:
29
+
30
+ ```bash
31
+ yarn add awesome-coverflow-carousel
32
+ ```
33
+
34
+ ## Quick Start
35
+
36
+ ```jsx
37
+ import { AwesomeCoverflowCarousel } from 'awesome-coverflow-carousel';
38
+ import 'awesome-coverflow-carousel/dist/style.css';
39
+
40
+ const slides = [
41
+ { title: 'Slide 1', description: 'First slide', image: 'url1.jpg' },
42
+ { title: 'Slide 2', description: 'Second slide', image: 'url2.jpg' },
43
+ ];
44
+
45
+ export default function App() {
46
+ return (
47
+ <div
48
+ style={{
49
+ minHeight: '100vh',
50
+ padding: '48px 20px 64px',
51
+ background:
52
+ 'radial-gradient(70% 50% at 50% 35%, rgba(0,245,255,0.18) 0%, rgba(0,0,0,0) 60%), linear-gradient(180deg, #05070f 0%, #060b1a 55%, #070b12 100%)',
53
+ color: '#e6f0ff',
54
+ display: 'flex',
55
+ flexDirection: 'column',
56
+ alignItems: 'center',
57
+ justifyContent: 'center',
58
+ gap: '18px',
59
+ }}
60
+ >
61
+ <h1 style={{ margin: 0, fontSize: 'clamp(28px, 5vw, 56px)', letterSpacing: '-0.02em' }}>
62
+ Explore the Universe of <span style={{ color: '#00f5ff' }}>Possibilities</span>
63
+ </h1>
64
+ <p style={{ margin: 0, opacity: 0.7 }}>
65
+ Explore the full spectrum of products by clicking on any card
66
+ </p>
67
+
68
+ <div style={{ width: '100%', maxWidth: 980, height: '60vh', minHeight: 420 }}>
69
+ <AwesomeCoverflowCarousel data={slides} theme="dark" />
70
+ </div>
71
+ </div>
72
+ );
73
+ }
74
+ ```
75
+
76
+ ## Data Format
77
+
78
+ Each item in the carousel requires the following structure:
79
+
80
+ ```js
81
+ const slide = {
82
+ title: 'Slide 1', // Required: Title displayed on the card
83
+ description: 'First slide', // Optional: Subtitle or description
84
+ image: 'url1.jpg', // Optional: Image URL
85
+ tag: 'Featured', // Optional: Tag label
86
+ color: '#ff6b6b', // Optional: Background color (hex)
87
+ onClick: () => {}, // Optional: Click handler
88
+ };
89
+ ```
90
+
91
+ For TypeScript users, this object shape maps directly to the `SlideData` type exported by the package.
92
+
93
+ ## Component Props
94
+
95
+ | Prop | Type | Default | Description |
96
+ |------|------|---------|-------------|
97
+ | `data` | `SlideData[]` | **Required** | Array of slide objects to display in the carousel |
98
+ | `autoRotate` | `boolean` | `true` | Enable automatic carousel rotation |
99
+ | `rotationSpeed` | `number` | `2800` | Time in milliseconds between auto-rotations |
100
+ | `friction` | `number` | `0.88` | Friction coefficient for inertia animations (0-1). Higher = more damping |
101
+ | `focusGlow` | `boolean` | `true` | Enable glow effect on the focused card |
102
+ | `theme` | `'dark' \| 'light' \| 'neon' \| 'glass'` | `'dark'` | Visual theme for the carousel |
103
+ | `perspective` | `number` | `1100` | 3D perspective depth in pixels |
104
+ | `onFocusChange` | `(index: number) => void` | `undefined` | Callback fired when the focused item changes |
105
+ | `className` | `string` | `undefined` | Custom CSS class for the carousel container |
106
+
107
+ ## Available Themes
108
+
109
+ ### Dark Theme
110
+ Modern dark theme with cyan accents. Perfect for tech products and modern designs.
111
+
112
+ ```jsx
113
+ <AwesomeCoverflowCarousel data={slides} theme="dark" />
114
+ ```
115
+
116
+ ### Light Theme
117
+ Clean light theme with violet accents. Great for portfolios and creative showcases.
118
+
119
+ ```jsx
120
+ <AwesomeCoverflowCarousel data={slides} theme="light" />
121
+ ```
122
+
123
+ ### Neon Theme
124
+ Vibrant neon magenta and cyan theme. Bold and eye-catching for entertainment and gaming.
125
+
126
+ ```jsx
127
+ <AwesomeCoverflowCarousel data={slides} theme="neon" />
128
+ ```
129
+
130
+ ### Glass Theme
131
+ Frosted glass effect with semi-transparent cards. Modern and elegant for premium brands.
132
+
133
+ ```jsx
134
+ <AwesomeCoverflowCarousel data={slides} theme="glass" />
135
+ ```
136
+
137
+ ## Usage Examples
138
+
139
+ ### Example 1: Static Data Source
140
+
141
+ Use hardcoded data directly in your component:
142
+
143
+ ```jsx
144
+ import { AwesomeCoverflowCarousel } from 'awesome-coverflow-carousel';
145
+ import 'awesome-coverflow-carousel/dist/style.css';
146
+
147
+ export default function StaticDataExample() {
148
+ const staticSlides = [
149
+ {
150
+ title: 'Product A',
151
+ description: 'Premium quality product',
152
+ image: 'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=500&h=300&fit=crop',
153
+ tag: 'Featured',
154
+ onClick: () => console.log('Product A clicked')
155
+ },
156
+ {
157
+ title: 'Product B',
158
+ description: 'Best seller item',
159
+ image: 'https://images.unsplash.com/photo-1523275335684-37898b6baf30?w=500&h=300&fit=crop',
160
+ tag: 'Sale',
161
+ onClick: () => console.log('Product B clicked')
162
+ },
163
+ {
164
+ title: 'Product C',
165
+ description: 'New arrival',
166
+ image: 'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=500&h=300&fit=crop',
167
+ tag: 'New',
168
+ onClick: () => console.log('Product C clicked')
169
+ },
170
+ {
171
+ title: 'Product D',
172
+ description: 'Limited edition',
173
+ image: 'https://images.unsplash.com/photo-1517457373614-b7152f800fd1?w=500&h=300&fit=crop',
174
+ tag: 'Limited',
175
+ onClick: () => console.log('Product D clicked')
176
+ },
177
+ ];
178
+
179
+ return (
180
+ <div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
181
+ <h1 style={{ textAlign: 'center', padding: '20px' }}>Static Data Example</h1>
182
+ <div style={{ flex: 1 }}>
183
+ <AwesomeCoverflowCarousel
184
+ data={staticSlides}
185
+ theme="dark"
186
+ onFocusChange={(index) => console.log('Focused item:', index)}
187
+ />
188
+ </div>
189
+ </div>
190
+ );
191
+ }
192
+ ```
193
+
194
+ ### Example 2: JSON File Data Source
195
+
196
+ Load carousel data from a JSON file:
197
+
198
+ ```jsx
199
+ import { useEffect, useState } from 'react';
200
+ import { AwesomeCoverflowCarousel } from 'awesome-coverflow-carousel';
201
+ import 'awesome-coverflow-carousel/dist/style.css';
202
+
203
+ export default function JSONDataExample() {
204
+ const [slides, setSlides] = useState([]);
205
+ const [loading, setLoading] = useState(true);
206
+ const [error, setError] = useState(null);
207
+
208
+ useEffect(() => {
209
+ // Load slides from JSON file in public folder
210
+ fetch('/carousel-data.json')
211
+ .then((response) => {
212
+ if (!response.ok) throw new Error('Failed to load data');
213
+ return response.json();
214
+ })
215
+ .then((data) => {
216
+ setSlides(data);
217
+ setLoading(false);
218
+ })
219
+ .catch((err) => {
220
+ setError(err.message);
221
+ setLoading(false);
222
+ });
223
+ }, []);
224
+
225
+ if (loading) return <div style={{ textAlign: 'center', padding: '20px' }}>Loading...</div>;
226
+ if (error) return <div style={{ textAlign: 'center', padding: '20px', color: 'red' }}>Error: {error}</div>;
227
+
228
+ return (
229
+ <div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
230
+ <h1 style={{ textAlign: 'center', padding: '20px' }}>JSON File Data Example</h1>
231
+ <div style={{ flex: 1 }}>
232
+ <AwesomeCoverflowCarousel
233
+ data={slides}
234
+ theme="light"
235
+ autoRotate={true}
236
+ rotationSpeed={3000}
237
+ onFocusChange={(index) => console.log('Focused item:', index)}
238
+ />
239
+ </div>
240
+ </div>
241
+ );
242
+ }
243
+ ```
244
+
245
+ **Sample `carousel-data.json` (place in `public` folder):**
246
+
247
+ ```json
248
+ [
249
+ {
250
+ "title": "Portfolio Project 1",
251
+ "description": "Award-winning design system",
252
+ "image": "https://images.unsplash.com/photo-1561070791-2526d30994b5?w=500&h=300&fit=crop",
253
+ "tag": "Design",
254
+ "color": "#1e3a8a"
255
+ },
256
+ {
257
+ "title": "Portfolio Project 2",
258
+ "description": "Enterprise web application",
259
+ "image": "https://images.unsplash.com/photo-1517694712202-14dd9538aa97?w=500&h=300&fit=crop",
260
+ "tag": "Development",
261
+ "color": "#064e3b"
262
+ },
263
+ {
264
+ "title": "Portfolio Project 3",
265
+ "description": "Mobile app with 10M+ downloads",
266
+ "image": "https://images.unsplash.com/photo-1560807707-38cc612d91b3?w=500&h=300&fit=crop",
267
+ "tag": "Mobile",
268
+ "color": "#5b1f39"
269
+ },
270
+ {
271
+ "title": "Portfolio Project 4",
272
+ "description": "Real-time data visualization",
273
+ "image": "https://images.unsplash.com/photo-1516321295223-4f2d3f2cf1e1?w=500&h=300&fit=crop",
274
+ "tag": "Analytics",
275
+ "color": "#78350f"
276
+ }
277
+ ]
278
+ ```
279
+
280
+ ### Example 3: REST API Data Source
281
+
282
+ Fetch carousel data from a REST API:
283
+
284
+ ```jsx
285
+ import { useEffect, useState } from 'react';
286
+ import { AwesomeCoverflowCarousel } from 'awesome-coverflow-carousel';
287
+ import 'awesome-coverflow-carousel/dist/style.css';
288
+
289
+ export default function RESTAPIExample() {
290
+ const [slides, setSlides] = useState([]);
291
+ const [loading, setLoading] = useState(true);
292
+ const [error, setError] = useState(null);
293
+ const [focusedItem, setFocusedItem] = useState(null);
294
+
295
+ useEffect(() => {
296
+ // Fetch from a REST API endpoint
297
+ fetch('https://api.example.com/carousel-items')
298
+ .then((response) => {
299
+ if (!response.ok) throw new Error(`HTTP ${response.status}`);
300
+ return response.json();
301
+ })
302
+ .then((data) => {
303
+ // Transform API response to match SlideData format
304
+ const transformedData = data.map((item) => ({
305
+ title: item.name || item.title,
306
+ description: item.summary || item.description,
307
+ image: item.thumbnail || item.image,
308
+ tag: item.category || item.type,
309
+ color: item.accentColor,
310
+ onClick: () => console.log(`Clicked: ${item.id}`)
311
+ }));
312
+ setSlides(transformedData);
313
+ setLoading(false);
314
+ })
315
+ .catch((err) => {
316
+ setError(err.message);
317
+ setLoading(false);
318
+ });
319
+ }, []);
320
+
321
+ const handleFocusChange = (index) => {
322
+ setFocusedItem(slides[index] || null);
323
+ console.log(`Focused on: ${slides[index]?.title}`);
324
+ };
325
+
326
+ if (loading) {
327
+ return (
328
+ <div style={{ textAlign: 'center', padding: '20px', color: '#999' }}>
329
+ Loading carousel data...
330
+ </div>
331
+ );
332
+ }
333
+
334
+ if (error) {
335
+ return (
336
+ <div style={{ textAlign: 'center', padding: '20px', color: 'red' }}>
337
+ Error loading data: {error}
338
+ </div>
339
+ );
340
+ }
341
+
342
+ return (
343
+ <div style={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
344
+ <h1 style={{ textAlign: 'center', padding: '20px' }}>REST API Data Example</h1>
345
+
346
+ {focusedItem && (
347
+ <div style={{
348
+ textAlign: 'center',
349
+ padding: '10px 20px',
350
+ backgroundColor: 'rgba(0, 245, 255, 0.1)',
351
+ borderBottom: '1px solid rgba(0, 245, 255, 0.2)',
352
+ }}>
353
+ <p>Currently viewing: <strong>{focusedItem.title}</strong></p>
354
+ {focusedItem.description && <p style={{ fontSize: '0.9em', color: '#aaa' }}>{focusedItem.description}</p>}
355
+ </div>
356
+ )}
357
+
358
+ <div style={{ flex: 1 }}>
359
+ <AwesomeCoverflowCarousel
360
+ data={slides}
361
+ theme="neon"
362
+ autoRotate={false}
363
+ friction={0.85}
364
+ perspective={1200}
365
+ focusGlow={true}
366
+ onFocusChange={handleFocusChange}
367
+ />
368
+ </div>
369
+
370
+ <div style={{
371
+ textAlign: 'center',
372
+ padding: '15px',
373
+ fontSize: '0.85em',
374
+ color: '#888',
375
+ borderTop: '1px solid rgba(255, 255, 255, 0.1)',
376
+ }}>
377
+ Use arrow keys or drag to navigate • Current count: {slides.length} items
378
+ </div>
379
+ </div>
380
+ );
381
+ }
382
+ ```
383
+
384
+ ## Interaction Methods
385
+
386
+ ### Mouse Interactions
387
+ - **Drag**: Click and drag left/right to rotate the carousel
388
+ - **Click**: Click on a side item to bring it to center
389
+
390
+ ### Keyboard Interactions
391
+ - **Arrow Left**: Rotate to previous item
392
+ - **Arrow Right**: Rotate to next item
393
+
394
+ ### Mouse Events
395
+ - **Hover**: Pauses auto-rotation when hovering over the carousel
396
+ - **Leave**: Resumes auto-rotation when mouse leaves
397
+
398
+ ## Performance Tips
399
+
400
+ 1. **Optimize Images**: Use optimized image URLs for better performance
401
+ 2. **Lazy Loading**: Load large datasets progressively
402
+ 3. **Memoize Callbacks**: Use `useCallback` for `onFocusChange` handlers
403
+ 4. **Responsive Container**: Set appropriate dimensions for different screen sizes
404
+
405
+ ```jsx
406
+ // Example with responsive sizing
407
+ <div style={{
408
+ width: '100%',
409
+ height: window.innerWidth < 768 ? '60vh' : '100vh'
410
+ }}>
411
+ <AwesomeCoverflowCarousel data={slides} />
412
+ </div>
413
+ ```
414
+
415
+ ## Styling
416
+
417
+ The component comes with built-in styles. Import the CSS file:
418
+
419
+ ```jsx
420
+ import 'awesome-coverflow-carousel/dist/style.css';
421
+ ```
422
+
423
+ All theme colors and styles are defined in the included CSS. You can override default styles with custom CSS classes:
424
+
425
+ ```css
426
+ /* Override carousel styles */
427
+ .custom-carousel {
428
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
429
+ }
430
+ ```
431
+
432
+ ```jsx
433
+ <AwesomeCoverflowCarousel
434
+ data={slides}
435
+ className="custom-carousel"
436
+ />
437
+ ```
@@ -0,0 +1,37 @@
1
+ [
2
+ {
3
+ "title": "Portfolio Project 1",
4
+ "description": "Award-winning design system",
5
+ "image": "https://images.unsplash.com/photo-1561070791-2526d30994b5?w=500&h=300&fit=crop",
6
+ "tag": "Design",
7
+ "color": "#1e3a8a"
8
+ },
9
+ {
10
+ "title": "Portfolio Project 2",
11
+ "description": "Enterprise web application",
12
+ "image": "https://images.unsplash.com/photo-1517694712202-14dd9538aa97?w=500&h=300&fit=crop",
13
+ "tag": "Development",
14
+ "color": "#064e3b"
15
+ },
16
+ {
17
+ "title": "Portfolio Project 3",
18
+ "description": "Mobile app with 10M+ downloads",
19
+ "image": "https://images.unsplash.com/photo-1560807707-38cc612d91b3?w=500&h=300&fit=crop",
20
+ "tag": "Mobile",
21
+ "color": "#5b1f39"
22
+ },
23
+ {
24
+ "title": "Portfolio Project 4",
25
+ "description": "Real-time data visualization",
26
+ "image": "https://images.unsplash.com/photo-1516321295223-4f2d3f2cf1e1?w=500&h=300&fit=crop",
27
+ "tag": "Analytics",
28
+ "color": "#78350f"
29
+ },
30
+ {
31
+ "title": "E-Commerce Platform",
32
+ "description": "Full-stack shopping experience",
33
+ "image": "https://images.unsplash.com/photo-1460925895917-adf4e565e6c1?w=500&h=300&fit=crop",
34
+ "tag": "Commerce",
35
+ "color": "#4c0519"
36
+ }
37
+ ]
package/dist/index.js ADDED
@@ -0,0 +1,310 @@
1
+ import { jsx as c, jsxs as A } from "react/jsx-runtime";
2
+ import { useRef as d, useState as tt, useCallback as v, useEffect as z, useMemo as rt } from "react";
3
+ const et = {
4
+ name: "dark",
5
+ background: "transparent",
6
+ cardBg: "rgba(10, 15, 30, 0.85)",
7
+ cardBorder: "rgba(0, 245, 255, 0.2)",
8
+ cardText: "#f1f5f9",
9
+ cardSubtext: "#94a3b8",
10
+ focusGlow: "0 0 40px rgba(0, 245, 255, 0.5), 0 0 80px rgba(0, 245, 255, 0.2)",
11
+ navBg: "rgba(0, 245, 255, 0.1)",
12
+ navText: "#00f5ff",
13
+ indicatorActive: "#00f5ff",
14
+ indicatorInactive: "rgba(0, 245, 255, 0.25)"
15
+ }, nt = {
16
+ name: "light",
17
+ background: "transparent",
18
+ cardBg: "rgba(255, 255, 255, 0.92)",
19
+ cardBorder: "rgba(124, 58, 237, 0.25)",
20
+ cardText: "#1e293b",
21
+ cardSubtext: "#64748b",
22
+ focusGlow: "0 0 40px rgba(124, 58, 237, 0.35), 0 8px 32px rgba(0,0,0,0.15)",
23
+ navBg: "rgba(124, 58, 237, 0.1)",
24
+ navText: "#7c3aed",
25
+ indicatorActive: "#7c3aed",
26
+ indicatorInactive: "rgba(124, 58, 237, 0.2)"
27
+ }, at = {
28
+ name: "neon",
29
+ background: "transparent",
30
+ cardBg: "rgba(5, 0, 20, 0.9)",
31
+ cardBorder: "rgba(255, 0, 255, 0.4)",
32
+ cardText: "#fff",
33
+ cardSubtext: "#f0abfc",
34
+ focusGlow: "0 0 50px rgba(255,0,255,0.6), 0 0 100px rgba(0,255,255,0.3)",
35
+ navBg: "rgba(255, 0, 255, 0.1)",
36
+ navText: "#ff00ff",
37
+ indicatorActive: "#ff00ff",
38
+ indicatorInactive: "rgba(255,0,255,0.2)"
39
+ }, ot = {
40
+ name: "glass",
41
+ background: "transparent",
42
+ cardBg: "rgba(255, 255, 255, 0.08)",
43
+ cardBorder: "rgba(255, 255, 255, 0.2)",
44
+ cardText: "#ffffff",
45
+ cardSubtext: "rgba(255,255,255,0.65)",
46
+ focusGlow: "0 8px 32px rgba(255,255,255,0.15), inset 0 1px 0 rgba(255,255,255,0.3)",
47
+ navBg: "rgba(255,255,255,0.1)",
48
+ navText: "#ffffff",
49
+ indicatorActive: "#ffffff",
50
+ indicatorInactive: "rgba(255,255,255,0.3)"
51
+ }, W = {
52
+ dark: et,
53
+ light: nt,
54
+ neon: at,
55
+ glass: ot
56
+ }, j = 220, H = 300, X = 155, it = 55, Y = 0.8, ct = 0.64, st = 0.72, dt = 0.4, lt = 3.4;
57
+ function bt({
58
+ data: e,
59
+ autoRotate: s = !0,
60
+ rotationSpeed: l = 2800,
61
+ friction: n = 0.88,
62
+ focusGlow: h = !0,
63
+ theme: q = "dark",
64
+ perspective: F = 1100,
65
+ onFocusChange: f,
66
+ className: U
67
+ }) {
68
+ const o = e.length, Z = W[q] || W.dark, p = d(0), g = d(0), b = d(0), m = d(0), u = d(!1), G = d(0), L = d(0), k = d(null), S = d(!1), [T, I] = tt(0), M = v(() => {
69
+ if (u.current) return;
70
+ const t = p.current, a = g.current, i = a - t;
71
+ b.current = b.current * n + i * (1 - n) * 0.28;
72
+ const r = t + b.current;
73
+ if (p.current = r, I(r), Math.abs(i) < 8e-4 && Math.abs(b.current) < 8e-4) {
74
+ p.current = a, I(a);
75
+ return;
76
+ }
77
+ m.current = requestAnimationFrame(M);
78
+ }, [n]), y = v(() => {
79
+ cancelAnimationFrame(m.current), m.current = requestAnimationFrame(M);
80
+ }, [M]), x = v((t) => {
81
+ g.current += t, b.current = 0, y();
82
+ const a = (Math.round(g.current) % o + o) % o;
83
+ f == null || f(a);
84
+ }, [o, y, f]);
85
+ z(() => {
86
+ if (!s) return;
87
+ const t = () => {
88
+ k.current = setTimeout(() => {
89
+ !u.current && !S.current && x(1), t();
90
+ }, l);
91
+ };
92
+ return t(), () => {
93
+ k.current && clearTimeout(k.current);
94
+ };
95
+ }, [s, l, x]);
96
+ const K = v((t) => {
97
+ u.current = !0, G.current = t.clientX, L.current = p.current, b.current = 0, cancelAnimationFrame(m.current), t.target.setPointerCapture(t.pointerId);
98
+ }, []), N = v((t) => {
99
+ if (!u.current) return;
100
+ const i = -((t.clientX - G.current) / X), r = L.current + i;
101
+ p.current = r, g.current = r, I(r);
102
+ }, []), V = v((t) => {
103
+ if (!u.current) return;
104
+ u.current = !1, g.current = Math.round(p.current), y();
105
+ const a = (Math.round(g.current) % o + o) % o;
106
+ f == null || f(a);
107
+ }, [o, y, f]);
108
+ z(() => {
109
+ const t = (a) => {
110
+ a.key === "ArrowLeft" && x(-1), a.key === "ArrowRight" && x(1);
111
+ };
112
+ return window.addEventListener("keydown", t), () => window.removeEventListener("keydown", t);
113
+ }, [x]), z(() => () => cancelAnimationFrame(m.current), []);
114
+ const J = (Math.round(T) % o + o) % o, Q = rt(() => e.map((t, a) => {
115
+ let i = a - T;
116
+ i = i - Math.round(i / o) * o;
117
+ const r = Math.abs(i), R = i >= 0 ? 1 : -1, B = r < lt, E = R * Math.min(it + r * 8, 85), $ = i * X, C = Math.max(0, 100 - r * 70), w = r < 0.05 ? 1 : r < 1.5 ? 1 - (1 - Y) * r : Math.max(ct, Y - (r - 1) * 0.1), D = r < 0.05 ? 1 : r < 1.5 ? 1 - (1 - st) * r : Math.max(0, dt - (r - 2) * 0.25), _ = Math.round(100 - r * 20);
118
+ return { slide: t, i: a, visible: B, rotY: r < 0.05 ? 0 : E, translateX: $, translateZ: C, scale: w, opacity: D, zIndex: _, dist: i };
119
+ }), [e, T, o]);
120
+ return /* @__PURE__ */ c(
121
+ "div",
122
+ {
123
+ className: U,
124
+ style: {
125
+ position: "relative",
126
+ width: "100%",
127
+ height: "100%",
128
+ cursor: u.current ? "grabbing" : "grab",
129
+ userSelect: "none",
130
+ outline: "none",
131
+ overflow: "hidden"
132
+ },
133
+ onPointerDown: K,
134
+ onPointerMove: N,
135
+ onPointerUp: V,
136
+ onMouseEnter: () => {
137
+ S.current = !0;
138
+ },
139
+ onMouseLeave: () => {
140
+ S.current = !1;
141
+ },
142
+ tabIndex: 0,
143
+ role: "region",
144
+ "aria-label": "Coverflow Carousel",
145
+ children: /* @__PURE__ */ c("div", { style: {
146
+ position: "absolute",
147
+ inset: 0,
148
+ perspective: `${F}px`,
149
+ perspectiveOrigin: "50% 50%",
150
+ display: "flex",
151
+ alignItems: "center",
152
+ justifyContent: "center"
153
+ }, children: /* @__PURE__ */ c("div", { style: { position: "relative", width: 0, height: 0, transformStyle: "preserve-3d" }, children: Q.map(({ slide: t, i: a, visible: i, rotY: r, translateX: R, translateZ: B, scale: E, opacity: $, zIndex: C, dist: w }) => {
154
+ if (!i) return null;
155
+ const D = a === J, _ = Math.abs(w);
156
+ return /* @__PURE__ */ c(
157
+ "div",
158
+ {
159
+ style: {
160
+ position: "absolute",
161
+ width: `${j}px`,
162
+ height: `${H}px`,
163
+ left: `${-j / 2}px`,
164
+ top: `${-H / 2}px`,
165
+ transform: `translateX(${R}px) translateZ(${B}px) rotateY(${r}deg) scale(${E})`,
166
+ opacity: $,
167
+ zIndex: C,
168
+ transition: u.current ? "none" : "transform 0.55s cubic-bezier(0.25,0.46,0.45,0.94), opacity 0.5s ease",
169
+ willChange: "transform, opacity",
170
+ cursor: "pointer"
171
+ },
172
+ onClick: () => {
173
+ var P, O;
174
+ _ > 0.3 ? x(Math.round(w)) : ((P = t.onClick) == null || P.call(t), (O = t.imageClick) == null || O.call(t));
175
+ },
176
+ children: /* @__PURE__ */ c(
177
+ ft,
178
+ {
179
+ slide: t,
180
+ isFocused: D,
181
+ focusGlow: h,
182
+ theme: Z
183
+ }
184
+ )
185
+ },
186
+ a
187
+ );
188
+ }) }) })
189
+ }
190
+ );
191
+ }
192
+ function ft({ slide: e, isFocused: s, focusGlow: l, theme: n }) {
193
+ const h = s && l ? n.focusGlow : void 0;
194
+ return /* @__PURE__ */ A("div", { style: {
195
+ width: "100%",
196
+ height: "100%",
197
+ borderRadius: "18px",
198
+ overflow: "hidden",
199
+ position: "relative",
200
+ background: n.cardBg,
201
+ border: `1.5px solid ${s ? n.indicatorActive : n.cardBorder}`,
202
+ boxShadow: h || (s ? "0 24px 64px rgba(0,0,0,0.65), 0 8px 24px rgba(0,0,0,0.4)" : "0 8px 32px rgba(0,0,0,0.4)"),
203
+ backdropFilter: "blur(12px)",
204
+ WebkitBackdropFilter: "blur(12px)",
205
+ transition: "border-color 0.4s, box-shadow 0.4s",
206
+ display: "flex",
207
+ flexDirection: "column"
208
+ }, children: [
209
+ /* @__PURE__ */ A("div", { style: { flex: "0 0 65%", position: "relative", overflow: "hidden" }, children: [
210
+ e.image ? /* @__PURE__ */ c(
211
+ "img",
212
+ {
213
+ src: e.image,
214
+ alt: e.title,
215
+ style: { width: "100%", height: "100%", objectFit: "cover", display: "block" }
216
+ }
217
+ ) : /* @__PURE__ */ c(ut, { title: e.title, color: e.color, accent: n.indicatorActive }),
218
+ e.tag && /* @__PURE__ */ c("span", { style: {
219
+ position: "absolute",
220
+ top: 10,
221
+ right: 10,
222
+ background: n.indicatorActive,
223
+ color: "#000",
224
+ fontSize: "9px",
225
+ fontWeight: 800,
226
+ letterSpacing: "0.08em",
227
+ padding: "3px 9px",
228
+ borderRadius: "100px",
229
+ fontFamily: "var(--font-display)",
230
+ textTransform: "uppercase"
231
+ }, children: e.tag }),
232
+ /* @__PURE__ */ c("div", { style: {
233
+ position: "absolute",
234
+ bottom: 0,
235
+ left: 0,
236
+ right: 0,
237
+ height: "50%",
238
+ background: `linear-gradient(to bottom, transparent, ${n.cardBg})`
239
+ } })
240
+ ] }),
241
+ /* @__PURE__ */ A("div", { style: {
242
+ flex: 1,
243
+ padding: "12px 16px 16px",
244
+ display: "flex",
245
+ flexDirection: "column",
246
+ justifyContent: "center",
247
+ gap: "5px"
248
+ }, children: [
249
+ /* @__PURE__ */ c("div", { style: {
250
+ fontFamily: "var(--font-display)",
251
+ fontWeight: 800,
252
+ fontSize: "15px",
253
+ color: n.cardText,
254
+ lineHeight: 1.25,
255
+ letterSpacing: "-0.02em"
256
+ }, children: e.title }),
257
+ e.description && /* @__PURE__ */ c("div", { style: {
258
+ fontFamily: "var(--font-body)",
259
+ fontSize: "11px",
260
+ color: n.cardSubtext,
261
+ lineHeight: 1.5,
262
+ fontWeight: 300
263
+ }, children: e.description }),
264
+ s && /* @__PURE__ */ c("div", { style: {
265
+ marginTop: "6px",
266
+ padding: "7px 16px",
267
+ borderRadius: "100px",
268
+ background: n.indicatorActive,
269
+ color: "#000",
270
+ fontSize: "10px",
271
+ fontWeight: 800,
272
+ fontFamily: "var(--font-display)",
273
+ letterSpacing: "0.05em",
274
+ textTransform: "uppercase",
275
+ cursor: "pointer",
276
+ alignSelf: "flex-start"
277
+ }, children: "Learn More →" })
278
+ ] })
279
+ ] });
280
+ }
281
+ function ut({ title: e, color: s, accent: l }) {
282
+ const n = ["#020d2e", "#1e1b4b", "#0c1445", "#1a0533", "#0d2137", "#1f1235", "#0a1400", "#1a1000", "#001820", "#160028"], h = s || n[e.charCodeAt(0) % n.length];
283
+ return /* @__PURE__ */ A("div", { style: {
284
+ width: "100%",
285
+ height: "100%",
286
+ background: `linear-gradient(145deg, ${h} 0%, ${l}22 100%)`,
287
+ display: "flex",
288
+ alignItems: "center",
289
+ justifyContent: "center",
290
+ position: "relative"
291
+ }, children: [
292
+ /* @__PURE__ */ c("div", { style: {
293
+ position: "absolute",
294
+ inset: 0,
295
+ background: `radial-gradient(circle at 60% 40%, ${l}38, transparent 65%)`
296
+ } }),
297
+ /* @__PURE__ */ c("span", { style: {
298
+ fontFamily: "var(--font-display)",
299
+ fontWeight: 900,
300
+ fontSize: "52px",
301
+ color: l,
302
+ opacity: 0.88,
303
+ position: "relative",
304
+ zIndex: 1
305
+ }, children: e.slice(0, 2).toUpperCase() })
306
+ ] });
307
+ }
308
+ export {
309
+ bt as AwesomeCoverflowCarousel
310
+ };
@@ -0,0 +1 @@
1
+ (function(d,t){typeof exports=="object"&&typeof module<"u"?t(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],t):(d=typeof globalThis<"u"?globalThis:d||self,t(d.AwesomeCoverflowCarousel={},d.jsxRuntime,d.React))})(this,(function(d,t,n){"use strict";const j={dark:{name:"dark",background:"transparent",cardBg:"rgba(10, 15, 30, 0.85)",cardBorder:"rgba(0, 245, 255, 0.2)",cardText:"#f1f5f9",cardSubtext:"#94a3b8",focusGlow:"0 0 40px rgba(0, 245, 255, 0.5), 0 0 80px rgba(0, 245, 255, 0.2)",navBg:"rgba(0, 245, 255, 0.1)",navText:"#00f5ff",indicatorActive:"#00f5ff",indicatorInactive:"rgba(0, 245, 255, 0.25)"},light:{name:"light",background:"transparent",cardBg:"rgba(255, 255, 255, 0.92)",cardBorder:"rgba(124, 58, 237, 0.25)",cardText:"#1e293b",cardSubtext:"#64748b",focusGlow:"0 0 40px rgba(124, 58, 237, 0.35), 0 8px 32px rgba(0,0,0,0.15)",navBg:"rgba(124, 58, 237, 0.1)",navText:"#7c3aed",indicatorActive:"#7c3aed",indicatorInactive:"rgba(124, 58, 237, 0.2)"},neon:{name:"neon",background:"transparent",cardBg:"rgba(5, 0, 20, 0.9)",cardBorder:"rgba(255, 0, 255, 0.4)",cardText:"#fff",cardSubtext:"#f0abfc",focusGlow:"0 0 50px rgba(255,0,255,0.6), 0 0 100px rgba(0,255,255,0.3)",navBg:"rgba(255, 0, 255, 0.1)",navText:"#ff00ff",indicatorActive:"#ff00ff",indicatorInactive:"rgba(255,0,255,0.2)"},glass:{name:"glass",background:"transparent",cardBg:"rgba(255, 255, 255, 0.08)",cardBorder:"rgba(255, 255, 255, 0.2)",cardText:"#ffffff",cardSubtext:"rgba(255,255,255,0.65)",focusGlow:"0 8px 32px rgba(255,255,255,0.15), inset 0 1px 0 rgba(255,255,255,0.3)",navBg:"rgba(255,255,255,0.1)",navText:"#ffffff",indicatorActive:"#ffffff",indicatorInactive:"rgba(255,255,255,0.3)"}},_=220,P=300,z=155,X=55,G=.8,Y=.64,q=.72,F=.4,U=3.4;function Z({data:o,autoRotate:l=!0,rotationSpeed:f=2800,friction:a=.88,focusGlow:v=!0,theme:V="dark",perspective:J=1100,onFocusChange:u,className:Q}){const c=o.length,ee=j[V]||j.dark,g=n.useRef(0),b=n.useRef(0),x=n.useRef(0),y=n.useRef(0),p=n.useRef(!1),L=n.useRef(0),O=n.useRef(0),w=n.useRef(null),A=n.useRef(!1),[T,S]=n.useState(0),C=n.useCallback(()=>{if(p.current)return;const e=g.current,i=b.current,s=i-e;x.current=x.current*a+s*(1-a)*.28;const r=e+x.current;if(g.current=r,S(r),Math.abs(s)<8e-4&&Math.abs(x.current)<8e-4){g.current=i,S(i);return}y.current=requestAnimationFrame(C)},[a]),m=n.useCallback(()=>{cancelAnimationFrame(y.current),y.current=requestAnimationFrame(C)},[C]),h=n.useCallback(e=>{b.current+=e,x.current=0,m();const i=(Math.round(b.current)%c+c)%c;u==null||u(i)},[c,m,u]);n.useEffect(()=>{if(!l)return;const e=()=>{w.current=setTimeout(()=>{!p.current&&!A.current&&h(1),e()},f)};return e(),()=>{w.current&&clearTimeout(w.current)}},[l,f,h]);const te=n.useCallback(e=>{p.current=!0,L.current=e.clientX,O.current=g.current,x.current=0,cancelAnimationFrame(y.current),e.target.setPointerCapture(e.pointerId)},[]),re=n.useCallback(e=>{if(!p.current)return;const s=-((e.clientX-L.current)/z),r=O.current+s;g.current=r,b.current=r,S(r)},[]),ne=n.useCallback(e=>{if(!p.current)return;p.current=!1,b.current=Math.round(g.current),m();const i=(Math.round(b.current)%c+c)%c;u==null||u(i)},[c,m,u]);n.useEffect(()=>{const e=i=>{i.key==="ArrowLeft"&&h(-1),i.key==="ArrowRight"&&h(1)};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[h]),n.useEffect(()=>()=>cancelAnimationFrame(y.current),[]);const oe=(Math.round(T)%c+c)%c,ae=n.useMemo(()=>o.map((e,i)=>{let s=i-T;s=s-Math.round(s/c)*c;const r=Math.abs(s),I=s>=0?1:-1,M=r<U,B=I*Math.min(X+r*8,85),E=s*z,$=Math.max(0,100-r*70),k=r<.05?1:r<1.5?1-(1-G)*r:Math.max(Y,G-(r-1)*.1),D=r<.05?1:r<1.5?1-(1-q)*r:Math.max(0,F-(r-2)*.25),R=Math.round(100-r*20);return{slide:e,i,visible:M,rotY:r<.05?0:B,translateX:E,translateZ:$,scale:k,opacity:D,zIndex:R,dist:s}}),[o,T,c]);return t.jsx("div",{className:Q,style:{position:"relative",width:"100%",height:"100%",cursor:p.current?"grabbing":"grab",userSelect:"none",outline:"none",overflow:"hidden"},onPointerDown:te,onPointerMove:re,onPointerUp:ne,onMouseEnter:()=>{A.current=!0},onMouseLeave:()=>{A.current=!1},tabIndex:0,role:"region","aria-label":"Coverflow Carousel",children:t.jsx("div",{style:{position:"absolute",inset:0,perspective:`${J}px`,perspectiveOrigin:"50% 50%",display:"flex",alignItems:"center",justifyContent:"center"},children:t.jsx("div",{style:{position:"relative",width:0,height:0,transformStyle:"preserve-3d"},children:ae.map(({slide:e,i,visible:s,rotY:r,translateX:I,translateZ:M,scale:B,opacity:E,zIndex:$,dist:k})=>{if(!s)return null;const D=i===oe,R=Math.abs(k);return t.jsx("div",{style:{position:"absolute",width:`${_}px`,height:`${P}px`,left:`${-_/2}px`,top:`${-P/2}px`,transform:`translateX(${I}px) translateZ(${M}px) rotateY(${r}deg) scale(${B})`,opacity:E,zIndex:$,transition:p.current?"none":"transform 0.55s cubic-bezier(0.25,0.46,0.45,0.94), opacity 0.5s ease",willChange:"transform, opacity",cursor:"pointer"},onClick:()=>{var W,H;R>.3?h(Math.round(k)):((W=e.onClick)==null||W.call(e),(H=e.imageClick)==null||H.call(e))},children:t.jsx(K,{slide:e,isFocused:D,focusGlow:v,theme:ee})},i)})})})})}function K({slide:o,isFocused:l,focusGlow:f,theme:a}){const v=l&&f?a.focusGlow:void 0;return t.jsxs("div",{style:{width:"100%",height:"100%",borderRadius:"18px",overflow:"hidden",position:"relative",background:a.cardBg,border:`1.5px solid ${l?a.indicatorActive:a.cardBorder}`,boxShadow:v||(l?"0 24px 64px rgba(0,0,0,0.65), 0 8px 24px rgba(0,0,0,0.4)":"0 8px 32px rgba(0,0,0,0.4)"),backdropFilter:"blur(12px)",WebkitBackdropFilter:"blur(12px)",transition:"border-color 0.4s, box-shadow 0.4s",display:"flex",flexDirection:"column"},children:[t.jsxs("div",{style:{flex:"0 0 65%",position:"relative",overflow:"hidden"},children:[o.image?t.jsx("img",{src:o.image,alt:o.title,style:{width:"100%",height:"100%",objectFit:"cover",display:"block"}}):t.jsx(N,{title:o.title,color:o.color,accent:a.indicatorActive}),o.tag&&t.jsx("span",{style:{position:"absolute",top:10,right:10,background:a.indicatorActive,color:"#000",fontSize:"9px",fontWeight:800,letterSpacing:"0.08em",padding:"3px 9px",borderRadius:"100px",fontFamily:"var(--font-display)",textTransform:"uppercase"},children:o.tag}),t.jsx("div",{style:{position:"absolute",bottom:0,left:0,right:0,height:"50%",background:`linear-gradient(to bottom, transparent, ${a.cardBg})`}})]}),t.jsxs("div",{style:{flex:1,padding:"12px 16px 16px",display:"flex",flexDirection:"column",justifyContent:"center",gap:"5px"},children:[t.jsx("div",{style:{fontFamily:"var(--font-display)",fontWeight:800,fontSize:"15px",color:a.cardText,lineHeight:1.25,letterSpacing:"-0.02em"},children:o.title}),o.description&&t.jsx("div",{style:{fontFamily:"var(--font-body)",fontSize:"11px",color:a.cardSubtext,lineHeight:1.5,fontWeight:300},children:o.description}),l&&t.jsx("div",{style:{marginTop:"6px",padding:"7px 16px",borderRadius:"100px",background:a.indicatorActive,color:"#000",fontSize:"10px",fontWeight:800,fontFamily:"var(--font-display)",letterSpacing:"0.05em",textTransform:"uppercase",cursor:"pointer",alignSelf:"flex-start"},children:"Learn More →"})]})]})}function N({title:o,color:l,accent:f}){const a=["#020d2e","#1e1b4b","#0c1445","#1a0533","#0d2137","#1f1235","#0a1400","#1a1000","#001820","#160028"],v=l||a[o.charCodeAt(0)%a.length];return t.jsxs("div",{style:{width:"100%",height:"100%",background:`linear-gradient(145deg, ${v} 0%, ${f}22 100%)`,display:"flex",alignItems:"center",justifyContent:"center",position:"relative"},children:[t.jsx("div",{style:{position:"absolute",inset:0,background:`radial-gradient(circle at 60% 40%, ${f}38, transparent 65%)`}}),t.jsx("span",{style:{fontFamily:"var(--font-display)",fontWeight:900,fontSize:"52px",color:f,opacity:.88,position:"relative",zIndex:1},children:o.slice(0,2).toUpperCase()})]})}d.AwesomeCoverflowCarousel=Z,Object.defineProperty(d,Symbol.toStringTag,{value:"Module"})}));
package/dist/style.css ADDED
@@ -0,0 +1 @@
1
+ :root{--awesome-carousel-dark-bg: #030712;--awesome-carousel-light-text: #f1f5f9;--awesome-carousel-secondary-text: #94a3b8;--awesome-carousel-cyan: #00f5ff;--awesome-carousel-violet: #7c3aed;--awesome-carousel-amber: #f59e0b;--awesome-carousel-card-dark-bg: rgba(10, 15, 30, .85);--awesome-carousel-card-dark-border: rgba(0, 245, 255, .2);--awesome-carousel-glow-dark: 0 0 40px rgba(0, 245, 255, .5), 0 0 80px rgba(0, 245, 255, .2);--awesome-carousel-nav-dark-bg: rgba(0, 245, 255, .1);--awesome-carousel-nav-dark-text: #00f5ff;--awesome-carousel-indicator-active-dark: #00f5ff;--awesome-carousel-indicator-inactive-dark: rgba(0, 245, 255, .25)}@media(prefers-color-scheme:light){:root{--awesome-carousel-dark-bg: #f8fafc;--awesome-carousel-light-text: #1e293b;--awesome-carousel-secondary-text: #64748b}}.awesome-carousel-root *,.awesome-carousel-root *:before,.awesome-carousel-root *:after{box-sizing:border-box;margin:0;padding:0}.awesome-carousel-root{position:relative;width:100%;height:100%;font-family:DM Sans,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.awesome-coverflow-carousel{position:relative;width:100%;height:100%;overflow:hidden;background:transparent;cursor:grab;-webkit-user-select:none;user-select:none;outline:none}.awesome-coverflow-carousel:active{cursor:grabbing}.awesome-coverflow-carousel[role=region]{outline:none}.awesome-coverflow-carousel:focus-visible{outline:2px solid var(--awesome-carousel-cyan);outline-offset:4px}.awesome-carousel-stage{position:absolute;top:0;right:0;bottom:0;left:0;display:flex;align-items:center;justify-content:center;perspective:1100px;perspective-origin:50% 50%;transform-style:preserve-3d}.awesome-carousel-stage__inner{position:relative;width:0;height:0;transform-style:preserve-3d}.awesome-carousel-card{position:absolute;width:220px;height:300px;border-radius:18px;overflow:hidden;will-change:transform,opacity;transform-style:preserve-3d;backface-visibility:hidden}.awesome-carousel-card--transition{transition:transform .55s cubic-bezier(.25,.46,.45,.94),opacity .5s ease}.awesome-carousel-card--no-transition{transition:none}.awesome-carousel-card:hover{z-index:1000!important}.awesome-carousel-card__content{width:100%;height:100%;display:flex;flex-direction:column;border-radius:18px;overflow:hidden;position:relative;backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);transition:border-color .4s,box-shadow .4s}.awesome-carousel-card__content--dark{background:var(--awesome-carousel-card-dark-bg);border:1.5px solid var(--awesome-carousel-card-dark-border);color:var(--awesome-carousel-light-text);box-shadow:0 8px 32px #0006}.awesome-carousel-card__content--dark.focused{border-color:var(--awesome-carousel-indicator-active-dark);box-shadow:var(--awesome-carousel-glow-dark)}.awesome-carousel-card__content--light{background:#ffffffeb;border:1.5px solid rgba(124,58,237,.25);color:#1e293b;box-shadow:0 8px 32px #00000026}.awesome-carousel-card__content--light.focused{border-color:var(--awesome-carousel-violet);box-shadow:0 0 40px #7c3aed59,0 8px 32px #00000026}.awesome-carousel-card__content--neon{background:#050014e6;border:1.5px solid rgba(255,0,255,.4);color:#fff;box-shadow:0 8px 32px #0006}.awesome-carousel-card__content--neon.focused{border-color:#f0f;box-shadow:0 0 50px #f0f9,0 0 100px #00ffff4d}.awesome-carousel-card__content--glass{background:#ffffff14;border:1.5px solid rgba(255,255,255,.2);color:#fff;box-shadow:0 8px 32px #ffffff26,inset 0 1px #ffffff4d}.awesome-carousel-card__content--glass.focused{border-color:#fff;box-shadow:0 8px 32px #fff3,inset 0 1px #fff6}.awesome-carousel-card__image-area{flex:0 0 65%;position:relative;overflow:hidden;background:#0000004d}.awesome-carousel-card__image{width:100%;height:100%;object-fit:cover;display:block;transition:transform .3s ease}.awesome-carousel-card:hover .awesome-carousel-card__image{transform:scale(1.05)}.awesome-carousel-card__image-placeholder{width:100%;height:100%;display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,#7c3aed33,#00f5ff33);color:#ffffff4d;font-size:2em}.awesome-carousel-card__text-area{flex:1;padding:16px 14px;display:flex;flex-direction:column;gap:6px;overflow:hidden}.awesome-carousel-card__title{font-size:14px;font-weight:600;line-height:1.4;text-transform:uppercase;letter-spacing:.5px;margin:0}.awesome-carousel-card__description{font-size:12px;line-height:1.3;margin:0;opacity:.8}.awesome-carousel-card__tag{display:inline-block;padding:4px 8px;border-radius:4px;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.3px;width:fit-content;margin-top:auto}.awesome-carousel-card__content--dark .awesome-carousel-card__tag{background:var(--awesome-carousel-nav-dark-bg);color:var(--awesome-carousel-nav-dark-text)}.awesome-carousel-card__content--light .awesome-carousel-card__tag{background:#7c3aed1a;color:var(--awesome-carousel-violet)}.awesome-carousel-card__content--neon .awesome-carousel-card__tag{background:#ff00ff26;color:#f0f}.awesome-carousel-card__content--glass .awesome-carousel-card__tag{background:#ffffff26;color:#fff}.sphere-item{transition:transform .2s ease}.sphere-item--lift:hover{transform:translate(-50%,-52%)!important;filter:brightness(1.1)}.sphere-item--zoom:hover{transform:translate(-50%,-50%) scale(1.12)!important}.sphere-item--tilt:hover{transform:translate(-50%,-50%) rotateY(-5deg) rotateX(5deg)!important}.sphere-item:focus{outline:none}.sphere-item:focus-visible{outline:2px solid var(--awesome-carousel-cyan);outline-offset:4px;border-radius:16px}input[type=range]{-webkit-appearance:none;width:100%;height:4px;border-radius:2px;background:#ffffff1a;outline:none;cursor:pointer}input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:14px;height:14px;border-radius:50%;background:var(--awesome-carousel-cyan);cursor:pointer;transition:box-shadow .2s ease}input[type=range]::-webkit-slider-thumb:hover{box-shadow:0 0 10px var(--awesome-carousel-cyan)}input[type=range]::-moz-range-thumb{width:14px;height:14px;border-radius:50%;background:var(--awesome-carousel-cyan);cursor:pointer;border:none;transition:box-shadow .2s ease}input[type=range]::-moz-range-thumb:hover{box-shadow:0 0 10px var(--awesome-carousel-cyan)}input[type=range]::-moz-range-track{background:transparent;border:none}input[type=range]::-moz-range-progress{background:var(--awesome-carousel-cyan);height:4px;border-radius:2px}@keyframes starfield{0%{transform:translateY(0)}to{transform:translateY(-50%)}}@keyframes pulseGlow{0%,to{opacity:.4;transform:scale(1)}50%{opacity:.8;transform:scale(1.05)}}@keyframes fadeUp{0%{opacity:0;transform:translateY(30px)}to{opacity:1;transform:translateY(0)}}@keyframes rotate360{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes cardEntrance{0%{opacity:0;transform:scale(.9)}to{opacity:1;transform:scale(1)}}@keyframes slideIn{0%{transform:translate(-20px);opacity:0}to{transform:translate(0);opacity:1}}.awesome-carousel-nav{display:flex;gap:10px;justify-content:center;padding:20px;background:transparent}.awesome-carousel-nav__button{padding:8px 16px;border:1px solid currentColor;border-radius:6px;background:transparent;color:inherit;cursor:pointer;font-size:14px;font-weight:600;text-transform:uppercase;letter-spacing:.5px;transition:all .3s ease;outline:none}.awesome-carousel-nav__button:hover{transform:translateY(-2px);box-shadow:0 4px 12px #0003}.awesome-carousel-nav__button:active{transform:translateY(0)}.awesome-carousel-nav__button:focus-visible{outline:2px solid var(--awesome-carousel-cyan);outline-offset:2px}.awesome-carousel-nav--dark .awesome-carousel-nav__button{color:var(--awesome-carousel-nav-dark-text);border-color:var(--awesome-carousel-nav-dark-text)}.awesome-carousel-nav--dark .awesome-carousel-nav__button:hover{background:var(--awesome-carousel-nav-dark-bg)}.awesome-carousel-nav--light .awesome-carousel-nav__button{color:var(--awesome-carousel-violet);border-color:var(--awesome-carousel-violet)}.awesome-carousel-nav--light .awesome-carousel-nav__button:hover{background:#7c3aed1a}.awesome-carousel-indicators{display:flex;gap:8px;justify-content:center;padding:16px;background:transparent}.awesome-carousel-indicator{width:8px;height:8px;border-radius:50%;cursor:pointer;transition:all .3s ease;border:none;padding:0}.awesome-carousel-indicator:hover{transform:scale(1.3)}.awesome-carousel-indicator:focus-visible{outline:2px solid var(--awesome-carousel-cyan);outline-offset:2px}.awesome-carousel-indicators--dark .awesome-carousel-indicator{background:var(--awesome-carousel-indicator-inactive-dark)}.awesome-carousel-indicators--dark .awesome-carousel-indicator.active{background:var(--awesome-carousel-indicator-active-dark);box-shadow:0 0 10px var(--awesome-carousel-indicator-active-dark)}.awesome-carousel-indicators--light .awesome-carousel-indicator{background:#7c3aed33}.awesome-carousel-indicators--light .awesome-carousel-indicator.active{background:var(--awesome-carousel-violet);box-shadow:0 0 10px #7c3aed80}.awesome-carousel-indicators--neon .awesome-carousel-indicator{background:#f0f3}.awesome-carousel-indicators--neon .awesome-carousel-indicator.active{background:#f0f;box-shadow:0 0 10px #f0f}.awesome-carousel-indicators--glass .awesome-carousel-indicator{background:#ffffff4d}.awesome-carousel-indicators--glass .awesome-carousel-indicator.active{background:#fff;box-shadow:0 0 10px #fff9}.awesome-carousel-fade-enter{animation:fadeUp .3s ease-out}.awesome-carousel-card-entrance{animation:cardEntrance .4s cubic-bezier(.34,1.56,.64,1)}.awesome-carousel-slide-in{animation:slideIn .3s ease-out}@media(prefers-reduced-motion:reduce){*{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}.awesome-carousel-card--transition{transition:none}}@media(max-width:768px){.awesome-carousel-card{width:180px;height:240px}.awesome-carousel-card__title{font-size:13px}.awesome-carousel-card__description{font-size:11px}.awesome-carousel-nav{padding:15px;gap:8px}.awesome-carousel-nav__button{padding:6px 12px;font-size:12px}.awesome-carousel-indicators{gap:6px;padding:12px}.awesome-carousel-indicator{width:6px;height:6px}}@media(max-width:480px){.awesome-carousel-card{width:150px;height:200px}.awesome-carousel-card__image-area{flex:0 0 60%}.awesome-carousel-card__text-area{padding:12px 10px;gap:4px}.awesome-carousel-card__title{font-size:12px}.awesome-carousel-card__description{font-size:10px}.awesome-carousel-card__tag{font-size:9px;padding:3px 6px}}.awesome-carousel-a11y-skip{position:absolute;left:-10000px;top:auto;width:1px;height:1px;overflow:hidden}.awesome-carousel-a11y-skip:focus{position:static;width:auto;height:auto;padding:10px;background:var(--awesome-carousel-cyan);color:var(--awesome-carousel-dark-bg);outline:2px solid var(--awesome-carousel-cyan)}@media(prefers-contrast:more){.awesome-carousel-card__content--dark{border-color:var(--awesome-carousel-indicator-active-dark)}.awesome-carousel-card__content--light{border-color:var(--awesome-carousel-violet)}.awesome-carousel-indicator{border:1px solid currentColor}}@media(forced-colors:active){.awesome-carousel-card__content,.awesome-carousel-nav__button,.awesome-carousel-indicator{border:1px solid}}
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "awesome-coverflow-carousel",
3
+ "version": "0.1.0",
4
+ "description": "A beautiful, interactive 3D Coverflow carousel component for React with smooth animations, multiple themes, and flexible data handling",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "module": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.js",
16
+ "require": "./dist/index.umd.cjs"
17
+ },
18
+ "./dist/style.css": "./dist/style.css"
19
+ },
20
+ "scripts": {
21
+ "dev": "vite",
22
+ "build": "tsc -b && vite build",
23
+ "preview": "vite preview",
24
+ "prepublishOnly": "npm run build"
25
+ },
26
+ "keywords": [
27
+ "react",
28
+ "carousel",
29
+ "coverflow",
30
+ "3d",
31
+ "Coverflow",
32
+ "component",
33
+ "interactive",
34
+ "animation",
35
+ "theme",
36
+ "ui"
37
+ ],
38
+ "author": "Pravinkumar Dabade",
39
+ "license": "MIT",
40
+ "peerDependenciesMeta": {
41
+ "react": {
42
+ "optional": false
43
+ },
44
+ "react-dom": {
45
+ "optional": false
46
+ }
47
+ },
48
+ "dependencies": {
49
+ "react": "^19.0.0",
50
+ "react-dom": "^19.0.0"
51
+ },
52
+ "devDependencies": {
53
+ "@types/react": "^19.0.0",
54
+ "@types/react-dom": "^19.0.0",
55
+ "@vitejs/plugin-react": "^4.3.4",
56
+ "typescript": "~5.6.2",
57
+ "vite": "^6.0.5"
58
+ },
59
+ "engines": {
60
+ "node": ">=14.0.0",
61
+ "npm": ">=6.0.0"
62
+ }
63
+ }