valaxy-theme-press 0.0.2 → 0.0.4

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.
Files changed (62) hide show
  1. package/client/index.ts +1 -0
  2. package/components/PressAlgoliaSearch.vue +208 -0
  3. package/components/PressArticle.vue +27 -16
  4. package/components/PressArticleCard.vue +6 -2
  5. package/components/PressAside.vue +38 -27
  6. package/components/PressBackdrop.vue +1 -1
  7. package/components/PressButton.vue +5 -12
  8. package/components/PressCategories.vue +24 -3
  9. package/components/PressCategory.vue +24 -15
  10. package/components/PressDocFooter.vue +15 -0
  11. package/components/PressDocFooterLastUpdated.vue +44 -0
  12. package/components/PressFeature.vue +1 -1
  13. package/components/PressFeatures.vue +1 -1
  14. package/components/PressFooter.vue +53 -0
  15. package/components/PressHome.vue +1 -7
  16. package/components/PressHomeFeatures.vue +1 -0
  17. package/components/PressHomeHero.vue +7 -8
  18. package/components/PressLocalNav.vue +9 -9
  19. package/components/PressNav.vue +30 -5
  20. package/components/PressNavBar.vue +94 -0
  21. package/components/PressNavBarAppearance.vue +5 -0
  22. package/components/PressNavBarHamburger.vue +79 -0
  23. package/components/PressNavBarMenu.vue +14 -0
  24. package/components/PressNavBarSearch.vue +40 -0
  25. package/components/PressNavBarSocialLinks.vue +26 -0
  26. package/components/PressNavBarTranslations.vue +5 -0
  27. package/components/PressNavItemGroup.vue +101 -0
  28. package/components/PressNavItemLink.vue +40 -0
  29. package/components/PressNavScreen.vue +95 -0
  30. package/components/PressNavScreenAppearance.vue +32 -0
  31. package/components/PressNavScreenMenu.vue +22 -0
  32. package/components/PressNavScreenMenuGroup.vue +115 -0
  33. package/components/PressNavScreenMenuGroupLink.vue +32 -0
  34. package/components/PressNavScreenMenuGroupSection.vue +37 -0
  35. package/components/PressNavScreenMenuLink.vue +33 -0
  36. package/components/PressNavScreenSocialLinks.vue +13 -0
  37. package/components/PressNavScreenTranslations.vue +7 -0
  38. package/components/{PressToc.vue → PressOutline.vue} +14 -39
  39. package/components/PressOutlineItem.vue +48 -0
  40. package/components/PressPostList.vue +3 -3
  41. package/components/PressSidebar.vue +31 -10
  42. package/components/PressSocialLink.vue +40 -0
  43. package/components/PressSocialLinks.vue +26 -0
  44. package/components/ValaxyMain.vue +60 -42
  45. package/composables/edit-link.ts +14 -0
  46. package/composables/index.ts +1 -0
  47. package/composables/nav.ts +37 -0
  48. package/config/index.ts +13 -2
  49. package/layouts/layout.vue +5 -3
  50. package/package.json +15 -5
  51. package/pages/[..all].vue +1 -0
  52. package/setup/main.ts +5 -4
  53. package/styles/css-vars.scss +16 -8
  54. package/styles/helper.scss +0 -10
  55. package/styles/markdown.scss +18 -8
  56. package/types/index.d.ts +76 -22
  57. package/utils/index.ts +9 -0
  58. package/valaxy.config.ts +7 -0
  59. package/LICENSE +0 -21
  60. package/components/DocsBoard.vue +0 -24
  61. package/components/nav/PressNavBar.vue +0 -123
  62. /package/components/{nav/PressSwitchAppearance.vue → PressSwitchAppearance.vue} +0 -0
