Merge branch 'feat/inda-383-daily-stat' into 'main'
[ProtonMail-WebClient.git] / packages / pass / components / Form / Field / Control / ClickToCopy.tsx
blob30ccdcac191cea5bd82560a110bbeb0ef416d148
1 import type { MouseEvent, PropsWithChildren } from 'react';
2 import { type FC, useEffect, useRef, useState } from 'react';
4 import { c } from 'ttag';
6 import { useCopyToClipboard } from '@proton/pass/hooks/useCopyToClipboard';
7 import clsx from '@proton/utils/clsx';
9 export type ClickToCopyProps = { className?: string; value?: string };
11 export const ClickToCopy: FC<PropsWithChildren<ClickToCopyProps>> = ({ className, children, value = '' }) => {
12     const ref = useRef<HTMLDivElement>(null);
13     const copyToClipboard = useCopyToClipboard();
14     const [selection, setSelection] = useState(false);
16     const handleClick = (evt: MouseEvent) => {
17         if (selection) evt.preventDefault();
18         else if (value) void copyToClipboard(value);
19     };
21     useEffect(() => {
22         const onSelectionChange = () => {
23             const selection = window.getSelection();
24             setSelection(selection !== null && selection.toString().length > 0);
25         };
27         document.addEventListener('selectionchange', onSelectionChange);
28         return () => document.removeEventListener('selectionchange', onSelectionChange);
29     }, []);
31     return (
32         /* disabling `prefer-tag-over-role` as we cannot use a
33          * `button` element here - children may include buttons and
34          * this would lead to invalid DOM structure */
35         /* eslint-disable-next-line jsx-a11y/prefer-tag-over-role */
36         <div
37             ref={ref}
38             className={clsx('cursor-pointer overflow-hidden', className)}
39             onKeyDown={(evt) => evt.key === 'Enter' && copyToClipboard(value)}
40             onClick={handleClick}
41             tabIndex={0}
42             role="button"
43         >
44             <span className="sr-only"> {c('Info').t`Press Enter to copy`}</span>
45             {children}
46         </div>
47     );