elements_Button_CopyButton_index.js

import { React, classnames, PropTypes } from '@gravityforms/libraries';
import { clipboard } from '@gravityforms/utils';
import Button from '../index';

const { forwardRef } = React;

/**
 * @module CopyButton
 * @description A copy button component.
 *
 * @since 5.6.0
 *
 * @param {object}                     props                  Component props.
 * @param {JSX.Element|null}           props.children         React element children.
 * @param {string}                     props.copyText         The text to copy to the clipboard when the button is clicked.
 * @param {object}                     props.customAttributes Custom attributes for the component.
 * @param {string|Array|object}        props.customClasses    Custom classes for the component.
 * @param {boolean}                    props.disabled         Whether the button is disabled or not.
 * @param {string}                     props.icon             Icon name if using an icon button.
 * @param {object}                     props.iconAttributes   Custom attributes for the icon.
 * @param {string}                     props.iconPrefix       The prefix for the icon library to be used.
 * @param {number}                     props.iconSize         The icon size, in px, when type is flexible.
 * @param {string}                     props.label            The button label.
 * @param {Function}                   props.onClick          On click handler for the button.
 * @param {string}                     props.size             The button size.
 * @param {string|number|Array|object} props.spacing          The spacing for the component, as a string, number, array, or object.
 * @param {string}                     props.type             The button type.
 *
 * @return {JSX.Element} The copy button component.
 *
 * @example
 * import CopyButton from '@gravityforms/components/react/admin/elements/Button/CopyButton';
 *
 * return (
 *     <CopyButton onClick={ () => {} } type="white" label={ 'Click me' } />
 * );
 *
 */
const CopyButton = forwardRef( ( {
	children = null,
	copyText = '',
	customAttributes = {},
	customClasses = [],
	disabled = false,
	icon = 'copy-alt',
	iconAttributes = {},
	iconPrefix = 'gravity-component-icon',
	iconSize = 0,
	label = '',
	onClick = () => {},
	size = 'size-height-s',
	spacing = '',
	type = 'icon-grey',
}, ref ) => {
	const buttonProps = {
		customClasses: classnames( {
			'gform-copy-button': true,
			'gform-copy-button--flexible': type === 'flexible',
		}, customClasses ),
		disabled,
		icon,
		iconAttributes: {
			customAttributes: {
				...( iconAttributes?.customAttributes || {} ),
				style: {
					...( iconAttributes?.customAttributes?.style || {} ),
					fontSize: type === 'flexible' && iconSize ? `${ iconSize }px` : undefined,
				},
			},
			...iconAttributes,
		},
		iconPrefix,
		label,
		onClick: ( event ) => {
			if ( disabled ) {
				return;
			}

			if ( copyText ) {
				clipboard( copyText );
			}

			onClick( event );
		},
		spacing,
		size,
		type: type !== 'flexible' ? type : 'icon-grey',
		...customAttributes,
	};

	return (
		<Button { ...buttonProps } ref={ ref }>
			{ children }
		</Button>
	);
} );

CopyButton.propTypes = {
	children: PropTypes.oneOfType( [
		PropTypes.string,
		PropTypes.node,
	] ),
	copyText: PropTypes.string,
	customAttributes: PropTypes.object,
	customClasses: PropTypes.oneOfType( [
		PropTypes.string,
		PropTypes.array,
		PropTypes.object,
	] ),
	disabled: PropTypes.bool,
	icon: PropTypes.string,
	iconAttributes: PropTypes.object,
	iconPrefix: PropTypes.string,
	iconSize: PropTypes.number,
	label: PropTypes.string,
	onClick: PropTypes.func,
	size: PropTypes.string,
	spacing: PropTypes.oneOfType( [
		PropTypes.string,
		PropTypes.number,
		PropTypes.array,
		PropTypes.object,
	] ),
	type: PropTypes.string,
};

CopyButton.displayName = 'Elements/Button/CopyButton';

export default CopyButton;