Skip to content

Commit

Permalink
feat(NavigationBar): add hideOnScroll prop (#3282)
Browse files Browse the repository at this point in the history
  • Loading branch information
mainframev committed Feb 15, 2022
1 parent 72e4620 commit c253f23
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 25 deletions.
6 changes: 6 additions & 0 deletions docs/src/__examples__/NavigationBar/DEFAULT.tsx
Expand Up @@ -27,4 +27,10 @@ export default {
</Stack>
</NavigationBar>
),
exampleKnobs: [
{
component: "NavigationBar",
knobs: [{ name: "hideOnScroll", type: "boolean", defaultValue: true }],
},
],
};
@@ -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";
Expand All @@ -20,11 +21,14 @@ export default {

export const NavBarUpToTablet = (): React.Element<"div"> => {
const dataTest = text("dataTest", "test");
const hideOnScroll = boolean("hideOnScroll", true);

return (
<div style={{ height: "1000px" }}>
<NavigationBar
onMenuOpen={action("onMenuOpen")}
onShow={action("onShow")}
hideOnScroll={hideOnScroll}
onHide={action("onHide")}
dataTest={dataTest}
>
Expand Down Expand Up @@ -53,12 +57,15 @@ NavBarUpToTablet.story = {

export const NavBarDesktop = (): React.Element<"div"> => {
const dataTest = text("dataTest", "test");
const hideOnScroll = boolean("hideOnScroll", true);

return (
<div style={{ height: "1000px" }}>
<NavigationBar
onMenuOpen={action("onMenuOpen")}
onShow={action("onShow")}
onHide={action("onHide")}
hideOnScroll={hideOnScroll}
dataTest={dataTest}
>
<Stack flex align="center" justify="between" spacing="none">
Expand All @@ -79,6 +86,37 @@ export const NavBarDesktop = (): React.Element<"div"> => {
);
};

export const RTL = (): React.Node => {
const hideOnScroll = boolean("hideOnScroll", true);

return (
<RenderInRtl>
<div style={{ height: "1000px" }}>
<NavigationBar
onMenuOpen={action("onMenuOpen")}
onShow={action("onShow")}
onHide={action("onHide")}
hideOnScroll={hideOnScroll}
>
<Stack flex align="center" justify="between" spacing="none">
<LinkList direction="row">
<TextLink type="secondary">Flights</TextLink>
<TextLink type="secondary">Flights</TextLink>
<TextLink type="secondary">Flights</TextLink>
<TextLink type="secondary">Flights</TextLink>
</LinkList>
<Stack direction="row" spacing="XXSmall" justify="end" shrink>
<ButtonLink type="secondary">Starred</ButtonLink>
<ButtonLink type="secondary">Help</ButtonLink>
<ButtonLink type="secondary">Account</ButtonLink>
</Stack>
</Stack>
</NavigationBar>
</div>
</RenderInRtl>
);
};

NavBarDesktop.story = {
name: "NavBar desktop",

Expand Down
1 change: 1 addition & 0 deletions packages/orbit-components/src/NavigationBar/README.md
Expand Up @@ -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 |
1 change: 1 addition & 0 deletions packages/orbit-components/src/NavigationBar/index.d.ts
Expand Up @@ -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<Props>;
Expand Down
62 changes: 38 additions & 24 deletions packages/orbit-components/src/NavigationBar/index.jsx
Expand Up @@ -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";
Expand All @@ -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
Expand All @@ -26,33 +29,42 @@ 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
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 => {
Expand All @@ -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
Expand All @@ -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);
Expand Down
1 change: 1 addition & 0 deletions packages/orbit-components/src/NavigationBar/index.jsx.flow
Expand Up @@ -7,6 +7,7 @@ export type Props = {|
+onMenuOpen?: () => void | Promise<any>,
+onShow?: () => void | Promise<any>,
+onHide?: () => void | Promise<any>,
+hideOnScroll?: boolean,
+children: React.Node,
...Globals,
|};
Expand Down

0 comments on commit c253f23

Please sign in to comment.