From c253f23b46040af1917f71527037019e6a57c7a8 Mon Sep 17 00:00:00 2001 From: Victor Genaev Date: Tue, 15 Feb 2022 11:57:04 +0100 Subject: [PATCH] feat(NavigationBar): add hideOnScroll prop (#3282) --- .../__examples__/NavigationBar/DEFAULT.tsx | 6 ++ .../NavigationBar/NavigationBar.stories.jsx | 40 +++++++++++- .../src/NavigationBar/README.md | 1 + .../src/NavigationBar/index.d.ts | 1 + .../src/NavigationBar/index.jsx | 62 ++++++++++++------- .../src/NavigationBar/index.jsx.flow | 1 + 6 files changed, 86 insertions(+), 25 deletions(-) diff --git a/docs/src/__examples__/NavigationBar/DEFAULT.tsx b/docs/src/__examples__/NavigationBar/DEFAULT.tsx index 2e8dc62954..3437c53d7d 100644 --- a/docs/src/__examples__/NavigationBar/DEFAULT.tsx +++ b/docs/src/__examples__/NavigationBar/DEFAULT.tsx @@ -27,4 +27,10 @@ export default { ), + exampleKnobs: [ + { + component: "NavigationBar", + knobs: [{ name: "hideOnScroll", type: "boolean", defaultValue: true }], + }, + ], }; diff --git a/packages/orbit-components/src/NavigationBar/NavigationBar.stories.jsx b/packages/orbit-components/src/NavigationBar/NavigationBar.stories.jsx index e25e80672b..6ae5f42ca8 100644 --- a/packages/orbit-components/src/NavigationBar/NavigationBar.stories.jsx +++ b/packages/orbit-components/src/NavigationBar/NavigationBar.stories.jsx @@ -1,8 +1,9 @@ // @flow import * as React from "react"; import { action } from "@storybook/addon-actions"; -import { text } from "@storybook/addon-knobs"; +import { text, boolean } from "@storybook/addon-knobs"; +import RenderInRtl from "../utils/rtl/RenderInRtl"; import ButtonLink from "../ButtonLink"; import Stack from "../Stack"; import LinkList from "../LinkList"; @@ -20,11 +21,14 @@ export default { export const NavBarUpToTablet = (): React.Element<"div"> => { const dataTest = text("dataTest", "test"); + const hideOnScroll = boolean("hideOnScroll", true); + return (
@@ -53,12 +57,15 @@ NavBarUpToTablet.story = { export const NavBarDesktop = (): React.Element<"div"> => { const dataTest = text("dataTest", "test"); + const hideOnScroll = boolean("hideOnScroll", true); + return (
@@ -79,6 +86,37 @@ export const NavBarDesktop = (): React.Element<"div"> => { ); }; +export const RTL = (): React.Node => { + const hideOnScroll = boolean("hideOnScroll", true); + + return ( + +
+ + + + Flights + Flights + Flights + Flights + + + Starred + Help + Account + + + +
+
+ ); +}; + NavBarDesktop.story = { name: "NavBar desktop", diff --git a/packages/orbit-components/src/NavigationBar/README.md b/packages/orbit-components/src/NavigationBar/README.md index f73538db16..2581593360 100644 --- a/packages/orbit-components/src/NavigationBar/README.md +++ b/packages/orbit-components/src/NavigationBar/README.md @@ -31,3 +31,4 @@ Table below contains all types of the props available in the NavigationBar compo | onMenuOpen | `() => void \| Promise` | | Function for handling onClick event on HamburgerMenu icon. If `null`, the HamburgerMenu won't appear. | | onHide | `() => void \| Promise` | | Function for handling event when the NavigationBar disappears. | | onShow | `() => void \| Promise` | | Function for handling event when the NavigationBar appears. | +| hideOnScroll | `boolean` | `true` | Turn on or off hiding navigation bar on scroll | diff --git a/packages/orbit-components/src/NavigationBar/index.d.ts b/packages/orbit-components/src/NavigationBar/index.d.ts index ad297138c7..0ff504fc80 100644 --- a/packages/orbit-components/src/NavigationBar/index.d.ts +++ b/packages/orbit-components/src/NavigationBar/index.d.ts @@ -9,6 +9,7 @@ export interface Props extends Common.Global { readonly onShow?: Common.Callback; readonly onHide?: Common.Callback; readonly children: React.ReactNode; + readonly hideOnScroll?: boolean; } declare const NavigationBar: React.FunctionComponent; diff --git a/packages/orbit-components/src/NavigationBar/index.jsx b/packages/orbit-components/src/NavigationBar/index.jsx index 8014517ca0..28c6f26856 100644 --- a/packages/orbit-components/src/NavigationBar/index.jsx +++ b/packages/orbit-components/src/NavigationBar/index.jsx @@ -2,6 +2,7 @@ import * as React from "react"; import styled, { css } from "styled-components"; +import { right } from "../utils/rtl"; import transition from "../utils/transition"; import defaultTheme from "../defaultTheme"; import MenuHamburger from "../icons/MenuHamburger"; @@ -15,9 +16,11 @@ import type { Props } from "."; const NAVBAR_HEIGHT = { MOBILE: 52, DESKTOP: 64 }; const StyledNavigationBarContent = styled.div` - display: block; - width: 100%; - margin-right: ${({ theme }) => theme.orbit.spaceXSmall}; + ${({ theme }) => css` + display: block; + width: 100%; + margin-${right}: ${theme.orbit.spaceXSmall}; + `} `; // $FlowFixMe: https://github.com/flow-typed/flow-typed/issues/3653#issuecomment-568539198 @@ -26,25 +29,27 @@ StyledNavigationBarContent.defaultProps = { }; const StyledNavigationBar = styled.nav` - position: fixed; - top: 0; - left: 0; - right: 0; - height: ${NAVBAR_HEIGHT.MOBILE}px; // TODO: create token - width: 100%; - display: flex; - align-items: center; - background: ${({ theme }) => theme.orbit.paletteWhite}; - box-shadow: ${({ theme }) => theme.orbit.boxShadowFixed}; - padding: ${({ theme }) => theme.orbit.spaceSmall}; - box-sizing: border-box; - z-index: 700; - transition: ${transition(["transform"], "normal", "ease-in-out")}; - transform: translate3d(0, ${({ shown }) => (shown ? "0" : `-${NAVBAR_HEIGHT.MOBILE}px`)}, 0); - ${mq.tablet(css` - height: ${NAVBAR_HEIGHT.DESKTOP}px; // TODO: create token - transform: translate3d(0, ${({ shown }) => (shown ? "0" : `-${NAVBAR_HEIGHT.DESKTOP}px`)}, 0); - `)}; + ${({ theme, shown }) => css` + position: fixed; + top: 0; + left: 0; + right: 0; + height: ${NAVBAR_HEIGHT.MOBILE}px; // TODO: create token + width: 100%; + display: flex; + align-items: center; + background: ${theme.orbit.paletteWhite}; + box-shadow: ${theme.orbit.boxShadowFixed}; + padding: ${theme.orbit.spaceSmall}; + box-sizing: border-box; + z-index: 700; + transition: ${transition(["transform"], "normal", "ease-in-out")}; + transform: translate3d(0, ${shown ? "0" : `-${NAVBAR_HEIGHT.MOBILE}px`}, 0); + ${mq.tablet(css` + height: ${NAVBAR_HEIGHT.DESKTOP}px; // TODO: create token + transform: translate3d(0, ${shown ? "0" : `-${NAVBAR_HEIGHT.DESKTOP}px`}, 0); + `)}; + `} `; // $FlowFixMe: https://github.com/flow-typed/flow-typed/issues/3653#issuecomment-568539198 @@ -52,7 +57,14 @@ StyledNavigationBar.defaultProps = { theme: defaultTheme, }; -const NavigationBar = ({ onMenuOpen, children, dataTest, onShow, onHide }: Props): React.Node => { +const NavigationBar = ({ + onMenuOpen, + children, + dataTest, + onShow, + onHide, + hideOnScroll = true, +}: Props): React.Node => { const translate = useTranslate(); const resolveCallback = React.useCallback( state => { @@ -71,6 +83,8 @@ const NavigationBar = ({ onMenuOpen, children, dataTest, onShow, onHide }: Props window.pageYOffset || (document.documentElement && document.documentElement.scrollTop); + if (!hideOnScroll) return; + if ( prevScrollPosition < currentScrollPosition && currentScrollPosition > NAVBAR_HEIGHT.DESKTOP @@ -81,7 +95,7 @@ const NavigationBar = ({ onMenuOpen, children, dataTest, onShow, onHide }: Props } setPrevScrollPosition(currentScrollPosition); - }, [prevScrollPosition, setShown]); + }, [prevScrollPosition, setShown, hideOnScroll]); React.useEffect(() => { window.addEventListener("scroll", handleNavigationBarPosition); diff --git a/packages/orbit-components/src/NavigationBar/index.jsx.flow b/packages/orbit-components/src/NavigationBar/index.jsx.flow index 75dd333e55..dd4dc6fc04 100644 --- a/packages/orbit-components/src/NavigationBar/index.jsx.flow +++ b/packages/orbit-components/src/NavigationBar/index.jsx.flow @@ -7,6 +7,7 @@ export type Props = {| +onMenuOpen?: () => void | Promise, +onShow?: () => void | Promise, +onHide?: () => void | Promise, + +hideOnScroll?: boolean, +children: React.Node, ...Globals, |};