@@ -0,0 +1 @@
1
+ export * from '../composables'
@@ -0,0 +1,208 @@
1
+ <script lang="ts" setup>
2
+ import { useI18n } from 'vue-i18n'
3
+ import { useAddonAlgolia } from 'valaxy-addon-algolia'
4
+
5
+ const { t } = useI18n()
6
+
7
+ const { loaded, load, metaKey } = useAddonAlgolia()
8
+ </script>
9
+
10
+ <template>
11
+ <div>
12
+ <AlgoliaSearchBox v-if="loaded" />
13
+
14
+ <div v-else id="docsearch" @click="load">
15
+ <button
16
+ class="DocSearch DocSearch-Button"
17
+ aria-label="Search"
18
+ >
19
+ <span class="DocSearch-Button-Container">
20
+ <svg
21
+ class="DocSearch-Search-Icon"
22
+ width="20"
23
+ height="20"
24
+ viewBox="0 0 20 20"
25
+ >
26
+ <path
27
+ d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z"
28
+ stroke="currentColor"
29
+ fill="none"
30
+ fill-rule="evenodd"
31
+ stroke-linecap="round"
32
+ stroke-linejoin="round"
33
+ />
34
+ </svg>
35
+ <span class="DocSearch-Button-Placeholder">{{ t('search.placeholder') }}</span>
36
+ </span>
37
+ <span class="DocSearch-Button-Keys">
38
+ <kbd class="DocSearch-Button-Key" />
39
+ <kbd class="DocSearch-Button-Key">K</kbd>
40
+ </span>
41
+ </button>
42
+ </div>
43
+ </div>
44
+ </template>
45
+
46
+ <style>
47
+ .DocSearch-Button {
48
+ display: flex;
49
+ justify-content: center;
50
+ align-items: center;
51
+ margin: 0;
52
+ padding: 0;
53
+ width: 32px;
54
+ height: 55px;
55
+ background: transparent;
56
+ transition: border-color 0.25s;
57
+ }
58
+
59
+ .DocSearch-Button:hover {
60
+ background: transparent;
61
+ }
62
+
63
+ .DocSearch-Button:focus {
64
+ outline: 1px dotted;
65
+ outline: 5px auto -webkit-focus-ring-color;
66
+ }
67
+
68
+ .DocSearch-Button:focus:not(:focus-visible) {
69
+ outline: none !important;
70
+ }
71
+
72
+ @media (min-width: 768px) {
73
+ .DocSearch-Button {
74
+ justify-content: flex-start;
75
+ border: 1px solid transparent;
76
+ border-radius: 8px;
77
+ padding: 0 10px 0 12px;
78
+ width: 100%;
79
+ height: 40px;
80
+ background-color: var(--va-c-bg-alt);
81
+ }
82
+
83
+ .DocSearch-Button:hover {
84
+ border-color: var(--va-c-brand);
85
+ background: var(--va-c-bg-alt);
86
+ }
87
+ }
88
+
89
+ .DocSearch-Button .DocSearch-Button-Container {
90
+ display: flex;
91
+ align-items: center;
92
+ }
93
+
94
+ .DocSearch-Button .DocSearch-Search-Icon {
95
+ position: relative;
96
+ width: 16px;
97
+ height: 16px;
98
+ color: var(--va-c-text-1);
99
+ fill: currentColor;
100
+ transition: color 0.5s;
101
+ }
102
+
103
+ .DocSearch-Button:hover .DocSearch-Search-Icon {
104
+ color: var(--va-c-text-1);
105
+ }
106
+
107
+ @media (min-width: 768px) {
108
+ .DocSearch-Button .DocSearch-Search-Icon {
109
+ top: 1px;
110
+ margin-right: 8px;
111
+ width: 14px;
112
+ height: 14px;
113
+ color: var(--va-c-text-2);
114
+ }
115
+ }
116
+
117
+ .DocSearch-Button .DocSearch-Button-Placeholder {
118
+ display: none;
119
+ margin-top: 2px;
120
+ padding: 0 16px 0 0;
121
+ font-size: 13px;
122
+ font-weight: 500;
123
+ color: var(--va-c-text-2);
124
+ transition: color 0.5s;
125
+ }
126
+
127
+ .DocSearch-Button:hover .DocSearch-Button-Placeholder {
128
+ color: var(--va-c-text-1);
129
+ }
130
+
131
+ @media (min-width: 768px) {
132
+ .DocSearch-Button .DocSearch-Button-Placeholder {
133
+ display: inline-block;
134
+ }
135
+ }
136
+
137
+ .DocSearch-Button .DocSearch-Button-Keys {
138
+ /*rtl:ignore*/
139
+ direction: ltr;
140
+ display: none;
141
+ min-width: auto;
142
+ }
143
+
144
+ @media (min-width: 768px) {
145
+ .DocSearch-Button .DocSearch-Button-Keys {
146
+ display: flex;
147
+ align-items: center;
148
+ }
149
+ }
150
+
151
+ .DocSearch-Button .DocSearch-Button-Key {
152
+ display: block;
153
+ margin: 2px 0 0 0;
154
+ border: 1px solid var(--va-c-divider);
155
+ /*rtl:begin:ignore*/
156
+ border-right: none;
157
+ border-radius: 4px 0 0 4px;
158
+ padding-left: 6px;
159
+ /*rtl:end:ignore*/
160
+ min-width: 0;
161
+ width: auto;
162
+ height: 22px;
163
+ font-family: var(--va-font-sans);
164
+ font-size: 12px;
165
+ font-weight: 500;
166
+ transition: color 0.5s, border-color 0.5s;
167
+ }
168
+
169
+ .DocSearch-Button .DocSearch-Button-Key + .DocSearch-Button-Key {
170
+ /*rtl:begin:ignore*/
171
+ border-right: 1px solid var(--va-c-divider);
172
+ border-left: none;
173
+ border-radius: 0 4px 4px 0;
174
+ padding-left: 2px;
175
+ padding-right: 6px;
176
+ /*rtl:end:ignore*/
177
+ }
178
+
179
+ .DocSearch-Button .DocSearch-Button-Key:first-child {
180
+ font-size: 1px;
181
+ letter-spacing: -12px;
182
+ color: transparent;
183
+ }
184
+
185
+ .DocSearch-Button .DocSearch-Button-Key:first-child:after {
186
+ content: v-bind(metaKey);
187
+ font-size: 12px;
188
+ letter-spacing: normal;
189
+ color: var(--docsearch-muted-color);
190
+ }
191
+
192
+ .DocSearch-Button .DocSearch-Button-Key:first-child > * {
193
+ display: none;
194
+ }
195
+
196
+ .dark .DocSearch-Footer {
197
+ border-top: 1px solid var(--va-c-divider);
198
+ }
199
+
200
+ .DocSearch-Form {
201
+ border: 1px solid var(--va-c-brand);
202
+ background-color: var(--va-c-white);
203
+ }
204
+
205
+ .dark .DocSearch-Form {
206
+ background-color: var(--va-c-bg-soft-mute);
207
+ }
208
+ </style>
@@ -2,36 +2,41 @@
2
2
  import { computed } from 'vue'
