From 29ddeab0d428aded3a56d178a90758553f38d567 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Tue, 30 Jul 2024 15:20:59 +0100 Subject: [PATCH] Update grid layout to include nested flex wrappers for more layout control --- .../[screenId]/_components/AppPreview.svelte | 4 +- .../builder/src/stores/builder/components.js | 11 +++ .../client/src/components/Component.svelte | 30 ++++-- .../app/container/FlexContainer.svelte | 6 +- .../app/container/GridContainer.svelte | 93 ++++++++++--------- .../components/preview/GridDNDHandler.svelte | 4 +- .../components/preview/IndicatorSet.svelte | 5 +- packages/client/src/stores/builder.js | 7 +- packages/client/src/utils/styleable.js | 2 +- 9 files changed, 99 insertions(+), 63 deletions(-) diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/AppPreview.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/AppPreview.svelte index 0ce9e096f2..94a303ead4 100644 --- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/AppPreview.svelte +++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/AppPreview.svelte @@ -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-styles") { - await componentStore.updateStyles(data.styles, data.id) + } else if (type === "update-meta-styles") { + await componentStore.updateMetaStyles(data.styles, data.id) } else if (type === "delete-component" && data.id) { // Legacy type, can be deleted in future confirmDeleteComponent(data.id) diff --git a/packages/builder/src/stores/builder/components.js b/packages/builder/src/stores/builder/components.js index c281c73dfe..a35169a646 100644 --- a/packages/builder/src/stores/builder/components.js +++ b/packages/builder/src/stores/builder/components.js @@ -64,6 +64,7 @@ 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) @@ -978,6 +979,16 @@ 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 diff --git a/packages/client/src/components/Component.svelte b/packages/client/src/components/Component.svelte index 8eacbdf041..eaab3c56a9 100644 --- a/packages/client/src/components/Component.svelte +++ b/packages/client/src/components/Component.svelte @@ -39,6 +39,7 @@ getActionContextKey, getActionDependentContextKeys, } from "../utils/buttonActions.js" + import { buildStyleString } from "utils/styleable.js" export let instance = {} export let isLayout = false @@ -102,8 +103,8 @@ let settingsDefinitionMap let missingRequiredSettings = false - // Temporary styles which can be added in the app preview for things like DND. - // We clear these whenever a new instance is received. + // Temporary meta styles which can be added in the app preview for things like + // DND. We clear these whenever a new instance is received. let ephemeralStyles // Single string of all HBS blocks, used to check if we use a certain binding @@ -196,16 +197,20 @@ $: currentTheme = $context?.device?.theme $: darkMode = !currentTheme?.includes("light") + // Build meta styles and stringify to apply to the wrapper node + $: metaStyles = { + ...instance._styles?.meta, + ...ephemeralStyles, + } + $: metaCSS = buildStyleString(metaStyles) + // Update component context $: store.set({ id, children: children.length, styles: { ...instance._styles, - normal: { - ...instance._styles?.normal, - ...ephemeralStyles, - }, + meta: metaStyles, custom: customCSS, id, empty: emptyState, @@ -605,6 +610,14 @@ } } + const select = e => { + if (isBlock) { + return + } + e.stopPropagation() + builderStore.actions.selectComponent(id) + } + onMount(() => { // Register this component instance for external access if ($appStore.isDevApp) { @@ -635,6 +648,8 @@ {#if constructor && initialSettings && (visible || inSelectedPath) && !builderHidden} + +
{#if errorState} diff --git a/packages/client/src/components/preview/GridDNDHandler.svelte b/packages/client/src/components/preview/GridDNDHandler.svelte index bc1b193629..1a9a54f1f1 100644 --- a/packages/client/src/components/preview/GridDNDHandler.svelte +++ b/packages/client/src/components/preview/GridDNDHandler.svelte @@ -200,7 +200,7 @@ const domGrid = getDOMNode(dragInfo.gridId) const gridCols = parseInt(domGrid.dataset.cols) const gridRows = parseInt(domGrid.dataset.rows) - const domNode = getDOMNode(dragInfo.id) + const domNode = getDOMNode(dragInfo.id)?.parentNode const styles = window.getComputedStyle(domNode) if (domGrid) { // Util to get the current grid CSS variable for this device. If unset, @@ -237,7 +237,7 @@ const stopDragging = async () => { // Save changes if ($gridStyles) { - await builderStore.actions.updateStyles($gridStyles, dragInfo.id) + await builderStore.actions.updateMetaStyles($gridStyles, dragInfo.id) } // Reset listener diff --git a/packages/client/src/components/preview/IndicatorSet.svelte b/packages/client/src/components/preview/IndicatorSet.svelte index aeeb32be86..f894b92fb9 100644 --- a/packages/client/src/components/preview/IndicatorSet.svelte +++ b/packages/client/src/components/preview/IndicatorSet.svelte @@ -124,9 +124,8 @@ // Extract valid children // Sanity limit of 100 active indicators - const children = Array.from( - document.getElementsByClassName(`${componentId}-dom`) - ) + const className = nextState.insideGrid ? componentId : `${componentId}-dom` + const children = Array.from(document.getElementsByClassName(className)) .filter(x => x != null) .slice(0, 100) diff --git a/packages/client/src/stores/builder.js b/packages/client/src/stores/builder.js index 5440fc3a79..6e82ecbe02 100644 --- a/packages/client/src/stores/builder.js +++ b/packages/client/src/stores/builder.js @@ -40,8 +40,11 @@ const createBuilderStore = () => { updateProp: (prop, value) => { eventStore.actions.dispatchEvent("update-prop", { prop, value }) }, - updateStyles: async (styles, id) => { - await eventStore.actions.dispatchEvent("update-styles", { styles, id }) + updateMetaStyles: async (styles, id) => { + await eventStore.actions.dispatchEvent("update-meta-styles", { + styles, + id, + }) }, keyDown: (key, ctrlKey) => { eventStore.actions.dispatchEvent("key-down", { key, ctrlKey }) diff --git a/packages/client/src/utils/styleable.js b/packages/client/src/utils/styleable.js index 3fccae0be5..dc6e8f5e26 100644 --- a/packages/client/src/utils/styleable.js +++ b/packages/client/src/utils/styleable.js @@ -3,7 +3,7 @@ import { builderStore } from "stores" /** * Helper to build a CSS string from a style object. */ -const buildStyleString = (styleObject, customStyles) => { +export const buildStyleString = (styleObject, customStyles) => { let str = "" Object.entries(styleObject || {}).forEach(([style, value]) => { if (style && value != null) {