Large refactor of grid css variable handling to simplify everything
This commit is contained in:
parent
de183d5c78
commit
cb3c667859
|
@ -132,8 +132,8 @@
|
|||
hoverStore.hover(data.id, false)
|
||||
} else if (type === "update-prop") {
|
||||
await componentStore.updateSetting(data.prop, data.value)
|
||||
} else if (type === "update-meta-styles") {
|
||||
await componentStore.updateMetaStyles(data.styles, data.id)
|
||||
} else if (type === "update-styles") {
|
||||
await componentStore.updateStyles(data.styles, data.id)
|
||||
} else if (type === "delete-component" && data.id) {
|
||||
// Legacy type, can be deleted in future
|
||||
confirmDeleteComponent(data.id)
|
||||
|
|
|
@ -64,7 +64,6 @@ export class ComponentStore extends BudiStore {
|
|||
this.moveDown = this.moveDown.bind(this)
|
||||
this.updateStyle = this.updateStyle.bind(this)
|
||||
this.updateStyles = this.updateStyles.bind(this)
|
||||
this.updateMetaStyles = this.updateMetaStyles.bind(this)
|
||||
this.updateCustomStyle = this.updateCustomStyle.bind(this)
|
||||
this.updateConditions = this.updateConditions.bind(this)
|
||||
this.requestEjectBlock = this.requestEjectBlock.bind(this)
|
||||
|
@ -979,16 +978,6 @@ export class ComponentStore extends BudiStore {
|
|||
await this.patch(patchFn, id)
|
||||
}
|
||||
|
||||
async updateMetaStyles(styles, id) {
|
||||
const patchFn = component => {
|
||||
component._styles.meta = {
|
||||
...component._styles.meta,
|
||||
...styles,
|
||||
}
|
||||
}
|
||||
await this.patch(patchFn, id)
|
||||
}
|
||||
|
||||
async updateCustomStyle(style) {
|
||||
await this.patch(component => {
|
||||
component._styles.custom = style
|
||||
|
|
|
@ -118,7 +118,9 @@
|
|||
"height": 200
|
||||
},
|
||||
"grid": {
|
||||
"fill": true
|
||||
"hAlign": "stretch",
|
||||
"vAlign": "stretch",
|
||||
"showControls": false
|
||||
},
|
||||
"styles": ["padding", "size", "background", "border", "shadow"],
|
||||
"settings": [
|
||||
|
@ -2790,6 +2792,10 @@
|
|||
"width": 400,
|
||||
"height": 400
|
||||
},
|
||||
"grid": {
|
||||
"hAlign": "stretch",
|
||||
"vAlign": "stretch"
|
||||
},
|
||||
"settings": [
|
||||
{
|
||||
"type": "select",
|
||||
|
@ -6915,6 +6921,10 @@
|
|||
"width": 400,
|
||||
"height": 400
|
||||
},
|
||||
"grid": {
|
||||
"hAlign": "stretch",
|
||||
"vAlign": "start"
|
||||
},
|
||||
"settings": [
|
||||
{
|
||||
"type": "table",
|
||||
|
@ -7256,6 +7266,11 @@
|
|||
"width": 600,
|
||||
"height": 400
|
||||
},
|
||||
"grid": {
|
||||
"hAlign": "stretch",
|
||||
"vAlign": "stretch",
|
||||
"showControls": false
|
||||
},
|
||||
"settings": [
|
||||
{
|
||||
"type": "dataSource",
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
getActionDependentContextKeys,
|
||||
} from "../utils/buttonActions.js"
|
||||
import { buildStyleString } from "utils/styleable.js"
|
||||
import { getBaseGridVars } from "utils/grid.js"
|
||||
|
||||
export let instance = {}
|
||||
export let isLayout = false
|
||||
|
@ -103,7 +104,7 @@
|
|||
let settingsDefinitionMap
|
||||
let missingRequiredSettings = false
|
||||
|
||||
// Temporary meta styles which can be added in the app preview for things like
|
||||
// Temporary styles which can be added in the app preview for things like
|
||||
// DND. We clear these whenever a new instance is received.
|
||||
let ephemeralStyles
|
||||
|
||||
|
@ -197,14 +198,14 @@
|
|||
$: currentTheme = $context?.device?.theme
|
||||
$: darkMode = !currentTheme?.includes("light")
|
||||
|
||||
// Build meta styles and stringify to apply to the wrapper node
|
||||
$: definitionMetaStyles = getDefinitonMetaStyles(definition)
|
||||
$: metaStyles = {
|
||||
...definitionMetaStyles,
|
||||
...instance._styles?.meta,
|
||||
// Build up full styles and split them into variables and non-variables
|
||||
$: baseStyles = getBaseStyles(definition)
|
||||
$: parsedStyles = parseStyles({
|
||||
...baseStyles,
|
||||
...instance._styles?.normal,
|
||||
...ephemeralStyles,
|
||||
}
|
||||
$: metaCSS = buildStyleString(metaStyles)
|
||||
})
|
||||
$: wrapperCSS = buildStyleString(parsedStyles.variables)
|
||||
|
||||
// Update component context
|
||||
$: store.set({
|
||||
|
@ -212,7 +213,7 @@
|
|||
children: children.length,
|
||||
styles: {
|
||||
...instance._styles,
|
||||
meta: metaStyles,
|
||||
normal: parsedStyles.nonVariables,
|
||||
custom: customCSS,
|
||||
id,
|
||||
empty: emptyState,
|
||||
|
@ -612,7 +613,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
const select = e => {
|
||||
const handleWrapperClick = e => {
|
||||
if (isBlock) {
|
||||
return
|
||||
}
|
||||
|
@ -620,19 +621,21 @@
|
|||
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",
|
||||
// Splits component styles into variables and non-variables
|
||||
const parseStyles = styles => {
|
||||
let variables = {}
|
||||
let nonVariables = {}
|
||||
for (let style of Object.keys(styles || {})) {
|
||||
const group = style.startsWith("--") ? variables : nonVariables
|
||||
group[style] = styles[style]
|
||||
}
|
||||
return { variables, nonVariables }
|
||||
}
|
||||
const getDefinitonMetaStyles = definition => {
|
||||
const gridHAlign = definition.grid?.hAlign || "stretch"
|
||||
const gridVAlign = definition.grid?.vAlign || "center"
|
||||
|
||||
// Generates any required base styles based on the component definition
|
||||
const getBaseStyles = definition => {
|
||||
return {
|
||||
["align-items"]: alignToStyleMap[gridHAlign],
|
||||
["justify-content"]: alignToStyleMap[gridVAlign],
|
||||
...getBaseGridVars(definition),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -684,9 +687,9 @@
|
|||
data-name={name}
|
||||
data-icon={icon}
|
||||
data-parent={$component.id}
|
||||
style={metaCSS}
|
||||
style={wrapperCSS}
|
||||
{draggable}
|
||||
on:click={select}
|
||||
on:click={handleWrapperClick}
|
||||
>
|
||||
{#if errorState}
|
||||
<ComponentErrorState
|
||||
|
|
|
@ -96,16 +96,22 @@
|
|||
.grid :global(> .component) {
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: stretch;
|
||||
|
||||
/* On desktop, use desktop metadata and fall back to mobile */
|
||||
/* Position vars */
|
||||
--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));
|
||||
|
||||
/* Flex vars */
|
||||
--h-align: var(--grid-desktop-h-align, var(--grid-mobile-h-align, stretch));
|
||||
--v-align: var(--grid-desktop-v-align, var(--grid-mobile-v-align, center));
|
||||
--child-flex: var(
|
||||
--grid-desktop-child-flex,
|
||||
var(--grid-mobile-child-flex, 0 0 auto)
|
||||
);
|
||||
|
||||
/* Ensure grid metadata falls within limits */
|
||||
grid-column-start: min(max(1, var(--col-start)), var(--cols)) !important;
|
||||
grid-column-end: min(
|
||||
|
@ -114,20 +120,32 @@
|
|||
) !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;
|
||||
|
||||
/* Flex container styles */
|
||||
flex-direction: column;
|
||||
align-items: var(--h-align);
|
||||
justify-content: var(--v-align);
|
||||
}
|
||||
|
||||
/* On mobile, use mobile metadata and fall back to desktop */
|
||||
.grid.mobile :global(> .component) {
|
||||
/* Position vars */
|
||||
--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));
|
||||
|
||||
/* Flex vars */
|
||||
--h-align: var(--grid-mobile-h-align, var(--grid-desktop-h-align, stretch));
|
||||
--v-align: var(--grid-mobile-v-align, var(--grid-desktop-v-align, center));
|
||||
--child-flex: var(
|
||||
--grid-mobile-child-flex,
|
||||
var(--grid-desktop-child-flex, 0 0 auto)
|
||||
);
|
||||
}
|
||||
|
||||
/* Handle grid children which need to fill the outer component wrapper */
|
||||
.grid :global(> .component.fill > *) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
flex: 1 1 0;
|
||||
.grid :global(> .component > *) {
|
||||
flex: var(--child-flex) !important;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -2,53 +2,20 @@
|
|||
import { onMount, onDestroy } from "svelte"
|
||||
import { builderStore, componentStore } from "stores"
|
||||
import { Utils, memo } from "@budibase/frontend-core"
|
||||
import { isGridEvent, getGridParentID } from "utils/grid"
|
||||
import {
|
||||
isGridEvent,
|
||||
getGridParentID,
|
||||
getGridVar,
|
||||
getDefaultGridVarValue,
|
||||
getOtherDeviceGridVar,
|
||||
} from "utils/grid"
|
||||
|
||||
// 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")
|
||||
},
|
||||
// Grid CSS variables
|
||||
$: vars = {
|
||||
colStart: $getGridVar("col-start"),
|
||||
colEnd: $getGridVar("col-end"),
|
||||
rowStart: $getGridVar("row-start"),
|
||||
rowEnd: $getGridVar("row-end"),
|
||||
}
|
||||
|
||||
let dragInfo
|
||||
|
@ -97,34 +64,34 @@
|
|||
deltaX = minMax(deltaX, 1 - colStart, cols + 1 - colEnd)
|
||||
deltaY = minMax(deltaY, 1 - rowStart, rows + 1 - rowEnd)
|
||||
const newStyles = {
|
||||
[Vars.ColStart]: colStart + deltaX,
|
||||
[Vars.ColEnd]: colEnd + deltaX,
|
||||
[Vars.RowStart]: rowStart + deltaY,
|
||||
[Vars.RowEnd]: rowEnd + deltaY,
|
||||
[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[Vars.ColEnd] = Math.max(colEnd + deltaX, colStart + 1)
|
||||
newStyles[vars.colEnd] = Math.max(colEnd + deltaX, colStart + 1)
|
||||
} else if (side === "left") {
|
||||
newStyles[Vars.ColStart] = Math.min(colStart + deltaX, colEnd - 1)
|
||||
newStyles[vars.colStart] = Math.min(colStart + deltaX, colEnd - 1)
|
||||
} else if (side === "top") {
|
||||
newStyles[Vars.RowStart] = Math.min(rowStart + deltaY, rowEnd - 1)
|
||||
newStyles[vars.rowStart] = Math.min(rowStart + deltaY, rowEnd - 1)
|
||||
} else if (side === "bottom") {
|
||||
newStyles[Vars.RowEnd] = Math.max(rowEnd + deltaY, rowStart + 1)
|
||||
newStyles[vars.rowEnd] = Math.max(rowEnd + deltaY, rowStart + 1)
|
||||
} else if (side === "bottom-right") {
|
||||
newStyles[Vars.ColEnd] = Math.max(colEnd + deltaX, colStart + 1)
|
||||
newStyles[Vars.RowEnd] = 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[Vars.ColStart] = Math.min(colStart + deltaX, colEnd - 1)
|
||||
newStyles[Vars.RowEnd] = 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[Vars.ColEnd] = Math.max(colEnd + deltaX, colStart + 1)
|
||||
newStyles[Vars.RowStart] = 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[Vars.ColStart] = Math.min(colStart + deltaX, colEnd - 1)
|
||||
newStyles[Vars.RowStart] = 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)
|
||||
}
|
||||
|
@ -197,20 +164,21 @@
|
|||
const getCurrent = cssVar => {
|
||||
let style = styles?.getPropertyValue(cssVar)
|
||||
if (!style) {
|
||||
style = styles?.getPropertyValue(getOtherDeviceCSSVar(cssVar))
|
||||
style = styles?.getPropertyValue(getOtherDeviceGridVar(cssVar))
|
||||
}
|
||||
return parseInt(style || getDefaultValue(cssVar))
|
||||
return parseInt(style || getDefaultGridVarValue(cssVar))
|
||||
}
|
||||
dragInfo.grid = {
|
||||
startX: e.clientX,
|
||||
startY: e.clientY,
|
||||
|
||||
// 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),
|
||||
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),
|
||||
}
|
||||
console.log(dragInfo.grid)
|
||||
handleEvent(e)
|
||||
}
|
||||
}
|
||||
|
@ -226,7 +194,7 @@
|
|||
const stopDragging = async () => {
|
||||
// Save changes
|
||||
if ($gridStyles) {
|
||||
await builderStore.actions.updateMetaStyles($gridStyles, dragInfo.id)
|
||||
await builderStore.actions.updateStyles($gridStyles, dragInfo.id)
|
||||
}
|
||||
|
||||
// Reset listener
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
<script>
|
||||
import { Icon } from "@budibase/bbui"
|
||||
import { builderStore, componentStore } from "stores"
|
||||
import { getGridVarValue } from "utils/grid"
|
||||
|
||||
export let style
|
||||
export let value
|
||||
export let icon
|
||||
export let title
|
||||
|
||||
$: currentValue = getGridVarValue($componentStore.selectedComponent, style)
|
||||
$: console.log(style, currentValue)
|
||||
$: active = currentValue === value
|
||||
</script>
|
||||
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<div
|
||||
{title}
|
||||
class:active
|
||||
on:click={() => {
|
||||
builderStore.actions.updateStyles(
|
||||
{ [style]: value },
|
||||
$componentStore.selectedComponent._id
|
||||
)
|
||||
}}
|
||||
>
|
||||
<Icon name={icon} size="S" />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
div {
|
||||
padding: 6px;
|
||||
border-radius: 2px;
|
||||
color: var(--spectrum-global-color-gray-700);
|
||||
display: flex;
|
||||
transition: color 0.13s ease-in-out, background-color 0.13s ease-in-out;
|
||||
}
|
||||
div:hover {
|
||||
background-color: var(--spectrum-global-color-gray-200);
|
||||
cursor: pointer;
|
||||
}
|
||||
.active,
|
||||
.active:hover {
|
||||
background-color: rgba(13, 102, 208, 0.1);
|
||||
color: var(--spectrum-global-color-blue-600);
|
||||
}
|
||||
</style>
|
|
@ -1,11 +1,13 @@
|
|||
<script>
|
||||
import { onMount, onDestroy } from "svelte"
|
||||
import SettingsButton from "./SettingsButton.svelte"
|
||||
import GridStylesButton from "./GridStylesButton.svelte"
|
||||
import SettingsColorPicker from "./SettingsColorPicker.svelte"
|
||||
import SettingsPicker from "./SettingsPicker.svelte"
|
||||
import { builderStore, componentStore, dndIsDragging } from "stores"
|
||||
import { Utils } from "@budibase/frontend-core"
|
||||
import { isGridChild } from "utils/grid"
|
||||
import { findComponentParent } from "utils/components"
|
||||
import { getGridVar } from "utils/grid"
|
||||
|
||||
const verticalOffset = 36
|
||||
const horizontalOffset = 2
|
||||
|
@ -16,7 +18,10 @@
|
|||
let self
|
||||
let measured = false
|
||||
|
||||
// TODO: respect dependsOn keys
|
||||
|
||||
$: id = $builderStore.selectedComponentId
|
||||
$: parent = findComponentParent($builderStore.screen.props, id)
|
||||
$: instance = componentStore.actions.getComponentInstance(id)
|
||||
$: state = $instance?.state
|
||||
$: definition = $componentStore.selectedComponentDefinition
|
||||
|
@ -32,6 +37,11 @@
|
|||
}
|
||||
$: settings = getBarSettings(definition)
|
||||
$: isRoot = id === $builderStore.screen?.props?._id
|
||||
$: insideGrid =
|
||||
parent?._component.endsWith("/container") && parent.layout === "grid"
|
||||
$: showGridStyles = insideGrid && definition?.grid?.showControls !== false
|
||||
$: gridHAlignVar = $getGridVar("h-align")
|
||||
$: gridVAlignVar = $getGridVar("v-align")
|
||||
|
||||
const getBarSettings = definition => {
|
||||
let allSettings = []
|
||||
|
@ -51,7 +61,7 @@
|
|||
}
|
||||
const id = $builderStore.selectedComponentId
|
||||
let element = document.getElementsByClassName(id)?.[0]
|
||||
if (!isGridChild(element)) {
|
||||
if (!insideGrid) {
|
||||
element = element?.children?.[0]
|
||||
}
|
||||
|
||||
|
@ -135,6 +145,58 @@
|
|||
bind:this={self}
|
||||
class:visible={measured}
|
||||
>
|
||||
{#if showGridStyles}
|
||||
<GridStylesButton
|
||||
style={gridHAlignVar}
|
||||
value="start"
|
||||
icon="AlignLeft"
|
||||
title="Align left"
|
||||
/>
|
||||
<GridStylesButton
|
||||
style={gridHAlignVar}
|
||||
value="center"
|
||||
icon="AlignCenter"
|
||||
title="Align center"
|
||||
/>
|
||||
<GridStylesButton
|
||||
style={gridHAlignVar}
|
||||
value="end"
|
||||
icon="AlignRight"
|
||||
title="Align right"
|
||||
/>
|
||||
<GridStylesButton
|
||||
style={gridHAlignVar}
|
||||
value="stretch"
|
||||
icon="MoveLeftRight"
|
||||
title="Stretch horizontally"
|
||||
/>
|
||||
<div class="divider" />
|
||||
<GridStylesButton
|
||||
style={gridVAlignVar}
|
||||
value="start"
|
||||
icon="AlignTop"
|
||||
title="Align top"
|
||||
/>
|
||||
<GridStylesButton
|
||||
style={gridVAlignVar}
|
||||
value="center"
|
||||
icon="AlignMiddle"
|
||||
title="Align middle"
|
||||
/>
|
||||
<GridStylesButton
|
||||
style={gridVAlignVar}
|
||||
value="end"
|
||||
icon="AlignBottom"
|
||||
title="Align bottom"
|
||||
/>
|
||||
<GridStylesButton
|
||||
style={gridVAlignVar}
|
||||
value="stretch"
|
||||
icon="MoveUpDown"
|
||||
title="Stretch vertically"
|
||||
/>
|
||||
<div class="divider" />
|
||||
{/if}
|
||||
{#each settings as setting, idx}
|
||||
{#if setting.type === "select"}
|
||||
{#if setting.barStyle === "buttons"}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
export let title
|
||||
export let rotate = false
|
||||
export let bool = false
|
||||
export let active = false
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
$: currentValue = $componentStore.selectedComponent?.[prop]
|
||||
|
|
|
@ -40,8 +40,8 @@ const createBuilderStore = () => {
|
|||
updateProp: (prop, value) => {
|
||||
eventStore.actions.dispatchEvent("update-prop", { prop, value })
|
||||
},
|
||||
updateMetaStyles: async (styles, id) => {
|
||||
await eventStore.actions.dispatchEvent("update-meta-styles", {
|
||||
updateStyles: async (styles, id) => {
|
||||
await eventStore.actions.dispatchEvent("update-styles", {
|
||||
styles,
|
||||
id,
|
||||
})
|
||||
|
|
|
@ -1,3 +1,51 @@
|
|||
import { builderStore } from "stores"
|
||||
import { derived, get } from "svelte/store"
|
||||
|
||||
/**
|
||||
* We use CSS variables on components to control positioning and layout of
|
||||
* components inside grids.
|
||||
* --grid-[mobile/desktop]-[row/col]-[start-end]: for positioning
|
||||
* --grid-[mobile/desktop]-[h/v]-align: for layout of inner components within
|
||||
* the components grid bounds
|
||||
*
|
||||
* Component definitions define their default layout preference via the
|
||||
* `grid.hAlign` and `grid.vAlign` keys in the manifest.
|
||||
*/
|
||||
|
||||
// Enum for device preview type, included in grid CSS variables
|
||||
const Devices = {
|
||||
Desktop: "desktop",
|
||||
Mobile: "mobile",
|
||||
}
|
||||
|
||||
// Generates the CSS variable for a certain grid param suffix, for the current
|
||||
// device
|
||||
const previewDevice = derived(builderStore, $store => $store.device)
|
||||
export const getGridVar = derived(previewDevice, device => suffix => {
|
||||
const prefix = device === Devices.Mobile ? Devices.Mobile : Devices.Desktop
|
||||
return `--grid-${prefix}-${suffix}`
|
||||
})
|
||||
|
||||
// Generates the CSS variable for a certain grid param suffix, for the other
|
||||
// device variant than the one included in this variable
|
||||
export const getOtherDeviceGridVar = 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
|
||||
export const getDefaultGridVarValue = cssVar => {
|
||||
if (cssVar.includes("align")) {
|
||||
return cssVar.includes("-h-") ? "stretch" : "center"
|
||||
} else {
|
||||
return cssVar.endsWith("-start") ? 1 : 2
|
||||
}
|
||||
}
|
||||
|
||||
// Determines whether a JS event originated from immediately within a grid
|
||||
export const isGridEvent = e => {
|
||||
return (
|
||||
e.target
|
||||
|
@ -8,6 +56,7 @@ export const isGridEvent = e => {
|
|||
)
|
||||
}
|
||||
|
||||
// Determines whether a DOM element is an immediate child of a grid
|
||||
export const isGridChild = node => {
|
||||
return node
|
||||
?.closest(".component")
|
||||
|
@ -15,6 +64,42 @@ export const isGridChild = node => {
|
|||
?.childNodes[0]?.classList?.contains("grid")
|
||||
}
|
||||
|
||||
// Gets the component ID of the closest parent grid
|
||||
export const getGridParentID = node => {
|
||||
return node?.closest(".grid")?.parentNode.dataset.id
|
||||
}
|
||||
|
||||
// Generates the base set of grid CSS vars from a component definition
|
||||
const alignmentToStyleMap = {
|
||||
start: "flex-start",
|
||||
center: "center",
|
||||
end: "flex-end",
|
||||
stretch: "stretch",
|
||||
}
|
||||
export const getBaseGridVars = definition => {
|
||||
const gridHAlign = definition.grid?.hAlign || "stretch"
|
||||
const gridVAlign = definition.grid?.vAlign || "center"
|
||||
const flexStyles = gridVAlign === "stretch" ? "1 1 0" : "0 0 auto"
|
||||
return {
|
||||
["--grid-desktop-h-align"]: alignmentToStyleMap[gridHAlign],
|
||||
["--grid-mobile-h-align"]: alignmentToStyleMap[gridHAlign],
|
||||
["--grid-desktop-v-align"]: alignmentToStyleMap[gridVAlign],
|
||||
["--grid-mobile-v-align"]: alignmentToStyleMap[gridVAlign],
|
||||
["--grid-desktop-child-flex"]: flexStyles,
|
||||
["--grid-mobile-child-flex"]: flexStyles,
|
||||
}
|
||||
}
|
||||
|
||||
// Gets the current value of a certain grid CSS variable for a component
|
||||
export const getGridVarValue = (component, variable) => {
|
||||
// Try the desired variable
|
||||
let val = component?._styles?.normal?.[variable]
|
||||
|
||||
// Otherwise try the other device variables
|
||||
if (!val) {
|
||||
val = component?._styles?.normal?.[getOtherDeviceGridVar(variable)]
|
||||
}
|
||||
|
||||
// Otherwise use the default
|
||||
return val ? val : getDefaultGridVarValue(variable)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue