clarity-theme 0.1.0 → 0.1.1

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 (119) hide show
  1. package/LICENSE +20 -20
  2. package/README.md +18 -4
  3. package/README.zh-CN.md +18 -4
  4. package/app/app.config.ts +110 -110
  5. package/app/app.vue +5 -5
  6. package/app/components/blog/BlogAside.vue +25 -25
  7. package/app/components/blog/BlogFooter.vue +25 -25
  8. package/app/components/blog/BlogHeader.global.vue +48 -48
  9. package/app/components/blog/BlogPanel.vue +43 -43
  10. package/app/components/blog/BlogSidebar.vue +53 -53
  11. package/app/components/blog/BlogWidget.vue +42 -42
  12. package/app/components/blog/Mask.vue +25 -25
  13. package/app/components/blog/SkipToContent.vue +9 -9
  14. package/app/components/blog/ThemeToggle.vue +22 -22
  15. package/app/components/content/Badge.vue +45 -45
  16. package/app/components/content/Blur.vue +14 -14
  17. package/app/components/content/CardList.vue +8 -8
  18. package/app/components/content/Chat.vue +41 -41
  19. package/app/components/content/Copy.vue +71 -71
  20. package/app/components/content/EmojiClock.vue +49 -49
  21. package/app/components/content/FeedCard.vue +96 -96
  22. package/app/components/content/FeedGroup.vue +61 -61
  23. package/app/components/content/Folding.vue +19 -19
  24. package/app/components/content/Key.vue +143 -143
  25. package/app/components/content/LinkBanner.vue +27 -27
  26. package/app/components/content/LinkCard.vue +28 -28
  27. package/app/components/content/MdTitle.vue +8 -8
  28. package/app/components/content/Mermaid.vue +99 -99
  29. package/app/components/content/MusicScore.vue +63 -63
  30. package/app/components/content/Pic.vue +49 -49
  31. package/app/components/content/Poetry.vue +27 -27
  32. package/app/components/content/ProseA.vue +24 -24
  33. package/app/components/content/ProseCode.vue +16 -16
  34. package/app/components/content/ProsePre.vue +117 -117
  35. package/app/components/content/ProseTable.vue +23 -23
  36. package/app/components/content/Quote.vue +21 -21
  37. package/app/components/content/Tab.vue +32 -32
  38. package/app/components/content/Timeline.vue +33 -33
  39. package/app/components/content/Tip.vue +40 -40
  40. package/app/components/content/VideoEmbed.vue +112 -112
  41. package/app/components/partial/Button.vue +36 -36
  42. package/app/components/partial/DlGroup.vue +31 -31
  43. package/app/components/partial/Dropdown.vue +21 -21
  44. package/app/components/partial/Error.vue +39 -39
  45. package/app/components/partial/Expand.vue +26 -26
  46. package/app/components/partial/IconNavList.vue +24 -24
  47. package/app/components/partial/Pagination.vue +62 -62
  48. package/app/components/partial/RadioGroup.vue +30 -30
  49. package/app/components/partial/Secret.vue +11 -11
  50. package/app/components/partial/Slider.vue +48 -48
  51. package/app/components/partial/Toggle.vue +17 -17
  52. package/app/components/popover/Lightbox.vue +44 -44
  53. package/app/components/popover/Search.vue +143 -143
  54. package/app/components/popover/SearchItem.vue +28 -28
  55. package/app/components/post/Archive.vue +40 -40
  56. package/app/components/post/Article.vue +49 -49
  57. package/app/components/post/Comment.vue +119 -119
  58. package/app/components/post/Excerpt.vue +40 -40
  59. package/app/components/post/OrderToggle.vue +70 -70
  60. package/app/components/post/PostFooter.vue +52 -52
  61. package/app/components/post/PostHeader.vue +66 -66
  62. package/app/components/post/PostSurround.vue +51 -51
  63. package/app/components/post/Slide.vue +85 -85
  64. package/app/components/util/Date.vue +62 -62
  65. package/app/components/util/HydrateSafe.vue +10 -10
  66. package/app/components/util/Img.vue +38 -38
  67. package/app/components/util/Link.vue +11 -11
  68. package/app/components/widget/BlogLog.vue +23 -23
  69. package/app/components/widget/BlogStats.vue +38 -38
  70. package/app/components/widget/BlogTech.vue +57 -57
  71. package/app/components/widget/Empty.vue +3 -3
  72. package/app/components/widget/Toc.vue +67 -67
  73. package/app/composables/useArticle.ts +113 -113
  74. package/app/composables/useAvoid.ts +87 -87
  75. package/app/composables/useCopy.ts +21 -21
  76. package/app/composables/usePagination.ts +70 -70
  77. package/app/composables/useShiki.ts +129 -129
  78. package/app/composables/useToc.ts +57 -57
  79. package/app/composables/useWidgets.ts +56 -56
  80. package/app/error.vue +31 -31
  81. package/app/layouts/default.vue +25 -25
  82. package/app/pages/[...slug].vue +59 -59
  83. package/app/pages/archive.vue +129 -129
  84. package/app/pages/index.vue +76 -76
  85. package/app/pages/link.vue +62 -62
  86. package/app/pages/preview.vue +46 -46
  87. package/app/plugins/easter-egg.ts +23 -23
  88. package/app/plugins/init.ts +6 -6
  89. package/app/plugins/tippy.ts +22 -22
  90. package/app/shiki.config.ts +8 -8
  91. package/app/stores/layout.ts +34 -34
  92. package/app/stores/search.ts +37 -37
  93. package/app/types/article.ts +16 -16
  94. package/app/types/index.ts +14 -14
  95. package/app/types/nav.ts +11 -11
  96. package/app/utils/anim.ts +37 -37
  97. package/app/utils/img.ts +83 -83
  98. package/config/app.ts +61 -61
  99. package/config/content.ts +75 -75
  100. package/config/define.ts +3 -3
  101. package/config/feeds.empty.ts +6 -4
  102. package/config/public.ts +1 -1
  103. package/config/schema.ts +89 -89
  104. package/config/server.ts +1 -1
  105. package/modules/clarity-config/index.ts +162 -159
  106. package/nuxt.config.ts +212 -212
  107. package/package.json +25 -21
  108. package/public/assets/atom.css +274 -274
  109. package/public/assets/atom.xsl +109 -109
  110. package/remark-plugins/rehype-meta-slots.ts +58 -58
  111. package/remark-plugins/remark-code-component.ts +41 -41
  112. package/server/api/stats.get.ts +84 -83
  113. package/server/routes/atom.xml.get.ts +85 -85
  114. package/server/routes/subscriptions.opml.get.ts +64 -64
  115. package/shared/utils/clarity.ts +24 -24
  116. package/shared/utils/icon.ts +218 -218
  117. package/shared/utils/link.ts +52 -52
  118. package/shared/utils/str.ts +88 -88
  119. package/shared/utils/time.ts +115 -115
