Rewrite grid CSS variable handling

This commit is contained in:
Andrew Kingston 2024-07-30 13:50:38 +01:00
parent f91cc26fe1
commit 7d4acc936b
No known key found for this signature in database
2 changed files with 107 additions and 44 deletions

View File

@ -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 @@
<div
class="grid"
class:mobile
use:styleable={{
...$component.styles,
normal: {
@ -61,22 +64,33 @@
overflow: hidden;
width: auto;
height: auto;
grid-column-start: min(
max(1, var(--grid-column-start)),
var(--cols)
) !important;
grid-column-end: min(
max(2, var(--grid-column-end)),
calc(var(--cols) + 1)
) !important;
grid-row-start: min(max(1, var(--grid-row-start)), var(--rows)) !important;
grid-row-end: min(
max(2, var(--grid-row-end)),
calc(var(--rows) + 1)
) !important;
max-height: 100%;
max-width: 100%;
/* On desktop, use desktop metadata and fall back to mobile */
--col-start: var(--grid-desktop-col-start, var(--grid-mobile-col-start, 1));
--col-end: var(--grid-desktop-col-end, var(--grid-mobile-col-end, 2));
--row-start: var(--grid-desktop-row-start, var(--grid-mobile-row-start, 1));
--row-end: var(--grid-desktop-row-end, var(--grid-mobile-row-end, 2));
/* Ensure grid metadata falls within limits */
grid-column-start: min(max(1, var(--col-start)), var(--cols)) !important;
grid-column-end: min(
max(2, var(--col-end)),
calc(var(--cols) + 1)
) !important;
grid-row-start: min(max(1, var(--row-start)), var(--rows)) !important;
grid-row-end: min(max(2, var(--row-end)), calc(var(--rows) + 1)) !important;
}
/* On mobile, use mobile metadata and fall back to desktop */
:global(.grid.mobile > .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;

View File

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