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.

116 lines (110 loc) 4.75 kB
import _extends from "@babel/runtime/helpers/esm/extends"; import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties"; const _excluded = ["children", "spacing", "scrollSnap", "onOverflow", "elevationColor", "overflowElevation", "scrollPadding", "dataTest", "minHeight"]; import * as React from "react"; import styled, { css } from "styled-components"; import Stack from "../Stack"; import mergeRefs from "../utils/mergeRefs"; import defaultTheme from "../defaultTheme"; import useTheme from "../hooks/useTheme"; import useScrollBox from "./useScroll"; const shadowMixin = css(["content:\"\";position:absolute;top:0;z-index:1;height:100%;"]); const StyledWrapper = styled.div.withConfig({ displayName: "HorizontalScroll__StyledWrapper", componentId: "sc-1rcvh7b-0" })(["", ""], ({ isDragging, $minHeight, elevationColor, overflowElevation, isStart, isOverflowing }) => css(["position:relative;width:100%;min-height:", ";cursor:", ";overflow:hidden;", " ", ""], $minHeight && `${$minHeight}px`, isOverflowing && (isDragging ? "grabbing" : "grab"), isOverflowing && overflowElevation && !isStart && css(["&:before{", ";left:0;box-shadow:5px 0px 20px 20px ", ";}"], shadowMixin, elevationColor), isOverflowing && overflowElevation && css(["&:after{", ";right:0;box-shadow:-5px 0px 20px 20px ", ";}"], shadowMixin, elevationColor))); // $FlowFixMe: https://github.com/flow-typed/flow-typed/issues/3653#issuecomment-568539198 StyledWrapper.defaultProps = { theme: defaultTheme }; const getSnap = ({ $scrollSnap }) => { if ($scrollSnap === "mandatory") return "x mandatory"; if ($scrollSnap === "proximity") return "x proximity"; return $scrollSnap; }; const StyledOverflow = styled.div.withConfig({ displayName: "HorizontalScroll__StyledOverflow", componentId: "sc-1rcvh7b-1" })(["", ""], ({ isDragging, scrollPadding }) => 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 = styled.div.withConfig({ displayName: "HorizontalScroll__StyledContainer", componentId: "sc-1rcvh7b-2" })(["", ""], ({ isDragging }) => css(["height:100%;width:100%;display:inline-flex;pointer-events:", ";"], isDragging && "none")); const HorizontalScroll = /*#__PURE__*/React.forwardRef((_ref, ref) => { let { children, spacing = "small", scrollSnap = "none", onOverflow, elevationColor = "paletteCloudDark", overflowElevation, scrollPadding, dataTest, minHeight } = _ref, props = _objectWithoutProperties(_ref, _excluded); const scrollWrapperRef = React.useRef(null); const containerRef = React.useRef(null); const { isDragging, reachedStart } = useScrollBox(scrollWrapperRef); const theme = useTheme(); const [isOverflowing, setOverflowing] = React.useState(false); const handleOverflow = React.useCallback(() => { var _scrollWrapperRef$cur, _containerRef$current; if ((_scrollWrapperRef$cur = scrollWrapperRef.current) !== null && _scrollWrapperRef$cur !== void 0 && _scrollWrapperRef$cur.scrollWidth && (_containerRef$current = containerRef.current) !== null && _containerRef$current !== void 0 && _containerRef$current.offsetWidth) { const { scrollWidth: containerScrollWidth } = scrollWrapperRef.current; const { offsetWidth } = containerRef.current; if (containerScrollWidth > offsetWidth) { setOverflowing(true); if (onOverflow) onOverflow(); } else { setOverflowing(false); } } }, [onOverflow]); React.useEffect(() => { handleOverflow(); window.addEventListener("resize", handleOverflow); return () => window.addEventListener("resize", handleOverflow); }, [handleOverflow]); return /*#__PURE__*/React.createElement(StyledWrapper, _extends({}, props, { $minHeight: minHeight, overflowElevation: overflowElevation, "data-test": dataTest, isDragging: isDragging, isStart: reachedStart, isOverflowing: isOverflowing, ref: mergeRefs([ref, containerRef]), elevationColor: theme.orbit[elevationColor] }), /*#__PURE__*/React.createElement(StyledOverflow, { $scrollSnap: scrollSnap, scrollPadding: scrollPadding, isDragging: isDragging, ref: scrollWrapperRef }, /*#__PURE__*/React.createElement(StyledContainer, { isDragging: isDragging }, /*#__PURE__*/React.createElement(Stack, { inline: true, spacing: spacing }, children)))); }); export default HorizontalScroll;