github.com/Jeffail/benthos/v3@v3.65.0/website/src/theme/CodeBlock/index.js (about)

     1  /**
     2   * Copyright (c) Facebook, Inc. and its affiliates.
     3   *
     4   * This source code is licensed under the MIT license found in the
     5   * LICENSE file in the root directory of this source tree.
     6   */
     7  
     8  import React, {useEffect, useState, useRef} from 'react';
     9  import clsx from 'clsx';
    10  import Highlight, {defaultProps} from 'prism-react-renderer';
    11  import copy from 'copy-text-to-clipboard';
    12  import {usePrismTheme} from '@docusaurus/theme-common';
    13  import Translate, {translate} from '@docusaurus/Translate';
    14  
    15  import styles from './styles.module.css';
    16  
    17  import {useThemeConfig} from '@docusaurus/theme-common';
    18  
    19  export default function CodeBlock({
    20    children,
    21    className: languageClassName,
    22  }) {
    23    const {prism} = useThemeConfig();
    24  
    25    const [showCopied, setShowCopied] = useState(false);
    26    const [mounted, setMounted] = useState(false);
    27    // The Prism theme on SSR is always the default theme but the site theme
    28    // can be in a different mode. React hydration doesn't update DOM styles
    29    // that come from SSR. Hence force a re-render after mounting to apply the
    30    // current relevant styles. There will be a flash seen of the original
    31    // styles seen using this current approach but that's probably ok. Fixing
    32    // the flash will require changing the theming approach and is not worth it
    33    // at this point.
    34    useEffect(() => {
    35      setMounted(true);
    36    }, []);
    37  
    38    const button = useRef(null);
    39  
    40    const prismTheme = usePrismTheme();
    41  
    42    // In case interleaved Markdown (e.g. when using CodeBlock as standalone component).
    43    const content = Array.isArray(children) ? children.join('') : children;
    44  
    45    let language = languageClassName && (languageClassName.replace(/language-/, ''));
    46    if (!language && prism.defaultLanguage) {
    47      language = prism.defaultLanguage;
    48    }
    49  
    50    // only declaration OR directive highlight can be used for a block
    51    let code = content.replace(/\n$/, '');
    52  
    53    const handleCopyCode = () => {
    54      copy(code);
    55      setShowCopied(true);
    56  
    57      setTimeout(() => setShowCopied(false), 2000);
    58    };
    59  
    60    return (
    61      <Highlight {...defaultProps} key={mounted} theme={prismTheme} code={code} language={language}>
    62        {({ className, style, tokens, getLineProps, getTokenProps }) => (
    63          <div className={styles.codeBlockContainer}>
    64            <div className={clsx(styles.codeBlockContent, language)}>
    65              <pre className={`${className}`} style={style}>
    66                {tokens.map((line, i) => (
    67                  <div {...getLineProps({ line, key: i })}>
    68                    {line.map((token, key) => (
    69                      <span {...getTokenProps({ token, key })} />
    70                    ))}
    71                  </div>
    72                ))}
    73              </pre>
    74  
    75              <button
    76                ref={button}
    77                type="button"
    78                aria-label={translate({
    79                  id: 'theme.CodeBlock.copyButtonAriaLabel',
    80                  message: 'Copy code to clipboard',
    81                  description: 'The ARIA label for copy code blocks button',
    82                })}
    83                className={clsx(styles.copyButton, 'clean-btn')}
    84                onClick={handleCopyCode}>
    85                {showCopied ? (
    86                  <Translate
    87                    id="theme.CodeBlock.copied"
    88                    description="The copied button label on code blocks">
    89                    Copied
    90                  </Translate>
    91                ) : (
    92                  <Translate
    93                    id="theme.CodeBlock.copy"
    94                    description="The copy button label on code blocks">
    95                    Copy
    96                  </Translate>
    97                )}
    98              </button>
    99            </div>
   100          </div>
   101        )}
   102      </Highlight>
   103    );
   104  }