UNPKG

flyonui

Version:

The easiest, free and open-source Tailwind CSS component library with semantic classes.

191 lines (149 loc) 5.83 kB
/* * HSTogglePassword * @version: 3.2.2 * @author: Preline Labs Ltd. * @license: Licensed under MIT and Preline UI Fair Use License (https://preline.co/docs/license.html) * Copyright 2024 Preline Labs Ltd. */ import { isFormElement, dispatch } from '../../utils' import { ITogglePasswordOptions, ITogglePassword } from './interfaces' import HSBasePlugin from '../base-plugin' import { ICollectionItem } from '../../interfaces' class HSTogglePassword extends HSBasePlugin<ITogglePasswordOptions> implements ITogglePassword { private readonly target: string | string[] | HTMLInputElement | HTMLInputElement[] | null private isShown: boolean private isMultiple: boolean private eventType: string private onElementActionListener: () => void constructor(el: HTMLElement, options?: ITogglePasswordOptions) { super(el, options) const data = el.getAttribute('data-toggle-password') const dataOptions: ITogglePasswordOptions = data ? JSON.parse(data) : {} const concatOptions = { ...dataOptions, ...options } const targets: HTMLInputElement[] = [] if (concatOptions?.target && typeof concatOptions?.target === 'string') { const ids = concatOptions?.target.split(',') ids.forEach(id => { targets.push(document.querySelector(id) as HTMLInputElement) }) } else if (concatOptions?.target && typeof concatOptions?.target === 'object') { ;(concatOptions.target as string[]).forEach(el => targets.push(document.querySelector(el))) } else { ;(concatOptions.target as HTMLInputElement[]).forEach(el => targets.push(el)) } this.target = targets this.isShown = this.el.hasAttribute('type') ? (this.el as HTMLInputElement).checked : false this.eventType = isFormElement(this.el) ? 'change' : 'click' this.isMultiple = this.target.length > 1 && !!this.el.closest('[data-toggle-password-group]') if (this.target) this.init() } private elementAction() { if (this.isShown) { this.hide() } else { this.show() } this.fireEvent('toggle', this.target) dispatch('toggle.toggle-select', this.el, this.target) } private init() { this.createCollection(window.$hsTogglePasswordCollection, this) if (!this.isShown) { this.hide() } else { this.show() } this.onElementActionListener = () => this.elementAction() this.el.addEventListener(this.eventType, this.onElementActionListener) } private getMultipleToggles(): HSTogglePassword[] { const group = this.el.closest('[data-toggle-password-group]') const toggles = group.querySelectorAll('[data-toggle-password]') const togglesInCollection: HSTogglePassword[] = [] toggles.forEach((el: HTMLElement) => { togglesInCollection.push(HSTogglePassword.getInstance(el) as HSTogglePassword) }) return togglesInCollection } // Public methods public show() { if (this.isMultiple) { const toggles = this.getMultipleToggles() toggles.forEach((el: HSTogglePassword) => (el ? (el.isShown = true) : false)) this.el.closest('[data-toggle-password-group]').classList.add('active') } else { this.isShown = true this.el.classList.add('active') } ;(this.target as HTMLInputElement[]).forEach(el => { ;(el as HTMLInputElement).type = 'text' }) } public hide() { if (this.isMultiple) { const toggles = this.getMultipleToggles() toggles.forEach((el: HSTogglePassword) => (el ? (el.isShown = false) : false)) this.el.closest('[data-toggle-password-group]').classList.remove('active') } else { this.isShown = false this.el.classList.remove('active') } ;(this.target as HTMLInputElement[]).forEach(el => { ;(el as HTMLInputElement).type = 'password' }) } public destroy() { // Remove classes if (this.isMultiple) { this.el.closest('[data-toggle-password-group]').classList.remove('active') } else { this.el.classList.remove('active') } // Remove attributes ;(this.target as HTMLInputElement[]).forEach(el => { ;(el as HTMLInputElement).type = 'password' }) // Remove listeners this.el.removeEventListener(this.eventType, this.onElementActionListener) this.isShown = false window.$hsTogglePasswordCollection = window.$hsTogglePasswordCollection.filter( ({ element }) => element.el !== this.el ) } // Static methods static getInstance(target: HTMLElement | string, isInstance?: boolean) { const elInCollection = window.$hsTogglePasswordCollection.find( el => el.element.el === (typeof target === 'string' ? document.querySelector(target) : target) ) return elInCollection ? (isInstance ? elInCollection : elInCollection.element) : null } static autoInit() { if (!window.$hsTogglePasswordCollection) window.$hsTogglePasswordCollection = [] if (window.$hsTogglePasswordCollection) window.$hsTogglePasswordCollection = window.$hsTogglePasswordCollection.filter(({ element }) => document.contains(element.el) ) document.querySelectorAll('[data-toggle-password]:not(.--prevent-on-load-init)').forEach((el: HTMLInputElement) => { if (!window.$hsTogglePasswordCollection.find(elC => (elC?.element?.el as HTMLElement) === el)) new HSTogglePassword(el) }) } } declare global { interface Window { HSTogglePassword: Function $hsTogglePasswordCollection: ICollectionItem<HSTogglePassword>[] } } window.addEventListener('load', () => { HSTogglePassword.autoInit() // Uncomment for debug // console.log('Toggle password collection:', window.$hsTogglePasswordCollection); }) if (typeof window !== 'undefined') { window.HSTogglePassword = HSTogglePassword } export default HSTogglePassword