2
0

TableOfContents.tsx 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import React, { useCallback } from 'react';
  2. import { pagePathUtils } from '@growi/core/dist/utils';
  3. import ReactMarkdown from 'react-markdown';
  4. import { useCurrentPagePath } from '~/stores/page';
  5. import { useTocOptions } from '~/stores/renderer';
  6. import loggerFactory from '~/utils/logger';
  7. import { StickyStretchableScroller } from './StickyStretchableScroller';
  8. import styles from './TableOfContents.module.scss';
  9. const { isUsersHomepage: _isUsersHomepage } = pagePathUtils;
  10. // eslint-disable-next-line @typescript-eslint/no-unused-vars
  11. const logger = loggerFactory('growi:TableOfContents');
  12. type Props = {
  13. tagsElementHeight?: number
  14. }
  15. const TableOfContents = ({ tagsElementHeight }: Props): JSX.Element => {
  16. const { data: currentPagePath } = useCurrentPagePath();
  17. const isUsersHomePage = currentPagePath != null && _isUsersHomepage(currentPagePath);
  18. const { data: rendererOptions } = useTocOptions();
  19. const calcViewHeight = useCallback(() => {
  20. // calculate absolute top of '#revision-toc' element
  21. const parentElem = document.querySelector('.grw-side-contents-container');
  22. const containerElem = document.querySelector('#revision-toc');
  23. // rendererOptions for redo calcViewHeight()
  24. // see: https://github.com/weseek/growi/pull/6791
  25. if (parentElem == null || containerElem == null || rendererOptions == null || tagsElementHeight == null) {
  26. return 0;
  27. }
  28. const parentBottom = parentElem.getBoundingClientRect().bottom;
  29. const containerTop = containerElem.getBoundingClientRect().top;
  30. const containerComputedStyle = getComputedStyle(containerElem);
  31. const containerPaddingTop = parseFloat(containerComputedStyle['padding-top']);
  32. // get smaller bottom line of window height - .system-version height - margin 5px) and containerTop
  33. let bottom = Math.min(window.innerHeight - 20 - 5, parentBottom);
  34. if (isUsersHomePage) {
  35. // raise the bottom line by the height and margin-top of UserContentLinks
  36. bottom -= 90;
  37. }
  38. // bottom - revisionToc top
  39. return bottom - (containerTop + containerPaddingTop);
  40. }, [isUsersHomePage, rendererOptions, tagsElementHeight]);
  41. return (
  42. <div id="revision-toc" className={`revision-toc ${styles['revision-toc']}`}>
  43. <StickyStretchableScroller
  44. stickyElemSelector=".grw-side-contents-sticky-container"
  45. calcViewHeight={calcViewHeight}
  46. >
  47. <div
  48. id="revision-toc-content"
  49. data-testid="revision-toc-content"
  50. className="revision-toc-content mb-3"
  51. >
  52. {/* parse blank to show toc (https://github.com/weseek/growi/pull/6277) */}
  53. <ReactMarkdown {...rendererOptions}>{' '}</ReactMarkdown>
  54. </div>
  55. </StickyStretchableScroller>
  56. </div>
  57. );
  58. };
  59. export default TableOfContents;