2021-06-11 14:47:57 +02:00
|
|
|
<script>
|
|
|
|
import { getContext } from "svelte"
|
2021-06-14 17:19:49 +02:00
|
|
|
import { ActionButton, Heading } from "@budibase/bbui"
|
2021-06-11 14:47:57 +02:00
|
|
|
|
2021-06-14 17:19:49 +02:00
|
|
|
const { styleable, linkable } = getContext("sdk")
|
2021-06-11 14:47:57 +02:00
|
|
|
const component = getContext("component")
|
2021-06-14 17:19:49 +02:00
|
|
|
|
2021-06-11 14:47:57 +02:00
|
|
|
export let title = ""
|
|
|
|
export let hideTitle = false
|
|
|
|
export let logoUrl = "https://i.imgur.com/Xhdt1YP.png"
|
|
|
|
export let hideLogo = false
|
|
|
|
export let navigation = "Top"
|
2021-06-14 19:24:02 +02:00
|
|
|
export let sticky = true
|
2021-06-14 17:19:49 +02:00
|
|
|
|
2021-06-11 14:47:57 +02:00
|
|
|
export let links = [
|
|
|
|
{ text: "Some Text", url: "/" },
|
|
|
|
{ text: "Some Text", url: "/" },
|
|
|
|
]
|
2021-06-14 17:19:49 +02:00
|
|
|
|
|
|
|
const navigationClasses = {
|
|
|
|
Top: "top",
|
|
|
|
Left: "left",
|
|
|
|
None: "none",
|
|
|
|
}
|
|
|
|
|
|
|
|
$: type = navigationClasses[navigation] || "none"
|
|
|
|
let mobileOpen = false
|
2021-06-11 14:47:57 +02:00
|
|
|
</script>
|
|
|
|
|
2021-06-14 17:19:49 +02:00
|
|
|
<div class="layout layout--{type}" use:styleable={$component.styles}>
|
|
|
|
{#if type !== "none"}
|
2021-06-14 19:24:02 +02:00
|
|
|
<div class="nav-wrapper" class:sticky>
|
2021-06-14 17:19:49 +02:00
|
|
|
<div class="nav nav--{type}">
|
|
|
|
<div class="burger">
|
|
|
|
<ActionButton
|
|
|
|
quiet
|
|
|
|
icon="ShowMenu"
|
|
|
|
on:click={() => (mobileOpen = !mobileOpen)}
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="logo">
|
|
|
|
{#if !hideLogo}
|
|
|
|
<img src="https://i.imgur.com/Xhdt1YP.png" alt={title} />
|
|
|
|
{/if}
|
|
|
|
{#if !hideTitle}
|
|
|
|
<Heading>{title}</Heading>
|
|
|
|
{/if}
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="portal">
|
|
|
|
<ActionButton quiet icon="Apps" on:click />
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div
|
|
|
|
class="mobile-click-handler"
|
|
|
|
class:visible={mobileOpen}
|
|
|
|
on:click={() => (mobileOpen = false)}
|
|
|
|
/>
|
|
|
|
<div class="links" class:visible={mobileOpen}>
|
|
|
|
{#each links as { text, url, external }}
|
|
|
|
{#if external}
|
|
|
|
<a class="link" href={url}>{text}</a>
|
|
|
|
{:else}
|
|
|
|
<a class="link" href={url} use:linkable>{text}</a>
|
|
|
|
{/if}
|
|
|
|
{/each}
|
|
|
|
<div class="close">
|
|
|
|
<ActionButton
|
|
|
|
quiet
|
|
|
|
icon="Close"
|
|
|
|
on:click={() => (mobileOpen = false)}
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</div>
|
2021-06-11 14:47:57 +02:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
{/if}
|
2021-06-14 17:19:49 +02:00
|
|
|
<div class="main-wrapper">
|
|
|
|
<div class="main">
|
|
|
|
<slot />
|
|
|
|
</div>
|
2021-06-11 14:47:57 +02:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<style>
|
2021-06-14 17:19:49 +02:00
|
|
|
/* Main components */
|
|
|
|
.layout {
|
2021-06-14 19:24:02 +02:00
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
|
|
|
justify-content: flex-start;
|
|
|
|
align-items: stretch;
|
|
|
|
height: 100%;
|
|
|
|
overflow: auto;
|
2021-06-14 17:19:49 +02:00
|
|
|
}
|
2021-06-14 19:24:02 +02:00
|
|
|
|
2021-06-14 17:19:49 +02:00
|
|
|
.nav-wrapper {
|
|
|
|
display: flex;
|
|
|
|
flex-direction: row;
|
|
|
|
justify-content: center;
|
|
|
|
align-items: stretch;
|
|
|
|
background: white;
|
2021-06-14 19:24:02 +02:00
|
|
|
z-index: 1;
|
|
|
|
}
|
|
|
|
.layout--top .nav-wrapper.sticky {
|
|
|
|
position: sticky;
|
|
|
|
top: 0;
|
|
|
|
left: 0;
|
|
|
|
box-shadow: 0 0 8px -1px rgba(0, 0, 0, 0.075);
|
2021-06-11 14:47:57 +02:00
|
|
|
}
|
2021-06-14 19:24:02 +02:00
|
|
|
|
2021-06-11 14:47:57 +02:00
|
|
|
.nav {
|
2021-06-14 17:19:49 +02:00
|
|
|
flex: 1 1 auto;
|
2021-06-11 14:47:57 +02:00
|
|
|
display: grid;
|
2021-06-14 17:19:49 +02:00
|
|
|
padding: var(--spacing-xl);
|
|
|
|
max-width: 1400px;
|
|
|
|
grid-template-columns: 1fr auto;
|
2021-06-11 14:47:57 +02:00
|
|
|
}
|
2021-06-14 17:19:49 +02:00
|
|
|
.main-wrapper {
|
|
|
|
display: flex;
|
|
|
|
flex-direction: row;
|
|
|
|
justify-content: center;
|
|
|
|
align-items: stretch;
|
2021-06-14 19:24:02 +02:00
|
|
|
flex: 1 1 auto;
|
2021-06-14 17:19:49 +02:00
|
|
|
}
|
|
|
|
.main {
|
|
|
|
flex: 1 1 auto;
|
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
|
|
|
justify-content: flex-start;
|
|
|
|
align-items: stretch;
|
|
|
|
max-width: 1400px;
|
2021-06-14 19:24:02 +02:00
|
|
|
position: relative;
|
2021-06-14 17:19:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Nav components */
|
|
|
|
.burger {
|
|
|
|
display: none;
|
2021-06-11 14:47:57 +02:00
|
|
|
}
|
|
|
|
.logo {
|
2021-06-14 17:19:49 +02:00
|
|
|
display: flex;
|
|
|
|
flex-direction: row;
|
|
|
|
justify-content: flex-start;
|
|
|
|
align-items: center;
|
|
|
|
gap: var(--spacing-xl);
|
|
|
|
grid-column: 1;
|
|
|
|
}
|
|
|
|
.logo img {
|
|
|
|
height: 48px;
|
2021-06-11 14:47:57 +02:00
|
|
|
}
|
|
|
|
.portal {
|
|
|
|
display: grid;
|
2021-06-14 17:19:49 +02:00
|
|
|
justify-items: center;
|
|
|
|
align-items: center;
|
|
|
|
grid-column: 2;
|
|
|
|
}
|
|
|
|
.links {
|
|
|
|
display: flex;
|
|
|
|
flex-direction: row;
|
|
|
|
justify-content: flex-start;
|
|
|
|
align-items: center;
|
|
|
|
gap: var(--spacing-l);
|
|
|
|
grid-column: 1 / 3;
|
|
|
|
grid-row: 2;
|
|
|
|
}
|
|
|
|
.link {
|
|
|
|
color: var(--spectrum-alias-text-color);
|
|
|
|
font-size: var(--spectrum-alias-font-size-default);
|
|
|
|
font-weight: 600;
|
|
|
|
transition: color 130ms ease-out;
|
|
|
|
}
|
|
|
|
.link:hover {
|
|
|
|
color: var(--spectrum-alias-text-color-hover);
|
|
|
|
}
|
|
|
|
.close {
|
|
|
|
display: none;
|
|
|
|
position: absolute;
|
|
|
|
top: var(--spacing-m);
|
|
|
|
right: var(--spacing-m);
|
|
|
|
}
|
|
|
|
.mobile-click-handler {
|
|
|
|
display: none;
|
2021-06-11 14:47:57 +02:00
|
|
|
}
|
|
|
|
|
2021-06-14 17:19:49 +02:00
|
|
|
/* Desktop nav overrides */
|
2021-06-11 14:47:57 +02:00
|
|
|
@media (min-width: 600px) {
|
2021-06-14 17:19:49 +02:00
|
|
|
.layout--left {
|
2021-06-14 19:24:02 +02:00
|
|
|
flex-direction: row;
|
|
|
|
overflow: hidden;
|
|
|
|
}
|
|
|
|
.layout--left .main-wrapper {
|
2021-06-14 17:19:49 +02:00
|
|
|
height: 100%;
|
2021-06-14 19:24:02 +02:00
|
|
|
overflow: auto;
|
2021-06-14 17:19:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
.nav--top {
|
|
|
|
grid-template-rows: auto auto;
|
|
|
|
justify-content: space-between;
|
|
|
|
gap: var(--spacing-xl);
|
|
|
|
}
|
|
|
|
.nav--left {
|
|
|
|
grid-template-rows: auto 1fr;
|
|
|
|
width: 250px;
|
|
|
|
gap: var(--spacing-m);
|
|
|
|
}
|
|
|
|
|
|
|
|
.nav--top .links {
|
|
|
|
margin-top: var(--spacing-l);
|
2021-06-11 14:47:57 +02:00
|
|
|
}
|
2021-06-14 17:19:49 +02:00
|
|
|
.nav--left .logo {
|
|
|
|
gap: var(--spacing-m);
|
|
|
|
}
|
|
|
|
.nav--left .logo img {
|
|
|
|
height: 28px;
|
|
|
|
}
|
|
|
|
.nav--left .logo :global(h1) {
|
|
|
|
font-size: var(--spectrum-global-dimension-font-size-100);
|
|
|
|
font-weight: 600;
|
|
|
|
white-space: nowrap;
|
|
|
|
overflow: hidden;
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
width: 0;
|
|
|
|
flex: 1 1 auto;
|
|
|
|
}
|
|
|
|
.nav--left .links {
|
|
|
|
margin-top: var(--spacing-l);
|
|
|
|
flex-direction: column;
|
|
|
|
justify-content: flex-start;
|
|
|
|
align-items: stretch;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Mobile nav overrides */
|
|
|
|
@media (max-width: 600px) {
|
2021-06-14 19:24:02 +02:00
|
|
|
.nav-wrapper {
|
|
|
|
position: sticky;
|
|
|
|
top: 0;
|
|
|
|
left: 0;
|
|
|
|
box-shadow: 0 0 8px -1px rgba(0, 0, 0, 0.075);
|
2021-06-14 17:19:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Show close button in drawer */
|
|
|
|
.close {
|
|
|
|
display: block;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Force standard top bar */
|
|
|
|
.nav {
|
|
|
|
justify-content: space-between;
|
|
|
|
gap: var(--spacing-xl);
|
|
|
|
grid-template-columns: auto auto auto;
|
|
|
|
grid-template-rows: auto;
|
|
|
|
padding: var(--spacing-m);
|
|
|
|
}
|
|
|
|
.burger {
|
|
|
|
display: grid;
|
|
|
|
place-items: center;
|
|
|
|
grid-column: 1;
|
|
|
|
}
|
|
|
|
.logo {
|
|
|
|
grid-column: 2;
|
|
|
|
}
|
|
|
|
.logo img {
|
|
|
|
height: 36px;
|
|
|
|
}
|
|
|
|
.logo :global(h1) {
|
|
|
|
display: none;
|
|
|
|
}
|
|
|
|
.portal {
|
|
|
|
grid-column: 3;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Transform links into drawer */
|
|
|
|
.links {
|
|
|
|
position: fixed;
|
|
|
|
top: 0;
|
|
|
|
left: -250px;
|
|
|
|
transform: translateX(0);
|
|
|
|
width: 250px;
|
|
|
|
transition: transform 0.26s ease-in-out, opacity 0.26s ease-in-out;
|
|
|
|
height: 100vh;
|
|
|
|
opacity: 0;
|
|
|
|
background: white;
|
|
|
|
z-index: 999;
|
|
|
|
flex-direction: column;
|
|
|
|
justify-content: flex-start;
|
|
|
|
align-items: stretch;
|
|
|
|
padding: var(--spacing-xl);
|
|
|
|
}
|
|
|
|
.link {
|
|
|
|
width: calc(100% - 30px);
|
|
|
|
}
|
|
|
|
.links.visible {
|
|
|
|
opacity: 1;
|
|
|
|
transform: translateX(250px);
|
|
|
|
box-shadow: 0 0 40px 20px rgba(0, 0, 0, 0.1);
|
2021-06-11 14:47:57 +02:00
|
|
|
}
|
2021-06-14 17:19:49 +02:00
|
|
|
.mobile-click-handler.visible {
|
|
|
|
position: fixed;
|
|
|
|
display: block;
|
|
|
|
top: 0;
|
|
|
|
left: 0;
|
|
|
|
width: 100vw;
|
|
|
|
height: 100vh;
|
|
|
|
z-index: 998;
|
2021-06-11 14:47:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
</style>
|