PageHeader.tsx 1.6 KB

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