TableOfContents.tsx 2.7 KB

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