valaxy-theme-hairy 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (121) hide show
  1. package/LICENSE +21 -21
  2. package/client/index.ts +1 -1
  3. package/components/HairyBody.vue +49 -49
  4. package/components/HairyCodepen.vue +40 -40
  5. package/components/HairyComment.vue +33 -33
  6. package/components/HairyContainer.vue +17 -17
  7. package/components/HairyDrawer.vue +44 -44
  8. package/components/HairyFooter.vue +62 -62
  9. package/components/HairyHeader.vue +32 -32
  10. package/components/HairyImage.vue +15 -15
  11. package/components/HairyImageGroup.vue +65 -65
  12. package/components/HairyNavbar.vue +56 -56
  13. package/components/HairyPageArchives.vue +59 -59
  14. package/components/HairyPageTags.vue +48 -48
  15. package/components/HairyPosts.vue +54 -54
  16. package/components/HairySearch.vue +201 -201
  17. package/components/HairySidebar.vue +30 -30
  18. package/components/HairyTabbar.vue +56 -56
  19. package/components/PageTags.vue +48 -48
  20. package/components/ValaxyMain.vue +45 -45
  21. package/components/navbar/HairyNav.vue +16 -16
  22. package/components/navbar/HairyNavExpand.vue +12 -12
  23. package/components/navbar/HairyNavItem.vue +35 -35
  24. package/components/navbar/HairyNavbarBackground.vue +7 -7
  25. package/components/navbar/HairyNavbarSearch.vue +8 -8
  26. package/components/navbar/HairyNavbarTitle.vue +15 -15
  27. package/components/navbar/HairyNavbarToggleDark.vue +22 -22
  28. package/components/parts/HairyBreadcrumb.vue +51 -51
  29. package/components/parts/HairyBreadcrumbItem.vue +11 -11
  30. package/components/parts/HairyFootFish.js +352 -352
  31. package/components/parts/HairyFootFish.vue +38 -38
  32. package/components/parts/HairyHeadHero.vue +34 -34
  33. package/components/parts/HairyHeadWaves.vue +67 -67
  34. package/components/parts/HairyImageGlobal.vue +51 -51
  35. package/components/parts/HairyImageViewer.vue +23 -23
  36. package/components/parts/HairyLink.vue +21 -21
  37. package/components/parts/HairyMenu.vue +16 -16
  38. package/components/parts/HairyMenuItem.vue +47 -47
  39. package/components/parts/HairyOutline.vue +99 -99
  40. package/components/parts/HairyOutlineItem.vue +48 -48
  41. package/components/parts/HairySocialLinks.vue +27 -27
  42. package/components/parts/HairyTimelineContent.vue +39 -39
  43. package/components/parts/HairyUserNav.vue +95 -95
  44. package/components/parts/HairyUserStats.vue +18 -18
  45. package/components/posts/HairyArticleImage.vue +126 -126
  46. package/components/posts/HairyArticleSeries.vue +89 -89
  47. package/components/posts/HairyArticleText.vue +43 -43
  48. package/components/posts/HairyPostFooter.vue +15 -15
  49. package/components/posts/HairyPostImageList.vue +27 -27
  50. package/components/posts/HairyPostTextsList.vue +22 -22
  51. package/components/posts/HairyPostToggleLayout.vue +36 -36
  52. package/components/third/HairyAlgoliaSearch.vue +17 -17
  53. package/components/third/HairyFuseSearch.vue +10 -10
  54. package/components/third/HairyFuseSearchDialog.vue +32 -32
  55. package/components/third/HairyFuseSearchDropdown.vue +77 -77
  56. package/components/third/HairyFuseSearchFooter.vue +28 -28
  57. package/components/third/HairyFuseSearchHeader.vue +30 -30
  58. package/components/third/HairyFuseSearchHit.vue +52 -52
  59. package/components/third/HairySearchBtnDisplay.vue +29 -29
  60. package/components/third/HairySearchBtnInput.vue +20 -20
  61. package/components/third/HairySearchBtnKeys.vue +19 -19
  62. package/components/third/HairySwiperCarousel.vue +45 -45
  63. package/composables/archives.ts +48 -48
  64. package/composables/category.ts +43 -43
  65. package/composables/config.ts +11 -11
  66. package/composables/dark.ts +13 -13
  67. package/composables/fuse.ts +60 -60
  68. package/composables/index.ts +7 -7
  69. package/composables/layout.ts +16 -16
  70. package/composables/outline.ts +49 -49
  71. package/composables/tags.ts +36 -36
  72. package/layouts/archive-month.vue +13 -13
  73. package/layouts/archive-year.vue +13 -13
  74. package/layouts/archives.vue +11 -11
  75. package/layouts/categories.vue +13 -13
  76. package/layouts/default.vue +13 -15
  77. package/layouts/home.vue +33 -33
  78. package/layouts/post.vue +54 -54
  79. package/layouts/tag.vue +10 -10
  80. package/layouts/tags.vue +10 -14
  81. package/library/loading.scss +535 -535
  82. package/library/loading.ts +60 -60
  83. package/library/scroll.ts +22 -22
  84. package/locales/en.yml +1 -1
  85. package/locales/zh-CN.yml +1 -1
  86. package/node/images/default.json +139 -139
  87. package/node/images/index.ts +46 -46
  88. package/node/images/shims.d.ts +8 -8
  89. package/node/index.ts +2 -2
  90. package/node/theme/index.ts +78 -78
  91. package/package.json +1 -1
  92. package/pages/archives/[year]/[month]/index.vue +48 -48
  93. package/pages/archives/[year]/index.vue +73 -73
  94. package/pages/archives/index.md +6 -0
  95. package/pages/categories/[...its].vue +108 -108
  96. package/pages/index.vue +8 -8
  97. package/pages/page/[page].vue +12 -12
  98. package/pages/tags/[tag]/index.vue +38 -38
  99. package/pages/tags/index.md +7 -0
  100. package/setup/main.ts +9 -9
  101. package/store/index.ts +1 -1
  102. package/store/modules/global.ts +12 -12
  103. package/styles/components/aplayer.scss +75 -75
  104. package/styles/components/index.scss +3 -3
  105. package/styles/components/markdown.scss +89 -89
  106. package/styles/components/nprogress.scss +15 -15
  107. package/styles/components/scrollbar.scss +25 -25
  108. package/styles/css-vars.scss +171 -171
  109. package/styles/element-plus/index.scss +1 -1
  110. package/styles/element-plus/tabs.scss +25 -25
  111. package/styles/element-plus/timeline.scss +18 -18
  112. package/styles/font-face.scss +19 -19
  113. package/styles/global.scss +38 -38
  114. package/styles/index.scss +3 -3
  115. package/tsconfig.json +27 -27
  116. package/types/index.d.ts +163 -163
  117. package/unocss.config.ts +43 -43
  118. package/utils/index.ts +37 -37
  119. package/valaxy.config.ts +26 -26
  120. package/pages/archives/index.vue +0 -6
  121. package/pages/tags/index.vue +0 -6
