@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
JavaScript
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;