modules_ProgressBar_Simple_index.js

import { React, PropTypes, classnames } from '@gravityforms/libraries';
import { spacerClasses } from '@gravityforms/utils';

const { forwardRef } = React;

/**
 * @module Simple
 * @description A simple progress bar component that displays completion percentage.
 *
 * @since 5.7.3
 *
 * @param {object}                  props                  Component props.
 * @param {string}                  props.customAttributes Custom attributes for the component.
 * @param {string | Array | object} props.customClasses    Custom CSS classes for the component.
 * @param {string}                  props.label            Custom label text (overrides percentage).
 * @param {boolean}                 props.showLabel        Whether to show the percentage label.
 * @param {string}                  props.size             Size variant of the progress bar. Options: 'small', 'regular', 'large'.
 * @param {string | number | Array} props.spacing          The spacing for the component, as a string, number, array, or object.
 * @param {boolean}                 props.stepMode         Whether the progress bar is in step mode.
 * @param {number}                  props.value            Current progress value (0-100).
 *
 * @return {JSX.Element} The progress bar component.
 *
 * @example
 * import ProgressBar from '@gravityforms/components/react/admin/modules/ProgressBar/Simple';
 *
 * return (
 *     <ProgressBar
 *         value={75}
 *         showLabel={true}
 *     />
 * );
 *
 */
const Simple = forwardRef( ( {
	customAttributes = {},
	customClasses = [],
	label = '',
	showLabel = false,
	size = 'regular',
	spacing = '',
	stepMode = false,
	totalSteps = 0,
	value = 0,
}, ref ) => {
	const componentProps = {
		className: classnames( {
			'gform-progress-bar': true,
			[ `gform-progress-bar--size-${ size }` ]: true,
			'gform-progress-bar--simple': true,
			'gform-progress-bar--has-label': showLabel,
			...spacerClasses( spacing ),
		}, customClasses ),
		ref,
		...customAttributes,
	};

	const normalizedValue = Math.min( 100, Math.max( 0, value ) );
	let displayLabel = label || `${ normalizedValue }%`;
	if ( stepMode ) {
		displayLabel = totalSteps > 0
			? `${ normalizedValue }% (${ Math.round( ( normalizedValue / 100 ) * totalSteps ) } of ${ totalSteps })`
			: `${ normalizedValue }%`;
	}

	const fillStyle = {
		width: `${ normalizedValue }%`,
	};

	return (
		<div
			{ ...componentProps }
			ref={ ref }
			role="progressbar"
			aria-valuenow={ normalizedValue }
			aria-valuemin="0"
			aria-valuemax="100"
		>
			<div className="gform-progress-bar__track">
				<div className="gform-progress-bar__fill" style={ fillStyle } />
			</div>
			{ showLabel && (
				<div className="gform-progress-bar__label">
					<div className="gform-progress-bar__label-inner">
						{ displayLabel }
					</div>
				</div>
			) }
		</div>
	);
} );

Simple.propTypes = {
	customAttributes: PropTypes.object,
	customClasses: PropTypes.oneOfType( [
		PropTypes.string,
		PropTypes.array,
		PropTypes.object,
	] ),
	label: PropTypes.string,
	showLabel: PropTypes.bool,
	size: PropTypes.oneOf( [ 'small', 'regular', 'large' ] ),
	spacing: PropTypes.oneOfType( [
		PropTypes.string,
		PropTypes.number,
		PropTypes.array,
		PropTypes.object,
	] ),
	stepMode: PropTypes.bool,
	value: PropTypes.number,
};

Simple.displayName = 'ProgressBar/Simple';

export default Simple;