Improve UX when resizing screen/component lists
This commit is contained in:
parent
d486a89ee7
commit
f72f3f88f7
|
@ -4,7 +4,7 @@ import { getTemporalStore } from "./store/temporal"
|
||||||
import { getThemeStore } from "./store/theme"
|
import { getThemeStore } from "./store/theme"
|
||||||
import { getUserStore } from "./store/users"
|
import { getUserStore } from "./store/users"
|
||||||
import { getDeploymentStore } from "./store/deployments"
|
import { getDeploymentStore } from "./store/deployments"
|
||||||
import { derived } from "svelte/store"
|
import { derived, writable } from "svelte/store"
|
||||||
import { findComponent, findComponentPath } from "./componentUtils"
|
import { findComponent, findComponentPath } from "./componentUtils"
|
||||||
import { RoleUtils } from "@budibase/frontend-core"
|
import { RoleUtils } from "@budibase/frontend-core"
|
||||||
import { createHistoryStore } from "builderStore/store/history"
|
import { createHistoryStore } from "builderStore/store/history"
|
||||||
|
@ -147,3 +147,5 @@ export const userSelectedResourceMap = derived(userStore, $userStore => {
|
||||||
export const isOnlyUser = derived(userStore, $userStore => {
|
export const isOnlyUser = derived(userStore, $userStore => {
|
||||||
return $userStore.length < 2
|
return $userStore.length < 2
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const screensHeight = writable("210px")
|
||||||
|
|
|
@ -1,20 +1,25 @@
|
||||||
<script>
|
<script>
|
||||||
import { Icon, Layout, Body } from "@budibase/bbui"
|
import { Icon, Layout, Body } from "@budibase/bbui"
|
||||||
import { store, sortedScreens, userSelectedResourceMap } from "builderStore"
|
import {
|
||||||
|
store,
|
||||||
|
sortedScreens,
|
||||||
|
userSelectedResourceMap,
|
||||||
|
screensHeight,
|
||||||
|
} from "builderStore"
|
||||||
import NavItem from "components/common/NavItem.svelte"
|
import NavItem from "components/common/NavItem.svelte"
|
||||||
import RoleIndicator from "./RoleIndicator.svelte"
|
import RoleIndicator from "./RoleIndicator.svelte"
|
||||||
import DropdownMenu from "./DropdownMenu.svelte"
|
import DropdownMenu from "./DropdownMenu.svelte"
|
||||||
import NewScreen from "components/design/NewScreen/index.svelte"
|
import NewScreen from "components/design/NewScreen/index.svelte"
|
||||||
import { tick } from "svelte"
|
import { onMount, tick } from "svelte"
|
||||||
|
|
||||||
let newScreen = false
|
let newScreen = false
|
||||||
let search = false
|
let search = false
|
||||||
let resizing = false
|
let resizing = false
|
||||||
let searchValue = ""
|
let searchValue = ""
|
||||||
let searchInput
|
let searchInput
|
||||||
|
let container
|
||||||
let screensContainer
|
let screensContainer
|
||||||
let scrolling = false
|
let scrolling = false
|
||||||
let height = "210px"
|
|
||||||
let previousHeight = null
|
let previousHeight = null
|
||||||
let dragOffset
|
let dragOffset
|
||||||
|
|
||||||
|
@ -27,14 +32,14 @@
|
||||||
await tick()
|
await tick()
|
||||||
searchInput.focus()
|
searchInput.focus()
|
||||||
screensContainer.scroll({ top: 0, behavior: "smooth" })
|
screensContainer.scroll({ top: 0, behavior: "smooth" })
|
||||||
previousHeight = height
|
previousHeight = $screensHeight
|
||||||
height = "calc(100% + 1px)"
|
$screensHeight = "calc(100% + 1px)"
|
||||||
}
|
}
|
||||||
|
|
||||||
const closeSearch = async () => {
|
const closeSearch = async () => {
|
||||||
if (previousHeight) {
|
if (previousHeight) {
|
||||||
// Restore previous height and wait for animation
|
// Restore previous height and wait for animation
|
||||||
height = previousHeight
|
$screensHeight = previousHeight
|
||||||
previousHeight = null
|
previousHeight = null
|
||||||
await sleep(300)
|
await sleep(300)
|
||||||
}
|
}
|
||||||
|
@ -71,28 +76,48 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
const startResizing = e => {
|
const startResizing = e => {
|
||||||
|
// Reset the height store to match the true height
|
||||||
|
$screensHeight = `${container.getBoundingClientRect().height}px`
|
||||||
|
|
||||||
|
// Store an offset to easily compute new height when moving the mouse
|
||||||
|
dragOffset = parseInt($screensHeight) - e.clientY
|
||||||
|
|
||||||
|
// Add event listeners
|
||||||
resizing = true
|
resizing = true
|
||||||
dragOffset = parseInt(height) - e.clientY
|
|
||||||
document.addEventListener("mousemove", resize)
|
document.addEventListener("mousemove", resize)
|
||||||
document.addEventListener("mouseup", stopResizing)
|
document.addEventListener("mouseup", stopResizing)
|
||||||
}
|
}
|
||||||
|
|
||||||
const resize = e => {
|
const resize = e => {
|
||||||
|
// Prevent negative heights as this screws with layout
|
||||||
const newHeight = Math.max(0, e.clientY + dragOffset)
|
const newHeight = Math.max(0, e.clientY + dragOffset)
|
||||||
if (newHeight == null || isNaN(newHeight)) {
|
if (newHeight == null || isNaN(newHeight)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
height = `${newHeight}px`
|
$screensHeight = `${newHeight}px`
|
||||||
}
|
}
|
||||||
|
|
||||||
const stopResizing = () => {
|
const stopResizing = () => {
|
||||||
resizing = false
|
resizing = false
|
||||||
document.removeEventListener("mousemove", resize)
|
document.removeEventListener("mousemove", resize)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
// Ensure we aren't stuck at 100% height from leaving while searching
|
||||||
|
if ($screensHeight == null || isNaN(parseInt($screensHeight))) {
|
||||||
|
$screensHeight = "210px"
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:window on:keydown={onKeyDown} />
|
<svelte:window on:keydown={onKeyDown} />
|
||||||
<div class="screens" class:search class:resizing style={`height:${height};`}>
|
<div
|
||||||
|
class="screens"
|
||||||
|
class:search
|
||||||
|
class:resizing
|
||||||
|
style={`height:${$screensHeight};`}
|
||||||
|
bind:this={container}
|
||||||
|
>
|
||||||
<div class="header" class:scrolling>
|
<div class="header" class:scrolling>
|
||||||
<input
|
<input
|
||||||
readonly={!search}
|
readonly={!search}
|
||||||
|
@ -143,7 +168,11 @@
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="divider" on:mousedown={startResizing} />
|
<div
|
||||||
|
class="divider"
|
||||||
|
on:mousedown={startResizing}
|
||||||
|
on:dblclick={() => screensHeight.set("210px")}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="newScreen" class:newScreenVisible={newScreen}>
|
<div class="newScreen" class:newScreenVisible={newScreen}>
|
||||||
|
|
Loading…
Reference in New Issue