flyonui
Version:
The easiest, free and open-source Tailwind CSS component library with semantic classes.
118 lines (88 loc) • 3.65 kB
text/typescript
/*
* HSRemoveElement
* @version: 3.0.1
* @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 { afterTransition } from '../../utils'
import { IRemoveElement, IRemoveElementOptions } from '../remove-element/interfaces'
import { ICollectionItem } from '../../interfaces'
import HSBasePlugin from '../base-plugin'
class HSRemoveElement extends HSBasePlugin<IRemoveElementOptions> implements IRemoveElement {
private readonly removeTargetId: string | null
private readonly removeTarget: HTMLElement | null
private readonly removeTargetAnimationClass: string
private onElementClickListener: () => void
constructor(el: HTMLElement, options?: IRemoveElementOptions) {
super(el, options)
const data = el.getAttribute('data-remove-element-options')
const dataOptions: IRemoveElementOptions = data ? JSON.parse(data) : {}
const concatOptions = {
...dataOptions,
...options
}
this.removeTargetId = this.el.getAttribute('data-remove-element')
this.removeTarget = document.querySelector(this.removeTargetId)
this.removeTargetAnimationClass = concatOptions?.removeTargetAnimationClass || 'removing'
if (this.removeTarget) this.init()
}
private elementClick() {
this.remove()
}
private init() {
this.createCollection(window.$hsRemoveElementCollection, this)
this.onElementClickListener = () => this.elementClick()
this.el.addEventListener('click', this.onElementClickListener)
}
private remove() {
if (!this.removeTarget) return false
this.removeTarget.classList.add(this.removeTargetAnimationClass)
afterTransition(this.removeTarget, () => setTimeout(() => this.removeTarget.remove()))
}
// Public methods
public destroy() {
// Remove classes
this.removeTarget.classList.remove(this.removeTargetAnimationClass)
// Remove listeners
this.el.removeEventListener('click', this.onElementClickListener)
window.$hsRemoveElementCollection = window.$hsRemoveElementCollection.filter(
({ element }) => element.el !== this.el
)
}
// Static method
static getInstance(target: HTMLElement, isInstance?: boolean) {
const elInCollection = window.$hsRemoveElementCollection.find(
el =>
el.element.el === (typeof target === 'string' ? document.querySelector(target) : target) ||
el.element.el === (typeof target === 'string' ? document.querySelector(target) : target)
)
return elInCollection ? (isInstance ? elInCollection : elInCollection.element.el) : null
}
static autoInit() {
if (!window.$hsRemoveElementCollection) window.$hsRemoveElementCollection = []
if (window.$hsRemoveElementCollection)
window.$hsRemoveElementCollection = window.$hsRemoveElementCollection.filter(({ element }) =>
document.contains(element.el)
)
document.querySelectorAll('[data-remove-element]:not(.--prevent-on-load-init)').forEach((el: HTMLElement) => {
if (!window.$hsRemoveElementCollection.find(elC => (elC?.element?.el as HTMLElement) === el))
new HSRemoveElement(el)
})
}
}
declare global {
interface Window {
HSRemoveElement: Function
$hsRemoveElementCollection: ICollectionItem<HSRemoveElement>[]
}
}
window.addEventListener('load', () => {
HSRemoveElement.autoInit()
// Uncomment for debug
// console.log('Remove element collection:', window.$hsRemoveElementCollection);
})
if (typeof window !== 'undefined') {
window.HSRemoveElement = HSRemoveElement
}
export default HSRemoveElement