PageHeader.tsx 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. import { type JSX, useCallback, useEffect, useRef, useState } from 'react';
  2. import { useCurrentPageData } from '~/states/page';
  3. import { useDeviceLargerThanSm } from '~/states/ui/device';
  4. import { usePageControlsX } from '~/states/ui/page';
  5. import { PagePathHeader } from './PagePathHeader';
  6. import { PageTitleHeader } from './PageTitleHeader';
  7. import styles from './PageHeader.module.scss';
  8. const moduleClass = styles['page-header'] ?? '';
  9. export const PageHeader = (): JSX.Element => {
  10. const currentPage = useCurrentPageData();
  11. const pageControlsX = usePageControlsX();
  12. const [isLargerThanSm] = useDeviceLargerThanSm();
  13. const pageHeaderRef = useRef<HTMLDivElement>(null);
  14. const [maxWidth, setMaxWidth] = useState<number>(300);
  15. const calcMaxWidth = useCallback(() => {
  16. if (pageHeaderRef.current == null) {
  17. return;
  18. }
  19. const pageHeaderX = pageHeaderRef.current.getBoundingClientRect().x;
  20. setMaxWidth(
  21. !isLargerThanSm
  22. ? window.innerWidth - pageHeaderX
  23. : pageControlsX != null
  24. ? pageControlsX - pageHeaderX
  25. : // Length that allows users to use PageHeader functionality.
  26. 300,
  27. );
  28. }, [isLargerThanSm, pageControlsX]);
  29. useEffect(() => {
  30. calcMaxWidth();
  31. }, [calcMaxWidth]);
  32. if (currentPage == null) {
  33. return <></>;
  34. }
  35. return (
  36. <div className={`${moduleClass} w-100`} ref={pageHeaderRef}>
  37. <PagePathHeader
  38. currentPage={currentPage}
  39. maxWidth={maxWidth}
  40. onRenameTerminated={calcMaxWidth}
  41. />
  42. <div className="mt-0 mt-md-1">
  43. <PageTitleHeader
  44. currentPage={currentPage}
  45. maxWidth={maxWidth}
  46. onMoveTerminated={calcMaxWidth}
  47. />
  48. </div>
  49. </div>
  50. );
  51. };