/** * -------------------------------------------- * AdminLTE card-widget.ts * License MIT * -------------------------------------------- */ import { domReady, slideUp, slideDown } from './util/index' /** * Constants * ==================================================== */ const CLASS_NAME_CARD = 'card' const CLASS_NAME_COLLAPSED = 'collapsed-card' const CLASS_NAME_COLLAPSING = 'collapsing-card' const CLASS_NAME_EXPANDING = 'expanding-card' const CLASS_NAME_WAS_COLLAPSED = 'was-collapsed' const CLASS_NAME_MAXIMIZED = 'maximized-card' const SELECTOR_DATA_REMOVE = '[data-lte-dismiss="card-remove"]' const SELECTOR_DATA_COLLAPSE = '[data-lte-toggle="card-collapse"]' const SELECTOR_DATA_MAXIMIZE = '[data-lte-toggle="card-maximize"]' const SELECTOR_CARD = `.${CLASS_NAME_CARD}` const SELECTOR_CARD_HEADER = '.card-header' const SELECTOR_CARD_BODY = '.card-body' const SELECTOR_CARD_FOOTER = '.card-footer' const Default = { animationSpeed: 500, collapseTrigger: SELECTOR_DATA_COLLAPSE, removeTrigger: SELECTOR_DATA_REMOVE, maximizeTrigger: SELECTOR_DATA_MAXIMIZE, collapseIcon: 'fa-minus', expandIcon: 'fa-plus', maximizeIcon: 'fa-expand', minimizeIcon: 'fa-compress' } interface Config { animationSpeed: number; collapseTrigger: string; removeTrigger: string; maximizeTrigger: string; collapseIcon: string; expandIcon: string; maximizeIcon: string; minimizeIcon: string; } class CardWidget { _element: HTMLElement _parent: HTMLElement | null _config: Config constructor(element: HTMLElement, config: Config) { this._element = element this._parent = element.closest(SELECTOR_CARD) if (element.classList.contains(CLASS_NAME_CARD)) { this._parent = element } this._config = { ...Default, ...config } } collapse() { if (this._parent) { this._parent.classList.add(CLASS_NAME_COLLAPSING) const elm = this._parent?.querySelectorAll(`${SELECTOR_CARD_BODY}, ${SELECTOR_CARD_FOOTER}`) if (elm !== undefined) { for (const el of elm) { if (el instanceof HTMLElement) { slideUp(el, this._config.animationSpeed) } } } setTimeout(() => { if (this._parent) { this._parent.classList.add(CLASS_NAME_COLLAPSED) this._parent.classList.remove(CLASS_NAME_COLLAPSING) } }, this._config.animationSpeed) } const icon = this._parent?.querySelector(`${SELECTOR_CARD_HEADER} ${this._config.collapseTrigger} .${this._config.collapseIcon}`) if (icon) { icon.classList.remove(this._config.collapseIcon) icon.classList.add(this._config.expandIcon) } } expand() { if (this._parent) { this._parent.classList.add(CLASS_NAME_EXPANDING) const elm = this._parent?.querySelectorAll(`${SELECTOR_CARD_BODY}, ${SELECTOR_CARD_FOOTER}`) if (elm !== undefined) { for (const el of elm) { if (el instanceof HTMLElement) { slideDown(el, this._config.animationSpeed) } } } setTimeout(() => { if (this._parent) { this._parent.classList.remove(CLASS_NAME_COLLAPSED) this._parent.classList.remove(CLASS_NAME_EXPANDING) } }, this._config.animationSpeed) } const icon = this._parent?.querySelector(`${SELECTOR_CARD_HEADER} ${this._config.collapseTrigger} .${this._config.expandIcon}`) if (icon) { icon.classList.add(this._config.collapseIcon) icon.classList.remove(this._config.expandIcon) } } remove() { if (this._parent) { slideUp(this._parent, this._config.animationSpeed) } } toggle() { if (this._parent?.classList.contains(CLASS_NAME_COLLAPSED)) { this.expand() return } this.collapse() } maximize() { if (this._parent) { const maxElm = this._parent.querySelector(`${this._config.maximizeTrigger} .${this._config.maximizeIcon}`) if (maxElm) { maxElm.classList.add(this._config.minimizeIcon) maxElm.classList.remove(this._config.maximizeIcon) } this._parent.style.height = `${this._parent.scrollHeight}px` this._parent.style.width = `${this._parent.scrollWidth}px` this._parent.style.transition = 'all .15s' setTimeout(() => { const htmlTag = document.querySelector('html') if (htmlTag) { htmlTag.classList.add(CLASS_NAME_MAXIMIZED) } if (this._parent) { this._parent.classList.add(CLASS_NAME_MAXIMIZED) if (this._parent.classList.contains(CLASS_NAME_COLLAPSED)) { this._parent.classList.add(CLASS_NAME_WAS_COLLAPSED) } } }, 150) } } minimize() { if (this._parent) { const minElm = this._parent.querySelector(`${this._config.maximizeTrigger} .${this._config.minimizeIcon}`) if (minElm) { minElm.classList.add(this._config.maximizeIcon) minElm.classList.remove(this._config.minimizeIcon) } this._parent.style.cssText = `height: ${this._parent.style.height} !important; width: ${this._parent.style.width} !important; transition: all .15s;` setTimeout(() => { const htmlTag = document.querySelector('html') if (htmlTag) { htmlTag.classList.remove(CLASS_NAME_MAXIMIZED) } if (this._parent) { this._parent.classList.remove(CLASS_NAME_MAXIMIZED) if (this._parent?.classList.contains(CLASS_NAME_WAS_COLLAPSED)) { this._parent.classList.remove(CLASS_NAME_WAS_COLLAPSED) } } }, 10) } } toggleMaximize() { if (this._parent?.classList.contains(CLASS_NAME_MAXIMIZED)) { this.minimize() return } this.maximize() } } /** * * Data Api implementation * ==================================================== */ domReady(() => { const collapseBtn = document.querySelectorAll(SELECTOR_DATA_COLLAPSE) for (const btn of collapseBtn) { btn.addEventListener('click', event => { event.preventDefault() const target = event.target as HTMLElement const data = new CardWidget(target, Default) data.toggle() }) } const removeBtn = document.querySelectorAll(SELECTOR_DATA_REMOVE) for (const btn of removeBtn) { btn.addEventListener('click', event => { event.preventDefault() const target = event.target as HTMLElement const data = new CardWidget(target, Default) data.remove() }) } const maxBtn = document.querySelectorAll(SELECTOR_DATA_MAXIMIZE) for (const btn of maxBtn) { btn.addEventListener('click', event => { event.preventDefault() const target = event.target as HTMLElement const data = new CardWidget(target, Default) data.toggleMaximize() }) } }) export default CardWidget