3
3
  import { useRoute } from 'vue-router'
4
4
 
5
- import { useFrontmatter, usePostList } from 'valaxy'
5
+ import { useFrontmatter, useSiteStore } from 'valaxy'
6
+ import { useI18n } from 'vue-i18n'
7
+ import { getLocaleTitle } from '../utils'
8
+
6
9
  const frontmatter = useFrontmatter()
7
10
 
8
11
  const route = useRoute()
9
- const posts = usePostList()
12
+ const site = useSiteStore()
10
13
 
11
14
  function findCurrentIndex() {
12
- return posts.value.findIndex(p => p.href === route.path)
15
+ return site.postList.findIndex(p => p.href === route.path)
13
16
  }
14
17
 
15
- const nextPost = computed(() => posts.value[findCurrentIndex() - 1])
16
- const prevPost = computed(() => posts.value[findCurrentIndex() + 1])
18
+ const nextPost = computed(() => site.postList[findCurrentIndex() - 1])
19
+ const prevPost = computed(() => site.postList[findCurrentIndex() + 1])
20
+
21
+ const { locale } = useI18n()
22
+ const localeTitle = computed(() => getLocaleTitle(locale.value, frontmatter.value))
17
23
  </script>
18
24
 
19
25
  <template>
20
- <article class="xl:divide-y xl:divide-gray-200">
21
- <header class="pt-6 xl:pb-10 space-y-1 text-center">
26
+ <article class="xl:divide-y xl:divide-gray-200 max-w-7xl m-auto" p="x-6" w="full">
27
+ <header class="pt-20 xl:pb-10 space-y-1 text-center">
22
28
  <PressDate :date="frontmatter.date" />
