code-preview.tsx 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940
  1. import { ChatContext } from '@/app/chat-context';
  2. import { CopyOutlined } from '@ant-design/icons';
  3. import { Button, message } from 'antd';
  4. import copy from 'copy-to-clipboard';
  5. import { CSSProperties, useContext } from 'react';
  6. import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
  7. import { coldarkDark, oneDark } from 'react-syntax-highlighter/dist/esm/styles/prism';
  8. interface Props {
  9. code: string;
  10. language: string;
  11. customStyle?: CSSProperties;
  12. light?: { [key: string]: CSSProperties };
  13. dark?: { [key: string]: CSSProperties };
  14. }
  15. export function CodePreview({ code, light, dark, language, customStyle }: Props) {
  16. const { mode } = useContext(ChatContext);
  17. return (
  18. <div className='relative'>
  19. <Button
  20. className='absolute right-3 top-2 text-gray-300 hover:!text-gray-200 bg-gray-700'
  21. type='text'
  22. icon={<CopyOutlined />}
  23. onClick={() => {
  24. const success = copy(code);
  25. message[success ? 'success' : 'error'](success ? '复制成功' : '复制失败');
  26. }}
  27. />
  28. <SyntaxHighlighter
  29. customStyle={customStyle}
  30. language={language}
  31. style={mode === 'dark' ? (dark ?? coldarkDark) : (light ?? oneDark)}
  32. >
  33. {code}
  34. </SyntaxHighlighter>
  35. </div>
  36. );
  37. }