Be more explicit about the boolean nature of component settings in the manifest and add back in a render key to fix toggling contenteditable attribute on dom elements

This commit is contained in:
Andrew Kingston 2021-11-18 20:32:42 +00:00
parent 0aa0f6a07d
commit df29ad1092
1 changed files with 46 additions and 30 deletions

View File

@ -72,13 +72,18 @@
$: inSelectedPath = $builderStore.selectedComponentPath?.includes(id)
$: inDragPath = inSelectedPath && $builderStore.editMode
// Derive definition properties which can all be optional, so need to be
// coerced to booleans
$: editable = !!definition?.editable
$: hasChildren = !!definition?.hasChildren
$: showEmptyState = !!definition?.showEmptyState
// Interactive components can be selected, dragged and highlighted inside
// the builder preview
$: interactive =
$builderStore.inBuilder &&
($builderStore.previewType === "layout" || insideScreenslot) &&
!isBlock
$: editable = definition?.editable
$: editing = editable && selected && $builderStore.editMode
$: draggable = !inDragPath && interactive && !isLayout && !isScreen
$: droppable = interactive && !isLayout && !isScreen
@ -86,8 +91,8 @@
// Empty components are those which accept children but do not have any.
// Empty states can be shown for these components, but can be disabled
// in the component manifest.
$: empty = interactive && !children.length && definition?.hasChildren
$: emptyState = empty && definition?.showEmptyState !== false
$: empty = interactive && !children.length && hasChildren
$: emptyState = empty && showEmptyState
// Raw settings are all settings excluding internal props and children
$: rawSettings = getRawSettings(instance)
@ -103,6 +108,9 @@
// Build up the final settings object to be passed to the component
$: cacheSettings(enrichedSettings, nestedSettings, conditionalSettings)
// Render key is used to determine when components need to fully remount
$: renderKey = getRenderKey(id, editing)
// Update component context
$: componentStore.set({
id,
@ -268,35 +276,43 @@
})
}
}
// Generates a key used to determine when components need to fully remount.
// Currently only toggling editing requires remounting.
const getRenderKey = (id, editing) => {
return hashString(`${id}-${editing}`)
}
</script>
{#if constructor && cachedSettings && (visible || inSelectedPath)}
<!-- The ID is used as a class because getElementsByClassName is O(1) -->
<!-- and the performance matters for the selection indicators -->
<div
class={`component ${id}`}
class:draggable
class:droppable
class:empty
class:interactive
class:editing
class:block={isBlock}
data-id={id}
data-name={name}
>
<svelte:component this={constructor} {...cachedSettings}>
{#if children.length}
{#each children as child (child._id)}
<svelte:self instance={child} />
{/each}
{:else if emptyState}
<Placeholder />
{:else if isBlock}
<slot />
{/if}
</svelte:component>
</div>
{/if}
{#key renderKey}
{#if constructor && cachedSettings && (visible || inSelectedPath)}
<!-- The ID is used as a class because getElementsByClassName is O(1) -->
<!-- and the performance matters for the selection indicators -->
<div
class={`component ${id}`}
class:draggable
class:droppable
class:empty
class:interactive
class:editing
class:block={isBlock}
data-id={id}
data-name={name}
>
<svelte:component this={constructor} {...cachedSettings}>
{#if children.length}
{#each children as child (child._id)}
<svelte:self instance={child} />
{/each}
{:else if emptyState}
<Placeholder />
{:else if isBlock}
<slot />
{/if}
</svelte:component>
</div>
{/if}
{/key}
<style>
.component {