valaxy-theme-yun 0.13.11 → 0.14.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.
@@ -5,7 +5,7 @@
5
5
  * @description https://github.com/YunYouJun/hexo-theme-yun
6
6
  */
7
7
 
8
- import { CSSProperties, computed } from 'vue'
8
+ import { CSSProperties, computed, onMounted, ref } from 'vue'
9
9
  import { random } from 'valaxy'
10
10
  import { useThemeConfig } from '../composables'
11
11
 
@@ -22,16 +22,20 @@ const chars = computed(() => {
22
22
  // height of top/bottom line
23
23
  const lineH = computed(() => chars.value.reduce((a, b) => a + b, 0) / 2)
24
24
 
25
- const lineStyle = computed(() => (
26
- {
27
- '--banner-line-height': `calc(var(--app-height, 100vh) / 2 - ${lineH.value}rem)`,
25
+ const bannerStyles = ref()
26
+ onMounted(() => {
27
+ bannerStyles.value = {
28
+ '--banner-height': `${window.innerHeight}px`,
29
+ '--banner-line-height': `calc(var(--banner-height, 100vh) / 2 - ${lineH.value}rem)`,
28
30
  } as CSSProperties
29
- ))
31
+ })
30
32
  </script>
31
33
 
32
34
  <template>
33
- <div id="banner" :style="lineStyle">
34
- <div class="banner-line vertical-line-top" :style="lineStyle" />
35
+ <div id="banner" :style="bannerStyles">
36
+ <div class="banner-line-container">
37
+ <div class="banner-line vertical-line-top" />
38
+ </div>
35
39
  <div class="banner-char-container">
36
40
  <div v-for="c, i in themeConfig.banner.title" :key="i" class="char-box">
37
41
  <span
@@ -45,11 +49,12 @@ const lineStyle = computed(() => (
45
49
  </span>
46
50
  </div>
47
51
  </div>
48
- <div class="banner-line vertical-line-bottom" :style="lineStyle" />
52
+ <div class="banner-line-container bottom">
53
+ <div class="banner-line vertical-line-bottom" />
54
+ </div>
55
+ <YunCloud v-if="themeConfig.banner.cloud?.enable" />
56
+ <YunGoDown />
49
57
  </div>
50
-
51
- <YunGoDown />
52
- <YunCloud v-if="themeConfig.banner.cloud?.enable" />
53
58
  </template>
54
59
 
55
60
  <style lang="scss">
@@ -8,7 +8,6 @@ const props = withDefaults(defineProps<{
8
8
  * 当前层级
9
9
  */
10
10
  level?: number
11
- displayCategory?: (category: string) => void
12
11
  collapsable?: boolean
13
12
  }>(), {
14
13
  level: 0,
@@ -19,8 +18,13 @@ const collapsable = ref(props.collapsable)
19
18
  </script>
20
19
 
21
20
  <template>
22
- <ul v-for="category, key in Object.fromEntries(categories)" :key="key" class="category-list" m="l-4">
23
- <YunCategory :name="key.toString()" :category="category" :level="level + 1" :display-category="displayCategory" :collapsable="collapsable" />
21
+ <ul v-for="category in categories" :key="category.name" class="category-list" m="l-4">
22
+ <YunCategory
23
+ :parent-key="category.name"
24
+ :category="category"
25
+ :level="level + 1"
26
+ :collapsable="collapsable"
27
+ />
24
28
  </ul>
25
29
  </template>
26
30
 
@@ -1,15 +1,15 @@
1
1
  <script lang="ts" setup>
2
- import { ref } from 'vue'
2
+ import { onMounted, ref } from 'vue'
3
3
  import type { Category, Post } from 'valaxy'
4
- import { isParentCategory } from 'valaxy'
4
+ import { isCategoryList, useInvisibleElement } from 'valaxy'
5
5
  import { useI18n } from 'vue-i18n'
6
+ import { useRouter } from 'vue-router'
6
7
 
7
- const props = withDefaults(defineProps<{
8
- name: string
8
+ withDefaults(defineProps<{
9
+ parentKey: string
9
10
  // to eliminate the warning
10
11
  category: Category
11
12
  level?: number
12
- displayCategory?: (category: string) => void
13
13
 
14
14
  /**
15
15
  * collapse children
@@ -19,34 +19,70 @@ const props = withDefaults(defineProps<{
19
19
  collapsable: true,
20
20
  })
21
21
 
22
- const collapsable = ref(props.collapsable)
23
- const { t, locale } = useI18n()
22
+ const router = useRouter()
24
23
 
24
+ const collapse = ref(true)
25
+ const { t } = useI18n()
26
+
27
+ /**
28
+ * i18n
29
+ */
30
+ const { locale } = useI18n()
25
31
  const getTitle = (post: Post | any) => {
26
32
  const lang = locale.value === 'zh-CN' ? 'zh' : locale.value
27
33
  return post[`title_${lang}`] ? post[`title_${lang}`] : post.title
28
34
  }
35
+
36
+ const postCollapseElRef = ref<HTMLElement>()
37
+ const { show } = useInvisibleElement(postCollapseElRef)
38
+ /**
39
+ * scroll to post collapse by category
40
+ * @param category
41
+ */
42
+ const jumpToDisplayCategory = (category: string) => {
43
+ router.push({
44
+ query: {
45
+ category,
46
+ },
47
+ })
48
+
49
+ show()
50
+ }
51
+
52
+ onMounted(() => {
53
+ const postCollapseEl = document.querySelector('.post-collapse-container') as HTMLElement
54
+ if (postCollapseEl)
55
+ postCollapseElRef.value = postCollapseEl
56
+ })
29
57
  </script>
30
58
 
31
59
  <template>
32
- <li v-if="category.total" class="category-list-item inline-flex items-center cursor-pointer">
33
- <span class="folder-action inline-flex" @click="collapsable = !collapsable">
34
- <div v-if="collapsable" i-ri-folder-add-line />
60
+ <li class="category-list-item inline-flex items-center cursor-pointer">
61
+ <span class="folder-action inline-flex" @click="collapse = !collapse">
62
+ <div v-if="collapse" i-ri-folder-add-line />
35
63
  <div v-else style="color:var(--va-c-primary)" i-ri-folder-reduce-line /></span>
36
- <span class="category-name" m="l-1" @click="displayCategory ? displayCategory(name) : null">
37
- {{ name === 'Uncategorized' ? t('category.uncategorized') : name }} [{{ category.total }}]
64
+ <span class="category-name" m="l-1" @click="jumpToDisplayCategory(parentKey)">
65
+ {{ category.name === 'Uncategorized' ? t('category.uncategorized') : category.name }} [{{ category.total }}]
38
66
  </span>
39
67
  </li>
40
68
 
41
- <template v-if="!collapsable">
42
- <ul v-if="!isParentCategory(category)">
43
- <li v-for="post, i in category.posts" :key="i" class="post-list-item" m="l-4">
44
- <router-link v-if="post.title" :to="post.path || ''" class="inline-flex items-center">
45
- <div i-ri-file-text-line />
46
- <span m="l-1" font="serif black">{{ getTitle(post) }}</span>
47
- </router-link>
69
+ <template v-if="!collapse">
70
+ <ul>
71
+ <li v-for="categoryItem, i in category.children" :key="i" class="post-list-item" m="l-4">
72
+ <template v-if="isCategoryList(categoryItem)">
73
+ <YunCategory
74
+ :parent-key="parentKey ? `${parentKey}/${categoryItem.name}` : categoryItem.name"
75
+ :category="categoryItem"
76
+ />
77
+ </template>
78
+
79
+ <template v-else>
80
+ <router-link v-if="categoryItem.title" :to="categoryItem.path || ''" class="inline-flex items-center">
81
+ <div i-ri-file-text-line />
82
+ <span m="l-1" font="serif black">{{ getTitle(categoryItem) }}</span>
83
+ </router-link>
84
+ </template>
48
85
  </li>
49
86
  </ul>
50
- <YunCategories v-else :categories="category.children" :display-category="displayCategory" :collapsable="collapsable" />
51
87
  </template>
52
88
  </template>
@@ -38,7 +38,8 @@ const { icon, styles } = usePostProperty(props.post.type)
38
38
 
39
39
  <YunPostMeta :frontmatter="post" />
40
40
 
41
- <div v-if="post.excerpt" class="markdown-body" text="left" w="full" p="x-6 lt-sm:4" v-html="post.excerpt" />
41
+ <div v-if="post.excerpt_type === 'text'" py="1" />
42
+ <div v-if="post.excerpt" class="markdown-body" text="left" w="full" p="x-6 lt-sm:4 y-1" v-html="post.excerpt" />
42
43
  <div m="b-5" />
43
44
 
44
45
  <a
@@ -57,7 +58,7 @@ const { icon, styles } = usePostProperty(props.post.type)
57
58
  <!-- always show -->
58
59
  <div w="full" class="yun-card-actions flex justify-between" border="t" text="sm">
59
60
  <div class="inline-flex">
60
- <YunPostCategories :categories="post.categories" />
61
+ <YunPostCategories m="l-2" :categories="post.categories" />
61
62
  </div>
62
63
 
63
64
  <div class="post-tags inline-flex" m="r-2">
@@ -12,7 +12,7 @@ defineProps<{
12
12
  path: '/categories/',
13
13
  query: { category: Array.isArray(categories) ? categories[categories.length - 1] : categories },
14
14
  }"
15
- class="post-categories inline-flex justify-center items-center" m="l-2"
15
+ class="post-categories inline-flex justify-center items-center"
16
16
  >
17
17
  <div m="x-1" i-ri-folder-2-line />
18
18
  {{ Array.isArray(categories) ? categories.join(' > ') : categories }}
@@ -11,20 +11,22 @@ const props = defineProps<{
11
11
  const { t } = useI18n()
12
12
 
13
13
  const years = ref<number[]>([])
14
- const postList = ref<Record<string, Post[]>>({})
14
+ const postListByYear = ref<Record<string, Post[]>>({})
15
15
 
16
16
  watch(() => props.posts, () => {
17
- postList.value = {}
17
+ postListByYear.value = {}
18
18
  years.value = []
19
19
  props.posts.forEach((post) => {
20
+ if (post.hide && post.hide !== 'index')
21
+ return
20
22
  if (post.date) {
21
23
  const year = parseInt(formatDate(post.date, 'YYYY'))
22
- if (postList.value[year]) {
23
- postList.value[year].push(post)
24
+ if (postListByYear.value[year]) {
25
+ postListByYear.value[year].push(post)
24
26
  }
25
27
  else {
26
28
  years.value.push(year)
27
- postList.value[year] = [post]
29
+ postListByYear.value[year] = [post]
28
30
  }
29
31
  }
30
32
  })
@@ -58,7 +60,7 @@ const sortedYears = computed(() => {
58
60
  </h2>
59
61
  </div>
60
62
 
61
- <article v-for="post, j in sortByDate(postList[year], isDesc)" :key="j" class="post-item">
63
+ <article v-for="post, j in sortByDate(postListByYear[year], isDesc)" :key="j" class="post-item">
62
64
  <header class="post-header">
63
65
  <div class="post-meta">
64
66
  <time v-if="post.date" class="post-time" font="mono" opacity="80">{{ formatDate(post.date, 'MM-DD') }}</time>
@@ -4,6 +4,7 @@ import { formatDate } from 'valaxy'
4
4
  import { useI18n } from 'vue-i18n'
5
5
 
6
6
  defineProps<{
7
+ // FrontMatter
7
8
  frontmatter: Post
8
9
  }>()
9
10
 
@@ -14,7 +15,11 @@ const { t } = useI18n()
14
15
  <div v-if="frontmatter.draft" class="post-draft-icon" title="draft">
15
16
  <div i-ri-draft-line />
16
17
  </div>
17
- <div v-if="frontmatter.top" class="post-top-icon">
18
+ <div v-if="frontmatter.hide" class="post-top-icon" color="$va-c-danger" :title="`hide:${frontmatter.hide}`">
19
+ <div v-if="frontmatter.hide === 'index'" i-ri-eye-close-line />
20
+ <div v-else i-ri-eye-off-line />
21
+ </div>
22
+ <div v-if="frontmatter.top" class="post-top-icon" color="$va-c-warning">
18
23
  <div i-ri-pushpin-line />
19
24
  </div>
20
25
 
@@ -52,7 +57,6 @@ const { t } = useI18n()
52
57
  position: absolute;
53
58
  top: 1rem;
54
59
  right: 1rem;
55
- color: var(--va-c-warning);
56
60
  font-size: 1.2rem;
57
61
  }
58
62
  </style>
@@ -7,7 +7,10 @@ defineProps<{
7
7
  </script>
8
8
 
9
9
  <template>
10
- <router-link v-for="tag, i in tags" :key="i" :to="{ path: '/tags/', query: { tag } }" m="x-1" class="post-tag inline-flex justify-center items-center">
10
+ <router-link
11
+ v-for="tag, i in tags" :key="i" :to="{ path: '/tags/', query: { tag } }" m="x-1"
12
+ class="post-tag inline-flex-center"
13
+ >
11
14
  <div m="r-1" i-ri-price-tag-3-line />
12
15
  {{ tag }}
13
16
  </router-link>
@@ -1,18 +1,17 @@
1
1
  <script lang="ts" setup>
2
- import { computed, ref } from 'vue'
3
- import { useCategory, useFrontmatter, useInvisibleElement, usePostTitle, useSiteStore } from 'valaxy'
2
+ import { computed } from 'vue'
3
+ import { useCategory, useFrontmatter, usePostTitle, useSiteStore } from 'valaxy'
4
4
  import { useI18n } from 'vue-i18n'
5
- import { useRoute, useRouter } from 'vue-router'
5
+ import { useRoute } from 'vue-router'
6
6
 
7
7
  const { t } = useI18n()
8
8
 
9
9
  const site = useSiteStore()
10
-
11
10
  const frontmatter = useFrontmatter()
12
- const categories = useCategory()
13
11
 
14
12
  const route = useRoute()
15
13
  const curCategory = computed(() => (route.query.category as string || ''))
14
+ const categories = useCategory()
16
15
 
17
16
  const posts = computed(() => {
18
17
  const list = site.postList.filter((post) => {
@@ -20,7 +19,7 @@ const posts = computed(() => {
20
19
  if (typeof post.categories === 'string')
21
20
  return post.categories === curCategory.value
22
21
  else
23
- return post.categories.includes(curCategory.value)
22
+ return post.categories.join('/').startsWith(curCategory.value) && post.categories[0] === curCategory.value.split('/')[0]
24
23
  }
25
24
  if (!post.categories && curCategory.value === 'Uncategorized')
26
25
  return post.categories === undefined
@@ -29,20 +28,6 @@ const posts = computed(() => {
29
28
  return list
30
29
  })
31
30
 
32
- const collapse = ref()
33
- const { show } = useInvisibleElement(collapse)
34
-
35
- const router = useRouter()
36
- const displayCategory = (category: string) => {
37
- router.push({
38
- query: {
39
- category,
40
- },
41
- })
42
-
43
- show()
44
- }
45
-
46
31
  const title = usePostTitle(frontmatter)
47
32
  </script>
48
33
 
@@ -57,15 +42,15 @@ const title = usePostTitle(frontmatter)
57
42
  </template>
58
43
  <template #main-content>
59
44
  <div text="center" class="yun-text-light" p="2">
60
- {{ t('counter.categories', categories.children!.size) }}
45
+ {{ t('counter.categories', categories.children.length) }}
61
46
  </div>
62
- <YunCategories :categories="categories.children!" :display-category="displayCategory" />
47
+ <YunCategories :categories="categories.children" />
63
48
  <router-view />
64
49
  </template>
65
50
 
66
51
  <template #main-nav-before>
67
- <YunCard v-if="curCategory" ref="collapse" m="t-4" w="full">
68
- <YunPageHeader :title="curCategory === 'Uncategorized' ? t('category.uncategorized') : curCategory" icon="i-ri-folder-open-line" />
52
+ <YunCard v-if="curCategory" class="post-collapse-container" m="t-4" w="full">
53
+ <YunPageHeader :title="curCategory === 'Uncategorized' ? t('category.uncategorized') : curCategory.split('/').join(' / ')" icon="i-ri-folder-open-line" />
69
54
  <YunPostCollapse w="full" m="b-4" p="x-20 lt-sm:x-5" :posts="posts" />
70
55
  </YunCard>
71
56
  </template>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "valaxy-theme-yun",
3
- "version": "0.13.11",
3
+ "version": "0.14.0",
4
4
  "author": {
5
5
  "email": "me@yunyoujun.cn",
6
6
  "name": "YunYouJun",
@@ -22,6 +22,6 @@
22
22
  "valaxy-addon-waline": "0.0.9"
23
23
  },
24
24
  "devDependencies": {
25
- "valaxy": "0.13.11"
25
+ "valaxy": "0.14.0"
26
26
  }
27
27
  }
@@ -40,4 +40,8 @@ html.dark {
40
40
  img {
41
41
  margin: auto;
42
42
  }
43
+
44
+ p {
45
+ overflow: unset;
46
+ }
43
47
  }