import React from 'react'; import hljs from 'highlight.js/lib/core'; import bash from 'highlight.js/lib/languages/bash'; import js from 'highlight.js/lib/languages/javascript'; import json from 'highlight.js/lib/languages/json'; import markdown from 'highlight.js/lib/languages/markdown'; import python from 'highlight.js/lib/languages/python'; import xml from 'highlight.js/lib/languages/xml'; import { BaseProps } from '@digigov/react-core/Base'; import CodeBlockContainer from '@digigov/react-core/CodeBlockContainer'; import CodeBlockContent from '@digigov/react-core/CodeBlockContent'; import CodeBlockHeader from '@digigov/react-core/CodeBlockHeader'; import { CopyToClipboard } from '@digigov/ui/feedback'; import { PhaseBannerTag } from '@digigov/ui/feedback/PhaseBanner'; import { Button } from '@digigov/ui/form/Button'; export interface CodeBlockProps extends BaseProps<'div'> { language?: 'javascript' | 'bash' | 'xml' | 'python' | 'markdown' | 'json'; copyToClipboard?: boolean; highlighted?: boolean; showLineNumbers?: boolean; phaseBannerTagName?: string; highlightLines?: number[]; } const languageMap = { javascript: js, python: python, bash: bash, xml: xml, markdown: markdown, json: json, }; const addLineNumbers = (code: string, highlightLines: number[]): string => { return code .split('\n') .map((line, index) => { const isHighlighted = highlightLines.includes(index + 1); const lineClass = isHighlighted ? 'ds-code--highlighted-line' : ''; return `${index + 1} ${line}`; }) .join('\n'); }; export const CodeBlock = React.forwardRef( function CodeBlock( { children, language, copyToClipboard, highlighted, showLineNumbers, phaseBannerTagName, highlightLines, ...props }, ref ) { const Tag = 'span'; const codeString = typeof children === 'string' ? children : ''; let displayingCode = codeString; if (highlighted && codeString) { try { hljs.configure({ classPrefix: 'ds-code--' }); let highlightedCode = hljs.highlightAuto(codeString).value; if (language) { hljs.registerLanguage(language, languageMap[language]); highlightedCode = hljs.highlight(codeString, { language: language, }).value; } displayingCode = showLineNumbers ? addLineNumbers(highlightedCode, highlightLines || []) : highlightedCode; } catch (error) { console.error('Highlighting failed:', error); } } return ( {phaseBannerTagName && ( {phaseBannerTagName} )} {copyToClipboard && ( )} {highlighted && codeString ? ( ) : ( children )} ); } ); export * from '@digigov/react-core/CodeBlockContent'; export * from '@digigov/react-core/CodeBlockHeader'; export * from '@digigov/react-core/CodeBlockContainer'; export default CodeBlock;