UNPKG

@botonic/react

Version:

Build Chatbots using React

102 lines 5.15 kB
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