'use client'; import { DocumentDuplicateIcon, CodeBracketIcon, } from '@heroicons/react/24/outline'; import { useTranslations } from 'next-intl'; import type { FC, PropsWithChildren, ReactNode } from 'react'; import { Fragment, isValidElement, useRef } from 'react'; import Button from '@/components/Common/Button'; import { useCopyToClipboard, useNotification } from '@/hooks'; import styles from './index.module.css'; // Transforms a code element with plain text content into a more structured // format for rendering with line numbers const transformCode = (code: ReactNode, language: string): ReactNode => { if (!isValidElement(code)) { // Early return when the `CodeBox` child is not a valid element since the // type is a ReactNode, and can assume any value return code; } const content = code.props?.children; if (code.type !== 'code' || typeof content !== 'string') { // There is no need to transform an element that is not a code element or // a content that is not a string return code; } // Note that since we use `.split` we will have an extra entry // being an empty string, so we need to remove it const lines = content.split('\n'); const extraStyle = language.length === 0 ? { fontFamily: 'monospace' } : {}; return ( {lines .flatMap((line, lineIndex) => { const columns = line.split(' '); return [ {columns.map((column, columnIndex) => ( {column} {columnIndex < columns.length - 1 && } ))} , // Add a break line so the text content is formatted correctly // when copying to clipboard '\n', ]; }) // Here we remove that empty line from before and // the last flatMap entry which is an `\n` .slice(0, -2)} ); }; type CodeBoxProps = { language: string; showCopyButton?: boolean }; const CodeBox: FC> = ({ children, language, showCopyButton = true, }) => { const ref = useRef(null); const notify = useNotification(); const [, copyToClipboard] = useCopyToClipboard(); const t = useTranslations(); const onCopy = async () => { if (ref.current?.textContent) { copyToClipboard(ref.current.textContent); notify({ duration: 3000, message: (
{t('components.common.codebox.copied')}
), }); } }; return (
        {transformCode(children, language)}
      
{language && (
{language} {showCopyButton && ( )}
)}
); }; export default CodeBox;