diff options
Diffstat (limited to 'templates/assets/bootstrap-material-design/js/drawer.js')
| -rw-r--r-- | templates/assets/bootstrap-material-design/js/drawer.js | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/templates/assets/bootstrap-material-design/js/drawer.js b/templates/assets/bootstrap-material-design/js/drawer.js new file mode 100644 index 0000000..ef0586e --- /dev/null +++ b/templates/assets/bootstrap-material-design/js/drawer.js @@ -0,0 +1,170 @@ +import BaseLayout from './baseLayout' + +const Drawer = (($) => { + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + const NAME = 'drawer' + const DATA_KEY = `bmd.${NAME}` + const JQUERY_NAME = `bmd${NAME.charAt(0).toUpperCase() + NAME.slice(1)}` + const JQUERY_NO_CONFLICT = $.fn[JQUERY_NAME] + + const Keycodes = { + ESCAPE: 27 + //ENTER: 13, + //SPACE: 32 + } + + const ClassName = { + IN: 'in', + DRAWER_IN: `bmd-drawer-in`, + DRAWER_OUT: `bmd-drawer-out`, + DRAWER: 'bmd-layout-drawer', + CONTAINER: 'bmd-layout-container' + } + + const Default = { + focusSelector: `a, button, input` + } + + /** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + class Drawer extends BaseLayout { + + // $element is expected to be the trigger + // i.e. <button class="btn bmd-btn-icon" for="search" data-toggle="drawer" data-target="#my-side-nav-drawer" aria-expanded="false" aria-controls="my-side-nav-drawer"> + constructor($element, config) { + super($element, $.extend(true, {}, Default, config)) + + this.$toggles = $(`[data-toggle="drawer"][href="#${this.$element[0].id}"], [data-toggle="drawer"][data-target="#${this.$element[0].id}"]`) + + this._addAria() + + // click or escape on the backdrop closes the drawer + this.$backdrop.keydown((ev) => { + if (ev.which === Keycodes.ESCAPE) { + this.hide() + } + }).click(() => { + this.hide() + }) + + // escape on the drawer closes it + this.$element.keydown((ev) => { + if (ev.which === Keycodes.ESCAPE) { + this.hide() + } + }) + + // any toggle button clicks + this.$toggles.click(() => { + this.toggle() + }) + } + + dispose() { + super.dispose(DATA_KEY) + this.$toggles = null + } + + toggle() { + if (this._isOpen()) { + this.hide() + } else { + this.show() + } + } + + show() { + if (this._isForcedClosed() || this._isOpen()) { + return + } + + this.$toggles.attr('aria-expanded', true) + this.$element.attr('aria-expanded', true) + this.$element.attr('aria-hidden', false) + + // focus on the first focusable item + let $focusOn = this.$element.find(this.config.focusSelector) + if ($focusOn.length > 0) { + $focusOn.first().focus() + } + + this.$container.addClass(ClassName.DRAWER_IN) + // backdrop is responsively styled based on bmd-drawer-overlay, therefore style is none of our concern, simply add the marker class and let the scss determine if it should be displayed or not. + this.$backdrop.addClass(ClassName.IN) + } + + hide() { + if (!this._isOpen()) { + return + } + + this.$toggles.attr('aria-expanded', false) + this.$element.attr('aria-expanded', false) + this.$element.attr('aria-hidden', true) + + this.$container.removeClass(ClassName.DRAWER_IN) + this.$backdrop.removeClass(ClassName.IN) + } + + + // ------------------------------------------------------------------------ + // private + + _isOpen() { + return this.$container.hasClass(ClassName.DRAWER_IN) + } + + _isForcedClosed() { + return this.$container.hasClass(ClassName.DRAWER_OUT) + } + + _addAria() { + let isOpen = this._isOpen() + this.$element.attr('aria-expanded', isOpen) + this.$element.attr('aria-hidden', isOpen) + + if (this.$toggles.length) { + this.$toggles.attr('aria-expanded', isOpen) + } + } + + // ------------------------------------------------------------------------ + // static + static _jQueryInterface(config) { + return this.each(function () { + let $element = $(this) + let data = $element.data(DATA_KEY) + + if (!data) { + data = new Drawer($element, config) + $element.data(DATA_KEY, data) + } + }) + } + } + + /** + * ------------------------------------------------------------------------ + * jQuery + * ------------------------------------------------------------------------ + */ + $.fn[JQUERY_NAME] = Drawer._jQueryInterface + $.fn[JQUERY_NAME].Constructor = Drawer + $.fn[JQUERY_NAME].noConflict = () => { + $.fn[JQUERY_NAME] = JQUERY_NO_CONFLICT + return Drawer._jQueryInterface + } + + return Drawer + +})(jQuery) + +export default Drawer |
