Permalink
Cannot retrieve contributors at this time
Fetching contributors…

<!DOCTYPE html> | |
<html> | |
<head> | |
<title>Tab Manager Component</title> | |
<link rel="stylesheet" type="text/css" href="../../src/debug.css"> | |
</head> | |
<body> | |
<element name="tabs" extends="article" constructor="TabsControl"> | |
<template> | |
<style id="exportedStyle"> | |
h2:nth-of-type(1) { | |
background: white; | |
color: black; | |
-webkit-user-select: none; | |
text-shadow: 0 0 1px black | |
} | |
h2 { | |
font-family: 'Open Sans'; | |
font-size: 16px; | |
line-height: 22px; | |
font-weight: 400; | |
padding: 5px 15px; | |
margin: 0 5px 0 0; | |
text-align: center; | |
text-overflow: ellipsis; | |
overflow: hidden; | |
cursor: pointer; | |
-webkit-user-select: none; | |
border-top-left-radius: 6px; | |
border-top-right-radius: 6px; | |
background: rgb(242, 242, 242); | |
color: rgb(64, 64, 64); | |
box-shadow: 0 2px 2px rgba(0, 0, 0, .3); | |
} | |
h2:nth-of-type(n+7) { | |
text-align: left; | |
box-shadow: none; | |
border-radius: 0; | |
background: white; | |
} | |
h2:nth-of-type(n+7):hover { | |
background: rgba(0 0 0 .1); | |
} | |
</style> | |
<style> | |
@import url(http://fonts.googleapis.com/css?family=Open+Sans:400,300,600); | |
</style> | |
<style> | |
div.container { | |
display: -webkit-flex; | |
-webkit-flex-direction: column; | |
-webkit-align-items: stretch; | |
background: -webkit-linear-gradient(rgb(230, 230, 230), rgb(200, 200, 200)); | |
padding: 10px; -webkit-font-smoothing: antialiased; | |
} | |
.tab-strip { | |
display: -webkit-flex; | |
-webkit-justify-content: space-between; | |
padding: 0 5px; | |
-webkit-user-select: none; | |
} | |
.tab-wrapper { | |
display: -webkit-flex; | |
height: 30px; | |
} | |
div.overflow { | |
position: relative | |
} | |
div.overflow .tab-wrapper { | |
overflow: hidden; | |
} | |
div.more { | |
display: -webkit-flex; | |
-webkit-justify-content: space-between; | |
padding: 0 5px; | |
-webkit-user-select: none; | |
} | |
div.overflow>div.closed { | |
display:none; | |
} | |
div.overflow>div.open { | |
position:absolute; | |
background: #fff; | |
border: 1px solid #999; | |
padding: 2px 0 2px 2px; | |
right: 0; | |
width: 300px; | |
} | |
.contents { | |
box-shadow: 0 2px 2px rgba(0, 0, 0, .3); | |
background: white; | |
border-radius: 3px; | |
padding: 5px 20px; | |
font-family: 'Open Sans'; | |
font-size: 14px; | |
line-height: 20px; | |
overflow: auto; | |
height: 600px; | |
} | |
.help { | |
background-color: #eee; | |
padding: 5px 10px; | |
margin: 2px 0 0 0; | |
font-family: 'Open Sans'; | |
font-size: 11px; | |
border-radius: 3px; | |
box-shadow: 0 2px 2px rgba(0, 0, 0, .3); | |
} | |
</style> | |
<div class="container"> | |
<div class="tab-strip"> | |
<div class="tab-wrapper"> | |
<content class="strip" select="h2:nth-of-type(-n+6)"></content> | |
</div> | |
<div class="overflow"> | |
<div class="tab-wrapper"> | |
<div class="more">…</div> | |
</div> | |
<div class="closed"> | |
<content class="overflow" select="h2:nth-of-type(n+6)"></content> | |
</div> | |
</div> | |
</div> | |
<div class="contents"> | |
<content class="current" select="section:nth-of-type(1)"></content> | |
</div> | |
<div class="help"> | |
Use <code>Ctrl+<Number></code> to select the tab directly <code>Ctrl+{</code> or <code>Ctrl+}</code> to cycle between tabs. Click on "…" to see more tabs. | |
</div> | |
</div> | |
</template> | |
<script> | |
if (this !== window) { | |
this.lifecycle({ | |
created: function(root) { | |
this.root = root; | |
var exportedStyle = this.root.querySelector('#exportedStyle'); | |
exportedStyle = this.appendChild(exportedStyle); | |
this.outerStylesheet = exportedStyle.sheet; | |
this.currentIndex = 1; | |
this.moreOpened = false; | |
this.current = this.root.querySelector('content.current'); | |
var overflow = this.root.querySelector('.overflow'); | |
overflow.addEventListener('click', this.onClickOverflow.bind(this)); | |
this.more = overflow.querySelector('.more'); | |
this.menu = overflow.lastElementChild; | |
this.updateCurrent(); | |
this.root.host.addEventListener('click', this.onClickTab.bind(this)); | |
window.addEventListener('click', this.onClickWindow.bind(this)); | |
window.addEventListener('keydown', this.onKeyDown.bind(this)); | |
} | |
}); | |
TabsControl.prototype = { | |
onKeyDown: function(evt) { | |
if (!evt.ctrlKey) | |
return; | |
if (evt.keyCode == 221) { | |
this.cycle(1); | |
} else if (evt.keyCode == 219) { | |
this.cycle(-1); | |
} else if (evt.keyCode > 48 && evt.keyCode < 58) { | |
this.currentIndex = evt.keyCode - 48; | |
this.updateCurrent(); | |
} | |
}, | |
onClickTab: function(evt) { | |
if (evt.target.nodeName == 'H2') { | |
this.currentIndex = this.indexOf(evt.target) || this.currentIndex; | |
this.updateCurrent(); | |
} | |
}, | |
openMore: function() { | |
this.menu.className = 'open'; | |
this.moreOpened = true; | |
}, | |
closeMore: function() { | |
this.menu.className = 'closed'; | |
this.moreOpened = false; | |
}, | |
onClickOverflow: function(evt) { | |
if (evt.target.className != 'more') | |
return; | |
if (this.moreOpened) | |
this.closeMore(); | |
else | |
this.openMore(); | |
evt.stopPropagation(); | |
}, | |
onClickWindow: function(evt) { | |
if (this.moreOpened) | |
this.closeMore(); | |
}, | |
indexOf: function(header) { | |
var index = 0; | |
return [].slice.call(this.root.host.querySelectorAll('h2')).indexOf(header) + 1; | |
}, | |
updateCurrent: function() { | |
this.current.select = 'section:nth-of-type(' + this.currentIndex + ')'; | |
var styleAttributes = this.outerStylesheet.cssRules[0].style.cssText; | |
this.outerStylesheet.deleteRule(0); | |
this.outerStylesheet.insertRule('h2:nth-of-type(' + this.currentIndex + '){' + styleAttributes + '}', 0); | |
}, | |
sectionCount: function() { | |
return this.root.host.querySelectorAll('section').length; | |
}, | |
cycle: function(delta) { | |
this.currentIndex += delta; | |
var sectionCount = this.sectionCount(); | |
if (this.currentIndex > sectionCount) { | |
this.currentIndex = sectionCount; | |
return; | |
} | |
else if (this.currentIndex == 0) { | |
this.currentIndex = 1; | |
return; | |
} | |
this.updateCurrent(); | |
} | |
}; | |
} | |
</script> | |
</element> | |
</body> | |
</html> |