PushMenu.js 4.9 KB

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