@@ -1,45 +1,45 @@
1
- <script setup lang="ts">
2
- defineProps<{
3
- hasAside?: boolean
4
- }>()
5
-
6
- const layoutStore = useLayoutStore()
7
- const { avoidTargets } = storeToRefs(layoutStore)
8
-
9
- const panelRef = useTemplateRef('blog-panel')
10
- const { transform } = useAvoidTransform(panelRef, avoidTargets)
11
- </script>
12
-
13
- <template>
14
- <div
15
- id="blog-panel"
16
- ref="blog-panel"
17
- :class="{ 'has-active': layoutStore.state !== 'none' }"
18
- :style="{ transform }"
19
- >
20
- <button
21
- v-if="hasAside"
22
- class="toggle-aside widescreen-only"
23
- :class="{ active: layoutStore.state === 'aside' }"
24
- aria-label="切换侧边栏"
25
- @click="layoutStore.toggle('aside')"
26
- >
27
- <Icon class="rtl-flip" name="tabler:align-right" />
28
- </button>
29
-
30
- <Icon v-show="false" name="tabler:layout-sidebar-filled" />
31
- <button
32
- class="toggle-sidebar mobile-only"
33
- :class="{ active: layoutStore.state === 'sidebar' }"
34
- aria-label="切换菜单"
35
- @click="layoutStore.toggle('sidebar')"
36
- >
37
- <Icon class="rtl-flip" :name="layoutStore.state === 'sidebar' ? 'tabler:layout-sidebar-filled' : 'tabler:layout-sidebar'" />
38
- </button>
39
- </div>
40
- </template>
41
-
42
- <style lang="scss" scoped>
1
+ <script setup lang="ts">
2
+ defineProps<{
3
+ hasAside?: boolean
4
+ }>()
5
+
6
+ const layoutStore = useLayoutStore()
7
+ const { avoidTargets } = storeToRefs(layoutStore)
8
+
9
+ const panelRef = useTemplateRef('blog-panel')
10
+ const { transform } = useAvoidTransform(panelRef, avoidTargets)
11
+ </script>
12
+
13
+ <template>
14
+ <div
15
+ id="blog-panel"
16
+ ref="blog-panel"
17
+ :class="{ 'has-active': layoutStore.state !== 'none' }"
18
+ :style="{ transform }"
19
+ >
20
+ <button
21
+ v-if="hasAside"
22
+ class="toggle-aside widescreen-only"
23
+ :class="{ active: layoutStore.state === 'aside' }"
24
+ aria-label="切换侧边栏"
25
+ @click="layoutStore.toggle('aside')"
26
+ >
27
+ <Icon class="rtl-flip" name="tabler:align-right" />
28
+ </button>
29
+
30
+ <Icon v-show="false" name="tabler:layout-sidebar-filled" />
31
+ <button
32
+ class="toggle-sidebar mobile-only"
33
+ :class="{ active: layoutStore.state === 'sidebar' }"
34
+ aria-label="切换菜单"
35
+ @click="layoutStore.toggle('sidebar')"
36
+ >
37
+ <Icon class="rtl-flip" :name="layoutStore.state === 'sidebar' ? 'tabler:layout-sidebar-filled' : 'tabler:layout-sidebar'" />
38
+ </button>
39
+ </div>
40
+ </template>
41
+
42
+ <style lang="scss" scoped>
43
43
  #blog-panel {
