MAIN-NAVIGATION (Globale Elemente )
src/app/core/components/main-navigation/templates
Demo Section
Each variation will be presented in the following section.
Readme
mainNavigation (coreComponent
)
Description
This component contains the main navigation. It contains a hidden headline and a list with n-items. There are several link with their default behaviour and the toggle links for the search-overlay and the stack-navigation.
JIRA
Requirements
- @veams/core - Veams Core Framework.
- @veams/query or
jquery
- Veams Query or jQuery. - @veams/component - Veams Component.
Fields
main-navigation.hbs
Settings
Parameter | Type | Default | Description |
---|---|---|---|
settings.mainNavigationClasses | String | '' |
Modifier classes for coreComponent |
Content
Parameter | Type | Description |
---|---|---|
content.headline | String | Hidden headline for the navigation (accessibility) |
content.items | Array | Array of n-items containing links |
main-navigation__list-item.hbs
Settings
Parameter | Type | Default | Description |
---|---|---|---|
settings.listItemClasses | String | '' |
Modifier classes for individual list item |
Content
Parameter | Type | Description |
---|---|---|
content.link | Object | Link settings and contents |
main-navigation__list-link.hbs
Settings
Parameter | Type | Default | Description |
---|---|---|---|
settings.linkClasses | String | '' |
Modifier classes for link item |
settings.linkButton | Boolean | false |
If set to true render a button instead of a link |
settings.linkJsItem | String | '' |
Content of data-js-item selector |
settings.linkIsActive | Boolean | false |
If set to true render a strong-tag instead of a link and add a class |
settings.linkExternal | Boolean | false |
If set to true a target blank attribute and a hidden text will be added |
Content
Parameter | Type | Description |
---|---|---|
content.linkText | String | Text of link that should be displayed |
content.linkHref | String | Location the link points to |
content.linkActiveText | String | Text to add to the link when active (e.g. you are here) |
content.linkLang | String | Language short form for links in other languages than the current website |
JavaScript Options
The module gives you the possibility to override default options:
Option | Type | Default | Description |
---|---|---|---|
classes.active | String | 'is-active' |
Active class to display or hide search overlay component |
classes.expanded | String | 'is-expanded' |
Expanded class to change state from collapsed to expanded |
selectors.stackNavToggler | String | '[data-js-item="toggle-stack-navigation"]' |
Button to toggle stack navigation component |
selectors.searchToggler | String | '[data-js-item="toggle-search"]' |
Button to toggle search overlay component |
selectors.stackNavigation | String | '[data-js-module="stack-navigation"]' |
Selector for the stack navigation component |
SASS
Modifier Classes
You can add the following modifiers to main-navigation__list-item
:
Modifier | Description |
---|---|
is-bordered | Will set a border on the right side of the item |
is-last | Will remove the border and margin-right from last item and will keep the item visible on tablet |
is-search.is-active | Will add a triangle at the bottom to the list item |
You can add the following modifiers to main-navigation__list-link
:
Modifier | Description |
---|---|
is-search | Will set the styles of this item to show a magnifier icon |
is-search.is-active | Will now show a green magnifier icon |
is-burger | Will set the styles of this item to show as a burger icon |
is-burger.is-active | Will set the styles of this item to show as a closing x-icon and change color |
Templates
main-navigation.hbs
<nav class="c-main-navigation{{#if settings.mainNavigationClasses}} {{settings.mainNavigationClasses}}{{/if}}"
data-js-module="main-navigation"{{#if settings.mainNavigationJsOptions}}
data-js-options='{{stringify settings.mainNavigationJsOptions}}'{{/if}}>
<h2 class="main-navigation__headline">{{content.headline}}</h2>
<ul class="main-navigation__list">
{{#each content.items }}
{{> main-navigation__list-item}}
{{/each}}
{{> hamburger-menu}}
</ul>
</nav>
main-navigation__list-item.hbs
<li class="main-navigation__list-item{{#if settings.listItemClasses}} {{ settings.listItemClasses}}{{/if}}">
{{#with content.link }}
{{> main-navigation__list-link }}
{{/with}}
</li>
main-navigation__list-link.hbs
<{{#if settings.linkIsActive}}strong{{else}}{{#if settings.linkButton}}button type="button"{{else}}a{{/if}}{{/if}}
class="main-navigation__list-link{{#if settings.linkClasses}} {{ settings.linkClasses}}{{/if}}"{{#unless settings.linkButton}} href="{{content.linkHref}}"{{#if settings.linkExternal}} target="_blank"{{/if}} title="{{#if settings.linkTitle}}{{settings.linkTitle}}{{else}}Link öffnet im neuen Fenster{{/if}}"{{/unless}}
{{#if settings.linkJsItem}} data-js-item="{{settings.linkJsItem}}"{{/if}}>
{{#if settings.linkIsActive}}<span class="is-aural">{{content.linkActiveText}} </span>{{/if}}
<span class="main-navigation__list-link-text"{{#if content.linkLang}} lang="{{content.linkLang}}"{{/if}}>{{content.linkText}}</span>
{{#if content.linkTextA11y}}
<span class="main-navigation__list-link-text-a11y"{{#if content.linkLang}} lang="{{content.linkLang}}"{{/if}}>{{content.linkTextA11y}}</span>
{{/if}}
</{{#if settings.linkIsActive}}strong{{else}}{{#if settings.linkButton}}button{{else}}a{{/if}}{{/if}}>
Data File
main-navigation.hjson
{
"variations": {
"default": {
"docs": {
"variationName": "Default"
},
"settings": {
"mainNavigationClasses": ""
},
"content": {
"headline": "Hauptnavigation",
"items": [
{
"settings": {
"listItemClasses": ""
},
"content": {
"link": {
"settings": {
"linkClasses": "",
"linkButton": false,
"linkJsItem": "",
"linkIsActive": false,
"linkExternal": false
},
"content": {
"linkText": "Studium",
"linkHref": "#",
"linkActiveText": ""
}
}
}
},
{
"settings": {
"listItemClasses": ""
},
"content": {
"link": {
"settings": {
"linkClasses": "",
"linkButton": false,
"linkJsItem": "",
"linkIsActive": false,
"linkExternal": false
},
"content": {
"linkText": "Forschung",
"linkHref": "#",
"linkActiveText": ""
}
}
}
},
{
"settings": {
"listItemClasses": ""
},
"content": {
"link": {
"settings": {
"linkClasses": "",
"linkButton": false,
"linkJsItem": "",
"linkIsActive": false,
"linkExternal": false
},
"content": {
"linkText": "Die LMU",
"linkHref": "#",
"linkActiveText": ""
}
}
}
},
{
"settings": {
"listItemClasses": "is-bordered is-language"
},
"content": {
"link": {
"settings": {
"linkClasses": "",
"linkButton": false,
"linkJsItem": "",
"linkIsActive": false,
"linkExternal": false,
"linkTitle": "Zur Englischen Sprachversion"
},
"content": {
"linkText": "EN",
"linkHref": "#",
"linkActiveText": "",
"linkLang": "en",
"linkTextA11y": "Zur englischen Sprachversion / Switch to English"
}
}
}
},
{
"settings": {
"listItemClasses": "is-bordered is-search"
},
"content": {
"link": {
"settings": {
"linkClasses": "is-search",
"linkButton": true,
"linkJsItem": "toggle-search",
"linkIsActive": false
},
"content": {
"linkText": "Suche öffnen/schließen"
}
}
}
},
{
"settings": {
"listItemClasses": "is-bordered is-last"
},
"content": {
"link": {
"settings": {
"linkClasses": "is-burger",
"linkButton": true,
"linkJsItem": "toggle-stack-navigation",
"linkIsActive": false
},
"content": {
"linkText": "Erweiterte Navigation öffnen/schließen"
}
}
}
}
]
}
}
}
}
Styles
main-navigation.scss
/* ===================================================
coreComponent: main-navigation
=================================================== */
/*
ANIMATIONS
----------------------- */
@keyframes burger-animation-top {
0% {
top: 0;
transform: translateY(0);
}
50% {
top: 50%;
transform: translateY(-50%);
}
100% {
transform: translateY(-50%) rotate(45deg);
}
}
@keyframes burger-animation-bottom {
0% {
bottom: 0;
transform: translateY(0);
}
50% {
bottom: 50%;
transform: translateY(-50%);
}
100% {
transform: translateY(-50%) rotate(-45deg);
}
}
/*
STYLES
----------------------- */
.c-main-navigation {
height: 100%;
display: flex;
.main-navigation__headline {
@include aural();
}
.main-navigation__list {
display: flex;
flex-direction: row;
justify-items: center;
}
.main-navigation__list-item {
margin-right: 60px;
height: 50px;
line-height: (50/16);
display: none;
@include bp($bp-desktop-l) {
display: inline-block;
}
/*
MODIFIERS
----------------------- */
&.is-bordered {
margin-right: 0;
padding: 0 20px;
border-left: 1px solid $color-light;
&.is-last {
padding-right: 0;
}
}
&.is-search {
display: inline-block;
border-left: none;
padding-right: 0px;
padding-left: 30px;
@include bp($bp-tablet-p) {
padding: 0 20px;
}
@include bp($bp-desktop-l) {
border-left: 1px solid $color-light;
}
&::before {
@include pseudo();
position: absolute;
bottom: 0;
display: block;
width: 0;
height: 0;
border-style: solid;
border-width: 0 15px;
border-color: transparent transparent $color-light transparent;
margin-left: -5px;
transition: border-width $animation-duration-std $animation-easing-std;
transition-delay: 100ms;
}
&.is-active {
&::before {
border-width: 0 15px 15px;
}
}
}
&.is-last {
margin-right: 0;
position: relative;
border-left: none;
display: none;
@include bp($bp-tablet-p) {
display: inline-block;
}
@include bp($bp-desktop-l) {
border-left: 1px solid $color-light;
}
}
&.is-language {
@include print() {
display: none;
}
.main-navigation__list-link-text {
@include hcm() {
@include hidden-text();
}
}
.main-navigation__list-link-text-a11y {
display: none;
@include hcm() {
display: inline-block;
font: 1.2rem $font-bold;
width: 100px;
height: auto;
border: 1px solid;
border-radius: 3px;
padding: 0 5px;
color: $color-dark;
}
}
}
}
.main-navigation__list-link {
color: $color-dark;
font-size: 1.6rem;
font-family: $font-bold;
letter-spacing: .3px;
text-decoration: none;
cursor: pointer;
transition: color $animation-duration-std $animation-easing-std;
&:hover,
&.a11y-focus-key {
color: $color-green;
}
/*
MODIFIERS
----------------------- */
&.is-active {
color: $color-green;
}
&.is-search { // SEARCH TOGGLER
@include hidden-text();
font-size: .00001rem;
border: none;
width: 21px;
height: 21px;
position: relative;
display: inline-block;
vertical-align: middle;
background-color: transparent;
@include hcm() {
font: 1.2rem $font-bold;
width: auto;
height: auto;
border: 1px solid;
border-radius: 3px;
}
&:hover,
&.a11y-focus-key {
&::before {
@include sprites-icon-search-green100();
}
}
&:focus {
outline: none;
}
/*
MODIFIERS
----------------------- */
&.is-active {
&::before {
opacity: 0;
}
&::after {
@include sprites-icon-close-green100();
opacity: 1;
}
&:hover {
&::after {
@include sprites-icon-close-black();
}
}
}
&::before,
&::after {
@include pseudo();
display: block;
position: absolute;
top: 0;
left: 0;
transition: opacity $animation-duration-std $animation-easing-std;
@include hcm() {
display: none;
}
}
&::before {
@include sprites-icon-search-green100();
opacity: 1;
}
&::after {
@include sprites-icon-close-green100();
opacity: 0;
}
@include bp($bp-tablet-p) {
&::before {
@include sprites-icon-search-black();
}
}
}
&.is-burger { // NAVIGATION TOGGLER
font-size: .00001rem;
border: none;
width: 25px;
height: 18px;
position: relative;
display: inline-block;
vertical-align: middle;
background-color: transparent;
color: transparent;
@include hcm() {
font-size: 1.2rem;
width: auto;
height: auto;
color: white;
}
&:hover,
&.a11y-focus-key {
&::before,
&::after {
background-color: $color-green;
}
.main-navigation__list-link-text {
background-color: $color-green;
}
}
&:focus {
outline: none;
}
/*
MODIFIERS
----------------------- */
&.is-active {
&::before {
transform: translateX(-8px) rotate(-45deg);
width: 21px;
}
&::after {
transform: translateX(-8px) rotate(45deg);
width: 21px;
}
.main-navigation__list-link-text {
opacity: 0;
transform: translateX(-100px);
}
}
&::before,
&::after {
@include pseudo();
width: 25px;
height: 3px;
background-color: $color-dark;
position: absolute;
left: 0;
transition: background-color $animation-duration-std $animation-easing-std, transform $animation-duration-std $animation-easing-std, width $animation-duration-std $animation-easing-std;
@include hcm() {
display: none;
}
}
&::before {
top: 0;
transform-origin: right top;
}
&::after {
bottom: 1px;
transform-origin: right bottom;
}
.main-navigation__list-link-text {
position: absolute;
left: 0;
top: 50%;
margin-top: -2px;
display: block;
width: 25px;
height: 3px;
background-color: $color-dark;
transition: background-color $animation-duration-std $animation-easing-std, opacity $animation-duration-std $animation-easing-std, transform $animation-duration-std $animation-easing-std;
@include hcm() {
position: relative;
top: auto;
left: auto;
width: auto;
height: auto;
margin-top: 0;
}
}
}
}
}
Scripts
main-navigation.js
/**
* Mainnavigation enables user to toggle state of navigation and search related components.
*
* Class properties and decorators are supported.
*
* @module MainNavigation
* @version v1.0.0
*
* @author Christian Rohowski, Oliver Broad
*/
// Imports
import $ from 'jquery';
import Component from '@veams/component';
class MainNavigation extends Component {
/**
* Class Properties
*/
$el = $(this.el);
/**
* Constructor for our class
*
* @see module.js
*
* @param {Object} obj - Object which is passed to our class
* @param {Object} obj.el - element which will be saved in this.el
* @param {Object} obj.options - options which will be passed in as JSON object
*/
constructor(obj) {
let options = {
selectors: {
stackNavToggler: '[data-js-item="toggle-stack-navigation"]',
searchToggler: '[data-js-item="toggle-search"]',
stackNavigation: '[data-js-module="stack-navigation"]'
},
classes: {
active: 'is-active',
expanded: 'is-expanded'
}
};
super(obj, options);
}
/**
* Event & subscribe handling
*/
// Local Handlers
get events() {
return {
'{{context.EVENTS.click}} {{this.options.selectors.searchToggler}}':
'searchTogglerClick'
};
}
get subscribe() { }
/**
* Handle click on search toggler icon
*
* @param {Object} e - Event object
*/
searchTogglerClick(e) {
e.preventDefault();
this.context.Vent.trigger(this.context.EVENTS.searchOverlay.toggle);
}
/**
* Render class
*/
render() {
return this;
}
didMount() {
}
}
export default MainNavigation;
HTML Output
Default
<nav class="c-main-navigation" data-js-module="main-navigation">
<h2 class="main-navigation__headline">Hauptnavigation</h2>
<ul class="main-navigation__list">
<li class="main-navigation__list-item">
<a class="main-navigation__list-link" href="#" title="Link öffnet im neuen Fenster">
<span class="main-navigation__list-link-text">Studium</span>
</a></li>
<li class="main-navigation__list-item">
<a class="main-navigation__list-link" href="#" title="Link öffnet im neuen Fenster">
<span class="main-navigation__list-link-text">Forschung</span>
</a></li>
<li class="main-navigation__list-item">
<a class="main-navigation__list-link" href="#" title="Link öffnet im neuen Fenster">
<span class="main-navigation__list-link-text">Die LMU</span>
</a></li>
<li class="main-navigation__list-item is-bordered is-language">
<a class="main-navigation__list-link" href="#" title="Zur Englischen Sprachversion">
<span class="main-navigation__list-link-text" lang="en">EN</span>
<span class="main-navigation__list-link-text-a11y" lang="en">Zur englischen Sprachversion / Switch to English</span>
</a></li>
<li class="main-navigation__list-item is-bordered is-search">
<button type="button" class="main-navigation__list-link is-search" data-js-item="toggle-search">
<span class="main-navigation__list-link-text">Suche öffnen/schließen</span>
</button></li>
<li class="main-navigation__list-item is-bordered is-last">
<button type="button" class="main-navigation__list-link is-burger" data-js-item="toggle-stack-navigation">
<span class="main-navigation__list-link-text">Erweiterte Navigation öffnen/schließen</span>
</button></li>
<li id="hamburgermenu" class="main-navigation__list-item is-bordered is-last">
<hamburger-menu-app></hamburger-menu-app>
</li>
</ul>
</nav>