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,64 +1,64 @@
1
- <script setup lang="ts">
2
- const props = defineProps<{
3
- totalPages: number
4
- expandPages?: number
5
- sticky?: boolean
6
- avoid?: boolean
7
- }>()
8
-
9
- const page = defineModel<number>({ required: true })
10
- const pageArr = computed(() => getPaginationIndicator(page.value, props.totalPages, props.expandPages ?? 2))
11
-
12
- const paginationEl = useTemplateRef('pagination')
13
- const anchorEl = useTemplateRef('pagination-anchor')
14
- const expand = useElementVisibility(anchorEl)
15
-
16
- if (props.avoid) {
17
- useAvoidTarget(paginationEl, toRef(props, 'avoid'))
18
- }
19
- </script>
20
-
21
- <template>
22
- <nav
23
- ref="pagination"
24
- class="pagination"
25
- :class="{ sticky, expand }"
26
- :aria-label="`第${page}页,共${totalPages}页`"
27
- :style="{ '--collapsed-width': `${pageArr.length * 2 + 6}em` }"
28
- >
29
- <ZButton
30
- :disabled="page <= 1"
31
- class="pagination-button rtl-flip"
32
- icon="tabler:arrow-left"
33
- aria-label="上一页"
34
- @click="page--"
35
- />
36
- <template v-for="i in pageArr" :key="i">
37
- <button
38
- v-if="Number.isFinite(i)"
39
- class="pagination-num"
40
- :class="{ active: i === page }"
41
- :aria-label="`第${i}页`"
42
- @click="page = i"
43
- v-text="i"
44
- />
45
- <!-- TODO: 点击后自主选择目标页面 -->
46
- <button v-else disabled class="pagination-num">
47
- …
48
- </button>
49
- </template>
50
- <ZButton
51
- :disabled="page >= totalPages"
52
- class="pagination-button rtl-flip"
53
- icon="tabler:arrow-right"
54
- aria-label="下一页"
55
- @click="page++"
56
- />
57
- </nav>
58
- <div ref="pagination-anchor" />
59
- </template>
60
-
61
- <style lang="scss" scoped>
1
+ <script setup lang="ts">
2
+ const props = defineProps<{
3
+ totalPages: number
4
+ expandPages?: number
5
+ sticky?: boolean
6
+ avoid?: boolean
7
+ }>()
8
+
9
+ const page = defineModel<number>({ required: true })
10
+ const pageArr = computed(() => getPaginationIndicator(page.value, props.totalPages, props.expandPages ?? 2))
11
+
12
+ const paginationEl = useTemplateRef('pagination')
13
+ const anchorEl = useTemplateRef('pagination-anchor')
14
+ const expand = useElementVisibility(anchorEl)
15
+
16
+ if (props.avoid) {
17
+ useAvoidTarget(paginationEl, toRef(props, 'avoid'))
18
+ }
19
+ </script>
20
+
21
+ <template>
22
+ <nav
23
+ ref="pagination"
24
+ class="pagination"
25
+ :class="{ sticky, expand }"
26
+ :aria-label="`第${page}页,共${totalPages}页`"
27
+ :style="{ '--collapsed-width': `${pageArr.length * 2 + 6}em` }"
28
+ >
29
+ <ZButton
30
+ :disabled="page <= 1"
31
+ class="pagination-button rtl-flip"
32
+ icon="tabler:arrow-left"
33
+ aria-label="上一页"
34
+ @click="page--"
35
+ />
36
+ <template v-for="i in pageArr" :key="i">
37
+ <button
38
+ v-if="Number.isFinite(i)"
39
+ class="pagination-num"
40
+ :class="{ active: i === page }"
41
+ :aria-label="`第${i}页`"
42
+ @click="page = i"
43
+ v-text="i"
44
+ />
45
+ <!-- TODO: 点击后自主选择目标页面 -->
46
+ <button v-else disabled class="pagination-num">
47
+ …
48
+ </button>
49
+ </template>
50
+ <ZButton
51
+ :disabled="page >= totalPages"
52
+ class="pagination-button rtl-flip"
53
+ icon="tabler:arrow-right"
54
+ aria-label="下一页"
55
+ @click="page++"
56
+ />
57
+ </nav>
58
+ <div ref="pagination-anchor" />
59
+ </template>
60
+
61
+ <style lang="scss" scoped>
62
62
  .pagination {
63
63
  display: flex;
64
64
  max-width: calc(100vw);
@@ -110,4 +110,4 @@ if (props.avoid) {
110
110
  }
111
111
  }
112
112
  }
