1
0
mirror of https://github.com/dzeiocom/libs.git synced 2025-04-23 03:12:12 +00:00
libs/packages/dom-manager/src/DOMElement.ts
Florian Bouillon 916406560b Made Functions more clear
Signed-off-by: Florian Bouillon <florian.bouillon@delta-wings.net>
2020-12-08 16:07:50 +01:00

205 lines
4.8 KiB
TypeScript

type Tags = keyof HTMLElementTagNameMap
export default class DOMElement<T extends HTMLElement = HTMLElement> {
public item: T
public constructor(tagName: Tags | T, options?: ElementCreationOptions) {
if (tagName instanceof HTMLElement) {
this.item = tagName
return
}
this.item = document.createElement(tagName, options) as any
}
public static create<K extends Tags>(
tagName: K,
options?: ElementCreationOptions
): DOMElement<HTMLElementTagNameMap[K]>
public static create(
tagName: string,
options?: ElementCreationOptions
): DOMElement<HTMLElement> {
return new DOMElement(tagName as Tags, options)
}
public static get<GT extends HTMLElement = HTMLElement>(
query: string | GT,
source?: HTMLElement | DOMElement
): DOMElement<GT> | undefined {
if (!(query instanceof HTMLElement)) {
const tmp = (source instanceof DOMElement ? source.item : source || document).querySelector<GT>(query)
if (!tmp) {
return undefined
}
return new DOMElement(tmp)
}
return new DOMElement(query)
}
public on<K extends keyof HTMLElementEventMap>(
type: K,
listener: (this: T, ev: HTMLElementEventMap[K]) => void,
options?: boolean | AddEventListenerOptions
): this
public on(
type: string,
listener: (this: T, ev: Event) => void,
options?: boolean | AddEventListenerOptions
): this
public on(
type: string,
listener: (this: T, ev: Event) => void,
options?: boolean | AddEventListenerOptions
) {
this.item.addEventListener(type, listener, options)
return this
}
public off<K extends keyof HTMLElementEventMap>(
type: K,
listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => void
) {
this.item.removeEventListener(type, listener)
return this
}
public text(): string
public text(val: string): this
public text(val?: string) {
if (val) {
this.item.innerText = val
return this
}
return this.item.innerText
}
public html(): string
public html(val: string): this
public html(val?: string) {
if (val) {
this.item.innerHTML = val
return this
}
return this.item.innerText
}
public addClass(...classes: Array<string>) {
this.item.classList.add(...classes)
return this
}
public setClass(...classes: Array<string>) {
this.item.classList.forEach((cls) => {
if (!classes.includes(cls)) {
this.item.classList.remove(cls)
}
})
this.addClass(...classes)
return this
}
public classList(...classes: Array<string>): this
public classList(): Array<string>
public classList(...classes: Array<string>) {
if (!classes) {
const res: Array<string> = []
this.item.classList.forEach((el) => res.push(el))
return res
}
return this.setClass(...classes)
}
public toggleClass(...classes: Array<string>) {
for (const classe of classes) {
this.item.classList.toggle(classe)
}
return this
}
public removeClass(...classes: Array<string>) {
this.item.classList.remove(...classes)
return this
}
public emit<E extends keyof HTMLElementEventMap>(event: E): this
public emit(event: string): this
public emit(event: string): this {
if (event in this.item) {
(this.item as any)[event]()
return this
}
this.item.dispatchEvent(new Event(event))
return this
}
public attr(key: string): string | null
public attr(key: string, value: string | null): this
public attr(key: keyof T, value: boolean): this
public attr(key: string | keyof T, value?: string | boolean | null): this | string | null {
if (!value) {
return this.item.getAttribute(key as string)
}
if (value === null) {
this.item.removeAttribute(key as string)
return this
}
if (typeof value === 'boolean') {
this.item[key as 'draggable'] = value
return this
}
this.item.setAttribute(key as string, value)
return this
}
public data(key: string): string | null
public data(key: string, value: string | null): this
public data(key: string, value?: string | null): this | string | null {
// @ts-ignore
return this.attr(`data-${key}`, value)
}
public style(key: string, value?: string | number) {
if (typeof value === 'undefined') {
return this.item.style[key as any]
}
this.item.style[key as any] = value as string
return this
}
public exist() {
return !!this.item
}
public placeBefore(item: DOMElement | HTMLElement) {
if (item instanceof DOMElement) {
item = item.item
}
const parent = item.parentElement
if (!parent) {
throw new Error('can\'t place DOMElement before item because it has no parent')
}
parent.insertBefore(this.item, item)
return this
}
public placeAsChildOf(item: DOMElement | HTMLElement) {
if (item instanceof DOMElement) {
item = item.item
}
item.appendChild(this.item)
return this
}
public place(verb: 'before' | 'asChildOf', item: DOMElement | HTMLElement) {
if (verb === 'before') {
return this.placeBefore(item)
} else {
return this.placeAsChildOf(item)
}
}
}