1
0
Fork 0
mirror of synced 2024-09-03 03:01:14 +12:00

Add sub link drawer

This commit is contained in:
Andrew Kingston 2024-03-28 13:16:57 +00:00
parent 26c4e504bf
commit fdc757029a
3 changed files with 67 additions and 59 deletions

View file

@ -78,7 +78,12 @@
{/if} {/if}
</div> </div>
<Drawer bind:this={bindingDrawer} title={title ?? placeholder ?? "Bindings"}> <Drawer
bind:this={bindingDrawer}
title={title ?? placeholder ?? "Bindings"}
on:drawerHide
on:drawerShow
>
<Button cta slot="buttons" on:click={handleClose}>Save</Button> <Button cta slot="buttons" on:click={handleClose}>Save</Button>
<svelte:component <svelte:component
this={panel} this={panel}

View file

@ -20,8 +20,8 @@
] ]
let popover let popover
let drawers = []
let open = false let open = false
let drawerCount = 0
$: urlOptions = $screenStore.screens $: urlOptions = $screenStore.screens
.map(screen => screen.routing?.route) .map(screen => screen.routing?.route)
@ -52,7 +52,7 @@
<Popover <Popover
bind:this={popover} bind:this={popover}
on:open={() => { on:open={() => {
drawers = [] open = true
$draggable.actions.select(navItem.id) $draggable.actions.select(navItem.id)
}} }}
on:close={() => { on:close={() => {
@ -63,8 +63,8 @@
}} }}
{anchor} {anchor}
align="left-outside" align="left-outside"
showPopover={drawers.length === 0} showPopover={drawerCount === 0}
clickOutsideOverride={drawers.length > 0} clickOutsideOverride={drawerCount > 0}
maxHeight={600} maxHeight={600}
offset={18} offset={18}
> >
@ -87,6 +87,8 @@
props={{ props={{
updateOnChange: false, updateOnChange: false,
}} }}
on:drawerShow={() => drawerCount++}
on:drawerHide={() => drawerCount--}
/> />
{#if navItem.type === "sublinks"} {#if navItem.type === "sublinks"}
<PropertyControl <PropertyControl
@ -94,6 +96,12 @@
control={SubLinksDrawer} control={SubLinksDrawer}
value={navItem.subLinks} value={navItem.subLinks}
onChange={update("subLinks")} onChange={update("subLinks")}
{bindings}
props={{
navItem,
}}
on:drawerShow={() => drawerCount++}
on:drawerHide={() => drawerCount--}
/> />
{:else} {:else}
<PropertyControl <PropertyControl
@ -107,6 +115,8 @@
appendBindingsAsOptions: false, appendBindingsAsOptions: false,
placeholder: null, placeholder: null,
}} }}
on:drawerShow={() => drawerCount++}
on:drawerHide={() => drawerCount--}
/> />
{/if} {/if}
<PropertyControl <PropertyControl

View file

