PushMenu.js 5.6 KB

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