Only save textContent of editable fields to fix HTML being inserted, and fully remount component when toggling editing to fix chrome issues

This commit is contained in:
Andrew Kingston 2022-03-30 09:32:19 +01:00
parent f8f8d3c9cb
commit 444072ecac
6 changed files with 75 additions and 70 deletions

View File

@ -2529,7 +2529,6 @@
"name": "Embedded Map",
"icon": "Location",
"styles": ["size"],
"editable": true,
"draggable": false,
"illegalChildren": ["section"],
"settings": [
@ -3631,7 +3630,6 @@
"name": "Markdown Viewer",
"icon": "TaskList",
"styles": ["size"],
"editable": true,
"settings": [
{
"type": "text",

View File

@ -22,41 +22,44 @@
$: componentText = getComponentText(text, $builderStore, $component)
const getComponentText = (text, builderState, componentState) => {
if (!builderState.inBuilder || componentState.editing) {
if (componentState.editing) {
return text || " "
}
return text || componentState.name || "Placeholder text"
}
const updateText = e => {
builderStore.actions.updateProp("text", e.target.textContent.trim())
builderStore.actions.updateProp("text", e.target.textContent)
}
</script>
<button
class={`spectrum-Button spectrum-Button--size${size} spectrum-Button--${type}`}
class:spectrum-Button--quiet={quiet}
{disabled}
use:styleable={$component.styles}
on:click={onClick}
contenteditable={$component.editing && !icon}
on:blur={$component.editing ? updateText : null}
bind:this={node}
class:active
>
{#if icon}
<svg
class:hasText={componentText?.length > 0}
class="spectrum-Icon spectrum-Icon--size{size.toUpperCase()}"
focusable="false"
aria-hidden="true"
aria-label={icon}
>
<use xlink:href="#spectrum-icon-18-{icon}" />
</svg>
{/if}
{componentText}
</button>
{#key $component.editing}
<button
class={`spectrum-Button spectrum-Button--size${size} spectrum-Button--${type}`}
class:spectrum-Button--quiet={quiet}
class:editing={$component.editing}
{disabled}
use:styleable={$component.styles}
on:click={onClick}
contenteditable={$component.editing && !icon}
on:blur={$component.editing ? updateText : null}
bind:this={node}
class:active
>
{#if icon}
<svg
class:hasText={componentText?.length > 0}
class="spectrum-Icon spectrum-Icon--size{size.toUpperCase()}"
focusable="false"
aria-hidden="true"
aria-label={icon}
>
<use xlink:href="#spectrum-icon-18-{icon}" />
</svg>
{/if}
{componentText}
</button>
{/key}
<style>
button {

View File

@ -47,24 +47,25 @@
// Convert contenteditable HTML to text and save
const updateText = e => {
const sanitized = e.target.innerHTML.replace(/<br>/gi, "\n").trim()
builderStore.actions.updateProp("text", sanitized)
builderStore.actions.updateProp("text", e.target.textContent)
}
</script>
<h1
bind:this={node}
contenteditable={$component.editing}
use:styleable={styles}
class:placeholder
class:bold
class:italic
class:underline
class="spectrum-Heading {sizeClass} {alignClass}"
on:blur={$component.editing ? updateText : null}
>
{componentText}
</h1>
{#key $component.editing}
<h1
bind:this={node}
contenteditable={$component.editing}
use:styleable={styles}
class:placeholder
class:bold
class:italic
class:underline
class="spectrum-Heading {sizeClass} {alignClass}"
on:blur={$component.editing ? updateText : null}
>
{componentText}
</h1>
{/key}
<style>
h1 {

View File

@ -61,7 +61,7 @@
}
const updateText = e => {
builderStore.actions.updateProp("text", e.target.textContent.trim())
builderStore.actions.updateProp("text", e.target.textContent)
}
</script>

View File

@ -46,24 +46,25 @@
// Convert contenteditable HTML to text and save
const updateText = e => {
const sanitized = e.target.innerHTML.replace(/<br>/gi, "\n").trim()
builderStore.actions.updateProp("text", sanitized)
builderStore.actions.updateProp("text", e.target.textContent)
}
</script>
<p
bind:this={node}
contenteditable={$component.editing}
use:styleable={styles}
class:placeholder
class:bold
class:italic
class:underline
class="spectrum-Body {sizeClass} {alignClass}"
on:blur={$component.editing ? updateText : null}
>
{componentText}
</p>
{#key $component.editing}
<p
bind:this={node}
contenteditable={$component.editing}
use:styleable={styles}
class:placeholder
class:bold
class:italic
class:underline
class="spectrum-Body {sizeClass} {alignClass}"
on:blur={$component.editing ? updateText : null}
>
{componentText}
</p>
{/key}
<style>
p {

View File

@ -50,22 +50,24 @@
$: labelClass = labelPos === "above" ? "" : `spectrum-FieldLabel--${labelPos}`
const updateLabel = e => {
builderStore.actions.updateProp("label", e.target.textContent.trim())
builderStore.actions.updateProp("label", e.target.textContent)
}
</script>
<FieldGroupFallback>
<div class="spectrum-Form-item" use:styleable={$component.styles}>
<label
bind:this={labelNode}
contenteditable={$component.editing}
on:blur={$component.editing ? updateLabel : null}
class:hidden={!label}
for={fieldState?.fieldId}
class={`spectrum-FieldLabel spectrum-FieldLabel--sizeM spectrum-Form-itemLabel ${labelClass}`}
>
{label || " "}
</label>
{#key $component.editing}
<label
bind:this={labelNode}
contenteditable={$component.editing}
on:blur={$component.editing ? updateLabel : null}
class:hidden={!label}
for={fieldState?.fieldId}
class={`spectrum-FieldLabel spectrum-FieldLabel--sizeM spectrum-Form-itemLabel ${labelClass}`}
>
{label || " "}
</label>
{/key}
<div class="spectrum-Form-itemField">
{#if !formContext}
<Placeholder text="Form components need to be wrapped in a form" />