2019-10-14 09:32:20 +02:00
|
|
|
<script>
|
|
|
|
|
|
|
|
export let items = [];
|
|
|
|
export let hideNavBar=false;
|
|
|
|
export let selectedItem="";
|
|
|
|
export let orientation="horizontal"; // horizontal, verical
|
2019-10-18 18:32:03 +02:00
|
|
|
export let alignment="start"; // start, center, end
|
2019-10-14 09:32:20 +02:00
|
|
|
export let pills=false;
|
|
|
|
export let fill=false;
|
|
|
|
export let _bb;
|
|
|
|
|
|
|
|
let selectedIndex = -1;
|
|
|
|
let styleVars={};
|
|
|
|
let components = {};
|
2019-10-18 18:32:03 +02:00
|
|
|
let componentElement;
|
2019-10-14 09:32:20 +02:00
|
|
|
let orientationClass="";
|
|
|
|
let navClasses="";
|
2019-10-18 18:32:03 +02:00
|
|
|
let currentComponent;
|
|
|
|
let _selectedItem="";
|
2019-10-14 09:32:20 +02:00
|
|
|
|
|
|
|
const hasComponentElements = () =>
|
|
|
|
Object.getOwnPropertyNames(componentElements).length > 0;
|
|
|
|
|
2019-10-18 18:32:03 +02:00
|
|
|
const getSelectedItemByIndex = (index) =>
|
|
|
|
index >= 0
|
|
|
|
? items[index].title
|
|
|
|
: "";
|
|
|
|
|
2019-10-14 09:32:20 +02:00
|
|
|
$: {
|
|
|
|
|
|
|
|
let _navClasses = "";
|
|
|
|
|
|
|
|
if(orientation === "vertical") {
|
|
|
|
_navClasses += " flex-column";
|
|
|
|
} else {
|
|
|
|
_navClasses += ` justify-content-${alignment}`;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(pills)
|
|
|
|
_navClasses += " nav-pills";
|
|
|
|
|
|
|
|
if(fill)
|
|
|
|
_navClasses += " nav-fill nav-justified";
|
|
|
|
|
|
|
|
navClasses = _navClasses;
|
|
|
|
|
2019-10-18 18:32:03 +02:00
|
|
|
|
|
|
|
if(items ) {
|
|
|
|
|
|
|
|
const currentSelectedItem = getSelectedItemByIndex(selectedIndex);
|
|
|
|
|
2019-10-14 09:32:20 +02:00
|
|
|
if(selectedItem && currentSelectedItem !== selectedItem) {
|
|
|
|
let i=0;
|
|
|
|
for(let item of items) {
|
|
|
|
if(item.title === selectedItem) {
|
2019-10-18 18:32:03 +02:00
|
|
|
SelectItem(i);
|
2019-10-14 09:32:20 +02:00
|
|
|
}
|
|
|
|
i++;
|
|
|
|
}
|
2019-10-18 18:32:03 +02:00
|
|
|
} else if(!selectedItem) {
|
|
|
|
SelectItem(-1);
|
2019-10-14 09:32:20 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-18 18:32:03 +02:00
|
|
|
const SelectItem = (index) => {
|
|
|
|
|
2019-10-14 09:32:20 +02:00
|
|
|
selectedIndex = index;
|
2019-10-18 18:32:03 +02:00
|
|
|
const newSelectedItem = getSelectedItemByIndex(index);
|
|
|
|
if(newSelectedItem !== selectedItem) {
|
|
|
|
selectedItem = newSelectedItem;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(currentComponent) {
|
|
|
|
try {
|
|
|
|
currentComponent.$destroy();
|
|
|
|
} catch(_) {}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(index >= 0)
|
|
|
|
currentComponent = _bb.hydrateComponent(
|
|
|
|
items[index].component, componentElement);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
const onSelectItemClicked = index => () => {
|
|
|
|
if(_bb.bindings["selectedItem"]) {
|
|
|
|
// binding - call state, which should SelectItem(..)
|
|
|
|
const selectedItemBinding = _bb.bindings["selectedItem"];
|
|
|
|
_bb.setStateFromBinding(
|
|
|
|
selectedItemBinding, getSelectedItemByIndex(index))
|
|
|
|
} else {
|
|
|
|
// no binding - call this
|
|
|
|
SelectItem(index);
|
2019-10-14 09:32:20 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<div class="root">
|
|
|
|
{#if !hideNavBar}
|
2019-10-18 18:32:03 +02:00
|
|
|
<ul class="nav {navClasses}">
|
2019-10-14 09:32:20 +02:00
|
|
|
{#each items as navItem, index}
|
2019-10-18 18:32:03 +02:00
|
|
|
<li class="nav-item">
|
|
|
|
<button class="nav-link btn btn-link"
|
|
|
|
on:click={onSelectItemClicked(index)}
|
|
|
|
class:disabled={navItem.disabled}
|
|
|
|
class:active={selectedIndex === index}>
|
|
|
|
{navItem.title}
|
|
|
|
</button>
|
|
|
|
</li>
|
2019-10-14 09:32:20 +02:00
|
|
|
{/each}
|
2019-10-18 18:32:03 +02:00
|
|
|
</ul>
|
2019-10-14 09:32:20 +02:00
|
|
|
{/if}
|
|
|
|
{#each items as navItem, index}
|
|
|
|
|
2019-10-18 18:32:03 +02:00
|
|
|
<div bind:this={componentElement}>
|
2019-10-14 09:32:20 +02:00
|
|
|
</div>
|
|
|
|
{/each}
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<style>
|
|
|
|
|
|
|
|
.root {
|
|
|
|
height: 100%;
|
|
|
|
width:100%;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
</style>
|
|
|
|
|