Skip to content

Commit

Permalink
#237 Expand StackedLayout tokens to include autohide classes (#238)
Browse files Browse the repository at this point in the history
  • Loading branch information
jtomic-croz authored Apr 3, 2024
1 parent 429ff34 commit 4b89ae8
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 24 deletions.
45 changes: 22 additions & 23 deletions libs/menu/src/StackedLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import * as React from "react";

import { Container } from "@tiller-ds/core";
import { ComponentTokens, cx, TokenProps, useTokens } from "@tiller-ds/theme";
import { createNamedContext } from "@tiller-ds/util";
import { createNamedContext, useWindowEvent } from "@tiller-ds/util";

type StackedLayoutProps = {
/**
Expand Down Expand Up @@ -48,6 +48,12 @@ type StackedLayoutProps = {
*/
navigation: React.ReactNode;

/**
* Defines whether the StackedLayout header statys fixed or hides when page is scrolled.
* Defaults to true.
*/
hideOnScroll?: boolean;

/**
* Custom additional class name for the main container component.
*/
Expand Down Expand Up @@ -82,8 +88,6 @@ type StackedLayoutContext = {
containerVariant?: "max" | "fullWidth" | "constrainedPadded" | "fullWidthContainer" | "narrowConstrained" | undefined;
isScrolling?: boolean;
isFixed?: boolean;
headingHeight: number;
setHeadingHeight: React.Dispatch<number>;
};

const StackedLayoutContext = createNamedContext<StackedLayoutContext>("StackedLayoutContext");
Expand All @@ -94,15 +98,16 @@ function StackedLayout({
isFixed,
children,
background = "gray",
hideOnScroll = true,
className,
...props
}: StackedLayoutProps) {
const tokens = useTokens("StackedLayout", props.tokens);
const [isScrolling, setIsScrolling] = React.useState<boolean>(false);
const [headingHeight, setHeadingHeight] = React.useState<number>(0);

const navigationContainerClassName = cx({
"transition duration-300 w-full sticky top-0 z-30": isFixed,
[tokens.navigationContainer.fixed]: isFixed,
[tokens.navigationContainer.scrolled]: isScrolling,
});

const containerClassName = cx(
Expand All @@ -112,21 +117,20 @@ function StackedLayout({
{ [tokens.grayBackgroundColor]: background !== "white" }
);

window.onscroll = function () {
if (window.pageYOffset > 80) {
setIsScrolling(true);
} else {
setIsScrolling(false);
useWindowEvent("scroll", () => {
if (hideOnScroll) {
if (window.pageYOffset > 80) {
setIsScrolling(true);
} else {
setIsScrolling(false);
}
}
};
});

return (
<StackedLayoutContext.Provider value={{ containerVariant, isScrolling, isFixed, headingHeight, setHeadingHeight }}>
<StackedLayoutContext.Provider value={{ containerVariant, isScrolling, isFixed }}>
<div className={containerClassName}>
<div
className={navigationContainerClassName}
style={{ transform: isScrolling && isFixed ? "translate(0, -64px)" : "" }}
>
<div className={navigationContainerClassName}>
{navigation}
</div>
{children}
Expand All @@ -143,14 +147,9 @@ function StackedLayoutHeading({
}: StackedLayoutHeadingProps) {
const tokens = useTokens("StackedLayout", props.tokens);
const layoutContext = React.useContext(StackedLayoutContext) as StackedLayoutContext;
const ref = React.useRef<HTMLDivElement>(null);

React.useEffect(() => {
layoutContext.setHeadingHeight(ref.current?.clientHeight ?? 0);
}, [ref.current]);

const headingContainerClassName = cx({
"bg-gray-100 transition duration-300 sticky top-0 w-full z-20": layoutContext?.isFixed,
[tokens.heading.fixed]: layoutContext?.isFixed,
});

const headingClassName = cx(
Expand All @@ -160,7 +159,7 @@ function StackedLayoutHeading({
);

return (
<div ref={ref} className={headingContainerClassName}>
<div className={headingContainerClassName}>
<div className={headingClassName}>
<Container variant={layoutContext.containerVariant}>{children}</Container>
</div>
Expand Down
7 changes: 7 additions & 0 deletions libs/theme/src/defaultTheme.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1619,6 +1619,13 @@ const defaultComponentConfig = {
compactPadding: "py-4",
padding: "py-6",
contentContainer: "px-4 py-8 sm:px-0 z-0",
navigationContainer: {
fixed: "transition duration-300 w-full sticky top-0 z-30",
scrolled: "-translate-y-full"
},
heading: {
fixed: "bg-gray-100 transition duration-300 sticky top-0 w-full z-20",
}
},
StatusButton: {
icon: {
Expand Down
1 change: 1 addition & 0 deletions libs/util/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export { default as useInterval } from "./useInterval";
export { default as useTimeout } from "./useTimeout";
export { default as useViewport } from "./useViewport";
export { default as usePrevious } from "./usePrevious";
export { default as useWindowEvent } from "./useWindowEvent";

export { default as createNamedContext } from "./createNamedContext";
export {
Expand Down
11 changes: 11 additions & 0 deletions libs/util/src/useWindowEvent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { useEffect } from "react";

export default function useWindowEvent<K extends keyof WindowEventMap>(
type: K,
listener: (this: Window, ev: WindowEventMap[K]) => void
) {
useEffect(() => {
window.addEventListener(type, listener);
return () => window.removeEventListener(type, listener);
}, [type, listener]);
}
8 changes: 7 additions & 1 deletion storybook/src/base-documentation/ReleaseNotes.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,13 @@ import { Meta } from "@storybook/addon-docs";

# 📝 Release Notes

## **1.11.0 - latest** <span>_(Mar 26th 2024)_</span>
## **1.12.0 - latest** <span>_(Apr 3rd 2024)_</span>

**<h4>⚡ Component Improvements</h4>**

- Improved `StackedLayout` autohide header functionality, so it can be controlled via tokens ([#237](https://github.com/croz-ltd/tiller/issues/237))

## **1.11.0 ** <span>_(Mar 26th 2024)_</span>

**<h4>🐛 Bug Fixes</h4>**

Expand Down

0 comments on commit 4b89ae8

Please sign in to comment.