@botonic/react
Version:
Build Chatbots using React
114 lines (113 loc) • 6.59 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Carousel = void 0;
const tslib_1 = require("tslib");
const jsx_runtime_1 = require("react/jsx-runtime");
const core_1 = require("@botonic/core");
const react_1 = require("react");
const styled_components_1 = tslib_1.__importDefault(require("styled-components"));
const leftArrow_svg_1 = tslib_1.__importDefault(require("../assets/leftArrow.svg"));
const rightArrow_svg_1 = tslib_1.__importDefault(require("../assets/rightArrow.svg"));
const constants_1 = require("../constants");
const environment_1 = require("../util/environment");
const context_1 = require("../webchat/context");
const buttons_disabler_1 = require("./buttons-disabler");
const message_1 = require("./message");
const ScrollableCarousel = styled_components_1.default.div `
overscroll-behavior: contain;
-webkit-overflow-scrolling: touch;
`;
const StyledCarousel = styled_components_1.default.div `
padding: 10px 0px;
display: flex;
flex-direction: row;
max-width: 100%;
${props => props.carouselArrowsEnabled && 'overflow-x: auto;'}
`;
const StyledItems = styled_components_1.default.div `
display: flex;
`;
const StyledArrowContainer = styled_components_1.default.div `
position: absolute;
top: calc(50% - 20px);
height: 40px;
width: 25px;
background: ${constants_1.COLORS.SILVER};
display: flex;
align-items: center;
cursor: pointer;
justify-content: ${props => props.justifyContent};
${props => (props.left ? ` left: ${props.left}px` : '')};
${props => (props.right ? ` right: ${props.right}px` : '')};
${props => (props.arrow === 'right' ? 'border-top-right-radius: 30px' : '')};
${props => props.arrow === 'right' ? 'border-bottom-right-radius: 30px' : ''};
${props => (props.arrow === 'left' ? 'border-top-left-radius: 30px' : '')};
${props => (props.arrow === 'left' ? 'border-bottom-left-radius: 30px' : '')};
`;
const StyledArrow = styled_components_1.default.img `
width: 20px;
height: 20px;
`;
const serialize = carouselProps => {
let carouselChildren = carouselProps.children;
if (!Array.isArray(carouselChildren))
carouselChildren = [carouselChildren];
return {
type: core_1.INPUT.CAROUSEL,
elements: carouselChildren.map(e => { var _a; return ((_a = e === null || e === void 0 ? void 0 : e.type) === null || _a === void 0 ? void 0 : _a.serialize) && e.type.serialize(e.props); }),
};
};
const Carousel = (props) => {
const { getThemeProperty } = (0, react_1.useContext)(context_1.WebchatContext);
const [hasLeftArrow, setLeftArrow] = (0, react_1.useState)(false);
const [hasRightArrow, setRightArrow] = (0, react_1.useState)(true);
const carouselRef = (0, react_1.useRef)(null);
const CustomCarouselLeftArrow = getThemeProperty(constants_1.WEBCHAT.CUSTOM_PROPERTIES.customCarouselLeftArrow);
const CustomCarouselRightArrow = getThemeProperty(constants_1.WEBCHAT.CUSTOM_PROPERTIES.customCarouselRightArrow);
// TODO: Investigate why when set to false, scroll is enabled via dragging the bar but not hovering the carousel elements
const carouselArrowsEnabled = getThemeProperty(constants_1.WEBCHAT.CUSTOM_PROPERTIES.enableCarouselArrows);
const scrollCarouselBy = value => {
var _a;
(_a = carouselRef.current) === null || _a === void 0 ? void 0 : _a.scrollBy({
left: value,
behavior: 'smooth',
});
};
const setArrowsVisibility = event => {
const carousel = event.currentTarget;
const maxRightScroll = carousel.scrollWidth -
carousel.offsetWidth -
constants_1.WEBCHAT.DEFAULTS.ELEMENT_MARGIN_RIGHT;
setLeftArrow(carousel.scrollLeft !== 0);
setRightArrow(carousel.scrollLeft < maxRightScroll);
};
const getArrows = () => {
const scrollBy = constants_1.WEBCHAT.DEFAULTS.ELEMENT_WIDTH + constants_1.WEBCHAT.DEFAULTS.ELEMENT_MARGIN_RIGHT;
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [hasLeftArrow &&
(CustomCarouselLeftArrow ? ((0, jsx_runtime_1.jsx)(CustomCarouselLeftArrow, { scrollCarouselBy: scrollCarouselBy })) : ((0, jsx_runtime_1.jsx)(StyledArrowContainer, Object.assign({ left: 0, arrow: 'right', justifyContent: 'flex-start', onClick: () => scrollCarouselBy(-scrollBy) }, { children: (0, jsx_runtime_1.jsx)(StyledArrow, { src: (0, environment_1.resolveImage)(leftArrow_svg_1.default) }) })))), hasRightArrow &&
(CustomCarouselRightArrow ? ((0, jsx_runtime_1.jsx)(CustomCarouselRightArrow, { scrollCarouselBy: scrollCarouselBy })) : ((0, jsx_runtime_1.jsx)(StyledArrowContainer, Object.assign({ right: 0, arrow: 'left', justifyContent: 'flex-end', onClick: () => scrollCarouselBy(scrollBy) }, { children: (0, jsx_runtime_1.jsx)(StyledArrow, { src: (0, environment_1.resolveImage)(rightArrow_svg_1.default) }) }))))] }));
};
(0, react_1.useEffect)(() => {
const carousel = carouselRef.current;
if (carousel && carousel.addEventListener) {
carousel.addEventListener('scroll', setArrowsVisibility, false);
}
return () => {
if (carousel && carousel.removeEventListener) {
carousel.removeEventListener('scroll', setArrowsVisibility, false);
}
};
}, [carouselRef.current]);
const carouselProps = Object.assign(Object.assign({}, props), { children: buttons_disabler_1.ButtonsDisabler.updateChildrenButtons(props.children) });
if ((0, core_1.isBrowser)()) {
return ((0, jsx_runtime_1.jsx)(message_1.Message, Object.assign({ style: {
width: '85%',
padding: 0,
backgroundColor: constants_1.COLORS.TRANSPARENT,
}, blob: false, json: serialize(carouselProps), type: core_1.INPUT.CAROUSEL }, carouselProps, { children: (0, jsx_runtime_1.jsx)(ScrollableCarousel, { children: (0, jsx_runtime_1.jsxs)(StyledCarousel, Object.assign({ ref: carouselRef, carouselArrowsEnabled: carouselArrowsEnabled }, { children: [(0, jsx_runtime_1.jsx)(StyledItems, { children: carouselProps.children }), carouselArrowsEnabled && getArrows()] })) }) })));
}
return ((0, jsx_runtime_1.jsx)(message_1.Message, Object.assign({ style: { width: '85%', padding: 0, backgroundColor: constants_1.COLORS.TRANSPARENT }, blob: false, json: serialize(carouselProps), type: core_1.INPUT.CAROUSEL }, carouselProps, { children: props.children })));
};
exports.Carousel = Carousel;
exports.Carousel.serialize = serialize;
//# sourceMappingURL=carousel.js.map