diff --git a/README.md b/README.md index 50a0320..0640752 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # Pushbar.js Pushbar.js is a tiny javascript plugin for creating sliding drawers in web apps It is fully customizable and dependency free.You can use it as sidebar menus or option drawers. +You can also nest pushbars, even different type ones. [Demo](https://oncebot.github.io/pushbar.js/) @@ -21,7 +22,7 @@ It is fully customizable and dependency free.You can use it as sidebar menus or overlay:true, }); - + ``` ### Example HTML @@ -29,13 +30,13 @@ It is fully customizable and dependency free.You can use it as sidebar menus or
Push bar content 1 - +
Push bar content 2 - +
@@ -67,13 +68,13 @@ Open and close pushbar with api }); //open a pushbar - pushbar.open('mypushbar1'); + pushbar.open('mypushbar1'); //close all pushbars - pushbar.close(); + pushbar.close(); ``` -### Emitted events +### Emitted events * 'pushbar_opening': when a pushbar is opening, that pushbar element will emit this event. * 'pushbar_closing': when a pushbar is closing, that pushbar element will emit this event. diff --git a/animated.pushbar.js.gif b/animated.pushbar.js.gif index a09f712..648b4d5 100644 Binary files a/animated.pushbar.js.gif and b/animated.pushbar.js.gif differ diff --git a/demo.css b/demo.css index 3894dbc..47c4912 100644 --- a/demo.css +++ b/demo.css @@ -1,101 +1,110 @@ -.wrapper{ +.wrapper { max-width: 678px; margin:auto; } -pre { - border-left: 0.3rem solid #4039ff; +pre { + border-left: 0.3rem solid #4039ff; } -body{ + +body { background:#f2f2f2; } -.push_left{ +.push_left { margin-left: 6px; } -.push_right{ + +.push_right { margin-right: 6px; } -code,xmp{ + +code,xmp { white-space: normal !important; } -textarea{ - margin-bottom: 0px; - min-height: 200px; - line-height: 1; + +textarea { + margin-bottom: 0px; + min-height: 200px; + line-height: 1; } -.close{ - width: 20px; - height: 21px; - position: relative; - display: inline-block; - vertical-align: text-bottom; - text-align: center; - cursor:pointer; +.close { + width: 20px; + height: 21px; + position: relative; + display: inline-block; + vertical-align: text-bottom; + text-align: center; + cursor:pointer; } + .close:before, .close:after { - position: absolute; - left: 10px; - content: ' '; - height: 21px; - width: 3px; - background-color: #fff; + position: absolute; + left: 10px; + content: ' '; + height: 21px; + width: 3px; + background-color: #fff; } + .close:before { transform: rotate(45deg); } + .close:after { transform: rotate(-45deg); } - -.card{ +.card { margin:20px; - border-radius: 5px; - background:#fff; + border-radius: 5px; + background:#fff; box-shadow:0px 0px 20px rgba(0, 0, 0, 0.1) } -.card_title,.title,.pushbar{ - background: #4039ff; - color: #fff; + +.card_title,.title,.pushbar { + background: #4039ff; + color: #fff; } -.card_title,.title{ +.card_title,.title { padding: 15px 20px; - font-weight: bold; + font-weight: bold; } -.card_title{ -border-radius: 4px 4px 0px 0px; + +.card_title { + border-radius: 4px 4px 0px 0px; } -.card_content{ + +.card_content { padding: 15px; } -a.button.getBtn{ -margin-top: 16px;background-color:#fff;color:#4039ff;border-color: #fff; -} - - - -.pushbar{ +a.button.getBtn { + margin-top: 16px;background-color:#fff;color:#4039ff;border-color: #fff; +} +.small { + font-size: 14px; + font-weight: 400; } -.small{ -font-size: 14px; -font-weight: 400; +.menu { + margin: 0; + font-size: 100%; } -.menu li{ - list-style: none; - padding: 15px 20px; - border-top: 1px solid rgba(255, 255, 255, 0.2); - display: block; - margin: 0px; - color: rgba(255, 255, 255, 0.65); + +.menu li { + list-style: none; + padding: 15px 20px; + border-top: 1px solid rgba(255, 255, 255, 0.2); + display: block; + margin: 0px; + color: rgba(255, 255, 255, 0.65); } .button, button, input[type='button'], input[type='reset'], input[type='submit'] { - background-color: #4039ff; - border: 0.1rem solid #4039ff; -} \ No newline at end of file + background-color: #4039ff; + border: 0.1rem solid #4039ff; +} diff --git a/index.html b/index.html index 7422d0c..07cb6ff 100644 --- a/index.html +++ b/index.html @@ -10,8 +10,6 @@ - - @@ -21,13 +19,33 @@ - + +
+
+
+
+ Pushbar.js + +
Pushbar.js is a tiny javascript plugin for creating sliding drawers in web apps
+
It is fully customizable and dependency free.You can use it as sidebar menus or option drawers.
+ +
+
+
+
+
+
+ +
+							
+								Installation
+								
+
+ +
    +
  1. Add the pushbar.css file to the head of your html.
  2. +
  3. Add the pushbar.js file to the head of your html or right before the closing body tag.
  4. +
  5. + Add this code after the pushbar.js script tag to initialize the plugin. +
    + + + +
  6. +
