From 5adef63e25aa6232580cd744ea172684ea1d1d50 Mon Sep 17 00:00:00 2001 From: jaywcjlove <398188662@qq.com> Date: Fri, 21 Oct 2022 02:08:23 +0800 Subject: [PATCH] fix: Fix code copy button issue. --- src/index.tsx | 4 +++- src/nodes/copy.ts | 13 +------------ src/plugins/useCopied.tsx | 23 +++++++++++++++++++++++ 3 files changed, 27 insertions(+), 13 deletions(-) create mode 100644 src/plugins/useCopied.tsx diff --git a/src/index.tsx b/src/index.tsx index 39e497a0..06542f4e 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -12,6 +12,7 @@ import rehypePrism from 'rehype-prism-plus'; import rehypeRewrite, { getCodeString, RehypeRewriteOptions } from 'rehype-rewrite'; import { octiconLink } from './nodes/octiconLink'; import { copyElement } from './nodes/copy'; +import { useCopied } from './plugins/useCopied'; import './styles/markdown.less'; import { reservedMeta } from './plugins/reservedMeta'; @@ -50,9 +51,10 @@ export default React.forwardRef((props warpperElement = {}, ...other } = props; - const mdp = React.createRef(); + const mdp = React.useRef(null); useImperativeHandle(ref, () => ({ ...props, mdp }), [mdp, props]); const cls = `${prefixCls || ''} ${className || ''}`; + useCopied(mdp); const rehypeRewriteHandle: RehypeRewriteOptions['rewrite'] = (node, index, parent) => { if (node.type === 'element' && parent && parent.type === 'root' && /h(1|2|3|4|5|6)/.test(node.tagName)) { diff --git a/src/nodes/copy.ts b/src/nodes/copy.ts index 9ac24a4d..bd751642 100644 --- a/src/nodes/copy.ts +++ b/src/nodes/copy.ts @@ -1,23 +1,12 @@ import { Element } from 'hast'; -import copyTextToClipboard from '@uiw/copy-to-clipboard'; export function copyElement(str: string = ''): Element { return { type: 'element', tagName: 'div', properties: { - // @ts-ignore - onClick: (event) => { - const target = event.currentTarget || event.target; - target.classList.add('active'); - copyTextToClipboard(target.dataset.code as string, function () { - setTimeout(() => { - target.classList.remove('active'); - }, 2000); - }); - }, - 'data-code': str, class: 'copied', + 'data-code': str, }, children: [ { diff --git a/src/plugins/useCopied.tsx b/src/plugins/useCopied.tsx new file mode 100644 index 00000000..5ce5ae7d --- /dev/null +++ b/src/plugins/useCopied.tsx @@ -0,0 +1,23 @@ +import copyTextToClipboard from '@uiw/copy-to-clipboard'; +import { useCallback, useEffect } from 'react'; + +export function useCopied(container: React.RefObject) { + const handle = useCallback((event: Event) => { + const target = (event.currentTarget || event.target) as HTMLDivElement; + target.classList.add('active'); + copyTextToClipboard(target.dataset.code as string, function () { + setTimeout(() => { + target.classList.remove('active'); + }, 2000); + }); + }, []); + useEffect(() => { + const btns = container.current?.querySelectorAll('pre code + div.copied'); + btns && Array.from(btns).forEach((elm) => elm.addEventListener('click', handle, false)); + btns && Array.from(btns).forEach((elm) => elm.addEventListener('click', (evn) => {}, false)); + return () => { + btns && Array.from(btns).forEach((elm) => elm.removeEventListener('click', handle)); + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [container]); +}