23
29
  <h1
24
30
  class="
25
31
  text-3xl
26
32
  leading-9
27
33
  font-extrabold
28
- text-gray-900
29
34
  tracking-tight
30
35
  sm:text-4xl sm:leading-10
31
36
  md:text-5xl md:leading-14
32
37
  "
33
38
  >
34
- {{ frontmatter.title }}
39
+ {{ localeTitle }}
35
40
  </h1>
36
41
  </header>
37
42
 
@@ -40,14 +45,14 @@ const prevPost = computed(() => posts.value[findCurrentIndex() + 1])
40
45
  divide-y
41
46
  xl:divide-y-0
42
47
  divide-gray-200
43
- xl:grid xl:grid-cols-4 xl:gap-x-10
48
+ xl:grid xl:grid-cols-12 xl:gap-x-6
44
49
  pb-16
45
50
  xl:pb-20
46
51
  "
47
52
  style="grid-template-rows: auto 1fr"
48
53
  >
49
54
  <PressAuthor v-if="frontmatter.author" :frontmatter="frontmatter" />
50
- <div class="divide-y divide-gray-200 xl:pb-0 xl:col-span-3 xl:row-span-2">
55
+ <div class="divide-y divide-gray-200 xl:pb-0 xl:col-span-8 xl:row-span-2">
51
56
  <router-view />
52
57
  </div>
53
58
 
@@ -57,7 +62,7 @@ const prevPost = computed(() => posts.value[findCurrentIndex() + 1])
57
62
  font-medium
58
63
  leading-5
59
64
  divide-y divide-gray-200
60
- xl:col-start-1 xl:row-start-2
65
+ xl:col-start-1 xl:row-start-2 xl:col-span-2
61
66
  "
62
67
  >
63
68
  <div v-if="nextPost" class="py-8">
@@ -65,19 +70,25 @@ const prevPost = computed(() => posts.value[findCurrentIndex() + 1])
65
70
  Next Article
66
71
  </h2>
67
72
  <div class="link">
68
- <a :href="nextPost.href">{{ nextPost.title }}</a>
73
+ <router-link :to="nextPost.href">
74
+ {{ nextPost.title }}
75
+ </router-link>
69
76
  </div>
70
77
  </div>
71
- <div v-if="prevPost" class="py-8">
78
+ <div v-if="prevPost && prevPost.href" class="py-8">
72
79
  <h2 class="text-xs tracking-wide uppercase text-gray-500">
73
80
  Previous Article
74
81
  </h2>
75
82
  <div class="link">
76
- <a :href="prevPost.href">{{ prevPost.title }}</a>
83
+ <router-link :to="prevPost.href">
84
+ {{ prevPost.title }}
85
+ </router-link>
77
86
  </div>
78
87
  </div>
79
88
  <div class="pt-8">
80
- <a class="link" href="/">← Back to the blog</a>
89
+ <router-link class="link" to="/">
90
+ ← Back to Home
91
+ </router-link>
81
92
  </div>
82
93
  </footer>
83
94
  </div>
