diff --git a/packages/builder/src/components/design/AppPreview/iframeTemplate.html b/packages/builder/src/components/design/AppPreview/iframeTemplate.html
index 49df3b5c0b..166a978d01 100644
--- a/packages/builder/src/components/design/AppPreview/iframeTemplate.html
+++ b/packages/builder/src/components/design/AppPreview/iframeTemplate.html
@@ -11,9 +11,6 @@
*, *:before, *:after {
box-sizing: border-box;
}
- * {
- pointer-events: none;
- }
{#if constructor && componentProps}
-
- {#if children.length}
- {#each children as child (getChildKey(child._id))}
-
- {/each}
- {/if}
-
+ {#key propsHash}
+
+ {#if children.length}
+ {#each children as child (child._id)}
+
+ {/each}
+ {/if}
+
+ {/key}
{/if}
diff --git a/packages/client/src/components/Router.svelte b/packages/client/src/components/Router.svelte
index 5477d02f86..efa0e321aa 100644
--- a/packages/client/src/components/Router.svelte
+++ b/packages/client/src/components/Router.svelte
@@ -7,9 +7,6 @@
const { styleable } = getContext("sdk")
const component = getContext("component")
- // Set context flag so components know that we're now inside the screenslot
- setContext("screenslot", true)
-
// Only wrap this as an array to take advantage of svelte keying,
// to ensure the svelte-spa-router is fully remounted when route config
// changes
diff --git a/packages/client/src/utils/hash.js b/packages/client/src/utils/hash.js
new file mode 100644
index 0000000000..2c42007e43
--- /dev/null
+++ b/packages/client/src/utils/hash.js
@@ -0,0 +1,12 @@
+export const hashString = str => {
+ if (!str) {
+ return 0
+ }
+ let hash = 0
+ for (let i = 0; i < str.length; i++) {
+ let char = str.charCodeAt(i)
+ hash = (hash << 5) - hash + char
+ hash = hash & hash // Convert to 32bit integer
+ }
+ return hash
+}
diff --git a/packages/client/src/utils/styleable.js b/packages/client/src/utils/styleable.js
index 665a3dc92d..6cc387058a 100644
--- a/packages/client/src/utils/styleable.js
+++ b/packages/client/src/utils/styleable.js
@@ -1,9 +1,6 @@
import { get } from "svelte/store"
import { builderStore } from "../store"
-const selectedComponentWidth = 2
-const selectedComponentColor = "#4285f4"
-
/**
* Helper to build a CSS string from a style object.
*/
@@ -23,24 +20,14 @@ const buildStyleString = (styleObject, customStyles) => {
* events for any selectable components (overriding the blanket ban on pointer
* events in the iframe HTML).
*/
-const addBuilderPreviewStyles = (styleString, componentId, selectable) => {
- let str = styleString
-
- // Apply extra styles if we're in the builder preview
- const state = get(builderStore)
- if (state.inBuilder) {
- // Allow pointer events and always enable cursor
- if (selectable) {
- str += ";pointer-events: all !important; cursor: pointer !important;"
- }
-
- // Highlighted selected element
- if (componentId === state.selectedComponentId) {
- str += `;border: ${selectedComponentWidth}px solid ${selectedComponentColor} !important;`
- }
+const addBuilderPreviewStyles = (node, styleString, componentId) => {
+ if (componentId === get(builderStore).selectedComponentId) {
+ const style = window.getComputedStyle(node)
+ const property = style?.display === "table-row" ? "outline" : "border"
+ return styleString + `;${property}: 2px solid #4285f4 !important;`
+ } else {
+ return styleString
}
-
- return str
}
/**
@@ -52,17 +39,9 @@ export const styleable = (node, styles = {}) => {
let applyHoverStyles
let selectComponent
- // Kill JS even bubbling
- const blockEvent = event => {
- event.preventDefault()
- event.stopPropagation()
- return false
- }
-
// Creates event listeners and applies initial styles
const setupStyles = (newStyles = {}) => {
const componentId = newStyles.id
- const selectable = !!newStyles.allowSelection
const customStyles = newStyles.custom || ""
const normalStyles = newStyles.normal || {}
const hoverStyles = {
@@ -70,10 +49,9 @@ export const styleable = (node, styles = {}) => {
...(newStyles.hover || {}),
}
- // Applies a style string to a DOM node, enriching it for the builder
- // preview
+ // Applies a style string to a DOM node
const applyStyles = styleString => {
- node.style = addBuilderPreviewStyles(styleString, componentId, selectable)
+ node.style = addBuilderPreviewStyles(node, styleString, componentId)
node.dataset.componentId = componentId
}
@@ -91,7 +69,9 @@ export const styleable = (node, styles = {}) => {
// builder preview
selectComponent = event => {
builderStore.actions.selectComponent(componentId)
- return blockEvent(event)
+ event.preventDefault()
+ event.stopPropagation()
+ return false
}
// Add listeners to toggle hover styles
@@ -101,10 +81,6 @@ export const styleable = (node, styles = {}) => {
// Add builder preview click listener
if (get(builderStore).inBuilder) {
node.addEventListener("click", selectComponent, false)
-
- // Kill other interaction events
- node.addEventListener("mousedown", blockEvent)
- node.addEventListener("mouseup", blockEvent)
}
// Apply initial normal styles
@@ -119,8 +95,6 @@ export const styleable = (node, styles = {}) => {
// Remove builder preview click listener
if (get(builderStore).inBuilder) {
node.removeEventListener("click", selectComponent)
- node.removeEventListener("mousedown", blockEvent)
- node.removeEventListener("mouseup", blockEvent)
}
}
diff --git a/packages/standard-components/src/Login.svelte b/packages/standard-components/src/Login.svelte
index 8a4af82320..1502b5c583 100644
--- a/packages/standard-components/src/Login.svelte
+++ b/packages/standard-components/src/Login.svelte
@@ -1,7 +1,7 @@
diff --git a/packages/standard-components/src/forms/OptionsField.svelte b/packages/standard-components/src/forms/OptionsField.svelte
index 2796356027..77d48867f6 100644
--- a/packages/standard-components/src/forms/OptionsField.svelte
+++ b/packages/standard-components/src/forms/OptionsField.svelte
@@ -92,16 +92,4 @@
{/each}
- {#if $fieldState.error}
-
{$fieldState.error}
- {/if}
-
-
diff --git a/packages/standard-components/src/forms/SpectrumField.svelte b/packages/standard-components/src/forms/SpectrumField.svelte
index 84f1a22ccb..4acda6e921 100644
--- a/packages/standard-components/src/forms/SpectrumField.svelte
+++ b/packages/standard-components/src/forms/SpectrumField.svelte
@@ -10,7 +10,7 @@
const component = getContext("component")
const { labelPosition, formApi } = formContext || {}
const formField = formApi?.registerField(field) ?? {}
- const { fieldId } = formField
+ const { fieldId, fieldState } = formField
$: labelPositionClass =
labelPosition === "top" ? "" : `spectrum-FieldLabel--${labelPosition}`
@@ -31,6 +31,20 @@
{/if}
{/if}
+
+
diff --git a/packages/standard-components/src/forms/StringField.svelte b/packages/standard-components/src/forms/StringField.svelte
index f75a5b1b6f..43ae0c1c13 100644
--- a/packages/standard-components/src/forms/StringField.svelte
+++ b/packages/standard-components/src/forms/StringField.svelte
@@ -1,7 +1,5 @@
-
-
+
+
{#if !$fieldState.valid}
+ class="spectrum-Textfield-input" />
- {#if numeric}
-
-
-
-
- {/if}
- {#if $fieldState.error}
-
{$fieldState.error}
- {/if}
-
-