UNPKG

@ubertheme/slider

Version:
200 lines (188 loc) 6.05 kB
import React from 'react'; import {string, number, shape} from 'prop-types'; import {Link, resourceUrl} from '@magento/venia-ui/lib/drivers'; import ReactPlayer from 'react-player' import RickText from '@magento/venia-ui/lib/components/RichText'; import { useItem } from '../../talons/Slider/useItem'; import { mergeClasses } from '@magento/venia-ui/lib/classify'; import defaultClasses from './styles/item.css'; import { useExtraCss } from '@ubertheme/base/src/talons/useExtraCss'; import { generateSrcset, generateUrl } from '@magento/venia-ui/lib/util/images'; import { UNCONSTRAINED_SIZE_KEY } from '@magento/peregrine/lib/talons/Image/useImage'; /** * Item component. * * This component is a renderer of slide item * * @typedef Item * @kind functional component * * @param {Object} props React component props * * @returns {React.Element} A React component. */ const Item = props => { const { parentStyle = 'default', item, height, width, mobileWidth } = props; // Mapping width by breakpoint to optimize images const widths = new Map() .set(640, mobileWidth) .set(UNCONSTRAINED_SIZE_KEY, width); //default width // call useItem Hooks const { isMobile, handleClick, openedId, imageSizes } = useItem({ item, width, widths }); const classes = mergeClasses(defaultClasses, props.classes); const additionalClasses = item.additional_class; const { classNames } = useExtraCss({classes, additionalClasses}); let itemStyle = {}; let itemClassNames = classNames; let image = item.image; if (isMobile && item.mobile_image) { image = item.mobile_image; } let itemContent = null; if (item.content_type === 'image' && image) { //generates image sources const src = generateUrl( `/media/ubcontentslider/images${image}`, 'image-slide' )(width, height); const srcSet = generateSrcset( `/media/ubcontentslider/images${image}`, 'image-slide' ); //make content itemContent = ( <img loading="lazy" alt={item.title} height={height} width={width} sizes={imageSizes} src={src} srcSet={srcSet} /> ); } else if (item.content_type.indexOf('video') !== -1 && item.video_id) { //append extra css global class 'clickToPlay' itemClassNames += ' clickToPlay'; //make video url let videoUrl; if (item.content_type == 'youtube_video') { videoUrl = `https://www.youtube.com/watch?v=${item.video_id}`; } else if (item.content_type == 'vimeo_video') { videoUrl = `https://vimeo.com/${item.video_id}`; } //make cover image urls let src = null; let srcSet = null; if (item.video_cover) { src = item.video_cover; const absoluteUrl = /^(data|http|https)?:/i; const isAbsolute = absoluteUrl.test(src) || (src.indexOf('//') !== -1); if (!isAbsolute) { // has uploaded video cover image src = generateUrl( `/media/ubcontentslider/images${item.video_cover}`, 'image-slide' )(width, height); srcSet = generateSrcset( `/media/ubcontentslider/images${item.video_cover}`, 'image-slide' ); } } //make content itemContent = ( (openedId && openedId === item.id) ? <ReactPlayer className='react-player' url={videoUrl} width='100%' height='100%' controls playing /> : ( <span><img loading="lazy" alt={item.title} height={height} width={width} sizes={imageSizes} src={src} srcSet={srcSet} /></span> ) ); } //build item desc elements let itemDesc = ( ( item.id !== openedId || (item.id == openedId && ( parentStyle === 'outside' || (parentStyle !== 'outside' && isMobile) || classNames.indexOf('captionedOut') !== -1)) ) ? <div className={'desc'}> <h3> <Link className={''} to={resourceUrl(`/${item.link}`)} > {item.title} </Link> </h3> <RickText content={item.desc} classes={{ root: 'descContent' }} /> <Link className={'readmore'} to={resourceUrl(`/${item.link}`)} > View More </Link> </div> : null ); return ( <div style={itemStyle} className={itemClassNames}> <div className={'info'}> <Link className={'media'} to={resourceUrl(`/${item.link}`)} onClick={(e) => handleClick(e)} > {itemContent} </Link> {itemDesc} </div> </div> ); }; Item.propTypes = { id: number, classes: shape({ root: string }), parentStyle: string.isRequired, item: shape({ title: string.isRequired, link: string.isRequired, link_target: string.isRequired }).isRequired, height: number, width: number, mobileWidth: number }; export default Item;