From 217ac49628c520f522cd3f503e577971f6232496 Mon Sep 17 00:00:00 2001 From: Gerard Burns Date: Tue, 21 Nov 2023 13:02:06 +0000 Subject: [PATCH 01/22] wip --- packages/bbui/src/Form/Core/TextField.svelte | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/bbui/src/Form/Core/TextField.svelte b/packages/bbui/src/Form/Core/TextField.svelte index 7afd8f86c3..cbc062d99a 100644 --- a/packages/bbui/src/Form/Core/TextField.svelte +++ b/packages/bbui/src/Form/Core/TextField.svelte @@ -21,7 +21,7 @@ let focus = false const updateValue = newValue => { - if (readonly) { + if (readonly || disabled) { return } if (type === "number") { @@ -32,14 +32,14 @@ } const onFocus = () => { - if (readonly) { + if (readonly || disabled) { return } focus = true } const onBlur = event => { - if (readonly) { + if (readonly || disabled) { return } focus = false @@ -47,14 +47,14 @@ } const onInput = event => { - if (readonly || !updateOnChange) { + if (readonly || !updateOnChange || disabled) { return } updateValue(event.target.value) } const updateValueOnEnter = event => { - if (readonly) { + if (readonly || disabled) { return } if (event.key === "Enter") { @@ -66,10 +66,12 @@ if (type === "bigint") { return "numeric" } - return type === "number" ? "decimal" : "text" + return type === "number" ? +"decimal" : "text" } onMount(() => { + if (disabled) return; focus = autofocus if (focus) field.focus() }) @@ -119,4 +121,8 @@ .spectrum-Textfield { width: 100%; } + + input:focus:hover::placeholder { + color: var(--grey-8) !important; + } From 96046dab3dc56246056fadfc490030ca22517d42 Mon Sep 17 00:00:00 2001 From: Gerard Burns Date: Tue, 21 Nov 2023 14:51:01 +0000 Subject: [PATCH 02/22] component name tooltips --- .../builder/src/builderStore/componentUtils.js | 17 +++++++++++++++++ .../src/components/common/NavItem.svelte | 5 ++++- .../builder/src/components/design/Panel.svelte | 7 +++++-- .../Component/ComponentSettingsPanel.svelte | 8 +++++--- .../ComponentList/ComponentTree.svelte | 2 ++ 5 files changed, 33 insertions(+), 6 deletions(-) diff --git a/packages/builder/src/builderStore/componentUtils.js b/packages/builder/src/builderStore/componentUtils.js index 522dbae416..85171ece66 100644 --- a/packages/builder/src/builderStore/componentUtils.js +++ b/packages/builder/src/builderStore/componentUtils.js @@ -1,4 +1,5 @@ import { store } from "./index" +import { get } from "svelte/store" import { Helpers } from "@budibase/bbui" import { decodeJSBinding, @@ -238,6 +239,10 @@ export const makeComponentUnique = component => { } export const getComponentText = component => { + if (component == null) { + return "" + } + if (component?._instanceName) { return component._instanceName } @@ -246,3 +251,15 @@ export const getComponentText = component => { "component" return capitalise(type) } + +export const getComponentName = component => { + if (component == null) { + return "" + } + + const components = get(store)?.components || {}; + const componentDefinition = components[component._component] || {}; + const name = componentDefinition.friendlyName || componentDefinition.name || ""; + + return name; +} diff --git a/packages/builder/src/components/common/NavItem.svelte b/packages/builder/src/components/common/NavItem.svelte index 2c8a862535..5ec399a7ea 100644 --- a/packages/builder/src/components/common/NavItem.svelte +++ b/packages/builder/src/components/common/NavItem.svelte @@ -1,10 +1,11 @@ {#if $selectedComponent} {#key $selectedComponent._id} - + { if (e.key.toLowerCase() === "enter") { e.target.blur() diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ComponentList/ComponentTree.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ComponentList/ComponentTree.svelte index 8adc6cb5d4..6b5d356deb 100644 --- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ComponentList/ComponentTree.svelte +++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ComponentList/ComponentTree.svelte @@ -11,6 +11,7 @@ import { findComponentPath, getComponentText, + getComponentName, } from "builderStore/componentUtils" import { get } from "svelte/store" import { dndStore } from "./dndStore" @@ -109,6 +110,7 @@ on:drop={onDrop} text={getComponentText(component)} icon={getComponentIcon(component)} + iconTooltip={getComponentName(component)} withArrow={componentHasChildren(component)} indentLevel={level} selected={$store.selectedComponentId === component._id} From f1c3d50930c288b2d4d0aa33a373aecefce8b7c5 Mon Sep 17 00:00:00 2001 From: Gerard Burns Date: Wed, 22 Nov 2023 20:50:55 +0000 Subject: [PATCH 03/22] functioning resize --- .../_components/ScreenList/index.svelte | 90 +++++-------- .../_components/ScreenList/resizable.js | 121 ++++++++++++++++++ 2 files changed, 150 insertions(+), 61 deletions(-) create mode 100644 packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ScreenList/resizable.js diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ScreenList/index.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ScreenList/index.svelte index ef5911c0f8..a7d56e047a 100644 --- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ScreenList/index.svelte +++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ScreenList/index.svelte @@ -9,51 +9,42 @@ import NavItem from "components/common/NavItem.svelte" import RoleIndicator from "./RoleIndicator.svelte" import DropdownMenu from "./DropdownMenu.svelte" - import { onMount, tick } from "svelte" import { goto } from "@roxi/routify" + import { getVerticalResizeActions } from './resizable'; + import { tick } from "svelte" - let search = false + const [resizable, resizableHandle] = getVerticalResizeActions(); + + let searching = false let resizing = false let searchValue = "" let searchInput let container let screensContainer let scrolling = false - let previousHeight = null - let dragOffset $: filteredScreens = getFilteredScreens($sortedScreens, searchValue) - const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)) - const openSearch = async () => { - search = true + searching = true await tick() searchInput.focus() screensContainer.scroll({ top: 0, behavior: "smooth" }) - previousHeight = $screensHeight - $screensHeight = "calc(100% + 1px)" } const closeSearch = async () => { - if (previousHeight) { - // Restore previous height and wait for animation - $screensHeight = previousHeight - previousHeight = null - await sleep(300) - } - search = false + searching = false searchValue = "" } - const getFilteredScreens = (screens, search) => { + const getFilteredScreens = (screens, searchValue) => { return screens.filter(screen => { - return !search || screen.routing.route.includes(search) + return !searchValue || screen.routing.route.includes(searchValue) }) } const handleAddButton = () => { - if (search) { + if (searching) { closeSearch() } else { $goto("../new") @@ -70,67 +61,35 @@ scrolling = e.target.scrollTop !== 0 } - 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 - document.addEventListener("mousemove", resize) - document.addEventListener("mouseup", stopResizing) - } - - const resize = e => { - // Prevent negative heights as this screws with layout - const newHeight = Math.max(0, e.clientY + dragOffset) - if (newHeight == null || isNaN(newHeight)) { - return - } - $screensHeight = `${newHeight}px` - } - - const stopResizing = () => { - resizing = false - 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" - } - })
-
+
Screens
-
+
@@ -164,8 +123,10 @@
screensHeight.set("210px")} />
@@ -177,10 +138,11 @@ min-height: 147px; max-height: calc(100% - 147px); position: relative; - } - .screens.search { transition: height 300ms ease-out; + } + .screens.searching { max-height: none; + height: 100% !important; } .screens.resizing { user-select: none; @@ -219,7 +181,7 @@ .input::placeholder { color: var(--spectrum-global-color-gray-600); } - .screens.search input { + .screens.searching input { display: block; } @@ -305,4 +267,10 @@ .divider:hover:after { background: var(--spectrum-global-color-gray-300); } + .divider.disabled { + cursor: auto; + } + .divider.disabled:after { + background: var(--spectrum-global-color-gray-200); + } diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ScreenList/resizable.js b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ScreenList/resizable.js new file mode 100644 index 0000000000..c3bccf024d --- /dev/null +++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ScreenList/resizable.js @@ -0,0 +1,121 @@ +export const getHorizontalResizeActions = (initialValue, setValue = () => {}) => { + let element = null; + + const elementAction = (node) => { + element = node; + + if (initialValue != null) { + element.style.height = `${initialValue}px` + } + + return { + destroy() { + element = null; + } + } + } + + const dragHandleAction = (node) => { + let startWidth = null; + let startPosition = null; + + const handleMouseMove = (e) => { + const change = e.pageX - startPosition; + element.style.width = `${startWidth + change}px` + } + + const handleMouseUp = () => { + window.removeEventListener("mousemove", handleMouseMove); + window.removeEventListener("mouseup", handleMouseUp); + element.style.removeProperty('transition'); // remove temporary transition override + setValue(element.clientHeight); + } + + const handleMouseDown = (e) => { + if (e.target.hasAttribute("disabled") && e.target.getAttribute("disabled") !== "false") { + return; + } + + element.style.transition = "width 0ms"; // temporarily override any width transitions + startWidth = element.clientWidth; + startPosition = e.pageX; + + window.addEventListener("mousemove", handleMouseMove); + window.addEventListener("mouseup", handleMouseUp); + }; + + node.addEventListener("mousedown", handleMouseDown); + + return { + destroy() { + node.removeEventListener("mousedown", handleMouseDown); + } + } + } + + return [ + elementAction, + dragHandleAction + ] +}; + +export const getVerticalResizeActions = (initialValue, setValue = () => {}) => { + let element = null; + + const elementAction = (node) => { + element = node; + + if (initialValue != null) { + element.style.height = `${initialValue}px` + } + + return { + destroy() { + element = null; + } + } + } + + const dragHandleAction = (node) => { + let startHeight = null; + let startPosition = null; + + const handleMouseMove = (e) => { + const change = e.pageY - startPosition; + element.style.height = `${startHeight + change}px` + } + + const handleMouseUp = () => { + window.removeEventListener("mousemove", handleMouseMove); + window.removeEventListener("mouseup", handleMouseUp); + element.style.removeProperty('transition'); // remove temporary transition override + setValue(element.clientHeight); + } + + const handleMouseDown = (e) => { + if (e.target.hasAttribute("disabled") && e.target.getAttribute("disabled") !== "false") { + return; + } + + element.style.transition = "height 0ms"; // temporarily override any height transitions + startHeight = element.clientHeight; + startPosition = e.pageY; + + window.addEventListener("mousemove", handleMouseMove); + window.addEventListener("mouseup", handleMouseUp); + }; + + node.addEventListener("mousedown", handleMouseDown); + + return { + destroy() { + node.removeEventListener("mousedown", handleMouseDown); + } + } + } + + return [ + elementAction, + dragHandleAction + ] +}; From 63b4a4cada687be3e44cdcd764546fb5bbd6240a Mon Sep 17 00:00:00 2001 From: Gerard Burns Date: Thu, 23 Nov 2023 13:18:11 +0000 Subject: [PATCH 04/22] wip --- packages/builder/src/builderStore/index.js | 2 - .../_components/ScreenList/index.svelte | 10 +-- .../_components/ScreenList/resizable.js | 76 ++++--------------- 3 files changed, 19 insertions(+), 69 deletions(-) diff --git a/packages/builder/src/builderStore/index.js b/packages/builder/src/builderStore/index.js index eecccab7a6..583611a105 100644 --- a/packages/builder/src/builderStore/index.js +++ b/packages/builder/src/builderStore/index.js @@ -147,5 +147,3 @@ export const userSelectedResourceMap = derived(userStore, $userStore => { export const isOnlyUser = derived(userStore, $userStore => { return $userStore.length < 2 }) - -export const screensHeight = writable("210px") diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ScreenList/index.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ScreenList/index.svelte index a7d56e047a..5fb48aec7d 100644 --- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ScreenList/index.svelte +++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ScreenList/index.svelte @@ -4,7 +4,6 @@ store, sortedScreens, userSelectedResourceMap, - screensHeight, } from "builderStore" import NavItem from "components/common/NavItem.svelte" import RoleIndicator from "./RoleIndicator.svelte" @@ -19,7 +18,6 @@ let resizing = false let searchValue = "" let searchInput - let container let screensContainer let scrolling = false @@ -68,8 +66,6 @@ class="screens" class:searching class:resizing - style={`height:${$screensHeight};`} - bind:this={container} use:resizable >
@@ -127,7 +123,6 @@ class="divider" class:disabled={searching} use:resizableHandle - on:dblclick={() => screensHeight.set("210px")} />
@@ -138,10 +133,11 @@ min-height: 147px; max-height: calc(100% - 147px); position: relative; - transition: height 300ms ease-out; + transition: height 300ms ease-out, max-height 300ms ease-out; + height: 210px; } .screens.searching { - max-height: none; + max-height: 100%; height: 100% !important; } .screens.resizing { diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ScreenList/resizable.js b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ScreenList/resizable.js index c3bccf024d..2c98c87977 100644 --- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ScreenList/resizable.js +++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ScreenList/resizable.js @@ -1,63 +1,3 @@ -export const getHorizontalResizeActions = (initialValue, setValue = () => {}) => { - let element = null; - - const elementAction = (node) => { - element = node; - - if (initialValue != null) { - element.style.height = `${initialValue}px` - } - - return { - destroy() { - element = null; - } - } - } - - const dragHandleAction = (node) => { - let startWidth = null; - let startPosition = null; - - const handleMouseMove = (e) => { - const change = e.pageX - startPosition; - element.style.width = `${startWidth + change}px` - } - - const handleMouseUp = () => { - window.removeEventListener("mousemove", handleMouseMove); - window.removeEventListener("mouseup", handleMouseUp); - element.style.removeProperty('transition'); // remove temporary transition override - setValue(element.clientHeight); - } - - const handleMouseDown = (e) => { - if (e.target.hasAttribute("disabled") && e.target.getAttribute("disabled") !== "false") { - return; - } - - element.style.transition = "width 0ms"; // temporarily override any width transitions - startWidth = element.clientWidth; - startPosition = e.pageX; - - window.addEventListener("mousemove", handleMouseMove); - window.addEventListener("mouseup", handleMouseUp); - }; - - node.addEventListener("mousedown", handleMouseDown); - - return { - destroy() { - node.removeEventListener("mousedown", handleMouseDown); - } - } - } - - return [ - elementAction, - dragHandleAction - ] -}; export const getVerticalResizeActions = (initialValue, setValue = () => {}) => { let element = null; @@ -93,6 +33,16 @@ export const getVerticalResizeActions = (initialValue, setValue = () => {}) => { } const handleMouseDown = (e) => { + if (e.detail > 1) { + // e.detail is the number of rapid clicks, so e.detail = 2 is + // a double click. We want to prevent default behaviour in + // this case as it highlights nearby selectable elements, which + // then interferes with the resizing mousemove. + // Putting this on the double click handler doesn't seem to + // work, so it must go here. + e.preventDefault(); + } + if (e.target.hasAttribute("disabled") && e.target.getAttribute("disabled") !== "false") { return; } @@ -105,11 +55,17 @@ export const getVerticalResizeActions = (initialValue, setValue = () => {}) => { window.addEventListener("mouseup", handleMouseUp); }; + const handleDoubleClick = (e) => { + element.style.removeProperty("height"); + } + node.addEventListener("mousedown", handleMouseDown); + node.addEventListener("dblclick", handleDoubleClick); return { destroy() { node.removeEventListener("mousedown", handleMouseDown); + node.removeEventListener("dblclick", handleDoubleClick); } } } From 8b8604267d25b2b3c3cc5e72becbbcdfab74b3a5 Mon Sep 17 00:00:00 2001 From: Gerard Burns Date: Thu, 23 Nov 2023 13:37:10 +0000 Subject: [PATCH 05/22] refactor --- .../_components/ScreenList/index.svelte | 1 + .../_components/ScreenList/resizable.js | 31 ++++++++++++------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ScreenList/index.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ScreenList/index.svelte index 5fb48aec7d..2e235754f2 100644 --- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ScreenList/index.svelte +++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ScreenList/index.svelte @@ -119,6 +119,7 @@