modules_Cards_MetricCard_index.js

import { React, PropTypes, classnames } from '@gravityforms/libraries';
import Card from '../Card';
import Box from '../../../elements/Box';
import Heading from '../../../elements/Heading';
import Icon from '../../../elements/Icon';
import Text from '../../../elements/Text';

const { forwardRef } = React;

/**
 * @module MetricCard
 * @description The metric card component. used to display icons with a measurement of some kind.
 *
 * @since 4.4.4
 *
 * @param {object}              props                   Component props.
 * @param {JSX.Element|null}    props.children          React element children.
 * @param {number}              props.count             The count to display.
 * @param {object}              props.contentAttributes Custom attributes for the content box.
 * @param {string|Array|object} props.contentClasses    Custom classes for the content box.
 * @param {object}              props.countAttributes   Custom attributes for the count text.
 * @param {string|Array|object} props.countClasses      Custom classes for the count text.
 * @param {object}              props.customAttributes  Custom attributes for the component.
 * @param {string|Array|object} props.customClasses     Custom classes for the component.
 * @param {object}              props.iconAttributes    Custom attributes for the icon.
 * @param {boolean}             props.hasIcon           Whether to include the icon.
 * @param {string}              props.title             The title to display.
 * @param {object}              props.titleAttributes   Custom attributes for the title.
 * @param {string|Array|object} props.titleClasses      Custom classes for the title.
 * @param {string}              props.type              The type of metric card.
 * @param {object|null}         ref                     Ref to the component.
 *
 * @return {JSX.Element} The form template card component.
 *
 * @example
 * import MetricCard from '@gravityforms/components/react/admin/modules/Cards/MetricCard';
 *
 * return (
 *     <MetricCard
 *         style="metric"
 *     />
 * );
 *
 */
const MetricCard = forwardRef( ( {
	children = null,
	count = 0,
	contentAttributes = {},
	contentClasses = [],
	countAttributes = {},
	countClasses = [],
	customAttributes = {},
	customClasses = [],
	iconAttributes = {},
	hasIcon = true,
	title = '',
	titleAttributes = {},
	titleClasses = [],
	type = 'info',
}, ref ) => {
	const componentProps = {
		customClasses: classnames( {
			'gform-card--metric': true,
			[ `gform-card--metric-${ type }` ]: true,
		}, customClasses ),
		...customAttributes,
		baseClass: false,
		ref,
	};

	const iconProps = {
		preset: `metric-${ type }`,
		...iconAttributes,
	};

	const contentProps = {
		customClasses: classnames( {
			'gform-card__metric-content': true,
		}, contentClasses ),
		spacing: [ 0, 0, 0, 6 ],
		...contentAttributes,
	};

	const titleProps = {
		customClasses: classnames( {
			'gform-card__metric-title': true,
		}, titleClasses ),
		size: 'text-sm',
		spacing: [ 0, 0, 1, 0 ],
		weight: 'medium',
		tagName: 'h3',
		...titleAttributes,
	};

	const countProps = {
		customClasses: classnames( {
			'gform-card__metric-count': true,
		}, countClasses ),
		size: 'text-xl',
		weight: 'semibold',
		...countAttributes,
	};

	return (
		<Card { ...componentProps }>
			{ hasIcon && <Icon { ...iconProps } /> }
			<Box { ...contentProps }>
				<Heading { ...titleProps }>{ title }</Heading>
				<Text { ...countProps }>{ count }</Text>
			</Box>
			{ children }
		</Card>
	);
} );

MetricCard.propTypes = {
	children: PropTypes.node,
	count: PropTypes.number,
	contentAttributes: PropTypes.object,
	contentClasses: PropTypes.oneOfType( [
		PropTypes.array,
		PropTypes.object,
		PropTypes.string,
	] ),
	countAttributes: PropTypes.object,
	countClasses: PropTypes.oneOfType( [
		PropTypes.array,
		PropTypes.object,
		PropTypes.string,
	] ),
	customAttributes: PropTypes.object,
	customClasses: PropTypes.oneOfType( [
		PropTypes.array,
		PropTypes.object,
		PropTypes.string,
	] ),
	iconAttributes: PropTypes.object,
	hasIcon: PropTypes.bool,
	title: PropTypes.string,
	titleAttributes: PropTypes.object,
	titleClasses: PropTypes.oneOfType( [
		PropTypes.array,
		PropTypes.object,
		PropTypes.string,
	] ),
	type: PropTypes.oneOf( [ 'info', 'success', 'warn', 'error' ] ),
};

MetricCard.displayName = 'Cards/MetricCard';

export default MetricCard;