gdq-archive/frontend/components/CopyField.tsx

95 lines
2.7 KiB
TypeScript

/**
* Copyright (C) 2019-2021 Carl Kittelberger <icedream@icedream.pw>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import React, { useState, useRef } from 'react';
import InputGroup from 'react-bootstrap/InputGroup';
import FormControl from 'react-bootstrap/FormControl';
import Button from 'react-bootstrap/Button';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Overlay, Tooltip } from 'react-bootstrap';
import type { IconProp } from '@fortawesome/fontawesome-svg-core';
import { faCopy, faShare } from '@fortawesome/free-solid-svg-icons';
import { FormattedMessage } from './localization';
function CopyField({
children,
copyIcon,
icon,
}: {
children: string,
copyIcon?: IconProp,
icon?: IconProp,
}) {
const [show, setShow] = useState(false);
const target = useRef(null);
const textbox = useRef(null);
let timer: NodeJS.Timeout = null;
const doCopy = () => {
if (timer !== null) {
clearTimeout(timer);
}
textbox.current.select();
document.execCommand('copy');
setShow(true);
timer = setTimeout(() => {
setShow(false);
}, 3000);
return false;
};
return (
<InputGroup>
{
icon
? (
<InputGroup.Text>
<FontAwesomeIcon icon={faShare} />
</InputGroup.Text>
)
: ''
}
<FormControl ref={textbox} readOnly value={children} />
<Button ref={target} onClick={doCopy}>
<FontAwesomeIcon icon={copyIcon} />
<Overlay target={target.current} show={show} placement="top">
{(props) => (
// eslint-disable-next-line react/jsx-props-no-spreading
<Tooltip id="overlay-copy" {...props}>
<FormattedMessage
id="CopyField.copied"
defaultMessage="Copied!"
description="Tooltip shown when user clicks the Copy button."
/>
</Tooltip>
)}
</Overlay>
</Button>
</InputGroup>
);
}
CopyField.defaultProps = {
copyIcon: faCopy,
icon: null,
};
export default CopyField;