valaxy-theme-yun 0.18.9 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/App.vue CHANGED
@@ -4,6 +4,8 @@ import { useAppStore, useSiteConfig } from 'valaxy'
4
4
  import { onMounted } from 'vue'
5
5
  import { useThemeConfig } from './composables'
6
6
 
7
+ const appStore = useAppStore()
8
+
7
9
  useHead({
8
10
  link: [
9
11
  {
@@ -11,6 +13,17 @@ useHead({
11
13
  href: 'https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@900&display=swap',
12
14
  },
13
15
  ],
16
+
17
+ meta: [
18
+ {
19
+ name: 'theme-color',
20
+ content: appStore.themeColor,
21
+ },
22
+ {
23
+ name: 'msapplication-TileColor',
24
+ content: appStore.themeColor,
25
+ },
26
+ ],
14
27
  })
15
28
 
16
29
  const siteConfig = useSiteConfig()
@@ -1,10 +1,9 @@
1
1
  <script lang="ts" setup>
2
2
  import { computed, nextTick } from 'vue'
3
3
  import type { PageData, Post } from 'valaxy'
4
- import { onContentUpdated, usePostTitle, useSiteConfig } from 'valaxy'
4
+ import { onClickHref, onContentUpdated, scrollTo, usePostTitle, useSiteConfig } from 'valaxy'
5
5
  import type { StyleValue } from 'vue'
6
6
  import { useRoute, useRouter } from 'vue-router'
7
- import { scrollTo } from '../utils'
8
7
  import { usePostProperty } from '../composables'
9
8
 
10
9
  const props = defineProps<{
@@ -25,48 +24,15 @@ const router = useRouter()
25
24
  nextTick(() => {
26
25
  if (route.hash) {
27
26
  setTimeout(() => {
28
- scrollTo(document.body, route.hash, true)
27
+ scrollTo(document.body, route.hash, {
28
+ smooth: true,
29
+ })
29
30
  }, 0)
30
31
  }
31
32
  })
32
33
 
33
34
  onContentUpdated(() => {
34
- // to extract
35
- // click title scroll
36
- window.addEventListener(
37
- 'click',
38
- async (e) => {
39
- const link = (e.target as Element).closest('a')
40
- if (link) {
41
- const { protocol, hostname, pathname, hash, target } = link
42
- const currentUrl = window.location
43
- const extMatch = pathname.match(/\.\w+$/)
44
- // only intercept inbound links
45
- if (
46
- !e.ctrlKey
47
- && !e.shiftKey
48
- && !e.altKey
49
- && !e.metaKey
50
- && target !== '_blank'
51
- && protocol === currentUrl.protocol
52
- && hostname === currentUrl.hostname
53
- && !(extMatch && extMatch[0] !== '.html')
54
- ) {
55
- if (pathname === currentUrl.pathname) {
56
- e.preventDefault()
57
- // scroll between hash anchors in the same page
58
- if (hash && hash !== currentUrl.hash) {
59
- await router.push({ hash: decodeURIComponent(hash) })
60
-
61
- // use smooth scroll when clicking on header anchor links
62
- scrollTo(link, hash, link.classList.contains('header-anchor'))
63
- }
64
- }
65
- }
66
- }
67
- },
68
- { capture: true },
69
- )
35
+ onClickHref(router)
70
36
  })
71
37
  </script>
72
38
 
@@ -80,8 +46,10 @@ onContentUpdated(() => {
80
46
  <YunPageHeader
81
47
  class="mb-2"
82
48
  :title="title"
83
- :icon="frontmatter.icon || icon" :color="frontmatter.color || color"
49
+ :icon="frontmatter.icon || icon"
50
+ :color="frontmatter.color || color"
84
51
  :cover="frontmatter.cover"
52
+ :page-title-class="frontmatter.pageTitleClass"
85
53
  />
86
54
  </slot>
87
55
  <slot name="main-header-after" />
@@ -1,9 +1,10 @@
1
1
  <script lang="ts" setup>
2
2
  import { computed, watch } from 'vue'
3
3
  import { useCssVar } from '@vueuse/core'
4
- import { isDark } from 'valaxy'
4
+ import { useAppStore } from 'valaxy'
5
5
  import { useThemeConfig } from '../composables'
6
6
 
7
+ const appStore = useAppStore()
7
8
  const themeConfig = useThemeConfig()
8
9
 
9
10
  if (typeof themeConfig.value.bg_image.url !== 'undefined') {
@@ -12,7 +13,7 @@ if (typeof themeConfig.value.bg_image.url !== 'undefined') {
12
13
  bgImgOpacity.value = themeConfig.value.bg_image.opacity.toString() || '1'
13
14
 
14
15
  const bgImgUrl = computed(() => {
15
- return isDark.value
16
+ return appStore.isDark
16
17
  ? themeConfig.value.bg_image.dark
17
18
  : themeConfig.value.bg_image.url
18
19
  })
@@ -1,18 +1,25 @@
1
1
  <script lang="ts" setup>
2
2
  import { useI18n } from 'vue-i18n'
3
3
  import { computed } from 'vue'
4
- import { isDark, toggleDarkWithTransition } from 'valaxy'
4
+ import { useAppStore } from 'valaxy'
5
5
 
6
+ const appStore = useAppStore()
6
7
  const { t } = useI18n()
7
8
 
8
9
  const themeTitle = computed(() => {
9
- return isDark.value ? t('button.toggle_light') : t('button.toggle_dark')
10
+ return appStore.isDark ? t('button.toggle_light') : t('button.toggle_dark')
11
+ })
12
+
13
+ const styles = computed(() => {
14
+ return {
15
+ color: appStore.isDark ? '' : '#f1cb64',
16
+ }
10
17
  })
11
18
  </script>
12
19
 
13
20
  <template>
14
21
  <div>
15
- <button class="yun-icon-btn" :title="themeTitle" :style="{ color: isDark ? '' : '#f1cb64' }" @click="toggleDarkWithTransition">
22
+ <button class="yun-icon-btn" :title="themeTitle" :style="styles" @click="appStore.toggleDarkWithTransition">
16
23
  <div i="ri-sun-line dark:ri-moon-line" />
17
24
  </button>
18
25
 
@@ -1,21 +1,20 @@
1
1
  <script lang="ts" setup>
2
- import { computed } from 'vue'
2
+ import { computed, ref, watch } from 'vue'
3
3
  import { useFrontmatter } from 'valaxy'
4
4
  import { useI18n } from 'vue-i18n'
5
5
 
6
6
  import { differenceInMilliseconds, formatDistanceToNow } from 'date-fns'
7
7
 
8
8
  const fm = useFrontmatter()
9
- const { t } = useI18n()
9
+ const { t, locale } = useI18n()
10
10
 
11
11
  const updated = computed(() => fm.value.updated || fm.value.date || new Date())
12
- const ago = computed(() => {
12
+ const ago = ref('')
13
+
14
+ watch(locale, () => {
13
15
  const fromNow = formatDistanceToNow(updated.value, { addSuffix: true })
14
- if (/^\d/.test(fromNow))
15
- return ` ${fromNow}`
16
- else
17
- return fromNow
18
- })
16
+ ago.value = /^\d/.test(fromNow) ? ` ${fromNow}` : fromNow
17
+ }, { immediate: true })
19
18
 
20
19
  /**
21
20
  * when the post is updated more than 180 days ago, show a warning
@@ -1,5 +1,9 @@
1
1
  <script lang="ts" setup>
2
2
  defineProps<{
3
+ pageTitleClass?: string
4
+ /**
5
+ * @deprecated Use `pageTitleClass` instead
6
+ */
3
7
  color?: string
4
8
  icon?: string
5
9
  title?: string
@@ -10,7 +14,9 @@ defineProps<{
10
14
  <header class="post-header" m="t-16 sm:t-6">
11
15
  <h1
12
16
  class="post-title flex-center" p="2" text="2xl center"
13
- font="serif black" :style="`color:${color}`"
17
+ font="serif black"
18
+ :style="`color:${color}`"
19
+ :class="pageTitleClass"
14
20
  >
15
21
  <div v-if="icon" class="icon" m="r-1 t-1px" inline-flex :class="icon" />
16
22
  <span inline-flex class="leading-none">{{ title }}</span>
@@ -31,9 +31,11 @@ const { icon, styles } = usePostProperty(props.post.type)
31
31
  class="post-title-link cursor-pointer"
32
32
  :to="post.path || ''"
33
33
  m="t-3"
34
+ :class="post.postTitleClass"
34
35
  >
35
36
  <div class="flex-center title text-2xl" text="center" font="serif black">
36
- <div v-if="post.type" class="inline-flex" m="r-1" :class="icon" />{{ post.title }}
37
+ <div v-if="post.type" class="inline-flex" m="r-1" :class="icon" />
38
+ <span>{{ post.title }}</span>
37
39
  </div>
38
40
  </AppLink>
39
41
 
@@ -1,5 +1,6 @@
1
1
  <script lang="ts" setup>
2
2
  import type { Post } from 'valaxy'
3
+ import { formatISO } from 'date-fns'
3
4
  import { formatDate, useSiteConfig } from 'valaxy'
4
5
  import { useI18n } from 'vue-i18n'
5
6
 
@@ -30,14 +31,14 @@ const siteConfig = useSiteConfig()
30
31
  flex="~ col" justify="center" items="center" text="sm" py="1"
31
32
  >
32
33
  <div v-if="frontmatter.date" class="post-time flex items-center">
33
- <span class="posted-time inline-flex-center" :title="t('post.posted') + frontmatter.date">
34
+ <span class="posted-time inline-flex-center" :title="t('post.posted') + formatISO(frontmatter.date)">
34
35
  <div class="inline-block" i-ri-calendar-line />
35
36
  <time m="l-1">{{ formatDate(frontmatter.date) }}</time>
36
37
  </span>
37
38
 
38
39
  <span
39
40
  v-if="frontmatter.updated && frontmatter.updated !== frontmatter.date"
40
- class="edited-time inline-flex-center" :title="t('post.edited') + frontmatter.updated"
41
+ class="edited-time inline-flex-center" :title="t('post.edited') + formatISO(frontmatter.updated)"
41
42
  >
42
43
  <span m="x-2">-</span>
43
44
  <div i-ri-calendar-2-line />
@@ -1,28 +1,31 @@
1
1
  <script lang="ts" setup>
2
2
  import { ref } from 'vue'
3
- import { useAppStore } from 'valaxy'
3
+ import { useYunAppStore } from '../stores'
4
4
 
5
5
  defineProps<{
6
6
  showHamburger?: boolean
7
7
  }>()
8
8
 
9
- const app = useAppStore()
9
+ const yunApp = useYunAppStore()
10
10
  const showOverview = ref(false)
11
11
  </script>
12
12
 
13
13
  <template>
14
- <ValaxyOverlay class="md:hidden" :show="app.isSidebarOpen" @click="app.toggleSidebar()" />
14
+ <ValaxyOverlay class="md:hidden" :show="yunApp.leftSidebar.isOpen" @click="yunApp.leftSidebar.toggle()" />
15
15
 
16
16
  <ValaxyHamburger
17
- :active="app.isSidebarOpen"
17
+ :active="yunApp.leftSidebar.isOpen"
18
18
  class="menu-btn sidebar-toggle yun-icon-btn leading-4 fixed left-0.8rem top-0.6rem"
19
19
  inline-flex cursor="pointer" z="$yun-z-menu-btn"
20
- :class="showHamburger ? '' : 'md:hidden'" @click="app.toggleSidebar()"
20
+ :class="showHamburger ? '' : 'md:hidden'" @click="yunApp.leftSidebar.toggle()"
21
21
  />
22
22
 
23
23
  <aside
24
24
  class="va-card transition sidebar fixed inset-y-0 left-0 overflow-y-auto"
25
- :class="[app.isSidebarOpen && 'open', !showHamburger && 'md:translate-x-0']"
25
+ :class="{
26
+ 'open': yunApp.leftSidebar.isOpen,
27
+ 'md:translate-x-0': !showHamburger,
28
+ }"
26
29
  text="center" bg="$yun-sidebar-bg-color contain no-repeat" z="$yun-z-sidebar"
27
30
  >
28
31
  <div v-if="$slots.default" class="sidebar-nav" m="t-6">
@@ -9,7 +9,8 @@ const themeConfig = useThemeConfig()
9
9
  <AppLink
10
10
  v-for="item, i in themeConfig.pages" :key="i"
11
11
  class="link-item yun-icon-btn" inline-flex
12
- :to="item.url" :title="item.name" :style="`color:${item.color}`"
12
+ :to="item.url" :title="item.name"
13
+ :style="`color:${item.color}`"
13
14
  >
14
15
  <div :class="item.icon" class="icon w-8 h-8" />
15
16
  </AppLink>
@@ -28,7 +28,12 @@ const albums = computed(() => frontmatter.value.albums || [])
28
28
  <RouterView v-slot="{ Component }">
29
29
  <component :is="Component">
30
30
  <template #main-header>
31
- <YunPageHeader :title="title || t('title.album')" :icon="frontmatter.icon || 'i-ri-gallery-line'" :color="frontmatter.color" />
31
+ <YunPageHeader
32
+ :title="title || t('title.album')"
33
+ :icon="frontmatter.icon || 'i-ri-gallery-line'"
34
+ :color="frontmatter.color"
35
+ :page-title-class="frontmatter.pageTitleClass"
36
+ />
32
37
  </template>
33
38
  <template #main-content>
34
39
  <div text="center" class="yun-text-light" p="2">
@@ -26,7 +26,12 @@ useSchemaOrg([
26
26
  <RouterView v-slot="{ Component }">
27
27
  <component :is="Component">
28
28
  <template #main-header>
29
- <YunPageHeader :title="title || t('menu.archives')" :icon="frontmatter.icon || 'i-ri-archive-line'" :color="frontmatter.color" />
29
+ <YunPageHeader
30
+ :title="title || t('menu.archives')"
31
+ :icon="frontmatter.icon || 'i-ri-archive-line'"
32
+ :color="frontmatter.color"
33
+ :page-title-class="frontmatter.pageTitleClass"
34
+ />
30
35
  </template>
31
36
  <template #main-content>
32
37
  <RouterView />
@@ -51,6 +51,7 @@ useSchemaOrg([
51
51
  :title="title || t('menu.categories')"
52
52
  :icon="frontmatter.icon || 'i-ri-folder-2-line'"
53
53
  :color="frontmatter.color"
54
+ :page-title-class="frontmatter.pageTitleClass"
54
55
  />
55
56
  </template>
56
57
  <template #main-content>
@@ -41,6 +41,7 @@ const YunGallery = runtimeConfig.value.addons['valaxy-addon-lightgallery']
41
41
  :title="title || t('title.gallery')"
42
42
  :icon="frontmatter.icon || 'i-ri-gallery-line'"
43
43
  :color="frontmatter.color"
44
+ :page-title-class="frontmatter.pageTitleClass"
44
45
  />
45
46
  </template>
46
47
  <template #main-content>
package/layouts/home.vue CHANGED
@@ -1,10 +1,11 @@
1
1
  <script lang="ts" setup>
2
- import { useAppStore, useLayout } from 'valaxy'
2
+ import { useLayout } from 'valaxy'
3
3
  import { computed } from 'vue'
4
4
  import { useRoute } from 'vue-router'
5
5
  import { useThemeConfig } from '../composables'
6
+ import { useYunAppStore } from '../stores'
6
7
 
7
- const app = useAppStore()
8
+ const yunApp = useYunAppStore()
8
9
  const isHome = useLayout('home')
9
10
  const themeConfig = useThemeConfig()
10
11
 
@@ -20,7 +21,7 @@ const showNotice = computed(() => {
20
21
  <template>
21
22
  <main
22
23
  class="yun-main flex-center"
23
- :class="(isHome && !app.isSidebarOpen) ? 'pl-0' : 'md:pl-$va-sidebar-width'" flex="~ col" w="full"
24
+ :class="(isHome && !yunApp.leftSidebar.isOpen) ? 'pl-0' : 'md:pl-$va-sidebar-width'" flex="~ col" w="full"
24
25
  >
25
26
  <YunSidebar :show-hamburger="true" />
26
27
 
package/layouts/tags.vue CHANGED
@@ -70,6 +70,7 @@ const title = usePostTitle(frontmatter)
70
70
  :title="title || t('menu.tags')"
71
71
  :icon="frontmatter.icon || 'i-ri-tag-line'"
72
72
  :color="frontmatter.color"
73
+ :page-title-class="frontmatter.pageTitleClass"
73
74
  />
74
75
  </template>
75
76
  <template #main-content>
package/node/config.ts CHANGED
@@ -4,6 +4,10 @@ import type { ThemeConfig, UserThemeConfig } from '../types'
4
4
  * Default Config
5
5
  */
6
6
  export const defaultThemeConfig: ThemeConfig = {
7
+ valaxyDarkOptions: {
8
+ circleTransition: true,
9
+ },
10
+
7
11
  outlineTitle: 'On this page',
8
12
  colors: {
9
13
  primary: '#0078E7',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "valaxy-theme-yun",
3
- "version": "0.18.9",
3
+ "version": "0.19.0",
4
4
  "author": {
5
5
  "email": "me@yunyoujun.cn",
6
6
  "name": "YunYouJun",
@@ -20,12 +20,12 @@
20
20
  "dependencies": {
21
21
  "@explosions/fireworks": "^0.0.2",
22
22
  "@iconify-json/ant-design": "^1.1.16",
23
- "@iconify-json/simple-icons": "^1.1.106",
23
+ "@iconify-json/simple-icons": "^1.1.108",
24
24
  "animejs": "^3.2.2"
25
25
  },
26
26
  "devDependencies": {
27
27
  "@types/animejs": "^3.1.12",
28
- "valaxy": "0.18.9",
28
+ "valaxy": "0.19.0",
29
29
  "valaxy-addon-waline": "0.1.4"
30
30
  }
31
31
  }
package/setup/main.ts CHANGED
@@ -1,5 +1,17 @@
1
- import { defineAppSetup } from 'valaxy'
1
+ import { defineAppSetup, useAppStore } from 'valaxy'
2
+ import { nextTick } from 'vue'
3
+ import { useYunAppStore } from '../stores'
2
4
 
3
- export default defineAppSetup((_ctx) => {
5
+ export default defineAppSetup((ctx) => {
4
6
  // can do for setup
7
+
8
+ const { router } = ctx
9
+ const appStore = useAppStore()
10
+ const yunAppStore = useYunAppStore()
11
+ router.afterEach(() => {
12
+ nextTick(() => {
13
+ if (appStore.isMobile)
14
+ yunAppStore.leftSidebar.close()
15
+ })
16
+ })
5
17
  })
package/stores/app.ts CHANGED
@@ -1,9 +1,13 @@
1
1
  import { acceptHMRUpdate, defineStore } from 'pinia'
2
+ import { useDynamicLeftSidebar } from 'valaxy'
2
3
 
3
4
  export const useYunAppStore = defineStore('yun-app', () => {
4
5
  // global cache for yun
6
+ const leftSidebar = useDynamicLeftSidebar()
5
7
 
6
- return {}
8
+ return {
9
+ leftSidebar,
10
+ }
7
11
  })
8
12
 
9
13
  if (import.meta.hot)
@@ -0,0 +1 @@
1
+ export * from './app'
package/types/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import type { DefaultTheme } from 'valaxy/types'
2
+
1
3
  export * from '../composables'
2
4
 
3
5
  export namespace YunTheme {
@@ -27,15 +29,28 @@ export namespace YunTheme {
27
29
 
28
30
  export interface Page {
29
31
  name: string
32
+ /**
33
+ * @description:en-US Page URL
34
+ * @description:zh-CN 页面链接
35
+ */
30
36
  url: string
37
+ /**
38
+ * @see https://valaxy.site/guide/features#icones
39
+ * @description:en-US Icon of page
40
+ * @description:zh-CN 页面图标
41
+ */
31
42
  icon: string
43
+ /**
44
+ * @description:en-US Color of icon
45
+ * @description:zh-CN 图标颜色
46
+ */
32
47
  color: string
33
48
  }
34
49
 
35
50
  /**
36
51
  * Theme Config
37
52
  */
38
- export interface ThemeConfig {
53
+ export interface ThemeConfig extends DefaultTheme.Config {
39
54
  /**
40
55
  * toc title
41
56
  * @default 'On this page'
package/utils/index.ts CHANGED
@@ -9,35 +9,3 @@ export function onImgError(e: Event, defaultImg = noneImg) {
9
9
  targetEl.setAttribute('data-src', targetEl.src)
10
10
  targetEl.src = defaultImg
11
11
  }
12
-
13
- export function scrollTo(el: HTMLElement, hash: string, smooth = false) {
14
- let target: Element | null = null
15
- try {
16
- target = el.classList.contains('header-anchor')
17
- ? el
18
- : ((decodeURIComponent(hash) && document.querySelector(decodeURIComponent(hash))) || null)
19
- }
20
- catch (e) {
21
- console.warn(e)
22
- }
23
-
24
- if (target) {
25
- const targetPadding = -64
26
- const targetTop
27
- = window.scrollY
28
- + (target as HTMLElement).getBoundingClientRect().top
29
- + targetPadding
30
-
31
- // only smooth scroll if distance is smaller than screen height.
32
- if (!smooth || Math.abs(targetTop - window.scrollY) > window.innerHeight) {
33
- window.scrollTo(0, targetTop)
34
- }
35
- else {
36
- window.scrollTo({
37
- // left: 0,
38
- top: targetTop,
39
- behavior: 'smooth',
40
- })
41
- }
42
- }
43
- }