UNPKG

@swissup/pwa-easy-slide

Version:

Easy slide(r) integration into venia-ui

230 lines (198 loc) 7.15 kB
import React, { useEffect, useState } from 'react'; import SwiperCore, { Navigation, Pagination, Scrollbar, Virtual, Keyboard, Parallax, Lazy, Autoplay, EffectFade, EffectCube, EffectFlip } from 'swiper'; // Import Swiper styles import 'swiper/swiper-bundle.min.css'; import { useStyle } from '@magento/venia-ui/lib/classify'; import defaultClasses from './easyslider.module.css'; // Import Swiper React components import { Swiper, SwiperSlide } from 'swiper/react'; import SlideImage from './slide/image'; import SlideDescription from './slide/description'; import { UNCONSTRAINED_SIZE_KEY } from '@magento/peregrine/lib/talons/Image/useImage'; import { useWindowSize } from '@magento/peregrine'; import easysliderOperations from '@swissup/pwa-easy-slide/lib/queries/getEasySlider.gql'; import { useEasySlider, useEasySlideImg } from '@swissup/pwa-easy-slide/lib/talons/EasySlide'; import PlaceholderImage from '@magento/venia-ui/lib/components/Image/placeholderImage'; // install Swiper components SwiperCore.use([ Navigation, Pagination, Scrollbar, Virtual, Keyboard, Parallax, Lazy, Autoplay, EffectFade, EffectCube, EffectFlip ]); const unescapeHtml = (html) => { const tempElement = document.createElement('div'); tempElement.innerHTML = html; return tempElement.textContent || tempElement.innerText || ""; }; const toHTML = str => ({ __html: unescapeHtml(str) }); const EasySlider = props => { const { identifier, sliderConfig: defaultSliderConfig, placeholder: placeholderProps } = props; const classes = useStyle(defaultClasses, props.classes); const talonProps = useEasySlider({ ...easysliderOperations, identifier }); const { data: { slider_config: loadedSliderConfig, slides } } = talonProps; const [isLoaded, setIsLoaded] = useState(false); const [swiper, setSwiper] = useState(null); const [isConfigLoaded, setIsConfigLoaded] = useState(false); const [swiperConfig, setSwiperConfig] = useState({ spaceBetween: 50, slidesPerView: 1,//'auto', loop: true, roundLengths: true, ...defaultSliderConfig, // autoHeight: true, // loadprevnext: true, // startrandomslide: true, }); useEffect(() => { if (!isConfigLoaded && loadedSliderConfig) { setIsConfigLoaded(true); setSwiperConfig({ ...swiperConfig, ...loadedSliderConfig }); } }, [ isConfigLoaded, setIsConfigLoaded, swiperConfig, setSwiperConfig, loadedSliderConfig, defaultSliderConfig ]); useEffect(() => { if (isConfigLoaded && slides && slides.length > 0) { setIsLoaded(true); } }, [slides, setIsLoaded, isConfigLoaded]); const placeholder = (<PlaceholderImage classes={classes} {...placeholderProps} />); const windowSize = useWindowSize(); const isDesktop = windowSize.innerWidth >= 768;//1024; // const getSlideDescription = (description) => { // if (!description) { // return ''; // } // const node = new DOMParser().parseFromString( // description, // 'text/html' // ); // const title = node.querySelector('div.h1').innerText; // const text = node.querySelector('div.text').innerText; // const actionNode = node.querySelector('a.action.primary'); // const href = actionNode.getAttribute('href') // .replace(process.env.MAGENTO_BACKEND_URL, '/') // .replace('/index.php', ''); // return (<div className={classes.slideDescription}> // <div className={classes.slideDescriptionTitle}>{title}</div> // <div className={classes.slideDescriptionText}>{text}</div> // <div> // <a className={classes.slideDescriptionAction} title={actionNode.getAttribute('title')} href={href}> // <div dangerouslySetInnerHTML={toHTML(actionNode.innerHTML)} /> // </a> // </div> // </div>); // // return description ? <div className={classes.slideDescription} dangerouslySetInnerHTML={toHTML(description)} /> : ''; // } const getSwiper = (config) => { const loop = !!config.loop; const scrollbar = config.scrollbar ? { draggable: true } : false; const freeMode = !!config.freeMode; const pagination = config.pagination ? { clickable: true } : false; const navigation = !!config.navigation; const lazy = !!config.lazy; const slidesPerView = config.slidesPerView && isDesktop ? config.slidesPerView : 'auto'; const spaceBetween = config.spaceBetween ? config.spaceBetween : 50; const widths = new Map(); if (config.sizes) { config.sizes.forEach( ({image_width}) => {widths.set(image_width, image_width)} ); } return (<Swiper scrollbar={scrollbar} freeMode={freeMode} pagination={pagination} navigation={navigation} loop={loop} lazy={lazy} slidesPerView={slidesPerView} spaceBetween={spaceBetween} onSwiper={setSwiper} onInit={(swiper) => {/*console.log('Swiper initialized!', swiper)*/}} onSlideChange={() => {/*console.log('slide change')*/}} onReachEnd={() => {/*console.log('Swiper end reached')*/}} > { slides && slides.length > 0 ? slides.map(({ slide_id, image, width, height, description }, index ) => { const { path, alt /*, src*/ } = useEasySlideImg({ slide_id, image, width, height }); widths.set(UNCONSTRAINED_SIZE_KEY, width); // const slideDescription = getSlideDescription(description); const isImageLazy = index === 0 ? false : lazy; return <SwiperSlide className={classes.slide} key={`slide-${slide_id}`}> <SlideImage className={classes.image} resource={path} type={'image-easyslide'} alt={alt} width={width} height={height} widths={widths} lazy={isImageLazy} /> <SlideDescription description={description} /> </SwiperSlide> }) : placeholder } </Swiper>) }; return ( <div className={classes.root}> {isLoaded ? getSwiper(swiperConfig) : placeholder} </div> ) }; export default EasySlider;