code.tsx 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. import React, { useCallback, useMemo, useState } from 'react';
  2. import { PropsWithChildren } from 'react';
  3. import { cssClasses } from '@douyinfe/semi-foundation/chat/constants';
  4. import copy from 'copy-text-to-clipboard';
  5. import { IconCopyStroked, IconTick } from '@douyinfe/semi-icons';
  6. import { nth } from 'lodash';
  7. import { code } from '../../markdownRender/components';
  8. import LocaleConsumer from "../../locale/localeConsumer";
  9. import { Locale } from "../../locale/interface";
  10. const { PREFIX_CHAT_BOX } = cssClasses;
  11. const Code = (props: PropsWithChildren<{ className: string }>) => {
  12. const [copied, setCopied] = useState(false);
  13. const language = useMemo(() => {
  14. return nth(props.className?.split("-"), -1);
  15. }, [props.className]);
  16. const onCopyButtonClick = useCallback(() => {
  17. copy(props.children as string);
  18. setCopied(true);
  19. setTimeout(() => {
  20. setCopied(false);
  21. }, 2000);
  22. }, [props.children]);
  23. return language ? (<div className={`${PREFIX_CHAT_BOX}-content-code semi-always-dark`}>
  24. <div className={`${PREFIX_CHAT_BOX}-content-code-topSlot`}>
  25. <span className={`${PREFIX_CHAT_BOX}-content-code-topSlot-type`}>{language}</span>
  26. <span className={`${PREFIX_CHAT_BOX}-content-code-topSlot-copy`}>
  27. {copied ? (<span className={`${PREFIX_CHAT_BOX}-content-code-topSlot-copy-wrapper`}>
  28. <IconTick />
  29. <LocaleConsumer<Locale["Chat"]> componentName="Chat" >
  30. {(locale: Locale["Chat"]) => locale['copied']}
  31. </LocaleConsumer>
  32. </span>) : (<button
  33. className={`${PREFIX_CHAT_BOX}-content-code-topSlot-copy-wrapper ${PREFIX_CHAT_BOX}-content-code-topSlot-toCopy`}
  34. onClick={onCopyButtonClick}
  35. >
  36. <IconCopyStroked />
  37. <LocaleConsumer<Locale["Chat"]> componentName="Chat" >
  38. {(locale: Locale["Chat"]) => locale['copy']}
  39. </LocaleConsumer>
  40. </button>)}
  41. </span>
  42. </div>
  43. {code(props)}
  44. </div>) : (code(props));
  45. };
  46. export default Code;