UNPKG

@hellotext/hellotext

Version:
210 lines (169 loc) 4.87 kB
/** * @typedef {'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'} Placement * @description Valid placements for the webchat. */ /** * @enum {Placement} */ const placements = { TOP_LEFT: 'top-left', TOP_RIGHT: 'top-right', BOTTOM_LEFT: 'bottom-left', BOTTOM_RIGHT: 'bottom-right', } /** * @typedef {'absolute' | 'fixed'} Strategy * @description Valid strategies for the webchat. */ /** * @enum {Strategy} */ const strategies = { ABSOLUTE: 'absolute', FIXED: 'fixed', } /** * @typedef {'modal' | 'popover'} Behaviour */ /** * @enum {Behaviour} */ const behaviors = { MODAL: 'modal', POPOVER: 'popover', } /** * @typedef {Object} Style * @property {string} primaryColor - The primary webchat color (e.g., a hex code or color name). * @property {string} secondaryColor - The secondary webchat color or style (e.g., a hex code or color name). * @property {string} typography - The typography style (e.g., font family). */ /** * @class Webchat * @classdesc * Configuration for webchat * @property {String} id - the id of the webchat. * @property {String} container - the container to append the webchat to, defaults to 'body' * @property {Placement} placement - the placement of the webchat within the container, defaults to "bottom-right". * @property {String} classes - additional classes to apply to the webchat popup. * @property {String} triggerClasses - additional classes to apply to the webchat popup trigger. * @property {Behaviour} behaviour - the behaviour of the webchat, defaults to 'popover'. * @property {Style} style - the style of the webchat. * @property {Strategy} strategy - the strategy used to position the webchat. Defaults to 'absolute' */ class Webchat { static _id static _container = 'body' static _placement = 'bottom-right' static _classes = [] static _triggerClasses = [] static _style = {} static _behaviour = behaviors.POPOVER static _strategy = null static set container(value) { this._container = value } static get container() { return this._container } static set placement(value) { if (!Object.values(placements).includes(value)) { throw new Error(`Invalid placement value: ${value}`) } this._placement = value } static get placement() { return this._placement } static set classes(value) { if (!Array.isArray(value) && typeof value !== 'string') { throw new Error('classes must be an array or a string') } this._classes = value } static get classes() { if (typeof this._classes === 'string') { return this._classes.split(',').map(c => c.trim()) } else { return this._classes } } static set triggerClasses(value) { if (!Array.isArray(value) && typeof value !== 'string') { throw new Error('triggerClasses must be an array or a string') } this._triggerClasses = value } static get triggerClasses() { if (typeof this._triggerClasses === 'string') { return this._triggerClasses.split(',').map(c => c.trim()) } else { return this._triggerClasses } } static set id(value) { this._id = value } static get id() { return this._id } static get isSet() { return !!this._id } static get style() { return this._style } static set style(value) { if (typeof value !== 'object') { throw new Error('Style must be an object') } Object.entries(value).forEach(([key, value]) => { if (!['primaryColor', 'secondaryColor', 'typography'].includes(key)) { throw new Error(`Invalid style property: ${key}`) } if (key === 'typography') { return } if (!this.isHexOrRgba(value)) { throw new Error(`Invalid color value: ${value} for ${key}. Colors must be hex or rgb/a.`) } }) this._style = value } static get behaviour() { return this._behaviour } static set behaviour(value) { if (!Object.values(behaviors).includes(value)) { throw new Error(`Invalid behaviour value: ${value}`) } this._behaviour = value } static get strategy() { if (this._strategy) { return this._strategy } return this.container == 'body' ? strategies.FIXED : strategies.ABSOLUTE } static set strategy(value) { if (value && !Object.values(strategies).includes(value)) { throw new Error(`Invalid strategy value: ${value}`) } this._strategy = value } static assign(props) { if (props) { Object.entries(props).forEach(([key, value]) => { this[key] = value }) } return this } static isHexOrRgba(value) { return ( /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(value) || /^rgba?\(\s*\d{1,3},\s*\d{1,3},\s*\d{1,3},?\s*(0|1|0?\.\d+)?\s*\)$/.test(value) ) } } export { behaviors, Webchat }