44
44
  contain: paint;
45
45
  position: fixed;
@@ -76,4 +76,4 @@ button {
76
76
  color: var(--c-primary);
77
77
  }
78
78
  }
79
- </style>
79
+ </style>
@@ -1,55 +1,55 @@
1
- <script setup lang="ts">
2
- const clarity = useClarityConfig()
3
- const layoutStore = useLayoutStore()
4
- const searchStore = useSearchStore()
5
-
6
- const { text } = useTextSelection()
7
- const debouncedSelection = refDebounced(text)
8
- </script>
9
-
10
- <template>
11
- <BlogMask
12
- :show="layoutStore.state === 'sidebar'"
13
- class="mobile-only"
14
- @click="layoutStore.close()"
15
- />
16
-
17
- <!-- 不能用 Transition 实现弹出收起动画,因为半宽屏状态始终显示 -->
18
- <aside id="blog-sidebar" :class="{ show: layoutStore.state === 'sidebar' }">
19
- <BlogHeader class="sidebar-header" to="/" />
20
-
21
- <nav class="sidebar-nav scrollcheck-y">
22
- <div class="search-btn sidebar-nav-item gradient-card" @click="layoutStore.toggle('search')">
23
- <Icon name="tabler:search" />
24
- <span class="nav-text">{{ debouncedSelection || searchStore.word || '搜索' }}</span>
25
- <Key class="keycut" code="K" cmd prevent @press="layoutStore.toggle('search')" />
26
- </div>
27
-
28
- <template v-for="(group, groupIndex) in clarity.nav" :key="groupIndex">
29
- <h3 v-if="group.title">
30
- {{ group.title }}
31
- </h3>
32
-
33
- <menu>
34
- <li v-for="(item, itemIndex) in group.items" :key="itemIndex">
35
- <UtilLink :to="item.url" class="sidebar-nav-item">
36
- <Icon :name="item.icon" />
37
- <span class="nav-text">{{ item.text }}</span>
38
- <Icon v-if="isExtLink(item.url)" class="external-tip" name="tabler:arrow-up-right" />
39
- </UtilLink>
40
- </li>
41
- </menu>
42
- </template>
43
- </nav>
44
-
45
- <footer class="sidebar-footer">
46
- <BlogThemeToggle />
47
- <ZIconNavList :list="clarity.footer.iconNav" />
48
- </footer>
49
- </aside>
50
- </template>
51
-
52
- <style lang="scss" scoped>
1
+ <script setup lang="ts">
2
+ const clarity = useClarityConfig()
3
+ const layoutStore = useLayoutStore()
4
+ const searchStore = useSearchStore()
5
+
6
+ const { text } = useTextSelection()
7
+ const debouncedSelection = refDebounced(text)
8
+ </script>
9
+
10
+ <template>
11
+ <BlogMask
12
+ :show="layoutStore.state === 'sidebar'"
13
+ class="mobile-only"
14
+ @click="layoutStore.close()"
15
+ />
16
+
17
+ <!-- 不能用 Transition 实现弹出收起动画,因为半宽屏状态始终显示 -->
18
+ <aside id="blog-sidebar" :class="{ show: layoutStore.state === 'sidebar' }">
19
+ <BlogHeader class="sidebar-header" to="/" />
20
+
21
+ <nav class="sidebar-nav scrollcheck-y">
22
+ <div class="search-btn sidebar-nav-item gradient-card" @click="layoutStore.toggle('search')">
23
+ <Icon name="tabler:search" />
24
+ <span class="nav-text">{{ debouncedSelection || searchStore.word || '搜索' }}</span>
25
+ <Key class="keycut" code="K" cmd prevent @press="layoutStore.toggle('search')" />
26
+ </div>
27
+
28
+ <template v-for="(group, groupIndex) in clarity.nav" :key="groupIndex">
29
+ <h3 v-if="group.title">
30
+ {{ group.title }}
31
+ </h3>
32
+
33
+ <menu>
34
+ <li v-for="(item, itemIndex) in group.items" :key="itemIndex">
35
+ <UtilLink :to="item.url" class="sidebar-nav-item">
36
+ <Icon :name="item.icon" />
37
+ <span class="nav-text">{{ item.text }}</span>
38
+ <Icon v-if="isExtLink(item.url)" class="external-tip" name="tabler:arrow-up-right" />
39
+ </UtilLink>
40
+ </li>
41
+ </menu>
42
+ </template>
43
+ </nav>
44
+
45
+ <footer class="sidebar-footer">
46
+ <BlogThemeToggle />
47
+ <ZIconNavList :list="clarity.footer.iconNav" />
48
+ </footer>
49
+ </aside>
50
+ </template>
51
+
52
+ <style lang="scss" scoped>
53
53
  #blog-sidebar {
