card-widget.ts 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. /**
  2. * --------------------------------------------
  3. * AdminLTE card-widget.js
  4. * License MIT
  5. * --------------------------------------------
  6. */
  7. import {
  8. domReady,
  9. slideUp,
  10. slideDown
  11. } from './util/index'
  12. /**
  13. * Constants
  14. * ====================================================
  15. */
  16. const CLASS_NAME_CARD = 'card'
  17. const CLASS_NAME_COLLAPSED = 'collapsed-card'
  18. const CLASS_NAME_COLLAPSING = 'collapsing-card'
  19. const CLASS_NAME_EXPANDING = 'expanding-card'
  20. const CLASS_NAME_WAS_COLLAPSED = 'was-collapsed'
  21. const CLASS_NAME_MAXIMIZED = 'maximized-card'
  22. const SELECTOR_DATA_REMOVE = '[data-lte-dismiss="card-remove"]'
  23. const SELECTOR_DATA_COLLAPSE = '[data-lte-toggle="card-collapse"]'
  24. const SELECTOR_DATA_MAXIMIZE = '[data-lte-toggle="card-maximize"]'
  25. const SELECTOR_CARD = `.${CLASS_NAME_CARD}`
  26. const SELECTOR_CARD_HEADER = '.card-header'
  27. const SELECTOR_CARD_BODY = '.card-body'
  28. const SELECTOR_CARD_FOOTER = '.card-footer'
  29. const Default = {
  30. animationSpeed: 500,
  31. collapseTrigger: SELECTOR_DATA_COLLAPSE,
  32. removeTrigger: SELECTOR_DATA_REMOVE,
  33. maximizeTrigger: SELECTOR_DATA_MAXIMIZE,
  34. collapseIcon: 'fa-minus',
  35. expandIcon: 'fa-plus',
  36. maximizeIcon: 'fa-expand',
  37. minimizeIcon: 'fa-compress'
  38. }
  39. interface Config {
  40. animationSpeed: number;
  41. collapseTrigger: string;
  42. removeTrigger: string;
  43. maximizeTrigger: string;
  44. collapseIcon: string;
  45. expandIcon: string;
  46. maximizeIcon: string;
  47. minimizeIcon: string;
  48. }
  49. class CardWidget {
  50. _element: HTMLElement
  51. _parent: HTMLElement | null
  52. _config: Config
  53. constructor(element: HTMLElement, config: Config) {
  54. this._element = element
  55. this._parent = element.closest(SELECTOR_CARD)
  56. if (element.classList.contains(CLASS_NAME_CARD)) {
  57. this._parent = element
  58. }
  59. this._config = Object.assign({}, Default, config)
  60. }
  61. collapse() {
  62. this._parent?.classList.add(CLASS_NAME_COLLAPSING)
  63. const elm = this._parent?.querySelectorAll(`${SELECTOR_CARD_BODY}, ${SELECTOR_CARD_FOOTER}`)
  64. if (elm !== undefined) {
  65. for (const el of elm) {
  66. if (el instanceof HTMLElement) {
  67. slideUp(el, this._config.animationSpeed)
  68. }
  69. }
  70. }
  71. setTimeout(() => {
  72. this._parent?.classList.add(CLASS_NAME_COLLAPSED)
  73. this._parent?.classList.remove(CLASS_NAME_COLLAPSING)
  74. }, this._config.animationSpeed)
  75. const icon = this._parent?.querySelector(`${SELECTOR_CARD_HEADER} ${this._config.collapseTrigger} .${this._config.collapseIcon}`)
  76. icon?.classList.add(this._config.expandIcon)
  77. icon?.classList.remove(this._config.collapseIcon)
  78. }
  79. expand() {
  80. this._parent?.classList.add(CLASS_NAME_EXPANDING)
  81. const elm = this._parent?.querySelectorAll(`${SELECTOR_CARD_BODY}, ${SELECTOR_CARD_FOOTER}`)
  82. if (elm !== undefined) {
  83. for (const el of elm) {
  84. if (el instanceof HTMLElement) {
  85. slideDown(el, this._config.animationSpeed)
  86. }
  87. }
  88. }
  89. setTimeout(() => {
  90. this._parent?.classList.remove(CLASS_NAME_COLLAPSED)
  91. this._parent?.classList.remove(CLASS_NAME_EXPANDING)
  92. }, this._config.animationSpeed)
  93. const icon = this._parent?.querySelector(`${SELECTOR_CARD_HEADER} ${this._config.collapseTrigger} .${this._config.expandIcon}`)
  94. icon?.classList.add(this._config.collapseIcon)
  95. icon?.classList.remove(this._config.expandIcon)
  96. }
  97. remove() {
  98. if (this._parent) {
  99. slideUp(this._parent, this._config.animationSpeed)
  100. }
  101. }
  102. toggle() {
  103. if (this._parent?.classList.contains(CLASS_NAME_COLLAPSED)) {
  104. this.expand()
  105. return
  106. }
  107. this.collapse()
  108. }
  109. maximize() {
  110. if (this._parent) {
  111. const maxElm = this._parent.querySelector(`${this._config.maximizeTrigger} .${this._config.maximizeIcon}`)
  112. maxElm?.classList.add(this._config.minimizeIcon)
  113. maxElm?.classList.remove(this._config.maximizeIcon)
  114. this._parent.style.height = `${this._parent.scrollHeight}px`
  115. this._parent.style.width = `${this._parent.scrollWidth}px`
  116. this._parent.style.transition = 'all .15s'
  117. setTimeout(() => {
  118. document.querySelector('html')?.classList.add(CLASS_NAME_MAXIMIZED)
  119. this._parent?.classList.add(CLASS_NAME_MAXIMIZED)
  120. if (this._parent?.classList.contains(CLASS_NAME_COLLAPSED)) {
  121. this._parent.classList.add(CLASS_NAME_WAS_COLLAPSED)
  122. }
  123. }, 150)
  124. }
  125. }
  126. minimize() {
  127. if (this._parent) {
  128. const minElm = this._parent.querySelector(`${this._config.maximizeTrigger} .${this._config.minimizeIcon}`)
  129. minElm?.classList.add(this._config.maximizeIcon)
  130. minElm?.classList.remove(this._config.minimizeIcon)
  131. this._parent.style.cssText = `height: ${this._parent.style.height} !important; width: ${this._parent.style.width} !important; transition: all .15s;`
  132. // console.log('🚀 ~ file: card-widget.ts ~ line 164 ~ CardWidget ~ minimize ~ this._parent.style.height', this._parent.style.height)
  133. setTimeout(() => {
  134. document.querySelector('html')?.classList.remove(CLASS_NAME_MAXIMIZED)
  135. if (this._parent) {
  136. this._parent.classList.remove(CLASS_NAME_MAXIMIZED)
  137. if (this._parent?.classList.contains(CLASS_NAME_WAS_COLLAPSED)) {
  138. this._parent.classList.remove(CLASS_NAME_WAS_COLLAPSED)
  139. }
  140. }
  141. }, 10)
  142. }
  143. }
  144. toggleMaximize() {
  145. if (this._parent?.classList.contains(CLASS_NAME_MAXIMIZED)) {
  146. this.minimize()
  147. return
  148. }
  149. this.maximize()
  150. }
  151. }
  152. /**
  153. *
  154. * Data Api implementation
  155. * ====================================================
  156. */
  157. domReady(() => {
  158. const collapseBtn = document.querySelectorAll(SELECTOR_DATA_COLLAPSE)
  159. for (const btn of collapseBtn) {
  160. btn.addEventListener('click', event => {
  161. event.preventDefault()
  162. const target = event.target as HTMLElement
  163. const data = new CardWidget(target, Default)
  164. data.toggle()
  165. })
  166. }
  167. const removeBtn = document.querySelectorAll(SELECTOR_DATA_REMOVE)
  168. for (const btn of removeBtn) {
  169. btn.addEventListener('click', event => {
  170. event.preventDefault()
  171. const target = event.target as HTMLElement
  172. const data = new CardWidget(target, Default)
  173. data.remove()
  174. })
  175. }
  176. const maxBtn = document.querySelectorAll(SELECTOR_DATA_MAXIMIZE)
  177. for (const btn of maxBtn) {
  178. btn.addEventListener('click', event => {
  179. event.preventDefault()
  180. const target = event.target as HTMLElement
  181. const data = new CardWidget(target, Default)
  182. data.toggleMaximize()
  183. })
  184. }
  185. })
  186. export default CardWidget