clarity-theme 0.1.0 → 0.1.2

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 (154) hide show
  1. package/LICENSE +20 -20
  2. package/README.md +70 -4
  3. package/README.zh-CN.md +67 -4
  4. package/nuxt.config.ts +217 -214
  5. package/package.json +35 -37
  6. package/{app → src}/app.config.ts +110 -110
  7. package/{app → src}/app.vue +5 -5
  8. package/{app → src}/components/blog/BlogAside.vue +25 -25
  9. package/{app → src}/components/blog/BlogFooter.vue +25 -25
  10. package/{app → src}/components/blog/BlogHeader.global.vue +48 -48
  11. package/{app → src}/components/blog/BlogPanel.vue +43 -43
  12. package/{app → src}/components/blog/BlogSidebar.vue +53 -53
  13. package/{app → src}/components/blog/BlogWidget.vue +42 -42
  14. package/{app → src}/components/blog/Mask.vue +25 -25
  15. package/{app → src}/components/blog/SkipToContent.vue +9 -9
  16. package/{app → src}/components/blog/ThemeToggle.vue +22 -22
  17. package/{app → src}/components/content/Badge.vue +45 -45
  18. package/{app → src}/components/content/Blur.vue +14 -14
  19. package/{app → src}/components/content/CardList.vue +8 -8
  20. package/{app → src}/components/content/Chat.vue +41 -41
  21. package/{app → src}/components/content/Copy.vue +71 -71
  22. package/{app → src}/components/content/EmojiClock.vue +49 -49
  23. package/{app → src}/components/content/FeedCard.vue +96 -96
  24. package/{app → src}/components/content/FeedGroup.vue +61 -61
  25. package/{app → src}/components/content/Folding.vue +19 -19
  26. package/{app → src}/components/content/Key.vue +143 -143
  27. package/{app → src}/components/content/LinkBanner.vue +27 -27
  28. package/{app → src}/components/content/LinkCard.vue +28 -28
  29. package/{app → src}/components/content/MdTitle.vue +8 -8
  30. package/{app → src}/components/content/Mermaid.vue +99 -99
  31. package/{app → src}/components/content/MusicScore.vue +63 -63
  32. package/{app → src}/components/content/Pic.vue +49 -49
  33. package/{app → src}/components/content/Poetry.vue +27 -27
  34. package/{app → src}/components/content/ProseA.vue +24 -24
  35. package/{app → src}/components/content/ProseCode.vue +16 -16
  36. package/{app → src}/components/content/ProsePre.vue +117 -117
  37. package/{app → src}/components/content/ProseTable.vue +23 -23
  38. package/{app → src}/components/content/Quote.vue +21 -21
  39. package/{app → src}/components/content/Tab.vue +32 -32
  40. package/{app → src}/components/content/Timeline.vue +33 -33
  41. package/{app → src}/components/content/Tip.vue +40 -40
  42. package/{app → src}/components/content/VideoEmbed.vue +112 -112
  43. package/{app → src}/components/partial/Button.vue +36 -36
  44. package/{app → src}/components/partial/DlGroup.vue +31 -31
  45. package/{app → src}/components/partial/Dropdown.vue +21 -21
  46. package/{app → src}/components/partial/Error.vue +39 -39
  47. package/{app → src}/components/partial/Expand.vue +26 -26
  48. package/{app → src}/components/partial/IconNavList.vue +24 -24
  49. package/{app → src}/components/partial/Pagination.vue +62 -62
  50. package/{app → src}/components/partial/RadioGroup.vue +30 -30
  51. package/{app → src}/components/partial/Secret.vue +11 -11
  52. package/{app → src}/components/partial/Slider.vue +48 -48
  53. package/{app → src}/components/partial/Toggle.vue +17 -17
  54. package/{app → src}/components/popover/Lightbox.vue +44 -44
  55. package/{app → src}/components/popover/Search.vue +143 -143
  56. package/{app → src}/components/popover/SearchItem.vue +28 -28
  57. package/{app → src}/components/post/Archive.vue +40 -40
  58. package/{app → src}/components/post/Article.vue +49 -49
  59. package/{app → src}/components/post/Comment.vue +119 -119
  60. package/{app → src}/components/post/Excerpt.vue +40 -40
  61. package/{app → src}/components/post/OrderToggle.vue +70 -70
  62. package/{app → src}/components/post/PostFooter.vue +52 -52
  63. package/{app → src}/components/post/PostHeader.vue +66 -66
  64. package/{app → src}/components/post/PostSurround.vue +51 -51
  65. package/{app → src}/components/post/Slide.vue +85 -85
  66. package/{app → src}/components/util/Date.vue +62 -62
  67. package/{app → src}/components/util/HydrateSafe.vue +10 -10
  68. package/{app → src}/components/util/Img.vue +38 -38
  69. package/{app → src}/components/util/Link.vue +11 -11
  70. package/{app → src}/components/widget/BlogLog.vue +23 -23
  71. package/{app → src}/components/widget/BlogStats.vue +38 -38
  72. package/{app → src}/components/widget/BlogTech.vue +57 -57
  73. package/{app → src}/components/widget/Empty.vue +3 -3
  74. package/{app → src}/components/widget/Toc.vue +67 -67
  75. package/{app → src}/composables/useArticle.ts +115 -115
  76. package/{app → src}/composables/useAvoid.ts +87 -87
  77. package/{app → src}/composables/useCopy.ts +21 -21
  78. package/{app → src}/composables/usePagination.ts +70 -70
  79. package/{app → src}/composables/useShiki.ts +129 -129
  80. package/{app → src}/composables/useToc.ts +57 -57
  81. package/{app → src}/composables/useWidgets.ts +56 -56
  82. package/{config → src/config}/app.ts +62 -62
  83. package/{config → src/config}/content.ts +75 -75
  84. package/{config → src/config}/define.ts +3 -3
  85. package/src/config/feeds.empty.ts +6 -0
  86. package/{config → src/config}/index.ts +1 -1
  87. package/{config → src/config}/schema.ts +89 -89
  88. package/{app → src}/error.vue +31 -31
  89. package/{img → src/img}/index.ts +2 -2
  90. package/{app → src}/layouts/default.vue +25 -25
  91. package/{modules → src/modules}/clarity-config/index.ts +168 -162
  92. package/src/modules/clarity-source-layout/index.ts +78 -0
  93. package/{app → src}/pages/[...slug].vue +59 -59
  94. package/{app → src}/pages/archive.vue +129 -129
  95. package/{app → src}/pages/index.vue +76 -76
  96. package/{app → src}/pages/link.vue +62 -62
  97. package/{app → src}/pages/preview.vue +46 -46
  98. package/{app → src}/plugins/easter-egg.ts +23 -23
  99. package/{app → src}/plugins/init.ts +6 -6
  100. package/{app → src}/plugins/tippy.ts +22 -22
  101. package/{public → src/public}/assets/atom.css +274 -274
  102. package/{public → src/public}/assets/atom.xsl +109 -109
  103. package/{remark-plugins → src/remark-plugins}/rehype-meta-slots.ts +58 -58
  104. package/{remark-plugins → src/remark-plugins}/remark-code-component.ts +41 -41
  105. package/{server → src/server}/api/stats.get.ts +84 -83
  106. package/{server → src/server}/routes/atom.xml.get.ts +85 -85
  107. package/{server → src/server}/routes/subscriptions.opml.get.ts +64 -64
  108. package/{shared → src/shared}/utils/clarity.ts +24 -24
  109. package/{shared → src/shared}/utils/icon.ts +218 -218
  110. package/{shared → src/shared}/utils/link.ts +52 -52
  111. package/{shared → src/shared}/utils/str.ts +88 -88
  112. package/{shared → src/shared}/utils/time.ts +115 -115
  113. package/{app → src}/shiki.config.ts +8 -8
  114. package/{app → src}/stores/layout.ts +34 -34
  115. package/{app → src}/stores/search.ts +37 -37
  116. package/{app → src}/types/article.ts +16 -16
  117. package/src/types/feed.ts +1 -0
  118. package/{app → src}/types/index.ts +14 -14
  119. package/{app → src}/types/nav.ts +11 -11
  120. package/{app → src}/utils/anim.ts +37 -37
  121. package/{app → src}/utils/img.ts +83 -83
  122. package/app/types/feed.ts +0 -1
  123. package/config/feeds.empty.ts +0 -4
  124. package/{app → src}/assets/css/_variable.scss +0 -0
  125. package/{app → src}/assets/css/animation.scss +0 -0
  126. package/{app → src}/assets/css/article.scss +0 -0
  127. package/{app → src}/assets/css/color.scss +0 -0
  128. package/{app → src}/assets/css/font.scss +0 -0
  129. package/{app → src}/assets/css/main.scss +0 -0
  130. package/{app → src}/assets/css/reusable.scss +0 -0
  131. package/{app → src}/assets/icons/solar-rewind-back-bold-duotone.svg +0 -0
  132. package/{app → src}/assets/icons/solar-rewind-forward-bold-duotone.svg +0 -0
  133. package/{app → src}/components/content/Alert.vue +0 -0
  134. package/{config → src/config}/content.d.mts +0 -0
  135. package/{config → src/config}/content.mjs +0 -0
  136. package/{config → src/config}/define.mjs +0 -0
  137. package/{config → src/config}/feed.ts +0 -0
  138. package/{config → src/config}/index.d.mts +0 -0
  139. package/{config → src/config}/index.mjs +0 -0
  140. package/{config → src/config}/public.ts +1 -1
  141. package/{config → src/config}/schema.d.mts +0 -0
  142. package/{config → src/config}/schema.mjs +0 -0
  143. package/{config → src/config}/server.ts +1 -1
  144. /package/{img → src/img}/index.d.mts +0 -0
  145. /package/{img → src/img}/index.mjs +0 -0
  146. /package/{modules → src/modules}/clarity-config/anti-mirror-client.ts +0 -0
  147. /package/{public → src/public}/fonts/AlimamaFangYuanTi.woff2 +0 -0
  148. /package/{remark-plugins → src/remark-plugins}/rehype-meta-slots.d.mts +0 -0
  149. /package/{remark-plugins → src/remark-plugins}/rehype-meta-slots.mjs +0 -0
  150. /package/{remark-plugins → src/remark-plugins}/remark-code-component.d.mts +0 -0
  151. /package/{remark-plugins → src/remark-plugins}/remark-code-component.mjs +0 -0
  152. /package/{server → src/server}/utils/clarity.ts +0 -0
  153. /package/{shared → src/shared}/types/content.ts +0 -0
  154. /package/{app → src}/types/modal.ts +0 -0
