Add component for customising navigation links, improve layouts and responsiveness
This commit is contained in:
parent
bd52745a90
commit
a522a87ee8
|
@ -78,7 +78,7 @@
|
||||||
"posthog-js": "1.4.5",
|
"posthog-js": "1.4.5",
|
||||||
"remixicon": "2.5.0",
|
"remixicon": "2.5.0",
|
||||||
"shortid": "2.2.15",
|
"shortid": "2.2.15",
|
||||||
"svelte-dnd-action": "^0.8.9",
|
"svelte-dnd-action": "^0.9.8",
|
||||||
"svelte-loading-spinners": "^0.1.1",
|
"svelte-loading-spinners": "^0.1.1",
|
||||||
"svelte-portal": "0.1.0",
|
"svelte-portal": "0.1.0",
|
||||||
"uuid": "8.3.1",
|
"uuid": "8.3.1",
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
import { setWith } from "lodash"
|
import { setWith } from "lodash"
|
||||||
|
|
||||||
$: definition = store.actions.components.getDefinition(
|
$: definition = store.actions.components.getDefinition(
|
||||||
$selectedComponent._component
|
$selectedComponent?._component
|
||||||
)
|
)
|
||||||
$: isComponentOrScreen =
|
$: isComponentOrScreen =
|
||||||
$store.currentView === "component" ||
|
$store.currentView === "component" ||
|
||||||
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
<script>
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
Icon,
|
||||||
|
DrawerContent,
|
||||||
|
Layout,
|
||||||
|
Input,
|
||||||
|
Combobox,
|
||||||
|
} from "@budibase/bbui"
|
||||||
|
import { flip } from "svelte/animate"
|
||||||
|
import { dndzone } from "svelte-dnd-action"
|
||||||
|
import { generate } from "shortid"
|
||||||
|
import { store } from "builderStore"
|
||||||
|
|
||||||
|
export let links = []
|
||||||
|
|
||||||
|
const flipDurationMs = 150
|
||||||
|
|
||||||
|
$: urlOptions = $store.screens
|
||||||
|
.map(screen => screen.routing?.route)
|
||||||
|
.filter(x => x != null)
|
||||||
|
|
||||||
|
const addLink = () => {
|
||||||
|
links = [...links, { id: generate() }]
|
||||||
|
}
|
||||||
|
|
||||||
|
const removeLink = id => {
|
||||||
|
links = links.filter(link => link.id !== id)
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateLinks = e => {
|
||||||
|
links = e.detail.items
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<DrawerContent>
|
||||||
|
<div class="container">
|
||||||
|
<Layout>
|
||||||
|
{#if links?.length}
|
||||||
|
<div
|
||||||
|
class="links"
|
||||||
|
use:dndzone={{
|
||||||
|
items: links,
|
||||||
|
flipDurationMs,
|
||||||
|
dropTargetStyle: { outline: "none" },
|
||||||
|
}}
|
||||||
|
on:finalize={updateLinks}
|
||||||
|
on:consider={updateLinks}
|
||||||
|
>
|
||||||
|
{#each links as link (link.id)}
|
||||||
|
<div class="link" animate:flip={{ duration: flipDurationMs }}>
|
||||||
|
<Icon name="DragHandle" size="XL" />
|
||||||
|
<Input bind:value={link.text} placeholder="Text" />
|
||||||
|
<Combobox
|
||||||
|
bind:value={link.url}
|
||||||
|
placeholder="URL"
|
||||||
|
options={urlOptions}
|
||||||
|
/>
|
||||||
|
<Icon
|
||||||
|
name="Close"
|
||||||
|
hoverable
|
||||||
|
size="S"
|
||||||
|
on:click={() => removeLink(link.id)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
<div class="button-container">
|
||||||
|
<Button secondary icon="Add" on:click={addLink}>Add Link</Button>
|
||||||
|
</div>
|
||||||
|
</Layout>
|
||||||
|
</div>
|
||||||
|
</DrawerContent>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.container {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 600px;
|
||||||
|
margin: var(--spacing-m) auto;
|
||||||
|
}
|
||||||
|
.links {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: stretch;
|
||||||
|
}
|
||||||
|
.link {
|
||||||
|
padding: 4px 8px;
|
||||||
|
gap: var(--spacing-l);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
border-radius: var(--border-radius-s);
|
||||||
|
transition: background-color ease-in-out 130ms;
|
||||||
|
}
|
||||||
|
.link:hover {
|
||||||
|
background-color: var(--spectrum-global-color-gray-100);
|
||||||
|
}
|
||||||
|
.link > :global(.spectrum-Form-item) {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
|
.button-container {
|
||||||
|
margin-left: var(--spacing-l);
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,23 @@
|
||||||
|
<script>
|
||||||
|
import { Button, Drawer } from "@budibase/bbui"
|
||||||
|
import { createEventDispatcher } from "svelte"
|
||||||
|
import NavigationDrawer from "./NavigationDrawer.svelte"
|
||||||
|
|
||||||
|
export let value = []
|
||||||
|
let drawer
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher()
|
||||||
|
const save = () => {
|
||||||
|
dispatch("change", value)
|
||||||
|
drawer.hide()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Button secondary on:click={drawer.show}>Configure Links</Button>
|
||||||
|
<Drawer bind:this={drawer} title={"Navigation Links"}>
|
||||||
|
<svelte:fragment slot="description">
|
||||||
|
Configure the links in your navigation bar.
|
||||||
|
</svelte:fragment>
|
||||||
|
<Button cta slot="buttons" on:click={save}>Save</Button>
|
||||||
|
<NavigationDrawer slot="body" bind:links={value} />
|
||||||
|
</Drawer>
|
|
@ -1,40 +0,0 @@
|
||||||
<script>
|
|
||||||
import { ActionButton } from "@budibase/bbui"
|
|
||||||
import { flip } from "svelte/animate"
|
|
||||||
import { dndzone } from "svelte-dnd-action"
|
|
||||||
|
|
||||||
let flipDurationMs = 150
|
|
||||||
|
|
||||||
// This should be the screens and any external links the user has added
|
|
||||||
let items = [
|
|
||||||
{ text: "Test", id: 0 },
|
|
||||||
{ text: "First", id: 1 },
|
|
||||||
{ text: "Second", id: 2 },
|
|
||||||
]
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="container">
|
|
||||||
<ul
|
|
||||||
use:dndzone={{
|
|
||||||
items,
|
|
||||||
flipDurationMs,
|
|
||||||
dropTargetStyle: { outline: "none" },
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{#each items as item (item)}
|
|
||||||
<li animate:flip={{ duration: flipDurationMs }}>{item}</li>
|
|
||||||
{/each}
|
|
||||||
</ul>
|
|
||||||
<ActionButton icon="Add">Add External Link</ActionButton>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.container {
|
|
||||||
display: grid;
|
|
||||||
}
|
|
||||||
ul {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
list-style-type: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -16,7 +16,7 @@
|
||||||
import MultiFieldSelect from "./PropertyControls/MultiFieldSelect.svelte"
|
import MultiFieldSelect from "./PropertyControls/MultiFieldSelect.svelte"
|
||||||
import SchemaSelect from "./PropertyControls/SchemaSelect.svelte"
|
import SchemaSelect from "./PropertyControls/SchemaSelect.svelte"
|
||||||
import SectionSelect from "./PropertyControls/SectionSelect.svelte"
|
import SectionSelect from "./PropertyControls/SectionSelect.svelte"
|
||||||
import NavigationSelect from "./PropertyControls/NavigationSelect.svelte"
|
import NavigationEditor from "./PropertyControls/NavigationEditor/NavigationEditor.svelte"
|
||||||
import EventsEditor from "./PropertyControls/EventsEditor"
|
import EventsEditor from "./PropertyControls/EventsEditor"
|
||||||
import FilterEditor from "./PropertyControls/FilterEditor/FilterEditor.svelte"
|
import FilterEditor from "./PropertyControls/FilterEditor/FilterEditor.svelte"
|
||||||
import { IconSelect } from "./PropertyControls/IconSelect"
|
import { IconSelect } from "./PropertyControls/IconSelect"
|
||||||
|
@ -65,7 +65,7 @@
|
||||||
multifield: MultiFieldSelect,
|
multifield: MultiFieldSelect,
|
||||||
schema: SchemaSelect,
|
schema: SchemaSelect,
|
||||||
section: SectionSelect,
|
section: SectionSelect,
|
||||||
navigationSelect: NavigationSelect,
|
navigation: NavigationEditor,
|
||||||
filter: FilterEditor,
|
filter: FilterEditor,
|
||||||
"field/string": StringFieldSelect,
|
"field/string": StringFieldSelect,
|
||||||
"field/number": NumberFieldSelect,
|
"field/number": NumberFieldSelect,
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -38,9 +38,9 @@
|
||||||
"defaultValue": "Top"
|
"defaultValue": "Top"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "navigationSelect",
|
"type": "navigation",
|
||||||
"label": "Links",
|
"label": "Links",
|
||||||
"key": "type"
|
"key": "links"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -58,7 +58,6 @@
|
||||||
"type": "select",
|
"type": "select",
|
||||||
"label": "Direction",
|
"label": "Direction",
|
||||||
"key": "direction",
|
"key": "direction",
|
||||||
"key": "direction",
|
|
||||||
"showInBar": true,
|
"showInBar": true,
|
||||||
"options": [
|
"options": [
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script>
|
<script>
|
||||||
import { getContext } from "svelte"
|
import { getContext } from "svelte"
|
||||||
import { ActionButton, Heading } from "@budibase/bbui"
|
import { ActionButton, Heading, Icon } from "@budibase/bbui"
|
||||||
|
|
||||||
const { styleable, linkable } = getContext("sdk")
|
const { styleable, linkable } = getContext("sdk")
|
||||||
const component = getContext("component")
|
const component = getContext("component")
|
||||||
|
@ -11,11 +11,11 @@
|
||||||
export let hideLogo = false
|
export let hideLogo = false
|
||||||
export let navigation = "Top"
|
export let navigation = "Top"
|
||||||
export let sticky = true
|
export let sticky = true
|
||||||
|
export let links
|
||||||
|
|
||||||
export let links = [
|
$: validLinks = links?.filter(link => link.text && link.url) || []
|
||||||
{ text: "Some Text", url: "/" },
|
$: type = navigationClasses[navigation] || "none"
|
||||||
{ text: "Some Text", url: "/" },
|
let mobileOpen = false
|
||||||
]
|
|
||||||
|
|
||||||
const navigationClasses = {
|
const navigationClasses = {
|
||||||
Top: "top",
|
Top: "top",
|
||||||
|
@ -23,56 +23,76 @@
|
||||||
None: "none",
|
None: "none",
|
||||||
}
|
}
|
||||||
|
|
||||||
$: type = navigationClasses[navigation] || "none"
|
const isInternal = url => {
|
||||||
let mobileOpen = false
|
return url.startsWith("/")
|
||||||
|
}
|
||||||
|
|
||||||
|
const ensureExternal = url => {
|
||||||
|
return !url.startsWith("http") ? `http://${url}` : url
|
||||||
|
}
|
||||||
|
|
||||||
|
const close = () => {
|
||||||
|
mobileOpen = false
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="layout layout--{type}" use:styleable={$component.styles}>
|
<div class="layout layout--{type}" use:styleable={$component.styles}>
|
||||||
{#if type !== "none"}
|
{#if type !== "none"}
|
||||||
<div class="nav-wrapper" class:sticky>
|
<div class="nav-wrapper" class:sticky>
|
||||||
<div class="nav nav--{type}">
|
<div class="nav nav--{type}">
|
||||||
|
<div class="nav-header">
|
||||||
|
{#if validLinks?.length}
|
||||||
<div class="burger">
|
<div class="burger">
|
||||||
<ActionButton
|
<Icon
|
||||||
quiet
|
hoverable
|
||||||
icon="ShowMenu"
|
name="ShowMenu"
|
||||||
on:click={() => (mobileOpen = !mobileOpen)}
|
on:click={() => (mobileOpen = !mobileOpen)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
{/if}
|
||||||
<div class="logo">
|
<div class="logo">
|
||||||
{#if !hideLogo}
|
{#if !hideLogo}
|
||||||
<img src="https://i.imgur.com/Xhdt1YP.png" alt={title} />
|
<img src={logoUrl} alt={title} />
|
||||||
{/if}
|
{/if}
|
||||||
{#if !hideTitle}
|
{#if !hideTitle}
|
||||||
<Heading>{title}</Heading>
|
<Heading>{title}</Heading>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="portal">
|
<div class="portal">
|
||||||
<ActionButton quiet icon="Apps" on:click />
|
<Icon
|
||||||
|
hoverable
|
||||||
|
name="Apps"
|
||||||
|
on:click={() => (window.location.href = "/builder/apps")}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="mobile-click-handler"
|
class="mobile-click-handler"
|
||||||
class:visible={mobileOpen}
|
class:visible={mobileOpen}
|
||||||
on:click={() => (mobileOpen = false)}
|
on:click={() => (mobileOpen = false)}
|
||||||
/>
|
/>
|
||||||
|
{#if validLinks?.length}
|
||||||
<div class="links" class:visible={mobileOpen}>
|
<div class="links" class:visible={mobileOpen}>
|
||||||
{#each links as { text, url, external }}
|
{#each validLinks as { text, url }}
|
||||||
{#if external}
|
{#if isInternal(url)}
|
||||||
<a class="link" href={url}>{text}</a>
|
<a class="link" href={url} use:linkable on:click={close}>
|
||||||
|
{text}
|
||||||
|
</a>
|
||||||
{:else}
|
{:else}
|
||||||
<a class="link" href={url} use:linkable>{text}</a>
|
<a class="link" href={ensureExternal(url)} on:click={close}>
|
||||||
|
{text}
|
||||||
|
</a>
|
||||||
{/if}
|
{/if}
|
||||||
{/each}
|
{/each}
|
||||||
<div class="close">
|
<div class="close">
|
||||||
<ActionButton
|
<Icon
|
||||||
quiet
|
hoverable
|
||||||
icon="Close"
|
name="Close"
|
||||||
on:click={() => (mobileOpen = false)}
|
on:click={() => (mobileOpen = false)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -110,11 +130,20 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav {
|
.nav {
|
||||||
flex: 1 1 auto;
|
display: flex;
|
||||||
display: grid;
|
flex-direction: column;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: stretch;
|
||||||
padding: var(--spacing-xl);
|
padding: var(--spacing-xl);
|
||||||
max-width: 1400px;
|
width: 1400px;
|
||||||
grid-template-columns: 1fr auto;
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
.nav-header {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
.main-wrapper {
|
.main-wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -124,12 +153,12 @@
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
}
|
}
|
||||||
.main {
|
.main {
|
||||||
flex: 1 1 auto;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
max-width: 1400px;
|
width: 1400px;
|
||||||
|
max-width: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,16 +172,13 @@
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: var(--spacing-xl);
|
gap: var(--spacing-xl);
|
||||||
grid-column: 1;
|
|
||||||
}
|
}
|
||||||
.logo img {
|
.logo img {
|
||||||
height: 48px;
|
height: 48px;
|
||||||
}
|
}
|
||||||
.portal {
|
.portal {
|
||||||
display: grid;
|
display: grid;
|
||||||
justify-items: center;
|
place-items: center;
|
||||||
align-items: center;
|
|
||||||
grid-column: 2;
|
|
||||||
}
|
}
|
||||||
.links {
|
.links {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -160,8 +186,6 @@
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: var(--spacing-l);
|
gap: var(--spacing-l);
|
||||||
grid-column: 1 / 3;
|
|
||||||
grid-row: 2;
|
|
||||||
}
|
}
|
||||||
.link {
|
.link {
|
||||||
color: var(--spectrum-alias-text-color);
|
color: var(--spectrum-alias-text-color);
|
||||||
|
@ -175,8 +199,8 @@
|
||||||
.close {
|
.close {
|
||||||
display: none;
|
display: none;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: var(--spacing-m);
|
top: var(--spacing-xl);
|
||||||
right: var(--spacing-m);
|
right: var(--spacing-xl);
|
||||||
}
|
}
|
||||||
.mobile-click-handler {
|
.mobile-click-handler {
|
||||||
display: none;
|
display: none;
|
||||||
|
@ -194,12 +218,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav--top {
|
.nav--top {
|
||||||
grid-template-rows: auto auto;
|
|
||||||
justify-content: space-between;
|
|
||||||
gap: var(--spacing-xl);
|
gap: var(--spacing-xl);
|
||||||
}
|
}
|
||||||
.nav--left {
|
.nav--left {
|
||||||
grid-template-rows: auto 1fr;
|
|
||||||
width: 250px;
|
width: 250px;
|
||||||
gap: var(--spacing-m);
|
gap: var(--spacing-m);
|
||||||
}
|
}
|
||||||
|
@ -246,19 +267,11 @@
|
||||||
|
|
||||||
/* Force standard top bar */
|
/* Force standard top bar */
|
||||||
.nav {
|
.nav {
|
||||||
justify-content: space-between;
|
padding: var(--spacing-m) var(--spacing-xl);
|
||||||
gap: var(--spacing-xl);
|
|
||||||
grid-template-columns: auto auto auto;
|
|
||||||
grid-template-rows: auto;
|
|
||||||
padding: var(--spacing-m);
|
|
||||||
}
|
}
|
||||||
.burger {
|
.burger {
|
||||||
display: grid;
|
display: grid;
|
||||||
place-items: center;
|
place-items: center;
|
||||||
grid-column: 1;
|
|
||||||
}
|
|
||||||
.logo {
|
|
||||||
grid-column: 2;
|
|
||||||
}
|
}
|
||||||
.logo img {
|
.logo img {
|
||||||
height: 36px;
|
height: 36px;
|
||||||
|
@ -266,9 +279,6 @@
|
||||||
.logo :global(h1) {
|
.logo :global(h1) {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
.portal {
|
|
||||||
grid-column: 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Transform links into drawer */
|
/* Transform links into drawer */
|
||||||
.links {
|
.links {
|
||||||
|
@ -289,6 +299,7 @@
|
||||||
}
|
}
|
||||||
.link {
|
.link {
|
||||||
width: calc(100% - 30px);
|
width: calc(100% - 30px);
|
||||||
|
font-size: 120%;
|
||||||
}
|
}
|
||||||
.links.visible {
|
.links.visible {
|
||||||
opacity: 1;
|
opacity: 1;
|
|
@ -24,7 +24,7 @@ export { default as stackedlist } from "./StackedList.svelte"
|
||||||
export { default as card } from "./Card.svelte"
|
export { default as card } from "./Card.svelte"
|
||||||
export { default as text } from "./Text.svelte"
|
export { default as text } from "./Text.svelte"
|
||||||
export { default as navigation } from "./Navigation.svelte"
|
export { default as navigation } from "./Navigation.svelte"
|
||||||
export { default as layout } from "./layout/Layout.svelte"
|
export { default as layout } from "./Layout.svelte"
|
||||||
export { default as link } from "./Link.svelte"
|
export { default as link } from "./Link.svelte"
|
||||||
export { default as heading } from "./Heading.svelte"
|
export { default as heading } from "./Heading.svelte"
|
||||||
export { default as image } from "./Image.svelte"
|
export { default as image } from "./Image.svelte"
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
<script>
|
|
||||||
import {
|
|
||||||
ActionButton,
|
|
||||||
SideNavigation,
|
|
||||||
SideNavigationItem as Item,
|
|
||||||
} from "@budibase/bbui"
|
|
||||||
export let links
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="overlay">
|
|
||||||
<SideNavigation>
|
|
||||||
{#each links as { text, url }}
|
|
||||||
<!-- Needs logic to select current route -->
|
|
||||||
<Item selected={false} href={url} on:click>{text}</Item>
|
|
||||||
{/each}
|
|
||||||
</SideNavigation>
|
|
||||||
<div class="close">
|
|
||||||
<ActionButton quiet icon="Close" on:click />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.overlay {
|
|
||||||
background: white;
|
|
||||||
position: absolute;
|
|
||||||
inset: 0;
|
|
||||||
}
|
|
||||||
.close {
|
|
||||||
position: absolute;
|
|
||||||
top: var(--spacing-m);
|
|
||||||
right: var(--spacing-m);
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,71 +0,0 @@
|
||||||
<script>
|
|
||||||
import Mobile from "./Mobile.svelte"
|
|
||||||
import {
|
|
||||||
ActionButton,
|
|
||||||
SideNavigation,
|
|
||||||
SideNavigationItem as Item,
|
|
||||||
} from "@budibase/bbui"
|
|
||||||
|
|
||||||
export let navigation
|
|
||||||
export let links
|
|
||||||
export let mobileOpen = false
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="container">
|
|
||||||
{#if navigation === "Top"}
|
|
||||||
<ul>
|
|
||||||
{#each links as { text, url }}
|
|
||||||
<li><a href={url}>{text}</a></li>
|
|
||||||
{/each}
|
|
||||||
</ul>
|
|
||||||
{:else}
|
|
||||||
<SideNavigation>
|
|
||||||
{#each links as { text, url }}
|
|
||||||
<!-- Needs logic to select current route -->
|
|
||||||
<Item selected={false} href="/">{text}</Item>
|
|
||||||
{/each}
|
|
||||||
</SideNavigation>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
<div class="mobile">
|
|
||||||
<ActionButton
|
|
||||||
quiet
|
|
||||||
selected
|
|
||||||
icon="ShowMenu"
|
|
||||||
on:click={() => (mobileOpen = !mobileOpen)}
|
|
||||||
/>
|
|
||||||
{#if mobileOpen}
|
|
||||||
<Mobile {links} on:click={() => (mobileOpen = !mobileOpen)} />
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.container {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
ul {
|
|
||||||
list-style-type: none;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: flex-start;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul > * {
|
|
||||||
margin-right: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
:global(ul > a) {
|
|
||||||
font-size: 1.5em;
|
|
||||||
text-decoration: none;
|
|
||||||
margin-right: 16px;
|
|
||||||
}
|
|
||||||
@media (min-width: 600px) {
|
|
||||||
.mobile {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.container {
|
|
||||||
display: initial;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
Loading…
Reference in New Issue