feat(theme): add transition options

This commit is contained in:
pengzhanbo 2024-06-26 00:40:36 +08:00
parent bf72d5025d
commit babd6114c3
7 changed files with 102 additions and 10 deletions

View File

@ -366,6 +366,38 @@ type NavItem = string | {
每个页面可以通过 [frontmatter outline](./frontmatter/basic.md#outline) 覆盖层级配置。
### transition
- 类型: `boolean | ThemeTransition`
- 默认值: `true`
- 详情:
是否启用过渡动画。
传入 `boolean` 类型时,`true` 代表启用,`false` 代表禁用。
也可以传入一个对象,具体配置见下
```ts
interface ThemeTransition {
/**
* 是否启用 页面间跳转过渡动画
* @default true
*/
page?: boolean
/**
* 是否启用 博客文章列表过渡动画
* @default true
*/
postList?: boolean
/**
* 是否启用 深色/浅色 模式切换过渡动画
* @default true
*/
appearance?: boolean
}
```
### selectLanguageName
- 类型: `string`

View File

@ -1,4 +1,7 @@
<script setup lang="ts">
import { computed } from 'vue'
import { useData } from '../composables/data.js'
interface Props {
delay?: number
duration?: number
@ -9,6 +12,15 @@ const props = withDefaults(defineProps<Props>(), {
duration: 0.25,
})
const { theme } = useData()
const enabledTransition = computed(() => {
const transition = theme.value.transition
return typeof transition === 'object'
? transition.postList !== false
: transition !== false
})
let _transition = ''
function beforeAppear(item: Element) {
@ -37,6 +49,7 @@ function unsetStyle(item: Element) {
<template>
<Transition
v-if="enabledTransition"
name="drop"
mode="out-in"
:appear="appear"
@ -49,4 +62,5 @@ function unsetStyle(item: Element) {
>
<slot />
</Transition>
<slot v-else />
</template>

View File

@ -1,11 +1,22 @@
<script lang="ts" setup>
import { computed } from 'vue'
import { useScrollPromise } from '../composables/scroll-promise.js'
import { useData } from '../composables/data.js'
const { theme } = useData()
const { resolve: onBeforeEnter, pending: onBeforeLeave } = useScrollPromise()
const enabledTransition = computed(() => {
const transition = theme.value.transition
return typeof transition === 'object'
? transition.page !== false
: transition !== false
})
</script>
<template>
<Transition
v-if="enabledTransition"
name="fade-slide-y"
mode="out-in"
@before-enter="onBeforeEnter"
@ -13,4 +24,5 @@ const { resolve: onBeforeEnter, pending: onBeforeLeave } = useScrollPromise()
>
<slot />
</Transition>
<slot v-else />
</template>

View File

@ -10,16 +10,21 @@ export const darkModeSymbol: InjectionKey<DarkModeRef> = Symbol(
)
export function setupDarkMode(app: App): void {
const themeLocale = useThemeData()
const theme = useThemeData()
const appearance = themeLocale.value.appearance
const transition = theme.value.transition
const disableTransition = typeof transition === 'object'
? transition.appearance === false
: transition === false
const appearance = theme.value.appearance
const isDark
= appearance === 'force-dark'
? ref(true)
: appearance
? useDark({
storageKey: 'vuepress-theme-appearance',
disableTransition: false,
disableTransition,
initialValue: () =>
typeof appearance === 'string' ? appearance : 'auto',
...(typeof appearance === 'object' ? appearance : {}),

View File

@ -18,11 +18,13 @@
/* ----------------- Transition ------------------------ */
.fade-slide-y-enter-active {
transition: all 0.25s ease !important;
transition: 0.25s ease !important;
transition-property: opacity, transform;
}
.fade-slide-y-leave-active {
transition: all 0.25s cubic-bezier(0, 1, 0.3, 1) !important;
transition: 0.25s cubic-bezier(0, 1, 0.3, 1) !important;
transition-property: opacity, transform;
}
.fade-slide-y-enter-from,
@ -32,11 +34,13 @@
}
.fade-slide-x-enter-active {
transition: all 0.25s ease !important;
transition: 0.25s ease !important;
transition-property: opacity, transform;
}
.fade-slide-x-leave-active {
transition: all 0.25s cubic-bezier(0, 1, 0.3, 1) !important;
transition: 0.25s cubic-bezier(0, 1, 0.3, 1) !important;
transition-property: opacity, transform;
}
.fade-slide-x-enter-from,

View File

@ -45,3 +45,21 @@ export interface PresetLocale {
tag: string
archive: string
}
export interface ThemeTransition {
/**
*
* @default true
*/
page?: boolean
/**
*
* @default true
*/
postList?: boolean
/**
* /
* @default true
*/
appearance?: boolean
}

View File

@ -1,6 +1,6 @@
import type { LocaleData } from 'vuepress/core'
import type { NotesDataOptions } from '@vuepress-plume/plugin-notes-data'
import type { SocialLink, SocialLinkIconUnion, ThemeOutline } from '../base.js'
import type { SocialLink, SocialLinkIconUnion, ThemeOutline, ThemeTransition } from '../base.js'
import type { PlumeThemeBlog } from '../blog.js'
import type { NavItem } from '../navbar.js'
@ -103,6 +103,13 @@ export interface PlumeThemeLocaleData extends LocaleData {
*/
aside?: boolean | 'left'
/**
*
*
* @default true
*/
transition?: boolean | ThemeTransition
/**
*
*/
@ -119,9 +126,9 @@ export interface PlumeThemeLocaleData extends LocaleData {
selectLanguageName?: string
/**
*
*
* "编辑此页"
*
* @default true
*/
editLink?: boolean