feat: add toggleDarkWithTransition

This commit is contained in:
YunYouJun 2023-10-22 02:25:07 +08:00
parent d95841f40d
commit b76f20e859
12 changed files with 150 additions and 7 deletions

View File

@ -47,7 +47,9 @@
"i18n-ally.sourceLanguage": "en",
"i18n-ally.keystyle": "nested",
"i18n-ally.localesPaths": [
"packages/valaxy/src/client/locales"
"packages/valaxy/client/locales",
"packages/valaxy-theme-yun/locales",
"demo/yun/locales"
],
"i18n-ally.sortKeys": true,
"files.associations": {

6
docs/pages/api/addon.md Normal file
View File

@ -0,0 +1,6 @@
---
title: Addon API
categories:
- API
end: false
---

33
docs/pages/api/index.md Normal file
View File

@ -0,0 +1,33 @@
---
title: Core API
categories:
- API
---
## Client
### Toggle Dark
- `isDark`: Whether dark mode is enabled
- `toggleDark`: Toggle dark mode
- `toggleDarkWithTransition`: Toggle dark mode with transition
Example:
```vue
<script lang="ts" setup>
import { isDark, toggleDarkWithTransition } from 'valaxy'
</script>
<template>
<button class="yun-icon-btn" @click="toggleDarkWithTransition">
<div i="ri-sun-line dark:ri-moon-line" />
</button>
</template>
```
## Node
### Hooks
- [钩子](/guide/custom/hooks.md)

6
docs/pages/api/theme.md Normal file
View File

@ -0,0 +1,6 @@
---
title: Theme API
categories:
- API
end: false
---

View File

@ -55,6 +55,23 @@ export default defineValaxyConfig<PressTheme.Config>({
},
],
},
{
text: 'API',
items: [
{
text: 'Core',
link: '/api/',
},
{
text: 'Theme',
link: '/api/theme',
},
{
text: 'Addon',
link: '/api/addon',
},
],
},
{
text: 'nav.theme',
items: [

View File

@ -14,7 +14,7 @@ const { t } = useI18n()
<template>
<AppLink
class="press-nav-item-link"
class="press-nav-item-link flex justify-center items-center"
:class="{
active: route.path === item.link,
}"

View File

@ -1,9 +1,9 @@
<script lang="ts" setup>
import { isDark, toggleDark } from 'valaxy'
import { isDark, toggleDarkWithTransition } from 'valaxy'
</script>
<template>
<button class="switch switch-appearance" type="button" aria-label="Toggle Dark Mode" @click="toggleDark()">
<button class="switch switch-appearance" type="button" aria-label="Toggle Dark Mode" @click="toggleDarkWithTransition">
<span class="check">
<span class="icon-wrap">
<div v-if="!isDark" class="icon" i-ri-sun-line />

View File

@ -1,7 +1,7 @@
<script lang="ts" setup>
import { useI18n } from 'vue-i18n'
import { computed } from 'vue'
import { isDark, toggleDark } from 'valaxy'
import { isDark, toggleDarkWithTransition } from 'valaxy'
const { t } = useI18n()
@ -12,7 +12,7 @@ const themeTitle = computed(() => {
<template>
<div>
<button class="yun-icon-btn" :title="themeTitle" :style="{ color: isDark ? '' : '#f1cb64' }" @click="toggleDark()">
<button class="yun-icon-btn" :title="themeTitle" :style="{ color: isDark ? '' : '#f1cb64' }" @click="toggleDarkWithTransition">
<div i="ri-sun-line dark:ri-moon-line" />
</button>

View File

@ -0,0 +1,21 @@
// transition
::view-transition-old(root),
::view-transition-new(root) {
animation: none;
mix-blend-mode: normal;
}
/* 进入dark模式和退出dark模式时两个图像的位置顺序正好相反 */
.dark::view-transition-old(root) {
z-index: 9999;
}
.dark::view-transition-new(root) {
z-index: 1;
}
::view-transition-old(root) {
z-index: 1;
}
::view-transition-new(root) {
z-index: 9999;
}

View File

@ -1,5 +1,4 @@
@use "./layout" as *;
@use "./common/button.scss" as *;
@forward "star-markdown-css/src/scss/theme/yun.scss" with (
$colors: (
"primary": $c-primary,
@ -7,6 +6,9 @@
);
// override the default style of star-markdown-css
@use "./common/button.scss" as *;
@use "./common/markdown.scss" as *;
@use './common/effects.scss' as *;
@use 'valaxy/client/styles/components/code-group.scss' as *;
@use 'valaxy/client/styles/components/custom-block.scss' as *;

View File

@ -2,3 +2,36 @@ import { useDark, useToggle } from '@vueuse/core'
export const isDark = useDark()
export const toggleDark = useToggle(isDark)
export function toggleDarkWithTransition(event: MouseEvent, options: { duration?: number; easing?: EffectTiming['easing'] } = {}) {
// toggleDark()
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 startViewTransition is not defined
const transition = document.startViewTransition(() => {
toggleDark()
})
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: options.duration || 300,
easing: options.easing || 'ease-in',
pseudoElement: isDark.value ? '::view-transition-old(root)' : '::view-transition-new(root)',
},
)
})
}

View File

@ -21,3 +21,26 @@
opacity: 0;
}
}
// dark toggle
// transition
::view-transition-old(root),
::view-transition-new(root) {
animation: none;
mix-blend-mode: normal;
}
/* 进入dark模式和退出dark模式时两个图像的位置顺序正好相反 */
.dark::view-transition-old(root) {
z-index: 9999;
}
.dark::view-transition-new(root) {
z-index: 1;
}
::view-transition-old(root) {
z-index: 1;
}
::view-transition-new(root) {
z-index: 9999;
}