UNPKG

vcc-ui

Version:

VCC UI is a collection of React UI Components that can be used for developing front-end applications at Volvo Car Corporation.

124 lines (109 loc) 3.56 kB
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } import React, { useState, useEffect } from 'react'; import PropTypes from 'prop-types'; import { useFela } from 'react-fela'; import { Block } from '../block'; import { getThemeStyle } from '../../get-theme-style'; var hideOnScrollOffsetTop = 80; var navStyle = function navStyle(_ref) { var theme = _ref.theme, sticky = _ref.sticky, hideOnScroll = _ref.hideOnScroll, isVisible = _ref.isVisible; return { position: 'relative', zIndex: 10, width: '100%', background: theme.color.background.primary, boxSizing: 'border-box', ':before': { content: "''", display: 'block', background: theme.color.ornament.divider, height: 1, outline: 'none', position: 'absolute', left: 0, right: 0, zIndex: -1, bottom: 0 }, extend: [{ condition: sticky, style: { position: 'fixed', top: 0, left: 0 } }, { condition: hideOnScroll, style: { transition: 'transform 200ms ease-out' } }, { condition: !isVisible, style: { transform: 'translateY(-100%)' } }] }; }; // using an external variable for performance reasons var previousScrollY = 0; export var Nav = React.forwardRef(function (_ref2, ref) { var hideOnScroll = _ref2.hideOnScroll, sticky = _ref2.sticky, children = _ref2.children; var _useState = useState(true), _useState2 = _slicedToArray(_useState, 2), isVisible = _useState2[0], setVisible = _useState2[1]; var _useFela = useFela(), theme = _useFela.theme; useEffect(function () { var toggleVisibility = function toggleVisibility() { if (window.scrollY > previousScrollY) { if (isVisible && window.scrollY > hideOnScrollOffsetTop) { setVisible(false); } } else { if (!isVisible) { setVisible(true); } } previousScrollY = window.scrollY; }; if (hideOnScroll) { window.addEventListener('scroll', toggleVisibility); } return function () { window.removeEventListener('scroll', toggleVisibility); }; }, [hideOnScroll, isVisible]); var styleProps = { sticky: sticky, hideOnScroll: hideOnScroll, isVisible: isVisible, theme: theme }; return React.createElement(Block, { as: "nav", ref: ref, extend: [navStyle(styleProps), getThemeStyle('nav', theme, styleProps)] }, children); }); Nav.displayName = 'Nav'; Nav.propTypes = { /** Automatically hide the sticky navigation if the user starts scrolling */ hideOnScroll: PropTypes.bool, /** Make the navigation stick to the top of the viewport */ sticky: PropTypes.bool, /** A JSX node */ children: PropTypes.node }; Nav.defaultProps = { hideOnScroll: false, sticky: false };