Skip to content

Commit

Permalink
Merge pull request #1014 from t3n/icon_button-in-carousel
Browse files Browse the repository at this point in the history
feat: allow chevron icon as button for carousel
  • Loading branch information
marxtin authored Jan 16, 2025
2 parents 22dbafd + d82269a commit b5691c8
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 5 deletions.
1 change: 1 addition & 0 deletions packages/components/src/Carousel/Carousel.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export interface CarouselProps {
hideNextButton?: boolean;
hidePrevButton?: boolean;
onChange?: (currentIndex: number) => void;
isIconButton?: boolean;
children?: ReactNode;
}
declare const Carousel: React.FC<CarouselProps>;
Expand Down
60 changes: 55 additions & 5 deletions packages/components/src/Carousel/Carousel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,15 @@ 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 IconButton from '../IconButton';

export interface CarouselProps {
slidesToShow?: number;
Expand All @@ -22,6 +29,7 @@ export interface CarouselProps {
hideNextButton?: boolean;
hidePrevButton?: boolean;
onChange?: (currentIndex: number) => void;
isIconButton?: boolean;
children?: ReactNode;
}

Expand Down Expand Up @@ -68,14 +76,40 @@ const StyledPrevButton = styled(Button)`
${({ theme }) => display({ theme, display: ['none', 'block'] })}
`;

const StyledIconButtonWrapper = 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;
label?: string;
customOnClick?: () => void;
}> = ({ onClick, show = true, label, customOnClick }) => {
isIconButton?: boolean;
isLastSlide?: boolean;
}> = ({
onClick,
show = true,
label,
customOnClick,
isIconButton,
isLastSlide,
}) => {
if (!show) return null;

const icon = isLastSlide ? MaterialCheck : MaterialChevronRight;

if (isIconButton) {
return (
<StyledIconButtonWrapper position="right">
<IconButton onClick={customOnClick || onClick} icon={icon} />
</StyledIconButtonWrapper>
);
}

return (
<StyledNextButton onClick={customOnClick || onClick}>
{label}
Expand All @@ -86,11 +120,23 @@ const NextButton: React.FC<{
const PrevButton: React.FC<{
onClick?: () => void;
show: boolean;
label: string;
label?: string;
customOnClick?: () => void;
}> = ({ onClick, show = true, label, customOnClick }) => {
isIconButton?: boolean;
}> = ({ onClick, show = true, label, customOnClick, isIconButton }) => {
if (!show) return null;

if (isIconButton) {
return (
<StyledIconButtonWrapper position="left">
<IconButton
onClick={customOnClick || onClick}
icon={MaterialChevronLeft}
/>
</StyledIconButtonWrapper>
);
}

return (
<StyledPrevButton onClick={customOnClick || onClick} variant="secondary">
{label}
Expand All @@ -112,6 +158,7 @@ const Carousel: React.FC<CarouselProps> = ({
onPrevClick,
hideNextButton,
hidePrevButton,
isIconButton,
onChange,
children,
}) => {
Expand All @@ -123,7 +170,7 @@ const Carousel: React.FC<CarouselProps> = ({
onChange(currentIndex);
}
}, [currentIndex, onChange]);

const isLastSlide = currentIndex === slidesAmount - slidesToShow;
return (
<Box>
<StyledSlider
Expand All @@ -141,6 +188,8 @@ const Carousel: React.FC<CarouselProps> = ({
? !hideNextButton
: currentIndex < slidesAmount - 1 || infinite
}
isLastSlide={isLastSlide}
isIconButton={isIconButton}
label={nextLabel}
customOnClick={onNextClick}
/>
Expand All @@ -152,6 +201,7 @@ const Carousel: React.FC<CarouselProps> = ({
? !hidePrevButton
: currentIndex > 0 || infinite
}
isIconButton={isIconButton}
label={prevLabel}
customOnClick={onPrevClick}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ export declare const infinite: Story;
export declare const autoplay: Story;
export declare const responsive: Story;
export declare const sliderInModal: Story;
export declare const carouselWithChevronButtons: Story;
export declare const sliderWithChevronButtonsInModal: Story;
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ const meta: Meta<typeof Carousel> = {
nextLabel: 'Nächste',
prevLabel: 'Zurück',
speed: 500,
isIconButton: false,
children: defaultData.map((el) => (
<Box key={el.id} mb={8} overflow="hidden">
<Image
Expand Down Expand Up @@ -150,6 +151,12 @@ const StyledBox = styled(Box)`

export const carousel: Story = {};

export const carouselWithChevronButtons: Story = {
args: {
isIconButton: true,
},
};

export const infinite: Story = {
args: {
infinite: true,
Expand Down Expand Up @@ -257,3 +264,62 @@ export const sliderInModal: Story = {
);
},
};

export const sliderWithChevronButtonsInModal: Story = {
decorators: [storyContainerDecorator],
render: () => {
const [showOnboardingModal, setShowOnboardingModal] = useState(true);
const [currentIndex, setCurrentIndex] = useState(0);

return (
<>
<Button onClick={() => setShowOnboardingModal(true)}>
Slider im Modal anzeigen
</Button>

{showOnboardingModal && (
<StyledBox>
<Modal headline="" onClose={() => setShowOnboardingModal(false)}>
<Carousel
onNextClick={
currentIndex === defaultData.length - 1
? () => setShowOnboardingModal(false)
: undefined
}
isIconButton
hideNextButton={false}
nextLabel={
currentIndex === defaultData.length - 1
? 'Schließen'
: undefined
}
onChange={setCurrentIndex}
>
{defaultData.map((el) => (
<Box key={el.id} mt={2} mb={8} overflow="hidden">
<Image
m="0 auto"
height={['165px', '180px', '150px', '200px', '250px']}
src={el.imageSrc}
alt={el.headline}
title={el.headline}
lazy={false}
/>

<Text bold mt={3} mb={2}>
{el.name}
</Text>
<Heading as="h5" my={0}>
{el.headline}
</Heading>
<Text>{el.description}</Text>
</Box>
))}
</Carousel>
</Modal>
</StyledBox>
)}
</>
);
},
};

0 comments on commit b5691c8

Please sign in to comment.