TableOfContents.jsx 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import React, { useCallback } from 'react';
  2. import PropTypes from 'prop-types';
  3. import loggerFactory from '@alias/logger';
  4. import { withTranslation } from 'react-i18next';
  5. import PageContainer from '../services/PageContainer';
  6. import { withUnstatedContainers } from './UnstatedUtils';
  7. import TopOfTableContents from './TopOfTableContents';
  8. import StickyStretchableScroller from './StickyStretchableScroller';
  9. // eslint-disable-next-line no-unused-vars
  10. const logger = loggerFactory('growi:TableOfContents');
  11. /**
  12. * @author Yuki Takei <yuki@weseek.co.jp>
  13. *
  14. */
  15. const TableOfContents = (props) => {
  16. const { pageContainer } = props;
  17. const calcViewHeight = useCallback(() => {
  18. // calculate absolute top of '#revision-toc' element
  19. const containerElem = document.querySelector('#revision-toc');
  20. const containerTop = containerElem.getBoundingClientRect().top;
  21. // window height - revisionToc top - .system-version - .grw-fab-container height - top-of-table-contents height
  22. return window.innerHeight - containerTop - 20 - 155 - 26;
  23. }, []);
  24. const { tocHtml } = pageContainer.state;
  25. return (
  26. <>
  27. <TopOfTableContents />
  28. <StickyStretchableScroller
  29. contentsElemSelector=".revision-toc .markdownIt-TOC"
  30. stickyElemSelector="#revision-toc"
  31. calcViewHeightFunc={calcViewHeight}
  32. >
  33. <div
  34. id="revision-toc-content"
  35. className="revision-toc-content"
  36. // eslint-disable-next-line react/no-danger
  37. dangerouslySetInnerHTML={{
  38. __html: tocHtml,
  39. }}
  40. />
  41. </StickyStretchableScroller>
  42. </>
  43. );
  44. };
  45. /**
  46. * Wrapper component for using unstated
  47. */
  48. const TableOfContentsWrapper = withUnstatedContainers(TableOfContents, [PageContainer]);
  49. TableOfContents.propTypes = {
  50. pageContainer: PropTypes.instanceOf(PageContainer).isRequired,
  51. };
  52. export default withTranslation()(TableOfContentsWrapper);