1
0
Fork 0
mirror of synced 2024-09-20 11:27:56 +12:00

Refactor and tidy up

This commit is contained in:
Andrew Kingston 2024-07-30 16:48:54 +01:00
parent 29ddeab0d4
commit de183d5c78
No known key found for this signature in database
10 changed files with 74 additions and 50 deletions

View file

@ -117,6 +117,9 @@
"width": 400,
"height": 200
},
"grid": {
"fill": true
},
"styles": ["padding", "size", "background", "border", "shadow"],
"settings": [
{
@ -561,6 +564,10 @@
"width": 105,
"height": 32
},
"grid": {
"hAlign": "center",
"vAlign": "center"
},
"settings": [
{
"type": "text",

View file

@ -198,7 +198,9 @@
$: darkMode = !currentTheme?.includes("light")
// Build meta styles and stringify to apply to the wrapper node
$: definitionMetaStyles = getDefinitonMetaStyles(definition)
$: metaStyles = {
...definitionMetaStyles,
...instance._styles?.meta,
...ephemeralStyles,
}
@ -618,6 +620,22 @@
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(() => {
// Register this component instance for external access
if ($appStore.isDevApp) {
@ -661,6 +679,7 @@
class:parent={hasChildren}
class:block={isBlock}
class:error={errorState}
class:fill={definition.grid?.fill}
data-id={id}
data-name={name}
data-icon={icon}

View file

@ -123,4 +123,11 @@
--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));
}
/* Handle grid children which need to fill the outer component wrapper */
.grid :global(> .component.fill > *) {
width: 100%;
height: 100%;
flex: 1 1 0;
}
</style>

View file

@ -13,6 +13,7 @@
import { Utils } from "@budibase/frontend-core"
import { findComponentById } from "utils/components.js"
import { DNDPlaceholderID } from "constants"
import { isGridEvent } from "utils/grid"
const ThrottleRate = 130
@ -25,15 +26,6 @@
// Local flag for whether we are awaiting an async drop event
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
const getDOMNode = id => {
return document.getElementsByClassName(`${id}-dom`)[0]
@ -267,7 +259,7 @@
// Check if we're adding a new component rather than moving one
if (source.newComponentType) {
dropping = true
await builderStore.actions.dropNewComponent(
builderStore.actions.dropNewComponent(
source.newComponentType,
drop.parent,
drop.index

View file

@ -1,7 +1,7 @@
<script>
import { onMount } from "svelte"
import { DNDPlaceholderID } from "constants"
import { domDebounce } from "utils/domDebounce.js"
import { Utils } from "@budibase/frontend-core"
let left, top, height, width
@ -19,7 +19,7 @@
width = bounds.width
}
}
const debouncedUpdate = domDebounce(updatePosition)
const debouncedUpdate = Utils.domDebounce(updatePosition)
onMount(() => {
const interval = setInterval(debouncedUpdate, 100)

View file

@ -2,6 +2,7 @@
import { onMount, onDestroy } from "svelte"
import { builderStore, componentStore } from "stores"
import { Utils, memo } from "@budibase/frontend-core"
import { isGridEvent, getGridParentID } from "utils/grid"
// Enum for device preview type, included in CSS variables
const Devices = {
@ -67,18 +68,6 @@
// Sugar for a combination of both min and max
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
const getDOMNode = id => {
const component = document.getElementsByClassName(id)[0]
@ -172,7 +161,7 @@
// Find grid parent
const domComponent = getDOMNode(id)
const gridId = domComponent?.closest(".grid")?.parentNode.dataset.id
const gridId = getGridParentID(domComponent)
if (!gridId) {
return
}

View file

@ -2,7 +2,7 @@
import { onMount, onDestroy } from "svelte"
import Indicator from "./Indicator.svelte"
import { builderStore, componentStore } from "stores"
import { memo } from "@budibase/frontend-core"
import { memo, Utils } from "@budibase/frontend-core"
import { writable } from "svelte/store"
export let componentId = null
@ -47,12 +47,12 @@
prefix,
allowResizeAnchors,
})
$: $config, updatePosition()
$: $config, debouncedUpdate()
// Update position when component state changes
$: instance = componentStore.actions.getComponentInstance(componentId)
$: componentState = $instance?.state || writable()
$: $componentState, updatePosition()
$: $componentState, debouncedUpdate()
const checkInsideGrid = id => {
const component = document.getElementsByClassName(id)[0]
@ -160,16 +160,17 @@
})
})
}
const debouncedUpdate = Utils.domDebounce(updatePosition)
onMount(() => {
updatePosition()
interval = setInterval(updatePosition, 100)
document.addEventListener("scroll", updatePosition, true)
debouncedUpdate()
interval = setInterval(debouncedUpdate, 100)
document.addEventListener("scroll", debouncedUpdate, true)
})
onDestroy(() => {
clearInterval(interval)
document.removeEventListener("scroll", updatePosition, true)
document.removeEventListener("scroll", v, true)
observers.forEach(o => o.disconnect())
})
</script>

View file

@ -4,7 +4,8 @@
import SettingsColorPicker from "./SettingsColorPicker.svelte"
import SettingsPicker from "./SettingsPicker.svelte"
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 horizontalOffset = 2
@ -49,8 +50,10 @@
return
}
const id = $builderStore.selectedComponentId
const parent = document.getElementsByClassName(id)?.[0]
const element = parent?.children?.[0]
let element = document.getElementsByClassName(id)?.[0]
if (!isGridChild(element)) {
element = element?.children?.[0]
}
// 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,
@ -111,7 +114,7 @@
measured = true
}
}
const debouncedUpdate = domDebounce(updatePosition)
const debouncedUpdate = Utils.domDebounce(updatePosition)
onMount(() => {
debouncedUpdate()

View file

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

View file

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