import { React, classnames, PropTypes } from '@gravityforms/libraries';
import Button from '../../elements/Button';
import Icon from '../../elements/Icon';
import Link from '../../elements/Link';
import Text from '../../elements/Text';
import { spacerClasses } from '@gravityforms/utils';
const { forwardRef, useState } = React;
/**
* @module Alert
* @description An alert component with predefined types and many customization arguments.
*
* @since 2.1.0
*
* @param {object} props The props for the component template.
* @param {JSX.Element} props.children React element children.
* @param {string} props.content The content of the alert.
* @param {object} props.contentCustomAttributes Custom attributes for the content.
* @param {string|Array|object} props.contentCustomClasses Custom classes for the content.
* @param {string} props.ctaLabel The label for the call-to-action button.
* @param {string} props.ctaLink The link href for the call-to-action button.
* @param {object} props.customAttributes Any custom attributes.
* @param {string|Array|object} props.customClasses An array of additional classes for the toggle.
* @param {string} props.customIcon An icon override for the defaults that are set based on type.
* @param {string} props.customIconPrefix The prefix for the custom override.
* @param {string} props.dismissableAriaLabel The aria-label for the dismiss button.
* @param {string} props.dismissableTitle The title for the dismiss button.
* @param {boolean} props.hasCta Whether or not the alert has a call-to-action button.
* @param {string} props.id Id for the alert, auto generated if not passed.
* @param {boolean} props.isDismissable Whether or not the alert is dismissable.
* @param {boolean} props.isInline Whether or not the alert is inline.
* @param {string|number|Array|object} props.spacing The spacing for the component, string, number, object or array.
* @param {string} props.theme Theme for the alert, primary or cosmos.
* @param {string} props.type The type of the alert. Default, notice, success, error and accessibility.
* @param {object|null} ref Ref to the component.
*
* @return {JSX.Element} The alert component.
*
* @example
* import Alert from '@gravityforms/components/react/admin/modules/Alert';
* import Text from '@gravityforms/components/react/admin/elements/Text';
*
* return (
* <Alert>
* <Text content="Some text for my alert!">
* </Alert>
* );
*
*/
const Alert = forwardRef( ( {
children = null,
content = '',
contentCustomAttributes = {},
contentCustomClasses = [],
ctaLabel = '',
ctaLink = '',
customAttributes = {},
customClasses = [],
customIcon = '',
customIconPrefix = 'gform-icon',
dismissableAriaLabel = '',
dismissableTitle = '',
hasCta = false,
iconAttributes = {},
iconClasses = [],
isDismissable = false,
isInline = false,
spacing = '',
theme = 'cosmos',
type = 'default',
}, ref ) => {
const [ isDismissed, setIsDismissed ] = useState( false );
const attributes = {
className: classnames( {
'gform-alert': true,
[ `gform-alert--${ type }` ]: true,
[ `gform-alert--theme-${ theme }` ]: true,
'gform-alert--inline': isInline,
...spacerClasses( spacing ),
}, customClasses ),
ref,
...customAttributes,
};
const isCosmosTheme = 'cosmos' === theme;
const customIconAttributes = {
'aria-hidden': 'true',
...iconAttributes,
};
const customIconClasses = classnames( {
'gform-alert__icon': true,
}, iconClasses );
let alertIcon = customIcon;
let alertIconPreset = '';
if ( ! customIcon ) {
switch ( type ) {
case 'default':
alertIcon = 'campaign';
break;
case 'info':
alertIcon = isCosmosTheme ? 'information-simple' : 'circle-notice-fine';
alertIconPreset = isCosmosTheme ? 'status-info' : '';
break;
case 'notice':
alertIcon = isCosmosTheme ? 'exclamation-simple' : 'circle-notice-fine';
alertIconPreset = isCosmosTheme ? 'status-info' : '';
break;
case 'success':
alertIcon = isCosmosTheme ? 'checkmark-simple' : 'circle-check-fine';
alertIconPreset = isCosmosTheme ? 'status-correct' : '';
break;
case 'error':
alertIcon = isCosmosTheme ? 'exclamation-simple' : 'circle-error-fine';
alertIconPreset = isCosmosTheme ? 'status-error' : '';
break;
case 'incorrect':
alertIcon = isCosmosTheme ? 'exclamation-simple' : 'circle-error-fine';
alertIconPreset = isCosmosTheme ? 'status-incorrect' : '';
break;
case 'accessibility':
alertIcon = 'accessibility';
break;
}
}
const contentAttributes = {
content,
customClasses: classnames(
[ 'gform-alert__message' ],
contentCustomClasses,
),
tagName: 'p',
...contentCustomAttributes,
};
return ! isDismissed
? (
<div { ...attributes }>
<Icon
customAttributes={ customIconAttributes }
customClasses={ customIconClasses }
icon={ alertIcon }
iconPrefix={ customIconPrefix }
preset={ alertIconPreset }
/>
<div className="gform-alert__message-wrap">
<Text { ...contentAttributes }>{ children }</Text>
{ hasCta &&
<Link
content={ ctaLabel }
customClasses={ [ 'gform-alert__cta', 'gform-button', 'gform-button--white', 'gform-button--size-xs' ] }
href={ ctaLink }
target="_blank"
/>
}
</div>
{ isDismissable &&
<Button
ariaLabel={ dismissableAriaLabel }
customAttributes={ {
title: dismissableTitle,
} }
customClasses={ [ 'gform-alert__dismiss' ] }
icon="delete"
onClick={ () => {
setIsDismissed( true );
} }
/>
}
</div>
) : null;
} );
Alert.propTypes = {
children: PropTypes.oneOfType( [
PropTypes.arrayOf( PropTypes.node ),
PropTypes.node,
] ),
content: PropTypes.string,
contentCustomAttributes: PropTypes.object,
contentCustomClasses: PropTypes.oneOfType( [
PropTypes.string,
PropTypes.array,
PropTypes.object,
] ),
ctaLabel: PropTypes.string,
ctaLink: PropTypes.string,
customAttributes: PropTypes.object,
customClasses: PropTypes.oneOfType( [
PropTypes.string,
PropTypes.array,
PropTypes.object,
] ),
customIcon: PropTypes.string,
customIconPrefix: PropTypes.string,
dismissableAriaLabel: PropTypes.string,
dismissableTitle: PropTypes.string,
hasCta: PropTypes.bool,
iconAttributes: PropTypes.object,
iconClasses: PropTypes.array,
isDismissable: PropTypes.bool,
isInline: PropTypes.bool,
spacing: PropTypes.oneOfType( [
PropTypes.string,
PropTypes.number,
PropTypes.array,
PropTypes.object,
] ),
theme: PropTypes.string,
type: PropTypes.string,
};
Alert.displayName = 'Alert';
export default Alert;