import {
consoleInfo,
getNode,
objectToAttributes,
spacerClasses,
trigger,
uniqueId,
} from '@gravityforms/utils';
/**
* @function helpTextTemplate
* @description The markup for form field helper text.
*
* @since 1.1.18
*
* @param {string} id Optional id. Auto generated if not passed.
* @param {string} helpText Optional helper text.
*
* @return {string}
*/
export const helpTextTemplate = (
helpText = '',
id = '',
) => {
const componentProps = objectToAttributes( {
class: [
'gform-input-help-text',
],
id: `${ id }-help-text`,
} );
return `
<span ${ componentProps }>
${ helpText }
</span>
`;
};
/**
* @function labelTemplate
* @description The markup for form field label.
*
* @since 1.1.18
*
* @param {string} id Optional id. Auto generated if not passed.
* @param {string} label Label for the textarea.
* @param {object} labelCustomAttributes Any custom attributes for the label.
* @param {Array} labelCustomClasses Any custom classes for the label.
* @param {boolean} labelVisible If the label should be visible. Defaults to true.
*
* @return {string}
*/
export const labelTemplate = (
id = '',
label = '',
labelCustomAttributes = {},
labelCustomClasses = [],
labelVisible = true,
) => {
const componentProps = objectToAttributes( {
class: [
'gform-label',
'gform-input__label',
'gform-input__label--textarea',
! labelVisible ? 'gform-visually-hidden' : '',
...labelCustomClasses,
],
for: id,
...labelCustomAttributes,
} );
return `
<label ${ componentProps }>
${ label }
</label>
`;
};
/**
* @function textareaTemplate
* @description The markup for a textarea.
*
* @since 1.1.18
*
* @requires labelTemplate as labelTemplate
* @requires helpTextTemplate as helpTextTemplate
*
* @param {object} options The options for the component template.
* @param {object} options.customAttributes Any custom attributes for the textarea.
* @param {Array} options.customClasses Any custom classes for the textarea.
* @param {string} options.helpText Optional helper text.
* @param {string} options.id Optional id. Auto generated if not passed.
* @param {string} options.label Label for the textarea.
* @param {object} options.labelCustomAttributes Any custom attributes for the label.
* @param {Array} options.labelCustomClasses Any custom classes for the label.
* @param {boolean} options.labelVisible If the label should be visible. Defaults to true.
* @param {boolean} options.disabled If the textarea should be disabled. Defaults to false.
* @param {string} options.placeholder Optional placeholder text.
* @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.value Optional initial value for the textarea.
* @param {object} options.wrapperCustomAttributes Any custom attributes for the textarea wrapper.
* @param {Array} options.wrapperCustomClasses Any custom classes for the textarea wrapper.
* @param {string} options.wrapperTagName Tag to use for the textarea wrapper. Defaults to 'div',
*
* @return {string}
* @example
* import { textareaTemplate } from '@gravityforms/components/html/admin/elements/Textarea';
*
* function Example() {
* const textareaHTML = textareaTemplate( options );
* document.body.insertAdjacentHTML( 'beforeend', textareaHTML );
* }
*
*/
export const textareaTemplate = ( {
customAttributes = {},
customClasses = [],
helpText = '',
id = '',
label = '',
labelCustomAttributes = {},
labelCustomClasses = [],
labelVisible = true,
disabled = false,
placeholder = '',
spacing = '',
theme = 'cosmos',
value = '',
wrapperCustomAttributes = {},
wrapperCustomClasses = [],
wrapperTagName = 'div',
} ) => {
const wrapperProps = objectToAttributes( {
class: [
'gform-input-wrapper',
`gform-input-wrapper--theme-${ theme }`,
...Object.keys( spacerClasses( spacing ) ),
...wrapperCustomClasses,
],
...wrapperCustomAttributes,
} );
const componentProps = {
class: [
'gform-input',
'gform-input--textarea',
...customClasses,
],
id,
name: id,
placeholder,
...customAttributes,
};
if ( helpText ) {
componentProps[ 'aria-describedby' ] = `${ id }-help-text`;
}
if ( disabled ) {
componentProps.disabled = 'disabled';
}
const labelHtml = labelTemplate(
id,
label,
labelCustomAttributes,
labelCustomClasses,
labelVisible,
);
const helpTextHtml = helpTextTemplate(
helpText,
id,
);
return `
<${ wrapperTagName } ${ wrapperProps }>
${ label && labelHtml }
<textarea ${ objectToAttributes( componentProps ) }>${ value }</textarea>
${ helpText && helpTextHtml }
</${ wrapperTagName }>
`;
};
/**
* @class Textarea
* @description A textarea component to use wherever textarea form fields are needed.
*
* @since 1.1.18
*
* @borrows textareaTemplate as textareaTemplate
*
* @param {object} options The options for the component.
* @param {object} options.customAttributes Any custom attributes for the textarea.
* @param {Array} options.customClasses Any custom classes for the textarea.
* @param {string} options.helpText Optional helper text.
* @param {string} options.id Optional id. Auto generated if not passed.
* @param {string} options.label Label for the textarea.
* @param {object} options.labelCustomAttributes Any custom attributes for the label.
* @param {Array} options.labelCustomClasses Any custom classes for the label.
* @param {boolean} options.labelVisible If the label should be visible. Defaults to true.
* @param {string} options.placeholder Optional placeholder text.
* @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} 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.value Optional initial value for the textarea.
* @param {object} options.wrapperCustomAttributes Any custom attributes for the textarea wrapper.
* @param {Array} options.wrapperCustomClasses Any custom classes for the textarea wrapper.
* @param {string} options.wrapperTagName Tag to use for the textarea wrapper. Defaults to 'div',
*
* @return {Class} The class instance.
* @example
* import Textarea from '@gravityforms/components/html/admin/elements/Textarea';
*
* function Example() {
* const textareaInstance = new Textarea( {
* id: 'example-textarea',
* renderOnInit: false,
* target: '#example-target',
* targetPosition: 'beforeend',
* theme: 'cosmos',
* } );
*
* // Some time later we can render it. This is only done if we set renderOnInit to false.
* // If true it will render on initialization.
* textareaInstance.init();
* }
*
*/
export default class Textarea {
constructor( options = {} ) {
this.options = {};
Object.assign(
this.options,
{
customAttributes: {},
customClasses: [],
helpText: '',
id: '',
label: '',
labelCustomAttributes: {},
labelCustomClasses: [],
labelVisible: true,
placeholder: '',
rendered: false,
renderOnInit: true,
spacing: '',
target: '',
targetPosition: 'afterbegin',
theme: 'cosmos',
value: '',
wrapperCustomAttributes: {},
wrapperCustomClasses: [],
wrapperTagName: 'div',
},
options
);
/**
* @event gform/textarea/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/textarea/pre_init', native: false, data: { instance: this } } );
this.options.id = this.options.id || uniqueId( 'textarea' );
this.elements = {};
if ( this.options.renderOnInit ) {
this.init();
}
}
/**
* @memberof Textarea
* @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,
textareaTemplate( this.options )
);
}
this.elements.textarea = getNode( `#${ this.options.id }`, document, true );
this.elements.wrapper = this.elements.textarea.parentNode;
}
/**
* @memberof Textarea
* @description Initialize the component.
*
* @fires gform/textarea/post_render
*
* @since 1.1.16
*
* @return {void}
*/
init() {
this.render();
/**
* @event gform/textarea/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/textarea/post_render', native: false, data: { instance: this } } );
consoleInfo( `Gravity Forms Admin: Initialized textarea component.` );
}
}