54
54
  display: flex;
55
55
  flex-direction: column;
@@ -157,4 +157,4 @@ const debouncedSelection = refDebounced(text)
157
157
  text-align: center;
158
158
  color: var(--c-text-2);
159
159
  }
160
- </style>
160
+ </style>
@@ -1,44 +1,44 @@
1
- <script setup lang="ts">
2
- defineProps<{
3
- title?: string
4
- card?: boolean
5
- shrink?: boolean
6
- grayscale?: boolean
7
- dim?: boolean
8
- bgImg?: string
9
- bgAside?: boolean
10
- }>()
11
-
12
- const body = useTemplateRef('widget-body')
13
-
14
- defineExpose({ body })
15
- </script>
16
-
17
- <template>
18
- <section
19
- class="blog-widget"
20
- :class="{ shrink, grayscale, dim }"
21
- >
22
- <hgroup class="widget-header text-creative">
23
- <slot name="title">
24
- {{ title }}
25
- </slot>
26
- <span v-if="$slots.action" class="seperator" />
27
- <slot name="action" />
28
- </hgroup>
29
-
30
- <div
31
- ref="widget-body"
32
- class="widget-body"
33
- :class="{ 'widget-card': card, 'with-bg': bgImg, 'scrollcheck-y scrollbar-hidden': shrink }"
34
- >
35
- <NuxtImg v-if="bgImg" class="bg-img" :class="{ 'bg-right': bgAside }" :src="bgImg" alt="" />
36
- <slot />
37
- </div>
38
- </section>
39
- </template>
40
-
41
- <style lang="scss" scoped>
1
+ <script setup lang="ts">
2
+ defineProps<{
3
+ title?: string
4
+ card?: boolean
5
+ shrink?: boolean
6
+ grayscale?: boolean
7
+ dim?: boolean
8
+ bgImg?: string
9
+ bgAside?: boolean
10
+ }>()
11
+
12
+ const body = useTemplateRef('widget-body')
13
+
14
+ defineExpose({ body })
15
+ </script>
16
+
17
+ <template>
18
+ <section
19
+ class="blog-widget"
20
+ :class="{ shrink, grayscale, dim }"
21
+ >
22
+ <hgroup class="widget-header text-creative">
23
+ <slot name="title">
24
+ {{ title }}
25
+ </slot>
26
+ <span v-if="$slots.action" class="seperator" />
27
+ <slot name="action" />
28
+ </hgroup>
29
+
30
+ <div
31
+ ref="widget-body"
32
+ class="widget-body"
33
+ :class="{ 'widget-card': card, 'with-bg': bgImg, 'scrollcheck-y scrollbar-hidden': shrink }"
34
+ >
35
+ <NuxtImg v-if="bgImg" class="bg-img" :class="{ 'bg-right': bgAside }" :src="bgImg" alt="" />
36
+ <slot />
37
+ </div>
38
+ </section>
39
+ </template>
40
+
41
+ <style lang="scss" scoped>
42
42
  .blog-widget {
43
43
  flex-shrink: 1;
44
44
  font-size: 0.9em;
@@ -131,4 +131,4 @@ defineExpose({ body })
131
131
  }
