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

View File

@ -5,32 +5,40 @@
<!-- Sets initial viewport load and disables zooming -->
<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">
</head>
<body>
<section class="panel-page-container">
<section data-panel="left-panel" class="panel-content">
Panel!
</section>
<section data-default-panel="my-left-panel">
<header class="bar bar-header bar-dark">
<button class="button" data-toggle-panel="my-left-panel"></button>
<h1 class="title">Panels</h1>
</header>
<main class="content-padded has-header">
<p>A whole bunch of content</p>
<a class="button button-primary" data-toggle-panel="left-panel" href="#">Panel</a>
<p><button class="button button-primary" data-toggle-panel="my-other-left-panel">Other Left Side Panel</button></p>
<p id="event-log"></p>
</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>
<script src="../../js/framework/framework-gestures.js"></script>
<script src="../../js/framework/framework-events.js"></script>
<script src="../../js/framework/framework-panel.js"></script>
</body>
</html>

View File

@ -1,55 +1,153 @@
(function(window, document, framework) {
var
el,
styleElement,
isPanelOpen;
x,
lockInWidthStyles,
isLockInWidthSet,
isPanelOpen,
panelReferences = {},
timeout,
className,
function onTap(e) {
if(e.target) {
el = e.target;
if(el.dataset.togglePanel) {
return togglePanel(e, el, el.dataset.togglePanel);
}
while(el.parentElement) {
el = el.parentElement;
if(el.dataset.togglePanel) {
return togglePanel(e, el, el.dataset.togglePanel);
}
}
}
}
PANEL_ACTIVE = "panel-active",
PANEL_OPENED = "panel-opened";
function togglePanel(e, el, panelName) {
var styles = "";
function click(e) {
if(e.target.dataset.togglePanel) {
logEvent("click");
if(isPanelOpen) {
// there is a panel already open, so close it
isPanelOpen = false;
// there's a panel open, close it if the page location changed
closePanel();
} else {
// open the panel
styles = "section .panel-content ~ * { width:" + document.width + "px !important; \
-webkit-transform: translate3d(17em,0,0); \
-moz-transform: translate3d(17em,0,0); \
transform: translate3d(17em,0,0); }";
openPanel(e.target.dataset.togglePanel);
}
return true;
}
}
function touchEnd(e) {
if(click(e)) {
e.preventDefault();
e.stopPropagation();
return false;
}
}
function autoClose() {
if(isPanelOpen) {
logEvent("autoClose");
// there's a panel open, close it if the page location changed
closePanel();
}
}
function openPanel(panelId) {
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;
}
setStyles(styles);
}
function setStyles(styles) {
// get the <style> from the head that will be used by the panel
if(!styleElement) {
styleElement = document.createElement("style");
styleElement.id = "panel-styles";
styleElement.innerHTML = styles;
document.head.appendChild(styleElement);
function closePanel() {
logEvent("closePanel");
// there is a panel already open, so close it
isPanelOpen = false;
// note: do not remove the panel-active class from panel
// the panel should stay displayed as it panel closes
// 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);
}
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 {
styleElement.innerHTML = styles;
lockInWidthStyles.innerHTML = styles;
}
isLockInWidthSet = true;
}
framework.on("click", onTap);
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 || {});

View File

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

View File

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