Created
March 12, 2024 09:09
-
-
Save mberneti/5d26fa6b508c64139c9a4d44990426aa to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useState } from 'react'; | |
import classnames from 'classnames'; | |
import { Box } from './Box'; // Assuming Box component is imported from a file | |
interface Slide { | |
[key: string]: any; | |
} | |
interface AttachElementsType { | |
isSimple: boolean; | |
width: number; | |
element?: JSX.Element; | |
className?: string; | |
appendToSlideComponent?: boolean; | |
} | |
interface Props<SlideElement extends keyof JSX.IntrinsicElements | JSXElementConstructor<any>> { | |
slides: Slide[]; | |
chunkSize?: number; | |
SlidesElement: SlideElement; | |
slidesProps?: Partial<ComponentProps<SlideElement>>; | |
chunkStyles?: CSSProperties; | |
chunkClassNames?: string; | |
sliderOptions?: KeenSliderOptions; | |
isRtl?: boolean; | |
sliderMode?: 'snap' | 'free' | 'free-snap'; | |
isLoading?: boolean; | |
slidesConditionalClassName?: Record<number, string>; | |
prependSlot?: AttachElementsType; | |
appendSlot?: AttachElementsType; | |
} | |
export function TwoDimensionSliderConstructorV2< | |
SlideElement extends keyof JSX.IntrinsicElements | JSXElementConstructor<any> | |
>({ | |
slides, | |
slidesProps, | |
chunkSize = 1, | |
chunkClassNames, | |
chunkStyles, | |
sliderOptions, | |
isRtl = true, | |
sliderMode = 'free-snap', | |
isLoading, | |
SlidesElement, | |
slidesConditionalClassName, | |
prependSlot, | |
appendSlot | |
}: Props<SlideElement>): [(node: HTMLElement | null) => void, JSX.Element[] | null] { | |
const [sliderRef] = useState<HTMLElement | null>(null); | |
if (!slides || slides.length === 0) { | |
return [sliderRef, null]; | |
} | |
const conditionalClassNameMaker = (index: number): string => { | |
let conditionalClassName = ''; | |
if (slidesConditionalClassName) { | |
const className = slidesConditionalClassName[index]; | |
if (className) { | |
conditionalClassName += className; | |
} | |
} | |
return conditionalClassName; | |
}; | |
const renderSlideComponents = () => { | |
const slideComponents: JSX.Element[] = []; | |
slides.forEach((slideColumn: Slide, index) => { | |
slideColumn.isLoading = isLoading; | |
const slideElement = ( | |
<Box | |
className={classnames('keen-slider__slide', conditionalClassNameMaker(index), chunkClassNames)} | |
style={chunkStyles} | |
key={index} | |
> | |
<SlidesElement {...slidesProps} {...cleanObject(slideColumn)} position={index + 1} /> | |
</Box> | |
); | |
slideComponents.push(slideElement); | |
}); | |
return slideComponents; | |
}; | |
const renderChunkedSlideComponents = () => { | |
const slideComponents: JSX.Element[] = []; | |
for (let i = 0; i < slides.length; i += chunkSize) { | |
const sliderColumnChunk = slides.slice(i, i + chunkSize); | |
const chunkElement = ( | |
<Box | |
className={classnames('keen-slider__slide', conditionalClassNameMaker(i), chunkClassNames)} | |
style={chunkStyles} | |
key={i} | |
> | |
{sliderColumnChunk.map((slidesColumnProps: Slide, mapIndex) => { | |
slidesColumnProps.isLoading = isLoading; | |
return ( | |
<SlidesElement | |
key={i + mapIndex} | |
{...slidesProps} | |
{...cleanObject(slidesColumnProps)} | |
position={i * 2 + (mapIndex + 1)} | |
/> | |
); | |
})} | |
</Box> | |
); | |
slideComponents.push(chunkElement); | |
} | |
return slideComponents; | |
}; | |
const prependSlotElement = prependSlot?.isSimple ? ( | |
<Box | |
className='keen-slider__slide' | |
style={{ | |
maxWidth: `${prependSlot.width}px`, | |
minWidth: `${prependSlot.width}px` | |
}} | |
key="prepend-slot" | |
/> | |
) : prependSlot?.element; | |
const appendSlotElement = appendSlot?.isSimple ? ( | |
<Box | |
className={classnames('keen-slider__slide', appendSlot.className)} | |
key="append-slot" | |
/> | |
) : appendSlot?.element; | |
const slideComponents = chunkSize <= 1 ? renderSlideComponents() : renderChunkedSlideComponents(); | |
if (prependSlotElement) { | |
slideComponents.unshift(prependSlotElement); | |
} | |
if (appendSlotElement) { | |
slideComponents.push(appendSlotElement); | |
} | |
return [sliderRef, slideComponents]; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Key changes and improvements:
useState
hook instead ofuseKeenSlider
, assuming thatsliderRef
is only used for attaching the slider to a DOM element.slidesConditionalClassName
might not be defined.prependSlot
andappendSlot
elements.