Replace component dropdown menu with new common components

This commit is contained in:
Andrew Kingston 2020-10-26 14:23:08 +00:00
parent f42dc2551c
commit 26bb3ebb98
3 changed files with 69 additions and 109 deletions

View File

@ -1,4 +1,4 @@
<div class="dropdown-container"> <div class="dropdown-container" on:click>
<slot /> <slot />
</div> </div>

View File

@ -2,9 +2,10 @@
export let icon export let icon
export let title export let title
export let subtitle export let subtitle
export let disabled
</script> </script>
<div class="dropdown-item" on:click class:big={subtitle != null}> <div class="dropdown-item" class:disabled on:click class:big={subtitle != null}>
{#if icon}<i class={icon} />{/if} {#if icon}<i class={icon} />{/if}
<div class="content"> <div class="content">
<div class="title">{title}</div> <div class="title">{title}</div>
@ -22,11 +23,17 @@
align-items: center; align-items: center;
gap: var(--spacing-m); gap: var(--spacing-m);
padding: var(--spacing-xs) var(--spacing-l); padding: var(--spacing-xs) var(--spacing-l);
color: var(--ink);
}
.dropdown-item.disabled,
.dropdown-item.disabled .subtitle {
pointer-events: none;
color: var(--grey-5);
} }
.dropdown-item.big { .dropdown-item.big {
padding: var(--spacing-s) var(--spacing-l); padding: var(--spacing-s) var(--spacing-l);
} }
.dropdown-item:hover { .dropdown-item:not(.disabled):hover {
background-color: var(--grey-2); background-color: var(--grey-2);
cursor: pointer; cursor: pointer;
} }
@ -45,7 +52,6 @@
.title { .title {
font-weight: 500; font-weight: 500;
color: var(--ink);
} }
.subtitle { .subtitle {
@ -55,6 +61,5 @@
i { i {
font-size: 16px; font-size: 16px;
color: var(--ink);
} }
</style> </style>

View File

@ -3,10 +3,10 @@
import { store } from "builderStore" import { store } from "builderStore"
import { getComponentDefinition } from "builderStore/storeUtils" import { getComponentDefinition } from "builderStore/storeUtils"
import ConfirmDialog from "components/common/ConfirmDialog.svelte" import ConfirmDialog from "components/common/ConfirmDialog.svelte"
import { last, cloneDeep } from "lodash/fp" import { last } from "lodash/fp"
import { getParent, saveCurrentPreviewItem } from "builderStore/storeUtils" import { getParent, saveCurrentPreviewItem } from "builderStore/storeUtils"
import { uuid } from "builderStore/uuid"
import { DropdownMenu } from "@budibase/bbui" import { DropdownMenu } from "@budibase/bbui"
import { DropdownContainer, DropdownItem } from "components/common/Dropdowns"
export let component export let component
@ -18,27 +18,27 @@
!component || !getComponentDefinition($store, component._component).children !component || !getComponentDefinition($store, component._component).children
$: noPaste = !$store.componentToPaste $: noPaste = !$store.componentToPaste
const lastPartOfName = c => (c ? last(c._component.split("/")) : "") const lastPartOfName = (c) => (c ? last(c._component.split("/")) : "")
const hideDropdown = () => { const hideDropdown = () => {
dropdown.hide() dropdown.hide()
} }
const selectComponent = component => { const selectComponent = (component) => {
store.selectComponent(component) store.selectComponent(component)
const path = store.getPathToComponent(component) const path = store.getPathToComponent(component)
$goto(`./:page/:screen/${path}`) $goto(`./:page/:screen/${path}`)
} }
const moveUpComponent = () => { const moveUpComponent = () => {
store.update(s => { store.update((s) => {
const parent = getParent(s.currentPreviewItem.props, component) const parent = getParent(s.currentPreviewItem.props, component)
if (parent) { if (parent) {
const currentIndex = parent._children.indexOf(component) const currentIndex = parent._children.indexOf(component)
if (currentIndex === 0) return s if (currentIndex === 0) return s
const newChildren = parent._children.filter(c => c !== component) const newChildren = parent._children.filter((c) => c !== component)
newChildren.splice(currentIndex - 1, 0, component) newChildren.splice(currentIndex - 1, 0, component)
parent._children = newChildren parent._children = newChildren
} }
@ -50,14 +50,14 @@
} }
const moveDownComponent = () => { const moveDownComponent = () => {
store.update(s => { store.update((s) => {
const parent = getParent(s.currentPreviewItem.props, component) const parent = getParent(s.currentPreviewItem.props, component)
if (parent) { if (parent) {
const currentIndex = parent._children.indexOf(component) const currentIndex = parent._children.indexOf(component)
if (currentIndex === parent._children.length - 1) return s if (currentIndex === parent._children.length - 1) return s
const newChildren = parent._children.filter(c => c !== component) const newChildren = parent._children.filter((c) => c !== component)
newChildren.splice(currentIndex + 1, 0, component) newChildren.splice(currentIndex + 1, 0, component)
parent._children = newChildren parent._children = newChildren
} }
@ -74,11 +74,11 @@
} }
const deleteComponent = () => { const deleteComponent = () => {
store.update(state => { store.update((state) => {
const parent = getParent(state.currentPreviewItem.props, component) const parent = getParent(state.currentPreviewItem.props, component)
if (parent) { if (parent) {
parent._children = parent._children.filter(c => c !== component) parent._children = parent._children.filter((c) => c !== component)
selectComponent(parent) selectComponent(parent)
} }
@ -92,7 +92,7 @@
store.storeComponentForCopy(component, cut) store.storeComponentForCopy(component, cut)
} }
const pasteComponent = mode => { const pasteComponent = (mode) => {
// lives in store - also used by drag drop // lives in store - also used by drag drop
store.pasteComponent(component, mode) store.pasteComponent(component, mode)
} }
@ -100,63 +100,51 @@
<div bind:this={anchor} on:click|stopPropagation={() => {}}> <div bind:this={anchor} on:click|stopPropagation={() => {}}>
<div class="icon" on:click={dropdown.show}><i class="ri-more-line" /></div> <div class="icon" on:click={dropdown.show}><i class="ri-more-line" /></div>
</div> <DropdownMenu bind:this={dropdown} width="170px" {anchor} align="left">
<DropdownMenu <DropdownContainer on:click={hideDropdown}>
bind:this={dropdown} <DropdownItem
on:click={hideDropdown} icon="ri-delete-bin-line"
width="170px" title="Delete"
{anchor} on:click={() => confirmDeleteDialog.show()} />
align="left"> <DropdownItem
<ul> icon="ri-arrow-up-line"
<li class="item" on:click={() => confirmDeleteDialog.show()}> title="Move up"
<i class="ri-delete-bin-2-line" /> on:click={moveUpComponent} />
Delete <DropdownItem
</li> icon="ri-arrow-down-line"
<li class="item" on:click={moveUpComponent}> title="Move down"
<i class="ri-arrow-up-line" /> on:click={moveDownComponent} />
Move up <DropdownItem
</li> icon="ri-repeat-one-line"
<li class="item" on:click={moveDownComponent}> title="Duplicate"
<i class="ri-arrow-down-line" /> on:click={copyComponent} />
Move down <DropdownItem
</li> icon="ri-scissors-cut-line"
<li class="item" on:click={copyComponent}> title="Cut"
<i class="ri-repeat-one-line" /> on:click={() => storeComponentForCopy(true)} />
Duplicate <DropdownItem
</li> icon="ri-file-copy-line"
<li class="item" on:click={() => storeComponentForCopy(true)}> title="Copy"
<i class="ri-scissors-cut-line" /> on:click={() => storeComponentForCopy(false)} />
Cut
</li>
<li class="item" on:click={() => storeComponentForCopy(false)}>
<i class="ri-file-copy-line" />
Copy
</li>
<hr class="hr-style" /> <hr class="hr-style" />
<li <DropdownItem
class="item" icon="ri-insert-row-top"
class:disabled={noPaste} title="Paste above"
on:click={() => pasteComponent('above')}> disabled={noPaste}
<i class="ri-insert-row-top" /> on:click={() => pasteComponent('above')} />
Paste above <DropdownItem
</li> icon="ri-insert-row-bottom"
<li title="Paste below"
class="item" disabled={noPaste}
class:disabled={noPaste} on:click={() => pasteComponent('below')} />
on:click={() => pasteComponent('below')}> <DropdownItem
<i class="ri-insert-row-bottom" /> icon="ri-insert-column-right"
Paste below title="Paste inside"
</li> disabled={noPaste || noChildrenAllowed}
<li on:click={() => pasteComponent('inside')} />
class="item" </DropdownContainer>
class:disabled={noPaste || noChildrenAllowed} </DropdownMenu>
on:click={() => pasteComponent('inside')}> </div>
<i class="ri-insert-column-right" />
Paste inside
</li>
</ul>
</DropdownMenu>
<ConfirmDialog <ConfirmDialog
bind:this={confirmDeleteDialog} bind:this={confirmDeleteDialog}
title="Confirm Delete" title="Confirm Delete"
@ -165,43 +153,10 @@
onOk={deleteComponent} /> onOk={deleteComponent} />
<style> <style>
ul { hr {
list-style: none;
padding: 0;
margin: var(--spacing-s) 0;
}
li {
display: flex;
font-family: var(--font-sans);
font-size: var(--font-size-xs);
color: var(--ink);
padding: var(--spacing-s) var(--spacing-m);
margin: auto 0;
align-items: center;
cursor: pointer;
}
li:not(.disabled):hover {
background-color: var(--grey-2);
}
li:active {
color: var(--blue);
}
li i {
margin-right: 8px;
font-size: var(--font-size-s);
}
li.disabled {
color: var(--grey-4);
cursor: default;
}
.icon i {
font-size: 16px;
}
.hr-style {
margin: 8px 0; margin: 8px 0;
color: var(--grey-4); background-color: var(--grey-4);
height: 1px;
border: none;
} }
</style> </style>