Presentation.tsx 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. import React, { useEffect } from 'react';
  2. import Reveal from 'reveal.js';
  3. import type { PresentationOptions } from '../consts';
  4. import { parseSlideFrontmatterInMarkdown } from '../services/parse-slide-frontmatter';
  5. import { Slides } from './Slides';
  6. import 'reveal.js/dist/reveal.css';
  7. import './Presentation.global.scss';
  8. import styles from './Presentation.module.scss';
  9. const baseRevealOptions: Reveal.Options = {
  10. // adjust size to the marp preset size
  11. width: 1280,
  12. height: 720,
  13. maxScale: 1.2,
  14. slideNumber: 'c/t',
  15. display: '',
  16. };
  17. /**
  18. * Remove all [hidden] in order to activate transitions
  19. * cz: All of .past and .future elements are hidden by `display: none !important`
  20. * @see https://getbootstrap.com/docs/4.6/content/reboot/#html5-hidden-attribute
  21. */
  22. const removeAllHiddenElements = () => {
  23. const sections = document.querySelectorAll('.grw-presentation section');
  24. sections.forEach(section => section.removeAttribute('hidden'));
  25. };
  26. export type PresentationProps = {
  27. options: PresentationOptions,
  28. isEnabledMarp: boolean,
  29. children?: string,
  30. }
  31. export const Presentation = (props: PresentationProps): JSX.Element => {
  32. const { options, isEnabledMarp, children } = props;
  33. const { revealOptions } = options;
  34. const [marp] = parseSlideFrontmatterInMarkdown(children);
  35. const hasMarpFlag = isEnabledMarp && marp;
  36. useEffect(() => {
  37. let deck: Reveal.Api;
  38. if (children != null) {
  39. deck = new Reveal({ ...baseRevealOptions, ...revealOptions });
  40. deck.initialize()
  41. .then(() => deck.slide(0)); // navigate to the first slide
  42. deck.on('ready', removeAllHiddenElements);
  43. deck.on('slidechanged', removeAllHiddenElements);
  44. }
  45. return function cleanup() {
  46. deck?.off('ready', removeAllHiddenElements);
  47. deck?.off('slidechanged', removeAllHiddenElements);
  48. };
  49. }, [children, revealOptions]);
  50. return (
  51. <div className={`grw-presentation ${styles['grw-presentation']} reveal`}>
  52. <Slides options={options} hasMarpFlag={hasMarpFlag} presentation>{children}</Slides>
  53. </div>
  54. );
  55. };