From 7d4acc936b309453f2e79e3a1f6b6bb7f43d1836 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Tue, 30 Jul 2024 13:50:38 +0100 Subject: [PATCH] Rewrite grid CSS variable handling --- .../app/container/GridContainer.svelte | 40 +++++-- .../components/preview/GridDNDHandler.svelte | 111 +++++++++++++----- 2 files changed, 107 insertions(+), 44 deletions(-) diff --git a/packages/client/src/components/app/container/GridContainer.svelte b/packages/client/src/components/app/container/GridContainer.svelte index 498b19b25b..9734998f79 100644 --- a/packages/client/src/components/app/container/GridContainer.svelte +++ b/packages/client/src/components/app/container/GridContainer.svelte @@ -3,6 +3,7 @@ const component = getContext("component") const { styleable, builderStore } = getContext("sdk") + const context = getContext("context") export let cols = 12 export let rows = 12 @@ -10,6 +11,7 @@ $: cols = cols || 12 $: rows = rows || 12 $: coords = generateCoords(rows, cols) + $: mobile = $context.device.mobile const generateCoords = (rows, cols) => { let grid = [] @@ -24,6 +26,7 @@
.component > *) { + --col-start: var(--grid-mobile-col-start, var(--grid-desktop-col-start, 1)); + --col-end: var(--grid-mobile-col-end, var(--grid-desktop-col-end, 2)); + --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)); + } + .grid { position: relative; height: 400px; diff --git a/packages/client/src/components/preview/GridDNDHandler.svelte b/packages/client/src/components/preview/GridDNDHandler.svelte index 878a8a7feb..bc1b193629 100644 --- a/packages/client/src/components/preview/GridDNDHandler.svelte +++ b/packages/client/src/components/preview/GridDNDHandler.svelte @@ -3,6 +3,53 @@ import { builderStore, componentStore } from "stores" import { Utils, memo } from "@budibase/frontend-core" + // Enum for device preview type, included in CSS variables + const Devices = { + Desktop: "desktop", + Mobile: "mobile", + } + + // Generates the CSS variable for a certain grid param suffix, for the current + // device + const getCSSVar = suffix => { + const device = + $builderStore.previewDevice === Devices.Mobile + ? Devices.Mobile + : Devices.Desktop + return `--grid-${device}-${suffix}` + } + + // Generates the CSS variable for a certain grid param suffix, for the other + // device variant than the one included in this variable + const getOtherDeviceCSSVar = cssVar => { + if (cssVar.includes(Devices.Desktop)) { + return cssVar.replace(Devices.Desktop, Devices.Mobile) + } else { + return cssVar.replace(Devices.Mobile, Devices.Desktop) + } + } + + // Gets the default value for a certain grid CSS variable + const getDefaultValue = cssVar => { + return cssVar.endsWith("-start") ? 1 : 2 + } + + // Enums for our grid CSS variables, for the current device + const Vars = { + get ColStart() { + return getCSSVar("col-start") + }, + get ColEnd() { + return getCSSVar("col-end") + }, + get RowStart() { + return getCSSVar("row-start") + }, + get RowEnd() { + return getCSSVar("row-end") + }, + } + let dragInfo let gridStyles = memo() let id @@ -57,46 +104,38 @@ const rowHeight = height / rows const diffY = mouseY - startY let deltaY = Math.round(diffY / rowHeight) - if (mode === "move") { + deltaX = minMax(deltaX, 1 - colStart, cols + 1 - colEnd) + deltaY = minMax(deltaY, 1 - rowStart, rows + 1 - rowEnd) const newStyles = { - "--grid-row-start": minMax(rowStart + deltaY, 1, rows), - "--grid-row-end": minMax(rowEnd + deltaY, 2, rows + 1), - "--grid-column-start": minMax(colStart + deltaX, 1, cols), - "--grid-column-end": minMax(colEnd + deltaX, 2, cols + 1), + [Vars.ColStart]: colStart + deltaX, + [Vars.ColEnd]: colEnd + deltaX, + [Vars.RowStart]: rowStart + deltaY, + [Vars.RowEnd]: rowEnd + deltaY, } gridStyles.set(newStyles) } else if (mode === "resize") { let newStyles = {} if (side === "right") { - newStyles["--grid-column-end"] = Math.max(colEnd + deltaX, colStart + 1) + newStyles[Vars.ColEnd] = Math.max(colEnd + deltaX, colStart + 1) } else if (side === "left") { - newStyles["--grid-column-start"] = Math.min( - colStart + deltaX, - colEnd - 1 - ) + newStyles[Vars.ColStart] = Math.min(colStart + deltaX, colEnd - 1) } else if (side === "top") { - newStyles["--grid-row-start"] = Math.min(rowStart + deltaY, rowEnd - 1) + newStyles[Vars.RowStart] = Math.min(rowStart + deltaY, rowEnd - 1) } else if (side === "bottom") { - newStyles["--grid-row-end"] = Math.max(rowEnd + deltaY, rowStart + 1) + newStyles[Vars.RowEnd] = Math.max(rowEnd + deltaY, rowStart + 1) } else if (side === "bottom-right") { - newStyles["--grid-column-end"] = Math.max(colEnd + deltaX, colStart + 1) - newStyles["--grid-row-end"] = Math.max(rowEnd + deltaY, rowStart + 1) + newStyles[Vars.ColEnd] = Math.max(colEnd + deltaX, colStart + 1) + newStyles[Vars.RowEnd] = Math.max(rowEnd + deltaY, rowStart + 1) } else if (side === "bottom-left") { - newStyles["--grid-column-start"] = Math.min( - colStart + deltaX, - colEnd - 1 - ) - newStyles["--grid-row-end"] = Math.max(rowEnd + deltaY, rowStart + 1) + newStyles[Vars.ColStart] = Math.min(colStart + deltaX, colEnd - 1) + newStyles[Vars.RowEnd] = Math.max(rowEnd + deltaY, rowStart + 1) } else if (side === "top-right") { - newStyles["--grid-column-end"] = Math.max(colEnd + deltaX, colStart + 1) - newStyles["--grid-row-start"] = Math.min(rowStart + deltaY, rowEnd - 1) + newStyles[Vars.ColEnd] = Math.max(colEnd + deltaX, colStart + 1) + newStyles[Vars.RowStart] = Math.min(rowStart + deltaY, rowEnd - 1) } else if (side === "top-left") { - newStyles["--grid-column-start"] = Math.min( - colStart + deltaX, - colEnd - 1 - ) - newStyles["--grid-row-start"] = Math.min(rowStart + deltaY, rowEnd - 1) + newStyles[Vars.ColStart] = Math.min(colStart + deltaX, colEnd - 1) + newStyles[Vars.RowStart] = Math.min(rowStart + deltaY, rowEnd - 1) } gridStyles.set(newStyles) } @@ -164,14 +203,24 @@ const domNode = getDOMNode(dragInfo.id) const styles = window.getComputedStyle(domNode) if (domGrid) { - const getStyle = x => parseInt(styles?.getPropertyValue(x) || "0") + // Util to get the current grid CSS variable for this device. If unset, + // fall back to using the other device type. + const getCurrent = cssVar => { + let style = styles?.getPropertyValue(cssVar) + if (!style) { + style = styles?.getPropertyValue(getOtherDeviceCSSVar(cssVar)) + } + return parseInt(style || getDefaultValue(cssVar)) + } dragInfo.grid = { startX: e.clientX, startY: e.clientY, - rowStart: minMax(getStyle("--grid-row-start"), 1, gridRows), - rowEnd: minMax(getStyle("--grid-row-end"), 2, gridRows + 1), - colStart: minMax(getStyle("--grid-column-start"), 1, gridCols), - colEnd: minMax(getStyle("--grid-column-end"), 2, gridCols + 1), + + // Ensure things are within limits + rowStart: minMax(getCurrent(Vars.RowStart), 1, gridRows), + rowEnd: minMax(getCurrent(Vars.RowEnd), 2, gridRows + 1), + colStart: minMax(getCurrent(Vars.ColStart), 1, gridCols), + colEnd: minMax(getCurrent(Vars.ColEnd), 2, gridCols + 1), } handleEvent(e) }