Refactor and tidy up
This commit is contained in:
parent
29ddeab0d4
commit
de183d5c78
|
@ -117,6 +117,9 @@
|
||||||
"width": 400,
|
"width": 400,
|
||||||
"height": 200
|
"height": 200
|
||||||
},
|
},
|
||||||
|
"grid": {
|
||||||
|
"fill": true
|
||||||
|
},
|
||||||
"styles": ["padding", "size", "background", "border", "shadow"],
|
"styles": ["padding", "size", "background", "border", "shadow"],
|
||||||
"settings": [
|
"settings": [
|
||||||
{
|
{
|
||||||
|
@ -561,6 +564,10 @@
|
||||||
"width": 105,
|
"width": 105,
|
||||||
"height": 32
|
"height": 32
|
||||||
},
|
},
|
||||||
|
"grid": {
|
||||||
|
"hAlign": "center",
|
||||||
|
"vAlign": "center"
|
||||||
|
},
|
||||||
"settings": [
|
"settings": [
|
||||||
{
|
{
|
||||||
"type": "text",
|
"type": "text",
|
||||||
|
|
|
@ -198,7 +198,9 @@
|
||||||
$: darkMode = !currentTheme?.includes("light")
|
$: darkMode = !currentTheme?.includes("light")
|
||||||
|
|
||||||
// Build meta styles and stringify to apply to the wrapper node
|
// Build meta styles and stringify to apply to the wrapper node
|
||||||
|
$: definitionMetaStyles = getDefinitonMetaStyles(definition)
|
||||||
$: metaStyles = {
|
$: metaStyles = {
|
||||||
|
...definitionMetaStyles,
|
||||||
...instance._styles?.meta,
|
...instance._styles?.meta,
|
||||||
...ephemeralStyles,
|
...ephemeralStyles,
|
||||||
}
|
}
|
||||||
|
@ -618,6 +620,22 @@
|
||||||
builderStore.actions.selectComponent(id)
|
builderStore.actions.selectComponent(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Util to generate meta styles based on component definition
|
||||||
|
const alignToStyleMap = {
|
||||||
|
start: "flex-start",
|
||||||
|
center: "center",
|
||||||
|
end: "flex-end",
|
||||||
|
stretch: "stretch",
|
||||||
|
}
|
||||||
|
const getDefinitonMetaStyles = definition => {
|
||||||
|
const gridHAlign = definition.grid?.hAlign || "stretch"
|
||||||
|
const gridVAlign = definition.grid?.vAlign || "center"
|
||||||
|
return {
|
||||||
|
["align-items"]: alignToStyleMap[gridHAlign],
|
||||||
|
["justify-content"]: alignToStyleMap[gridVAlign],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
// Register this component instance for external access
|
// Register this component instance for external access
|
||||||
if ($appStore.isDevApp) {
|
if ($appStore.isDevApp) {
|
||||||
|
@ -661,6 +679,7 @@
|
||||||
class:parent={hasChildren}
|
class:parent={hasChildren}
|
||||||
class:block={isBlock}
|
class:block={isBlock}
|
||||||
class:error={errorState}
|
class:error={errorState}
|
||||||
|
class:fill={definition.grid?.fill}
|
||||||
data-id={id}
|
data-id={id}
|
||||||
data-name={name}
|
data-name={name}
|
||||||
data-icon={icon}
|
data-icon={icon}
|
||||||
|
|
|
@ -123,4 +123,11 @@
|
||||||
--row-start: var(--grid-mobile-row-start, var(--grid-desktop-row-start, 1));
|
--row-start: var(--grid-mobile-row-start, var(--grid-desktop-row-start, 1));
|
||||||
--row-end: var(--grid-mobile-row-end, var(--grid-desktop-row-end, 2));
|
--row-end: var(--grid-mobile-row-end, var(--grid-desktop-row-end, 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Handle grid children which need to fill the outer component wrapper */
|
||||||
|
.grid :global(> .component.fill > *) {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
flex: 1 1 0;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
import { Utils } from "@budibase/frontend-core"
|
import { Utils } from "@budibase/frontend-core"
|
||||||
import { findComponentById } from "utils/components.js"
|
import { findComponentById } from "utils/components.js"
|
||||||
import { DNDPlaceholderID } from "constants"
|
import { DNDPlaceholderID } from "constants"
|
||||||
|
import { isGridEvent } from "utils/grid"
|
||||||
|
|
||||||
const ThrottleRate = 130
|
const ThrottleRate = 130
|
||||||
|
|
||||||
|
@ -25,15 +26,6 @@
|
||||||
// Local flag for whether we are awaiting an async drop event
|
// Local flag for whether we are awaiting an async drop event
|
||||||
let dropping = false
|
let dropping = false
|
||||||
|
|
||||||
// Util to check if a DND event originates from a grid (or inside a grid).
|
|
||||||
// This is important as we do not handle grid DND in this handler.
|
|
||||||
const isGridEvent = e => {
|
|
||||||
return e.target
|
|
||||||
?.closest?.(".component")
|
|
||||||
?.parentNode?.closest?.(".component")
|
|
||||||
?.childNodes[0]?.classList.contains("grid")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Util to get the inner DOM node by a component ID
|
// Util to get the inner DOM node by a component ID
|
||||||
const getDOMNode = id => {
|
const getDOMNode = id => {
|
||||||
return document.getElementsByClassName(`${id}-dom`)[0]
|
return document.getElementsByClassName(`${id}-dom`)[0]
|
||||||
|
@ -267,7 +259,7 @@
|
||||||
// Check if we're adding a new component rather than moving one
|
// Check if we're adding a new component rather than moving one
|
||||||
if (source.newComponentType) {
|
if (source.newComponentType) {
|
||||||
dropping = true
|
dropping = true
|
||||||
await builderStore.actions.dropNewComponent(
|
builderStore.actions.dropNewComponent(
|
||||||
source.newComponentType,
|
source.newComponentType,
|
||||||
drop.parent,
|
drop.parent,
|
||||||
drop.index
|
drop.index
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
import { onMount } from "svelte"
|
import { onMount } from "svelte"
|
||||||
import { DNDPlaceholderID } from "constants"
|
import { DNDPlaceholderID } from "constants"
|
||||||
import { domDebounce } from "utils/domDebounce.js"
|
import { Utils } from "@budibase/frontend-core"
|
||||||
|
|
||||||
let left, top, height, width
|
let left, top, height, width
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@
|
||||||
width = bounds.width
|
width = bounds.width
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const debouncedUpdate = domDebounce(updatePosition)
|
const debouncedUpdate = Utils.domDebounce(updatePosition)
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
const interval = setInterval(debouncedUpdate, 100)
|
const interval = setInterval(debouncedUpdate, 100)
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import { onMount, onDestroy } from "svelte"
|
import { onMount, onDestroy } from "svelte"
|
||||||
import { builderStore, componentStore } from "stores"
|
import { builderStore, componentStore } from "stores"
|
||||||
import { Utils, memo } from "@budibase/frontend-core"
|
import { Utils, memo } from "@budibase/frontend-core"
|
||||||
|
import { isGridEvent, getGridParentID } from "utils/grid"
|
||||||
|
|
||||||
// Enum for device preview type, included in CSS variables
|
// Enum for device preview type, included in CSS variables
|
||||||
const Devices = {
|
const Devices = {
|
||||||
|
@ -67,18 +68,6 @@
|
||||||
// Sugar for a combination of both min and max
|
// Sugar for a combination of both min and max
|
||||||
const minMax = (value, min, max) => Math.min(max, Math.max(min, value))
|
const minMax = (value, min, max) => Math.min(max, Math.max(min, value))
|
||||||
|
|
||||||
// Util to check if a DND event originates from a grid (or inside a grid).
|
|
||||||
// This is important as we do not handle grid DND in this handler.
|
|
||||||
const isGridEvent = e => {
|
|
||||||
return (
|
|
||||||
e.target
|
|
||||||
.closest?.(".component")
|
|
||||||
?.parentNode.closest(".component")
|
|
||||||
?.childNodes[0].classList?.contains("grid") ||
|
|
||||||
e.target.classList.contains("anchor")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Util to get the inner DOM node by a component ID
|
// Util to get the inner DOM node by a component ID
|
||||||
const getDOMNode = id => {
|
const getDOMNode = id => {
|
||||||
const component = document.getElementsByClassName(id)[0]
|
const component = document.getElementsByClassName(id)[0]
|
||||||
|
@ -172,7 +161,7 @@
|
||||||
|
|
||||||
// Find grid parent
|
// Find grid parent
|
||||||
const domComponent = getDOMNode(id)
|
const domComponent = getDOMNode(id)
|
||||||
const gridId = domComponent?.closest(".grid")?.parentNode.dataset.id
|
const gridId = getGridParentID(domComponent)
|
||||||
if (!gridId) {
|
if (!gridId) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
import { onMount, onDestroy } from "svelte"
|
import { onMount, onDestroy } from "svelte"
|
||||||
import Indicator from "./Indicator.svelte"
|
import Indicator from "./Indicator.svelte"
|
||||||
import { builderStore, componentStore } from "stores"
|
import { builderStore, componentStore } from "stores"
|
||||||
import { memo } from "@budibase/frontend-core"
|
import { memo, Utils } from "@budibase/frontend-core"
|
||||||
import { writable } from "svelte/store"
|
import { writable } from "svelte/store"
|
||||||
|
|
||||||
export let componentId = null
|
export let componentId = null
|
||||||
|
@ -47,12 +47,12 @@
|
||||||
prefix,
|
prefix,
|
||||||
allowResizeAnchors,
|
allowResizeAnchors,
|
||||||
})
|
})
|
||||||
$: $config, updatePosition()
|
$: $config, debouncedUpdate()
|
||||||
|
|
||||||
// Update position when component state changes
|
// Update position when component state changes
|
||||||
$: instance = componentStore.actions.getComponentInstance(componentId)
|
$: instance = componentStore.actions.getComponentInstance(componentId)
|
||||||
$: componentState = $instance?.state || writable()
|
$: componentState = $instance?.state || writable()
|
||||||
$: $componentState, updatePosition()
|
$: $componentState, debouncedUpdate()
|
||||||
|
|
||||||
const checkInsideGrid = id => {
|
const checkInsideGrid = id => {
|
||||||
const component = document.getElementsByClassName(id)[0]
|
const component = document.getElementsByClassName(id)[0]
|
||||||
|
@ -160,16 +160,17 @@
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
const debouncedUpdate = Utils.domDebounce(updatePosition)
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
updatePosition()
|
debouncedUpdate()
|
||||||
interval = setInterval(updatePosition, 100)
|
interval = setInterval(debouncedUpdate, 100)
|
||||||
document.addEventListener("scroll", updatePosition, true)
|
document.addEventListener("scroll", debouncedUpdate, true)
|
||||||
})
|
})
|
||||||
|
|
||||||
onDestroy(() => {
|
onDestroy(() => {
|
||||||
clearInterval(interval)
|
clearInterval(interval)
|
||||||
document.removeEventListener("scroll", updatePosition, true)
|
document.removeEventListener("scroll", v, true)
|
||||||
observers.forEach(o => o.disconnect())
|
observers.forEach(o => o.disconnect())
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
import SettingsColorPicker from "./SettingsColorPicker.svelte"
|
import SettingsColorPicker from "./SettingsColorPicker.svelte"
|
||||||
import SettingsPicker from "./SettingsPicker.svelte"
|
import SettingsPicker from "./SettingsPicker.svelte"
|
||||||
import { builderStore, componentStore, dndIsDragging } from "stores"
|
import { builderStore, componentStore, dndIsDragging } from "stores"
|
||||||
import { domDebounce } from "utils/domDebounce"
|
import { Utils } from "@budibase/frontend-core"
|
||||||
|
import { isGridChild } from "utils/grid"
|
||||||
|
|
||||||
const verticalOffset = 36
|
const verticalOffset = 36
|
||||||
const horizontalOffset = 2
|
const horizontalOffset = 2
|
||||||
|
@ -49,8 +50,10 @@
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const id = $builderStore.selectedComponentId
|
const id = $builderStore.selectedComponentId
|
||||||
const parent = document.getElementsByClassName(id)?.[0]
|
let element = document.getElementsByClassName(id)?.[0]
|
||||||
const element = parent?.children?.[0]
|
if (!isGridChild(element)) {
|
||||||
|
element = element?.children?.[0]
|
||||||
|
}
|
||||||
|
|
||||||
// The settings bar is higher in the dom tree than the selection indicators
|
// The settings bar is higher in the dom tree than the selection indicators
|
||||||
// as we want to be able to render the settings bar wider than the screen,
|
// as we want to be able to render the settings bar wider than the screen,
|
||||||
|
@ -111,7 +114,7 @@
|
||||||
measured = true
|
measured = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const debouncedUpdate = domDebounce(updatePosition)
|
const debouncedUpdate = Utils.domDebounce(updatePosition)
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
debouncedUpdate()
|
debouncedUpdate()
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
export const domDebounce = (callback, extractParams = x => x) => {
|
|
||||||
let active = false
|
|
||||||
let lastParams
|
|
||||||
return (...params) => {
|
|
||||||
lastParams = extractParams(...params)
|
|
||||||
if (!active) {
|
|
||||||
active = true
|
|
||||||
requestAnimationFrame(() => {
|
|
||||||
callback(lastParams)
|
|
||||||
active = false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
export const isGridEvent = e => {
|
||||||
|
return (
|
||||||
|
e.target
|
||||||
|
.closest?.(".component")
|
||||||
|
?.parentNode.closest(".component")
|
||||||
|
?.childNodes[0]?.classList?.contains("grid") ||
|
||||||
|
e.target.classList.contains("anchor")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const isGridChild = node => {
|
||||||
|
return node
|
||||||
|
?.closest(".component")
|
||||||
|
?.parentNode.closest(".component")
|
||||||
|
?.childNodes[0]?.classList?.contains("grid")
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getGridParentID = node => {
|
||||||
|
return node?.closest(".grid")?.parentNode.dataset.id
|
||||||
|
}
|
Loading…
Reference in New Issue