@ -6,99 +6,96 @@
DrawerContent, DrawerContent,
Layout, Layout,
Input, Input,
Combobox,
Drawer, Drawer,
} from "@budibase/bbui" } from "@budibase/bbui"
import { flip } from "svelte/animate" import { flip } from "svelte/animate"
import { dndzone } from "svelte-dnd-action" import { dndzone } from "svelte-dnd-action"
import { generate } from "shortid" import { generate } from "shortid"
import { screenStore } from "stores/builder" import { screenStore } from "stores/builder"
import RoleSelect from "components/design/settings/controls/RoleSelect.svelte" import DrawerBindableCombobox from "components/common/bindings/DrawerBindableCombobox.svelte"
export let value = [] export let value = []
export let onChange
export let navItem
export let bindings
const flipDurationMs = 150 const flipDurationMs = 150
let dragDisabled = true
let drawer let drawer
let subLinks = value?.slice() || []
$: links = value || [] $: count = value?.length ?? 0
$: links.forEach(link => { $: buttonText = `${count || "No"} sub link${count === 1 ? "" : "s"}`
if (!link.id) { $: drawerTitle = navItem.text ? `${navItem.text} sub links` : "Sub links"
link.id = generate() $: subLinks.forEach(subLink => {
if (!subLink.id) {
subLink.id = generate()
} }
}) })
$: urlOptions = $screenStore.screens $: urlOptions = $screenStore.screens
.map(screen => screen.routing?.route) .map(screen => screen.routing?.route)
.filter(x => x != null) .filter(x => x != null)
.sort()
const addLink = () => { const addSubLink = () => {
links = [...links, {}] subLinks = [...subLinks, {}]
} }
const removeLink = id => { const removeSubLink = id => {
links = links.filter(link => link.id !== id) subLinks = subLinks.filter(link => link.id !== id)
} }
const updateLinks = e => { const saveSubLinks = () => {
links = e.detail.items onChange(subLinks)
drawer.hide()
} }
const handleFinalize = e => { const updateSubLinks = e => {
updateLinks(e) subLinks = e.detail.items
dragDisabled = true
} }
</script> </script>
<!-- svelte-ignore a11y-no-static-element-interactions --> <Drawer bind:this={drawer} title={drawerTitle} on:drawerShow on:drawerHide>
<Drawer bind:this={drawer}> <Button cta slot="buttons" on:click={saveSubLinks}>Save</Button>
<DrawerContent> <DrawerContent slot="body">
<div class="container"> <div class="container">
<Layout noPadding gap="S"> <Layout noPadding gap="S">
{#if links?.length} {#if subLinks?.length}
<div <div
class="links" class="subLinks"
use:dndzone={{ use:dndzone={{
items: links, items: subLinks,
flipDurationMs, flipDurationMs,
dropTargetStyle: { outline: "none" }, dropTargetStyle: { outline: "none" },
dragDisabled,
}} }}
on:finalize={handleFinalize} on:consider={updateSubLinks}
on:consider={updateLinks} on:finalize={updateSubLinks}
> >
{#each links as link (link.id)} {#each subLinks as subLink (subLink.id)}
<div class="link" animate:flip={{ duration: flipDurationMs }}> <div class="subLink" animate:flip={{ duration: flipDurationMs }}>
<div <Icon name="DragHandle" size="XL" />
class="handle" <Input bind:value={subLink.text} placeholder="Text" />
aria-label="drag-handle" <DrawerBindableCombobox
style={dragDisabled ? "cursor: grab" : "cursor: grabbing"} value={subLink.url}
on:mousedown={() => (dragDisabled = false)} on:change={e => (subLink.url = e.detail)}
> placeholder="Link"
<Icon name="DragHandle" size="XL" />
</div>
<Input bind:value={link.text} placeholder="Text" />
<Combobox
bind:value={link.url}
placeholder="URL"
options={urlOptions} options={urlOptions}
/> {bindings}
<RoleSelect
bind:value={link.roleId}
placeholder="Minimum role"
/> />
<Icon <Icon
name="Close" name="Close"
hoverable hoverable
size="S" size="S"
on:click={() => removeLink(link.id)} on:click={() => removeSubLink(subLink.id)}
/> />
</div> </div>
{/each} {/each}
</div> </div>
{/if} {/if}
<div> <div>
<Button secondary icon="Add" on:click={addLink}>Add Link</Button> <ActionButton quiet icon="Add" on:click={addSubLink}>
Add link
</ActionButton>
</div> </div>
</Layout> </Layout>
</div> </div>
@ -106,7 +103,7 @@
</Drawer> </Drawer>
<div class="button"> <div class="button">
<ActionButton>No sub links</ActionButton> <ActionButton on:click={drawer.show}>{buttonText}</ActionButton>
</div> </div>
<style> <style>
@ -118,14 +115,14 @@
max-width: 800px; max-width: 800px;
margin: 0 auto; margin: 0 auto;
} }
.links { .subLinks {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: flex-start; justify-content: flex-start;
align-items: stretch; align-items: stretch;
gap: var(--spacing-m); gap: var(--spacing-m);
} }
.link { .subLink {
gap: var(--spacing-l); gap: var(--spacing-l);
display: flex; display: flex;
flex-direction: row; flex-direction: row;
@ -134,15 +131,11 @@
border-radius: var(--border-radius-s); border-radius: var(--border-radius-s);
transition: background-color ease-in-out 130ms; transition: background-color ease-in-out 130ms;
} }
.link:hover { .subLink:hover {
background-color: var(--spectrum-global-color-gray-100); background-color: var(--spectrum-global-color-gray-100);
} }
.link > :global(.spectrum-Form-item) { .subLink > :global(.spectrum-Form-item) {
flex: 1 1 auto; flex: 1 1 auto;
width: 0; width: 0;
} }
.handle {
display: grid;
place-items: center;
}
</style> </style>