mirror of
https://github.com/element-plus/element-plus.git
synced 2025-02-17 11:49:41 +08:00
feat(docs): theme switch use startViewTransition api (#14489)
* feat(docs): theme switch use startViewTransition api * chore: format * feat: update
This commit is contained in:
parent
ef0d5820b4
commit
e0f47610e4
@ -1,5 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, watch } from 'vue'
|
import { nextTick, ref, watch } from 'vue'
|
||||||
import { isDark, toggleDark } from '../../composables/dark'
|
import { isDark, toggleDark } from '../../composables/dark'
|
||||||
import DarkIcon from '../icons/dark.vue'
|
import DarkIcon from '../icons/dark.vue'
|
||||||
import LightIcon from '../icons/light.vue'
|
import LightIcon from '../icons/light.vue'
|
||||||
@ -12,13 +12,60 @@ watch(
|
|||||||
toggleDark()
|
toggleDark()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
let resolveFn: (value: boolean | PromiseLike<boolean>) => void
|
||||||
|
const switchTheme = (event: MouseEvent) => {
|
||||||
|
const isAppearanceTransition =
|
||||||
|
// @ts-expect-error
|
||||||
|
document.startViewTransition &&
|
||||||
|
!window.matchMedia('(prefers-reduced-motion: reduce)').matches
|
||||||
|
if (!isAppearanceTransition || !event) {
|
||||||
|
resolveFn(true)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const x = event.clientX
|
||||||
|
const y = event.clientY
|
||||||
|
const endRadius = Math.hypot(
|
||||||
|
Math.max(x, innerWidth - x),
|
||||||
|
Math.max(y, innerHeight - y)
|
||||||
|
)
|
||||||
|
// @ts-expect-error: Transition API
|
||||||
|
const transition = document.startViewTransition(async () => {
|
||||||
|
resolveFn(true)
|
||||||
|
await nextTick()
|
||||||
|
})
|
||||||
|
transition.ready.then(() => {
|
||||||
|
const clipPath = [
|
||||||
|
`circle(0px at ${x}px ${y}px)`,
|
||||||
|
`circle(${endRadius}px at ${x}px ${y}px)`,
|
||||||
|
]
|
||||||
|
document.documentElement.animate(
|
||||||
|
{
|
||||||
|
clipPath: isDark.value ? [...clipPath].reverse() : clipPath,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
duration: 400,
|
||||||
|
easing: 'ease-in',
|
||||||
|
pseudoElement: isDark.value
|
||||||
|
? '::view-transition-old(root)'
|
||||||
|
: '::view-transition-new(root)',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const beforeChange = (): Promise<boolean> => {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
resolveFn = resolve
|
||||||
|
})
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div @click.stop="switchTheme">
|
||||||
<ClientOnly>
|
<ClientOnly>
|
||||||
<el-switch
|
<el-switch
|
||||||
v-model="darkMode"
|
v-model="darkMode"
|
||||||
|
:before-change="beforeChange"
|
||||||
:active-action-icon="DarkIcon"
|
:active-action-icon="DarkIcon"
|
||||||
:inactive-action-icon="LightIcon"
|
:inactive-action-icon="LightIcon"
|
||||||
/>
|
/>
|
||||||
|
@ -171,6 +171,7 @@ a.header-anchor {
|
|||||||
padding-right: 0.23em;
|
padding-right: 0.23em;
|
||||||
font-size: 0.85em;
|
font-size: 0.85em;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
|
||||||
&:hover,
|
&:hover,
|
||||||
:focus {
|
:focus {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
@ -200,6 +201,7 @@ li > ol {
|
|||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
margin-bottom: 45px;
|
margin-bottom: 45px;
|
||||||
|
|
||||||
& > table {
|
& > table {
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -271,6 +273,7 @@ details {
|
|||||||
p:not(.custom-block-title) {
|
p:not(.custom-block-title) {
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.tip {
|
&.tip {
|
||||||
padding: 8px 16px;
|
padding: 8px 16px;
|
||||||
background-color: var(--block-tip-bg-color);
|
background-color: var(--block-tip-bg-color);
|
||||||
@ -297,3 +300,25 @@ details {
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
width: 1px;
|
width: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::view-transition-old(root),
|
||||||
|
::view-transition-new(root) {
|
||||||
|
animation: none;
|
||||||
|
mix-blend-mode: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
::view-transition-old(root) {
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
::view-transition-new(root) {
|
||||||
|
z-index: 2147483646;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark::view-transition-old(root) {
|
||||||
|
z-index: 2147483646;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark::view-transition-new(root) {
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user