import React, { ReactNode, useEffect, useState } from 'react';
// eslint-disable-next-line import/no-named-default
import { default as SlickSlider, ResponsiveObject } from 'react-slick';
import styled from 'styled-components';
import { display, layout, space } from 'styled-system';
import {
MaterialCheck,
MaterialChevronLeft,
MaterialChevronRight,
} from '@t3n/icons';
import Box from '../Box';
import Button from '../Button';
import RoundedButton from '../RoundedButton';
export interface CarouselProps {
slidesToShow?: number;
slidesToScroll?: number;
responsive?: ResponsiveObject[];
speed?: number;
infinite?: boolean;
autoplay?: boolean;
autoplaySpeed?: number;
nextLabel?: string;
prevLabel?: string;
onNextClick?: () => void;
onPrevClick?: () => void;
hideNextButton?: boolean;
hidePrevButton?: boolean;
onChange?: (currentIndex: number) => void;
isRoundedButton?: boolean;
children?: ReactNode;
adaptiveHeight?: boolean;
}
const StyledSlider = styled(SlickSlider)`
> .slick-dots {
bottom: 10px;
${({ theme }) => layout({ theme, width: ['100%', 'unset'] })};
left: 50%;
transform: translateX(-50%);
}
> .slick-dots > li {
${({ theme }) =>
space({
theme,
m: ['0 8px', 0, 0, '0 1px'],
})};
@media (max-width: 429px) {
${({ theme }) =>
space({
theme,
m: ['0 4px', 0, 0, '0 1px'],
})};
}
}
> .slick-dots li button {
height: 8px;
width: 8px;
}
> .slick-dots li button:before {
font-size: 8px;
height: 8px;
width: 8px;
}
`;
const StyledNextButton = styled(Button)`
position: absolute;
right: 0;
bottom: 0;
${({ theme }) => display({ theme, display: ['none', 'block'] })}
`;
const StyledPrevButton = styled(Button)`
position: absolute;
left: 0;
bottom: 0;
z-index: 1;
${({ theme }) => display({ theme, display: ['none', 'block'] })}
`;
const StyledRoundedButtonWrapper = styled.div<{ position: 'left' | 'right' }>`
position: absolute;
bottom: 0;
${({ position }) => (position === 'left' ? 'left: 0;' : 'right: 0;')}
z-index: 1;
`;
const NextButton: React.FC<{
onClick?: () => void;
show: boolean;
label?: string;
customOnClick?: () => void;
isRoundedButton?: boolean;
isLastSlide?: boolean;
}> = ({
onClick,
show = true,
label,
customOnClick,
isRoundedButton,
isLastSlide,
}) => {
if (!show) return null;
const icon = isLastSlide ? MaterialCheck : MaterialChevronRight;
if (isRoundedButton) {
return (
);
}
return (
{label}
);
};
const PrevButton: React.FC<{
onClick?: () => void;
show: boolean;
label?: string;
customOnClick?: () => void;
isRoundedButton?: boolean;
}> = ({ onClick, show = true, label, customOnClick, isRoundedButton }) => {
if (!show) return null;
if (isRoundedButton) {
return (
);
}
return (
{label}
);
};
const Carousel: React.FC = ({
slidesToShow = 1,
slidesToScroll = 1,
responsive,
speed = 500,
infinite = false,
autoplay = false,
autoplaySpeed = 2000,
prevLabel = 'Zurück',
nextLabel = 'Nächste',
onNextClick,
onPrevClick,
hideNextButton,
hidePrevButton,
isRoundedButton,
onChange,
children,
adaptiveHeight,
}) => {
const [currentIndex, setCurrentIndex] = useState(0);
const slidesAmount = React.Children.count(children);
useEffect(() => {
if (onChange) {
onChange(currentIndex);
}
}, [currentIndex, onChange]);
const isLastSlide = currentIndex === slidesAmount - slidesToShow;
return (
}
prevArrow={
0 || infinite
}
isRoundedButton={isRoundedButton}
label={prevLabel}
customOnClick={onPrevClick}
/>
}
beforeChange={(prev, next) => setCurrentIndex(next)}
responsive={responsive}
>
{children}
);
};
export default Carousel;