import { IconClipboard, IconDownload } from '@tabler/icons' import { memo, useState } from 'react' import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter' import { oneDark } from 'react-syntax-highlighter/dist/esm/styles/prism' import PropTypes from 'prop-types' import { Box, IconButton, Popover, Typography } from '@mui/material' import { useTheme } from '@mui/material/styles' const programmingLanguages = { javascript: '.js', python: '.py', java: '.java', c: '.c', cpp: '.cpp', 'c++': '.cpp', 'c#': '.cs', ruby: '.rb', php: '.php', swift: '.swift', 'objective-c': '.m', kotlin: '.kt', typescript: '.ts', go: '.go', perl: '.pl', rust: '.rs', scala: '.scala', haskell: '.hs', lua: '.lua', shell: '.sh', sql: '.sql', html: '.html', css: '.css' } export const CodeBlock = memo(({ language, chatflowid, isDialog, value }) => { const theme = useTheme() const [anchorEl, setAnchorEl] = useState(null) const openPopOver = Boolean(anchorEl) const handleClosePopOver = () => { setAnchorEl(null) } const copyToClipboard = (event) => { if (!navigator.clipboard || !navigator.clipboard.writeText) { return } navigator.clipboard.writeText(value) setAnchorEl(event.currentTarget) setTimeout(() => { handleClosePopOver() }, 1500) } const downloadAsFile = () => { const fileExtension = programmingLanguages[language] || '.file' const suggestedFileName = `file-${chatflowid}${fileExtension}` const fileName = suggestedFileName if (!fileName) { // user pressed cancel on prompt return } const blob = new Blob([value], { type: 'text/plain' }) const url = URL.createObjectURL(blob) const link = document.createElement('a') link.download = fileName link.href = url link.style.display = 'none' document.body.appendChild(link) link.click() document.body.removeChild(link) URL.revokeObjectURL(url) } return (
{language}
Copied!
{value}
) }) CodeBlock.displayName = 'CodeBlock' CodeBlock.propTypes = { language: PropTypes.string, chatflowid: PropTypes.string, isDialog: PropTypes.bool, value: PropTypes.string }