132
132
  }
133
133
  }
134
- </style>
134
+ </style>
@@ -1,27 +1,27 @@
1
- <script setup lang="ts">
2
- defineProps<{
3
- blur?: boolean | string
4
- zIndex?: number
5
- }>()
6
-
7
- const show = defineModel<boolean>('show')
8
- </script>
9
-
10
- <template>
11
- <Transition>
12
- <div
13
- v-if="show"
14
- class="bg-mask"
15
- :style="{
16
- '--z-index-popover': zIndex,
17
- '--bdfilter': blur ? `blur(${blur === true ? '4px' : blur})` : 'none',
18
- }"
19
- @click="show = false"
20
- />
21
- </Transition>
22
- </template>
23
-
24
- <style lang="scss" scoped>
1
+ <script setup lang="ts">
2
+ defineProps<{
3
+ blur?: boolean | string
4
+ zIndex?: number
5
+ }>()
6
+
7
+ const show = defineModel<boolean>('show')
8
+ </script>
9
+
10
+ <template>
11
+ <Transition>
12
+ <div
13
+ v-if="show"
14
+ class="bg-mask"
15
+ :style="{
16
+ '--z-index-popover': zIndex,
17
+ '--bdfilter': blur ? `blur(${blur === true ? '4px' : blur})` : 'none',
18
+ }"
19
+ @click="show = false"
20
+ />
21
+ </Transition>
22
+ </template>
23
+
24
+ <style lang="scss" scoped>
25
25
  .bg-mask {
26
26
  position: fixed;
27
27
  inset: 0;
@@ -39,4 +39,4 @@ const show = defineModel<boolean>('show')
39
39
  .v-leave-active {
40
40
  transition: all var(--delay);
41
41
  }
42
- </style>
42
+ </style>
@@ -1,11 +1,11 @@
1
- <template>
2
- <!-- 若使用 NuxtLink 则键盘焦点不会切换 -->
3
- <a href="#main-content" class="skip-link gradient-card active">
4
- 跳转到主要内容 / Skip to content
5
- </a>
6
- </template>
7
-
8
- <style lang="scss" scoped>
1
+ <template>
2
+ <!-- 若使用 NuxtLink 则键盘焦点不会切换 -->
3
+ <a href="#main-content" class="skip-link gradient-card active">
4
+ 跳转到主要内容 / Skip to content
5
+ </a>
6
+ </template>
7
+
8
+ <style lang="scss" scoped>
9
9
  .skip-link {
10
10
  position: fixed;
11
11
  top: -100%;
@@ -19,4 +19,4 @@
19
19
  .skip-link:focus {
20
20
  top: auto;
21
21
  }
22
- </style>
22
+ </style>
@@ -1,24 +1,24 @@
1
- <script setup lang="ts">
2
- const clarity = useClarityConfig()
3
- const colorMode = useColorMode()
4
- </script>
5
-
6
- <template>
7
- <div class="theme-toggle">
8
- <button
9
- v-for="(themeData, themeName) in clarity.themes"
10
- :key="themeName"
11
- v-tip="themeData.tip"
12
- :aria-label="themeData.tip"
13
- :class="{ active: colorMode.preference === themeName }"
14
- @click="colorMode.preference = themeName"
15
- >
16
- <Icon :name="themeData.icon" />
17
- </button>
18
- </div>
19
- </template>
20
-
21
- <style lang="scss" scoped>
1
+ <script setup lang="ts">
2
+ const clarity = useClarityConfig()
3
+ const colorMode = useColorMode()
4
+ </script>
5
+
6
+ <template>
7
+ <div class="theme-toggle">
8
+ <button
9
+ v-for="(themeData, themeName) in clarity.themes"
10
+ :key="themeName"
11
+ v-tip="themeData.tip"
12
+ :aria-label="themeData.tip"
13
+ :class="{ active: colorMode.preference === themeName }"
14
+ @click="colorMode.preference = themeName"
15
+ >
16
+ <Icon :name="themeData.icon" />
17
+ </button>
18
+ </div>
19
+ </template>
20
+
21
+ <style lang="scss" scoped>
22
22
  .theme-toggle {
23
23
  display: flex;
24
24
  gap: 3px;
@@ -47,4 +47,4 @@ const colorMode = useColorMode()
47
47
  }
48
48
  }
49
49
  }