@@ -1,19 +1,19 @@
1
- <script setup lang="ts">
2
- defineProps<{
3
- label?: string
4
- }>()
5
-
6
- const modelValue = defineModel<boolean>()
7
- </script>
8
-
9
- <template>
10
- <label class="z-toggle">
11
- <input v-model="modelValue" class="input-toggle" name="toggle" type="checkbox" @keypress.enter="modelValue = !modelValue">
12
- <slot><span v-if="label" v-text="label" /></slot>
13
- </label>
14
- </template>
15
-
16
- <style lang="scss" scoped>
1
+ <script setup lang="ts">
2
+ defineProps<{
3
+ label?: string
4
+ }>()
5
+
6
+ const modelValue = defineModel<boolean>()
7
+ </script>
8
+
9
+ <template>
10
+ <label class="z-toggle">
11
+ <input v-model="modelValue" class="input-toggle" name="toggle" type="checkbox" @keypress.enter="modelValue = !modelValue">
12
+ <slot><span v-if="label" v-text="label" /></slot>
13
+ </label>
14
+ </template>
15
+
16
+ <style lang="scss" scoped>
17
17
  .z-toggle {
18
18
  user-select: none;
19
19
  }
@@ -67,4 +67,4 @@ const modelValue = defineModel<boolean>()
67
67
  }
