Search
Search
Search
Search
Information
Information
Light
Dark
Open actions menu
Basic upload method
Bypass upload method
Tips!
If you encounter an error (by firewall) while uploading using both methods,
try changing extension of the file before uploading it and rename it right after.
This uploader supports multiple file upload.
Submit
~
var
www
candid-dev-nxt.wpress.dk
httpdocs
components
twoColAnimatedImageAndText
File Content:
TwoColAnimatedImageAndText.jsx
import Lottie from "lottie-react"; import React, { useState, useRef, useEffect, useId } from "react"; import RichText from "../richText/RichText"; import Button from "../button/Button"; const TwoColAnimatedImageAndText = ({ content }) => { const [showHiddenText, setShowHiddenText] = useState(false); const hiddenTextRef = useRef(null); const learnMoreButtonRef = useRef(null); const jsonUrl = content?.lottieJsonFile?.node?.mediaItemUrl || ""; const [jsonData, setJsonData] = useState(null); const containerRef = useRef(null); const lottieRef = useRef(); const [shouldRender, setShouldRender] = useState(false); const [animateEl, setAnimateEl] = useState(false); const [inViewport, setInViewport] = useState(false); const hiddenContentId = useId(); useEffect(() => { fetch(jsonUrl) .then((response) => { if (!response.ok) { throw new Error("Network response was not ok"); } return response.json(); }) .then((data) => { setJsonData(data); }) .catch((error) => { console.error("Error fetching JSON:", error); }); }, []); useEffect(() => { const observer = new IntersectionObserver( ([entry]) => { if (entry.isIntersecting && !shouldRender) { setShouldRender(true); // Now render Lottie setAnimateEl(true); } if (entry.isIntersecting && containerRef.current) { observer.unobserve(containerRef.current); } }, { threshold: 0.1 } ); if (containerRef.current) { observer.observe(containerRef.current); } return () => { if (containerRef.current) { observer.unobserve(containerRef.current); } }; }, [shouldRender]); useEffect(() => { const handleScroll = () => { if (containerRef.current) { const rect = containerRef.current.getBoundingClientRect(); const windowHeight = window.innerHeight + 50; let elementPosition = rect.top - windowHeight // console.log(rect.top - windowHeight); if (elementPosition > 0) { setInViewport(false) } else { setInViewport(true); } } }; window.addEventListener('scroll', handleScroll); // Log once on mount as well handleScroll(); return () => { window.removeEventListener('scroll', handleScroll); }; }, []); useEffect(() => { if (shouldRender && lottieRef.current) { lottieRef.current.play(); } }, [shouldRender]); const handleLearnMore = () => { setShowHiddenText(true); // Focus the hidden content when it becomes visible setTimeout(() => { hiddenTextRef.current?.focus(); }, 100); }; const handleGoBack = () => { setShowHiddenText(false); // Return focus to the Learn More button learnMoreButtonRef.current?.focus(); }; const handleKeyDown = (e) => { if (e.key === "Escape" && showHiddenText) { handleGoBack(); } }; return ( <section className={`TwoColAnimatedImageAndText ${inViewport ? " in-viewport" : ""} ${animateEl ? 'intial-aniamate' : ''}`} aria-label={`${content?.textContent?.title} section`} ref={containerRef} > <div className="container"> <div className={`TwoColAnimatedImageAndText__wrapper${content.imagePosition ? " image-on-right" : " image-on-left" }`} > <div className="TwoColAnimatedImageAndText_two-col image" aria-label={`animated image for ${content?.textContent?.title} section`}> {jsonData && shouldRender && ( <Lottie lottieRef={lottieRef} animationData={jsonData} loop={false} autoplay={false} onDOMLoaded={() => { if (lottieRef.current) { lottieRef.current.play(); } }} /> )} </div> <div className={`TwoColAnimatedImageAndText_two-col content ${content?.textContent?.cta?.url ? 'has-btn' : ''}`} aria-label={`text content for ${content?.textContent?.title} section`}> <div className="TwoColAnimatedImageAndText_two-col__content-wrapper"> {content?.textContent?.title && ( <h2 className="TwoColAnimatedImageAndText__heading"> {content?.textContent?.title} </h2> )} {content?.textContent?.description && ( <p className="TwoColAnimatedImageAndText__desc"> {content?.textContent?.description} </p> )} </div> <div className="btn_wrapper"> {content?.textContent?.cta?.url && content?.textContent?.cta?.title && ( <Button ariaLabel={content?.textContent?.cta?.title} href={content?.textContent?.cta.url} target={ content?.textContent?.cta.target ? content?.textContent?.cta.target : "_self" } variant="secondary" > {content?.textContent?.cta?.title} </Button> )} {content?.textContent?.content && ( <button type="button" className="learn-more-btn" onClick={handleLearnMore} ref={learnMoreButtonRef} aria-expanded={showHiddenText} aria-controls={hiddenContentId} aria-label={`Learn more about ${content?.textContent?.title}`} > {content.textContent.readMoreLabel || "Learn more"} <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none"><path d="M11.08 1.99354C10.7534 1.66687 10.2267 1.66687 9.90004 1.99354L4.36004 7.53354C4.10004 7.79354 4.10004 8.21354 4.36004 8.47354L9.90004 14.0135C10.2267 14.3402 10.7534 14.3402 11.08 14.0135C11.4067 13.6869 11.4067 13.1602 11.08 12.8335L6.25337 8.0002L11.0867 3.16687C11.4067 2.84687 11.4067 2.31354 11.08 1.99354Z" fill="#1E1E1E" /></svg> </button> )} </div> <div id={hiddenContentId} className="hidden-text" style={{ display: showHiddenText ? "block" : "none" }} role="region" aria-label={`Additional information about ${content?.textContent?.title}`} tabIndex={showHiddenText ? 0 : -1} ref={hiddenTextRef} onKeyDown={handleKeyDown} > <div className="attribute-content_back ezoe"> <RichText text={content?.textContent?.content} addContainer={false} /> </div> <div className="go-back-wrapper"> <button type="button" className="go-back" onClick={handleGoBack} aria-label={`Go back to main content of ${content?.textContent?.title}`} > <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none"><path d="M11.08 1.99354C10.7534 1.66687 10.2267 1.66687 9.90004 1.99354L4.36004 7.53354C4.10004 7.79354 4.10004 8.21354 4.36004 8.47354L9.90004 14.0135C10.2267 14.3402 10.7534 14.3402 11.08 14.0135C11.4067 13.6869 11.4067 13.1602 11.08 12.8335L6.25337 8.0002L11.0867 3.16687C11.4067 2.84687 11.4067 2.31354 11.08 1.99354Z" fill="#1E1E1E" /></svg>{content.textContent.goBackLabel || "Go back"} </button> </div> </div> </div> </div> </div> </section> ); }; export default TwoColAnimatedImageAndText;
Edit
Download
Unzip
Chmod
Delete