components_sprintr.js

import { React } from '@gravityforms/libraries';

/**
 * @module SprintR
 * @description Renders dynamic content by replacing placeholders in the given text with passed react components.
 * Uses %1$s, %2$s, etc. as placeholders in the text and replaces them with the corresponding component from the tokens array.
 *
 * @since 3.1.1
 *
 * @param {object} props        The options object.
 * @param {string} props.text   The text containing placeholders.
 * @param {Array}  props.tokens The array of tokens to be used for replacement.
 *
 * @return {React.ReactNode} - The JSX element with injected components.
 * @example
 * import Link from '@gravityforms/components/react/admin/elements/Link';
 * import Text from '@gravityforms/components/react/admin/elements/Text';
 * import { SprintR } from '@gravityforms/react-utils';
 *
 * <SprintR
 * 	text="Hey there replace this: %1$s and this: %2$s and this with the first component again: %1$s"
 * 	tokens={ [
 * 		{
 * 			component: Text,
 * 			props: {
 * 				content: "I replace both %1$s",
 * 				customClasses: [ 'gform-example-text' ],
 * 				size: 'text-xs',
 * 				tagName: 'span',
 * 			},
 * 		},
 * 	    {
 * 			component: Link,
 * 			props: {
 * 				content: "I replace %2$s",
 * 				customClasses: [ 'gform-example-link' ],
 * 				size: 'text-xs',
 * 				tagName: 'span',
 * 			},
 * 		},
 * 	] }
 * />
 *
 */
export default function SprintR( {
	text = '',
	tokens = [],
} ) {
	const renderContent = () => {
		const parts = text.split( /(%\d\$s)/ );
		return parts.map( ( part, index ) => {
			const match = part.match( /%(\d)\$s/ );
			if ( match ) {
				const tokenIndex = parseInt( match[ 1 ], 10 ) - 1;
				const token = tokens[ tokenIndex ];
				if ( ! token ) {
					return null;
				}
				const Component = token.component;
				return <Component key={ index } { ...token.props } />;
			}
			return part;
		} );
	};

	return <>{ renderContent() }</>;
}