fix(stage-*): redundant template ref & ref for elmenets

This commit is contained in:
Neko Ayaka
2025-12-11 15:39:28 +08:00
parent e1de84ecb2
commit 7f5234de74
10 changed files with 19 additions and 36 deletions
@@ -1,32 +1,33 @@
import { nextTick, ref, watch } from 'vue'
import type { MaybeRefOrGetter } from 'vue'
import { nextTick, toRef, watch } from 'vue'
import { useRoute } from 'vue-router'
const scrollPositions = new Map<string, number>()
export function useRestoreScroll() {
export function useRestoreScroll(scrollContainer: MaybeRefOrGetter<HTMLElement | null | undefined>) {
const route = useRoute()
const scrollContainer = ref<HTMLElement | null>(null)
const scrollContainerRef = toRef(scrollContainer)
watch(
() => route.fullPath,
async (newPath, oldPath) => {
if (!scrollContainer.value) {
if (!scrollContainerRef.value) {
return
}
if (oldPath) {
scrollPositions.set(oldPath, scrollContainer.value.scrollTop)
scrollPositions.set(oldPath, scrollContainerRef.value.scrollTop)
}
await nextTick()
if (!scrollContainer.value) {
if (!scrollContainerRef.value) {
return
}
const savedPosition = scrollPositions.get(newPath) || 0
scrollContainer.value.scrollTop = savedPosition
scrollContainerRef.value.scrollTop = savedPosition
},
)
@@ -2,7 +2,7 @@
import { PageHeader } from '@proj-airi/stage-ui/components'
import { useProvidersStore } from '@proj-airi/stage-ui/stores/providers'
import { storeToRefs } from 'pinia'
import { computed } from 'vue'
import { computed, ref } from 'vue'
import { useI18n } from 'vue-i18n'
import { RouterView, useRoute } from 'vue-router'
@@ -14,6 +14,8 @@ const route = useRoute()
const { t } = useI18n()
const providersStore = useProvidersStore()
const { allProvidersMetadata } = storeToRefs(providersStore)
const scrollContainer = ref<HTMLElement>()
useRestoreScroll(scrollContainer)
const routeHeaderMetadataMap = computed(() => {
const map: Record<string, { subtitle?: string, title: string }> = {
@@ -134,8 +136,6 @@ const routeHeaderMetadataMap = computed(() => {
const routeHeaderMetadata = computed(() => {
return routeHeaderMetadataMap.value[route.path] || routeHeaderMetadataMap.value[`${route.path}/`]
})
const { scrollContainer } = useRestoreScroll()
</script>
<template>
@@ -1,13 +1,12 @@
<script setup lang="ts">
import { useWindowSize } from '@vueuse/core'
import { computed, ref } from 'vue'
import { computed } from 'vue'
import { useElectronAllDisplays, useElectronMouse } from '../../composables/electron-vueuse'
const allDisplays = useElectronAllDisplays()
const { x: cursorX, y: cursorY } = useElectronMouse()
const containerRef = ref<HTMLElement>()
const windowSize = useWindowSize()
const displayBounds = computed(() => {
@@ -89,7 +88,6 @@ const containerDimensions = computed(() => {
<template>
<div>
<div
ref="containerRef"
class="relative"
:style="{
width: `${containerDimensions.width}px`,
@@ -31,7 +31,6 @@ import {
import { useControlsIslandStore } from '../stores/controls-island'
import { useWindowStore } from '../stores/window'
const resourceStatusIslandRef = ref<InstanceType<typeof ResourceStatusIsland>>()
const controlsIslandRef = ref<InstanceType<typeof ControlsIsland>>()
const widgetStageRef = ref<{ canvasElement: () => HTMLCanvasElement }>()
const stageCanvas = toRef(() => widgetStageRef.value?.canvasElement())
@@ -218,7 +217,7 @@ watch([stream, () => vadLoaded.value], async ([s, loaded]) => {
'transition-opacity duration-250 ease-in-out',
]"
>
<ResourceStatusIsland ref="resourceStatusIslandRef" />
<ResourceStatusIsland />
<WidgetStage
ref="widgetStageRef"
v-model:state="componentStateStage"
@@ -20,7 +20,6 @@ const { t } = useI18n()
const descriptionContainerRef = ref<HTMLDivElement>()
const { isOutside } = useMouseInElement(descriptionContainerRef)
const descriptionContainerTitleRef = ref<HTMLDivElement>()
const descriptionOpenImmediate = computed(() => !isOutside.value)
const descriptionOpen = refDebounced(descriptionOpenImmediate, 80)
@@ -118,7 +117,7 @@ async function handleAction(action: 'confirm' | 'cancel' | 'close') {
>
<div class="space-y-2">
<div class="flex items-center gap-3">
<div ref="descriptionContainerTitleRef" class="line-clamp-1 min-h-full flex-1 overflow-hidden text-ellipsis text-lg font-semibold space-y-0.5">
<div class="line-clamp-1 min-h-full flex-1 overflow-hidden text-ellipsis text-lg font-semibold space-y-0.5">
<template v-if="!descriptionOpen">
<i18n-t keypath="tamagotchi.stage.notice.fade-on-hover.opacity" tag="div">
<template #value>
@@ -9,7 +9,6 @@ interface Point {
y: number
}
const containerRef = ref<HTMLDivElement>()
const canvasContainerRef = ref<HTMLDivElement>()
const canvasRef = ref<HTMLCanvasElement>()
const canvasContext = ref<CanvasRenderingContext2D | undefined | null>()
@@ -129,7 +128,7 @@ watch(pointThrottled, (point) => {
</script>
<template>
<div ref="containerRef" h="[calc(100dvh-40px)]">
<div h="[calc(100dvh-40px)]">
<div relative h-full>
<div bg="neutral-100/50 dark:neutral-900/50" absolute inset-0 h-fit rounded-xl px-3 py-2 font-mono shadow-md backdrop-blur-md grid="~ cols-[150px_1fr]">
<div text="neutral-400 dark:neutral-600">
+1
View File
@@ -29,6 +29,7 @@ export default defineConfig({
}, {
rules: {
'pnpm/json-valid-catalog': 'off',
'pnpm/json-enforce-catalog': 'off',
'antfu/import-dedupe': 'error',
// TODO: remove this
'depend/ban-dependencies': 'warn',
@@ -28,7 +28,6 @@ const emit = defineEmits<{
// State
const isReplaying = ref(false)
const replayCount = ref(0)
const containerRef = ref<HTMLElement>()
const autoReplayTimer = ref<NodeJS.Timeout>()
// Replay callbacks registry
@@ -143,10 +142,7 @@ defineExpose({
</script>
<template>
<div
ref="containerRef"
class="relative inline-block h-full w-full"
>
<div class="relative inline-block h-full w-full">
<!-- Slot content -->
<div class="relative z-1">
<slot />
@@ -1,12 +1,5 @@
<script setup lang="ts">
import { ref } from 'vue'
import CursorMomentum from './CursorMomentum.vue'
// Example components that use momentum
const rotatingBox = ref(null)
const floatingBall = ref(null)
const pulsingCircle = ref(null)
</script>
<template>
@@ -31,7 +24,6 @@ const pulsingCircle = ref(null)
:momentum-factor="0.005"
>
<div
ref="rotatingBox"
class="h-20 w-20 bg-primary-500/20"
:style="{
transform: `rotate(${currentValue}deg)`,
@@ -53,7 +45,6 @@ const pulsingCircle = ref(null)
:momentum-factor="0.01"
>
<div
ref="floatingBall"
class="h-10 w-10 rounded-full bg-primary-500/20"
:style="{
transform: `translateY(${Math.sin(momentum * 0.1) * 20}px)`,
@@ -75,7 +66,6 @@ const pulsingCircle = ref(null)
:momentum-factor="0.008"
>
<div
ref="pulsingCircle"
class="h-16 w-16 rounded-full bg-primary-500/20"
:style="{
transform: `scale(${0.8 + (momentum * 0.2)})`,
@@ -82,7 +82,7 @@ function toDisplayValue(value: T): string {
<template
v-for="(group, index) in options"
:key="group.name"
:key="group.groupLabel"
>
<ComboboxGroup :class="['overflow-x-hidden']">
<ComboboxSeparator