@botonic/react
Version:
Build Chatbots using React
102 lines • 5.15 kB
JavaScript
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
import { INPUT, isBrowser } from '@botonic/core';
import React, { useContext, useEffect, useRef, useState } from 'react';
import styled from 'styled-components';
import LeftArrow from '../assets/leftArrow.svg';
import RightArrow from '../assets/rightArrow.svg';
import { COLORS, WEBCHAT } from '../constants';
import { WebchatContext } from '../contexts';
import { resolveImage } from '../util/environment';
import { StyledScrollbar } from '../webchat/components/styled-scrollbar';
import { ButtonsDisabler } from './buttons-disabler';
import { Message } from './message';
const StyledCarousel = styled.div `
padding: 10px 0px;
display: flex;
flex-direction: row;
max-width: 100%;
${props => props.carouselArrowsEnabled && 'overflow-x: auto;'}
`;
const StyledItems = styled.div `
display: flex;
`;
const StyledArrowContainer = styled.div `
position: absolute;
top: calc(50% - 20px);
height: 40px;
width: 25px;
background: ${COLORS.SILVER};
display: flex;
align-items: center;
cursor: pointer;
justify-content: ${props => props.justifyContent};
left: ${props => props.left}px;
right: ${props => props.right}px;
border-top-${props => props.arrow}-radius: 30px;
border-bottom-${props => props.arrow}-radius: 30px;
`;
const StyledArrow = styled.img `
width: 20px;
height: 20px;
`;
const serialize = carouselProps => {
let carouselChildren = carouselProps.children;
if (!Array.isArray(carouselChildren))
carouselChildren = [carouselChildren];
return {
type: INPUT.CAROUSEL,
elements: carouselChildren.map(e => e && e.type && e.type.serialize && e.type.serialize(e.props)),
};
};
/**
*
* @param {MessageProps} props
* @returns {JSX.Element}
*/
export const Carousel = props => {
const { getThemeProperty } = useContext(WebchatContext);
let content = props.children;
const scrollbarOptions = Object.assign({ enable: true, autoHide: true }, getThemeProperty(WEBCHAT.CUSTOM_PROPERTIES.scrollbar));
const [hasLeftArrow, setLeftArrow] = useState(false);
const [hasRightArrow, setRightArrow] = useState(true);
const carouselRef = useRef(null);
const CustomCarouselLeftArrow = getThemeProperty(WEBCHAT.CUSTOM_PROPERTIES.customCarouselLeftArrow, undefined);
const CustomCarouselRightArrow = getThemeProperty(WEBCHAT.CUSTOM_PROPERTIES.customCarouselRightArrow, undefined);
const carouselArrowsEnabled = getThemeProperty(WEBCHAT.CUSTOM_PROPERTIES.enableCarouselArrows, true);
const scrollCarouselBy = value => {
carouselRef.current.scrollBy({
left: value,
behavior: 'smooth',
});
};
const setArrowsVisibility = event => {
const carousel = event.currentTarget;
const maxRightScroll = carousel.scrollWidth -
carousel.offsetWidth -
WEBCHAT.DEFAULTS.ELEMENT_MARGIN_RIGHT;
setLeftArrow(carousel.scrollLeft !== 0);
setRightArrow(carousel.scrollLeft < maxRightScroll);
};
const getArrows = () => {
const scrollBy = WEBCHAT.DEFAULTS.ELEMENT_WIDTH + WEBCHAT.DEFAULTS.ELEMENT_MARGIN_RIGHT;
return (_jsxs(_Fragment, { children: [hasLeftArrow &&
(CustomCarouselLeftArrow ? (_jsx(CustomCarouselLeftArrow, { scrollCarouselBy: scrollCarouselBy })) : (_jsx(StyledArrowContainer, Object.assign({ left: 0, arrow: 'right', justifyContent: 'flex-start', onClick: () => scrollCarouselBy(-scrollBy) }, { children: _jsx(StyledArrow, { src: resolveImage(LeftArrow) }) })))), hasRightArrow &&
(CustomCarouselRightArrow ? (_jsx(CustomCarouselRightArrow, { scrollCarouselBy: scrollCarouselBy })) : (_jsx(StyledArrowContainer, Object.assign({ right: 0, arrow: 'left', justifyContent: 'flex-end', onClick: () => scrollCarouselBy(scrollBy) }, { children: _jsx(StyledArrow, { src: resolveImage(RightArrow) }) }))))] }));
};
useEffect(() => {
const carousel = carouselRef.current;
if (carousel && carousel.addEventListener) {
carousel.addEventListener('scroll', setArrowsVisibility, false);
}
else if (carousel && carousel.attachEvent) {
carousel.attachEvent('scroll', setArrowsVisibility);
}
}, [carouselRef.current]);
const carouselProps = Object.assign(Object.assign({}, props), { children: ButtonsDisabler.updateChildrenButtons(props.children) });
if (isBrowser()) {
content = (_jsx(StyledScrollbar, Object.assign({ scrollbar: scrollbarOptions, autoHide: scrollbarOptions.autoHide }, { children: _jsxs(StyledCarousel, Object.assign({ ref: carouselRef, carouselArrowsEnabled: carouselArrowsEnabled }, { children: [_jsx(StyledItems, { children: carouselProps.children }), carouselArrowsEnabled && getArrows()] })) })));
}
return (_jsx(Message, Object.assign({ style: { width: '85%', padding: 0, backgroundColor: COLORS.TRANSPARENT }, blob: false, json: serialize(carouselProps), type: INPUT.CAROUSEL }, carouselProps, { children: content })));
};
Carousel.serialize = serialize;
//# sourceMappingURL=carousel.js.map