2016-01-26 21:12:48 +03:00
import BaseLayout from './baseLayout'
const Drawer = ( ( $ ) => {
/ * *
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* Constants
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
const NAME = 'drawer'
2016-03-28 23:18:19 +03:00
const DATA _KEY = ` bmd. ${ NAME } `
const JQUERY _NAME = ` bmd ${ NAME . charAt ( 0 ) . toUpperCase ( ) + NAME . slice ( 1 ) } `
2016-01-26 21:12:48 +03:00
const JQUERY _NO _CONFLICT = $ . fn [ JQUERY _NAME ]
const Keycodes = {
ESCAPE : 27
//ENTER: 13,
//SPACE: 32
}
const ClassName = {
IN : 'in' ,
2016-03-21 17:56:51 +03:00
DRAWER _IN : ` bmd-drawer-in ` ,
DRAWER _OUT : ` bmd-drawer-out ` ,
DRAWER : 'bmd-layout-drawer' ,
CONTAINER : 'bmd-layout-container'
2016-01-26 21:12:48 +03:00
}
const Default = {
focusSelector : ` a, button, input `
}
/ * *
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* Class Definition
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
class Drawer extends BaseLayout {
// $element is expected to be the trigger
2016-03-21 17:56:51 +03:00
// 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">
2016-01-26 21:12:48 +03:00
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 )
2016-03-21 17:56:51 +03:00
// 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.
2016-01-26 21:12:48 +03:00
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