panel stuff

This commit is contained in:
Adam Bradley
2013-08-28 10:49:01 -05:00
parent 82d747f688
commit 3738aea6e3
6 changed files with 196 additions and 70 deletions

26
dist/framework.css vendored
View File

@ -221,26 +221,36 @@ a.list-item {
margin-bottom: 0; margin-bottom: 0;
line-height: 1.3; } line-height: 1.3; }
/* the container of panel content to show */ [data-panel] {
.panel-content { display: none;
display: block;
width: 17em;
min-height: 100%; min-height: 100%;
max-height: 100%; max-height: 100%;
position: absolute; position: absolute;
top: 0; top: 0;
z-index: 0; } z-index: 0; }
.panel-active {
display: block;
width: 270px; }
header, main, footer { header, main, footer {
z-index: 100;
left: 0; left: 0;
right: 0; right: 0;
-webkit-transition: -webkit-transform 200ms ease; -webkit-transition: -webkit-transform 300ms ease;
-moz-transition: -moz-transform 200ms ease; -moz-transition: -moz-transform 300ms ease;
transition: transform 200ms ease; transition: transform 300ms ease;
-webkit-transform: translate3d(0, 0, 0); -webkit-transform: translate3d(0, 0, 0);
-moz-transform: translate3d(0, 0, 0); -moz-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0); } transform: translate3d(0, 0, 0); }
.panel-opened > section > header,
.panel-opened > section > main,
.panel-opened > section > footer {
-webkit-transform: translate3d(270px, 0, 0);
-moz-transform: translate3d(270px, 0, 0);
transform: translate3d(270px, 0, 0); }
.ptr-capable { .ptr-capable {
-webkit-user-drag: element; } -webkit-user-drag: element; }
@ -524,7 +534,7 @@ main {
a.list-item { a.list-item {
color: #333333; } color: #333333; }
.panel-content { [data-panel] {
background: #eeeeee; background: #eeeeee;
border-right: 1px solid #bbbbbb; } border-right: 1px solid #bbbbbb; }

View File

@ -5,32 +5,40 @@
<!-- Sets initial viewport load and disables zooming --> <!-- Sets initial viewport load and disables zooming -->
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
<link href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet"> <!--<link href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet">-->
<link rel="stylesheet" href="../../dist/framework.css"> <link rel="stylesheet" href="../../dist/framework.css">
</head> </head>
<body> <body>
<section class="panel-page-container"> <section data-default-panel="my-left-panel">
<section data-panel="left-panel" class="panel-content">
Panel!
</section>
<header class="bar bar-header bar-dark"> <header class="bar bar-header bar-dark">
<button class="button" data-toggle-panel="my-left-panel"></button>
<h1 class="title">Panels</h1> <h1 class="title">Panels</h1>
</header> </header>
<main class="content-padded has-header"> <main class="content-padded has-header">
<p>A whole bunch of content</p> <p><button class="button button-primary" data-toggle-panel="my-other-left-panel">Other Left Side Panel</button></p>
<a class="button button-primary" data-toggle-panel="left-panel" href="#">Panel</a> <p id="event-log"></p>
</main> </main>
<footer class="bar bar-footer bar-dark">
<h3 class="title">Panels</h3>
</footer>
</section>
<section data-panel="my-left-panel">
This is my default left side panel!
</section>
<section data-panel="my-other-left-panel">
This is my other left side panel!
</section> </section>
<script src="../../js/framework/framework-gestures.js"></script>
<script src="../../js/framework/framework-events.js"></script>
<script src="../../js/framework/framework-panel.js"></script> <script src="../../js/framework/framework-panel.js"></script>
</body> </body>
</html> </html>

View File

@ -1,55 +1,153 @@
(function(window, document, framework) { (function(window, document, framework) {
var var
el, x,
styleElement, lockInWidthStyles,
isPanelOpen; isLockInWidthSet,
isPanelOpen,
panelReferences = {},
timeout,
className,
function onTap(e) { PANEL_ACTIVE = "panel-active",
if(e.target) { PANEL_OPENED = "panel-opened";
el = e.target;
if(el.dataset.togglePanel) {
return togglePanel(e, el, el.dataset.togglePanel); function click(e) {
} if(e.target.dataset.togglePanel) {
while(el.parentElement) { logEvent("click");
el = el.parentElement; if(isPanelOpen) {
if(el.dataset.togglePanel) { // there's a panel open, close it if the page location changed
return togglePanel(e, el, el.dataset.togglePanel); closePanel();
} } else {
openPanel(e.target.dataset.togglePanel);
} }
return true;
} }
} }
function togglePanel(e, el, panelName) { function touchEnd(e) {
var styles = ""; if(click(e)) {
e.preventDefault();
e.stopPropagation();
return false;
}
}
function autoClose() {
if(isPanelOpen) { if(isPanelOpen) {
// there is a panel already open, so close it logEvent("autoClose");
isPanelOpen = false; // there's a panel open, close it if the page location changed
} else { closePanel();
// open the panel }
styles = "section .panel-content ~ * { width:" + document.width + "px !important; \ }
-webkit-transform: translate3d(17em,0,0); \
-moz-transform: translate3d(17em,0,0); \ function openPanel(panelId) {
transform: translate3d(17em,0,0); }"; logEvent("openPanel: " + panelId);
// see if there is an element with this id
var panel = getPanelElement(panelId);
if(panel) {
// this element is a panel, open it!
// find all the panels that are or were active
var panelsActive = document.getElementsByClassName(PANEL_ACTIVE);
// remove the panel-active css classes from each of the previously opened panels
for(x=0; x<panelsActive.length; x++) {
className = panelsActive[x].className.replace(PANEL_ACTIVE, "").trim();
panelsActive[x].className = className;
}
// open the panel we want open by adding the panel-active css classes
panel.className += " " + PANEL_ACTIVE;
// manually lock in all the widths of the page which the panel will slide over
// do all of this in one DOM manipulation
// This makes it easy to modify all of the elements in one call,
// and also undo all of the element widths in one call
// the css added below makes something like: #my-panel ~ * {width: 420px !important}
// basically any sibling elements to the panel should lock in the document width
setLockInWidthStyles();
// add to <body> that a panel is open
document.body.className += " " + PANEL_OPENED;
// remember that a panel is currently open
isPanelOpen = true; isPanelOpen = true;
} }
setStyles(styles);
} }
function setStyles(styles) { function closePanel() {
// get the <style> from the head that will be used by the panel logEvent("closePanel");
if(!styleElement) {
styleElement = document.createElement("style"); // there is a panel already open, so close it
styleElement.id = "panel-styles"; isPanelOpen = false;
styleElement.innerHTML = styles;
document.head.appendChild(styleElement); // note: do not remove the panel-active class from panel
} else { // the panel should stay displayed as it panel closes
styleElement.innerHTML = styles; // find the element with panel-open class
var openedPanels = document.getElementsByClassName(PANEL_OPENED);
// remove the panel-opened css classes from each of the previously opened panels
for(x=0; x<openedPanels.length; x++) {
// if this panel is the same last opened panel then don't remove the css class yet
className = openedPanels[x].className.replace(PANEL_OPENED, "").trim();
openedPanels[x].className = className;
} }
// remove from <body> that no panels should be open
className = document.body.className.replace(PANEL_OPENED, "").trim();
document.body.className = className;
// remove the locked in widths
timeout = setTimeout(removeLockInWidthStyles, 300);
} }
framework.on("click", onTap); function setLockInWidthStyles() {
if(isLockInWidthSet) return;
clearTimeout(timeout);
var styles = "section>header,section>main,section>footer {width:" + document.width + "px !important}";
if(!lockInWidthStyles) {
lockInWidthStyles = document.createElement("style");
lockInWidthStyles.innerHTML = styles;
document.head.appendChild(lockInWidthStyles);
} else {
lockInWidthStyles.innerHTML = styles;
}
isLockInWidthSet = true;
}
function removeLockInWidthStyles() {
lockInWidthStyles.innerHTML = "";
isLockInWidthSet = false;
}
function getPanelElement(panelId) {
// used to minimize DOM lookups
if( !panelReferences[panelId] ) {
panelReferences[panelId] = document.querySelector( "[data-panel='" + panelId + "']" );
}
return panelReferences[panelId];
}
var logEvent = function(data) {
var e = document.getElementById('event-log');
var l = document.createElement('div');
l.innerHTML = data;
if(e.childNodes.length > 10) {
e.innerHTML = "";
}
e.appendChild(l);
}
window.addEventListener('click', click, false);
window.addEventListener('touchend', touchEnd, false);
window.addEventListener("resize", autoClose, false);
window.addEventListener("popstate", autoClose, false);
})(this, document, FM = this.FM || {}); })(this, document, FM = this.FM || {});

View File

@ -26,4 +26,5 @@ $listItemBorder: 1px solid #ddd;
// Panels // Panels
$panelViewWidth: 17em; $panelOpenWidth: 270px;
$panelAnimationSpeed: 300ms;

View File

@ -1,27 +1,36 @@
[data-panel] {
/* the container of panel content to show */ display: none;
.panel-content {
display: block;
width: $panelViewWidth;
min-height: 100%; min-height: 100%;
max-height: 100%; max-height: 100%;
position: absolute; position: absolute;
top: 0; top: 0;
z-index: 0; z-index: 0;
}
.panel-active {
display: block;
width: $panelOpenWidth;
} }
header, main, footer { header, main, footer {
z-index: 100;
left: 0; left: 0;
right: 0; right: 0;
-webkit-transition: -webkit-transform 200ms ease; -webkit-transition: -webkit-transform $panelAnimationSpeed ease;
-moz-transition: -moz-transform 200ms ease; -moz-transition: -moz-transform $panelAnimationSpeed ease;
transition: transform 200ms ease; transition: transform $panelAnimationSpeed ease;
-webkit-transform: translate3d(0,0,0); -webkit-transform: translate3d(0, 0, 0);
-moz-transform: translate3d(0,0,0); -moz-transform: translate3d(0, 0, 0);
transform: translate3d(0,0,0); transform: translate3d(0, 0, 0);
}
.panel-opened > section > header,
.panel-opened > section > main,
.panel-opened > section > footer
{
-webkit-transform: translate3d($panelOpenWidth, 0,0 );
-moz-transform: translate3d($panelOpenWidth, 0,0 );
transform: translate3d($panelOpenWidth, 0,0 );
} }

View File

@ -1,5 +1,5 @@
.panel-content { [data-panel] {
background: $panelBackgroundColor; background: $panelBackgroundColor;
border-right: 1px solid $panelInsetBorderColor; border-right: 1px solid $panelInsetBorderColor;
} }