import {
consoleInfo,
cookieStorage,
delegate,
getClosest,
getNode,
objectToAttributes,
spacerClasses,
trigger,
uniqueId,
} from '@gravityforms/utils';
/**
* @function alertTemplate
* @description Generates the markup for an alert in the admin.
*
* @since 1.1.16
*
* @param {object} options The options for the component template.
* @param {string} options.content The content of the alert.
* @param {string} options.ctaLabel The label for the call-to-action button.
* @param {string} options.ctaLink The link href for the call-to-action button.
* @param {object} options.customAttributes Any custom attributes.
* @param {Array} options.customClasses An array of additional classes for the toggle.
* @param {string} options.dismissableAriaLabel The aria-label for the dismiss button.
* @param {string} options.dismissableTitle The title for the dismiss button.
* @param {boolean} options.hasCta Whether or not the alert has a call-to-action button.
* @param {string} options.id Id for the alert, auto generated if not passed.
* @param {boolean} options.isDismissable Whether or not the alert is dismissable.
* @param {boolean} options.isInline Whether or not the alert is inline.
* @param {string} options.selector The data-js selector string for the alert.
* @param {string|number|Array|object} options.spacing The spacing for the component, string, number, object or array.
* @param {string} options.theme Theme for the toggle, primary or cosmos.
* @param {string} options.type The type of the alert. Default, notice, success, error and accessibility.
*
* @return {string}
* @example
* import { alertTemplate } from '@gravityforms/components/html/admin/elements/Alert';
*
* function Example() {
* const alertTemplateHTML = alertTemplateTemplate( options );
* document.body.insertAdjacentHTML( 'beforeend', alertTemplateHTML );
* }
*
*/
export const alertTemplate = ( {
content = '',
ctaLabel = '',
ctaLink = '',
customAttributes = {},
customClasses = [],
dismissableAriaLabel = '',
dismissableTitle = '',
hasCta = false,
id = uniqueId( 'alert' ),
isDismissable = false,
isInline = false,
spacing = '',
theme = 'primary',
type = 'default',
} ) => {
const componentAttrs = objectToAttributes( {
...customAttributes,
id,
class: [
'gform-alert',
`gform-alert--${ type }`,
`gform-alert--theme-${ theme }`,
isInline && 'gform-alert--inline',
...Object.keys( spacerClasses( spacing ) ),
...customClasses,
],
} );
const iconAttrs = objectToAttributes( {
'aria-hidden': 'true',
class: [
'gform-alert__icon',
'gform-icon',
type === 'default' && 'gform-icon--campaign',
type === 'notice' && 'gform-icon--circle-notice-fine',
type === 'success' && 'gform-icon--circle-check-fine',
type === 'error' && 'gform-icon--circle-error-fine',
type === 'accessibility' && 'gform-icon--accessibility',
],
} );
return `
<div ${ componentAttrs }>
<span ${ iconAttrs }></span>
<div class="gform-alert__message-wrap">
<p class="gform-alert__message">${ content }</p>
${ hasCta ? `
<a
class="gform-alert__cta gform-button gform-button--white gform-button--size-xs"
href="${ ctaLink }"
target="_blank"
title="title for a11y"
>
${ ctaLabel }
</a>
` : '' }
</div>
${ isDismissable ? `
<button
class="gform-alert__dismiss"
aria-label="${ dismissableAriaLabel }"
title="${ dismissableTitle }"
data-js="gform-alert-dismiss-trigger"
>
<span class="gform-icon gform-icon--delete"></span>
</button>
` : '' }
</div>
`;
};
/**
* @class Alert
* @description A alert component with 5 styles, default, notice, success, error and accessibility. It also allows for a cookie to store dismissed state.
*
* @since 1.1.16
*
* @borrows alertTemplate as alertTemplate
*
* @param {object} options The options for the component.
* @param {string} options.content The content of the alert.
* @param {string} options.ctaLabel The label for the call-to-action button.
* @param {string} options.ctaLink The link href for the call-to-action button.
* @param {object} options.customAttributes Any custom attributes for the component.
* @param {Array} options.customClasses An array of additional classes for the component.
* @param {string} options.dismissableAriaLabel The aria-label for the dismiss button.
* @param {string} options.dismissableTitle The title for the dismiss button.
* @param {boolean} options.hasCta Whether or not the alert has a call-to-action button.
* @param {string} options.id Id for the component, auto generated if not passed.
* @param {boolean} options.isDismissable Whether or not the alert is dismissable.
* @param {boolean} options.isInline Whether or not the alert is inline.
* @param {string} options.rendered Is the component already rendered in the dom, eg by php?
* @param {string} options.renderOnInit Render the component on init of the class?
* @param {string|number|Array|object} options.spacing Spacing for the component.
* @param {string} options.target The target to render to. Any valid css selector string.
* @param {string} options.targetPosition The insert position for the component relative to the target.
* @param {string} options.theme Theme for the component, primary or cosmos.
* @param {string} options.type The type of the alert. Default, notice, success, error and accessibility.
*
* @return {Class} The class instance.
* @example
* import Alert from '@gravityforms/components/html/admin/elements/Alert';
*
* function Example() {
* const alertInstance = new Alert( {
* content: 'This is an alert',
* id: 'my-alert',
* renderOnInit: false,
* target: '#example-target',
* targetPosition: 'beforeend',
* type: 'error',
* } );
*
* // Some time later we can render it. This is only done if we set renderOnInit to false.
* // If true it will render on initialization.
* alertInstance.init();
* }
*
*/
export default class Alert {
constructor( options = {} ) {
this.options = {};
Object.assign(
this.options,
{
container: document,
content: '',
cookieName: '',
ctaLabel: '',
ctaLink: '',
customAttributes: {},
customClasses: [],
dismissableAriaLabel: '',
dismissableTitle: '',
hasCta: false,
id: uniqueId( 'alert' ),
isDismissable: false,
isInline: false,
rendered: false,
renderOnInit: true,
spacing: '',
target: '',
targetPosition: 'afterbegin',
theme: 'cosmos',
type: 'default',
},
options
);
/**
* @event gform/alert/pre_init
* @type {object}
* @description Fired before the component has started any internal init functions. A great chance to augment the options.
*
* @since 1.1.16
*
* @property {object} instance The Component class instance.
*/
trigger( { event: 'gform/alert/pre_init', native: false, data: { instance: this } } );
this.elements = {};
if ( this.options.renderOnInit ) {
this.init();
}
}
/**
* @memberof Alert
* @description Renders the component into the dom.
*
* @since 1.1.16
*
* @return {void}
*/
render() {
const { rendered, target, targetPosition } = this.options;
if ( ! rendered ) {
const renderTarget = getNode( target, document, true );
renderTarget.insertAdjacentHTML(
targetPosition,
alertTemplate( this.options )
);
}
this.elements.alert = getNode( `#${ this.options.id }`, document, true );
}
/**
* @param e
* @memberof Alert
* @description Dismiss the alert and store a cookie if name is set.
*
* @since 1.1.16
*
* @return {void}
*/
dismissAlert( e ) {
const parentEl = getClosest( e.target, `#${ this.options.id }` );
parentEl.style.display = 'none';
if ( this.options.cookieName ) {
const cookieValue = uniqueId( 'gform-alert' );
cookieStorage.set( this.options.cookieName, cookieValue, 1, true );
}
}
/**
* @memberof Alert
* @description Bind event listeners for the alert.
*
* @since 1.1.16
*
* @return {void}
*/
bindEvents() {
delegate(
`#${ this.options.id }`,
'[data-js="gform-alert-dismiss-trigger"]',
'click',
this.dismissAlert.bind( this )
);
}
/**
* @memberof Alert
* @description Initialize the component.
*
* @fires gform/alert/post_render
*
* @since 1.1.16
*
* @return {void}
*/
init() {
this.bindEvents();
this.render();
/**
* @event gform/alert/post_render
* @type {object}
* @description Fired when the component has completed rendering and all class init functions have completed.
*
* @since 1.1.16
*
* @property {object} instance The Component class instance.
*/
trigger( { event: 'gform/alert/post_render', native: false, data: { instance: this } } );
consoleInfo( `Gravity Forms Admin: Initialized alert component.` );
}
}