PageSourceSearch

https://reactbits.dev/assets/CarouselDemo-ieVSyVac.js

js reactbits.dev collected 2026-10-03 19:26:53 UTC 44,929 bytes, 1,305 lines download raw bytes

1import{r as m,k as n,cv as J,cx as E,dg as B,dh as Y,di as V,dj as q,bP as z,cw as X,y as K}from"./index-Bn1bbOAe.js";import{u as Q,C as Z,T as nn,P as en,a as tn,b as on,c as sn}from"./useComponentProps-CkrCaLvB.js";import{C as an}from"./Customize-DBLruEgy.js";import{P as b}from"./PreviewSwitch-BKSQdkt2.js";import{D as rn}from"./Dependencies-BritF_2p.js";import{u as cn}from"./useForceRerender-CvsfwHEi.js";import{P as T}from"./PreviewSlider-CJmB9pdC.js";import"./index-CKdJydTQ.js";import"./backgroundThemeProps-BAOOEp3Q.js";import"./ShikiCode-CUach_VP.js";import"./aiExport--nnywH9U.js";import"./IconSelect-CgfYlisg.js";import"./sparkles-DtoGwhqa.js";import"./maximize-2-DQy3aI7-.js";import"./preview-slider-B9GA5uEa.js";import"./copy--0PRdOLE.js";import"./useScrubGesture-BHz_XSAB.js";const ln=[{title:"Text Animations",description:"Cool text animations for your projects.",id:1,icon:n.jsx(B,{className:"carousel-icon"})},{title:"Animations",description:"Smooth animations for your projects.",id:2,icon:n.jsx(Y,{className:"carousel-icon"})},{title:"Components",description:"Reusable components for your projects.",id:3,icon:n.jsx(V,{className:"carousel-icon"})},{title:"Backgrounds",description:"Beautiful backgrounds and patterns for your projects.",id:4,icon:n.jsx(q,{className:"carousel-icon"})},{title:"Common UI",description:"Common UI components are coming soon!",id:5,icon:n.jsx(z,{className:"carousel-icon"})}],N=0,w=500,L=16,dn={type:"spring",stiffness:300,damping:30};function mn({item:e,index:a,itemWidth:x,round:u,trackItemOffset:d,x:i,transition:f}){const g=[-(a+1)*d,-a*d,-(a-1)*d],c=X(i,g,[90,0,-90],{clamp:!1});return n.jsxs(E.div,{className:`carousel-item ${u?"round":""}`,style:{width:x,height:u?x:"100%",rotateY:c,...u&&{borderRadius:"50%"}},transition:f,children:[n.jsx("div",{className:`carousel-item-header ${u?"round":""}`,children:n.jsx("span",{className:"carousel-icon-container",children:e.icon})}),n.jsxs("div",{className:"carousel-item-content",children:[n.jsx("div",{className:"carousel-item-title",children:e.title}),n.jsx("p",{className:"carousel-item-description",children:e.description})]})]},`${(e==null?void 0:e.id)??a}-${a}`)}function un({items:e=ln,baseWidth:a=300,autoplay:x=!1,autoplayDelay:u=3e3,pauseOnHover:d=!1,loop:i=!1,round:f=!1}){const h=a-32,c=h+L,l=m.useMemo(()=>i?e.length===0?[]:[e[e.length-1],...e,e[0]]:e,[e,i]),[r,p]=m.useState(i?1:0),o=J(0),[C,O]=m.useState(!1),[M,y]=m.useState(!1),[D,v]=m.useState(!1),R=m.useRef(null);m.useEffect(()=>{if(d&&R.current){const s=R.current,t=()=>O(!0),I=()=>O(!1);return s.addEventListener("mouseenter",t),s.addEventListener("mouseleave",I),()=>{s.removeEventListener("mouseenter",t),s.removeEventListener("mouseleave",I)}}},[d]),m.useEffect(()=>{if(!x||l.length<=1||d&&C)return;const s=setInterval(()=>{p(t=>Math.min(t+1,l.length-1))},u);return()=>clearInterval(s)},[x,u,C,d,l.length]),m.useEffect(()=>{const s=i?1:0;p(s),o.set(-s*c)},[e.length,i,c,o]),m.useEffect(()=>{!i&&r>l.length-1&&p(Math.max(0,l.length-1))},[l.length,i,r]);const P=M?{duration:0}:dn,H=()=>{v(!0)},j=()=>
1{if(!i||l.length<=1){v(!1);return}const s=l.length-1;if(r===s){y(!0);const t=1;p(t),o.set(-t*c),requestAnimationFrame(()=>{y(!1),v(!1)});return}if(r===0){y(!0);const t=e.length;p(t),o.set(-t*c),requestAnimationFrame(()=>{y(!1),v(!1)});return}v(!1)},$=(s,t)=>{const{offset:I,velocity:A}=t,k=I.x<-N||A.x<-w?1:I.x>N||A.x>w?-1:0;k!==0&&p(_=>{const G=_+k,U=l.length-1;return Math.max(0,Math.min(G,U))})},W=i?{}:{dragConstraints:{left:-c*Math.max(l.length-1,0),right:0}},F=e.length===0?0:i?(r-1+e.length)%e.length:Math.min(r,e.length-1);return n.jsxs("div",{ref:R,className:`carousel-container ${f?"round":""}`,style:{width:`${a}px`,...f&&{height:`${a}px`,borderRadius:"50%"}},children:[n.jsx(E.div,{className:"carousel-track",drag:D?!1:"x",...W,style:{width:h,gap:`${L}px`,perspective:1e3,perspectiveOrigin:`${r*c+h/2}px 50%`,x:o},onDragEnd:$,animate:{x:-(r*c)},transition:P,onAnimationStart:H,onAnimationComplete:j,children:l.map((s,t)=>n.jsx(mn,{item:s,index:t,itemWidth:h,round:f,trackItemOffset:c,x:o,transition:P},`${(s==null?void 0:s.id)??t}-${t}`))}),n.jsx("div",{className:`carousel-indicators-container ${f?"round":""}`,children:n.jsx("div",{className:"carousel-indicators",children:e.map((s,t)=>n.jsx(E.button,{type:"button",className:`carousel-indicator ${F===t?"active":"inactive"}`,"aria-label":`Go to slide ${t+1}`,"aria-current":F===t,animate:{scale:F===t?1.2:1},onClick:()=>p(i?t+1:t),transition:{duration:.15}},t))})})]})}const fn=`'use client';
2
3import { useEffect, useMemo, useRef, useState } from 'react';
4import { motion, useMotionValue, useTransform } from 'motion/react';
5// replace icons with your own if needed
6import { FiCircle, FiCode, FiFileText, FiLayers, FiLayout } from 'react-icons/fi';
7
8import './Carousel.css';
9
10const DEFAULT_ITEMS = [
11  {
12    title: 'Text Animations',
13    description: 'Cool text animations for your projects.',
14    id: 1,
15    icon: <FiFileText className="carousel-icon" />
16  },
17  {
18    title: 'Animations',
19    description: 'Smooth animations for your projects.',
20    id: 2,
21    icon: <FiCircle className="carousel-icon" />
22  },
23  {
24    title: 'Components',
25    description: 'Reusable components for your projects.',
26    id: 3,
27    icon: <FiLayers className="carousel-icon" />
28  },
29  {
30    title: 'Backgrounds',
31    description: 'Beautiful backgrounds and patterns for your projects.',
32    id: 4,
33    icon: <FiLayout className="carousel-icon" />
34  },
35  {
36    title: 'Common UI',
37    description: 'Common UI components are coming soon!',
38    id: 5,
39    icon: <FiCode className="carousel-icon" />
40  }
41];
42
43const DRAG_BUFFER = 0;
44const VELOCITY_THRESHOLD = 500;
45const GAP = 16;
46const SPRING_OPTIONS = { type: 'spring', stiffness: 300, damping: 30 };
47
48function CarouselItem({ item, index, itemWidth, round, trackItemOffset, x, transition }) {
49  const range = [-(index + 1) * trackItemOffset, -index * trackItemOffset, -(index - 1) * trackItemOffset];
50  const outputRange = [90, 0, -90];
51  const rotateY = useTransform(x, range, outputRange, { clamp: false });
52
53  return (
54    <motion.div
55      key={\`\${item?.id ?? index}-\${index}\`}
56      className={\`carousel-item \${round ? 'round' : ''}\`}
57      style={{
58        width: itemWidth,
59        height: round ? itemWidth : '100%',
60        rotateY: rotateY,
61        ...(round && { borderRadius: '50%' })
62      }}
63      transition={transition}
64    >
65      <div className={\`carousel-item-header \${round ? 'round' : ''}\`}>
66        <span className="carousel-icon-container">{item.icon}</span>
67      </div>
68      <div className="carousel-item-content">
69        <div className="carousel-item-title">{item.title}</div>
70        <p className="carousel-item-description">{item.description}</p>
71      </div>
72    </motion.div>
73  );
74}
75
76export default function Carousel({
77  items = DEFAULT_ITEMS,
78  baseWidth = 300,
79  autoplay = false,
80  autoplayDelay = 3000,
81  pauseOnHover = false,
82  loop = false,
83  round = false
84}) {
85  const containerPadding = 16;
86  const itemWidth = baseWidth - containerPadding * 2;
87  const trackItemOffset = itemWidth + GAP;
88  const itemsForRender = useMemo(() => {
89    if (!loop) return items;
90    if (items.length === 0) return [];
91    return [items[items.length - 1], ...items, items[0]];
92  }, [items, loop]);
93
94  const [position, setPosition] = useState(loop ? 1 : 0);
95  const x = useMotionValue(0);
96  const [isHovered, setIsHovered] = useState(false);
97  const [isJumping, setIsJumping] = useState(false);
98  const [isAnimating, setIsAnimating] = useState(false);
99
100  const containerRef = useRef(null);
101  useEffect(() => {
102    if (pauseOnHover && containerRef.current) {
103      const container = containerRef.current;
104      const handleMouseEnter = () => setIsHovered(true);
105      const handleMouseLeave = () => setIsHovered(false);
106      container.addEventListener('mouseenter', handleMouseEnter);
107      container.addEventListener('mouseleave', handleMouseLeave);
108      return () => {
109        container.removeEventListener('mouseenter', handleMouseEnter);
110        container.removeEventListener('mouseleave', handleMouseLeave);
111      };
112    }
113  }, [pauseOnHover]);
114
115  useEffect(() => {
116    if (!autoplay || itemsForRender.length <= 1) return undefined;
117    if (pauseOnHover && isHovered) return undefined;
118
119    const timer = setInterval(() => {
120      setPosition(prev => Math.min(prev + 1, itemsForRender.length - 1));
121    }, autoplayDelay);
122
123    return () => clearInterval(timer);
124  }, [autoplay, autoplayDelay, isHovered, pauseOnHover, itemsForRender.length]);
125
126  useEffect(() => {
127    const startingPosition = loop ? 1 : 0;
128    setPosition(startingPosition);
129    x.set(-startingPosition * trackItemOffset);
130  }, [items.length, loop, trackItemOffset, x]);
131
132  useEffect(() => {
133    if (!loop && position > itemsForRender.length - 1) {
134      setPosition(Math.max(0, itemsForRender.length - 1));
135    }
136  }, [itemsForRender.length, loop, position]);
137
138  const effectiveTransition = isJumping ? { duration: 0 } : SPRING_OPTIONS;
139
140  const handleAnimationStart = () => {
141    setIsAnimating(true);
142  };
143
144  const handleAnimationComplete = () => {
145    if (!loop || itemsForRender.length <= 1) {
146      setIsAnimating(false);
147      return;
148    }
149    const lastCloneIndex = itemsForRender.length - 1;
150
151    if (position === lastCloneIndex) {
152      setIsJumping(true);
153      const target = 1;
154      setPosition(target);
155      x.set(-target * trackItemOffset);
156      requestAnimationFrame(() => {
157        setIsJumping(false);
158        setIsAnimating(false);
159      });
160      return;
161    }
162
163    if (position === 0) {
164      setIsJumping(true);
165      const target = items.length;
166      setPosition(target);
167      x.set(-target * trackItemOffset);
168      requestAnimationFrame(() => {
169        setIsJumping(false);
170        setIsAnimating(false);
171      });
172      return;
173    }
174
175    setIsAnimating(false);
176  };
177
178  const handleDragEnd = (_, info) => {
179    const { offset, velocity } = info;
180    const direction =
181      offset.x < -DRAG_BUFFER || velocity.x < -VELOCITY_THRESHOLD
182        ? 1
183        : offset.x > DRAG_BUFFER || velocity.x > VELOCITY_THRESHOLD
184          ? -1
185          : 0;
186
187    if (direction === 0) return;
188
189    setPosition(prev => {
190      const next = prev + direction;
191      const max = itemsForRender.length - 1;
192      return Math.max(0, Math.min(next, max));
193    });
194  };
195
196  const dragProps = loop
197    ? {}
198    : {
199        dragConstraints: {
200          left: -trackItemOffset * Math.max(itemsForRender.length - 1, 0),
201          right: 0
202        }
203      };
204
205  const activeIndex =
206    items.length === 0 ? 0 : loop ? (position - 1 + items.length) % items.length : Math.min(position, items.length - 1);
207
208  return (
209    <div
210      ref={containerRef}
211      className={\`carousel-container \${round ? 'round' : ''}\`}
212      style={{
213        width: \`\${baseWidth}px\`,
214        ...(round && { height: \`\${baseWidth}px\`, borderRadius: '50%' })
215      }}
216    >
217      <motion.div
218        className="carousel-track"
219        drag={isAnimating ? false : 'x'}
220        {...dragProps}
221        style={{
222          width: itemWidth,
223          gap: \`\${GAP}px\`,
224          perspective: 1000,
225          perspectiveOrigin: \`\${position * trackItemOffset + itemWidth / 2}px 50%\`,
226          x
227        }}
228        onDragEnd={handleDragEnd}
229        animate={{ x: -(position * trackItemOffset) }}
230        transition={effectiveTransition}
231        onAnimationStart={handleAnimationStart}
232        onAnimationComplete={handleAnimationComplete}
233      >
234        {itemsForRender.map((item, index) => (
235          <CarouselItem
236            key={\`\${item?.id ?? index}-\${index}\`}
237            item={item}
238            index={index}
239            itemWidth={itemWidth}
240            round={round}
241            trackItemOffset={trackItemOffset}
242            x={x}
243            transition={effectiveTransition}
244          />
245        ))}
246      </motion.div>
247      <div className={\`carousel-indicators-container \${round ? 'round' : ''}\`}>
248        <div className="carousel-indicators">
249          {items.map((_, index) => (
250            <motion.button
251              type="button"
252              key={index}
253              className={\`carousel-indicator \${activeIndex === index ? 'active' : 'inactive'}\`}
254              aria-label={\`Go to slide \${index + 1}\`}
255              aria-current={activeIndex === index}
256              animate={{
257                scale: activeIndex === index ? 1.2 : 1
258              }}
259              onClick={() => setPosition(loop ? index + 1 : index)}
260              transition={{ duration: 0.15 }}
261            />
262          ))}
263        </div>
264      </div>
265    </div>
266  );
267}
268`,pn=`.carousel-container {
269  position: relative;
270  overflow: hidden;
271  border: 1px solid #555;
272  border-radius: 24px;
273  padding: 16px;
274  --outer-r: 24px;
275  --p-distance: 12px;
276}
277
278.carousel-track {
279  display: flex;
280}
281
282.carousel-item {
283  position: relative;
284  display: flex;
285  flex-shrink: 0;
286  flex-direction: column;
287  align-items: flex-start;
288  justify-content: space-between;
289  border: 1px solid #555;
290  border-radius: calc(var(--outer-r) - var(--p-distance));
291  background-color: #1B1722;
292  overflow: hidden;
293  cursor: grab;
294}
295
296.carousel-item:active {
297  cursor: grabbing;
298}
299
300.carousel-container.round {
301  border: 1px solid #555;
302}
303
304.carousel-item.round {
305  background-color: #1B1722;
306  position: relative;
307  bottom: 0.1em;
308  border: 1px solid #555;
309  justify-content: center;
310  align-items: center;
311  text-align: center;
312}
313
314.carousel-item-header.round {
315  padding: 0;
316  margin: 0;
317}
318
319.carousel-indicators-container.round {
320  position: absolute;
321  z-index: 2;
322  bottom: 3em;
323  left: 50%;
324  transform: translateX(-50%);
325}
326
327.carousel-indicator.active {
328  background-color: #333333;
329}
330
331.carousel-indicator.inactive {
332  background-color: rgba(51, 51, 51, 0.4);
333}
334
335.carousel-item-header {
336  margin-bottom: 16px;
337  padding: 20px;
338  padding-top: 20px;
339}
340
341.carousel-icon-container {
342  display: flex;
343  height: 28px;
344  width: 28px;
345  align-items: center;
346  justify-content: center;
347  border-radius: 50%;
348  background-color: #fff;
349}
350
351.carousel-icon {
352  height: 16px;
353  width: 16px;
354  color: #120F17;
355}
356
357.carousel-item-content {
358  padding: 20px;
359  padding-bottom: 20px;
360}
361
362.carousel-item-title {
363  margin-bottom: 4px;
364  font-weight: 900;
365  font-size: 18px;
366  color: #fff;
367}
368
369.carousel-item-description {
370  font-size: 14px;
371  color: #fff;
372}
373
374.carousel-indicators-container {
375  display: flex;
376  width: 100%;
377  justify-content: center;
378}
379
380.carousel-indicators {
381  margin-top: 16px;
382  display: flex;
383  width: 150px;
384  justify-content: space-between;
385  padding: 0 32px;
386}
387
388.carousel-indicator {
389  height: 8px;
390  width: 8px;
391  border: none;
392  padding: 0;
393  appearance: none;
394  border-radius: 50%;
395  cursor: pointer;
396  transition: background-color 150ms;
397}
398
399.carousel-indicator:focus-visible {
400  outline: 2px solid #fff;
401  outline-offset: 2px;
402}
403
404.carousel-indicator.active {
405  background-color: #fff;
406}
407
408.carousel-indicator.inactive {
409  background-color: #555;
410}
411`,hn=`'use client';
412
413import { useEffect, useMemo, useRef, useState } from 'react';
414import { motion, useMotionValue, useTransform } from 'motion/react';
415// replace icons with your own if needed
416import { FiCircle, FiCode, FiFileText, FiLayers, FiLayout } from 'react-icons/fi';
417
418const DEFAULT_ITEMS = [
419  {
420    title: 'Text Animations',
421    description: 'Cool text animations for your projects.',
422    id: 1,
423    icon: <FiFileText className="h-[16px] w-[16px] text-white" />
424  },
425  {
426    title: 'Animations',
427    description: 'Smooth animations for your projects.',
428    id: 2,
429    icon: <FiCircle className="h-[16px] w-[16px] text-white" />
430  },
431  {
432    title: 'Components',
433    description: 'Reusable components for your projects.',
434    id: 3,
435    icon: <FiLayers className="h-[16px] w-[16px] text-white" />
436  },
437  {
438    title: 'Backgrounds',
439    description: 'Beautiful backgrounds and patterns for your projects.',
440    id: 4,
441    icon: <FiLayout className="h-[16px] w-[16px] text-white" />
442  },
443  {
444    title: 'Common UI',
445    description: 'Common UI components are coming soon!',
446    id: 5,
447    icon: <FiCode className="h-[16px] w-[16px] text-white" />
448  }
449];
450
451const DRAG_BUFFER = 0;
452const VELOCITY_THRESHOLD = 500;
453const GAP = 16;
454const SPRING_OPTIONS = { type: 'spring', stiffness: 300, damping: 30 };
455
456function CarouselItem({ item, index, itemWidth, round, trackItemOffset, x, transition }) {
457  const range = [-(index + 1) * trackItemOffset, -index * trackItemOffset, -(index - 1) * trackItemOffset];
458  const outputRange = [90, 0, -90];
459  const rotateY = useTransform(x, range, outputRange, { clamp: false });
460
461  return (
462    <motion.div
463      key={\`\${item?.id ?? index}-\${index}\`}
464      className={\`relative shrink-0 flex flex-col \${
465        round
466          ? 'items-center justify-center text-center bg-[#120F17] border-0'
467          : 'items-start justify-between bg-[#222] border border-[#222] rounded-[12px]'
468      } overflow-hidden cursor-grab active:cursor-grabbing\`}
469      style={{
470        width: itemWidth,
471        height: round ? itemWidth : '100%',
472        rotateY: rotateY,
473        ...(round && { borderRadius: '50%' })
474      }}
475      transition={transition}
476    >
477      <div className={\`\${round ? 'p-0 m-0' : 'mb-4 p-5'}\`}>
478        <span className="flex h-[28px] w-[28px] items-center justify-center rounded-full bg-[#120F17]">
479          {item.icon}
480        </span>
481      </div>
482      <div className="p-5">
483        <div className="mb-1 font-black text-lg text-white">{item.title}</div>
484        <p className="text-sm text-white">{item.description}</p>
485      </div>
486    </motion.div>
487  );
488}
489
490export default function Carousel({
491  items = DEFAULT_ITEMS,
492  baseWidth = 300,
493  autoplay = false,
494  autoplayDelay = 3000,
495  pauseOnHover = false,
496  loop = false,
497  round = false
498}) {
499  const containerPadding = 16;
500  const itemWidth = baseWidth - containerPadding * 2;
501  const trackItemOffset = itemWidth + GAP;
502  const itemsForRender = useMemo(() => {
503    if (!loop) return items;
504    if (items.length === 0) return [];
505    return [items[items.length - 1], ...items, items[0]];
506  }, [items, loop]);
507
508  const [position, setPosition] = useState(loop ? 1 : 0);
509  const x = useMotionValue(0);
510  const [isHovered, setIsHovered] = useState(false);
511  const [isJumping, setIsJumping] = useState(false);
512  const [isAnimating, setIsAnimating] = useState(false);
513
514  const containerRef = useRef(null);
515  useEffect(() => {
516    if (pauseOnHover && containerRef.current) {
517      const container = containerRef.current;
518      const handleMouseEnter = () => setIsHovered(true);
519      const handleMouseLeave = () => setIsHovered(false);
520      container.addEventListener('mouseenter', handleMouseEnter);
521      container.addEventListener('mouseleave', handleMouseLeave);
522      return () => {
523        container.removeEventListener('mouseenter', handleMouseEnter);
524        container.removeEventListener('mouseleave', handleMouseLeave);
525      };
526    }
527  }, [pauseOnHover]);
528
529  useEffect(() => {
530    if (!autoplay || itemsForRender.length <= 1) return undefined;
531    if (pauseOnHover && isHovered) return undefined;
532
533    const timer = setInterval(() => {
534      setPosition(prev => Math.min(prev + 1, itemsForRender.length - 1));
535    }, autoplayDelay);
536
537    return () => clearInterval(timer);
538  }, [autoplay, autoplayDelay, isHovered, pauseOnHover, itemsForRender.length]);
539
540  useEffect(() => {
541    const startingPosition = loop ? 1 : 0;
542    setPosition(startingPosition);
543    x.set(-startingPosition * trackItemOffset);
544  }, [items.length, loop, trackItemOffset, x]);
545
546  useEffect(() => {
547    if (!loop && position > itemsForRender.length - 1) {
548      setPosition(Math.max(0, itemsForRender.length - 1));
549    }
550  }, [itemsForRender.length, loop, position]);
551
552  const effectiveTransition = isJumping ? { duration: 0 } : SPRING_OPTIONS;
553
554  const handleAnimationStart = () => {
555    setIsAnimating(true);
556  };
557
558  const handleAnimationComplete = () => {
559    if (!loop || itemsForRender.length <= 1) {
560      setIsAnimating(false);
561      return;
562    }
563    const lastCloneIndex = itemsForRender.length - 1;
564
565    if (position === lastCloneIndex) {
566      setIsJumping(true);
567      const target = 1;
568      setPosition(target);
569      x.set(-target * trackItemOffset);
570      requestAnimationFrame(() => {
571        setIsJumping(false);
572        setIsAnimating(false);
573      });
574      return;
575    }
576
577    if (position === 0) {
578      setIsJumping(true);
579      const target = items.length;
580      setPosition(target);
581      x.set(-target * trackItemOffset);
582      requestAnimationFrame(() => {
583        setIsJumping(false);
584        setIsAnimating(false);
585      });
586      return;
587    }
588
589    setIsAnimating(false);
590  };
591
592  const handleDragEnd = (_, info) => {
593    const { offset, velocity } = info;
594    const direction =
595      offset.x < -DRAG_BUFFER || velocity.x < -VELOCITY_THRESHOLD
596        ? 1
597        : offset.x > DRAG_BUFFER || velocity.x > VELOCITY_THRESHOLD
598          ? -1
599          : 0;
600
601    if (direction === 0) return;
602
603    setPosition(prev => {
604      const next = prev + direction;
605      const max = itemsForRender.length - 1;
606      return Math.max(0, Math.min(next, max));
607    });
608  };
609
610  const dragProps = loop
611    ? {}
612    : {
613        dragConstraints: {
614          left: -trackItemOffset * Math.max(itemsForRender.length - 1, 0),
615          right: 0
616        }
617      };
618
619  const activeIndex =
620    items.length === 0 ? 0 : loop ? (position - 1 + items.length) % items.length : Math.min(position, items.length - 1);
621
622  return (
623    <div
624      ref={containerRef}
625      className={\`relative overflow-hidden p-4 \${
626        round ? 'rounded-full border border-white' : 'rounded-[24px] border border-[#222]'
627      }\`}
628      style={{
629        width: \`\${baseWidth}px\`,
630        ...(round && { height: \`\${baseWidth}px\` })
631      }}
632    >
633      <motion.div
634        className="flex"
635        drag={isAnimating ? false : 'x'}
636        {...dragProps}
637        style={{
638          width: itemWidth,
639          gap: \`\${GAP}px\`,
640          perspective: 1000,
641          perspectiveOrigin: \`\${position * trackItemOffset + itemWidth / 2}px 50%\`,
642          x
643        }}
644        onDragEnd={handleDragEnd}
645        animate={{ x: -(position * trackItemOffset) }}
646        transition={effectiveTransition}
647        onAnimationStart={handleAnimationStart}
648        onAnimationComplete={handleAnimationComplete}
649      >
650        {itemsForRender.map((item, index) => (
651          <CarouselItem
652            key={\`\${item?.id ?? index}-\${index}\`}
653            item={item}
654            index={index}
655            itemWidth={itemWidth}
656            round={round}
657            trackItemOffset={trackItemOffset}
658            x={x}
659            transition={effectiveTransition}
660          />
661        ))}
662      </motion.div>
663      <div className={\`flex w-full justify-center \${round ? 'absolute z-20 bottom-12 left-1/2 -translate-x-1/2' : ''}\`}>
664        <div className="mt-4 flex w-[150px] justify-between px-8">
665          {items.map((_, index) => (
666            <motion.button
667              type="button"
668              key={index}
669              aria-label={\`Go to slide \${index + 1}\`}
670              aria-current={activeIndex === index}
671              className={\`h-2 w-2 rounded-full cursor-pointer border-0 p-0 appearance-none transition-colors duration-150 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white \${
672                activeIndex === index
673                  ? round
674                    ? 'bg-white'
675                    : 'bg-[#333333]'
676                  : round
677                    ? 'bg-[#555]'
678                    : 'bg-[rgba(51,51,51,0.4)]'
679              }\`}
680              animate={{
681                scale: activeIndex === index ? 1.2 : 1
682              }}
683              onClick={() => setPosition(loop ? index + 1 : index)}
684              transition={{ duration: 0.15 }}
685            />
686          ))}
687        </div>
688      </div>
689    </div>
690  );
691}
692`,xn=`'use client';
693
694import { useEffect, useMemo, useRef, useState } from 'react';
695import { motion, type PanInfo, useMotionValue, useTransform } from 'motion/react';
696// replace icons with your own if needed
697import { FiCircle, FiCode, FiFileText, FiLayers, FiLayout } from 'react-icons/fi';
698import './Carousel.css';
699
700export interface CarouselItem {
701  title: string;
702  description: string;
703  id: number;
704  icon: React.ReactElement;
705}
706
707export interface CarouselProps {
708  items?: CarouselItem[];
709  baseWidth?: number;
710  autoplay?: boolean;
711  autoplayDelay?: number;
712  pauseOnHover?: boolean;
713  loop?: boolean;
714  round?: boolean;
715}
716
717const DEFAULT_ITEMS: CarouselItem[] = [
718  {
719    title: 'Text Animations',
720    description: 'Cool text animations for your projects.',
721    id: 1,
722    icon: <FiFileText className="carousel-icon" />
723  },
724  {
725    title: 'Animations',
726    description: 'Smooth animations for your projects.',
727    id: 2,
728    icon: <FiCircle className="carousel-icon" />
729  },
730  {
731    title: 'Components',
732    description: 'Reusable components for your projects.',
733    id: 3,
734    icon: <FiLayers className="carousel-icon" />
735  },
736  {
737    title: 'Backgrounds',
738    description: 'Beautiful backgrounds and patterns for your projects.',
739    id: 4,
740    icon: <FiLayout className="carousel-icon" />
741  },
742  {
743    title: 'Common UI',
744    description: 'Common UI components are coming soon!',
745    id: 5,
746    icon: <FiCode className="carousel-icon" />
747  }
748];
749
750const DRAG_BUFFER = 0;
751const VELOCITY_THRESHOLD = 500;
752const GAP = 16;
753const SPRING_OPTIONS = { type: 'spring' as const, stiffness: 300, damping: 30 };
754
755interface CarouselItemProps {
756  item: CarouselItem;
757  index: number;
758  itemWidth: number;
759  round: boolean;
760  trackItemOffset: number;
761  x: any;
762  transition: any;
763}
764
765function CarouselItem({ item, index, itemWidth, round, trackItemOffset, x, transition }: CarouselItemProps) {
766  const range = [-(index + 1) * trackItemOffset, -index * trackItemOffset, -(index - 1) * trackItemOffset];
767  const outputRange = [90, 0, -90];
768  const rotateY = useTransform(x, range, outputRange, { clamp: false });
769
770  return (
771    <motion.div
772      key={\`\${item?.id ?? index}-\${index}\`}
773      className={\`carousel-item \${round ? 'round' : ''}\`}
774      style={{
775        width: itemWidth,
776        height: round ? itemWidth : '100%',
777        rotateY: rotateY,
778        ...(round && { borderRadius: '50%' })
779      }}
780      transition={transition}
781    >
782      <div className={\`carousel-item-header \${round ? 'round' : ''}\`}>
783        <span className="carousel-icon-container">{item.icon}</span>
784      </div>
785      <div className="carousel-item-content">
786        <div className="carousel-item-title">{item.title}</div>
787        <p className="carousel-item-description">{item.description}</p>
788      </div>
789    </motion.div>
790  );
791}
792
793export default function Carousel({
794  items = DEFAULT_ITEMS,
795  baseWidth = 300,
796  autoplay = false,
797  autoplayDelay = 3000,
798  pauseOnHover = false,
799  loop = false,
800  round = false
801}: CarouselProps): React.JSX.Element {
802  const containerPadding = 16;
803  const itemWidth = baseWidth - containerPadding * 2;
804  const trackItemOffset = itemWidth + GAP;
805  const itemsForRender = useMemo(() => {
806    if (!loop) return items;
807    if (items.length === 0) return [];
808    return [items[items.length - 1], ...items, items[0]];
809  }, [items, loop]);
810
811  const [position, setPosition] = useState<number>(loop ? 1 : 0);
812  const x = useMotionValue(0);
813  const [isHovered, setIsHovered] = useState<boolean>(false);
814  const [isJumping, setIsJumping] = useState<boolean>(false);
815  const [isAnimating, setIsAnimating] = useState<boolean>(false);
816
817  const containerRef = useRef<HTMLDivElement>(null);
818  useEffect(() => {
819    if (pauseOnHover && containerRef.current) {
820      const container = containerRef.current;
821      const handleMouseEnter = () => setIsHovered(true);
822      const handleMouseLeave = () => setIsHovered(false);
823      container.addEventListener('mouseenter', handleMouseEnter);
824      container.addEventListener('mouseleave', handleMouseLeave);
825      return () => {
826        container.removeEventListener('mouseenter', handleMouseEnter);
827        container.removeEventListener('mouseleave', handleMouseLeave);
828      };
829    }
830  }, [pauseOnHover]);
831
832  useEffect(() => {
833    if (!autoplay || itemsForRender.length <= 1) return undefined;
834    if (pauseOnHover && isHovered) return undefined;
835
836    const timer = setInterval(() => {
837      setPosition(prev => Math.min(prev + 1, itemsForRender.length - 1));
838    }, autoplayDelay);
839
840    return () => clearInterval(timer);
841  }, [autoplay, autoplayDelay, isHovered, pauseOnHover, itemsForRender.length]);
842
843  useEffect(() => {
844    const startingPosition = loop ? 1 : 0;
845    setPosition(startingPosition);
846    x.set(-startingPosition * trackItemOffset);
847  }, [items.length, loop, trackItemOffset, x]);
848
849  useEffect(() => {
850    if (!loop && position > itemsForRender.length - 1) {
851      setPosition(Math.max(0, itemsForRender.length - 1));
852    }
853  }, [itemsForRender.length, loop, position]);
854
855  const effectiveTransition = isJumping ? { duration: 0 } : SPRING_OPTIONS;
856
857  const handleAnimationStart = () => {
858    setIsAnimating(true);
859  };
860
861  const handleAnimationComplete = () => {
862    if (!loop || itemsForRender.length <= 1) {
863      setIsAnimating(false);
864      return;
865    }
866    const lastCloneIndex = itemsForRender.length - 1;
867
868    if (position === lastCloneIndex) {
869      setIsJumping(true);
870      const target = 1;
871      setPosition(target);
872      x.set(-target * trackItemOffset);
873      requestAnimationFrame(() => {
874        setIsJumping(false);
875        setIsAnimating(false);
876      });
877      return;
878    }
879
880    if (position === 0) {
881      setIsJumping(true);
882      const target = items.length;
883      setPosition(target);
884      x.set(-target * trackItemOffset);
885      requestAnimationFrame(() => {
886        setIsJumping(false);
887        setIsAnimating(false);
888      });
889      return;
890    }
891
892    setIsAnimating(false);
893  };
894
895  const handleDragEnd = (_: MouseEvent | TouchEvent | PointerEvent, info: PanInfo): void => {
896    const { offset, velocity } = info;
897    const direction =
898      offset.x < -DRAG_BUFFER || velocity.x < -VELOCITY_THRESHOLD
899        ? 1
900        : offset.x > DRAG_BUFFER || velocity.x > VELOCITY_THRESHOLD
901          ? -1
902          : 0;
903
904    if (direction === 0) return;
905
906    setPosition(prev => {
907      const next = prev + direction;
908      const max = itemsForRender.length - 1;
909      return Math.max(0, Math.min(next, max));
910    });
911  };
912
913  const dragProps = loop
914    ? {}
915    : {
916        dragConstraints: {
917          left: -trackItemOffset * Math.max(itemsForRender.length - 1, 0),
918          right: 0
919        }
920      };
921
922  const activeIndex =
923    items.length === 0 ? 0 : loop ? (position - 1 + items.length) % items.length : Math.min(position, items.length - 1);
924
925  return (
926    <div
927      ref={containerRef}
928      className={\`carousel-container \${round ? 'round' : ''}\`}
929      style={{
930        width: \`\${baseWidth}px\`,
931        ...(round && { height: \`\${baseWidth}px\`, borderRadius: '50%' })
932      }}
933    >
934      <motion.div
935        className="carousel-track"
936        drag={isAnimating ? false : 'x'}
937        {...dragProps}
938        style={{
939          width: itemWidth,
940          gap: \`\${GAP}px\`,
941          perspective: 1000,
942          perspectiveOrigin: \`\${position * trackItemOffset + itemWidth / 2}px 50%\`,
943          x
944        }}
945        onDragEnd={handleDragEnd}
946        animate={{ x: -(position * trackItemOffset) }}
947        transition={effectiveTransition}
948        onAnimationStart={handleAnimationStart}
949        onAnimationComplete={handleAnimationComplete}
950      >
951        {itemsForRender.map((item, index) => (
952          <CarouselItem
953            key={\`\${item?.id ?? index}-\${index}\`}
954            item={item}
955            index={index}
956            itemWidth={itemWidth}
957            round={round}
958            trackItemOffset={trackItemOffset}
959            x={x}
960            transition={effectiveTransition}
961          />
962        ))}
963      </motion.div>
964      <div className={\`carousel-indicators-container \${round ? 'round' : ''}\`}>
965        <div className="carousel-indicators">
966          {items.map((_, index) => (
967            <motion.button
968              type="button"
969              key={index}
970              className={\`carousel-indicator \${activeIndex === index ? 'active' : 'inactive'}\`}
971              aria-label={\`Go to slide \${index + 1}\`}
972              aria-current={activeIndex === index}
973              animate={{
974                scale: activeIndex === index ? 1.2 : 1
975              }}
976              onClick={() => setPosition(loop ? index + 1 : index)}
977              transition={{ duration: 0.15 }}
978            />
979          ))}
980        </div>
981      </div>
982    </div>
983  );
984}
985`,gn=`'use client';
986
987import { useEffect, useMemo, useRef, useState } from 'react';
988import { motion, type PanInfo, useMotionValue, useTransform } from 'motion/react';
989import React, { type JSX } from 'react';
990
991// replace icons with your own if needed
992import { FiCircle, FiCode, FiFileText, FiLayers, FiLayout } from 'react-icons/fi';
993export interface CarouselItem {
994  title: string;
995  description: string;
996  id: number;
997  icon: React.ReactNode;
998}
999
1000export interface CarouselProps {
1001  items?: CarouselItem[];
1002  baseWidth?: number;
1003  autoplay?: boolean;
1004  autoplayDelay?: number;
1005  pauseOnHover?: boolean;
1006  loop?: boolean;
1007  round?: boolean;
1008}
1009
1010const DEFAULT_ITEMS: CarouselItem[] = [
1011  {
1012    title: 'Text Animations',
1013    description: 'Cool text animations for your projects.',
1014    id: 1,
1015    icon: <FiFileText className="h-[16px] w-[16px] text-white" />
1016  },
1017  {
1018    title: 'Animations',
1019    description: 'Smooth animations for your projects.',
1020    id: 2,
1021    icon: <FiCircle className="h-[16px] w-[16px] text-white" />
1022  },
1023  {
1024    title: 'Components',
1025    description: 'Reusable components for your projects.',
1026    id: 3,
1027    icon: <FiLayers className="h-[16px] w-[16px] text-white" />
1028  },
1029  {
1030    title: 'Backgrounds',
1031    description: 'Beautiful backgrounds and patterns for your projects.',
1032    id: 4,
1033    icon: <FiLayout className="h-[16px] w-[16px] text-white" />
1034  },
1035  {
1036    title: 'Common UI',
1037    description: 'Common UI components are coming soon!',
1038    id: 5,
1039    icon: <FiCode className="h-[16px] w-[16px] text-white" />
1040  }
1041];
1042
1043const DRAG_BUFFER = 0;
1044const VELOCITY_THRESHOLD = 500;
1045const GAP = 16;
1046const SPRING_OPTIONS = { type: 'spring' as const, stiffness: 300, damping: 30 };
1047
1048interface CarouselItemProps {
1049  item: CarouselItem;
1050  index: number;
1051  itemWidth: number;
1052  round: boolean;
1053  trackItemOffset: number;
1054  x: any;
1055  transition: any;
1056}
1057
1058function CarouselItem({ item, index, itemWidth, round, trackItemOffset, x, transition }: CarouselItemProps) {
1059  const range = [-(index + 1) * trackItemOffset, -index * trackItemOffset, -(index - 1) * trackItemOffset];
1060  const outputRange = [90, 0, -90];
1061  const rotateY = useTransform(x, range, outputRange, { clamp: false });
1062
1063  return (
1064    <motion.div
1065      key={\`\${item?.id ?? index}-\${index}\`}
1066      className={\`relative shrink-0 flex flex-col \${
1067        round
1068          ? 'items-center justify-center text-center bg-[#120F17] border-0'
1069          : 'items-start justify-between bg-[#222] border border-[#222] rounded-[12px]'
1070      } overflow-hidden cursor-grab active:cursor-grabbing\`}
1071      style={{
1072        width: itemWidth,
1073        height: round ? itemWidth : '100%',
1074        rotateY: rotateY,
1075        ...(round && { borderRadius: '50%' })
1076      }}
1077      transition={transition}
1078    >
1079      <div className={\`\${round ? 'p-0 m-0' : 'mb-4 p-5'}\`}>
1080        <span className="flex h-[28px] w-[28px] items-center justify-center rounded-full bg-[#120F17]">
1081          {item.icon}
1082        </span>
1083      </div>
1084      <div className="p-5">
1085        <div className="mb-1 font-black text-lg text-white">{item.title}</div>
1086        <p className="text-sm text-white">{item.description}</p>
1087      </div>
1088    </motion.div>
1089  );
1090}
1091
1092export default function Carousel({
1093  items = DEFAULT_ITEMS,
1094  baseWidth = 300,
1095  autoplay = false,
1096  autoplayDelay = 3000,
1097  pauseOnHover = false,
1098  loop = false,
1099  round = false
1100}: CarouselProps): JSX.Element {
1101  const containerPadding = 16;
1102  const itemWidth = baseWidth - containerPadding * 2;
1103  const trackItemOffset = itemWidth + GAP;
1104  const itemsForRender = useMemo(() => {
1105    if (!loop) return items;
1106    if (items.length === 0) return [];
1107    return [items[items.length - 1], ...items, items[0]];
1108  }, [items, loop]);
1109
1110  const [position, setPosition] = useState<number>(loop ? 1 : 0);
1111  const x = useMotionValue(0);
1112  const [isHovered, setIsHovered] = useState<boolean>(false);
1113  const [isJumping, setIsJumping] = useState<boolean>(false);
1114  const [isAnimating, setIsAnimating] = useState<boolean>(false);
1115
1116  const containerRef = useRef<HTMLDivElement>(null);
1117  useEffect(() => {
1118    if (pauseOnHover && containerRef.current) {
1119      const container = containerRef.current;
1120      const handleMouseEnter = () => setIsHovered(true);
1121      const handleMouseLeave = () => setIsHovered(false);
1122      container.addEventListener('mouseenter', handleMouseEnter);
1123      container.addEventListener('mouseleave', handleMouseLeave);
1124      return () => {
1125        container.removeEventListener('mouseenter', handleMouseEnter);
1126        container.removeEventListener('mouseleave', handleMouseLeave);
1127      };
1128    }
1129  }, [pauseOnHover]);
1130
1131  useEffect(() => {
1132    if (!autoplay || itemsForRender.length <= 1) return undefined;
1133    if (pauseOnHover && isHovered) return undefined;
1134
1135    const timer = setInterval(() => {
1136      setPosition(prev => Math.min(prev + 1, itemsForRender.length - 1));
1137    }, autoplayDelay);
1138
1139    return () => clearInterval(timer);
1140  }, [autoplay, autoplayDelay, isHovered, pauseOnHover, itemsForRender.length]);
1141
1142  useEffect(() => {
1143    const startingPosition = loop ? 1 : 0;
1144    setPosition(startingPosition);
1145    x.set(-startingPosition * trackItemOffset);
1146  }, [items.length, loop, trackItemOffset, x]);
1147
1148  useEffect(() => {
1149    if (!loop && position > itemsForRender.length - 1) {
1150      setPosition(Math.max(0, itemsForRender.length - 1));
1151    }
1152  }, [itemsForRender.length, loop, position]);
1153
1154  const effectiveTransition = isJumping ? { duration: 0 } : SPRING_OPTIONS;
1155
1156  const handleAnimationStart = () => {
1157    setIsAnimating(true);
1158  };
1159
1160  const handleAnimationComplete = () => {
1161    if (!loop || itemsForRender.length <= 1) {
1162      setIsAnimating(false);
1163      return;
1164    }
1165    const lastCloneIndex = itemsForRender.length - 1;
1166
1167    if (position === lastCloneIndex) {
1168      setIsJumping(true);
1169      const target = 1;
1170      setPosition(target);
1171      x.set(-target * trackItemOffset);
1172      requestAnimationFrame(() => {
1173        setIsJumping(false);
1174        setIsAnimating(false);
1175      });
1176      return;
1177    }
1178
1179    if (position === 0) {
1180      setIsJumping(true);
1181      const target = items.length;
1182      setPosition(target);
1183      x.set(-target * trackItemOffset);
1184      requestAnimationFrame(() => {
1185        setIsJumping(false);
1186        setIsAnimating(false);
1187      });
1188      return;
1189    }
1190
1191    setIsAnimating(false);
1192  };
1193
1194  const handleDragEnd = (_: MouseEvent | TouchEvent | PointerEvent, info: PanInfo): void => {
1195    const { offset, velocity } = info;
1196    const direction =
1197      offset.x < -DRAG_BUFFER || velocity.x < -VELOCITY_THRESHOLD
1198        ? 1
1199        : offset.x > DRAG_BUFFER || velocity.x > VELOCITY_THRESHOLD
1200          ? -1
1201          : 0;
1202
1203    if (direction === 0) return;
1204
1205    setPosition(prev => {
1206      const next = prev + direction;
1207      const max = itemsForRender.length - 1;
1208      return Math.max(0, Math.min(next, max));
1209    });
1210  };
1211
1212  const dragProps = loop
1213    ? {}
1214    : {
1215        dragConstraints: {
1216          left: -trackItemOffset * Math.max(itemsForRender.length - 1, 0),
1217          right: 0
1218        }
1219      };
1220
1221  const activeIndex =
1222    items.length === 0 ? 0 : loop ? (position - 1 + items.length) % items.length : Math.min(position, items.length - 1);
1223
1224  return (
1225    <div
1226      ref={containerRef}
1227      className={\`relative overflow-hidden p-4 \${
1228        round ? 'rounded-full border border-white' : 'rounded-[24px] border border-[#222]'
1229      }\`}
1230      style={{
1231        width: \`\${baseWidth}px\`,
1232        ...(round && { height: \`\${baseWidth}px\` })
1233      }}
1234    >
1235      <motion.div
1236        className="flex"
1237        drag={isAnimating ? false : 'x'}
1238        {...dragProps}
1239        style={{
1240          width: itemWidth,
1241          gap: \`\${GAP}px\`,
1242          perspective: 1000,
1243          perspectiveOrigin: \`\${position * trackItemOffset + itemWidth / 2}px 50%\`,
1244          x
1245        }}
1246        onDragEnd={handleDragEnd}
1247        animate={{ x: -(position * trackItemOffset) }}
1248        transition={effectiveTransition}
1249        onAnimationStart={handleAnimationStart}
1250        onAnimationComplete={handleAnimationComplete}
1251      >
1252        {itemsForRender.map((item, index) => (
1253          <CarouselItem
1254            key={\`\${item?.id ?? index}-\${index}\`}
1255            item={item}
1256            index={index}
1257            itemWidth={itemWidth}
1258            round={round}
1259            trackItemOffset={trackItemOffset}
1260            x={x}
1261            transition={effectiveTransition}
1262          />
1263        ))}
1264      </motion.div>
1265      <div className={\`flex w-full justify-center \${round ? 'absolute z-20 bottom-12 left-1/2 -translate-x-1/2' : ''}\`}>
1266        <div className="mt-4 flex w-[150px] justify-between px-8">
1267          {items.map((_, index) => (
1268            <motion.button
1269              type="button"
1270              key={index}
1271              aria-label={\`Go to slide \${index + 1}\`}
1272              aria-current={activeIndex === index}
1273              className={\`h-2 w-2 rounded-full cursor-pointer border-0 p-0 appearance-none transition-colors duration-150 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white \${
1274                activeIndex === index
1275                  ? round
1276                    ? 'bg-white'
1277                    : 'bg-[#333333]'
1278                  : round
1279                    ? 'bg-[#555]'
1280                    : 'bg-[rgba(51,51,51,0.4)]'
1281              }\`}
1282              animate={{
1283                scale: activeIndex === index ? 1.2 : 1
1284              }}
1285              onClick={() => setPosition(loop ? index + 1 : index)}
1286              transition={{ duration: 0.15 }}
1287            />
1288          ))}
1289        </div>
1290      </div>
1291    </div>
1292  );
1293}
1294`,vn={dependencies:"motion",usage:`import Carousel from './Carousel'
1295
1296<div style={{ height: '600px', position: 'relative' }}>
1297  <Carousel
1298    baseWidth={300}
1299    autoplay={true}
1300    autoplayDelay={3000}
1301    pauseOnHover={true}
1302    loop={true}
1303    round={false}
1304  />
1305</div>`,code:fn,css:pn,tailwind:hn,tsCode:xn,tsTailwind:gn},S={baseWidth:300,autoplay:!1,autoplayDelay:3e3,pauseOnHover:!1,loop:!1,round:!1},Dn=()=>{const{props:e,updateProp:a,resetProps:x,hasChanges:u}=Q(S),{baseWidth:d,autoplay:i,autoplayDelay:f,pauseOnHover:g,loop:h,round:c}=e,[l,r]=cn(),p=m.useMemo(()=>[{name:"items",type:"CarouselItem[]",default:"DEFAULT_ITEMS",description:"An array of carousel items. Each item must include title, description, id, and icon."},{name:"baseWidth",type:"number",default:"300",description:"Total width (in px) of the carousel container. Effective item width is baseWidth minus padding."},{name:"autoplay",type:"boolean",default:"false",description:"Enables automatic scrolling to the next item at a fixed interval."},{name:"autoplayDelay",type:"number",default:"3000",description:"Delay in milliseconds between automatic scrolls when autoplay is enabled."},{name:"pauseOnHover",type:"boolean",default:"false",description:"Pauses the autoplay functionality when the carousel is hovered."},{name:"loop",type:"boolean",default:"false",description:"When true, the carousel loops seamlessly from the last item back to the first."},{name:"round",type:"boolean",default:"false",description:"When true, the carousel is rendered with a 1:1 aspect ratio and circular container/items."}],[]);return n.jsx(Z,{props:e,defaultProps:S,resetProps:x,hasChanges:u,children:n.jsxs(nn,{children:[n.jsxs(en,{children:[n.jsx(K,{position:"relative",className:"demo-container",h:4
130500,overflow:"hidden",children:n.jsx(un,{baseWidth:d,autoplay:i,autoplayDelay:f,pauseOnHover:g,loop:h,round:c},l)}),n.jsxs(an,{children:[n.jsx(T,{title:"Width",min:250,max:330,step:10,value:d,onChange:o=>{a("baseWidth",o),r()}}),n.jsx(b,{title:"Round Variant",isChecked:c,onChange:o=>{a("round",o),r()}}),n.jsx(b,{title:"Loop",isChecked:h,onChange:o=>{a("loop",o),r()}}),n.jsx(b,{title:"Autoplay",isChecked:i,onChange:o=>{a("autoplay",o),r()}}),n.jsx(T,{title:"Delay",min:1e3,max:4e3,step:1e3,value:f,isDisabled:!i,onChange:o=>{a("autoplayDelay",o),r()}}),n.jsx(b,{title:"Pause On Hover",isChecked:g,isDisabled:!i,onChange:o=>{a("pauseOnHover",o),r()}})]}),n.jsx(tn,{data:p}),n.jsx(rn,{dependencyList:["motion"]})]}),n.jsx(on,{children:n.jsx(sn,{codeObject:vn,componentName:"Carousel"})})]})})};export{Dn as default};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.