UX Enhancements and custom positioning behaviour for the popover
This commit is contained in:
parent
7492a70bcf
commit
13f6fed101
|
@ -17,6 +17,7 @@ export default function positionDropdown(element, opts) {
|
|||
maxWidth,
|
||||
useAnchorWidth,
|
||||
offset = 5,
|
||||
customUpdate,
|
||||
} = opts
|
||||
if (!anchor) {
|
||||
return
|
||||
|
@ -32,33 +33,42 @@ export default function positionDropdown(element, opts) {
|
|||
left: null,
|
||||
top: null,
|
||||
}
|
||||
// Determine vertical styles
|
||||
if (align === "right-outside") {
|
||||
styles.top = anchorBounds.top
|
||||
} else if (window.innerHeight - anchorBounds.bottom < (maxHeight || 100)) {
|
||||
styles.top = anchorBounds.top - elementBounds.height - offset
|
||||
styles.maxHeight = maxHeight || 240
|
||||
} else {
|
||||
styles.top = anchorBounds.bottom + offset
|
||||
styles.maxHeight =
|
||||
maxHeight || window.innerHeight - anchorBounds.bottom - 20
|
||||
}
|
||||
|
||||
// Determine horizontal styles
|
||||
if (!maxWidth && useAnchorWidth) {
|
||||
styles.maxWidth = anchorBounds.width
|
||||
}
|
||||
if (useAnchorWidth) {
|
||||
styles.minWidth = anchorBounds.width
|
||||
}
|
||||
if (align === "right") {
|
||||
styles.left = anchorBounds.left + anchorBounds.width - elementBounds.width
|
||||
} else if (align === "right-outside") {
|
||||
styles.left = anchorBounds.right + offset
|
||||
} else if (align === "left-outside") {
|
||||
styles.left = anchorBounds.left - elementBounds.width - offset
|
||||
if (typeof customUpdate === "function") {
|
||||
styles = customUpdate(anchorBounds, elementBounds, styles)
|
||||
} else {
|
||||
styles.left = anchorBounds.left
|
||||
// Determine vertical styles
|
||||
if (align === "right-outside") {
|
||||
styles.top = anchorBounds.top
|
||||
} else if (
|
||||
window.innerHeight - anchorBounds.bottom <
|
||||
(maxHeight || 100)
|
||||
) {
|
||||
styles.top = anchorBounds.top - elementBounds.height - offset
|
||||
styles.maxHeight = maxHeight || 240
|
||||
} else {
|
||||
styles.top = anchorBounds.bottom + offset
|
||||
styles.maxHeight =
|
||||
maxHeight || window.innerHeight - anchorBounds.bottom - 20
|
||||
}
|
||||
|
||||
// Determine horizontal styles
|
||||
if (!maxWidth && useAnchorWidth) {
|
||||
styles.maxWidth = anchorBounds.width
|
||||
}
|
||||
if (useAnchorWidth) {
|
||||
styles.minWidth = anchorBounds.width
|
||||
}
|
||||
if (align === "right") {
|
||||
styles.left =
|
||||
anchorBounds.left + anchorBounds.width - elementBounds.width
|
||||
} else if (align === "right-outside") {
|
||||
styles.left = anchorBounds.right + offset
|
||||
} else if (align === "left-outside") {
|
||||
styles.left = anchorBounds.left - elementBounds.width - offset
|
||||
} else {
|
||||
styles.left = anchorBounds.left
|
||||
}
|
||||
}
|
||||
|
||||
// Apply styles
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
export let animate = true
|
||||
export let customZindex
|
||||
|
||||
export let handlePostionUpdate
|
||||
export let showPopover = true
|
||||
export let clickOutsideOverride = false
|
||||
|
||||
|
@ -88,6 +89,7 @@
|
|||
maxWidth,
|
||||
useAnchorWidth,
|
||||
offset,
|
||||
customUpdate: handlePostionUpdate,
|
||||
}}
|
||||
use:clickOutside={{
|
||||
callback: dismissible ? handleOutsideClick : () => {},
|
||||
|
|
|
@ -3,15 +3,30 @@
|
|||
import { dndzone } from "svelte-dnd-action"
|
||||
import { createEventDispatcher } from "svelte"
|
||||
import { generate } from "shortid"
|
||||
import { setContext } from "svelte"
|
||||
import { writable } from "svelte/store"
|
||||
|
||||
export let items = []
|
||||
export let showHandle = true
|
||||
export let highlighted
|
||||
export let listType
|
||||
export let listTypeProps = {}
|
||||
export let listItemKey
|
||||
export let draggable = true
|
||||
|
||||
let store = writable({
|
||||
selected: null,
|
||||
actions: {
|
||||
select: id => {
|
||||
store.update(state => ({
|
||||
...state,
|
||||
selected: id,
|
||||
}))
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
setContext("draggable", store)
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
const flipDurationMs = 150
|
||||
|
||||
|
@ -66,7 +81,7 @@
|
|||
{#each draggableItems as draggable (draggable.id)}
|
||||
<li
|
||||
bind:this={anchors[draggable.id]}
|
||||
class:highlighted={draggable.id === highlighted}
|
||||
class:highlighted={draggable.id === $store.selected}
|
||||
>
|
||||
<div class="left-content">
|
||||
{#if showHandle}
|
||||
|
@ -113,7 +128,8 @@
|
|||
border-bottom: 1px solid
|
||||
var(--spectrum-table-border-color, var(--spectrum-alias-border-color-mid));
|
||||
}
|
||||
.list-wrap > li:hover {
|
||||
.list-wrap > li:hover,
|
||||
li.highlighted {
|
||||
background-color: var(
|
||||
--spectrum-table-row-background-color-hover,
|
||||
var(--spectrum-alias-highlight-hover)
|
||||
|
@ -135,7 +151,4 @@
|
|||
padding-left: var(--spacing-s);
|
||||
padding-right: var(--spacing-s);
|
||||
}
|
||||
li.highlighted {
|
||||
background-color: pink;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -4,17 +4,24 @@
|
|||
import { cloneDeep } from "lodash/fp"
|
||||
import { createEventDispatcher } from "svelte"
|
||||
import ComponentSettingsSection from "../../../../../pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Component/ComponentSettingsSection.svelte"
|
||||
import { getContext } from "svelte"
|
||||
|
||||
export let anchor
|
||||
export let field
|
||||
export let componentBindings
|
||||
export let bindings
|
||||
|
||||
const draggable = getContext("draggable")
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
let popover
|
||||
let drawers = []
|
||||
let sudoComponentInstance
|
||||
let open = false
|
||||
|
||||
$: if (open && $draggable.selected && $draggable.selected != field._id) {
|
||||
popover.hide()
|
||||
}
|
||||
|
||||
$: if (field) {
|
||||
sudoComponentInstance = field
|
||||
|
@ -61,7 +68,10 @@
|
|||
hoverable
|
||||
size="S"
|
||||
on:click={() => {
|
||||
popover.show()
|
||||
if (!open) {
|
||||
popover.show()
|
||||
open = true
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
|
@ -69,11 +79,37 @@
|
|||
bind:this={popover}
|
||||
on:open={() => {
|
||||
drawers = []
|
||||
$draggable.actions.select(field._id)
|
||||
}}
|
||||
on:close={() => {
|
||||
open = false
|
||||
if ($draggable.selected == field._id) {
|
||||
$draggable.actions.select()
|
||||
}
|
||||
}}
|
||||
{anchor}
|
||||
align="left-outside"
|
||||
showPopover={drawers.length == 0}
|
||||
clickOutsideOverride={drawers.length > 0}
|
||||
maxHeight={600}
|
||||
handlePostionUpdate={(anchorBounds, eleBounds, cfg) => {
|
||||
let { left, top } = cfg
|
||||
let percentageOffset = 30
|
||||
// left-outside
|
||||
left = anchorBounds.left - eleBounds.width - 5
|
||||
|
||||
// shift up from the anchor, if space allows
|
||||
let offsetPos = Math.floor(eleBounds.height / 100) * percentageOffset
|
||||
let defaultTop = anchorBounds.top - offsetPos
|
||||
|
||||
if (window.innerHeight - defaultTop < eleBounds.height) {
|
||||
top = window.innerHeight - eleBounds.height - 5
|
||||
} else {
|
||||
top = anchorBounds.top - offsetPos
|
||||
}
|
||||
|
||||
return { ...cfg, left, top }
|
||||
}}
|
||||
>
|
||||
<span class="popover-wrap">
|
||||
<Layout noPadding noGap>
|
||||
|
|
Loading…
Reference in New Issue