Hi to everyone !!!
I am developing a multipage app with panel and I need a nice navBar to navigate between different apps served with pn.serve.
I found in youtube this nice sticky IconBar.I utilize it to switch between differents panel apps, but it can be utilized to link to external pages too, and when the datamodel is available, it will be possible to trigger python actions with the icons.
As a sidenote, the new hotloading feature it is really amazing. One thing I needed 2 hours, now I spent only 45 minutes to make it.
Here you have a short video and the code.
iconbar
import panel as pn
import numpy as np
import holoviews as hv
pn.extension()
print ('version', pn.__version__)
material = pn.template.MaterialTemplate(title='Template')
pn.config.sizing_mode = 'stretch_width'
xs = np.linspace(0, np.pi)
freq = pn.widgets.FloatSlider(name="Freqfghuasdassdency", start=0, end=10, value=2)
phase = pn.widgets.FloatSlider(name="Phase", start=0, end=np.pi)
@pn.depends(freq=freq, phase=phase)
def sine(freq, phase):
return hv.Curve((xs, np.sin(xs*freq+phase))).opts(
responsive=True, min_height=400)
@pn.depends(freq=freq, phase=phase)
def cosine(freq, phase):
return hv.Curve((xs, np.cos(xs*freq+phase))).opts(
responsive=True, min_height=400)
material.sidebar.append(freq)
material.sidebar.append(phase)
script = """
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" integrity="sha512-5A8nwdMOWrSz20fDsjczgUidUBR8liPYU+WymTZP1lmY9G6Oc7HlZv156XqnsgNUzTyMefFTcsFH/tnJE/+xBg==" crossorigin="anonymous" />
<style>
*{
margin:0;
padding:0;
box-sizing:border-box;
list-style:none;
text-decoration:none;
font-family:sans-serif;
font-weight:800;
}
nav{
position:fixed;
z-index: 100;
width:50px;
height:200px;
border-radius:10px;
background: #00aa41;
bottom:20px;
left:20px;
box-shadow: 10px 10px 50px #00000055;
}
li{
position:relative;
width:50px;
height:50px;
}
li a{
position:absolute;
top:50%;
left:50%;
transform:translate(-50%,-50%);
}
.fa {
color:white;
}
.info{
display:none;
pointer-events:none;
position:absolute;
color:white;
background:#00aa41;
padding: 7px;
border-radius: 5px;
top:50%;
left:125%;
transform: translate(0%,-50%);
font-size: 0.8rem;
}
.info::before{
position:absolute;
content:"";
width:10px;
height:10px;
background: #00aa41;
top:50%;
left:-5px;
transform: translate(0%,-50%) rotate(45deg);
}
li a:hover ~ .info{
display:block;
}
li:hover{
transform: scale(1.2);
}
</style>
<nav draggable="true">
<ul>
<li><a href="app1" class="link"><i class="fa fa-instagram fa-2x"></i></a><p class="info">Instagram</p></li>
<li><a href="app2" class="link"><i class="fa fa-facebook fa-2x"></i></a><p class="info">Facebook</p></li>
<li><a href="app3" class="link"><i class="fa fa-youtube fa-2x"></i></a><p class="info">Youtube</p></li>
<li><a href="app4" class="link"><i class="fa fa-twitter fa-2x"></i></a><p class="info">Twitter</p></li>
</ul>
</nav>
<script>
iconBar=document.querySelector("nav");
iconBar.ondragend=(e)=>{
iconBar.style.top=e.screenY-window.screenY-200+"px";
iconBar.style.left=e.screenX-window.screenX-50+"px";
}
</script>
"""
material.header.append(
pn.pane.HTML(script, sizing_mode='stretch_both')
)
material.main.append(
pn.Row(
pn.Card(hv.DynamicMap(sine), title='Sine'),
pn.Card(hv.DynamicMap(cosine), title='Cosine')
)
)
material.servable();
Best regards,
N