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