diff options
Diffstat (limited to 'src/components/MDX/CodeBlock')
| -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> ); }; |
