Skip to content

Commit

Permalink
Dragging the parent works!
Browse files Browse the repository at this point in the history
  • Loading branch information
cibernox committed Oct 4, 2024
1 parent 4b3a09d commit a51b0c6
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 23 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts" context="module">
import { writable, type Writable } from "svelte/store"
import { page, selectedAstElementId, parentOfSelectedAstElement } from "$lib/stores/page"
import { page, selectedAstElementId, parentOfSelectedAstElement, parentSelectedAstElementId, grandParentOfSelectedAstElement } from "$lib/stores/page"
import { findHoveredSiblingIndex, getBoundingRect, getDragDirection, type Coords } from "$lib/utils/drag-helpers"
import { live } from "$lib/stores/live"
Expand Down Expand Up @@ -123,25 +123,35 @@
}
function applyNewOrder() {
if (newIndex !== null && newIndex !== dragElementInfo.selectedIndex) {
let parent = isParent ? $grandParentOfSelectedAstElement : $parentOfSelectedAstElement
if (newIndex !== null && newIndex !== dragElementInfo.selectedIndex && !!parent) {
// Reordering happened, apply new order
let parent = $parentOfSelectedAstElement
const selectedAstElement = parent.content.splice(dragElementInfo.selectedIndex, 1)[0]
parent.content.splice(newIndex, 0, selectedAstElement)
// Update the selectedAstElementId so the same item remains selected
if (isParent) {
let parts = $selectedAstElementId.split(".")
parts[parts.length - 2] = newIndex.toString()
$selectedAstElementId = parts.join(".")
} else {
let parts = $selectedAstElementId.split(".")
parts[parts.length - 1] = newIndex.toString()
$selectedAstElementId = parts.join(".")
}
// console.log('$page.ast[0]', $page.ast[0]);
$page.ast = [...$page.ast]
let parts = $selectedAstElementId.split(".")
parts[parts.length - 1] = newIndex.toString()
$selectedAstElementId = parts.join(".")
// Update in the server
$live.pushEvent("update_page_ast", { id: $page.id, ast: $page.ast })
}
}
function resetDragElementHandle() {
dragHandleElement.style.transform = null
dragHandleElement.style.setProperty("--tw-translate-y", null)
dragHandleElement.style.setProperty("--tw-translate-x", null)
if (dragHandleElement) {
dragHandleElement.style.transform = null
dragHandleElement.style.setProperty("--tw-translate-y", null)
dragHandleElement.style.setProperty("--tw-translate-x", null)
}
}
async function handleMouseup(e: MouseEvent) {
Expand Down
37 changes: 25 additions & 12 deletions assets/svelte/stores/page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,46 @@ export const page: Writable<Page> = writable()
export const selectedAstElementId: Writable<string | undefined> = writable()
export const highlightedAstElement: Writable<AstElement | undefined> = writable()
export const slotTargetElement: Writable<AstElement | undefined> = writable()

export const rootAstElement: Readable<AstElement | undefined> = derived([page], ([$page]) => {
// This is a virtual AstElement intended to simulate the page itself to reorder the components at the first level.
if ($page) {
return { tag: "root", attrs: {}, content: $page.ast }
}
})

export const selectedAstElement: Readable<AstElement | undefined> = derived(
[page, selectedAstElementId],
([$page, $selectedAstElementId]) => {
if ($page && $selectedAstElementId) {
if ($selectedAstElementId === "root") return get(rootAstElement)
return findAstElement($page.ast, $selectedAstElementId)
}
},
)

function getParentId(id: string | null) {
if (id === "root") return null
let levels = id.split(".")
if (levels.length === 1) return "root"
levels.pop()
return levels.join(".")
}

export const parentSelectedAstElementId: Readable<string> = derived([selectedAstElementId], ([$selectedAstElementId]) => {
return getParentId($selectedAstElementId);
})

export const grandParentSelectedAstElementId: Readable<string> = derived([parentSelectedAstElementId], ([$parentSelectedAstElementId]) => {
return getParentId($parentSelectedAstElementId);
})

export const parentOfSelectedAstElement: Readable<AstElement | undefined> = derived(
[page, selectedAstElementId],
([$page, $selectedAstElementId]) => {
if ($page && $selectedAstElementId) {
if ($selectedAstElementId === "root") return null
let levels = $selectedAstElementId.split(".")
if (levels.length === 1) return get(rootAstElement)
levels.pop()
return findAstElement($page.ast, levels.join("."))
}
},
[page, parentSelectedAstElementId],
([$page, $parentSelectedAstElementId]) => findAstElement($page.ast, $parentSelectedAstElementId)
)

export const grandParentOfSelectedAstElement: Readable<AstElement | undefined> = derived(
[page, grandParentSelectedAstElementId],
([$page, $grandParentSelectedAstElementId]) => findAstElement($page.ast, $grandParentSelectedAstElementId)
)

export const selectedDomElement: Writable<Element | null> = writable(null)
Expand All @@ -56,6 +68,7 @@ export function isAstElement(maybeNode: AstNode): maybeNode is AstElement {
}

export function findAstElement(ast: AstNode[], id: string): AstElement {
if (id === "root") return get(rootAstElement);
let indexes = id.split(".").map((s) => parseInt(s, 10))
let node: AstNode = ast[indexes[0]] as AstElement
ast = node.content
Expand Down
4 changes: 2 additions & 2 deletions assets/svelte/utils/drag-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,9 @@ function detectFlow(rects: DOMRect[]) {
// I'm not sure if there's any imaginative layout in which is not good enough, but just in case
// there's a second logic to check if the parent element uses a horizontal flexbox layout.
export function getDragDirection(element: Element): DragDirection {
let parentEl = element.parentElement
let parentEl = element?.parentElement

if (parentEl === null) {
if (!parentEl) {
return "vertical"
}

Expand Down

0 comments on commit a51b0c6

Please sign in to comment.