Skip to content

Instantly share code, notes, and snippets.

@codemile
Created January 2, 2025 16:53
Show Gist options
  • Save codemile/b4d3d78d8a3ee40d7716830c6b503d96 to your computer and use it in GitHub Desktop.
Save codemile/b4d3d78d8a3ee40d7716830c6b503d96 to your computer and use it in GitHub Desktop.
React TypeScript component for clipboard copy/paste functionality with MUI icons and tooltips.
import CheckIcon from '@mui/icons-material/Check';
import ContentCopyIcon from '@mui/icons-material/ContentCopy';
import ContentPasteIcon from '@mui/icons-material/ContentPaste';
import {IconButton, Tooltip} from '@mui/material';
import {FC, useState} from 'react';
import {useBounceValue} from './hooks/useBounceValue';
interface ClipboardIconButtonProps {
fontSize?: 'inherit' | 'large' | 'medium' | 'small';
mode: 'copy' | 'paste';
onPaste?: (value: string) => void;
value?: string;
}
export const ClipboardIconButton: FC<ClipboardIconButtonProps> = ({
fontSize = 'small',
mode,
value,
onPaste
}) => {
const [count, setCount] = useState(0);
const copied = Boolean(useBounceValue(count, 0, 2000));
const icon =
mode === 'copy' ? (
<ContentCopyIcon fontSize={fontSize} />
) : (
<ContentPasteIcon fontSize={fontSize} />
);
const title_copy = copied ? 'Copied' : 'Copy';
const title_paste = copied ? 'Pasted' : 'Paste';
const title = mode === 'copy' ? title_copy : title_paste;
return (
<Tooltip title={title}>
<IconButton
edge="end"
onClick={(e) => {
if (mode === 'copy') {
navigator.clipboard.writeText(value).then();
} else {
navigator.clipboard.readText().then((text) => {
onPaste?.(text);
});
}
setCount((v) => v + 1);
}}
>
{copied ? (
<CheckIcon className="text-green-400 dark:text-green-600" />
) : (
icon
)}
</IconButton>
</Tooltip>
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment