<script setup lang="ts"> import DefaultTheme from 'vitepress/theme' import { useData } from 'vitepress' import { nextTick, provide } from 'vue' import Sidebar from './components/SidebarCard.vue' import Announcement from './components/Announcement.vue' const { isDark } = useData() const enableTransitions = () => 'startViewTransition' in document && window.matchMedia('(prefers-reduced-motion: no-preference)').matches provide('toggle-appearance', async ({ clientX: x, clientY: y }: MouseEvent) => { if (!enableTransitions()) { isDark.value = !isDark.value return } const clipPath = [ `circle(0px at ${x}px ${y}px)`, `circle(${Math.hypot( Math.max(x, innerWidth - x), Math.max(y, innerHeight - y) )}px at ${x}px ${y}px)` ] // @ts-expect-error await document.startViewTransition(async () => { isDark.value = !isDark.value await nextTick() }).ready document.documentElement.animate( { clipPath: isDark.value ? clipPath.reverse() : clipPath }, { duration: 300, easing: 'ease-in', pseudoElement: `::view-transition-${isDark.value ? 'old' : 'new'}(root)` } ) }) const { Layout } = DefaultTheme </script> <template> <Layout> <template #sidebar-nav-after> <Sidebar /> </template> <template #home-hero-prelink> <Announcement /> </template> <Content /> </Layout> </template> <style> ::view-transition-old(root), ::view-transition-new(root) { animation: none; mix-blend-mode: normal; } ::view-transition-old(root), .dark::view-transition-new(root) { z-index: 1; } ::view-transition-new(root), .dark::view-transition-old(root) { z-index: 9999; } .VPSwitchAppearance { width: 22px !important; } .VPSwitchAppearance .check { transform: none !important; } </style>