@@ -1,38 +1,38 @@
1
- <!-- eslint-disable no-new -->
2
- <script lang="ts" setup>
3
- import { computed, onMounted, ref, watch } from 'vue'
4
- import { useScriptTag } from '@vueuse/core'
5
- import { useAppStore } from 'valaxy'
6
- import { RENDERER } from './HairyFootFish'
7
-
8
- const fishContainer = ref()
9
-
10
- const tag = useScriptTag('https://cdn.bootcdn.net/ajax/libs/zepto/1.2.0/zepto.min.js')
11
- const appStore = useAppStore()
12
- const dark = computed(() => appStore.isDark)
13
-
14
- let renderer: RENDERER
15
-
16
- function reset() {
17
- const color = dark.value ? 'hsl(0, 0%, 95%)' : 'hsl(0, 0%, 80%)'
18
- if (!renderer)
19
- renderer = new RENDERER(color)
20
- else
21
- renderer.setColor(color)
22
- }
23
-
24
- onMounted(() => {
25
- tag.load()
26
- .then(reset)
27
- })
28
- watch(dark, reset)
29
- </script>
30
-
31
- <template>
32
- <div
33
- id="jsi-flying-fish-container"
34
- ref="fishContainer"
35
- class="z-1 relative"
36
- style="margin-top: -60px;"
37
- />
38
- </template>
1
+ <!-- eslint-disable no-new -->
2
+ <script lang="ts" setup>
3
+ import { computed, onMounted, ref, watch } from 'vue'
4
+ import { useScriptTag } from '@vueuse/core'
5
+ import { useAppStore } from 'valaxy'
6
+ import { RENDERER } from './HairyFootFish'
7
+
8
+ const fishContainer = ref()
9
+
10
+ const tag = useScriptTag('https://cdn.bootcdn.net/ajax/libs/zepto/1.2.0/zepto.min.js')
11
+ const appStore = useAppStore()
12
+ const dark = computed(() => appStore.isDark)
13
+
14
+ let renderer: RENDERER
15
+
16
+ function reset() {
17
+ const color = dark.value ? 'hsl(0, 0%, 95%)' : 'hsl(0, 0%, 80%)'
18
+ if (!renderer)
19
+ renderer = new RENDERER(color)
20
+ else
21
+ renderer.setColor(color)
22
+ }
23
+
24
+ onMounted(() => {
25
+ tag.load()
26
+ .then(reset)
27
+ })
28
+ watch(dark, reset)
29
+ </script>
30
+
31
+ <template>
32
+ <div
33
+ id="jsi-flying-fish-container"
34
+ ref="fishContainer"
35
+ class="z-1 relative"
36
+ style="margin-top: -60px;"
37
+ />
38
+ </template>
@@ -1,34 +1,34 @@
1
- <script lang="ts" setup>
2
- import { useFrontmatter } from 'valaxy'
3
- import { computed } from 'vue'
4
-
5
- const props = defineProps<{
6
- headline?: string
7
- title: string
8
- description?: string
9
- }>()
10
-
11
- const post = useFrontmatter()
12
-
13
- const headline = computed(() => props.headline || post.value.headline)
14
- const title = computed(() => props.title || post.value.title)
15
- </script>
16
-
17
- <template>
18
- <div class="flex-center flex-col text-shadow-lg text-white mx-12px text-center">
19
- <div v-if="headline" class="font-frederick text-size-3.35em lt-sm:text-size-3rem leading-snug">
20
- {{ headline }}
21
- </div>
22
- <div class="text-size-2.5em lt-sm:text-size-2rem font-bold title tracking-1">
23
- {{ title }}
24
- </div>
25
- <p v-if="description || $slots.description" class="text-size-sm">
26
- <template v-if="description">
27
- {{ description }}
28
- </template>
29
- <slot v-else name="description" />
30
- </p>
31
- </div>
32
- </template>
33
-
34
- <style lang="scss" scoped></style>
1
+ <script lang="ts" setup>
2
+ import { useFrontmatter } from 'valaxy'
3
+ import { computed } from 'vue'
4
+
5
+ const props = defineProps<{
6
+ headline?: string
7
+ title: string
8
+ description?: string
9
+ }>()
10
+
11
+ const post = useFrontmatter()
12
+
13
+ const headline = computed(() => props.headline || post.value.headline)
14
+ const title = computed(() => props.title || post.value.title)
15
+ </script>
16
+
17
+ <template>
18
+ <div class="flex-center flex-col text-shadow-lg text-white mx-12px text-center">
19
+ <div v-if="headline" class="font-frederick text-size-3.35em lt-sm:text-size-3rem leading-snug">
20
+ {{ headline }}
21
+ </div>
22
+ <div class="text-size-2.5em lt-sm:text-size-2rem font-bold title tracking-1">
23
+ {{ title }}
24
+ </div>
25
+ <p v-if="description || $slots.description" class="text-size-sm">
26
+ <template v-if="description">
27
+ {{ description }}
28
+ </template>
29
+ <slot v-else name="description" />
30
+ </p>
31
+ </div>
32
+ </template>
33
+
34
+ <style lang="scss" scoped></style>
@@ -1,67 +1,67 @@
1
- <template>
2
- <svg
3
- class="waves w-full min-h-100px max-h-150px"
4
- viewBox="0 24 150 28" preserveAspectRatio="none" shape-rendering="auto"
5
- >
6
- <defs>rgba(250,250,250,var(--un-bg-opacity))
7
- <path id="gentle-wave" d="M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z" />
8
- </defs>
9
- <g class="parallax">
10
- <use class="" xlink:href="#gentle-wave" x="48" y="0" fill="var(--hy-c-waves-dimm-1)" />
11
- <use class="" xlink:href="#gentle-wave" x="48" y="3" fill="var(--hy-c-waves-dimm-2)" />
12
- <use class="" xlink:href="#gentle-wave" x="48" y="5" fill="var(--hy-c-waves-dimm-3)" />
13
- <use class="" xlink:href="#gentle-wave" x="48" y="7" fill="var(--hy-c-waves-dimm)" />
14
- </g>
15
- </svg>
16
- </template>
17
-
18
- <style lang="scss" scoped>
19
- .waves {
20
- height: max(100px, min(150px, 15vh));
21
- margin-bottom: -7px;
22
- }
23
-
24
- /* Animation */
25
- .parallax > use {
26
- animation: move-forever 25s cubic-bezier(.55, .5, .45, .5) infinite;
27
- }
28
-
29
- .parallax > use:nth-child(1) {
30
- animation-delay: -2s;
31
- animation-duration: 7s;
32
- }
33
-
34
- .parallax > use:nth-child(2) {
35
- animation-delay: -3s;
36
- animation-duration: 10s;
37
- }
38
-
39
- .parallax > use:nth-child(3) {
40
- animation-delay: -4s;
41
- animation-duration: 13s;
42
- }
43
-
44
- .parallax > use:nth-child(4) {
45
- animation-delay: -5s;
46
- animation-duration: 20s;
47
- }
48
-
49
- @keyframes move-forever {
50
- 0% {
51
- transform: translate3d(-90px, 0, 0);
52
- }
53
- 100% {
54
- transform: translate3d(85px, 0, 0);
55
- }
56
- }
57
-
58
- /*Shrinking for mobile*/
59
- @media (max-width: 768px) {
60
- .waves {
61
- margin-top: -40px;
62
- height: 40px;
63
- min-height: 40px;
64
- }
65
-
66
- }
67
- </style>
1
+ <template>
2
+ <svg
3
+ class="waves w-full min-h-100px max-h-150px"
4
+ viewBox="0 24 150 28" preserveAspectRatio="none" shape-rendering="auto"
5
+ >
6
+ <defs>rgba(250,250,250,var(--un-bg-opacity))
7
+ <path id="gentle-wave" d="M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z" />
8
+ </defs>
9
+ <g class="parallax">
10
+ <use class="" xlink:href="#gentle-wave" x="48" y="0" fill="var(--hy-c-waves-dimm-1)" />
11
+ <use class="" xlink:href="#gentle-wave" x="48" y="3" fill="var(--hy-c-waves-dimm-2)" />
12
+ <use class="" xlink:href="#gentle-wave" x="48" y="5" fill="var(--hy-c-waves-dimm-3)" />
13
+ <use class="" xlink:href="#gentle-wave" x="48" y="7" fill="var(--hy-c-waves-dimm)" />
14
+ </g>
15
+ </svg>
16
+ </template>
17
+
18
+ <style lang="scss" scoped>
19
+ .waves {
20
+ height: max(100px, min(150px, 15vh));
21
+ margin-bottom: -7px;
22
+ }
23
+
24
+ /* Animation */
25
+ .parallax > use {
26
+ animation: move-forever 25s cubic-bezier(.55, .5, .45, .5) infinite;
27
+ }
28
+
29
+ .parallax > use:nth-child(1) {
30
+ animation-delay: -2s;
31
+ animation-duration: 7s;
32
+ }
33
+
34
+ .parallax > use:nth-child(2) {
35
+ animation-delay: -3s;
36
+ animation-duration: 10s;
37
+ }
38
+
39
+ .parallax > use:nth-child(3) {
40
+ animation-delay: -4s;
41
+ animation-duration: 13s;
42
+ }
43
+
44
+ .parallax > use:nth-child(4) {
45
+ animation-delay: -5s;
46
+ animation-duration: 20s;
47
+ }
48
+
49
+ @keyframes move-forever {
50
+ 0% {
51
+ transform: translate3d(-90px, 0, 0);
52
+ }
53
+ 100% {
54
+ transform: translate3d(85px, 0, 0);
55
+ }
56
+ }
57
+
58
+ /*Shrinking for mobile*/
59
+ @media (max-width: 768px) {
60
+ .waves {
61
+ margin-top: -40px;
62
+ height: 40px;
63
+ min-height: 40px;
64
+ }
65
+
66
+ }
67
+ </style>
@@ -1,51 +1,51 @@
1
- <script lang="ts" setup>
2
- import { provide, useCssVars } from 'vue'
3
- import { renderOverlay } from '@overlastic/vue'
4
- import type { ImageViewerProps } from 'element-plus/es/components/image-viewer/index'
5
- import { atWillToUnit } from '@hairy/utils'
6
- import HairyImageViewer from './HairyImageViewer.vue'
7
-
8
- const props = withDefaults(defineProps<{
9
- row?: string | number
10
- col?: string | number
11
- gap?: string | number
12
- justify?: string
13
- align?: string
14
- }>(), {
15
- row: 'auto',
16
- col: 'auto',
17
- gap: 10,
18
- justify: 'space-evenly',
19
- align: 'initial',
20
- })
21
-
22
- useCssVars(() => ({
23
- width: atWillToUnit(props.row),
24
- height: atWillToUnit(props.col),
25
- gap: atWillToUnit(props.gap),
26
- justify: props.justify,
27
- align: props.align,
28
- }))
29
-
30
- // TODO global find images
31
- // const slots = useSlots()
32
- // const paths = computed(() => slots
33
- // .default?.()
34
- // .map(v => v.props?.src)
35
- // .filter(Boolean) as string[],
36
- // )
37
-
38
- function preview(url: string) {
39
- // const initialIndex = paths.value.findIndex(v => v === url) || 0
40
- renderOverlay<Partial<ImageViewerProps>>(HairyImageViewer, {
41
- urlList: [url],
42
- initialIndex: 0,
43
- })
44
- }
45
-
46
- provide('HairyImageGroup:preview', preview)
47
- </script>
48
-
49
- <template>
50
- <slot />
51
- </template>
1
+ <script lang="ts" setup>
2
+ import { provide, useCssVars } from 'vue'
3
+ import { renderOverlay } from '@overlastic/vue'
4
+ import type { ImageViewerProps } from 'element-plus'
5
+ import { atWillToUnit } from '@hairy/utils'
6
+ import HairyImageViewer from './HairyImageViewer.vue'
7
+
8
+ const props = withDefaults(defineProps<{
9
+ row?: string | number
10
+ col?: string | number
11
+ gap?: string | number
12
+ justify?: string
13
+ align?: string
14
+ }>(), {
15
+ row: 'auto',
16
+ col: 'auto',
17
+ gap: 10,
18
+ justify: 'space-evenly',
19
+ align: 'initial',
20
+ })
21
+
22
+ useCssVars(() => ({
23
+ width: atWillToUnit(props.row),
24
+ height: atWillToUnit(props.col),
25
+ gap: atWillToUnit(props.gap),
26
+ justify: props.justify,
27
+ align: props.align,
28
+ }))
29
+
30
+ // TODO global find images
31
+ // const slots = useSlots()
32
+ // const paths = computed(() => slots
33
+ // .default?.()
34
+ // .map(v => v.props?.src)
35
+ // .filter(Boolean) as string[],
36
+ // )
37
+
38
+ function preview(url: string) {
39
+ // const initialIndex = paths.value.findIndex(v => v === url) || 0
40
+ renderOverlay<Partial<ImageViewerProps>>(HairyImageViewer, {
41
+ urlList: [url],
42
+ initialIndex: 0,
43
+ })
44
+ }
45
+
46
+ provide('HairyImageGroup:preview', preview)
47
+ </script>
48
+
49
+ <template>
50
+ <slot />
51
+ </template>
@@ -1,23 +1,23 @@
1
- <script lang="ts" setup>
2
- import { usePrograms } from '@overlastic/vue'
3
- import { ElImageViewer, imageViewerProps } from 'element-plus/es/components/image-viewer/index'
4
- import 'element-plus/theme-chalk/el-image-viewer.css'
5
- import { onMounted, onUnmounted } from 'vue'
6
-
7
- const props = defineProps(imageViewerProps)
8
-
9
- const { visible, resolve } = usePrograms()
10
-
11
- onMounted(() => {
12
- document.body.style.overflow = 'hidden'
13
- })
14
- onUnmounted(() => {
15
- document.body.style.overflow = ''
16
- })
17
- </script>
18
-
19
- <template>
20
- <div class="HairyImageViewer fixed inset-0 z-2000">
21
- <ElImageViewer v-if="visible" v-bind="props" @close="resolve()" />
22
- </div>
23
- </template>
1
+ <script lang="ts" setup>
2
+ import { usePrograms } from '@overlastic/vue'
3
+ import { ElImageViewer, imageViewerProps } from 'element-plus'
4
+ import 'element-plus/theme-chalk/el-image-viewer.css'
5
+ import { onMounted, onUnmounted } from 'vue'
6
+
7
+ const props = defineProps(imageViewerProps)
8
+
9
+ const { visible, resolve } = usePrograms()
10
+
11
+ onMounted(() => {
12
+ document.body.style.overflow = 'hidden'
13
+ })
14
+ onUnmounted(() => {
15
+ document.body.style.overflow = ''
16
+ })
17
+ </script>
18
+
19
+ <template>
20
+ <div class="HairyImageViewer fixed inset-0 z-2000">
21
+ <ElImageViewer v-if="visible" v-bind="props" @close="resolve()" />
22
+ </div>
23
+ </template>
@@ -1,21 +1,21 @@
1
- <script lang="ts" setup>
2
- defineProps<{
3
- type?: 'white' | 'normal'
4
- bordered?: boolean
5
- }>()
6
- </script>
7
-
8
- <template>
9
- <a
10
- class="cursor-pointer" :class="[
11
- type === 'white'
12
- ? 'text-black hover:text-primary dark:text-white'
13
- : 'text:text-primary-light hover:text-primary-dark',
14
- bordered && 'border-b border-dashed hover:border-primary',
15
- ]"
16
- >
17
- <slot />
18
- </a>
19
- </template>
20
-
21
- <style lang="scss" scoped></style>
1
+ <script lang="ts" setup>
2
+ defineProps<{
3
+ type?: 'white' | 'normal'
4
+ bordered?: boolean
5
+ }>()
6
+ </script>
7
+
8
+ <template>
9
+ <a
10
+ class="cursor-pointer" :class="[
11
+ type === 'white'
12
+ ? 'text-black hover:text-primary dark:text-white'
13
+ : 'text:text-primary-light hover:text-primary-dark',
14
+ bordered && 'border-b border-dashed hover:border-primary',
15
+ ]"
16
+ >
17
+ <slot />
18
+ </a>
19
+ </template>
20
+
21
+ <style lang="scss" scoped></style>
@@ -1,16 +1,16 @@
1
- <script lang="ts" setup>
2
- import type { HairyTheme } from 'valaxy-theme-hairy'
3
- import { useThemeConfig } from 'valaxy'
4
- import { computed } from 'vue'
5
-
6
- const themeConfig = useThemeConfig<HairyTheme.Config>()
7
- const nav = computed(() => themeConfig.value.nav || [])
8
- </script>
9
-
10
- <template>
11
- <div class="flex items-center h-12.5">
12
- <HairyMenuItem v-for="(item, index) in nav" :key="index" :item="item" />
13
- </div>
14
- </template>
15
-
16
- <style lang="scss" scoped></style>
1
+ <script lang="ts" setup>
2
+ import type { HairyTheme } from 'valaxy-theme-hairy'
3
+ import { useThemeConfig } from 'valaxy'
4
+ import { computed } from 'vue'
5
+
6
+ const themeConfig = useThemeConfig<HairyTheme.Config>()
7
+ const nav = computed(() => themeConfig.value.nav || [])
8
+ </script>
9
+
10
+ <template>
11
+ <div class="flex items-center h-12.5">
12
+ <HairyMenuItem v-for="(item, index) in nav" :key="index" :item="item" />
13
+ </div>
14
+ </template>
15
+
16
+ <style lang="scss" scoped></style>
@@ -1,47 +1,47 @@
1
- <script lang="ts" setup>
2
- import type { NavItem } from 'valaxy-theme-hairy'
3
- import { computed } from 'vue'
4
- import { useRoute, useRouter } from 'vue-router'
5
- import { storeToRefs } from 'pinia'
6
- import { ejectWindow } from '../../utils'
7
- import { useGlobalStore } from '../../store'
8
-
9
- const props = defineProps<{
10
- item: NavItem
11
- }>()
12
- const { showDrawer } = storeToRefs(useGlobalStore())
13
- const urlReg = /^(((ht|f)tps?):\/\/)?([^!@#$%^&*?.\s-]([^!@#$%^&*?.\s]{0,63}[^!@#$%^&*?.\s])?\.)+[a-z]{2,6}\/?/
14
- const isLink = computed(() => urlReg.test(props.item?.link || ''))
15
- const isPointer = computed(() => Boolean(props.item.link) || isLink.value)
16
- const router = useRouter()
17
- const route = useRoute()
18
-
19
- function toLink() {
20
- if (isLink.value)
21
- return ejectWindow(props.item.link!)
22
- if (props.item.link)
23
- router.push(props.item.link)
24
- showDrawer.value = false
25
- }
26
-
27
- const isActive = computed(() => {
28
- if (isLink.value)
29
- return false
30
- if (props.item.link === '/')
31
- return route.path === props.item.link
32
- return route.path.includes(props.item.link!)
33
- })
34
- </script>
35
-
36
- <template>
37
- <button class="px-2.5 HairyMenuItem" :class="[isPointer ? 'cursor-pointer' : 'select-none', isActive && 'text-primary active']">
38
- <div class="flex items-center hover:text-primary" @click="toLink">
39
- <div v-if="item.icon" class="mr-1 icon" :class="item.icon" />
40
- <div class="question">
41
- {{ item.text }}
42
- </div>
43
- </div>
44
- </button>
45
- </template>
46
-
47
- <style lang="scss" scoped></style>
1
+ <script lang="ts" setup>
2
+ import type { NavItem } from 'valaxy-theme-hairy'
3
+ import { computed } from 'vue'
4
+ import { useRoute, useRouter } from 'vue-router'
5
+ import { storeToRefs } from 'pinia'
6
+ import { ejectWindow } from '../../utils'
7
+ import { useGlobalStore } from '../../store'
8
+
9
+ const props = defineProps<{
10
+ item: NavItem
11
+ }>()
12
+ const { showDrawer } = storeToRefs(useGlobalStore())
13
+ const urlReg = /^(((ht|f)tps?):\/\/)?([^!@#$%^&*?.\s-]([^!@#$%^&*?.\s]{0,63}[^!@#$%^&*?.\s])?\.)+[a-z]{2,6}\/?/
14
+ const isLink = computed(() => urlReg.test(props.item?.link || ''))
15
+ const isPointer = computed(() => Boolean(props.item.link) || isLink.value)
16
+ const router = useRouter()
17
+ const route = useRoute()
18
+
19
+ function toLink() {
20
+ if (isLink.value)
21
+ return ejectWindow(props.item.link!)
22
+ if (props.item.link)
23
+ router.push(props.item.link)
24
+ showDrawer.value = false
25
+ }
26
+
27
+ const isActive = computed(() => {
28
+ if (isLink.value)
29
+ return false
30
+ if (props.item.link === '/')
31
+ return route.path === props.item.link
32
+ return route.path.includes(props.item.link!)
33
+ })
34
+ </script>
35
+
36
+ <template>
37
+ <button class="px-2.5 HairyMenuItem" :class="[isPointer ? 'cursor-pointer' : 'select-none', isActive && 'text-primary active']">
38
+ <div class="flex items-center hover:text-primary" @click="toLink">
39
+ <div v-if="item.icon" class="mr-1 icon" :class="item.icon" />
40
+ <div class="question">
41
+ {{ item.text }}
42
+ </div>
43
+ </div>
44
+ </button>
45
+ </template>
46
+
47
+ <style lang="scss" scoped></style>