68
68
  }
69
69
  }
70
- </style>
70
+ </style>
@@ -1,46 +1,46 @@
1
- <script setup lang="ts">
2
- import type { CSSProperties } from 'vue'
3
-
4
- defineProps<{
5
- el: HTMLImageElement
6
- caption?: string | Component
7
- open?: boolean
8
- style?: CSSProperties
9
- }>()
10
-
11
- defineEmits<{
12
- close: []
13
- }>()
14
- </script>
15
-
16
- <template>
17
- <BikariyaImageViewer
18
- v-bind="$attrs"
19
- :target="el"
20
- :open
21
- :style
22
- clamp
23
- :rate=".8"
24
- @close="$emit('close')"
25
- />
26
-
27
- <Transition>
28
- <div v-if="open" class="tooltip" :style="{ zIndex: style?.zIndex }">
29
- <span v-if="caption" class="caption">
30
- <component :is="() => toValue(caption)" />
31
- </span>
32
- <button
33
- class="close"
34
- aria-label="关闭灯箱"
35
- @click="$emit('close')"
36
- >
37
- <Icon name="tabler:x" />
38
- </button>
39
- </div>
40
- </Transition>
41
- </template>
42
-
43
- <style lang="scss" scoped>
1
+ <script setup lang="ts">
2
+ import type { CSSProperties } from 'vue'
3
+
4
+ defineProps<{
5
+ el: HTMLImageElement
6
+ caption?: string | Component
7
+ open?: boolean
8
+ style?: CSSProperties
9
+ }>()
10
+
11
+ defineEmits<{
12
+ close: []
13
+ }>()
14
+ </script>
15
+
16
+ <template>
17
+ <BikariyaImageViewer
18
+ v-bind="$attrs"
19
+ :target="el"
20
+ :open
21
+ :style
22
+ clamp
23
+ :rate=".8"
24
+ @close="$emit('close')"
25
+ />
26
+
27
+ <Transition>
28
+ <div v-if="open" class="tooltip" :style="{ zIndex: style?.zIndex }">
29
+ <span v-if="caption" class="caption">
30
+ <component :is="() => toValue(caption)" />
31
+ </span>
32
+ <button
33
+ class="close"
34
+ aria-label="关闭灯箱"
35
+ @click="$emit('close')"
36
+ >
37
+ <Icon name="tabler:x" />
38
+ </button>
39
+ </div>
40
+ </Transition>
41
+ </template>
42
+
43
+ <style lang="scss" scoped>
44
44
  .tooltip {
45
45
  display: flex;
46
46
  align-items: center;
@@ -74,4 +74,4 @@ defineEmits<{
74
74
  cursor: pointer;
75
75
  }
76
76
  }
