Update when grid lines are shown, show sibling borders, add component padding, remove row and column settings
This commit is contained in:
parent
5071f39153
commit
df77aa3f83
|
@ -96,32 +96,6 @@
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
// Add grid layout settings if required
|
|
||||||
if (screen.props.layout === "grid") {
|
|
||||||
settings = settings.concat([
|
|
||||||
{
|
|
||||||
key: "props.cols",
|
|
||||||
label: "Columns",
|
|
||||||
control: Stepper,
|
|
||||||
defaultValue: 24,
|
|
||||||
props: {
|
|
||||||
min: 2,
|
|
||||||
max: 50,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "props.rows",
|
|
||||||
label: "Rows",
|
|
||||||
control: Stepper,
|
|
||||||
defaultValue: 24,
|
|
||||||
props: {
|
|
||||||
min: 2,
|
|
||||||
max: 50,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
])
|
|
||||||
}
|
|
||||||
|
|
||||||
return settings
|
return settings
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -145,32 +145,6 @@
|
||||||
],
|
],
|
||||||
"defaultValue": "flex"
|
"defaultValue": "flex"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"type": "number",
|
|
||||||
"label": "Columns",
|
|
||||||
"key": "cols",
|
|
||||||
"placeholder": 12,
|
|
||||||
"defaultValue": 12,
|
|
||||||
"min": 2,
|
|
||||||
"max": 50,
|
|
||||||
"dependsOn": {
|
|
||||||
"setting": "layout",
|
|
||||||
"value": "grid"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "number",
|
|
||||||
"label": "Rows",
|
|
||||||
"key": "rows",
|
|
||||||
"placeholder": 12,
|
|
||||||
"defaultValue": 12,
|
|
||||||
"min": 2,
|
|
||||||
"max": 50,
|
|
||||||
"dependsOn": {
|
|
||||||
"setting": "layout",
|
|
||||||
"value": "grid"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"type": "select",
|
"type": "select",
|
||||||
"label": "Direction",
|
"label": "Direction",
|
||||||
|
|
|
@ -480,10 +480,10 @@
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 32px;
|
padding: 32px;
|
||||||
}
|
}
|
||||||
.main:has(.screenslot-dom > .component > .grid) {
|
/* .main:has(.screenslot-dom > .component > .grid) {
|
||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
padding-bottom: 0;
|
padding-bottom: 0;
|
||||||
}
|
}*/
|
||||||
.layout--none .main {
|
.layout--none .main {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,19 +2,18 @@
|
||||||
import { getContext } from "svelte"
|
import { getContext } from "svelte"
|
||||||
|
|
||||||
const component = getContext("component")
|
const component = getContext("component")
|
||||||
const { styleable, builderStore } = getContext("sdk")
|
const { styleable } = getContext("sdk")
|
||||||
const context = getContext("context")
|
const context = getContext("context")
|
||||||
|
|
||||||
export let cols = 12
|
const cols = 12
|
||||||
export let rows = 12
|
const rowHeight = 24
|
||||||
|
|
||||||
let width
|
let width
|
||||||
let height
|
let height
|
||||||
|
|
||||||
$: cols = cols || 12
|
|
||||||
$: rows = rows || 12
|
|
||||||
$: mobile = $context.device.mobile
|
$: mobile = $context.device.mobile
|
||||||
$: empty = $component.empty
|
$: empty = $component.empty
|
||||||
|
$: rows = Math.max(1, Math.floor(height / rowHeight))
|
||||||
$: colSize = width / cols
|
$: colSize = width / cols
|
||||||
$: rowSize = height / rows
|
$: rowSize = height / rows
|
||||||
</script>
|
</script>
|
||||||
|
@ -22,7 +21,6 @@
|
||||||
<div
|
<div
|
||||||
class="grid"
|
class="grid"
|
||||||
class:mobile
|
class:mobile
|
||||||
class:builder={$builderStore.inBuilder}
|
|
||||||
bind:clientWidth={width}
|
bind:clientWidth={width}
|
||||||
bind:clientHeight={height}
|
bind:clientHeight={height}
|
||||||
use:styleable={{
|
use:styleable={{
|
||||||
|
@ -39,13 +37,11 @@
|
||||||
data-rows={rows}
|
data-rows={rows}
|
||||||
data-cols={cols}
|
data-cols={cols}
|
||||||
>
|
>
|
||||||
{#if $builderStore.inBuilder}
|
<div class="underlay">
|
||||||
<div class="underlay">
|
{#each { length: cols * rows } as _}
|
||||||
{#each { length: cols * rows } as _}
|
<div class="placeholder" />
|
||||||
<div class="placeholder" />
|
{/each}
|
||||||
{/each}
|
</div>
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<!-- Only render the slot if not empty, as we don't want the placeholder -->
|
<!-- Only render the slot if not empty, as we don't want the placeholder -->
|
||||||
{#if !empty}
|
{#if !empty}
|
||||||
|
@ -57,32 +53,53 @@
|
||||||
.grid {
|
.grid {
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 400px;
|
height: 400px;
|
||||||
gap: 0;
|
--spacing: 10;
|
||||||
}
|
|
||||||
.grid.builder {
|
|
||||||
background: var(--spectrum-alias-background-color-secondary);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.grid,
|
.grid,
|
||||||
.underlay {
|
.underlay {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-rows: repeat(var(--rows), 1fr);
|
grid-template-rows: repeat(var(--rows), 1fr);
|
||||||
grid-template-columns: repeat(var(--cols), 1fr);
|
grid-template-columns: repeat(var(--cols), 1fr);
|
||||||
|
gap: 0;
|
||||||
}
|
}
|
||||||
.underlay {
|
.underlay {
|
||||||
|
display: none;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
border: 1px solid var(--spectrum-global-color-gray-900);
|
border-top: 1px solid var(--spectrum-global-color-gray-900);
|
||||||
opacity: 0.07;
|
border-left: 1px solid var(--spectrum-global-color-gray-900);
|
||||||
|
opacity: 0.1;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
.underlay {
|
.underlay {
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
}
|
}
|
||||||
.placeholder {
|
.placeholder {
|
||||||
border: 1px solid var(--spectrum-global-color-gray-900);
|
border-bottom: 1px solid var(--spectrum-global-color-gray-900);
|
||||||
|
border-right: 1px solid var(--spectrum-global-color-gray-900);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Highlight grid lines when resizing children */
|
||||||
|
:global(.grid.highlight > .underlay) {
|
||||||
|
display: grid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Highlight sibling borders when resizing childern */
|
||||||
|
:global(.grid.highlight > .component:not(.dragging):after) {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
border: 1px solid var(--spectrum-global-color-static-blue-200);
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 1;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ensure all top level children have grid styles applied */
|
/* Ensure all top level children have grid styles applied */
|
||||||
|
@ -90,6 +107,9 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
pointer-events: all;
|
pointer-events: all;
|
||||||
|
position: relative;
|
||||||
|
padding: 5px;
|
||||||
|
margin: 5px;
|
||||||
|
|
||||||
/* On desktop, use desktop metadata and fall back to mobile */
|
/* On desktop, use desktop metadata and fall back to mobile */
|
||||||
/* Position vars */
|
/* Position vars */
|
||||||
|
@ -98,7 +118,12 @@
|
||||||
--grid-desktop-col-end,
|
--grid-desktop-col-end,
|
||||||
var(
|
var(
|
||||||
--grid-mobile-col-end,
|
--grid-mobile-col-end,
|
||||||
round(up, calc(var(--default-width) / var(--col-size) + 1))
|
round(
|
||||||
|
up,
|
||||||
|
calc(
|
||||||
|
(var(--spacing) * 2 + var(--default-width)) / var(--col-size) + 1
|
||||||
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
--row-start: var(--grid-desktop-row-start, var(--grid-mobile-row-start, 1));
|
--row-start: var(--grid-desktop-row-start, var(--grid-mobile-row-start, 1));
|
||||||
|
@ -106,7 +131,12 @@
|
||||||
--grid-desktop-row-end,
|
--grid-desktop-row-end,
|
||||||
var(
|
var(
|
||||||
--grid-mobile-row-end,
|
--grid-mobile-row-end,
|
||||||
round(up, calc(var(--default-height) / var(--row-size) + 1))
|
round(
|
||||||
|
up,
|
||||||
|
calc(
|
||||||
|
(var(--spacing) * 2 + var(--default-height)) / var(--row-size) + 1
|
||||||
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -137,7 +167,12 @@
|
||||||
--grid-mobile-col-end,
|
--grid-mobile-col-end,
|
||||||
var(
|
var(
|
||||||
--grid-desktop-col-end,
|
--grid-desktop-col-end,
|
||||||
round(up, calc(var(--default-width) / var(--col-size) + 1))
|
round(
|
||||||
|
up,
|
||||||
|
calc(
|
||||||
|
(var(--spacing) * 2 + var(--default-width)) / var(--col-size) + 1
|
||||||
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
--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));
|
||||||
|
@ -145,7 +180,12 @@
|
||||||
--grid-mobile-row-end,
|
--grid-mobile-row-end,
|
||||||
var(
|
var(
|
||||||
--grid-desktop-row-end,
|
--grid-desktop-row-end,
|
||||||
round(up, calc(var(--default-height) / var(--row-size) + 1))
|
round(
|
||||||
|
up,
|
||||||
|
calc(
|
||||||
|
(var(--spacing) * 2 + var(--default-height)) / var(--row-size) + 1
|
||||||
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
import { Utils, memo } from "@budibase/frontend-core"
|
import { Utils, memo } from "@budibase/frontend-core"
|
||||||
import {
|
import {
|
||||||
isGridEvent,
|
isGridEvent,
|
||||||
getGridParentID,
|
getGridParent,
|
||||||
GridParams,
|
GridParams,
|
||||||
getGridVar,
|
getGridVar,
|
||||||
} from "utils/grid"
|
} from "utils/grid"
|
||||||
|
@ -62,6 +62,9 @@
|
||||||
const { startX, startY, rowStart, rowEnd, colStart, colEnd } = grid
|
const { startX, startY, rowStart, rowEnd, colStart, colEnd } = grid
|
||||||
|
|
||||||
const domGrid = getDOMNode(gridId)
|
const domGrid = getDOMNode(gridId)
|
||||||
|
if (!domGrid) {
|
||||||
|
return
|
||||||
|
}
|
||||||
const cols = parseInt(domGrid.dataset.cols)
|
const cols = parseInt(domGrid.dataset.cols)
|
||||||
const rows = parseInt(domGrid.dataset.rows)
|
const rows = parseInt(domGrid.dataset.rows)
|
||||||
const { width, height } = domGrid.getBoundingClientRect()
|
const { width, height } = domGrid.getBoundingClientRect()
|
||||||
|
@ -107,7 +110,7 @@
|
||||||
}
|
}
|
||||||
gridStyles.set(newStyles)
|
gridStyles.set(newStyles)
|
||||||
}
|
}
|
||||||
}, 100)
|
}, 10)
|
||||||
|
|
||||||
const handleEvent = e => {
|
const handleEvent = e => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
@ -140,16 +143,20 @@
|
||||||
|
|
||||||
// Find grid parent
|
// Find grid parent
|
||||||
const domComponent = getDOMNode(id)
|
const domComponent = getDOMNode(id)
|
||||||
const gridId = getGridParentID(domComponent)
|
const domGrid = getGridParent(domComponent)
|
||||||
if (!gridId) {
|
if (!domGrid) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Apply active class to grid
|
||||||
|
domComponent.parentNode.classList.add("dragging")
|
||||||
|
domGrid.classList.add("highlight")
|
||||||
|
|
||||||
// Update state
|
// Update state
|
||||||
dragInfo = {
|
dragInfo = {
|
||||||
domTarget: e.target,
|
domTarget: e.target,
|
||||||
id,
|
id,
|
||||||
gridId,
|
gridId: domGrid.parentNode.dataset.id,
|
||||||
mode,
|
mode,
|
||||||
side,
|
side,
|
||||||
}
|
}
|
||||||
|
@ -168,22 +175,23 @@
|
||||||
const { id, gridId } = dragInfo
|
const { id, gridId } = dragInfo
|
||||||
const domComponent = getDOMNode(id)
|
const domComponent = getDOMNode(id)
|
||||||
const domGrid = getDOMNode(gridId)
|
const domGrid = getDOMNode(gridId)
|
||||||
|
if (!domComponent || !domGrid) {
|
||||||
|
return
|
||||||
|
}
|
||||||
const gridCols = parseInt(domGrid.dataset.cols)
|
const gridCols = parseInt(domGrid.dataset.cols)
|
||||||
const gridRows = parseInt(domGrid.dataset.rows)
|
const gridRows = parseInt(domGrid.dataset.rows)
|
||||||
const styles = getComputedStyle(domComponent.parentNode)
|
const styles = getComputedStyle(domComponent.parentNode)
|
||||||
if (domGrid) {
|
dragInfo.grid = {
|
||||||
dragInfo.grid = {
|
startX: e.clientX,
|
||||||
startX: e.clientX,
|
startY: e.clientY,
|
||||||
startY: e.clientY,
|
|
||||||
|
|
||||||
// Ensure things are within limits
|
// Ensure things are within limits
|
||||||
rowStart: minMax(styles["grid-row-start"], 1, gridRows),
|
rowStart: minMax(styles["grid-row-start"], 1, gridRows),
|
||||||
rowEnd: minMax(styles["grid-row-end"], 2, gridRows + 1),
|
rowEnd: minMax(styles["grid-row-end"], 2, gridRows + 1),
|
||||||
colStart: minMax(styles["grid-column-start"], 1, gridCols),
|
colStart: minMax(styles["grid-column-start"], 1, gridCols),
|
||||||
colEnd: minMax(styles["grid-column-end"], 2, gridCols + 1),
|
colEnd: minMax(styles["grid-column-end"], 2, gridCols + 1),
|
||||||
}
|
|
||||||
handleEvent(e)
|
|
||||||
}
|
}
|
||||||
|
handleEvent(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
const onDragOver = e => {
|
const onDragOver = e => {
|
||||||
|
@ -195,15 +203,26 @@
|
||||||
|
|
||||||
// Callback when drag stops (whether dropped or not)
|
// Callback when drag stops (whether dropped or not)
|
||||||
const stopDragging = async () => {
|
const stopDragging = async () => {
|
||||||
|
if (!dragInfo) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const { id, gridId, domTarget } = dragInfo
|
||||||
|
|
||||||
// Save changes
|
// Save changes
|
||||||
if ($gridStyles) {
|
if ($gridStyles) {
|
||||||
await builderStore.actions.updateStyles($gridStyles, dragInfo.id)
|
await builderStore.actions.updateStyles($gridStyles, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset listener
|
// Reset DOM
|
||||||
if (dragInfo?.domTarget) {
|
const domComponent = getDOMNode(id)
|
||||||
dragInfo.domTarget.removeEventListener("dragend", stopDragging)
|
if (domComponent) {
|
||||||
|
domComponent.parentNode.classList.remove("dragging")
|
||||||
}
|
}
|
||||||
|
const domGrid = getDOMNode(gridId)
|
||||||
|
if (domGrid) {
|
||||||
|
domGrid.classList.remove("highlight")
|
||||||
|
}
|
||||||
|
domTarget.removeEventListener("dragend", stopDragging)
|
||||||
|
|
||||||
// Reset state
|
// Reset state
|
||||||
dragInfo = null
|
dragInfo = null
|
||||||
|
|
|
@ -60,8 +60,8 @@ export const isGridChild = node => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets the component ID of the closest parent grid
|
// Gets the component ID of the closest parent grid
|
||||||
export const getGridParentID = node => {
|
export const getGridParent = node => {
|
||||||
return node?.parentNode?.closest(".grid")?.parentNode.dataset.id
|
return node?.parentNode?.closest(".grid")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Svelte action to apply required class names and styles to our component
|
// Svelte action to apply required class names and styles to our component
|
||||||
|
|
Loading…
Reference in New Issue