Skip to content

Commit 8a3cb45

Browse files
committed
fix: 🐞 修复代码块配置项 codeBlock 失效问题
1 parent 774dd94 commit 8a3cb45

File tree

9 files changed

+133
-145
lines changed

9 files changed

+133
-145
lines changed

README.md

-2
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,8 @@ pnpm plugin:build
5151

5252
## TODO
5353

54-
- permalink 重新点击菜单不重新加载,permalink 导航栏同级文档访问不高亮问题
5554
- Banner 支持半图背景
5655
- 文章页添加 updateTime
57-
- 代码块 codeBlock 配置没有关闭 md 文档和样式,支持官方 [xxx] 命名
5856
- 新增、删除、修改 md 后自动重启,参考 Vitepress 修改 config 重启方式
5957
- 主题使用文档编写
6058
- 部署测试、线上效果测试

docs/10.配置/01.主题配置/15.文章列表配置.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -122,4 +122,4 @@ import type { PaginationProps } from "element-plus";
122122
page?: Partial<PaginationProps>;
123123
```
124124

125-
:::
125+
:::

vitepress-theme-teeker/src/components/CodeBlockToggle/src/index.vue

+31-19
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,52 @@
11
<script setup lang="ts" name="CodeBlockToggle">
2-
import { nextTick, watch } from "vue";
3-
import { useRoute } from "vitepress";
2+
import { nextTick, unref, watch } from "vue";
3+
import { useRoute, useData } from "vitepress";
44
import { useNamespace } from "../../../hooks";
5+
import arrowSvg from "../../../assets/svg/arrow";
56
67
defineOptions({ name: "CodeBlockToggle" });
78
89
const ns = useNamespace("");
10+
const { frontmatter, theme } = useData();
911
12+
const documentAttribute = "code-block";
1013
const foldClass = "fold";
1114
const arrowClass = "code-arrow";
1215
16+
if (unref(theme).codeBlock !== false) {
17+
const route = useRoute();
18+
19+
watch(
20+
route,
21+
() => {
22+
const { codeBlock = true } = unref(frontmatter);
23+
if (codeBlock == false) return document.documentElement.removeAttribute(documentAttribute);
24+
25+
document.documentElement.setAttribute(documentAttribute, ns.namespace);
26+
nextTick(() => initCodeBlock());
27+
},
28+
{ immediate: true }
29+
);
30+
}
31+
1332
/**
1433
* 初始化代码块
1534
*/
1635
const initCodeBlock = () => {
1736
const modes = document.querySelectorAll(".vp-doc div[class*='language-']") as unknown as HTMLElement[];
1837
1938
Array.from(modes).forEach(item => {
20-
// 获取箭头元素,箭头元素已经在 src/markdown/plugins/codeArrow.ts 中通过 MD 插件添加
2139
const arrowElement: HTMLElement | null = item.querySelector(`.${arrowClass}`);
22-
if (!arrowElement) return;
23-
addClickEvent(arrowElement, item);
24-
25-
// 下面代码是第一版功能:手动创建箭头元素,然后添加点击事件,最后 append 到代码块元素的最后面
26-
// if (arrowElement) return;
27-
// const arrowElement: HTMLElement | null = document.createElement("div");
28-
// arrowElement.classList.add(arrowClass);
29-
// // 添加箭头图标
30-
// arrowElement.innerHTML = arrowSvg;
31-
// // 给箭头图标添加点击事件
32-
// addClickEvent(arrowElement, item);
33-
// item.append(arrowElement);
40+
// 手动创建箭头元素,然后添加点击事件,最后 append 到代码块元素的最后面
41+
if (arrowElement) return;
42+
43+
const newArrowElement: HTMLElement | null = document.createElement("div");
44+
newArrowElement.classList.add(arrowClass);
45+
// 添加箭头图标
46+
newArrowElement.innerHTML = arrowSvg;
47+
// 给箭头图标添加点击事件
48+
addClickEvent(newArrowElement, item);
49+
item.append(newArrowElement);
3450
});
3551
};
3652
@@ -95,10 +111,6 @@ const getElementHeight = (item: HTMLElement) => {
95111
item.style.display = "";
96112
return height;
97113
};
98-
99-
const route = useRoute();
100-
101-
watch(route, () => nextTick(() => initCodeBlock()), { immediate: true });
102114
</script>
103115

104116
<template></template>

vitepress-theme-teeker/src/config/index.ts

+2-4
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import DocAnalysis from "vitepress-plugin-doc-analysis";
1010
import FileContentLoader, { FileContentLoaderOptions } from "vitepress-plugin-file-content-loader";
1111
import AutoFrontmatter from "vitepress-plugin-auto-frontmatter";
1212
import { transformData, transformRaw } from "../post";
13-
import { todoPlugin, shareCardPlugin, imgCardPlugin, navCardPlugin, codeArrowPlugin } from "../markdown";
13+
import { todoPlugin, shareCardPlugin, imgCardPlugin, navCardPlugin } from "../markdown";
1414
import { createCategory, createPermalink } from "./addFrontmatter";
1515
import { containerPlugins, createContainersThenUse } from "../markdown/plugins/container";
1616

@@ -151,9 +151,7 @@ export default function tkThemeConfig(config: TkThemeConfig & UserConfig<Default
151151
config: md => {
152152
md.use(containerPlugins, containerLabel);
153153

154-
[todoPlugin, shareCardPlugin, imgCardPlugin, navCardPlugin, codeArrowPlugin].forEach(plugin =>
155-
md.use(plugin, containerLabel)
156-
);
154+
[todoPlugin, shareCardPlugin, imgCardPlugin, navCardPlugin].forEach(plugin => md.use(plugin, containerLabel));
157155

158156
// 创建用户配置的自定义容器
159157
createContainersThenUse(md, markdownContainers);

vitepress-theme-teeker/src/layout/index.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ const commentConfig = computed(() => {
112112
<ArticleAnalyze />
113113
<ArticleImagePreview />
114114
<ArticlePageStyle />
115-
<CodeBlockToggle v-if="themeConfig.codeBlock" />
115+
<CodeBlockToggle />
116116
</ClientOnly>
117117
<slot name="teeker-article-analyze-after" />
118118
</template>

vitepress-theme-teeker/src/markdown/index.ts

-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,3 @@ export { default as todoPlugin } from "./plugins/todo";
22
export { default as shareCardPlugin } from "./plugins/shareCard";
33
export { default as imgCardPlugin } from "./plugins/imgCard";
44
export { default as navCardPlugin } from "./plugins/navCard";
5-
export { default as codeArrowPlugin } from "./plugins/codeArrow";

vitepress-theme-teeker/src/markdown/plugins/codeArrow.ts

-20
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,93 +1,117 @@
11
@use "../mixins/function" as *;
22
@use "../mixins/config" as *;
3-
@use "../md-plugin/code-arrow";
43

5-
// 因为 stroke 无法直接写 var(--vp-c-text-1),所以只能写死 var(--vp-c-text-1) 的具体颜色,如果改动了 var(--vp-c-text-1) 的值,则需要修改 stroke 为对于的值
6-
:root {
7-
/* clipboard */
8-
--vp-icon-copy: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='rgba(60,60,67,1)' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='8' height='4' x='8' y='2' rx='1' ry='1'/%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2'/%3E%3C/svg%3E");
9-
/* clipboard-copy */
10-
--vp-icon-copied: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='rgba(60,60,67,1)' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='8' height='4' x='8' y='2' rx='1' ry='1'/%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2'/%3E%3Cpath d='m9 14 2 2 4-4'/%3E%3C/svg%3E");
11-
}
4+
html[code-block="#{$namespace}"] {
5+
// 因为 stroke 无法直接写 var(--vp-c-text-1),所以只能写死 var(--vp-c-text-1) 的具体颜色,如果改动了 var(--vp-c-text-1) 的值,则需要修改 stroke 为对于的值
6+
&:root {
7+
/* clipboard */
8+
--vp-icon-copy: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='rgba(60,60,67,1)' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='8' height='4' x='8' y='2' rx='1' ry='1'/%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2'/%3E%3C/svg%3E");
9+
/* clipboard-copy */
10+
--vp-icon-copied: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='rgba(60,60,67,1)' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='8' height='4' x='8' y='2' rx='1' ry='1'/%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2'/%3E%3Cpath d='m9 14 2 2 4-4'/%3E%3C/svg%3E");
11+
}
1212

13-
:root.dark {
14-
/* clipboard */
15-
--vp-icon-copy: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='rgba(223,223,214,1)' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='8' height='4' x='8' y='2' rx='1' ry='1'/%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2'/%3E%3C/svg%3E");
16-
/* clipboard-copy */
17-
--vp-icon-copied: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='rgba(223,223,214,1)' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='8' height='4' x='8' y='2' rx='1' ry='1'/%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2'/%3E%3Cpath d='m9 14 2 2 4-4'/%3E%3C/svg%3E");
18-
}
13+
&:root.dark {
14+
/* clipboard */
15+
--vp-icon-copy: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='rgba(223,223,214,1)' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='8' height='4' x='8' y='2' rx='1' ry='1'/%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2'/%3E%3C/svg%3E");
16+
/* clipboard-copy */
17+
--vp-icon-copied: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='rgba(223,223,214,1)' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='8' height='4' x='8' y='2' rx='1' ry='1'/%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2'/%3E%3Cpath d='m9 14 2 2 4-4'/%3E%3C/svg%3E");
18+
}
1919

20-
.vp-doc div[class*="language-"],
21-
.#{$namespace}-postItem__info__left__excerpt div[class*="language-"] {
22-
transition: height 0.3s;
23-
overflow: hidden;
20+
.vp-doc div[class*="language-"],
21+
.#{$namespace}-postItem__info__left__excerpt div[class*="language-"] {
22+
transition: height 0.3s;
23+
overflow: hidden;
2424

25-
.vp-code {
26-
padding-top: getCssVar("code-block-fold-height");
27-
}
25+
.vp-code {
26+
padding-top: getCssVar("code-block-fold-height");
27+
}
2828

29-
.line-numbers-wrapper {
30-
margin-top: getCssVar("code-block-fold-height");
31-
padding-top: 0;
32-
}
29+
.line-numbers-wrapper {
30+
margin-top: getCssVar("code-block-fold-height");
31+
padding-top: 0;
32+
}
3333

34-
/* 代码块三个圆圈 */
35-
&::before {
36-
content: "";
37-
display: block;
38-
position: absolute;
39-
top: calc(getCssVar("code-block-fold-height") / 2);
40-
left: 14px;
41-
transform: translateY(-50%);
42-
width: 12px;
43-
height: 12px;
44-
border-radius: 50%;
45-
background: #fc625d;
46-
box-shadow:
47-
20px 0 #fdbc40,
48-
40px 0 #35cd4b;
34+
/* 代码块三个圆圈 */
35+
&::before {
36+
content: "";
37+
display: block;
38+
position: absolute;
39+
top: calc(getCssVar("code-block-fold-height") / 2);
40+
left: 14px;
41+
transform: translateY(-50%);
42+
width: 12px;
43+
height: 12px;
44+
border-radius: 50%;
45+
background: #fc625d;
46+
box-shadow:
47+
20px 0 #fdbc40,
48+
40px 0 #35cd4b;
49+
}
50+
51+
/* 代码块语言 */
52+
span.lang {
53+
position: absolute;
54+
z-index: 3;
55+
top: calc(getCssVar("code-block-fold-height") / 2);
56+
left: 75px;
57+
transform: translateY(-50%);
58+
font-size: 18px;
59+
color: var(--vp-c-text-1);
60+
text-transform: getCssVar("code-block-lang-transform");
61+
font-weight: bold;
62+
width: fit-content;
63+
}
64+
65+
/* 一键复制图标 */
66+
button.copy {
67+
width: 18px;
68+
height: 18px;
69+
position: absolute;
70+
top: calc(getCssVar("code-block-fold-height") / 2);
71+
right: 36px;
72+
transform: translateY(-50%);
73+
opacity: 1;
74+
background-size: 14px;
75+
background-color: transparent;
76+
border: none;
77+
color: var(--vp-c-text-1);
78+
fill: var(--vp-c-text-1);
79+
&:hover,
80+
.copied {
81+
background-color: transparent;
82+
border: none;
83+
}
84+
}
85+
86+
/* 语言和一键复制图标不会消失 */
87+
&:hover button.copy + span.lang,
88+
button.copy:focus + span.lang,
89+
&:hover > button.copy,
90+
button.copy:focus {
91+
opacity: 1;
92+
}
4993
}
5094

51-
/* 代码块语言 */
52-
span.lang {
95+
/* 代码块箭头 */
96+
.code-arrow {
97+
cursor: pointer;
5398
position: absolute;
5499
z-index: 3;
55100
top: calc(getCssVar("code-block-fold-height") / 2);
56-
left: 75px;
101+
right: 14px;
57102
transform: translateY(-50%);
58-
font-size: 18px;
59-
color: var(--vp-c-text-1);
60-
text-transform: getCssVar("code-block-lang-transform");
61-
font-weight: bold;
62-
width: fit-content;
63-
}
103+
transition: all 0.3s;
104+
user-select: none;
64105

65-
/* 一键复制图标 */
66-
button.copy {
67-
width: 18px;
68-
height: 18px;
69-
position: absolute;
70-
top: calc(getCssVar("code-block-fold-height") / 2);
71-
right: 36px;
72-
transform: translateY(-50%);
73-
opacity: 1;
74-
background-size: 14px;
75-
background-color: transparent;
76-
border: none;
77-
color: var(--vp-c-text-1);
78-
fill: var(--vp-c-text-1);
79-
&:hover,
80-
.copied {
81-
background-color: transparent;
82-
border: none;
106+
svg {
107+
width: 16px;
108+
height: 16px;
109+
fill: var(--vp-c-text-1);
83110
}
84-
}
85111

86-
/* 语言和一键复制图标不会消失 */
87-
&:hover button.copy + span.lang,
88-
button.copy:focus + span.lang,
89-
&:hover > button.copy,
90-
button.copy:focus {
91-
opacity: 1;
112+
/* 代码块折叠后后旋转 -90 度 */
113+
&.fold {
114+
transform: rotate(90deg) translateX(-50%);
115+
}
92116
}
93117
}

vitepress-theme-teeker/src/styles/md-plugin/code-arrow.scss

-23
This file was deleted.

0 commit comments

Comments
 (0)