|
1 | 1 | import copyTextToClipboard from '@uiw/copy-to-clipboard';
|
2 |
| -import { useCallback, useEffect } from 'react'; |
| 2 | +import { useEffect } from 'react'; |
| 3 | + |
| 4 | +function getParentElement(target: EventTarget | null): null | HTMLElement { |
| 5 | + if (!target) return null; |
| 6 | + const dom = target as HTMLElement; |
| 7 | + if (dom.dataset.code && dom.classList.contains('copied')) { |
| 8 | + return dom; |
| 9 | + } |
| 10 | + if (dom.parentElement) { |
| 11 | + return getParentElement(dom.parentElement); |
| 12 | + } |
| 13 | + return null; |
| 14 | +} |
3 | 15 |
|
4 | 16 | export function useCopied(container: React.RefObject<HTMLDivElement>) {
|
5 |
| - const handle = useCallback((event: Event) => { |
6 |
| - const target = (event.currentTarget || event.target) as HTMLDivElement; |
| 17 | + const handle = (event: Event) => { |
| 18 | + const target = getParentElement(event.target); |
| 19 | + if (!target) return; |
7 | 20 | target.classList.add('active');
|
8 | 21 | copyTextToClipboard(target.dataset.code as string, function () {
|
9 | 22 | setTimeout(() => {
|
10 | 23 | target.classList.remove('active');
|
11 | 24 | }, 2000);
|
12 | 25 | });
|
13 |
| - }, []); |
| 26 | + }; |
14 | 27 | useEffect(() => {
|
15 |
| - const btns = container.current?.querySelectorAll('div.copied[data-code]'); |
16 |
| - btns && Array.from(btns).forEach((elm) => elm.addEventListener('click', handle, false)); |
| 28 | + container.current?.removeEventListener('click', handle, false); |
| 29 | + container.current?.addEventListener('click', handle, false); |
17 | 30 | return () => {
|
18 |
| - btns && Array.from(btns).forEach((elm) => elm.removeEventListener('click', handle, false)); |
| 31 | + container.current?.removeEventListener('click', handle, false); |
19 | 32 | };
|
20 | 33 | // eslint-disable-next-line react-hooks/exhaustive-deps
|
21 | 34 | }, [container]);
|
|
0 commit comments