Browse Source

support dark mode

Yuki Takei 3 years ago
parent
commit
67cdcc931d

+ 10 - 4
packages/app/src/components/PagePresentationModal.tsx

@@ -10,6 +10,7 @@ import {
 import { usePagePresentationModal } from '~/stores/modal';
 import { useSWRxCurrentPage } from '~/stores/page';
 import { usePresentationViewOptions } from '~/stores/renderer';
+import { useNextThemes } from '~/stores/use-next-themes';
 
 
 import styles from './PagePresentationModal.module.scss';
@@ -27,6 +28,8 @@ const PagePresentationModal = (): JSX.Element => {
 
   const { data: presentationModalData, close: closePresentationModal } = usePagePresentationModal();
 
+  const { isDarkMode } = useNextThemes();
+
   const { data: currentPage } = useSWRxCurrentPage();
   const { data: rendererOptions } = usePresentationViewOptions();
 
@@ -51,10 +54,13 @@ const PagePresentationModal = (): JSX.Element => {
       <ModalBody className="modal-body d-flex justify-content-center align-items-center">
         { rendererOptions != null && (
           <Presentation
-            rendererOptions={rendererOptions as ReactMarkdownOptions}
-            revealOptions={{
-              embedded: true,
-              hash: true,
+            options={{
+              rendererOptions: rendererOptions as ReactMarkdownOptions,
+              revealOptions: {
+                embedded: true,
+                hash: true,
+              },
+              isDarkMode,
             }}
           >
             {markdown}

+ 6 - 5
packages/presentation/src/components/Presentation.tsx

@@ -1,8 +1,9 @@
 import React, { useEffect } from 'react';
 
-import type { ReactMarkdownOptions } from 'react-markdown/lib/react-markdown';
 import Reveal from 'reveal.js';
 
+import type { PresentationOptions } from '../consts';
+
 import { MARP_CONTAINER_CLASS_NAME, Sections } from './Sections';
 
 import 'reveal.js/dist/reveal.css';
@@ -16,13 +17,13 @@ const baseRevealOptions: Reveal.Options = {
 };
 
 type Props = {
-  rendererOptions: ReactMarkdownOptions,
-  revealOptions?: Reveal.Options,
+  options: PresentationOptions,
   children?: string,
 }
 
 export const Presentation = (props: Props): JSX.Element => {
-  const { rendererOptions, revealOptions, children } = props;
+  const { options, children } = props;
+  const { revealOptions } = options;
 
   useEffect(() => {
     if (children != null) {
@@ -35,7 +36,7 @@ export const Presentation = (props: Props): JSX.Element => {
   return (
     <div className={`grw-presentation ${styles['grw-presentation']} reveal ${MARP_CONTAINER_CLASS_NAME}`}>
       <div className="slides d-flex justify-content-center align-items-center">
-        <Sections rendererOptions={rendererOptions}>{children}</Sections>
+        <Sections options={options}>{children}</Sections>
       </div>
     </div>
   );

+ 1 - 1
packages/presentation/src/components/Sections.global.scss

@@ -1,5 +1,5 @@
 div.marpit > div.slides > section :is(pre, marp-pre) {
   padding: 0;
-  background-color: none;
+  // background-color: none;
   border: none;
 }

+ 5 - 4
packages/presentation/src/components/Sections.tsx

@@ -4,8 +4,8 @@ import { Marp } from '@marp-team/marp-core';
 import { Element } from '@marp-team/marpit';
 import Head from 'next/head';
 import { ReactMarkdown } from 'react-markdown/lib/react-markdown';
-import type { ReactMarkdownOptions } from 'react-markdown/lib/react-markdown';
 
+import type { PresentationOptions } from '../consts';
 import * as extractSections from '../services/renderer/extract-sections';
 
 import './Sections.global.scss';
@@ -26,14 +26,15 @@ const marp = new Marp({
 
 
 type SectionsProps = {
-  rendererOptions: ReactMarkdownOptions,
+  options: PresentationOptions,
   children?: string,
 }
 
 export const Sections = (props: SectionsProps): JSX.Element => {
-  const { rendererOptions, children } = props;
+  const { options, children } = props;
+  const { rendererOptions, isDarkMode } = options;
 
-  rendererOptions.remarkPlugins?.push(extractSections.remarkPlugin);
+  rendererOptions.remarkPlugins?.push([extractSections.remarkPlugin, { isDarkMode }]);
 
   const { css } = marp.render('', { htmlAsArray: true });
 

+ 8 - 0
packages/presentation/src/consts/index.ts

@@ -0,0 +1,8 @@
+import type { ReactMarkdownOptions } from 'react-markdown/lib/react-markdown';
+import type { Options as RevealOptions } from 'reveal.js';
+
+export type PresentationOptions = {
+  rendererOptions: ReactMarkdownOptions,
+  revealOptions?: RevealOptions,
+  isDarkMode?: boolean,
+}

+ 11 - 3
packages/presentation/src/services/renderer/extract-sections.ts

@@ -5,7 +5,7 @@ import { findAfter } from 'unist-util-find-after';
 import { visit } from 'unist-util-visit';
 
 
-function wrapWithSection(parentNode: Parent, startElem: Node, endElem: Node | null): void {
+function wrapWithSection(parentNode: Parent, startElem: Node, endElem: Node | null, isDarkMode?: boolean): void {
   const siblings = parentNode.children;
 
   const startIndex = siblings.indexOf(startElem);
@@ -21,6 +21,9 @@ function wrapWithSection(parentNode: Parent, startElem: Node, endElem: Node | nu
     children: between,
     data: {
       hName: 'section',
+      hProperties: {
+        className: isDarkMode ? 'invert' : '',
+      },
     },
   };
 
@@ -32,7 +35,12 @@ function removeElement(parentNode: Parent, elem: Node): void {
   siblings.splice(siblings.indexOf(elem), 1);
 }
 
-export const remarkPlugin: Plugin = function() {
+export type ExtractSectionsPluginParams = {
+  isDarkMode?: boolean,
+}
+
+export const remarkPlugin: Plugin<[ExtractSectionsPluginParams]> = (options) => {
+  const { isDarkMode } = options;
 
   return (tree) => {
     // wrap with <section>
@@ -47,7 +55,7 @@ export const remarkPlugin: Plugin = function() {
         const startElem = node;
         const endElem = findAfter(parent, startElem, node => node.type === 'thematicBreak');
 
-        wrapWithSection(parent, startElem, endElem);
+        wrapWithSection(parent, startElem, endElem, isDarkMode);
 
         // remove <hr>
         if (endElem != null) {