50
- </style>
50
+ </style>
@@ -1,47 +1,47 @@
1
- <script setup lang="ts">
2
- // 即使 boolean 可选,其值也不会是 undefined
3
- const props = defineProps<{
4
- img?: string
5
- text?: string
6
- link?: string
7
- round?: boolean
8
- square?: boolean
9
- }>()
10
-
11
- const img = computed(() => {
12
- if (props.img)
13
- return props.img
14
- const ghUsername = getGithubUsername(props.link)
15
- if (ghUsername)
16
- return getGithubAvatar(ghUsername)
17
- if (props.link && isExtLink(props.link))
18
- return getFavicon(getDomain(props.link))
19
- return ''
20
- })
21
-
22
- // 有图时默认为圆形样式,除非指定为方形
23
- // 无图时默认为方形样式,除非指定为圆形
24
- const round = computed(() => img.value ? !props.square : props.round)
25
-
26
- const tip = computed(() => {
27
- if (!props.link)
28
- return ''
29
- if (isExtLink(props.link))
30
- return getDomain(props.link)
31
- return safelyDecodeUriComponent(props.link)
32
- })
33
- </script>
34
-
35
- <template>
36
- <UtilLink v-tip="tip" class="badge" :class="{ round }" :to="link">
37
- <NuxtImg v-if="img" class="badge-icon" :src="img" alt="" densities="1x" />
38
- <span class="badge-text">
39
- <slot>{{ text }}</slot>
40
- </span>
41
- </UtilLink>
42
- </template>
43
-
44
- <style lang="scss" scoped>
1
+ <script setup lang="ts">
2
+ // 即使 boolean 可选,其值也不会是 undefined
3
+ const props = defineProps<{
4
+ img?: string
5
+ text?: string
6
+ link?: string
7
+ round?: boolean
8
+ square?: boolean
9
+ }>()
10
+
11
+ const img = computed(() => {
12
+ if (props.img)
13
+ return props.img
14
+ const ghUsername = getGithubUsername(props.link)
15
+ if (ghUsername)
16
+ return getGithubAvatar(ghUsername)
17
+ if (props.link && isExtLink(props.link))
18
+ return getFavicon(getDomain(props.link))
19
+ return ''
20
+ })
21
+
22
+ // 有图时默认为圆形样式,除非指定为方形
23
+ // 无图时默认为方形样式,除非指定为圆形
24
+ const round = computed(() => img.value ? !props.square : props.round)
25
+
26
+ const tip = computed(() => {
27
+ if (!props.link)
28
+ return ''
29
+ if (isExtLink(props.link))
30
+ return getDomain(props.link)
31
+ return safelyDecodeUriComponent(props.link)
32
+ })
33
+ </script>
34
+
35
+ <template>
36
+ <UtilLink v-tip="tip" class="badge" :class="{ round }" :to="link">
37
+ <NuxtImg v-if="img" class="badge-icon" :src="img" alt="" densities="1x" />
38
+ <span class="badge-text">
39
+ <slot>{{ text }}</slot>
40
+ </span>
41
+ </UtilLink>
42
+ </template>
43
+
44
+ <style lang="scss" scoped>
45
45
  // 对齐到基线,同时保持图片垂直居中
