Create a slim sidebar style for your analysis file using JavaScript
This slim sidebar is Intended for smooth page navigation
|
How to use
Add a TextArea and edit the HTML. Add the sample html code below and then the provided JavaScript at the end. Just create a new script and copy+paste the code from the sidebar-popup.js into a new JavaScript.
html
Example (no grouping)
<DIV id="sidebar" style="FONT-SIZE: 20px; BACKGROUND: #3498db; COLOR: white"></DIV> <span id="sidebar-logo">C. Corp</span> <DIV id="sidebar-nav" > <a>Page 1</a> <a>Page 2</a> <SpotfireControl (repalce with link spotfire control) /> <a>Page 4</a> <a>Page 5</a> <a>Page 6</a> <a>Page 7</a> <a>Page 8</a> </div> <div id="sidebar-nav-icons" >house,user,circle,box,umbrella,music,heart,gear</div>
Example (with groups)
<DIV id="sidebar" style="FONT-SIZE: 20px; BACKGROUND: #243772; COLOR: white"></DIV> <span id="sidebar-logo"><img src="bffeccd1047746e5bd1a3a11c6048a9d.png" style="border: 0; width: 409px; height: 113px;"/></span> <DIV id="sidebar-nav" > <a>Page 1</a> <li> <a>page 2</a> <a>Page 3</a> </li> <a>Page 4***</a> <li> <a>Page 5</a> <a>Page 6</a> </li> <a>Page 7</a> <li> <a>Page 8</a> </li> </div> <div id="sidebar-nav-icons" >house,user,circle,box,umbrella,music,heart,gear</div>
JavaScript
sidebar-slim.js
sidebar = document.getElementById("sidebar") h=sidebar.offsetParent.offsetHeight; hasLogo = document.querySelector("#sidebar-logo"); fontSize = parseInt(window.getComputedStyle(document.querySelector("#sidebar")).fontSize); hasTrigger = document.querySelector("#sidebar-trigger"); hasFeathers = typeof feather != "undefined"; template = ` <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css" /> <span class="sidebar-trigger" id="showMenuBtn" title="click to show menu"> ${hasTrigger?'':'<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-eye"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>'} </span> <nav class="main-menu"> <ul><li class="sidebar-logo"></li></ul> <ul><li><i><span class="right" id="hideMenuBtn" title="clcik to hide menu" ><svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-eye-off"><path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"/><line x1="1" y1="1" x2="23" y2="23"/></svg></span></i></li></ul> <ul id="navItems" class="sidebar-nav"></ul> </nav> <style> #showMenuBtn { FONT-SIZE: 20px; BACKGROUND: ${sidebar.style.background}; COLOR: ${sidebar.style.color}; width: 25px; text-align: center; border-radius: 15px; cursor: pointer; position: absolute; } #hideMenuBtn{ padding:3px; cursor: pointer; z-index:40; position: absolute; top: -50px;} #navItems li a { position: relative; display: flex; vertical-align: middle; align-items: center; font-size:${fontSize}px; line-height:3; } .submenu { overflow: hidden; max-height: 0; margin-left:2em; -webkit-transition: all 0.5s ease-out; } .submenu:before { content: "▼"; position: absolute; right: 15px; top: ${fontSize*.75}px; } .icon { width: 22.5px; height: 22.5px; margin-right: ${fontSize*1.5-fontSize/2}px; margin-left: ${fontSize*1.5-fontSize/2}px; display: flex; align-items: center; align-content: flex-end; justify-content: center; } .right{ position:absolute; right:10px; } /*when using text as logo*/ .sidebar-logo { color: ${sidebar.style.color}; font-size: 14px; width: 100% !important; top: -7px; padding: 2px; text-align: center; border-bottom: 1px solid white; } /*when using an image as logo*/ .sidebar-logo img{ background: ${sidebar.style.background}; color: ${sidebar.style.color}; height:unset !important; max-width:50% !important; min-width:${fontSize*3}px; } .main-menu:hover,nav.main-menu.expanded { width:260px; overflow:visible; } .main-menu { position:fixed; z-index:10; box-shadow: 3px 3px 10px 1px #888; background: ${sidebar.style.background}; border-right:1px solid #555; height:${h}px; width:${fontSize*3}px ; overflow:hidden; transition:width .05s linear; } .main-menu>ul { margin:7px 0; } .main-menu li { position:relative; display:block; width:260px; } .main-menu li>a { color:${sidebar.style.color}!important; text-decoration:none !important; transition:all .1s linear; width:260+${fontSize}px; } nav ul,nav li { padding:0; } .main-menu li:hover .submenu { max-height: 200px; } </style> ` //move components (ids) to template placeholders (class names) function moveElement(component,templateComponent){ if(templateComponent!=undefined){ if (component.id == "sidebar-nav") { ul = document.getElementById("navItems"); icons = document.querySelector("#sidebar-nav-icons"); if (hasFeathers) icons = icons.innerText.split(",").map(x=>`<i class="icon" data-feather="${x}"></i>`); if (!hasFeathers) icons = icons.innerText.split(",").map(x=>`<i class="icon fa-solid fa-${x}"></i>`); navItems = [...document.querySelectorAll("#sidebar-nav > *")].forEach((x)=>{ if (x.nodeName=="A"){ if(x.innerText.endsWith("***")) x.innerText = x.innerText.replace("***",""); } if (x.nodeName=="A" && x.nextElementSibling?.nodeName!="LI"){ if(x.innerText.endsWith("***")) x.innerText = x.innerText.replace("***",""); li = document.createElement("li"); x.insertAdjacentHTML("afterbegin",icons.shift()); li.append(x); ul.append(li); } if (x.nodeName=="A" && x.nextElementSibling?.nodeName=="LI"){ li = document.createElement("li"); x.insertAdjacentHTML("afterbegin",icons.shift().replace("icon","icon parent")); li.append(x); ul.append(li); } if (x.nodeName=="LI"){ sul = document.createElement("ul"); sul.className="submenu"; [...x.querySelectorAll("a")].forEach(a=>{ if(a.innerText.endsWith("***")) a.innerText = a.innerText.replace("***",""); li = document.createElement("li"); a.insertAdjacentHTML("afterbegin",icons.shift()); li.append(a); sul.append(li); }) ul.lastChild.append(sul); } }); } templateComponent.append(...component.childNodes); } if (!templateComponent) console.log(`⚠️ class ".${component.id}" does not exists on template!`); component.remove(); } sidebar.innerHTML = template //move elements var components = "nav,title,logo,options,controls,nav-icons,trigger"; components = components.split(",").map(x=>{return "#sidebar-"+x}).join(", "); [...document.querySelectorAll(components)].forEach(component=>{templateComponent="."+component.id;moveElement(component,document.querySelector(templateComponent)) }); iconSize = parseInt(window.getComputedStyle(sidebar).getPropertyValue("font-size").replace("px",""))-5+"px"; if (hasFeathers) feather.replace({width:iconSize,height:iconSize}) //show or hide menu function showMenu(isVisible){ document.querySelector(".main-menu").hidden=!isVisible document.getElementById("showMenuBtn").hidden=isVisible; console.log(isVisible) //save state (TBD) window.localStorage.setItem("sidebarVisibleState",isVisible); } document.getElementById("hideMenuBtn").onclick=()=>{showMenu(false)}; document.getElementById("showMenuBtn").onclick=()=>{showMenu(true)}; //load state (TBD) showMenu(JSON.parse(window.localStorage.getItem("sidebarVisibleState")));
See also
JavaScript Sidebar for Spotfire
JavaScript Masthead for Spotfire
IronPython Masthead for Spotfire
Recommended Comments
There are no comments to display.