JSFiddle - React, Tailwind, and code Playground
by neonDog
HTML
<link rel="stylesheet" href="https://howdoweb.com/themes/media-company/css/style.css">
<link rel="stylesheet" href="https://maxst.icons8.com/vue-static/landings/line-awesome/font-awesome-line-awesome/css/all.min.css">
<div class="page-editor-block nav-container nav-push-content navbar-side-no-log navbar-side navbar-toggler-fixe navbar-show-as-list-group navbar-bar-swap-order annot-toggle" style="min-height: 100vh;">
<nav class="navbar section section-dark bs-color-scheme-2 color-dark" data-id="block-051bc2e6-0c91-468e-90c1-a75f981552f6" style="background: var(--bg-primary)">
<div class="navbar-bar container w-100 h-100">
<a class="navbar-brand navbar-init-hide-item bs-display-light"><img src="https://howdoweb.com/local/howdoweb.com/uploads/images/2020/5/1590625157534_how%20do%20w.svg" alt=""></a>
<a class="navbar-brand navbar-init-hide-item bs-display-dark"><img src="https://howdoweb.com/local/howdoweb.com/uploads/images/2020/6/1593458982467_how%20do%20w_921x953.svg" alt=""></a>
<button class="navbar-toggler collapsed neon-ui-interaction" data-action="toggle-menu">
<span class="icon-bar top-bar"></span>
<span class="icon-bar middle-bar"></span>
<span class="icon-bar bottom-bar"></span>
</button>
</div>
<div class="navbar-inner">
<div class="container w-100 h-100 text-center align-items-end show-as-list-group">
<a class="navbar-brand navbar-init-hide-item bs-display-light"><img src="https://howdoweb.com/local/howdoweb.com/uploads/images/2020/5/1590625157534_how%20do%20w.svg" alt=""></a>
<a class="navbar-brand navbar-init-hide-item bs-display-dark"><img src="https://howdoweb.com/local/howdoweb.com/uploads/images/2020/6/1593458982467_how%20do%20w_921x953.svg" alt=""></a>
<div class="navbar-collapse2">
...
SCSS
.section {
--bg-primary: #4f11d6;
}
.navbar {
padding: 0;
}
.nav-container {
width: 100%;
&.cannot-toggle {
.navbar-toggler {
display: none;
}
}
//Bar logo size
.navbar-brand img {
height: 40px;
}
//Normal logo size
&.navbar-normal {
.navbar-brand {
img {
height: 40px;
}
}
}
//Sidebar image size
&.navbar-side > .navbar > .navbar-inner .navbar-brand {
width: 100%;
//display: none;
img {
width: 75%;
height: initial;
}
}
&.navbar-side-no-logo > .navbar > .navbar-inner > .container > .navbar-brand {
display: none;
}
.navbar-inner {
width: 100%;
}
&.navbar-mobile {
> .navbar {
min-height: 50px;
}
}
&.navbar-side {
//Hide top bar (also requires .navbar-toggler-fixed to completely hide)
&:not(.navbar-mobile) {
> .navbar > .navbar-bar .navbar-brand {
display: none;
}
}
&.navbar-mobile {
.navbar-inner {
margin-top: 50px;
}
}
> .navbar > .navbar-inner {
transform: translate(-300px);
transition: transform 0.45s cubic-bezier(0.77, 0, 0.175, 1);
overflow-x: hidden;
overflow-y: auto;
position: fixed;
top: 0;
left: 0;
bottom: 0;
width: 300px;
z-index: 200;
background: inherit;
> .container {
padding: 0;
display: flex;
flex-direction: column;
}
}
//Slide from the right instead
&.navbar-right > .navbar > .navbar-inner {
transform: translate(300px);
left: initial;
right: 0;
}
.content {
transition: margin 0.45s cubic-bezier(0.77, 0, 0.175, 1);
}
&.open {
> .navbar > .navbar-inner {
transform: translate(0);
}
&.nav-push-content .content {
width: calc(100% - 300px);
margin-left: 300px;
}
&.nav-push-content.navbar-right .content {
...
JavaScript
const slide = async function(open = true, el = null, unit = 'max-height', duration = 500, easing = 'ease-in-out', callback = () => {}) {
const direction = open ? 'normal' : 'reverse';
//const originalStyle = el.getAttribute('style');
if (open) {
//We need to override styles so we can calculate what its final height / width will be
el.setAttribute('style', 'height: auto; max-height: none; visibility:hidden; transition: none; overflow: hidden;'); //display: block / table-row;
}
const bounds = el.getBoundingClientRect();
const length = bounds.height;
const c = window.getComputedStyle(el);
const keyframes = [{
paddingTop: 0,
paddingBottom: 0,
[unit]: 0
}, {
paddingTop: c.paddingTop,
paddingBottom: c.paddingBottom,
[unit]: length + 'px'
}];
//During whole transition, keep overflow hidden
el.setAttribute('style', 'display: block; overflow: hidden; transition: none;'); //display: block / table-row;
//duration += length * 0.5;
const animation = el.animate(keyframes, {
direction,
duration,
easing
}); //iterations: Infinity
return new Promise(resolve => {
//Finish by adding display:none
animation.finished.then(function() {
//Reset style
el.setAttribute('style', !open ? 'overflow: hidden;' : '');
callback(open);
resolve(open);
});
});
}
class NeonTabs {
constructor() {
this.click = this.click.bind(this);
document.addEventListener('click', this.click);
}
click(e) {
let btn = e.target.closest('.neon-tab-trigger');
//console.log(e.target, btn);
if (!btn) return;
const control = btn.closest('.neon-tab-control');
if (control) {
btn = control;
}
const tab = btn.getAttribute('data-tab');
if (!tab) throw new Error('No tab ID');
const container = btn.closest('.neon-tab-container');
if (!container) throw new Error('No container found');
this.select(container, tab);
}
...