Convert ClipboardButton to TypeScript

(cherry picked from commit 99fc52039f44264c83d939e5f096d8e16d2f3355)
This commit is contained in:
Treycos
2024-09-21 19:09:55 +02:00
committed by Bogdan
parent 24063e06ab
commit 94cf07ddb4
5 changed files with 73 additions and 173 deletions
@@ -0,0 +1,69 @@
import React, { useCallback, useEffect, useState } from 'react';
import FormInputButton from 'Components/Form/FormInputButton';
import Icon from 'Components/Icon';
import { icons, kinds } from 'Helpers/Props';
import { ButtonProps } from './Button';
import styles from './ClipboardButton.css';
export interface ClipboardButtonProps extends Omit<ButtonProps, 'children'> {
value: string;
}
export type ClipboardState = 'success' | 'error' | null;
export default function ClipboardButton({
id,
value,
className = styles.button,
...otherProps
}: ClipboardButtonProps) {
const [state, setState] = useState<ClipboardState>(null);
useEffect(() => {
if (!state) {
return;
}
const timeoutId = setTimeout(() => {
setState(null);
}, 3000);
return () => {
if (timeoutId) {
clearTimeout(timeoutId);
}
};
}, [state]);
const handleClick = useCallback(async () => {
try {
await navigator.clipboard.writeText(value);
setState('success');
} catch (_) {
setState('error');
}
}, [value]);
return (
<FormInputButton
className={className}
onClick={handleClick}
{...otherProps}
>
<span className={state ? styles.showStateIcon : undefined}>
{state ? (
<span className={styles.stateIconContainer}>
<Icon
name={state === 'error' ? icons.DANGER : icons.CHECK}
kind={state === 'error' ? kinds.DANGER : kinds.SUCCESS}
/>
</span>
) : null}
<span className={styles.clipboardIconContainer}>
<Icon name={icons.CLIPBOARD} />
</span>
</span>
</FormInputButton>
);
}