responsive home page and layout
This commit is contained in:
@@ -35,11 +35,37 @@ function useCarousel() {
|
||||
return context;
|
||||
}
|
||||
|
||||
type ResponsiveNumber = number | { base: number; md?: number; lg?: number };
|
||||
|
||||
function useResponsiveNumber(value: ResponsiveNumber): number {
|
||||
const base = typeof value === "number" ? value : value.base;
|
||||
const md = typeof value === "number" ? undefined : value.md;
|
||||
const lg = typeof value === "number" ? undefined : value.lg;
|
||||
|
||||
const resolve = () => {
|
||||
if (typeof window === "undefined") return base;
|
||||
if (window.matchMedia("(min-width: 1024px)").matches) return lg ?? md ?? base;
|
||||
if (window.matchMedia("(min-width: 768px)").matches) return md ?? base;
|
||||
return base;
|
||||
};
|
||||
|
||||
const [resolved, setResolved] = useState(base);
|
||||
|
||||
useEffect(() => {
|
||||
const update = () => setResolved(resolve());
|
||||
update();
|
||||
window.addEventListener("resize", update);
|
||||
return () => window.removeEventListener("resize", update);
|
||||
}, [base, md, lg]);
|
||||
|
||||
return resolved;
|
||||
}
|
||||
|
||||
type CarouselProps = {
|
||||
children: ReactNode;
|
||||
slidesPerView?: number;
|
||||
slidesPerView?: ResponsiveNumber;
|
||||
slidesToScroll?: number;
|
||||
gap?: number;
|
||||
gap?: ResponsiveNumber;
|
||||
direction?: "rtl" | "ltr";
|
||||
className?: string;
|
||||
};
|
||||
@@ -52,10 +78,14 @@ const Carousel: FC<CarouselProps> = ({
|
||||
direction = "rtl",
|
||||
className,
|
||||
}) => {
|
||||
const resolvedSlidesPerView = useResponsiveNumber(slidesPerView);
|
||||
const resolvedGap = useResponsiveNumber(gap);
|
||||
const scrollBy = slidesToScroll ?? Math.max(1, Math.floor(resolvedSlidesPerView));
|
||||
|
||||
const [emblaRef, emblaApi] = useEmblaCarousel({
|
||||
align: "start",
|
||||
direction,
|
||||
slidesToScroll: slidesToScroll ?? slidesPerView,
|
||||
slidesToScroll: scrollBy,
|
||||
containScroll: "trimSnaps",
|
||||
});
|
||||
|
||||
@@ -80,6 +110,10 @@ const Carousel: FC<CarouselProps> = ({
|
||||
};
|
||||
}, [emblaApi]);
|
||||
|
||||
useEffect(() => {
|
||||
emblaApi?.reInit({ slidesToScroll: scrollBy });
|
||||
}, [emblaApi, scrollBy, resolvedSlidesPerView, resolvedGap]);
|
||||
|
||||
return (
|
||||
<CarouselContext.Provider
|
||||
value={{
|
||||
@@ -87,8 +121,8 @@ const Carousel: FC<CarouselProps> = ({
|
||||
scrollNext: () => emblaApi?.scrollNext(),
|
||||
canScrollPrev,
|
||||
canScrollNext,
|
||||
slidesPerView,
|
||||
gap,
|
||||
slidesPerView: resolvedSlidesPerView,
|
||||
gap: resolvedGap,
|
||||
}}
|
||||
>
|
||||
<CarouselViewportContext.Provider value={emblaRef}>
|
||||
|
||||
Reference in New Issue
Block a user