+ +
+
+ +
+							
+								Example html
+								
+
+ +
+
+ +
+							
+								How to use
+								
+
+

Your pushbar must have the class .pushbar and any of the directional classes: .from_left, .from_right, .from_top, .from_bottom to set the opening direction.

+

Pushbar also must have an attribute : data-pushbar-id , which must have a unique value for that pushbar.

+

Your pushbar open button must have an attribute : data-pushbar-target, with the name of the pushbar as value (same value as data-pushbar-id).

+

data-pushbar-close attribute, with the name of the pushbar as value, can be used on any element to make it a close button for given pushbar.

+

Your main content must have the class .pushbar_main_content.

+

You can also nest pushbars, even different types of them. (Some level of tweaking css a bit may be necessary)

+

Keyboard navigation included, close open pushbars by using "Escape" key.

+
+
+ +
+							
+								Options
+								
+
+ +
    +
  1. blur : set it to true for blur effect on the main content (Default:false)
  2. +
  3. overlay : set it to true for dark overlay effect on the main content (Default:true)
  4. +
+
+
+ +
+							
+								API
+								
+
+ Open and close pushbar with api + + + +
+
+ +
+							
+								Emitted events
+								
+
+ +

'pushbar_opening': when a pushbar is opening, that pushbar element will emit this event.

+

'pushbar_closing': when a pushbar is closing, that pushbar element will emit this event.

+ +
+
+ +
+							
+								Important CSS classes for modification
+								
+
+ +
    +
  1. .from_left, .from_right: change the width for your sidebars.
  2. +
  3. .from_top, .from_bottom: change the height for your top and bottom bars.
  4. +
  5. .pushbar_overlay: change the background and opacity for the overlay.
  6. +
+ +
+
+ +
-
-
-
-
- Pushbar.js - -
Pushbar.js is a tiny javascript plugin for creating sliding drawers in web apps
-
It is fully customizable and dependency free.You can use it as sidebar menus or option drawers.
-
-
-
-
-
-
- - - - - - -

-						Installation
-						
-
- -
    -
  1. Add the pushbar.css file to the head of your html.
  2. -
  3. Add the pushbar.js file to the head of your html or right before the closing body tag.
  4. -
  5. Add this code after the pushbar.js script tag to initialize the plugin.
    - - - - -
  6. -
- -
- -

-						Example html
-						
-
- -
- - - - - - - -

-						Options
-						
-
- -
    -
  1. blur : set it to true for blur effect on the main content (Default:false)
  2. -
  3. overlay : set it to true for dark overlay effect on the main content (Default:true)
  4. - -
- -
- -

-						API
-						
-
- - Open and close pushbar with api - - -
- - -

-						Emitted events
-						
-
- -

'pushbar_opening': when a pushbar is opening, that pushbar element will emit this event.

-

'pushbar_closing': when a pushbar is closing, that pushbar element will emit this event.