77
- </style>
77
+ </style>
@@ -1,146 +1,146 @@
1
- <script setup lang="ts">
1
+ <script setup lang="ts">
2
2
  import type { ModalEmits, ModalProps } from '../../types/modal'
3
- import MiniSearch from 'minisearch'
4
-
5
- const props = defineProps<ModalProps>()
6
-
7
- defineEmits<ModalEmits>()
8
-
9
- const clarity = useClarityConfig()
10
- const segmenter = Intl.Segmenter && new Intl.Segmenter(clarity.site.language, { granularity: 'word' })
11
-
12
- // await useAsyncData() 会阻塞渲染
13
- const { data, status } = await useLazyAsyncData(
14
- 'search',
15
- () => queryCollectionSearchSections('content', {
16
- ignoredTags: ['pre'],
17
- }),
18
- )
19
-
20
- const miniSearch = new MiniSearch({
21
- fields: ['title', 'content'],
22
- storeFields: ['title', 'titles', 'content', 'level'],
23
- searchOptions: {
24
- prefix: true,
25
- fuzzy: 0.2,
26
- combineWith: 'AND',
27
- boost: { title: 3, titles: 2 },
28
- },
29
- processTerm: segmenter
30
- ? term => Array.from(segmenter.segment(term), seg => seg.segment.toLowerCase())
31
- : undefined,
32
- })
33
-
34
- const searchStore = useSearchStore()
35
- const searchInput = ref<HTMLInputElement>()
36
-
37
- const { word, debouncedWord } = storeToRefs(searchStore)
38
- const result = computed(() => {
39
- void data.value
40
- return miniSearch.search(debouncedWord.value)
41
- })
42
-
43
- const isKeyboardMode = ref(false)
44
- const listResult = useTemplateRef('list-result')
45
-
46
- const activeIndex = ref(0)
47
- const activeItem = computed(() => listResult.value?.children[activeIndex.value] as HTMLLinkElement | undefined)
48
-
49
- whenever(() => props.open, focusInput)
50
-
51
- watch(status, (newStatus) => {
52
- if (newStatus === 'success' && data.value) {
53
- miniSearch.addAll(data.value)
54
- }
55
- })
56
-
57
- watch(debouncedWord, () => {
58
- activeIndex.value = 0
59
- })
60
-
61
- useEventListener('mousemove', () => isKeyboardMode.value = false)
62
- useEventListener('keydown', () => isKeyboardMode.value = true)
63
-
64
- async function focusInput(allSelect = false) {
65
- await nextTick()
66
- searchInput.value?.focus()
67
- if (allSelect)
68
- searchInput.value?.select()
69
- }
70
-
71
- function updateActiveIndex(index: number, isKeyboard = false) {
72
- focusInput()
73
- if (index < 0 || index >= result.value?.length)
74
- return
75
- activeIndex.value = index
76
- if (isKeyboard)
77
- isKeyboardMode.value = true
78
- if (activeItem.value && isKeyboardMode.value) {
79
- activeItem.value.scrollIntoView({ block: 'nearest' })
80
- }
81
- }
82
-
83
- function openActiveItem() {
84
- // 触发 vue-router 点击事件
85
- activeItem.value?.click()
86
- }
87
- </script>
88
-
89
- <template>
90
- <Transition name="float-in">
91
- <div v-if="open" class="blog-search">
92
- <form class="input" @submit.prevent>
93
- <Icon v-show="false" name="line-md:loading-alt-loop" />
94
- <Icon :name="status === 'pending' ? 'line-md:loading-alt-loop' : 'tabler:search'" />
95
-
96
- <!-- 方向键切换搜索结果不应只在搜索框内触发 -->
97
- <input
98
- ref="searchInput"
99
- v-model="word"
100
- type="search"
101
- incremental
102
- class="search-input"
103
- placeholder="键入开始搜索"
104
- @keydown.up.prevent
105
- @keydown.down.prevent
106
- >
107
- </form>
108
-
109
- <TransitionGroup name="expand">
110
- <div v-if="debouncedWord && status === 'success' && !result.length" class="no-result">
111
- 无结果
112
- </div>
113
-
114
- <menu
115
- v-if="result.length"
116
- ref="list-result"
117
- :key="result.length < 5 ? result.length : result[0]?.id"
118
- class="scrollcheck-y search-result"
119
- >
120
- <PopoverSearchItem
121
- v-for="(item, itemIndex) in result"
122
- :key="item.id"
123
- v-bind="item"
124
- :class="{ active: activeIndex === itemIndex }"
125
- @mousemove="updateActiveIndex(itemIndex)"
126
- />
127
- </menu>
128
-
129
- <div v-if="result.length" class="tip" @click="searchInput?.focus()">
130
- <Key code="ArrowUp" prevent @press="updateActiveIndex(activeIndex - 1, true)" />
131
- <Key code="ArrowDown" prevent @press="updateActiveIndex(activeIndex + 1, true)" />
132
- 切换&emsp;
133
- <Key code="Enter" icon @press="openActiveItem" />
134
- 选择&emsp;
135
- <Key code="Escape" :icon="false" @press="$emit('close')" />
136
- 关闭
137
- </div>
138
- </TransitionGroup>
139
- </div>
140
- </Transition>
141
- </template>
142
-
143
- <style lang="scss" scoped>
3
+ import MiniSearch from 'minisearch'
4
+
5
+ const props = defineProps<ModalProps>()
6
+
7
+ defineEmits<ModalEmits>()
8
+
9
+ const clarity = useClarityConfig()
10
+ const segmenter = Intl.Segmenter && new Intl.Segmenter(clarity.site.language, { granularity: 'word' })
11
+
12
+ // await useAsyncData() 会阻塞渲染
13
+ const { data, status } = await useLazyAsyncData(
14
+ 'search',
15
+ () => queryCollectionSearchSections('content', {
16
+ ignoredTags: ['pre'],
17
+ }),
18
+ )
19
+
20
+ const miniSearch = new MiniSearch({
21
+ fields: ['title', 'content'],
22
+ storeFields: ['title', 'titles', 'content', 'level'],
23
+ searchOptions: {
24
+ prefix: true,
25
+ fuzzy: 0.2,
26
+ combineWith: 'AND',
27
+ boost: { title: 3, titles: 2 },
28
+ },
29
+ processTerm: segmenter
30
+ ? term => Array.from(segmenter.segment(term), seg => seg.segment.toLowerCase())
31
+ : undefined,
32
+ })
33
+
34
+ const searchStore = useSearchStore()
35
+ const searchInput = ref<HTMLInputElement>()
36
+
37
+ const { word, debouncedWord } = storeToRefs(searchStore)
38
+ const result = computed(() => {
39
+ void data.value
40
+ return miniSearch.search(debouncedWord.value)
41
+ })
42
+
43
+ const isKeyboardMode = ref(false)
44
+ const listResult = useTemplateRef('list-result')
45
+
46
+ const activeIndex = ref(0)
47
+ const activeItem = computed(() => listResult.value?.children[activeIndex.value] as HTMLLinkElement | undefined)
48
+
49
+ whenever(() => props.open, focusInput)
50
+
51
+ watch(status, (newStatus) => {
52
+ if (newStatus === 'success' && data.value) {
53
+ miniSearch.addAll(data.value)
54
+ }
55
+ })
56
+
57
+ watch(debouncedWord, () => {
58
+ activeIndex.value = 0
59
+ })
60
+
61
+ useEventListener('mousemove', () => isKeyboardMode.value = false)
62
+ useEventListener('keydown', () => isKeyboardMode.value = true)
63
+
64
+ async function focusInput(allSelect = false) {
65
+ await nextTick()
66
+ searchInput.value?.focus()
67
+ if (allSelect)
68
+ searchInput.value?.select()
69
+ }
70
+
71
+ function updateActiveIndex(index: number, isKeyboard = false) {
72
+ focusInput()
73
+ if (index < 0 || index >= result.value?.length)
74
+ return
75
+ activeIndex.value = index
76
+ if (isKeyboard)
77
+ isKeyboardMode.value = true
78
+ if (activeItem.value && isKeyboardMode.value) {
79
+ activeItem.value.scrollIntoView({ block: 'nearest' })
80
+ }
81
+ }
82
+
83
+ function openActiveItem() {
84
+ // 触发 vue-router 点击事件
85
+ activeItem.value?.click()
86
+ }
87
+ </script>
88
+
89
+ <template>
90
+ <Transition name="float-in">
91
+ <div v-if="open" class="blog-search">
92
+ <form class="input" @submit.prevent>
93
+ <Icon v-show="false" name="line-md:loading-alt-loop" />
94
+ <Icon :name="status === 'pending' ? 'line-md:loading-alt-loop' : 'tabler:search'" />
95
+
96
+ <!-- 方向键切换搜索结果不应只在搜索框内触发 -->
97
+ <input
98
+ ref="searchInput"
99
+ v-model="word"
100
+ type="search"
101
+ incremental
102
+ class="search-input"
103
+ placeholder="键入开始搜索"
104
+ @keydown.up.prevent
105
+ @keydown.down.prevent
106
+ >
107
+ </form>
108
+
109
+ <TransitionGroup name="expand">
110
+ <div v-if="debouncedWord && status === 'success' && !result.length" class="no-result">
111
+ 无结果
112
+ </div>
113
+
114
+ <menu
115
+ v-if="result.length"
116
+ ref="list-result"
117
+ :key="result.length < 5 ? result.length : result[0]?.id"
118
+ class="scrollcheck-y search-result"
119
+ >
120
+ <PopoverSearchItem
121
+ v-for="(item, itemIndex) in result"
122
+ :key="item.id"
123
+ v-bind="item"
124
+ :class="{ active: activeIndex === itemIndex }"
125
+ @mousemove="updateActiveIndex(itemIndex)"
126
+ />
127
+ </menu>
128
+
129
+ <div v-if="result.length" class="tip" @click="searchInput?.focus()">
130
+ <Key code="ArrowUp" prevent @press="updateActiveIndex(activeIndex - 1, true)" />
131
+ <Key code="ArrowDown" prevent @press="updateActiveIndex(activeIndex + 1, true)" />
132
+ 切换&emsp;
133
+ <Key code="Enter" icon @press="openActiveItem" />
134
+ 选择&emsp;
135
+ <Key code="Escape" :icon="false" @press="$emit('close')" />
136
+ 关闭
137
+ </div>
138
+ </TransitionGroup>
139
+ </div>
140
+ </Transition>
141
+ </template>
142
+
143
+ <style lang="scss" scoped>
144
144
  .blog-search {
145
145
  --float-distance: 20vh;
146
146
 
@@ -211,4 +211,4 @@ function openActiveItem() {
211
211
  opacity: 0;
212
212
  max-height: 0;
213
213
  }
214
- </style>
214
+ </style>
@@ -1,30 +1,30 @@
1
- <script setup lang="ts">
2
- import type { SearchResult } from 'minisearch'
3
-
4
- interface SearchItem extends SearchResult {
5
- title: string
6
- content: string
7
- titles: string[]
8
- level: number
9
- }
10
-
11
- withDefaults(defineProps<Partial<SearchItem>>(), {
12
- titles: () => [],
13
- title: '',
14
- })
15
- </script>
16
-
17
- <template>
18
- <UtilLink :to="id" class="search-item">
19
- <hgroup class="text-creative">
20
- <span v-for="heading in [...titles, title]" :key="heading" class="title" v-html="highlightHtml(heading, queryTerms)" />
21
- <Icon v-if="level === 1" name="tabler:file-text" />
22
- </hgroup>
23
- <p v-if="content" class="content" v-html="highlightHtml(content, queryTerms)" />
24
- </UtilLink>
25
- </template>
26
-
27
- <style lang="scss" scoped>
1
+ <script setup lang="ts">
2
+ import type { SearchResult } from 'minisearch'
3
+
4
+ interface SearchItem extends SearchResult {
5
+ title: string
6
+ content: string
7
+ titles: string[]
8
+ level: number
9
+ }
10
+
11
+ withDefaults(defineProps<Partial<SearchItem>>(), {
12
+ titles: () => [],
13
+ title: '',
14
+ })
15
+ </script>
16
+
17
+ <template>
18
+ <UtilLink :to="id" class="search-item">
19
+ <hgroup class="text-creative">
20
+ <span v-for="heading in [...titles, title]" :key="heading" class="title" v-html="highlightHtml(heading, queryTerms)" />
21
+ <Icon v-if="level === 1" name="tabler:file-text" />
22
+ </hgroup>
23
+ <p v-if="content" class="content" v-html="highlightHtml(content, queryTerms)" />
24
+ </UtilLink>
25
+ </template>
26
+
27
+ <style lang="scss" scoped>
28
28
  .search-item {
29
29
  display: block;
30
30
  margin: 0.5em;
@@ -61,4 +61,4 @@ withDefaults(defineProps<Partial<SearchItem>>(), {
61
61
  white-space: pre-wrap;
62
62
  color: var(--c-text-2);
63
63
  }
64
- </style>
64
+ </style>
@@ -1,42 +1,42 @@
1
- <script setup lang="ts">
2
- import type { ArticleProps } from '../../types/article'
3
-
4
- const props = defineProps<{
5
- to?: string
6
- useUpdated?: boolean
7
- showCategory?: boolean
8
- } & ArticleProps>()
9
-
10
- const mainDate = computed(() => props.useUpdated ? props.updated : props.date)
11
- </script>
12
-
13
- <template>
14
- <li class="article-item">
15
- <UtilDate class="dim-hover" :date="mainDate" format="monthDay" />
16
-
17
- <div class="gradient-card" :style="{ '--c-accent': getCategoryColor(categories?.[0]) }">
18
- <UtilLink class="article-link scrollbar-hidden scrollcheck-x" :to :title="description">
19
- <span class="article-title">
20
- <Icon v-if="showCategory" :name="getCategoryIcon(categories?.[0])" />
21
- {{ title }}
22
- </span>
23
-
24
- <UtilDate
25
- v-if="date && useUpdated && isTimeDiffSignificant(date, updated)"
26
- class="dim-hover info"
27
- :date="date"
28
- :format="updated && isSameUnit(date, updated, 'year') ? 'monthDay' : 'date'"
29
- />
30
-
31
- <ul v-if="tags?.length" class="dim-hover info tag-list">
32
- <li v-for="tag in tags" :key="tag" v-text="tag" />
33
- </ul>
34
- </UtilLink>
35
- </div>
36
- </li>
37
- </template>
38
-
39
- <style lang="scss" scoped>
1
+ <script setup lang="ts">
2
+ import type { ArticleProps } from '../../types/article'
3
+
4
+ const props = defineProps<{
5
+ to?: string
6
+ useUpdated?: boolean
7
+ showCategory?: boolean
8
+ } & ArticleProps>()
9
+
10
+ const mainDate = computed(() => props.useUpdated ? props.updated : props.date)
11
+ </script>
12
+
13
+ <template>
14
+ <li class="article-item">
15
+ <UtilDate class="dim-hover" :date="mainDate" format="monthDay" />
16
+
17
+ <div class="gradient-card" :style="{ '--c-accent': getCategoryColor(categories?.[0]) }">
18
+ <UtilLink class="article-link scrollbar-hidden scrollcheck-x" :to :title="description">
19
+ <span class="article-title">
20
+ <Icon v-if="showCategory" :name="getCategoryIcon(categories?.[0])" />
21
+ {{ title }}
22
+ </span>
23
+
24
+ <UtilDate
25
+ v-if="date && useUpdated && isTimeDiffSignificant(date, updated)"
26
+ class="dim-hover info"
27
+ :date="date"
28
+ :format="updated && isSameUnit(date, updated, 'year') ? 'monthDay' : 'date'"
29
+ />
30
+
31
+ <ul v-if="tags?.length" class="dim-hover info tag-list">
32
+ <li v-for="tag in tags" :key="tag" v-text="tag" />
33
+ </ul>
34
+ </UtilLink>
35
+ </div>
36
+ </li>
37
+ </template>
38
+
39
+ <style lang="scss" scoped>
40
40
  .article-item {
41
41
  display: flex;
42
42
  align-items: center;
@@ -101,4 +101,4 @@ const mainDate = computed(() => props.useUpdated ? props.updated : props.date)
101
101
  }
102
102
  }
103
103
  }
104
- </style>
104
+ </style>