@mskcc/carbon-react
Version:
Carbon react components for the MSKCC DSM
94 lines (90 loc) • 2.8 kB
JavaScript
/**
* MSKCC 2021, 2024
*/
import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
import PropTypes from 'prop-types';
import React__default, { useState, useCallback, useEffect } from 'react';
import debounce from 'lodash.debounce';
import cx from 'classnames';
import { composeEventHandlers } from '../../tools/events.js';
import { usePrefix } from '../../internal/usePrefix.js';
import { IconButton } from '../IconButton/IconButton.js';
function Copy(_ref) {
let {
children,
className,
feedback,
feedbackTimeout,
onAnimationEnd,
onClick,
...other
} = _ref;
const [animation, setAnimation] = useState('');
const prefix = usePrefix();
const classNames = cx(className, `${prefix}--copy`, {
[`${prefix}--copy-btn--animating`]: animation,
[`${prefix}--copy-btn--${animation}`]: animation
});
// eslint-disable-next-line react-hooks/exhaustive-deps
const handleFadeOut = useCallback(debounce(() => {
setAnimation('fade-out');
}, feedbackTimeout), [feedbackTimeout]);
const handleClick = useCallback(() => {
setAnimation('fade-in');
handleFadeOut();
}, [handleFadeOut]);
const handleAnimationEnd = event => {
if (event.animationName === 'hide-feedback') {
setAnimation('');
}
};
useEffect(() => () => {
handleFadeOut.cancel();
}, [handleFadeOut]);
const initialLabel = other['aria-label'] ?? '';
return /*#__PURE__*/React__default.createElement(IconButton, _extends({
closeOnActivation: false,
align: "bottom",
className: classNames,
label: animation ? feedback : initialLabel,
onClick: composeEventHandlers([onClick, handleClick]),
onAnimationEnd: composeEventHandlers([onAnimationEnd, handleAnimationEnd])
}, other, {
"aria-label": !children && (animation ? feedback : other['aria-label']) || null
}), children);
}
Copy.propTypes = {
/**
* Pass in content to be rendered in the underlying `<button>`
*/
children: PropTypes.node,
/**
* Specify an optional className to be applied to the underlying `<button>`
*/
className: PropTypes.string,
/**
* Specify the string that is displayed when the button is clicked and the
* content is copied
*/
feedback: PropTypes.string,
/**
* Specify the time it takes for the feedback message to timeout
*/
feedbackTimeout: PropTypes.number,
/**
* Specify an optional `onAnimationEnd` handler that is called when the underlying
* animation ends
*/
onAnimationEnd: PropTypes.func,
/**
* Specify an optional `onClick` handler that is called when the underlying
* `<button>` is clicked
*/
onClick: PropTypes.func
};
Copy.defaultProps = {
feedback: 'Copied!',
feedbackTimeout: 2000,
onClick: () => {}
};
export { Copy as default };