UNPKG

@kiwicom/orbit-components

Version:

Orbit-components is a React component library which provides developers with the easiest possible way of building Kiwi.com’s products.

184 lines (183 loc) 7.47 kB
"use strict"; "use client"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default; exports.__esModule = true; exports.default = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var React = _interopRequireWildcard(require("react")); var _styledComponents = _interopRequireWildcard(require("styled-components")); var _Stack = _interopRequireDefault(require("../Stack")); var _mergeRefs = _interopRequireDefault(require("../utils/mergeRefs")); var _defaultTheme = _interopRequireDefault(require("../defaultTheme")); var _useTheme = _interopRequireDefault(require("../hooks/useTheme")); var _useScroll = _interopRequireDefault(require("./useScroll")); var _ChevronBackward = _interopRequireDefault(require("../icons/ChevronBackward")); var _ChevronForward = _interopRequireDefault(require("../icons/ChevronForward")); const TRIGGER_OFFSET = 20; const shadowMixin = (0, _styledComponents.css)(["content:\"\";position:absolute;top:0;z-index:1;height:100%;"]); const StyledButton = _styledComponents.default.button.withConfig({ displayName: "HorizontalScroll__StyledButton", componentId: "sc-c9mal1-0" })(["", ""], ({ isHidden }) => (0, _styledComponents.css)(["display:flex;cursor:pointer;align-items:center;background:transparent;border:0;z-index:10;height:100%;visibility:", ";"], isHidden ? "hidden" : "visible")); const StyledWrapper = _styledComponents.default.div.withConfig({ displayName: "HorizontalScroll__StyledWrapper", componentId: "sc-c9mal1-1" })(["", ";"], ({ isDragging, $minHeight, elevationColor, overflowElevation, isStart, theme, isOverflowing, isEnd }) => (0, _styledComponents.css)(["position:relative;width:100%;display:inline-flex;align-items:center;min-height:", ";cursor:", ";overflow:hidden;", " ", " ", "{position:absolute;&:first-child{left:", ";}&:nth-child(2){right:", ";}}"], $minHeight && `${$minHeight}px`, isOverflowing && (isDragging ? "grabbing" : "grab"), isOverflowing && overflowElevation && !isStart && (0, _styledComponents.css)(["&:before{", ";left:0;box-shadow:5px 0px 20px 20px ", ";}"], shadowMixin, elevationColor), isOverflowing && !isEnd && overflowElevation && (0, _styledComponents.css)(["&:after{", ";right:0;box-shadow:-5px 0px 20px 20px ", ";}"], shadowMixin, elevationColor), StyledButton, theme.orbit.spaceXXSmall, theme.orbit.spaceXXSmall)); StyledWrapper.defaultProps = { theme: _defaultTheme.default }; const getSnap = ({ $scrollSnap }) => { if ($scrollSnap === "mandatory") return "x mandatory"; if ($scrollSnap === "proximity") return "x proximity"; return $scrollSnap; }; const StyledOverflow = _styledComponents.default.div.withConfig({ displayName: "HorizontalScroll__StyledOverflow", componentId: "sc-c9mal1-2" })(["", ";"], ({ isDragging, scrollPadding }) => (0, _styledComponents.css)(["width:100%;height:100%;overflow-y:hidden;overflow-x:auto;scroll-snap-type:", ";scroll-padding:", ";box-sizing:border-box;-ms-overflow-style:none;overflow:-moz-scrollbars-none;scrollbar-width:none;::-webkit-scrollbar{display:none;}"], isDragging ? "none" : getSnap, scrollPadding && `${scrollPadding}px`)); const StyledContainer = _styledComponents.default.div.withConfig({ displayName: "HorizontalScroll__StyledContainer", componentId: "sc-c9mal1-3" })(["", ";"], ({ isDragging }) => (0, _styledComponents.css)(["height:100%;position:relative;width:100%;display:inline-flex;pointer-events:", ";"], isDragging && "none")); const HorizontalScroll = /*#__PURE__*/React.forwardRef(({ children, spacing = "small", arrows, scrollSnap = "none", onOverflow, elevationColor = "paletteCloudDark", arrowColor, overflowElevation, scrollPadding, dataTest, id, minHeight, ...props }, ref) => { const scrollWrapperRef = React.useRef(null); const [isOverflowing, setOverflowing] = React.useState(false); const [reachedStart, setReachedStart] = React.useState(true); const [reachedEnd, setReachedEnd] = React.useState(false); const containerRef = React.useRef(null); const { isDragging } = (0, _useScroll.default)(scrollWrapperRef); const theme = (0, _useTheme.default)(); const scrollEl = scrollWrapperRef.current; const handleOverflow = React.useCallback(() => { if (scrollWrapperRef.current?.scrollWidth && containerRef.current?.offsetWidth) { const { scrollWidth: containerScrollWidth } = scrollWrapperRef.current; const { offsetWidth } = containerRef.current; if (containerScrollWidth > offsetWidth) { setOverflowing(true); if (onOverflow) onOverflow(); } else { setOverflowing(false); } } }, [onOverflow]); const handleClick = direction => { if (scrollEl) { const { scrollLeft, offsetWidth } = scrollEl; const scrollAmount = scrollLeft + (direction === "left" ? -offsetWidth / 2 : offsetWidth / 2); scrollEl.scrollTo({ left: scrollAmount, behavior: "smooth" }); } }; const handleScroll = React.useCallback(() => { if (scrollEl) { const scrollWidth = scrollEl.scrollWidth - scrollEl.clientWidth; const { scrollLeft } = scrollEl; if (scrollLeft - TRIGGER_OFFSET <= 0) { setReachedStart(true); } else { setReachedStart(false); } if (scrollLeft + TRIGGER_OFFSET >= scrollWidth) { setReachedEnd(true); } else { setReachedEnd(false); } } }, [scrollEl]); const handleResize = React.useCallback(() => { handleOverflow(); handleScroll(); }, [handleOverflow, handleScroll]); React.useEffect(() => { handleOverflow(); window.addEventListener("resize", handleResize); return () => { window.removeEventListener("resize", handleResize); }; }, [handleOverflow, handleResize]); return /*#__PURE__*/React.createElement(StyledWrapper, (0, _extends2.default)({}, props, { $minHeight: minHeight, overflowElevation: overflowElevation, "data-test": dataTest, id: id, isDragging: isDragging, isEnd: reachedEnd, isStart: reachedStart, isOverflowing: isOverflowing, ref: (0, _mergeRefs.default)([ref, containerRef]), elevationColor: theme.orbit[elevationColor] }), arrows && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(StyledButton, { tabIndex: 0, type: "button", isHidden: reachedStart || !isOverflowing, onClick: () => handleClick("left") }, /*#__PURE__*/React.createElement(_ChevronBackward.default, { customColor: arrowColor })), /*#__PURE__*/React.createElement(StyledButton, { tabIndex: 0, type: "button", isHidden: reachedEnd || !isOverflowing, onClick: () => handleClick("right") }, /*#__PURE__*/React.createElement(_ChevronForward.default, { customColor: arrowColor }))), /*#__PURE__*/React.createElement(StyledOverflow, { $scrollSnap: scrollSnap, scrollPadding: scrollPadding, isDragging: isDragging, onScroll: handleScroll, ref: scrollWrapperRef }, /*#__PURE__*/React.createElement(StyledContainer, { isDragging: isDragging }, /*#__PURE__*/React.createElement(_Stack.default, { inline: true, spacing: spacing }, children)))); }); var _default = HorizontalScroll; exports.default = _default;