Presentation.tsx 1.7 KB

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