mirror of
https://github.com/mdbootstrap/mdb-ui-kit.git
synced 2024-11-22 17:47:11 +03:00
175 lines
4.6 KiB
JavaScript
175 lines
4.6 KiB
JavaScript
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;
|
|
}
|
|
|
|
|
|
$(".bmd-layout-drawer").hide();
|
|
this.$element.show();
|
|
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;
|