diff options
Diffstat (limited to 'src/components/MDX')
| -rw-r--r-- | src/components/MDX/CodeBlock/CodeBlock.tsx | 81 | 
1 files changed, 60 insertions, 21 deletions
| diff --git a/src/components/MDX/CodeBlock/CodeBlock.tsx b/src/components/MDX/CodeBlock/CodeBlock.tsx index 69f0124..c330063 100644 --- a/src/components/MDX/CodeBlock/CodeBlock.tsx +++ b/src/components/MDX/CodeBlock/CodeBlock.tsx @@ -1,28 +1,25 @@ +import { +  PrismDefaultPlugins, +  PrismLanguages, +  PrismPlugins, +} from '@ts/types/prism'; +import { usePrismTheme } from '@utils/providers/prism-theme';  import { useRouter } from 'next/router';  import Prism from 'prismjs'; -import { ReactChildren, useEffect } from 'react'; +import { useCallback, useEffect, useMemo } from 'react';  import { useIntl } from 'react-intl'; -import '@utils/plugins/prism-color-scheme'; -import { usePrismTheme } from '@utils/providers/prism';  const CodeBlock = ({ -  className, -  children, +  code, +  language, +  plugins,  }: { -  className: string; -  children: ReactChildren; +  code: string; +  language: PrismLanguages; +  plugins: PrismPlugins[];  }) => { -  const classNames = className.split('+'); -  const languageClass = classNames.find((name: string) => -    name.startsWith('language-') -  );    const intl = useIntl();    const router = useRouter(); - -  useEffect(() => { -    Prism.highlightAll(); -  }, []); -    const { setCodeBlocks } = usePrismTheme();    useEffect(() => { @@ -32,6 +29,46 @@ const CodeBlock = ({      setCodeBlocks(allPre);    }, [setCodeBlocks, router.asPath]); +  const defaultPlugins: PrismDefaultPlugins[] = useMemo( +    () => [ +      'autoloader', +      'toolbar', +      'show-language', +      'copy-to-clipboard', +      'color-scheme', +      'match-braces', +      'normalize-whitespace', +    ], +    [] +  ); + +  const loadPrismPlugins = useCallback( +    async (prismPlugins: (PrismDefaultPlugins | PrismPlugins)[]) => { +      for (const plugin of prismPlugins) { +        try { +          if (plugin === 'color-scheme') { +            await import(`@utils/plugins/prism-${plugin}`); +          } else { +            await import(`prismjs/plugins/${plugin}/prism-${plugin}.min.js`); + +            if (plugin === 'autoloader') +              Prism.plugins.autoloader.languages_path = '/prism/'; +          } +        } catch (error) { +          console.error('CodeBlock: an error occurred with Prism.'); +          console.error(error); +        } +      } +    }, +    [] +  ); + +  useEffect(() => { +    loadPrismPlugins([...defaultPlugins, ...plugins]).then(() => { +      Prism.highlightAll(); +    }); +  }, [loadPrismPlugins, defaultPlugins, plugins]); +    const copyText = intl.formatMessage({      defaultMessage: 'Copy',      description: 'Prism: copy button text (no clicked)', @@ -58,18 +95,20 @@ const CodeBlock = ({      id: 'Ua2g2p',    }); +  const defaultPluginsClasses = 'match-braces'; +  const pluginsClasses = plugins.join(' '); +    return ( -    <div +    <pre +      className={`language-${language} ${defaultPluginsClasses} ${pluginsClasses}`}        data-prismjs-copy={copyText}        data-prismjs-copy-success={copiedText}        data-prismjs-copy-error={errorText}        data-prismjs-color-scheme-dark={darkTheme}        data-prismjs-color-scheme-light={lightTheme}      > -      <pre className={classNames.join(' ')}> -        <code className={languageClass}>{children}</code> -      </pre> -    </div> +      <code className={`language-${language}`}>{code}</code> +    </pre>    );  }; | 
