forked from tsai/budibase
12 changed files with 231 additions and 1224 deletions
@ -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> |
|
||||
File diff suppressed because it is too large
@ -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