Refactor client app data tags to be classnames and simplify logic
This commit is contained in:
parent
07e0cbb210
commit
488ec4d988
|
@ -51,11 +51,11 @@
|
|||
$: children = instance._children || []
|
||||
$: id = instance._id
|
||||
$: name = instance._instanceName
|
||||
$: empty =
|
||||
!children.length &&
|
||||
definition?.hasChildren &&
|
||||
definition?.showEmptyState !== false &&
|
||||
$builderStore.inBuilder
|
||||
$: interactive =
|
||||
$builderStore.inBuilder &&
|
||||
($builderStore.previewType === "layout" || insideScreenslot)
|
||||
$: empty = interactive && !children.length && definition?.hasChildren
|
||||
$: emptyState = empty && definition?.showEmptyState !== false
|
||||
$: rawProps = getRawProps(instance)
|
||||
$: instanceKey = JSON.stringify(rawProps)
|
||||
$: updateComponentProps(rawProps, instanceKey, $context)
|
||||
|
@ -63,9 +63,6 @@
|
|||
$builderStore.inBuilder &&
|
||||
$builderStore.selectedComponentId === instance._id
|
||||
$: inSelectedPath = $builderStore.selectedComponentPath?.includes(id)
|
||||
$: interactive =
|
||||
$builderStore.inBuilder &&
|
||||
($builderStore.previewType === "layout" || insideScreenslot)
|
||||
$: evaluateConditions(enrichedSettings?._conditions)
|
||||
$: componentSettings = { ...enrichedSettings, ...conditionalSettings }
|
||||
|
||||
|
@ -73,8 +70,8 @@
|
|||
$: componentStore.set({
|
||||
id,
|
||||
children: children.length,
|
||||
styles: { ...instance._styles, id, empty, interactive },
|
||||
empty,
|
||||
styles: { ...instance._styles, id, empty: emptyState, interactive },
|
||||
empty: emptyState,
|
||||
selected,
|
||||
name,
|
||||
})
|
||||
|
@ -177,38 +174,44 @@
|
|||
// Drag and drop helper tags
|
||||
$: draggable = interactive && !isLayout && !isScreen
|
||||
$: droppable = interactive && !isLayout && !isScreen
|
||||
$: dropInside = interactive && definition?.hasChildren && !children.length
|
||||
</script>
|
||||
|
||||
{#key propsHash}
|
||||
{#if constructor && componentSettings && (visible || inSelectedPath)}
|
||||
<div
|
||||
class={`component ${id}`}
|
||||
data-type={interactive ? "component" : "readonly"}
|
||||
data-id={id}
|
||||
data-name={name}
|
||||
data-draggable={draggable}
|
||||
data-droppable={droppable}
|
||||
data-droppable-inside={dropInside}
|
||||
>
|
||||
<svelte:component this={constructor} {...componentSettings}>
|
||||
{#if children.length}
|
||||
{#each children as child (child._id)}
|
||||
<svelte:self instance={child} />
|
||||
{/each}
|
||||
{:else if empty}
|
||||
<Placeholder />
|
||||
{/if}
|
||||
</svelte:component>
|
||||
</div>
|
||||
{/if}
|
||||
{#key empty}
|
||||
{#if constructor && componentSettings && (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
|
||||
data-id={id}
|
||||
data-name={name}
|
||||
>
|
||||
<svelte:component this={constructor} {...componentSettings}>
|
||||
{#if children.length}
|
||||
{#each children as child (child._id)}
|
||||
<svelte:self instance={child} />
|
||||
{/each}
|
||||
{:else if emptyState}
|
||||
<Placeholder />
|
||||
{/if}
|
||||
</svelte:component>
|
||||
</div>
|
||||
{/if}
|
||||
{/key}
|
||||
{/key}
|
||||
|
||||
<style>
|
||||
.component {
|
||||
display: contents;
|
||||
}
|
||||
[data-draggable="true"] :global(*:hover) {
|
||||
.interactive :global(*:hover) {
|
||||
cursor: pointer;
|
||||
}
|
||||
.draggable :global(*:hover) {
|
||||
cursor: grab;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
display: flex;
|
||||
max-width: 100%;
|
||||
}
|
||||
.valid-container :global([data-type="component"] > *) {
|
||||
.valid-container :global(.component > *) {
|
||||
max-width: 100%;
|
||||
}
|
||||
.direction-row {
|
||||
|
@ -46,7 +46,7 @@
|
|||
|
||||
/* Grow containers inside a row need 0 width 0 so that they ignore content */
|
||||
/* The nested selector for data-type is the wrapper around all components */
|
||||
.direction-row :global(> [data-type="component"] > .size-grow) {
|
||||
.direction-row :global(> .component > .size-grow) {
|
||||
width: 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,16 +9,15 @@
|
|||
let dropInfo
|
||||
|
||||
const getDOMNodeForComponent = component => {
|
||||
const parent = component.closest("[data-type='component']")
|
||||
const parent = component.closest(".component")
|
||||
const children = Array.from(parent.childNodes)
|
||||
return children?.find(node => node?.nodeType === 1)
|
||||
}
|
||||
|
||||
// Callback when initially starting a drag on a draggable component
|
||||
const onDragStart = e => {
|
||||
const parent = e.target.closest("[data-type='component']")
|
||||
const child = getDOMNodeForComponent(e.target)
|
||||
if (!parent?.dataset?.id || !child) {
|
||||
const parent = e.target.closest(".component")
|
||||
if (!parent?.classList.contains("draggable")) {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -31,7 +30,10 @@
|
|||
builderStore.actions.setDragging(true)
|
||||
|
||||
// Highlight being dragged by setting opacity
|
||||
child.style.opacity = "0.5"
|
||||
const child = getDOMNodeForComponent(e.target)
|
||||
if (child) {
|
||||
child.style.opacity = "0.5"
|
||||
}
|
||||
}
|
||||
|
||||
// Callback when drag stops (whether dropped or not)
|
||||
|
@ -102,10 +104,10 @@
|
|||
return
|
||||
}
|
||||
|
||||
const element = e.target.closest("[data-type='component']")
|
||||
const element = e.target.closest(".component")
|
||||
if (
|
||||
element &&
|
||||
element.dataset.droppable === "true" &&
|
||||
element.classList.contains("droppable") &&
|
||||
element.dataset.id !== dragInfo.target
|
||||
) {
|
||||
// Do nothing if this is the same target
|
||||
|
@ -130,7 +132,7 @@
|
|||
dropInfo = {
|
||||
target,
|
||||
name: element.dataset.name,
|
||||
droppableInside: element.dataset.droppableInside === "true",
|
||||
droppableInside: element.classList.contains("empty"),
|
||||
bounds,
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
$: zIndex = componentId === $builderStore.selectedComponentId ? 900 : 920
|
||||
|
||||
const onMouseOver = e => {
|
||||
const element = e.target.closest("[data-type='component']")
|
||||
const element = e.target.closest(".interactive.component")
|
||||
const newId = element?.dataset?.id
|
||||
if (newId !== componentId) {
|
||||
componentId = newId
|
||||
|
|
|
@ -24,8 +24,8 @@ export const styleable = (node, styles = {}) => {
|
|||
let selectComponent
|
||||
|
||||
// Allow dragging if required
|
||||
const parent = node.closest("[data-type='component']")
|
||||
if (parent && parent.dataset.draggable === "true") {
|
||||
const parent = node.closest(".component")
|
||||
if (parent && parent.classList.contains("draggable")) {
|
||||
node.setAttribute("draggable", true)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue