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);
22 const onSelectionChange = () => {
23 const selection = window.getSelection();
24 setSelection(selection !== null && selection.toString().length > 0);
27 document.addEventListener('selectionchange', onSelectionChange);
28 return () => document.removeEventListener('selectionchange', onSelectionChange);
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 */
38 className={clsx('cursor-pointer overflow-hidden', className)}
39 onKeyDown={(evt) => evt.key === 'Enter' && copyToClipboard(value)}
44 <span className="sr-only"> {c('Info').t`Press Enter to copy`}</span>