@sikka/hawa
Version:
Modern UI Kit made with Tailwind
158 lines (155 loc) • 5.48 kB
JavaScript
"use client";
// elements/carousel/Carousel.tsx
import React, { useEffect, useState } from "react";
// util/index.ts
import { clsx } from "clsx";
import { twMerge } from "tailwind-merge";
function cn(...inputs) {
return twMerge(clsx(inputs));
}
// elements/carousel/Carousel.tsx
import useEmblaCarousel from "embla-carousel-react";
var Carousel = ({
items,
showArrows,
options,
autoplay,
direction = "ltr",
autoplayInterval = 3e3,
...props
}) => {
const [emblaRef, emblaApi] = useEmblaCarousel({
...options,
direction,
loop: autoplay ? true : (options == null ? void 0 : options.loop) || false
});
const [selectedIndex, setSelectedIndex] = useState(0);
useEffect(() => {
function selectHandler() {
const index = emblaApi == null ? void 0 : emblaApi.selectedScrollSnap();
setSelectedIndex(index || 0);
}
emblaApi == null ? void 0 : emblaApi.on("select", selectHandler);
return () => {
emblaApi == null ? void 0 : emblaApi.off("select", selectHandler);
};
}, [emblaApi]);
useEffect(() => {
let autoplayTimer;
if (autoplay && emblaApi) {
autoplayTimer = setInterval(() => {
emblaApi.scrollNext();
}, autoplayInterval);
}
return () => {
if (autoplayTimer) clearInterval(autoplayTimer);
};
}, [emblaApi, autoplay, autoplayInterval]);
const length = React.Children.count(items);
const canScrollNext = !!(emblaApi == null ? void 0 : emblaApi.canScrollNext());
const canScrollPrev = !!(emblaApi == null ? void 0 : emblaApi.canScrollPrev());
return /* @__PURE__ */ React.createElement("div", { className: "hawa-relative hawa-h-full" }, /* @__PURE__ */ React.createElement("div", { className: "hawa-h-full hawa-overflow-hidden" }, /* @__PURE__ */ React.createElement("div", { className: "hawa-h-full", ref: emblaRef }, /* @__PURE__ */ React.createElement("div", { className: "hawa-flex hawa-h-full" }, items == null ? void 0 : items.map((item, i) => /* @__PURE__ */ React.createElement(
"div",
{
key: i,
className: "hawa-flex hawa-h-full hawa-min-w-0 hawa-flex-[0_0_100%] hawa-items-center hawa-justify-center"
},
item
))))), /* @__PURE__ */ React.createElement(
Dots,
{
direction,
itemsLength: length,
selectedIndex,
onDotClick: (index) => emblaApi == null ? void 0 : emblaApi.scrollTo(index)
}
), showArrows && /* @__PURE__ */ React.createElement(
CarouselControls,
{
canScrollNext,
canScrollPrev,
onNext: () => emblaApi == null ? void 0 : emblaApi.scrollNext(),
onPrev: () => emblaApi == null ? void 0 : emblaApi.scrollPrev()
}
));
};
var Dots = ({
onDotClick,
itemsLength,
selectedIndex,
direction
}) => {
const arr = new Array(itemsLength).fill(0);
return /* @__PURE__ */ React.createElement(
"div",
{
dir: direction,
className: "hawa-z-50 hawa-my-2 hawa-flex hawa-justify-center hawa-gap-1"
},
arr.map((_, index) => {
const selected = index === selectedIndex;
return /* @__PURE__ */ React.createElement(
"div",
{
key: index,
onClick: () => onDotClick(index),
className: cn(
"hawa-h-2 hawa-rounded-full hawa-bg-primary hawa-transition-all hawa-duration-300 hover:hawa-cursor-pointer",
!selected ? "hawa-w-2 hawa-opacity-50" : "hawa-w-6 hawa-opacity-100"
)
}
);
})
);
};
var CarouselControls = (props) => {
return /* @__PURE__ */ React.createElement("div", { className: "hawa-flex hawa-justify-end hawa-gap-2" }, /* @__PURE__ */ React.createElement(
"button",
{
onClick: () => props.canScrollPrev && props.onPrev(),
disabled: !props.canScrollPrev,
className: cn(
"hawa-absolute hawa-start-0 hawa-top-1/2 -hawa-translate-y-2 hawa-rounded-full hawa-p-2 hawa-text-white",
!props.canScrollPrev && "hawa-bg-primary/50",
props.canScrollPrev && "hawa-bg-primary"
)
},
/* @__PURE__ */ React.createElement(
"svg",
{
"aria-label": "Chevron Right Icon",
stroke: "currentColor",
fill: "currentColor",
viewBox: "0 0 16 16",
className: "hawa-h-2 hawa-w-2 hawa-shrink-0 hawa-rotate-180 hawa-transition-transform hawa-duration-200"
},
/* @__PURE__ */ React.createElement("path", { d: "M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z" })
)
), /* @__PURE__ */ React.createElement(
"button",
{
onClick: () => props.canScrollNext && props.onNext(),
disabled: !props.canScrollNext,
className: cn(
"hawa-absolute hawa-end-0 hawa-top-1/2 -hawa-translate-y-2 hawa-rounded-full hawa-p-2 hawa-text-white",
!props.canScrollNext && "hawa-bg-primary/50",
props.canScrollNext && "hawa-bg-primary"
)
},
/* @__PURE__ */ React.createElement(
"svg",
{
"aria-label": "Chevron Right Icon",
stroke: "currentColor",
fill: "currentColor",
viewBox: "0 0 16 16",
className: "hawa-h-2 hawa-w-2 hawa-shrink-0 hawa-transition-transform hawa-duration-200"
},
/* @__PURE__ */ React.createElement("path", { d: "M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z" })
)
));
};
export {
Carousel
};
//# sourceMappingURL=index.mjs.map