import React, { useContext } from 'react'; import { useDispatch, ReactReduxContext } from 'react-redux'; import classNames from 'classnames'; import { createMarkers } from './marker'; // import 'element-closest-polyfill'; import isElement from 'lodash/isElement'; /* !- React Actions */ import { flush } from '../layer/actions'; /* !- Components */ const Title = ({ heading, children, className, style }) => { if (typeof heading === 'number') { const Heading = `h${heading}`; return {children}; } return
{children}
; } /* !- Constants */ /* !- Types */ const defaultProps = { image: '', title: '', subTitle: '', className: '', classNameCaption: 'bg-white p-2 absolute w-full', classNameTitle: 'text-l bold text-line-m mobile:text-m', classNameSubTitle: 'pt-1/2 light text-line-l', classNameImage: '', createMarkers, onClick: () => { return false; }, } type PropTypes = Partial & { onDragMarker: () => void, heading?: number, }; /** * [Card description] */ const Card = ({ image = defaultProps.image, title = defaultProps.title, subTitle = defaultProps.subTitle, className = defaultProps.className, classNameImage = defaultProps.classNameImage, classNameCaption = defaultProps.classNameCaption, classNameTitle = defaultProps.classNameTitle, classNameSubTitle = defaultProps.classNameSubTitle, border, markers, createMarkers = defaultProps.createMarkers, onClick = defaultProps.onClick, onDragMarker, children, heading, }: PropTypes) => { const { store } = useContext(ReactReduxContext); const dispatch = useDispatch(); let cardElement; // const onErrorImageListener = (e) => // { // const item = e.currentTarget; // item.parentNode.removeChild(item); // e.currentTarget.src = 'http://beta.rs.hu/img/uploads/700x510_1561547628.0117_5d1352b33f6cc.jpg'; // } const classes = classNames({ relative: true, 'no-select': true, border: border === true, pointer: onClick.toString() !== defaultProps.onClick.toString(), [className]: true, }); const captionPadding = parseInt((/p-([0-9]{1})/.exec(classNameCaption) || [])[1] || 0) * 2 / 1.6; let imagePadding = '0rem'; if (title || subTitle) { imagePadding += ` + ${captionPadding}em`; } if (title) { imagePadding += ' + 1.5em + 0.5em'; } if (subTitle) { imagePadding += ' + 1.5em'; } const onMouseOutLayerHandler = (event) => { const layer = store.getState().layer || {}; if ( layer.method !== 'popover' || ( event.relatedTarget && event.currentTarget && typeof (event.currentTarget.contains) === 'function' && isElement(event.relatedTarget) && ( event.currentTarget.contains(event.relatedTarget) || event.relatedTarget === cardElement || cardElement.contains(event.relatedTarget) ) ) ) { return; } event.stopPropagation(); // need before remove listener event.currentTarget.removeEventListener('mouseout', onMouseOutLayerHandler); dispatch(flush()); } const onMouseOutHandler = (event) => { if (!markers || !markers.length) { return false; } cardElement = event.currentTarget; if ( event.relatedTarget && ( event.currentTarget.contains(event.relatedTarget) || (event.relatedTarget.closest && event.relatedTarget.closest('.layer')) ) ) { if (event.relatedTarget.closest && event.relatedTarget.closest('.layer .container')) { event.relatedTarget .closest('.layer .container') .addEventListener( "mouseout", onMouseOutLayerHandler, ) } return; } const layer = store.getState().layer; if (layer && layer.method === 'popover') { dispatch(flush()); } } /** * Invoke when marker position chage by drag. * Marker draging enable by onDragMarker props function. */ const onDragEndHandler = (event) => { const targetRect = event.currentTarget.getBoundingClientRect(); const x = Math.round((event.clientX - targetRect.x) / targetRect.width * 1000) / 10; const y = Math.round((event.clientY - targetRect.y) / targetRect.height * 1000) / 10; const index = event.target.dataset.index; onDragMarker({ x, y, index }); } return (
{image &&
{title} {markers ? createMarkers(onDragMarker ? markers.map(marker => ({ ...marker, draggable: true })) : markers) : children}
} {(title || subTitle) &&
{title && {title} } {subTitle &&
{subTitle}
}
}
); }; export default Card;