fix: re-mount DOM widget elements after leaving Linear mode (#8753)

## Summary

LinearView renders its own WidgetDOM instances which steal the
widget.element via replaceChildren. When LinearView unmounts
(v-if="linearMode") the element is removed from the DOM entirely.
The canvas-side WidgetDOM stays mounted but its container is now empty,
so DOM widgets (e.g. Three.js scenes) disappear.

Watch canvasStore.linearMode and reclaim the element when switching back
from Linear to Canvas mode.

## Screenshots (if applicable)
before


https://github.com/user-attachments/assets/78cea2bc-c4b3-4b21-bdb3-a521bb0d3062


after


https://github.com/user-attachments/assets/8f92c44d-9514-4001-bbdb-bc4c80468ed7

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8753-fix-re-mount-DOM-widget-elements-after-leaving-Linear-mode-3026d73d3650810b8968eff13dc84e9a)
by [Unito](https://www.unito.io)
This commit is contained in:
Terry Jia
2026-02-08 22:51:57 -05:00
committed by GitHub
parent be515d6fcc
commit 3238ad3d32
2 changed files with 15 additions and 3 deletions

View File

@@ -18,7 +18,7 @@
</template>
<script setup lang="ts">
import { useElementBounding, useEventListener } from '@vueuse/core'
import { useElementBounding, useEventListener, whenever } from '@vueuse/core'
import type { CSSProperties } from 'vue'
import { computed, nextTick, onMounted, ref, watch } from 'vue'
@@ -180,6 +180,8 @@ watch(
mountElementIfVisible()
}
)
whenever(() => !canvasStore.linearMode, mountElementIfVisible)
</script>
<style scoped>

View File

@@ -1,4 +1,5 @@
<script setup lang="ts">
import { whenever } from '@vueuse/core'
import { onMounted, ref } from 'vue'
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
@@ -13,15 +14,24 @@ const props = defineProps<{
const domEl = ref<HTMLElement>()
const { canvas } = useCanvasStore()
onMounted(() => {
const canvasStore = useCanvasStore()
const { canvas } = canvasStore
function mountWidgetElement() {
if (!domEl.value) return
const node = canvas?.graph?.getNodeById(props.nodeId) ?? undefined
if (!node) return
const widget = node.widgets?.find((w) => w.name === props.widget.name)
if (!widget || !isDOMWidget(widget)) return
if (domEl.value.contains(widget.element)) return
domEl.value.replaceChildren(widget.element)
}
onMounted(() => {
mountWidgetElement()
})
whenever(() => !canvasStore.linearMode, mountWidgetElement)
</script>
<template>
<div ref="domEl" @pointerdown.stop @pointermove.stop @pointerup.stop />