Skip to content

Instantly share code, notes, and snippets.

@laurisstepanovs
Created April 21, 2024 17:49
Show Gist options
  • Save laurisstepanovs/d25c374840bfc835275065f3ec1b12e8 to your computer and use it in GitHub Desktop.
Save laurisstepanovs/d25c374840bfc835275065f3ec1b12e8 to your computer and use it in GitHub Desktop.
import {
getAttributeValueByBreakpoint,
stringSnakeToCamel,
getObjectPropertyValueByKey,
EventHandlerUtil,
throttle,
} from '../_utils/index'
export class SwapperStore {
static store: Map<string, SwapperComponent> = new Map()
public static set(instanceId: string, drawerComponentObj: SwapperComponent): void {
if (SwapperStore.has(instanceId)) {
return
}
SwapperStore.store.set(instanceId, drawerComponentObj)
}
public static get(instanceId: string): SwapperComponent | undefined {
if (!SwapperStore.has(instanceId)) {
return
}
return SwapperStore.store.get(instanceId)
}
public static remove(instanceId: string): void {
if (!SwapperStore.has(instanceId)) {
return
}
SwapperStore.store.delete(instanceId)
}
public static has(instanceId: string): boolean {
return SwapperStore.store.has(instanceId)
}
public static getAllInstances() {
return SwapperStore.store
}
}
export interface ISwapperOptions {
mode: string
}
export interface ISwapperQueries {
componentName: string
instanseQuery: string
attrQuery: string
}
const defaultSwapperOptions: ISwapperOptions = {
mode: 'append',
}
const defaultSwapperQueires: ISwapperQueries = {
componentName: 'swapper',
instanseQuery: '[data-kt-swapper="true"]',
attrQuery: 'data-kt-swapper-',
}
class SwapperComponent {
element: HTMLElement
options: ISwapperOptions
queries: ISwapperQueries
constructor(_element: HTMLElement, _options: ISwapperOptions, _queries: ISwapperQueries) {
this.element = _element
this.options = Object.assign(defaultSwapperOptions, _options)
this.queries = _queries
// Initial update
this.update()
SwapperStore.set(this.element.id, this)
}
private getOption(name: string) {
const attr = this.element.getAttribute(`${this.queries.attrQuery}${name}`)
if (attr) {
const value = getAttributeValueByBreakpoint(attr)
if (attr != null && String(value) === 'true') {
return true
} else if (value !== null && String(value) === 'false') {
return false
}
return value
} else {
const optionName = stringSnakeToCamel(name)
const option = getObjectPropertyValueByKey(this.options, optionName)
if (option) {
return getAttributeValueByBreakpoint(option)
} else {
return null
}
}
}
///////////////////////
// ** Public API ** //
///////////////////////
public update = () => {
const parentSelector = this.getOption('parent')?.toString()
const mode = this.getOption('mode')
const parentElement = parentSelector ? document.querySelector(parentSelector) : null
if (parentElement && this.element.parentNode !== parentElement) {
const alreadyPended = parentElement.querySelector(this.element.id) !== null;
if (!alreadyPended) {
if (mode === 'prepend') {
parentElement.prepend(this.element)
} else if (mode === 'append') {
parentElement.append(this.element)
}
}
}
}
// Event API
public on = (name: string, handler: Function) => {
return EventHandlerUtil.on(this.element, name, handler)
}
public one = (name: string, handler: Function) => {
return EventHandlerUtil.one(this.element, name, handler)
}
public off = (name: string, handlerId: string) => {
return EventHandlerUtil.off(this.element, name, handlerId)
}
public trigger = (name: string, event: Event) => {
return EventHandlerUtil.trigger(this.element, name, event)
}
// Static methods
public static getInstance = (
el: HTMLElement,
componentName: string = defaultSwapperQueires.componentName
): SwapperComponent | null => {
const place = SwapperStore.get(el.id)
if (place) {
return place as SwapperComponent
}
return null
}
public static createInstances = (
selector: string = defaultSwapperQueires.instanseQuery,
options: ISwapperOptions = defaultSwapperOptions,
queries: ISwapperQueries = defaultSwapperQueires
) => {
const elements = document.body.querySelectorAll(selector)
elements.forEach((el) => {
const item = el as HTMLElement
let place = SwapperComponent.getInstance(item)
if (!place) {
place = new SwapperComponent(item, options, queries)
}
})
}
public static createInsance = (
selector: string = defaultSwapperQueires.instanseQuery,
options: ISwapperOptions = defaultSwapperOptions,
queries: ISwapperQueries = defaultSwapperQueires
): SwapperComponent | undefined => {
const element = document.body.querySelector(selector)
if (!element) {
return
}
const item = element as HTMLElement
let place = SwapperComponent.getInstance(item)
if (!place) {
place = new SwapperComponent(item, options, queries)
}
return place
}
public static bootstrap = (selector: string = defaultSwapperQueires.instanseQuery) => {
SwapperComponent.createInstances(selector)
}
public static reinitialization = (selector: string = defaultSwapperQueires.instanseQuery) => {
SwapperComponent.createInstances(selector)
}
}
// Window resize handler
window.addEventListener('resize', function () {
let timer
throttle(
timer,
() => {
// Locate and update Offcanvas instances on window resize
const elements = document.querySelectorAll(defaultSwapperQueires.instanseQuery)
elements.forEach((el) => {
const place = SwapperComponent.getInstance(el as HTMLElement)
if (place) {
place.update()
}
})
},
200
)
})
export {SwapperComponent, defaultSwapperOptions, defaultSwapperQueires}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment