Add labels to DND to describe where the component will be dropped

This commit is contained in:
Andrew Kingston 2021-09-16 15:08:42 +01:00
parent bdc86e4c22
commit 46867b8a19
3 changed files with 46 additions and 27 deletions

View File

@ -1,6 +1,7 @@
<script>
import { onMount } from "svelte"
import IndicatorSet from "./IndicatorSet.svelte"
import Indicator from "./Indicator.svelte"
import DNDPositionIndicator from "./DNDPositionIndicator.svelte"
import { builderStore } from "stores"
@ -106,6 +107,7 @@
const child = getDOMNodeForComponent(e.target)
const bounds = child.getBoundingClientRect()
dropInfo = {
name: element.dataset.name,
droppableInside: element.dataset.droppableInside === "true",
bounds,
}
@ -160,6 +162,10 @@
prefix="Inside"
/>
{#if dropMode !== "inside" && dropInfo}
<DNDPositionIndicator bounds={dropInfo.bounds} mode={dropMode} zIndex="940" />
{/if}
<DNDPositionIndicator
dropInfo={dropMode !== "inside" ? dropInfo : null}
mode={dropMode}
color="var(--spectrum-global-color-static-green-500)"
zIndex="940"
transition
/>

View File

@ -1,33 +1,42 @@
<script>
export let bounds
import Indicator from "./Indicator.svelte"
export let dropInfo
export let mode
export let zIndex
export let color
export let transition
$: x = bounds?.left
$: y = getYPos(bounds, mode)
$: width = bounds?.width
$: valid = bounds != null
$: dimensions = getDimensions(dropInfo?.bounds, mode)
$: prefix = mode === "above" ? "Above" : "Below"
$: text = `${prefix} ${dropInfo?.name}`
const getYPos = (bounds, mode) => {
const getDimensions = (bounds, mode) => {
if (!bounds || !mode) {
return null
}
const { top, height } = bounds
return mode === "above" ? top - 2 : top + height
const { left, top, width, height } = bounds
return {
top: mode === "above" ? top - 4 : top + height,
left: left - 2,
width: width + 4,
}
}
</script>
{#if valid}
<div
class="indicator"
style={`top:${y}px;left:${x}px;width:${width}px;z-index:${zIndex};`}
/>
{/if}
<style>
.indicator {
position: absolute;
height: 2px;
background: var(--spectrum-global-color-static-green-500);
}
</style>
{#key mode}
{#if dimensions}
<Indicator
left={dimensions.left}
top={dimensions.top}
width={dimensions.width}
height={0}
{text}
{zIndex}
{color}
{transition}
flip={mode === "below"}
rounded
/>
{/if}
{/key}

View File

@ -9,6 +9,9 @@
export let color
export let zIndex
export let transition = false
export let flip = false
$: flipped = flip || top < 20
</script>
<div
@ -18,11 +21,11 @@
}}
out:fade={{ duration: transition ? 130 : 0 }}
class="indicator"
class:flipped={top < 20}
class:flipped
style="top: {top}px; left: {left}px; width: {width}px; height: {height}px; --color: {color}; --zIndex: {zIndex};"
>
{#if text}
<div class="text" class:flipped={top < 20}>
<div class="text" class:flipped>
{text}
</div>
{/if}
@ -63,6 +66,7 @@
}
.text.flipped {
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
transform: translateY(0%);
top: -2px;
}