HelpLogin
© 2022-2025 Spice AI, Inc.
SQL Query ReferenceDocsFAQSupport
PrivacyTerms
Status
Home
Datasets
Models
trunk
Edit on GitHub
Fork
/docs/website/src/components/organisms/before-and-after/before-and-after-slide.tsx
1'use client';
2
3import clsx from 'clsx';
4import { ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/24/outline';
5
6import { SlideData } from './data';
7import { CarouselApi } from '../../ui/carousel';
8import { Benefit } from '../../molecules/benefit/benefit';
9
10import { classNames } from '../../../lib/utils';
11
12type BeforeAndAfterSlideProps = {
13 slideData: SlideData;
14 carouselApi?: CarouselApi;
15 isCurrentSlide?: boolean;
16 isBefore: boolean;
17};
18
19export const BeforeAndAfterSlide = ({
20 slideData,
21 carouselApi,
22 isCurrentSlide,
23 isBefore,
24}: BeforeAndAfterSlideProps) => {
25 return (
26 <div className={clsx(!carouselApi && 'px-4 sm:px-16 xl:px-20')}>
27 <div
28 className={clsx(
29 'relative overflow-hidden rounded-lg border border-alpha-150 bg-neutral px-6 pb-10 pt-28 md:px-20',
30 !carouselApi && 'mx-auto max-w-screen-xl'
31 )}
32 >
33 <img
34 src={isBefore ? slideData.imageBefore : slideData.imageAfter}
35 alt='Before and After Slide'
36 width={1600}
37 height={800}
38 className='w-full object-contain lg:h-80'
39 />
40
41 <div className='mt-14 grid grid-cols-1 gap-6 lg:mt-12 lg:grid-cols-3'>
42 {slideData.benefits.map((benefit, index) => (
43 <Benefit
44 key={index}
45 isBefore={isBefore}
46 textBefore={benefit.textBefore}
47 textAfter={benefit.textAfter}
48 />
49 ))}
50 </div>
51
52 {/* Desktop arrows */}
53
54 {carouselApi && !isCurrentSlide && (
55 <>
56 <ArrowButton
57 className='right-1.5 xl:right-3'
58 onClick={() => carouselApi?.scrollPrev()}
59 >
60 <ChevronLeftIcon className='relative right-px h-6 w-6' />
61 </ArrowButton>
62 <ArrowButton
63 className='left-1.5 xl:left-3'
64 onClick={() => carouselApi?.scrollNext()}
65 >
66 <ChevronRightIcon className='relative left-px h-6 w-6' />
67 </ArrowButton>
68 </>
69 )}
70 </div>
71 </div>
72 );
73};
74
75const ArrowButton = ({
76 className,
77 onClick,
78 children,
79}: {
80 className?: string;
81 onClick: () => void;
82 children: React.ReactNode;
83}) => {
84 return (
85 <button
86 type='button'
87 onClick={onClick}
88 className={classNames(
89 'absolute bottom-[47%] z-10 hidden -translate-y-1/2 rounded-full p-2 text-neutral-700 transition-colors hover:bg-neutral-100 hover:text-primary md:block',
90 className
91 )}
92 aria-label='Change slide'
93 >
94 {children}
95 </button>
96 );
97};
98
1'use client';
2
3import clsx from 'clsx';
4import { ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/24/outline';
5
6import { SlideData } from './data';
7import { CarouselApi } from '../../ui/carousel';
8import { Benefit } from '../../molecules/benefit/benefit';
9
10import { classNames } from '../../../lib/utils';
11
12type BeforeAndAfterSlideProps = {
13 slideData: SlideData;
14 carouselApi?: CarouselApi;
15 isCurrentSlide?: boolean;
16 isBefore: boolean;
17};
18
19export const BeforeAndAfterSlide = ({
20 slideData,
21 carouselApi,
22 isCurrentSlide,
23 isBefore,
24}: BeforeAndAfterSlideProps) => {
25 return (
26 <div className={clsx(!carouselApi && 'px-4 sm:px-16 xl:px-20')}>
27 <div
28 className={clsx(
29 'relative overflow-hidden rounded-lg border border-alpha-150 bg-neutral px-6 pb-10 pt-28 md:px-20',
30 !carouselApi && 'mx-auto max-w-screen-xl'
31 )}
32 >
33 <img
34 src={isBefore ? slideData.imageBefore : slideData.imageAfter}
35 alt='Before and After Slide'
36 width={1600}
37 height={800}
38 className='w-full object-contain lg:h-80'
39 />
40
41 <div className='mt-14 grid grid-cols-1 gap-6 lg:mt-12 lg:grid-cols-3'>
42 {slideData.benefits.map((benefit, index) => (
43 <Benefit
44 key={index}
45 isBefore={isBefore}
46 textBefore={benefit.textBefore}
47 textAfter={benefit.textAfter}
48 />
49 ))}
50 </div>
51
52 {/* Desktop arrows */}
53
54 {carouselApi && !isCurrentSlide && (
55 <>
56 <ArrowButton
57 className='right-1.5 xl:right-3'
58 onClick={() => carouselApi?.scrollPrev()}
59 >
60 <ChevronLeftIcon className='relative right-px h-6 w-6' />
61 </ArrowButton>
62 <ArrowButton
63 className='left-1.5 xl:left-3'
64 onClick={() => carouselApi?.scrollNext()}
65 >
66 <ChevronRightIcon className='relative left-px h-6 w-6' />
67 </ArrowButton>
68 </>
69 )}
70 </div>
71 </div>
72 );
73};
74
75const ArrowButton = ({
76 className,
77 onClick,
78 children,
79}: {
80 className?: string;
81 onClick: () => void;
82 children: React.ReactNode;
83}) => {
84 return (
85 <button
86 type='button'
87 onClick={onClick}
88 className={classNames(
89 'absolute bottom-[47%] z-10 hidden -translate-y-1/2 rounded-full p-2 text-neutral-700 transition-colors hover:bg-neutral-100 hover:text-primary md:block',
90 className
91 )}
92 aria-label='Change slide'
93 >
94 {children}
95 </button>
96 );
97};
98