Skip to content

Commit

Permalink
feat(NavigationBar): allow for transparent background when at the top…
Browse files Browse the repository at this point in the history
… of the screen

This was requested on Slack.
  • Loading branch information
RobinCsl committed Jan 21, 2025
1 parent cc7902e commit d3943c9
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const meta: Meta<typeof NavigationBar> = {
onShow: action("onShow"),
onHide: action("onHide"),
bottomStyle: "shadow",
transparentBgAtTop: false,
},

argTypes: {
Expand Down
25 changes: 13 additions & 12 deletions packages/orbit-components/src/NavigationBar/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,19 @@ After adding import into your project you can use it simply like:

Table below contains all types of the props available in the NavigationBar component.

| Name | Type | Default | Description |
| :----------- | :---------------------- | :----------------------- | :---------------------------------------------------------------------------------------------------- |
| **children** | `React.Node` | | The content of the NavigationBar. |
| dataTest | `string` | | Optional prop for testing purposes. |
| id | `string` | | Set `id` for `NavigationBar`. |
| 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 |
| openTitle | `string` | `"Open navigation menu"` | Property for passing translation string to open Button. |
| bottomStyle | `"shadow" \| "border"` | `"shadow"` | Property for setting bottom style of NavigationBar. |
| ariaLabel | `string` | `"navigation"` | Optional prop for `aria-label` value (accessibility). |
| Name | Type | Default | Description |
| :----------------- | :---------------------- | :----------------------- | :---------------------------------------------------------------------------------------------------------- |
| **children** | `React.Node` | | The content of the NavigationBar. |
| dataTest | `string` | | Optional prop for testing purposes. |
| id | `string` | | Set `id` for `NavigationBar`. |
| 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 |
| openTitle | `string` | `"Open navigation menu"` | Property for passing translation string to open Button. |
| bottomStyle | `"shadow" \| "border"` | `"shadow"` | Property for setting bottom style of NavigationBar. |
| ariaLabel | `string` | `"navigation"` | Optional prop for `aria-label` value (accessibility). |
| transparentBgAtTop | `boolean` | `false` | Property for setting the background to be transparent when the NavigationBar is at the top of the viewport. |

## Accessibility

Expand Down
39 changes: 34 additions & 5 deletions packages/orbit-components/src/NavigationBar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const NavigationBar = ({
hideOnScroll = true,
bottomStyle = "shadow",
ariaLabel = "navigation",
transparentBgAtTop = false,
}: Props) => {
const resolveCallback = React.useCallback(
state => {
Expand All @@ -32,13 +33,18 @@ const NavigationBar = ({
const [shown, setShown] = useStateWithCallback<boolean>(true, resolveCallback);

const [prevScrollPosition, setPrevScrollPosition] = React.useState(0);
const [isTransparentBg, setTransparentBg] = React.useState(transparentBgAtTop);

const handleNavigationBarPosition = React.useCallback(() => {
const currentScrollPosition =
window.scrollY ||
window.pageYOffset ||
(document.documentElement && document.documentElement.scrollTop);

if (transparentBgAtTop) {
setTransparentBg(currentScrollPosition <= 0);
}

if (!hideOnScroll) return;

if (
Expand All @@ -51,7 +57,7 @@ const NavigationBar = ({
}

setPrevScrollPosition(currentScrollPosition);
}, [prevScrollPosition, setShown, hideOnScroll]);
}, [prevScrollPosition, setShown, hideOnScroll, transparentBgAtTop, setTransparentBg]);

React.useEffect(() => {
window.addEventListener("scroll", handleNavigationBarPosition);
Expand All @@ -60,17 +66,40 @@ const NavigationBar = ({
};
});

React.useEffect(() => {
const currentScrollPosition =
window.scrollY ||
window.pageYOffset ||
(document.documentElement && document.documentElement.scrollTop);
if (transparentBgAtTop) {
setTransparentBg(currentScrollPosition <= 0);
} else {
setTransparentBg(false);
}
}, [transparentBgAtTop]);

React.useEffect(() => {
if (!hideOnScroll) {
setShown(true);
}
}, [hideOnScroll, setShown]);

return (
<nav
data-test={dataTest}
id={id}
className={cx(
"bg-white-normal px-400 py-300 tb:p-300 z-navigation-bar fixed inset-x-0 top-0 box-border flex w-full translate-x-0 items-center",
"duration-normal transform-gpu transition-transform ease-in-out",
"px-400 py-300 tb:p-300 z-navigation-bar fixed inset-x-0 top-0 box-border flex w-full translate-x-0 items-center",
"duration-normal transform-gpu ease-in-out",
"tb:h-1600 h-1300", // As defined on the const above
shown ? "translate-y-0" : "tb:-translate-y-1600 -translate-y-1300", // As defined on the const above
bottomStyle === "shadow" && "shadow-fixed",
bottomStyle === "border" && "border-cloud-normal border-b",
transparentBgAtTop
? "transition-[transform,background-color,border-color]"
: "transition-transform",
!isTransparentBg && bottomStyle === "shadow" && "shadow-fixed",
isTransparentBg && bottomStyle === "border" && "border-transparent", // important for the transition to work well
!isTransparentBg && bottomStyle === "border" && "border-cloud-normal border-b",
isTransparentBg ? "bg-transparent" : "bg-white-normal",
)}
aria-label={ariaLabel}
>
Expand Down
1 change: 1 addition & 0 deletions packages/orbit-components/src/NavigationBar/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ export interface Props extends Common.Globals {
readonly hideOnScroll?: boolean;
readonly bottomStyle?: "shadow" | "border";
readonly ariaLabel?: string;
readonly transparentBgAtTop?: boolean;
}

0 comments on commit d3943c9

Please sign in to comment.