PushMenu.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. /**
  2. * --------------------------------------------
  3. * AdminLTE PushMenu.js
  4. * License MIT
  5. * --------------------------------------------
  6. */
  7. import $ from 'jquery'
  8. /**
  9. * Constants
  10. * ====================================================
  11. */
  12. const NAME = 'PushMenu'
  13. const DATA_KEY = 'lte.pushmenu'
  14. const EVENT_KEY = `.${DATA_KEY}`
  15. const JQUERY_NO_CONFLICT = $.fn[NAME]
  16. const EVENT_COLLAPSED = `collapsed${EVENT_KEY}`
  17. const EVENT_SHOWN = `shown${EVENT_KEY}`
  18. const SELECTOR_TOGGLE_BUTTON = '[data-widget="pushmenu"]'
  19. const SELECTOR_BODY = 'body'
  20. const SELECTOR_OVERLAY = '#sidebar-overlay'
  21. const SELECTOR_WRAPPER = '.wrapper'
  22. const CLASS_NAME_COLLAPSED = 'sidebar-collapse'
  23. const CLASS_NAME_OPEN = 'sidebar-open'
  24. const CLASS_NAME_IS_OPENING = 'sidebar-is-opening'
  25. const CLASS_NAME_CLOSED = 'sidebar-closed'
  26. const Default = {
  27. autoCollapseSize: 992,
  28. enableRemember: false,
  29. noTransitionAfterReload: true
  30. }
  31. /**
  32. * Class Definition
  33. * ====================================================
  34. */
  35. class PushMenu {
  36. constructor(element, options) {
  37. this._element = element
  38. this._options = $.extend({}, Default, options)
  39. if ($(SELECTOR_OVERLAY).length === 0) {
  40. this._addOverlay()
  41. }
  42. this._init()
  43. }
  44. // Public
  45. expand() {
  46. const $bodySelector = $(SELECTOR_BODY)
  47. if (this._options.autoCollapseSize && $(window).width() <= this._options.autoCollapseSize) {
  48. $bodySelector.addClass(CLASS_NAME_OPEN)
  49. }
  50. $bodySelector.addClass(CLASS_NAME_IS_OPENING).removeClass(`${CLASS_NAME_COLLAPSED} ${CLASS_NAME_CLOSED}`).delay(50).queue(function () {
  51. $bodySelector.removeClass(CLASS_NAME_IS_OPENING)
  52. $(this).dequeue()
  53. })
  54. if (this._options.enableRemember) {
  55. localStorage.setItem(`remember${EVENT_KEY}`, CLASS_NAME_OPEN)
  56. }
  57. $(this._element).trigger($.Event(EVENT_SHOWN))
  58. }
  59. collapse() {
  60. const $bodySelector = $(SELECTOR_BODY)
  61. if (this._options.autoCollapseSize && $(window).width() <= this._options.autoCollapseSize) {
  62. $bodySelector.removeClass(CLASS_NAME_OPEN).addClass(CLASS_NAME_CLOSED)
  63. }
  64. $bodySelector.addClass(CLASS_NAME_COLLAPSED)
  65. if (this._options.enableRemember) {
  66. localStorage.setItem(`remember${EVENT_KEY}`, CLASS_NAME_COLLAPSED)
  67. }
  68. $(this._element).trigger($.Event(EVENT_COLLAPSED))
  69. }
  70. toggle() {
  71. if ($(SELECTOR_BODY).hasClass(CLASS_NAME_COLLAPSED)) {
  72. this.expand()
  73. } else {
  74. this.collapse()
  75. }
  76. }
  77. autoCollapse(resize = false) {
  78. if (!this._options.autoCollapseSize) {
  79. return
  80. }
  81. const $bodySelector = $(SELECTOR_BODY)
  82. if ($(window).width() <= this._options.autoCollapseSize) {
  83. if (!$bodySelector.hasClass(CLASS_NAME_OPEN)) {
  84. this.collapse()
  85. }
  86. } else if (resize === true) {
  87. if ($bodySelector.hasClass(CLASS_NAME_OPEN)) {
  88. $bodySelector.removeClass(CLASS_NAME_OPEN)
  89. } else if ($bodySelector.hasClass(CLASS_NAME_CLOSED)) {
  90. this.expand()
  91. }
  92. }
  93. }
  94. remember() {
  95. if (!this._options.enableRemember) {
  96. return
  97. }
  98. const $body = $('body')
  99. const toggleState = localStorage.getItem(`remember${EVENT_KEY}`)
  100. if (toggleState === CLASS_NAME_COLLAPSED) {
  101. if (this._options.noTransitionAfterReload) {
  102. $body.addClass('hold-transition').addClass(CLASS_NAME_COLLAPSED).delay(50).queue(function () {
  103. $(this).removeClass('hold-transition')
  104. $(this).dequeue()
  105. })
  106. } else {
  107. $body.addClass(CLASS_NAME_COLLAPSED)
  108. }
  109. } else if (this._options.noTransitionAfterReload) {
  110. $body.addClass('hold-transition').removeClass(CLASS_NAME_COLLAPSED).delay(50).queue(function () {
  111. $(this).removeClass('hold-transition')
  112. $(this).dequeue()
  113. })
  114. } else {
  115. $body.removeClass(CLASS_NAME_COLLAPSED)
  116. }
  117. }
  118. // Private
  119. _init() {
  120. this.remember()
  121. this.autoCollapse()
  122. $(window).resize(() => {
  123. this.autoCollapse(true)
  124. })
  125. }
  126. _addOverlay() {
  127. const overlay = $('<div />', {
  128. id: 'sidebar-overlay'
  129. })
  130. overlay.on('click', () => {
  131. this.collapse()
  132. })
  133. $(SELECTOR_WRAPPER).append(overlay)
  134. }
  135. // Static
  136. static _jQueryInterface(operation) {
  137. return this.each(function () {
  138. let data = $(this).data(DATA_KEY)
  139. const _options = $.extend({}, Default, $(this).data())
  140. if (!data) {
  141. data = new PushMenu(this, _options)
  142. $(this).data(DATA_KEY, data)
  143. }
  144. if (typeof operation === 'string' && operation.match(/collapse|expand|toggle/)) {
  145. data[operation]()
  146. }
  147. })
  148. }
  149. }
  150. /**
  151. * Data API
  152. * ====================================================
  153. */
  154. $(document).on('click', SELECTOR_TOGGLE_BUTTON, event => {
  155. event.preventDefault()
  156. let button = event.currentTarget
  157. if ($(button).data('widget') !== 'pushmenu') {
  158. button = $(button).closest(SELECTOR_TOGGLE_BUTTON)
  159. }
  160. PushMenu._jQueryInterface.call($(button), 'toggle')
  161. })
  162. $(window).on('load', () => {
  163. PushMenu._jQueryInterface.call($(SELECTOR_TOGGLE_BUTTON))
  164. })
  165. /**
  166. * jQuery API
  167. * ====================================================
  168. */
  169. $.fn[NAME] = PushMenu._jQueryInterface
  170. $.fn[NAME].Constructor = PushMenu
  171. $.fn[NAME].noConflict = function () {
  172. $.fn[NAME] = JQUERY_NO_CONFLICT
  173. return PushMenu._jQueryInterface
  174. }
  175. export default PushMenu