- -
- - - - -
- +
- -
-
- - - - - \ No newline at end of file +
+ + + + + + diff --git a/pushbar/pushbar.css b/pushbar/pushbar.css index d0654a2..484316a 100644 --- a/pushbar/pushbar.css +++ b/pushbar/pushbar.css @@ -53,6 +53,12 @@ html.pushbar_locked .pushbar_overlay{ transform: translateZ(0) translateX(-100%); } +.pushbar.from_left .from_top, +.pushbar.from_left .from_bottom{ + height: 100%; + overflow:hidden; +} + .pushbar.from_right{ top: 0; right: 0; diff --git a/pushbar/pushbar.js b/pushbar/pushbar.js index 72f2170..31443c9 100644 --- a/pushbar/pushbar.js +++ b/pushbar/pushbar.js @@ -1,7 +1,8 @@ class Pushbar { - constructor(config = { overlay: true, blur: false }) { - this.activeBar = null; - this.overlay = false; + constructor(config = { overlay: false, blur: false }) { + this.activeBar = ''; + this.previousBars = []; + this.root = document.querySelector('html'); if (config.overlay) { this.overlay = document.createElement('div'); @@ -19,16 +20,6 @@ class Pushbar { this.bindEvents(); } - get opened() { - const { activeBar } = this; - return Boolean(activeBar instanceof HTMLElement && activeBar.classList.contains('opened')); - } - - get activeBarId() { - const { activeBar } = this; - return activeBar instanceof HTMLElement && activeBar.getAttribute('data-pushbar-id'); - } - static dispatchOpen(pushbar) { const event = new CustomEvent('pushbar_opening', { bubbles: true, detail: { pushbar } }); pushbar.dispatchEvent(event); @@ -39,13 +30,14 @@ class Pushbar { pushbar.dispatchEvent(event); } - static findElementById(pushbarId) { - return document.querySelector(`[data-pushbar-id="${pushbarId}"]`); + static findPushbarById(pushbarId) { + return document.querySelector('[data-pushbar-id='+pushbarId+']'); } handleOpenEvent(e) { e.preventDefault(); - const pushbarId = e.currentTarget.getAttribute('data-pushbar-target'); + var pushbarId = e.currentTarget.getAttribute('data-pushbar-target'); + if (pushbarId) { this.open(pushbarId); } @@ -53,65 +45,97 @@ class Pushbar { handleCloseEvent(e) { e.preventDefault(); - this.close(); + if ('click' === e.type) { + var pushbarId = e.currentTarget.getAttribute('data-pushbar-target') || e.currentTarget.getAttribute('data-pushbar-close') || this.activeBar; + this.close(pushbarId); + } else if ('keyup' === e.type) { + this.close(this.activeBar); + } } handleKeyEvent(e) { - if (this.opened && e.keyCode === 27) { - this.close(); + if (this.root.classList.contains('pushbar_locked') && e.keyCode === 27) { + this.handleCloseEvent(e); } } bindEvents() { - const triggers = document.querySelectorAll('[data-pushbar-target]'); - const closers = document.querySelectorAll('[data-pushbar-close]'); - - triggers.forEach(trigger => trigger.addEventListener('click', e => this.handleOpenEvent(e), false)); - closers.forEach(closer => closer.addEventListener('click', e => this.handleCloseEvent(e), false)); + var _this = this, + trigger_types = [ 'target', 'close' ], + triggers = ''; + + trigger_types.forEach(function (type) { + triggers = Array.from(document.querySelectorAll('[data-pushbar-'+type+']')); + triggers.forEach(function (trigger) { + return trigger.addEventListener('click', function (e) { + var pushbar = Pushbar.findPushbarById(e.currentTarget.getAttribute('data-pushbar-'+type)); + + if (pushbar) { + if (pushbar.classList.contains('opened')) { + this.classList.remove('open'); + return _this.handleCloseEvent(e); + } else { + this.classList.add('open'); + return _this.handleOpenEvent(e); + } + } else { + return e.preventDefault(); + } + }, false); + }); + }); if (this.overlay) { this.overlay.addEventListener('click', e => this.handleCloseEvent(e), false); } + + // Handle closing stacked pushbars with escape key. document.addEventListener('keyup', e => this.handleKeyEvent(e)); } open(pushbarId) { - // Current bar is already opened - if (String(pushbarId) === this.activeBarId && this.opened) { - return; - } - // Get new pushbar target - const pushbar = Pushbar.findElementById(pushbarId); + var pushbar = Pushbar.findPushbarById(pushbarId); if (!pushbar) return; - - // Close active bar (if exists) - if (this.opened) { - this.close(); - } - - Pushbar.dispatchOpen(pushbar); + pushbar.classList.add('opened'); + pushbar.classList.add('is-open'); + Pushbar.dispatchOpen(pushbar); - const Root = document.querySelector('html'); - Root.classList.add('pushbar_locked'); - Root.setAttribute('pushbar', pushbarId); - this.activeBar = pushbar; + // Set pushbar lock on html element for easy access. + this.root.classList.add('pushbar_locked'); + // Save currently open pushbar to pushbar trail arrray. + var previousBar = this.root.getAttribute('pushbar', pushbarId); + if (previousBar) { + this.previousBars.push(previousBar); + } + // Set currently open pushbar as active one. + this.root.setAttribute('pushbar', pushbarId); + + this.activeBar = pushbarId; } - close() { - const { activeBar } = this; - if (!activeBar) return; - - Pushbar.dispatchClose(activeBar); - activeBar.classList.remove('opened'); - - const Root = document.querySelector('html'); - Root.classList.remove('pushbar_locked'); - Root.removeAttribute('pushbar'); - - this.activeBar = null; + close(pushbarId) { + // Get new pushbar target + var pushbar = Pushbar.findPushbarById(pushbarId); + + if (!pushbar) return; + + Pushbar.dispatchClose(pushbar); + + pushbar.classList.remove('opened'); + + // Set previusly opened pushbar as currently active one. + if (this.previousBars) { + this.activeBar = this.previousBars.pop(); + this.root.setAttribute('pushbar', this.activeBar); + } + + // If all pushbars are closed remove pushbar lock and active bar data. + if (! this.activeBar) { + this.root.classList.remove('pushbar_locked'); + this.root.removeAttribute('pushbar'); + } } } -