Skip to content
Closed
24 changes: 14 additions & 10 deletions apps/app/src/client/components/PageHeader/PageHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { type JSX, useCallback, useEffect, useRef, useState } from 'react';

import { useCurrentPageData } from '~/states/page';
import { useDeviceLargerThanSm } from '~/states/ui/device';
import { usePageControlsX } from '~/states/ui/page';

import { PagePathHeader } from './PagePathHeader';
Expand All @@ -13,23 +14,26 @@ const moduleClass = styles['page-header'] ?? '';
export const PageHeader = (): JSX.Element => {
const currentPage = useCurrentPageData();
const pageControlsX = usePageControlsX();
const [isLargerThanSm] = useDeviceLargerThanSm();
const pageHeaderRef = useRef<HTMLDivElement>(null);

const [maxWidth, setMaxWidth] = useState<number>();
const [maxWidth, setMaxWidth] = useState<number>(300);

const calcMaxWidth = useCallback(() => {
if (pageControlsX == null || pageHeaderRef.current == null) {
// Length that allows users to use PageHeader functionality.
setMaxWidth(300);
if (pageHeaderRef.current == null) {
return;
}

// PageControls.x - PageHeader.x
const maxWidth =
pageControlsX - pageHeaderRef.current.getBoundingClientRect().x;

setMaxWidth(maxWidth);
}, [pageControlsX]);
const pageHeaderX = pageHeaderRef.current.getBoundingClientRect().x;
setMaxWidth(
!isLargerThanSm
? window.innerWidth - pageHeaderX
: pageControlsX != null
? pageControlsX - pageHeaderX
: // Length that allows users to use PageHeader functionality.
300,
);
}, [isLargerThanSm, pageControlsX]);

useEffect(() => {
calcMaxWidth();
Expand Down
23 changes: 23 additions & 0 deletions apps/app/src/states/ui/device.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { atom, useAtom } from 'jotai';
export const isDeviceLargerThanXlAtom = atom(false);
export const isDeviceLargerThanLgAtom = atom(false);
export const isDeviceLargerThanMdAtom = atom(false);
export const isDeviceLargerThanSmAtom = atom(false);
export const isMobileAtom = atom(false);

export const useDeviceLargerThanXl = () => {
Expand Down Expand Up @@ -78,6 +79,28 @@ export const useDeviceLargerThanMd = () => {
return [isLargerThanMd, setIsLargerThanMd] as const;
};

export const useDeviceLargerThanSm = () => {
const [isLargerThanSm, setIsLargerThanSm] = useAtom(isDeviceLargerThanSmAtom);

useEffect(() => {
const smOrAboveHandler = function (this: MediaQueryList): void {
// xs -> sm: matches will be true
// sm -> xs: matches will be false
setIsLargerThanSm(this.matches);
};
const mql = addBreakpointListener(Breakpoint.SM, smOrAboveHandler);

// initialize
setIsLargerThanSm(mql.matches);

return () => {
cleanupBreakpointListener(mql, smOrAboveHandler);
};
}, [setIsLargerThanSm]);

return [isLargerThanSm, setIsLargerThanSm] as const;
};

export const useIsMobile = () => {
const [isMobile, setIsMobile] = useAtom(isMobileAtom);

Expand Down
Loading