Improve UX when resizing screen/component lists

This commit is contained in:
Andrew Kingston 2023-08-23 10:49:48 +01:00
parent d486a89ee7
commit f72f3f88f7
2 changed files with 42 additions and 11 deletions

View File

@ -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")

View File

@ -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}>