@@ -12,7 +12,9 @@ defineProps<{
12
12
  <div class="space-y-5 xl:col-span-3">
13
13
  <div class="space-y-6">
14
14
  <h2 class="text-2xl leading-8 font-bold tracking-tight">
15
- <a class="text-gray-900" :href="post.path">{{ post.title }}</a>
15
+ <router-link class="text-gray-900" :to="post.path || ''">
16
+ {{ post.title }}
17
+ </router-link>
16
18
  </h2>
17
19
  <div
18
20
  v-if="post.excerpt"
@@ -21,7 +23,9 @@ defineProps<{
21
23
  />
22
24
  </div>
23
25
  <div class="text-base leading-6 font-medium">
24
- <a class="link" aria-label="read more" :href="post.path">Read more →</a>
26
+ <router-link class="link" aria-label="read more" :to="post.path || ''">
27
+ Read more →
28
+ </router-link>
25
29
  </div>
26
30
  </div>
27
31
  </article>
@@ -1,18 +1,15 @@
1
1
  <script lang="ts" setup>
2
- // import { useI18n } from 'vue-i18n'
3
- import { useData, useFrontmatter } from 'valaxy'
4
- import { useAppStore } from 'valaxy/client/stores/app'
2
+ import { useAppStore, useFrontmatter } from 'valaxy'
3
+ import PressOutline from './PressOutline.vue'
5
4
 
6
5
  const frontmatter = useFrontmatter()
7
- const data = useData()
8
- // const { t } = useI18n()
9
6
  const app = useAppStore()
10
7
  </script>
11
8
 
12
9
  <template>
13
10
  <button
14
- class="xl:hidden toc-btn shadow fixed press-icon-btn z-350"
15
- opacity="75" right="2" bottom="19"
11
+ class="toc-btn shadow-lg fixed press-icon-btn z-99 xl:hidden!"
12
+ right="5" bottom="8"
16
13
  @click="app.toggleRightSidebar()"
17
14
  >
18
15
  <div i-ri-file-list-line />
@@ -21,43 +18,48 @@ const app = useAppStore()
21
18
  <ValaxyOverlay :show="app.isRightSidebarOpen" @click="app.toggleRightSidebar()" />
22
19
 
23
20
  <aside
24
- class="press-aside lt-xl:fixed
25
- press-card xl:(shadow-none hover:shadow-none) shadow hover:shadow-lg"
26
- p="l-0 xl:l-4" text="center"
27
- z="10"
21
+ class="press-aside lt-xl:fixed shadow
22
+ press-card xl:(shadow-none hover:shadow-none) hover:shadow-lg"
23
+ flex="~ col grow"
24
+ p="l-0 xl:l-8" text="center"
25
+ z="$"
28
26
  :class="app.isRightSidebarOpen && 'open'"
29
27
  >
28
+ <div class="aside-curtain" />
30
29
  <div class="aside-container lt-xl:fixed" flex="~ col">
31
- <PressToc v-if="frontmatter.toc !== false" :headers="data.headers || []" />
32
- <div class="flex-grow" />
33
- <div v-if="$slots.default" class="custom-container">
34
- <slot />
30
+ <div class="aside-content overflow-auto" flex="~ col">
31
+ <PressOutline v-if="frontmatter.toc !== false" />
32
+ <div class="flex-grow" />
33
+ <div v-if="$slots.default" class="custom-container">
34
+ <slot />
35
+ </div>
35
36
  </div>
36
37
  </div>
37
38
  </aside>
38
39
  </template>
39
40
 
40
41
  <style lang="scss">
41
- @use 'valaxy/client/styles/mixins' as *;
42
+ @use 'valaxy/client/styles/mixins/index.scss' as *;
42
43
 
43
44
  .press-card{
44
- box-shadow: none;
45
45
  background-color: var(--va-c-bg);
46
46
  }
47
47
 
48
48
  .press-aside {
49
- position: relative;
50
- min-width: 272px;
51
- transform: translateX(100%);
52
49
  top: 0;
53
50
  bottom: 0;
54
51
  right: 0;
55
- z-index: 10;
52
+ z-index: var(--pr-z-aside);
53
+ width: var(--va-aside-width);
54
+
55
+ transform: translateX(100%);
56
56
 
57
57
  transition: box-shadow var(--va-transition-duration), opacity 0.25s,
58
58
  transform var(--va-transition-duration) cubic-bezier(0.19, 1, 0.22, 1);
59
59
 
60
60
  &.open {
61
+ position: fixed;
62
+ right: 0;
61
63
  display: block;
62
64
  transform: translateX(0);
63
65
  }
@@ -65,13 +67,22 @@ const app = useAppStore()
65
67
 
66
68
  .aside-container {
67
69
  position: sticky;
68
- top: calc(var(--pr-nav-height) + 32px);
69
- margin-top: calc(var(--pr-nav-height) * -1 - 32px);
70
- padding-top: calc(var(--pr-nav-height) + 32px);
70
+ top: 0;
71
+ margin-top: calc(var(--pr-nav-height) * -1 - 20px);
72
+ padding-top: calc(var(--pr-nav-height) + 20px);
71
73
  height: 100vh;
72
74
  }
73
75
 
74
- @include media('xl') {
76
+ .aside-curtain {
77
+ position: fixed;
78
+ bottom: 0;
79
+ z-index: 10;
80
+ width: 220px;
81
+ height: 32px;
82
+ background: linear-gradient(transparent,var(--va-c-bg) 70%);
83
+ }
84
+
85
+ @include screen('xl') {
75
86
  .aside-container {
76
87
  top: 0;
77
88
  }
@@ -82,7 +93,7 @@ const app = useAppStore()
82
93
  }
83
94
 
84
95
  .toc-btn {
85
- color: var(--va-c-primary);
86
- background-color: var(--va-c-bg);
96
+ color: var(--va-c-bg);
97
+ background-color: var(--va-c-primary);
87
98
  }
88
99
  </style>
@@ -17,7 +17,7 @@ defineProps<{
17
17
  right: 0;
18
18
  bottom: 0;
19
19
  left: 0;
20
- z-index: var(--pr-z-index-backdrop);
20
+ z-index: var(--pr-z-backdrop);
21
21
  background: rgba(0, 0, 0, .6);
22
22
  transition: opacity 0.5s;
23
23
 
@@ -1,7 +1,5 @@
1
1
  <script lang="ts" setup>
2
2
  import { computed } from 'vue'
3
- import { useRouter } from 'vue-router'
4
- import { EXTERNAL_URL_RE } from 'valaxy'
5
3
 
6
4
  const props = defineProps<{
7
5
  theme: 'brand' | 'alt'
@@ -9,9 +7,6 @@ const props = defineProps<{
9
7
  text: string
10
8
  }>()
11
9
 
12
- const isUrl = computed(() => EXTERNAL_URL_RE.test(props.link))
13
- const router = useRouter()
14
-
15
10
  const classes = computed(() => {
16
11
  const arr = []
17
12
  if (props.theme === 'brand')
@@ -24,15 +19,13 @@ const classes = computed(() => {
24
19
  </script>
25
20
 
26
21
  <template>
27
- <component
28
- :is="isUrl ? 'a' : 'button'"
22
+ <AppLink
23
+ :to="link"
29
24
  m="2"
30
25
  :class="classes"
31
- class="sese-btn btn" bg="gradient-to-r"
32
- :href="isUrl ? link : undefined"
33
- :target="isUrl ? '_blank' : undefined"
34
- @click="!isUrl && router.push(link)"
26
+ class="sese-btn btn rounded-full hover:shadow-lg" bg="gradient-to-r"
27
+ p="x-6"
35
28
  >
36
29
  {{ text }}
37
- </component>
30
+ </AppLink>
38
31
  </template>
@@ -1,6 +1,7 @@
1
1
  <script lang="ts" setup>
2
+ import { useThemeConfig } from 'valaxy'
2
3
  import type { Categories } from 'valaxy'
3
- import { ref } from 'vue'
4
+ import { computed, ref } from 'vue'
4
5
 
5
6
  const props = withDefaults(defineProps<{
6
7
  categories: Categories
@@ -16,15 +17,31 @@ const props = withDefaults(defineProps<{
16
17
  })
17
18
 
18
19
  const collapsable = ref(props.collapsable)
20
+
21
+ const themeConfig = useThemeConfig()
22
+ const sidebar = computed(() => themeConfig.value.sidebar)
19
23
  </script>
20
24
 
21
25
  <template>
22
- <ul v-for="category, key in Object.fromEntries(categories)" :key="key" class="category-list" m="l-4">
23
- <PressCategory :name="key.toString()" :category="category" :level="level + 1" :display-category="displayCategory" :collapsable="collapsable" />
26
+ <ul v-for="item in sidebar" :key="item" class="category-list">
27
+ <PressCategory
28
+ v-if="categories.find(c => c.name === item)"
29
+ :category="categories.find(c => c.name === item)"
30
+ :level="level + 1"
31
+ :display-category="displayCategory"
32
+ :collapsable="collapsable"
33
+ />
24
34
  </ul>
25
35
  </template>
26
36
 
27
37
  <style lang="scss">
38
+ .category-list {
39
+ &:first-child {
40
+ .category-list-item {
41
+ border-top: 0px;
42
+ }
43
+ }
44
+ }
28
45
  .post-list-item {
29
46
  a {
30
47
  color: var(--va-c-text-light);
@@ -47,4 +64,8 @@ const collapsable = ref(props.collapsable)
47
64
  }
48
65
  }
49
66
  }
67
+
68
+ .category-list+.category-list {
69
+ margin-top: 1rem;
70
+ }
50
71
  </style>
@@ -1,11 +1,10 @@
1
1
  <script lang="ts" setup>
2
2
  import { ref } from 'vue'
3
3
  import type { Category, Post } from 'valaxy'
4
- import { isParentCategory } from 'valaxy'
4
+ import { isCategoryList } from 'valaxy'
5
5
  import { useI18n } from 'vue-i18n'
6
6
 
7
7
  const props = withDefaults(defineProps<{
8
- name: string
9
8
  // to eliminate the warning
10
9
  category: Category
11
10
  level?: number
@@ -22,30 +21,40 @@ const props = withDefaults(defineProps<{
22
21
  const collapsable = ref(props.collapsable)
23
22
  const { t, locale } = useI18n()
24
23
 
25
- const getTitle = (post: Post | any) => {
26
- const lang = locale.value === 'zh-CN' ? 'zh' : locale.value
24
+ function getTitle(post: Post | any) {
25
+ const lang = locale.value
27
26
  return post[`title_${lang}`] ? post[`title_${lang}`] : post.title
28
27
  }
29
28
  </script>
30
29
 
31
30
  <template>
32
- <li v-if="category.total" class="category-list-item inline-flex items-center">
33
- <span class="folder-action inline-flex cursor-pointer" @click="collapsable = !collapsable">
31
+ <li
32
+ v-if="category.total"
33
+ p="t-2"
34
+ w="full" border="t t-$pr-c-divider-light"
35
+ class="category-list-item inline-flex items-center justify-between"
36
+ >
37
+ <span class="category-name" font="bold" m="l-1" @click="displayCategory ? displayCategory(category.name) : null">
38
+ {{ category.name === 'Uncategorized' ? t('category.uncategorized') : category.name }}
39
+ <!-- <sup font="normal">[{{ category.total }}]</sup> -->
40
+ </span>
41
+ <span class="folder-action inline-flex cursor-pointer" opacity="50" @click="collapsable = !collapsable">
34
42
  <div v-if="collapsable" i-ri-folder-add-line />
35
- <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 }}]
43
+ <div v-else i-ri-folder-reduce-line />
38
44
  </span>
39
45
  </li>
40
46
 
41
47
  <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" active-class="active">
45
- <span m="l-1" text="sm">{{ getTitle(post) }}</span>
46
- </router-link>
48
+ <ul>
49
+ <li v-for="categoryItem, i in category.children" :key="i" class="post-list-item">
50
+ <template v-if="!isCategoryList(categoryItem)">
51
+ <router-link v-if="categoryItem.title" :to="categoryItem.path || ''" class="inline-flex items-center" active-class="active">
52
+ <span m="l-1" text="sm">{{ getTitle(categoryItem) }}</span>
53
+ </router-link>
54
+ </template>
55
+
56
+ <PressCategory v-else :category="categoryItem" :display-category="displayCategory" :collapsable="collapsable" />
47
57
  </li>
48
58
  </ul>
49
- <PressCategories v-else :categories="category.children" :display-category="displayCategory" :collapsable="collapsable" />
50
59
  </template>
51
60
  </template>
@@ -0,0 +1,15 @@
1
+ <script lang="ts" setup>
2
+ import { useEditLink } from '../composables'
3
+
4
+ const editLink = useEditLink()
5
+ </script>
6
+
7
+ <template>
8
+ <div flex justify="between" text="sm">
9
+ <a flex items="center" :href="editLink.url" target="_blank">
10
+ <div i-ri-external-link-line />
11
+ <span ml-1>{{ editLink.text }}</span>
12
+ </a>
13
+ <PressDocFooterLastUpdated />
14
+ </div>
15
+ </template>