46
46
  .badge {
47
47
  display: inline-flex;
@@ -87,4 +87,4 @@ const tip = computed(() => {
87
87
  display: none;
88
88
  }
89
89
  }
90
- </style>
90
+ </style>
@@ -1,16 +1,16 @@
1
- <script setup lang="ts">
2
- defineProps<{
3
- text?: string
4
- }>()
5
- </script>
6
-
7
- <template>
8
- <span class="blur">
9
- <slot>{{ text }}</slot>
10
- </span>
11
- </template>
12
-
13
- <style lang="scss" scoped>
1
+ <script setup lang="ts">
2
+ defineProps<{
3
+ text?: string
4
+ }>()
5
+ </script>
6
+
7
+ <template>
8
+ <span class="blur">
9
+ <slot>{{ text }}</slot>
10
+ </span>
11
+ </template>
12
+
13
+ <style lang="scss" scoped>
14
14
  .blur {
15
15
  transition: filter 0.2s;
16
16
  filter: blur(4px);
@@ -19,4 +19,4 @@ defineProps<{
19
19
  filter: blur(0);
20
20
  }
21
21
  }
22
- </style>
22
+ </style>
@@ -1,10 +1,10 @@
1
- <template>
2
- <div class="card-list">
3
- <slot />
4
- </div>
5
- </template>
6
-
7
- <style lang="scss" scoped>
1
+ <template>
2
+ <div class="card-list">
3
+ <slot />
4
+ </div>
5
+ </template>
6
+
7
+ <style lang="scss" scoped>
8
8
  :deep() {
9
9
  :where(ol, ul):not([class]) {
10
10
  margin: 0;
@@ -29,4 +29,4 @@
29
29
  }
30
30
  }
31
31
  }
32
- </style>
32
+ </style>