App bar
The app bar is used to switch between the different top-level views of an app.
To see a detailed explanation of all existing helper classes for the advanced app bar, please refer to the usage table below.
All functionality for expanding/collapsing, selecting and interacting is implemented (and documented) with plain JavaScript at the end of the examples.
Advanced app bar
<div class="appWrapper has-appBarAdvanced has-appBarAdvanced-collapsed">
<div class="appWrapper__regions has-appBarAdvanced has-contextRegion has-appBarAdvanced-collapsed has-leadingRegion contextRegion-is-expanded leadingRegion-is-expanded appWrapper__regions--pushLayout">
<section class="leadingRegion">
</section>
<section class="mainRegion">
<button class="button button--secondary" id="toggleLeadingRegionDemo">
Toggle visibility of leading region
</button>
<button class="button button--secondary" id="toggleContextRegionDemo">
Toggle visibility of context region
</button>
</section>
<section class="contextRegion">
<button class="button button--secondary" id="toggleSlidingBehaviour">
Toggle sliding behaviour for demo
</button>
</section>
<aside class="leadingRegionToggleArea">
<a href="#"></a>
</aside>
<aside class="contextRegionToggleArea">
<a href="#"></a>
</aside>
</div>
<nav class="appBarAdvanced">
<div class="appBarAdvanced__inner">
<div class="appBarAdvanced__header">
<!-- optional header -->
</div>
<ul class="appBarAdvanced__content">
<li class="level1 is-home">
<a href="#" class="item__link">
<div class="item__icon">
<i aria-hidden="true" class="iconMdsp home"></i>
</div>
<span class="item__title">Home</span>
</a>
</li>
<li class="level1 is-active">
<a href="#" class="item__link">
<div class="item__icon has-notification">
<i aria-hidden="true" class="iconMdsp chartPie"></i>
</div>
<span class="item__title">Issues</span>
<span class="item__badge">31</span>
</a>
<ul class="level2">
<li class="subitem">
<a href="#">Details</a>
</li>
<li class="subitem">
<a href="#">Activity</a>
</li>
</ul>
</li>
<li class="level1">
<a href="#" class="item__link">
<div class="item__icon">
<i aria-hidden="true" class="iconMdsp shoppingCart"></i>
</div>
<span class="item__title">Activity</span>
</a>
<ul class="level2">
<li class="subitem">
<a href="#">Details</a>
</li>
<li class="subitem">
<a href="#">Activity</a>
</li>
</ul>
</li>
<li class="level1">
<a href="#" class="item__link">
<div class="item__icon">
<i aria-hidden="true" class="iconMdsp hierarchy"></i>
</div>
<span class="item__title">Members</span>
</a>
<ul class="level2">
<li class="subitem">
<a href="#">Details</a>
</li>
<li class="subitem">
<a href="#">Activity</a>
</li>
</ul>
</li>
<li class="level1 has-separator">
<a href="#" class="item__link">
<div class="item__icon has-notification">
<i aria-hidden="true" class="iconMdsp subtenant4"></i>
</div>
<span class="item__title">Settings</span>
<span class="item__badge">12</span>
</a>
<ul class="level2">
<li class="subitem">
<a href="#">Details</a>
</li>
<li class="subitem">
<a href="#">Activity</a>
</li>
</ul>
</li>
<li class="level1">
<a href="#" class="item__link">
<div class="item__icon has-notification">
<i aria-hidden="true" class="iconMdsp chartTrend"></i>
</div>
<span class="item__title"> Tools </span>
<span class="item__badge">4</span>
</a>
<ul class="level2">
<li class="subitem">
<a href="#"> Details </a>
</li>
<li class="subitem">
<a href="#"> Activity </a>
</li>
</ul>
</li>
</ul>
<div class="appBarAdvanced__footer">
<a href="#" id="appBar--expander">
<!-- optional expand / collapse label -->
<span class="item__title">Collapse</span>
</a>
</div>
</div>
</nav>
</div>
<script type="text/javascript" src="https://static.eu1.mindsphere.io/osbar/v4/js/main.min.js"></script>
<script>
window.onload = function(e){
// polyfill for closest() - IE11 does not support that out of the box
if (!Element.prototype.matches) {
Element.prototype.matches = Element.prototype.msMatchesSelector ||
Element.prototype.webkitMatchesSelector;
}
if (!Element.prototype.closest) {
Element.prototype.closest = function(s) {
var el = this;
do {
if (Element.prototype.matches.call(el, s)) return el;
el = el.parentElement || el.parentNode;
} while (el !== null && el.nodeType === 1);
return null;
};
}
// toggle expand / collapse feature of sidebar
var toggle = document.querySelector("#appBar--expander");
var appWrapper = document.querySelector(".appWrapper");
toggle.addEventListener("click", function () {
// appBar.classList.toggle("has-appBarAdvanced-collapsed");
appWrapper.classList.toggle("has-appBarAdvanced-collapsed");
var elems = document.querySelectorAll(".appBarAdvanced .level1");
for (var i = 0; i < elems.length; i++) {
elems[i].classList.remove("is-shown");
}
});
// set active state of item on click
var level1links = document.querySelectorAll(".appBarAdvanced .item__link");
for (var i = 0; i < level1links.length; i++) {
level1links[i].addEventListener("click", function (event) {
for (var j = 0; j < level1links.length; j++) {
level1links[j].parentElement.classList.remove("is-active");
}
event.target.closest(".level1").classList.add("is-active");
event.target.blur();
event.target.parentNode.parentNode.blur(); // needed for collapsed mode
event.preventDefault();
});
}
// add class to show submenu on hover
var timerHover;
var collapsedAppBarElements = document.querySelectorAll(
".has-appBarAdvanced-collapsed .appBarAdvanced .level1"
);
var collapsedAppBarLinks = document.querySelectorAll(
".has-appBarAdvanced-collapsed .appBarAdvanced .level1 a"
);
for (var i = 0; i < collapsedAppBarLinks.length; i++) {
collapsedAppBarLinks[i].addEventListener("mouseenter", function (event) {
clearTimeout(timerHover);
for (var j = 0; j < collapsedAppBarElements.length; j++) {
collapsedAppBarElements[j].classList.remove("is-shown");
}
event.target.closest(".level1").classList.add("is-shown");
});
}
// hide all possible open items on mouse-leave, but wait for a split second
// to avoid unintentional mouseleave events
var appBar = document.querySelector(".appBarAdvanced");
appBar.addEventListener("mouseleave", function () {
timerHover = setTimeout(function () {
for (var j = 0; j < collapsedAppBarElements.length; j++) {
collapsedAppBarElements[j].classList.remove("is-shown");
}
}, 100);
});
// functionality for expanding and collapsing leading and context region
var leading = document.querySelectorAll("a.leadingRegionToggle, .leadingRegionToggleArea > a");
var context = document.querySelectorAll("a.contextRegionToggle, .contextRegionToggleArea > a");
var regionsWrapper = document.querySelector(".appWrapper__regions");
for (var i=0; i < leading.length; i++) {
leading[i].addEventListener('click', function(e) {
regionsWrapper.classList.toggle('leadingRegion-is-expanded');
for (var j=0; j<leading.length; j++) {
leading[j].classList.toggle('is-activated');
}
});
}
for (var i=0; i < leading.length; i++) {
context[i].addEventListener('click', function(e) {
regionsWrapper.classList.toggle('contextRegion-is-expanded');
for (var j=0; j<context.length; j++) {
context[j].classList.toggle('is-activated');
}
});
}
// functionality to hide context and/or leadimg region through button
var toggleLeading = document.querySelector("#toggleLeadingRegionDemo");
toggleLeading.addEventListener('click', function() {
regionsWrapper.classList.toggle('has-leadingRegion');
});
var toggleContext = document.querySelector("#toggleContextRegionDemo");
toggleContext.addEventListener('click', function() {
regionsWrapper.classList.toggle('has-contextRegion');
});
// functionality to toggle sliding behaviour for leading and context region
var switchLayoutType = document.querySelector("#toggleSlidingBehaviour");
switchLayoutType.addEventListener('click', function() {
regionsWrapper.classList.toggle('appWrapper__regions--pushLayout');
});
}
</script>
Advanced app bar, with OS Bar
<div class="appWrapper has-appBarAdvanced has-appBarAdvanced-collapsed">
<div class="appWrapper__regions has-appBarAdvanced has-contextRegion has-appBarAdvanced-collapsed has-leadingRegion contextRegion-is-expanded leadingRegion-is-expanded appWrapper__regions--pushLayout">
<section class="leadingRegion">
</section>
<section class="mainRegion">
<button class="button button--secondary" id="toggleLeadingRegionDemo">
Toggle visibility of leading region
</button>
<button class="button button--secondary" id="toggleContextRegionDemo">
Toggle visibility of context region
</button>
</section>
<section class="contextRegion">
<button class="button button--secondary" id="toggleSlidingBehaviour">
Toggle sliding behaviour for demo
</button>
</section>
<aside class="leadingRegionToggleArea">
<a href="#"></a>
</aside>
<aside class="contextRegionToggleArea">
<a href="#"></a>
</aside>
</div>
<nav class="appBarAdvanced">
<div class="appBarAdvanced__inner">
<div class="appBarAdvanced__header">
<!-- optional header -->
</div>
<ul class="appBarAdvanced__content">
<li class="level1 is-home">
<a href="#" class="item__link">
<div class="item__icon">
<i aria-hidden="true" class="iconMdsp home"></i>
</div>
<span class="item__title">Home</span>
</a>
</li>
<li class="level1 is-active">
<a href="#" class="item__link">
<div class="item__icon has-notification">
<i aria-hidden="true" class="iconMdsp chartPie"></i>
</div>
<span class="item__title">Issues</span>
<span class="item__badge">31</span>
</a>
<ul class="level2">
<li class="subitem">
<a href="#">Details</a>
</li>
<li class="subitem">
<a href="#">Activity</a>
</li>
</ul>
</li>
<li class="level1">
<a href="#" class="item__link">
<div class="item__icon">
<i aria-hidden="true" class="iconMdsp shoppingCart"></i>
</div>
<span class="item__title">Activity</span>
</a>
<ul class="level2">
<li class="subitem">
<a href="#">Details</a>
</li>
<li class="subitem">
<a href="#">Activity</a>
</li>
</ul>
</li>
<li class="level1">
<a href="#" class="item__link">
<div class="item__icon">
<i aria-hidden="true" class="iconMdsp hierarchy"></i>
</div>
<span class="item__title">Members</span>
</a>
<ul class="level2">
<li class="subitem">
<a href="#">Details</a>
</li>
<li class="subitem">
<a href="#">Activity</a>
</li>
</ul>
</li>
<li class="level1 has-separator">
<a href="#" class="item__link">
<div class="item__icon has-notification">
<i aria-hidden="true" class="iconMdsp subtenant4"></i>
</div>
<span class="item__title">Settings</span>
<span class="item__badge">12</span>
</a>
<ul class="level2">
<li class="subitem">
<a href="#">Details</a>
</li>
<li class="subitem">
<a href="#">Activity</a>
</li>
</ul>
</li>
<li class="level1">
<a href="#" class="item__link">
<div class="item__icon has-notification">
<i aria-hidden="true" class="iconMdsp chartTrend"></i>
</div>
<span class="item__title"> Tools </span>
<span class="item__badge">4</span>
</a>
<ul class="level2">
<li class="subitem">
<a href="#"> Details </a>
</li>
<li class="subitem">
<a href="#"> Activity </a>
</li>
</ul>
</li>
</ul>
<div class="appBarAdvanced__footer">
<a href="#" id="appBar--expander">
<!-- optional expand / collapse label -->
<span class="item__title">Collapse</span>
</a>
</div>
</div>
</nav>
</div>
<script type="text/javascript" src="https://static.eu1.mindsphere.io/osbar/v4/js/main.min.js"></script>
<script>
_msb.init({
title: "App Layout",
showLegal: true,
polyfills: {
promise: true
}
});
window.onload = function(e){
// polyfill for closest() - IE11 does not support that out of the box
if (!Element.prototype.matches) {
Element.prototype.matches = Element.prototype.msMatchesSelector ||
Element.prototype.webkitMatchesSelector;
}
if (!Element.prototype.closest) {
Element.prototype.closest = function(s) {
var el = this;
do {
if (Element.prototype.matches.call(el, s)) return el;
el = el.parentElement || el.parentNode;
} while (el !== null && el.nodeType === 1);
return null;
};
}
// toggle expand / collapse feature of sidebar
var toggle = document.querySelector("#appBar--expander");
var appWrapper = document.querySelector(".appWrapper");
toggle.addEventListener("click", function () {
// appBar.classList.toggle("has-appBarAdvanced-collapsed");
appWrapper.classList.toggle("has-appBarAdvanced-collapsed");
var elems = document.querySelectorAll(".appBarAdvanced .level1");
for (var i = 0; i < elems.length; i++) {
elems[i].classList.remove("is-shown");
}
});
// set active state of item on click
var level1links = document.querySelectorAll(".appBarAdvanced .item__link");
for (var i = 0; i < level1links.length; i++) {
level1links[i].addEventListener("click", function (event) {
for (var j = 0; j < level1links.length; j++) {
level1links[j].parentElement.classList.remove("is-active");
}
event.target.closest(".level1").classList.add("is-active");
event.target.blur();
event.target.parentNode.parentNode.blur(); // needed for collapsed mode
event.preventDefault();
});
}
// add class to show submenu on hover
var timerHover;
var collapsedAppBarElements = document.querySelectorAll(
".has-appBarAdvanced-collapsed .appBarAdvanced .level1"
);
var collapsedAppBarLinks = document.querySelectorAll(
".has-appBarAdvanced-collapsed .appBarAdvanced .level1 a"
);
for (var i = 0; i < collapsedAppBarLinks.length; i++) {
collapsedAppBarLinks[i].addEventListener("mouseenter", function (event) {
clearTimeout(timerHover);
for (var j = 0; j < collapsedAppBarElements.length; j++) {
collapsedAppBarElements[j].classList.remove("is-shown");
}
event.target.closest(".level1").classList.add("is-shown");
});
}
// hide all possible open items on mouse-leave, but wait for a split second
// to avoid unintentional mouseleave events
var appBar = document.querySelector(".appBarAdvanced");
appBar.addEventListener("mouseleave", function () {
timerHover = setTimeout(function () {
for (var j = 0; j < collapsedAppBarElements.length; j++) {
collapsedAppBarElements[j].classList.remove("is-shown");
}
}, 100);
});
// functionality for expanding and collapsing leading and context region
var leading = document.querySelectorAll("a.leadingRegionToggle, .leadingRegionToggleArea > a");
var context = document.querySelectorAll("a.contextRegionToggle, .contextRegionToggleArea > a");
var regionsWrapper = document.querySelector(".appWrapper__regions");
for (var i=0; i < leading.length; i++) {
leading[i].addEventListener('click', function(e) {
regionsWrapper.classList.toggle('leadingRegion-is-expanded');
for (var j=0; j<leading.length; j++) {
leading[j].classList.toggle('is-activated');
}
});
}
for (var i=0; i < leading.length; i++) {
context[i].addEventListener('click', function(e) {
regionsWrapper.classList.toggle('contextRegion-is-expanded');
for (var j=0; j<context.length; j++) {
context[j].classList.toggle('is-activated');
}
});
}
// functionality to hide context and/or leading region through button
var toggleLeading = document.querySelector("#toggleLeadingRegionDemo");
toggleLeading.addEventListener('click', function() {
regionsWrapper.classList.toggle('has-leadingRegion');
});
var toggleContext = document.querySelector("#toggleContextRegionDemo");
toggleContext.addEventListener('click', function() {
regionsWrapper.classList.toggle('has-contextRegion');
});
// functionality to toggle sliding behaviour for leading and context region
var switchLayoutType = document.querySelector("#toggleSlidingBehaviour");
switchLayoutType.addEventListener('click', function() {
regionsWrapper.classList.toggle('appWrapper__regions--pushLayout');
});
}
</script>
Usage
Element | Class | Description |
---|---|---|
.appWrapper | .has-appBarAdvanced | This class is necessary for the general / overall layout to calculate (left side) whitespace for the advanced app bar. |
.appWrapper | .has-appBarAdvanced .has-appBarAdvanced-collapsed | This class has to be toggled from clicking the "collapse" link in the footer section of the advanced app bar and extends the app layout for a smaller, condensed version of the advanced app bar. |
.level1 | .is-shown | This class shows the title as well as the subitems ("level2") of an app bar item. This class should be removed on mouseout of such an item again. There should never be more then one single app bar item with this class. |
.level1 | .is-active | This class expands and visually highlights the currently selected ("active") app bar item. This should be triggered on click of the App bar item. There should never be more then one single app bar item with this class. |
.level1 | .is-home | This class can be used for the first item, it adds a thin visual separator after this item as well as hides the item label on hover in collapsed state. This class shall only be used on the first item (= the "home" item). |
.level1 | .has-separator | This class adds a thin visual separator between this and the preceeding item. |
.item__icon | .has-notification | This class shows an indicator next to an item's icon. This can be used to indicate that something within this app's module needs an user's attention. The color of the indicator is set to the global state color used for errors (default: red). |
To see a detailed explanation of all existing helper classes for the app bar, please refer to the usage table below.
App bar
<div class="appWrapper">
<div class="appWrapper__regions has-appBar has-contextRegion has-leadingRegion contextRegion-is-expanded leadingRegion-is-expanded appWrapper__regions--pushLayout">
<section class="leadingRegion">
<!-- content for leading region goes here -->
</section>
<section class="mainRegion">
<!-- content for main region goes here -->
</section>
<section class="contextRegion">
<!-- content for context region goes here -->
</section>
<aside class="leadingRegionToggleArea">
<a href="#"></a>
</aside>
<aside class="contextRegionToggleArea">
<a href="#"></a>
</aside>
</div>
<ul class="appWrapper__appBar">
<li class="appBar__item">
<a href="#">
<span class="iconMdsp person" aria-hidden="true"></span>
<span class="item__title">Lorem</span>
</a>
</li>
<li class="appBar__item is-activated">
<a href="#">
<span class="iconMdsp calendarDay" aria-hidden="true"></span>
<span class="item__title">Ipsum</span>
</a>
</li>
<li class="appBar__item">
<a href="#">
<span class="iconMdsp aspects" aria-hidden="true"></span>
<span class="item__title">Dolor sit</span>
</a>
</li>
<li class="appBar__item">
<a href="#">
<span class="iconMdsp asset" aria-hidden="true"></span>
<span class="item__title">Amet tempor aliquam quctor</span>
</a>
</li>
<li class="appBar__item is-disabled">
<a href="#">
<span class="iconMdsp calendar" aria-hidden="true"></span>
<span class="item__title">Morbi et lobortis lacus sed tempor</span>
</a>
</li>
<li class="appBar__item">
<a href="#">
<span class="iconMdsp globalSettings" aria-hidden="true"></span>
<span class="item__title">Lobortis lacus sed tempor</span>
</a>
</li>
</ul>
<div class="appWrapper__mobileToggle">
<a href="#" class="leadingRegionToggle is-activated button button--secondary">
<span class="iconMdsp sidebar" aria-hidden="true"></span>
</a>
<a href="#" class="contextRegionToggle is-activated button button--secondary">
<span class="iconMdsp sidebar" aria-hidden="true"></span>
</a>
</div>
</div>
<script type="text/javascript" src="https://static.eu1.mindsphere.io/osbar/v4/js/main.min.js"></script>
<script>
_msb.init({
title: "App Layout",
showLegal: true,
polyfills: {
promise: true
}
});
window.onload = function(e){
var leading = document.querySelectorAll("a.leadingRegionToggle, .leadingRegionToggleArea > a");
var context = document.querySelectorAll("a.contextRegionToggle, .contextRegionToggleArea > a");
var regionsWrapper = document.querySelector(".appWrapper__regions");
for (var i=0; i < leading.length; i++) {
leading[i].addEventListener('click', function(e) {
regionsWrapper.classList.toggle('leadingRegion-is-expanded');
for (var j=0; j<leading.length; j++) {
leading[j].classList.toggle('is-activated');
}
});
}
for (var i=0; i < leading.length; i++) {
context[i].addEventListener('click', function(e) {
regionsWrapper.classList.toggle('contextRegion-is-expanded');
for (var j=0; j<context.length; j++) {
context[j].classList.toggle('is-activated');
}
});
}
var switchLayoutType = document.querySelector("#toggleSlidingBehaviour");
switchLayoutType.addEventListener('click', function() {
regionsWrapper.classList.toggle('appWrapper__regions--pushLayout');
});
var toggleLeading = document.querySelector("#toggleLeadingRegionDemo");
toggleLeading.addEventListener('click', function() {
regionsWrapper.classList.toggle('has-leadingRegion');
});
var toggleContext = document.querySelector("#toggleContextRegionDemo");
toggleContext.addEventListener('click', function() {
regionsWrapper.classList.toggle('has-contextRegion');
});
}
</script>
App bar (alternative markup)
<div class="appWrapper">
<div class="appWrapper__regions has-appBar has-contextRegion has-leadingRegion contextRegion-is-expanded leadingRegion-is-expanded appWrapper__regions--pushLayout">
<section class="leadingRegion">
<!-- content for leading region goes here -->
</section>
<section class="mainRegion">
<!-- content for main region goes here -->
</section>
<section class="contextRegion">
<!-- content for context region goes here -->
</section>
<aside class="leadingRegionToggleArea">
<a href="#"></a>
</aside>
<aside class="contextRegionToggleArea">
<a href="#"></a>
</aside>
</div>
<div class="appWrapper__appBar">
<a class="appBar__item" href="#">
<span class="iconMdsp person" aria-hidden="true"></span>
<span class="item__title">Lorem</span>
</a>
<a class="appBar__item is-activated" href="#">
<span class="iconMdsp calendarDay" aria-hidden="true"></span>
<span class="item__title">Ipsum</span>
</a>
<a class="appBar__item" href="#">
<span class="iconMdsp aspects" aria-hidden="true"></span>
<span class="item__title">Dolor sit</span>
</a>
<a class="appBar__item" href="#">
<span class="iconMdsp asset" aria-hidden="true"></span>
<span class="item__title">Amet tempor aliquam quctor</span>
</a>
<a class="appBar__item is-disabled" href="#">
<span class="iconMdsp calendar" aria-hidden="true"></span>
<span class="item__title">Morbi et lobortis lacus sed tempor</span>
</a>
<a class="appBar__item" href="#">
<span class="iconMdsp globalSettings" aria-hidden="true"></span>
<span class="item__title">Lobortis lacus sed tempor</span>
</a>
</div>
<div class="appWrapper__mobileToggle">
<a href="#" class="leadingRegionToggle is-activated button button--secondary">
<span class="iconMdsp sidebar" aria-hidden="true"></span>
</a>
<a href="#" class="contextRegionToggle is-activated button button--secondary">
<span class="iconMdsp sidebar" aria-hidden="true"></span>
</a>
</div>
</div>
<script type="text/javascript" src="https://static.eu1.mindsphere.io/osbar/v4/js/main.min.js"></script>
<script>
_msb.init({
title: "App Layout",
showLegal: true,
polyfills: {
promise: true
}
});
window.onload = function(e){
var leading = document.querySelectorAll("a.leadingRegionToggle, .leadingRegionToggleArea > a");
var context = document.querySelectorAll("a.contextRegionToggle, .contextRegionToggleArea > a");
var regionsWrapper = document.querySelector(".appWrapper__regions");
for (var i=0; i < leading.length; i++) {
leading[i].addEventListener('click', function(e) {
regionsWrapper.classList.toggle('leadingRegion-is-expanded');
for (var j=0; j<leading.length; j++) {
leading[j].classList.toggle('is-activated');
}
});
}
for (var i=0; i < leading.length; i++) {
context[i].addEventListener('click', function(e) {
regionsWrapper.classList.toggle('contextRegion-is-expanded');
for (var j=0; j<context.length; j++) {
context[j].classList.toggle('is-activated');
}
});
}
var switchLayoutType = document.querySelector("#toggleSlidingBehaviour");
switchLayoutType.addEventListener('click', function() {
regionsWrapper.classList.toggle('appWrapper__regions--pushLayout');
});
var toggleLeading = document.querySelector("#toggleLeadingRegionDemo");
toggleLeading.addEventListener('click', function() {
regionsWrapper.classList.toggle('has-leadingRegion');
});
var toggleContext = document.querySelector("#toggleContextRegionDemo");
toggleContext.addEventListener('click', function() {
regionsWrapper.classList.toggle('has-contextRegion');
});
}
</script>
Usage
Element | Class | Description |
---|---|---|
.appBar__item | .is-activated | Highlights the current app bar item |
.appBar__item | .is-focused , :focus | Visually highlights a (focused via keyboard navigation) element. |
.appBar__item | .is-disabled | Disables an app bar item (visually and on hover) |