mirror of
https://github.com/manilarome/the-glorious-startpage.git
synced 2025-01-08 06:18:54 +01:00
web menu gui and backend
This commit is contained in:
parent
b117869435
commit
bef2769676
@ -15,6 +15,7 @@
|
|||||||
@import url('theme-engine.css');
|
@import url('theme-engine.css');
|
||||||
@import url('weather-screen.css');
|
@import url('weather-screen.css');
|
||||||
@import url('weather-settings.css');
|
@import url('weather-settings.css');
|
||||||
|
@import url('web-menu.css');
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
/* Colors */
|
/* Colors */
|
||||||
|
245
css/web-menu.css
Normal file
245
css/web-menu.css
Normal file
@ -0,0 +1,245 @@
|
|||||||
|
#webMenu {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
background: var(--panel-bg);
|
||||||
|
z-index: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
backdrop-filter: blur(var(--blur-strength));
|
||||||
|
|
||||||
|
padding-top: 6vh;
|
||||||
|
padding-bottom: 6vh;
|
||||||
|
padding-left: 12vw;
|
||||||
|
padding-right: 12vw;
|
||||||
|
|
||||||
|
/*Dont increase the geometry by using padding*/
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
-moz-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
/*Disable user touch/select on text elements*/
|
||||||
|
-webkit-touch-callout: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-khtml-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
|
||||||
|
/*Transitions*/
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(0);
|
||||||
|
transition: transform var(--transition-speed),
|
||||||
|
opacity var(--transition-speed),
|
||||||
|
z-index var(--transition-speed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 580px) {
|
||||||
|
#webMenu {
|
||||||
|
padding-top: 6vh;
|
||||||
|
padding-bottom: 0vh;
|
||||||
|
padding-left: 18vw;
|
||||||
|
padding-right: 18vw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-height: 799px) {
|
||||||
|
#webMenu {
|
||||||
|
padding-top: 40px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Show web menu*/
|
||||||
|
.showWebMenu {
|
||||||
|
transform: scale(1) !important;
|
||||||
|
opacity: 1 !important;
|
||||||
|
z-index: 3 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#webMenuContainer {
|
||||||
|
background: transparent;
|
||||||
|
max-height: 100%;
|
||||||
|
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
#webMenuSearchBox {
|
||||||
|
background: var(--base-container);
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
font-family: roboto-bold;
|
||||||
|
color: var(--panel-color);
|
||||||
|
|
||||||
|
border: none;
|
||||||
|
border-radius: 6px;
|
||||||
|
|
||||||
|
width: 25%;
|
||||||
|
height: 36px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 580px) {
|
||||||
|
#webMenuSearchBox {
|
||||||
|
width: 50vw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#webMenuSearchBoxContainer {
|
||||||
|
/*Center horizontally*/
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column wrap;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Web menu list*/
|
||||||
|
|
||||||
|
/*UL*/
|
||||||
|
#webMenuList {
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0 auto;
|
||||||
|
text-align: justify;
|
||||||
|
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*List*/
|
||||||
|
#webMenuList li {
|
||||||
|
/*Align list horizontally*/
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 580px) {
|
||||||
|
#webMenuList li {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#webMenuList li.selected {
|
||||||
|
background: var(--base-active-bg);
|
||||||
|
border-radius: var(--rounded-radius);
|
||||||
|
transition: transform var(--transition-speed);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Child of li*/
|
||||||
|
.webItem {
|
||||||
|
background: transparent;
|
||||||
|
width: 128px;
|
||||||
|
height: 128px;
|
||||||
|
margin: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: var(--rounded-radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
.webItem:hover {
|
||||||
|
background: var(--base-hover-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.webItem:active {
|
||||||
|
background: var(--base-active-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.webItemFocus {
|
||||||
|
width: 128px;
|
||||||
|
height: 128px;
|
||||||
|
margin: 5px;
|
||||||
|
border-radius: var(--rounded-radius);
|
||||||
|
background: var(--base-hover-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.webItemFocus:hover {
|
||||||
|
background: var(--base-hover-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.webItemFocus:active {
|
||||||
|
background: var(--base-active-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Contains web icon and label*/
|
||||||
|
.webItemContainer {
|
||||||
|
/*Align vertically*/
|
||||||
|
margin:0 auto;
|
||||||
|
position: relative;
|
||||||
|
top: 50%;
|
||||||
|
-webkit-transform: translateY(-50%);
|
||||||
|
|
||||||
|
/*Align horizontally*/
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Web icon container*/
|
||||||
|
.webItemIconContainer {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column wrap;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.webItemIcon {
|
||||||
|
height: 64px;
|
||||||
|
width: 64px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Web label/name*/
|
||||||
|
.webItemName {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 11pt;
|
||||||
|
font-family: roboto;
|
||||||
|
word-wrap: break-word;
|
||||||
|
color: var(--base-color);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#webMenuListContainer {
|
||||||
|
position: relative;
|
||||||
|
max-height: 70vh;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
overflow-y: scroll;
|
||||||
|
/*scrollbar-width: none !important;
|
||||||
|
-ms-overflow-style: none !important;*/
|
||||||
|
|
||||||
|
/*Fade transparency*/
|
||||||
|
/*-webkit-mask-image: linear-gradient(to bottom, black 85%, transparent 100%);*/
|
||||||
|
/*mask-image: linear-gradient(to bottom, black 85%, transparent 100%);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Hide scrollbar*/
|
||||||
|
/*#webMenuListContainer::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/*Stretch list item if screen width < 580px*/
|
||||||
|
@media screen and (max-width: 580px) {
|
||||||
|
#webMenuList {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.webItem {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.webItem:hover {
|
||||||
|
-ms-transform: scale(1);
|
||||||
|
-webkit-transform: scale(1);
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.webItemFocus {
|
||||||
|
-ms-transform: scale(1);
|
||||||
|
-webkit-transform: scale(1);
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
}
|
18
index.html
18
index.html
@ -167,9 +167,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="dashboardOverlay" id="dashboardOverlay"></div>
|
<div class="dashboardOverlay" id="dashboardOverlay"></div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Weather screen -->
|
<!-- Weather screen -->
|
||||||
<div id="weatherScreen">
|
<div id="weatherScreen">
|
||||||
<div id="weatherScreenContainer">
|
<div id="weatherScreenContainer">
|
||||||
@ -203,7 +200,21 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Web menu panel -->
|
||||||
|
<div id="webMenu">
|
||||||
|
<div id="webMenuContainer">
|
||||||
|
<div id="webMenuSearchBoxContainer">
|
||||||
|
<input type="text" id="webMenuSearchBox" autocomplete="off" placeholder="Type to search">
|
||||||
|
</div>
|
||||||
|
<div id="webMenuListContainer">
|
||||||
|
|
||||||
|
<ul id="webMenuList">
|
||||||
|
<!-- Javascript will generate a list here -->
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<script src="js/body-background-set.js"></script>
|
<script src="js/body-background-set.js"></script>
|
||||||
@ -219,5 +230,6 @@
|
|||||||
<script src="js/theme-engine.js"></script>
|
<script src="js/theme-engine.js"></script>
|
||||||
<script src="js/weather-screen.js"></script>
|
<script src="js/weather-screen.js"></script>
|
||||||
<script src="js/weather-settings.js"></script>
|
<script src="js/weather-settings.js"></script>
|
||||||
|
<script src="js/web-menu.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
@ -25,11 +25,11 @@ const hideDashboard = () => {
|
|||||||
const toggleDashboard = () => {
|
const toggleDashboard = () => {
|
||||||
|
|
||||||
if (rightDashboardVisibility) {
|
if (rightDashboardVisibility) {
|
||||||
// Hide search box
|
// Hide dashboard
|
||||||
hideDashboard();
|
hideDashboard();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Show search box
|
// Show dashboard
|
||||||
showDashboard();
|
showDashboard();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,8 +66,8 @@ const populateDock = () => {
|
|||||||
'Launch',
|
'Launch',
|
||||||
'launch',
|
'launch',
|
||||||
() => {
|
() => {
|
||||||
// Toggle web pad
|
// Toggle web menu
|
||||||
alert('toggle web pad');
|
toggleWebMenu();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
341
js/web-menu.js
Normal file
341
js/web-menu.js
Normal file
@ -0,0 +1,341 @@
|
|||||||
|
var webMenu = document.getElementById("webMenu");
|
||||||
|
var webMenuList = document.getElementById("webMenuList");
|
||||||
|
var webMenuListContainer = document.getElementById("webMenuListContainer");
|
||||||
|
var webMenuSearchBox = document.getElementById("webMenuSearchBox");
|
||||||
|
|
||||||
|
let webMenuVisibility = false;
|
||||||
|
|
||||||
|
let webItemFocus;
|
||||||
|
let webListIndex = 0;
|
||||||
|
|
||||||
|
// Create mouse event for passed li
|
||||||
|
const createMouseUpEvent = (li, url) => {
|
||||||
|
// Create a callback property for the passed li
|
||||||
|
li.callback = () => {
|
||||||
|
window.location.href = encodeURI(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create onmouseup event for the li
|
||||||
|
li.onmouseup = () => {
|
||||||
|
li.callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort list alphabetically
|
||||||
|
const sortList = () => {
|
||||||
|
Array.from(webMenuList.getElementsByTagName("li"))
|
||||||
|
.sort((a, b) => a.textContent.localeCompare(b.textContent))
|
||||||
|
.forEach(li => webMenuList.appendChild(li));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Populate web menu
|
||||||
|
const populateWebMenu = () => {
|
||||||
|
|
||||||
|
// Generate a list
|
||||||
|
for (i = 0; i < (webSites.length); i++) {
|
||||||
|
|
||||||
|
var site = webSites[i].site;
|
||||||
|
var icon = webSites[i].icon;
|
||||||
|
var url = webSites[i].url;
|
||||||
|
|
||||||
|
var li = document.createElement('li');
|
||||||
|
|
||||||
|
// Add mouseup event
|
||||||
|
createMouseUpEvent(li, url);
|
||||||
|
|
||||||
|
// Create an outer div, child of li
|
||||||
|
let webItemDiv = document.createElement('div')
|
||||||
|
webItemDiv.className = 'webItem';
|
||||||
|
// webItemDiv.tabitemIndex = '1';
|
||||||
|
webItemDiv.id = "id" + site;
|
||||||
|
|
||||||
|
// Create a second div, webItemContainer
|
||||||
|
var webItemContainer = document.createElement('div');
|
||||||
|
webItemContainer.className = 'webItemContainer';
|
||||||
|
|
||||||
|
// Create the innermost div, contains icon and label
|
||||||
|
var webItemBody = document.createElement('div');
|
||||||
|
webItemBody.className = 'webItemBody';
|
||||||
|
|
||||||
|
// Create div for webItemIcon
|
||||||
|
var webItemIconContainer = document.createElement('div');
|
||||||
|
webItemIconContainer.className = 'webItemIconContainer';
|
||||||
|
|
||||||
|
var webItemIcon = document.createElement('div');
|
||||||
|
webItemIcon.className = 'webItemIcon';
|
||||||
|
webItemIcon.style.background = "url('assets/webcons/" + icon + ".svg')";
|
||||||
|
webItemIcon.style.backgroundSize = 'cover';
|
||||||
|
|
||||||
|
// Create webItemName
|
||||||
|
var webItemName = document.createElement('div');
|
||||||
|
webItemName.className = 'webItemName';
|
||||||
|
webItemName.innerHTML = site;
|
||||||
|
|
||||||
|
// Append divs with heirarchy
|
||||||
|
webItemDiv.appendChild(webItemContainer);
|
||||||
|
webItemContainer.appendChild(webItemBody);
|
||||||
|
|
||||||
|
webItemIconContainer.appendChild(webItemIcon);
|
||||||
|
webItemBody.appendChild(webItemIconContainer);
|
||||||
|
webItemBody.appendChild(webItemName);
|
||||||
|
|
||||||
|
li.appendChild(webItemDiv);
|
||||||
|
webMenuList.appendChild(li);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call to sort list
|
||||||
|
sortList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fuzzy search
|
||||||
|
String.prototype.fuzzy = (term, ratio) => {
|
||||||
|
var string = this.toLowerCase();
|
||||||
|
var compare = term.toLowerCase();
|
||||||
|
var matches = 0;
|
||||||
|
|
||||||
|
if (string.indexOf(compare) > -1) return true; // covers basic partial matches
|
||||||
|
for (var i = 0; i < compare.length; i++) {
|
||||||
|
string.indexOf(compare[i]) > -1 ? matches += 1 : matches -=1;
|
||||||
|
}
|
||||||
|
return (matches/this.length >= ratio || term == "");
|
||||||
|
};
|
||||||
|
|
||||||
|
// Search through the list
|
||||||
|
const filterWebList = () => {
|
||||||
|
|
||||||
|
var input, filter, ul, li, a, i, txtValue;
|
||||||
|
|
||||||
|
input = webMenuSearchBox;
|
||||||
|
filter = input.value.toUpperCase();
|
||||||
|
ul = webMenuList;
|
||||||
|
li = ul.getElementsByTagName('li');
|
||||||
|
|
||||||
|
// Loop through all list items, and focus if matches the search query
|
||||||
|
for (i = 0; i < li.length; i++) {
|
||||||
|
|
||||||
|
a = li[i].getElementsByClassName("webItemName")[0];
|
||||||
|
txtValue = a.innerHTML || a.textContent || a.innerText;
|
||||||
|
|
||||||
|
// If an item match, hightlight it and focus
|
||||||
|
// if (txtValue.toUpperCase().indexOf(filter) !== -1) {
|
||||||
|
if (txtValue.toUpperCase().fuzzy(filter, 1) === true) {
|
||||||
|
|
||||||
|
// Unselect/Unhightlight old active
|
||||||
|
var oldWebItemFocus = webItemFocus;
|
||||||
|
var oldWebItemFocusChild = oldWebItemFocus.querySelector('.webItem');
|
||||||
|
oldWebItemFocusChild.classList.remove('webItemFocus');
|
||||||
|
|
||||||
|
// Update webItemFocus
|
||||||
|
webItemFocus = li[i];
|
||||||
|
|
||||||
|
// Update weblistindex
|
||||||
|
webListIndex = i;
|
||||||
|
|
||||||
|
// Get child
|
||||||
|
var webItemFocusChild = webItemFocus.querySelector('.webItem');
|
||||||
|
// Add webItemFocus class to child
|
||||||
|
webItemFocusChild.classList.add('webItemFocus');
|
||||||
|
|
||||||
|
// Scroll focus into active
|
||||||
|
webItemFocus.scrollIntoView();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type event on web mmenu search box
|
||||||
|
webMenuSearchBox.onkeydown = (event) => {
|
||||||
|
|
||||||
|
// Don't hijack keyboard navigation buttons (up, down, left, right)
|
||||||
|
if ((event.key === 'ArrowRight') || (event.key === 'ArrowDown') ||
|
||||||
|
(event.key === 'ArrowLeft') || (event.key === 'ArrowUp')) return;
|
||||||
|
|
||||||
|
if (event.key === 'Enter' && webItemFocus) {
|
||||||
|
// Run the focused li's callback
|
||||||
|
webItemFocus.callback();
|
||||||
|
|
||||||
|
// Hide web menu
|
||||||
|
// webMenuToggle();
|
||||||
|
|
||||||
|
} else if (event.key === 'Backspace' && webMenuSearchBox.value.length < 1) {
|
||||||
|
// Hide web menu if backspace is pressed and searchbox value is 0
|
||||||
|
// webMenuToggle();
|
||||||
|
|
||||||
|
} else if ((event.key === 'Escape') || (event.key === 'Alt')) {
|
||||||
|
// Ignore escape and alt key
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter
|
||||||
|
filterWebList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset focus on web menu close
|
||||||
|
const focusReset = () => {
|
||||||
|
var oldWebItemFocus = webItemFocus;
|
||||||
|
var oldWebItemFocusChild = oldWebItemFocus.querySelector('.webItem');
|
||||||
|
oldWebItemFocusChild.classList.remove('webItemFocus');
|
||||||
|
webListIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get first item of ul
|
||||||
|
const getFirstItem = () => {
|
||||||
|
var ul = webMenuList;
|
||||||
|
var li = ul.getElementsByTagName('li');
|
||||||
|
|
||||||
|
// Focus on first item
|
||||||
|
webItemFocus = li[0];
|
||||||
|
|
||||||
|
// Get child
|
||||||
|
var webItemFocusChildren = webItemFocus.querySelector('.webItem');
|
||||||
|
|
||||||
|
// Add webItemFocus class
|
||||||
|
webItemFocusChildren.classList.add('webItemFocus');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show/Hide web menu
|
||||||
|
// const webMenuToggle = () => {
|
||||||
|
|
||||||
|
// webMenuVisible = !webMenuVisible;
|
||||||
|
|
||||||
|
// hideCenterContainer();
|
||||||
|
// rotateProfile();
|
||||||
|
// webMenu.classList.toggle("show");
|
||||||
|
|
||||||
|
// // Clear and unfocus searchbox
|
||||||
|
// if (!webMenuVisible) {
|
||||||
|
// webMenuSearchBox.value = '';
|
||||||
|
// webMenuSearchBox.blur();
|
||||||
|
// filterWebList();
|
||||||
|
// webMenuListContainer.scrollTop = 0;
|
||||||
|
|
||||||
|
// focusReset();
|
||||||
|
// getFirstItem();
|
||||||
|
// } else {
|
||||||
|
// // Focus
|
||||||
|
// webMenuSearchBox.focus();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if(weatherVisible && webMenuVisible) {
|
||||||
|
// weatherToggle();
|
||||||
|
// } else if (floatPanelVisible && webMenuVisible) {
|
||||||
|
// slideDashboard();
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
const showWebMenu = () => {
|
||||||
|
webMenu.classList.add('showWebMenu');
|
||||||
|
webMenuVisibility = !webMenuVisibility;
|
||||||
|
}
|
||||||
|
|
||||||
|
const hideWebMenu = () => {
|
||||||
|
webMenu.classList.remove('showWebMenu');
|
||||||
|
webMenuVisibility = !webMenuVisibility;
|
||||||
|
}
|
||||||
|
|
||||||
|
const toggleWebMenu = () => {
|
||||||
|
|
||||||
|
// If profile anim is still running,
|
||||||
|
// Return to avoid spam
|
||||||
|
if (profileAnimRunning) return;
|
||||||
|
|
||||||
|
// Rotate profile
|
||||||
|
rotateProfile();
|
||||||
|
|
||||||
|
if (webMenuVisibility) {
|
||||||
|
// Hide web menu
|
||||||
|
hideWebMenu();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Show Web menu
|
||||||
|
showWebMenu();
|
||||||
|
}
|
||||||
|
console.log('toggle web menu');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Remove class to focused item
|
||||||
|
const removeClass = (el, className) => {
|
||||||
|
// Remove webItemFocus class
|
||||||
|
var oldWebItemFocus = el.querySelector('.webItem');
|
||||||
|
oldWebItemFocus.classList.remove('webItemFocus');
|
||||||
|
};
|
||||||
|
|
||||||
|
// Add class to focused item
|
||||||
|
const addClass = (el, className) => {
|
||||||
|
var webItemFocusChild = el.querySelector('.webItem');
|
||||||
|
|
||||||
|
// Add webItemFocus class to child
|
||||||
|
webItemFocusChild.classList.add('webItemFocus');
|
||||||
|
|
||||||
|
// Scroll focus into active
|
||||||
|
webItemFocusChild.scrollIntoView();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Keyboard navigation
|
||||||
|
webMenu.addEventListener(
|
||||||
|
'keydown',
|
||||||
|
(event) => {
|
||||||
|
var len = webMenuList.getElementsByTagName('li').length - 1;
|
||||||
|
// Right and Down
|
||||||
|
if((event.which === 39) || (event.which === 40)) {
|
||||||
|
|
||||||
|
// Clear web menu searchbox
|
||||||
|
webMenuSearchBox.value = '';
|
||||||
|
webListIndex++;
|
||||||
|
if (webItemFocus) {
|
||||||
|
removeClass(webItemFocus, 'webItemFocus');
|
||||||
|
next = webMenuList.getElementsByTagName('li')[webListIndex];
|
||||||
|
if(typeof next !== undefined && webListIndex <= len) {
|
||||||
|
webItemFocus = next;
|
||||||
|
} else {
|
||||||
|
webListIndex = 0;
|
||||||
|
webItemFocus = webMenuList.getElementsByTagName('li')[0];
|
||||||
|
}
|
||||||
|
addClass(webItemFocus, 'webItemFocus');
|
||||||
|
// console.log(webListIndex);
|
||||||
|
} else {
|
||||||
|
webListIndex = 0;
|
||||||
|
webItemFocus = webMenuList.getElementsByTagName('li')[0];
|
||||||
|
addClass(webItemFocus, 'webItemFocus');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Up and left
|
||||||
|
else if ((event.which === 37) || (event.which === 38)) {
|
||||||
|
|
||||||
|
// Clear web menu searchbox
|
||||||
|
webMenuSearchBox.value = '';
|
||||||
|
if (webItemFocus) {
|
||||||
|
removeClass(webItemFocus, 'webItemFocus');
|
||||||
|
webListIndex--;
|
||||||
|
// console.log(webListIndex);
|
||||||
|
next = webMenuList.getElementsByTagName('li')[webListIndex];
|
||||||
|
if(typeof next !== undefined && webListIndex >= 0) {
|
||||||
|
webItemFocus = next;
|
||||||
|
} else {
|
||||||
|
webListIndex = len;
|
||||||
|
webItemFocus = webMenuList.getElementsByTagName('li')[len];
|
||||||
|
}
|
||||||
|
addClass(webItemFocus, 'webItemFocus');
|
||||||
|
} else {
|
||||||
|
webListIndex = 0;
|
||||||
|
webItemFocus = webMenuList.getElementsByTagName('li')[len];
|
||||||
|
addClass(webItemFocus, 'webItemFocus');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
// Populate and get first child
|
||||||
|
const initWebMenu = () => {
|
||||||
|
populateWebMenu();
|
||||||
|
getFirstItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize web menu
|
||||||
|
window.onload = initWebMenu();
|
Loading…
Reference in New Issue
Block a user