PushMenu.js 5.1 KB

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