diff --git a/cms-slider/src/components/CMSSlider/CMSSlider.tsx b/cms-slider/src/components/CMSSlider/CMSSlider.tsx index 000f657..ab172c7 100644 --- a/cms-slider/src/components/CMSSlider/CMSSlider.tsx +++ b/cms-slider/src/components/CMSSlider/CMSSlider.tsx @@ -33,8 +33,9 @@ const CMSSlider = (props: CMSSliderProps) => { const parentRef = useRef(null); // Extract CMS collection items from Webflow slot - const { cmsCollectionComponentSlotRef, slideElements } = - useCMSCollectionItems("cmsCollectionComponentSlot"); + const { cmsCollectionComponentSlotRef, items } = useCMSCollectionItems( + "cmsCollectionComponentSlot" + ); // Inject global styles into shadow DOM useShadowGlobalStyles(parentRef); @@ -50,7 +51,7 @@ const CMSSlider = (props: CMSSliderProps) => { {/* Render slider once CMS items are extracted */} - {slideElements && slideElements.length > 0 && ( + {items && items.length > 0 && ( { autoplaySpeed={autoplaySpeed} swipeToSlide={true} > - {slideElements.map((slide, index) => ( - + {items.map((item, index) => ( + ))} )} diff --git a/cms-slider/src/components/CMSSlider/SlideItem.tsx b/cms-slider/src/components/CMSSlider/SlideItem.tsx index dca3eb4..ccf1ec4 100644 --- a/cms-slider/src/components/CMSSlider/SlideItem.tsx +++ b/cms-slider/src/components/CMSSlider/SlideItem.tsx @@ -3,18 +3,18 @@ import { useEffect, useRef } from "react"; /** * Wrapper component that renders a single CMS collection item as a slide */ -const SlideItem = (props: { slide: HTMLDivElement; index: number }) => { - const { slide, index } = props; - const slideRef = useRef(null); +const SlideItem = (props: { item: HTMLDivElement; index: number }) => { + const { item, index } = props; + const itemRef = useRef(null); // Append the cloned slide element to the container useEffect(() => { - if (slideRef.current) { - slideRef.current.appendChild(slide.cloneNode(true) as HTMLDivElement); + if (itemRef.current) { + itemRef.current.appendChild(item.cloneNode(true) as HTMLDivElement); } - }, [slide]); + }, [item]); - return
; + return
; }; export default SlideItem; diff --git a/cms-slider/src/components/CMSSlider/useCMSCollectionItems.ts b/cms-slider/src/components/CMSSlider/useCMSCollectionItems.ts index a5eba0e..149b39e 100644 --- a/cms-slider/src/components/CMSSlider/useCMSCollectionItems.ts +++ b/cms-slider/src/components/CMSSlider/useCMSCollectionItems.ts @@ -7,12 +7,10 @@ import { useEffect, useMemo, useRef, useState } from "react"; */ export function useCMSCollectionItems(slotName: string) { const cmsCollectionComponentSlotRef = useRef(null); - const [slideElements, setSlideElements] = useState( - null - ); + const [items, setItems] = useState(null); useEffect(() => { - if (slideElements === null && cmsCollectionComponentSlotRef.current) { + if (items === null && cmsCollectionComponentSlotRef.current) { // Find the slot element by name const slot = cmsCollectionComponentSlotRef.current.querySelector( `[name="${slotName}"]` @@ -29,22 +27,20 @@ export function useCMSCollectionItems(slotName: string) { ) ) as HTMLDivElement[] ).map((slide) => slide.cloneNode(true) as HTMLDivElement); - setSlideElements(slides); + setItems(slides); } } } - }, [cmsCollectionComponentSlotRef.current, slideElements]); + }, [cmsCollectionComponentSlotRef.current, items]); // Filter out empty slides and memoize for performance - const memoizedSlideElements = useMemo( - () => - slideElements?.filter((slide) => slide && slide.children.length > 0) ?? - [], - [slideElements] + const memoizedItems = useMemo( + () => items?.filter((item) => item && item.children.length > 0) ?? [], + [items] ); return { cmsCollectionComponentSlotRef, - slideElements: memoizedSlideElements, + items: memoizedItems, }; } diff --git a/cms-slider/src/hooks/useShadowGlobalStyles.tsx b/cms-slider/src/hooks/useShadowGlobalStyles.tsx index 551c14b..21ddc14 100644 --- a/cms-slider/src/hooks/useShadowGlobalStyles.tsx +++ b/cms-slider/src/hooks/useShadowGlobalStyles.tsx @@ -38,20 +38,97 @@ function copyGlobalStylesToShadow(shadowRoot: ShadowRoot) { ); styleElements.forEach((el) => { - let clone: HTMLElement | null = null; - - // Clone inline styles - if (el.tagName === "STYLE") { - clone = document.createElement("style"); - (clone as HTMLStyleElement).textContent = el.textContent; - } - // Clone linked stylesheets - else if (el.tagName === "LINK" && (el as HTMLLinkElement).href) { - clone = document.createElement("link"); - (clone as HTMLLinkElement).rel = "stylesheet"; - (clone as HTMLLinkElement).href = (el as HTMLLinkElement).href; + const clone = cloneStyleElement(el); + if (clone) { + shadowRoot.appendChild(clone); } - - if (clone) shadowRoot.appendChild(clone); }); } + +/** + * Clones a style or link element for injection into shadow DOM. + * + * @param el - The style or link element to clone + * @returns A cloned HTMLElement ready for shadow DOM, or null if element cannot be cloned + */ +function cloneStyleElement(el: Element): HTMLElement | null { + // Clone inline