113
- </style>
113
+ </style>
@@ -1,32 +1,32 @@
1
- <script setup lang="ts" generic="T">
2
- interface RadioItem {
3
- label?: string
4
- value: T
5
- }
6
-
7
- defineProps<{
8
- items: RadioItem[]
9
- }>()
10
-
11
- const modelValue = defineModel<T>()
12
- </script>
13
-
14
- <template>
15
- <div class="z-radio-group">
16
- <button
17
- v-for="{ label, value }, i in items"
18
- :key="i"
19
- type="button"
20
- class="radio-item"
21
- :class="{ active: value === modelValue }"
22
- @click="modelValue = value"
23
- >
24
- {{ label || value }}
25
- </button>
26
- </div>
27
- </template>
28
-
29
- <style lang="scss" scoped>
1
+ <script setup lang="ts" generic="T">
2
+ interface RadioItem {
3
+ label?: string
4
+ value: T
5
+ }
6
+
7
+ defineProps<{
8
+ items: RadioItem[]
9
+ }>()
10
+
11
+ const modelValue = defineModel<T>()
12
+ </script>
13
+
14
+ <template>
15
+ <div class="z-radio-group">
16
+ <button
17
+ v-for="{ label, value }, i in items"
18
+ :key="i"
19
+ type="button"
20
+ class="radio-item"
21
+ :class="{ active: value === modelValue }"
22
+ @click="modelValue = value"
23
+ >
24
+ {{ label || value }}
25
+ </button>
26
+ </div>
27
+ </template>
28
+
29
+ <style lang="scss" scoped>
30
30
  .z-radio-group {
31
31
  display: flex;
32
32
  margin: 1em 0;
@@ -74,4 +74,4 @@ const modelValue = defineModel<T>()
74
74
  border-inline-start: 1px solid var(--c-bg-soft);
75
75
  }
76
76
  }
77
- </style>
77
+ </style>
@@ -1,13 +1,13 @@
1
- <template>
2
- <!-- 外层元素用于占位 -->
3
- <div class="secret-container">
4
- <div class="secret">
5
- <slot />
6
- </div>
7
- </div>
8
- </template>
9
-
10
- <style lang="scss" scoped>
1
+ <template>
2
+ <!-- 外层元素用于占位 -->
3
+ <div class="secret-container">
4
+ <div class="secret">
5
+ <slot />
6
+ </div>
7
+ </div>
8
+ </template>
9
+
10
+ <style lang="scss" scoped>
11
11
  .secret {
12
12
  position: relative;
13
13
  opacity: 0;
@@ -20,4 +20,4 @@
20
20
  z-index: 0;
21
21
  }
22
22
  }
23
- </style>
23
+ </style>
@@ -1,50 +1,50 @@
1
- <script setup lang="ts">
2
- const props = defineProps<{
3
- label?: string
4
- springMin?: number
5
- springMax?: number
6
- list?: (string | { value: string, label?: string })[]
7
- }>()
8
-
9
- const modelValue = defineModel<number>({ required: true })
10
- const initialValue = modelValue.value
11
- const id = useId()
12
- const list = computed(() => props.list?.map(v => typeof v === 'string' ? { value: v } : v))
13
-
14
- function spring() {
15
- if (props.springMin !== undefined && modelValue.value < props.springMin) {
16
- modelValue.value = props.springMin
17
- }
18
- if (props.springMax !== undefined && modelValue.value > props.springMax) {
19
- modelValue.value = props.springMax
20
- }
21
- }
22
- const debounceSpring = useDebounceFn(spring, 500)
23
- </script>
24
-
25
- <template>
26
- <label class="z-slider">
27
- <slot><span v-if="label" v-text="label" /></slot>
28
-
29
- <input
30
- v-bind="$attrs"
31
- v-model.number="modelValue"
32
- class="input-slider"
33
- type="range"
34
- :list="id"
35
- @change="debounceSpring"
36
- @dblclick="modelValue = initialValue"
37
- >
38
-
39
- <data class="data-value" :value="modelValue" v-text="modelValue" />
40
-
41
- <datalist v-if="list" :id="id">
42
- <option v-for="{ value, label: text } in list" :key="value" :value :label="text" />
43
- </datalist>
44
- </label>
45
- </template>
46
-
47
- <style lang="scss" scoped>
1
+ <script setup lang="ts">
2
+ const props = defineProps<{
3
+ label?: string
4
+ springMin?: number
5
+ springMax?: number
6
+ list?: (string | { value: string, label?: string })[]
7
+ }>()
8
+
9
+ const modelValue = defineModel<number>({ required: true })
10
+ const initialValue = modelValue.value
11
+ const id = useId()
12
+ const list = computed(() => props.list?.map(v => typeof v === 'string' ? { value: v } : v))
13
+
14
+ function spring() {
15
+ if (props.springMin !== undefined && modelValue.value < props.springMin) {
16
+ modelValue.value = props.springMin
17
+ }
18
+ if (props.springMax !== undefined && modelValue.value > props.springMax) {
19
+ modelValue.value = props.springMax
20
+ }
21
+ }
22
+ const debounceSpring = useDebounceFn(spring, 500)
23
+ </script>
24
+
25
+ <template>
26
+ <label class="z-slider">
27
+ <slot><span v-if="label" v-text="label" /></slot>
28
+
29
+ <input
30
+ v-bind="$attrs"
31
+ v-model.number="modelValue"
32
+ class="input-slider"
33
+ type="range"
34
+ :list="id"
35
+ @change="debounceSpring"
36
+ @dblclick="modelValue = initialValue"
37
+ >
38
+
39
+ <data class="data-value" :value="modelValue" v-text="modelValue" />
40
+
41
+ <datalist v-if="list" :id="id">
42
+ <option v-for="{ value, label: text } in list" :key="value" :value :label="text" />
43
+ </datalist>
44
+ </label>
45
+ </template>
46
+
47
+ <style lang="scss" scoped>
48
48
  .z-slider {
49
49
  display: flex;
50
50
  align-items: center;
@@ -93,4 +93,4 @@ const debounceSpring = useDebounceFn(spring, 500)
93
93
  min-width: var(--slider-value, 3ch);
94
94
  text-align: right;
95
95
  }
96
- </style>
96
+ </style>
@@ -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>