Skip to content

Commit dcf9b5f

Browse files
committed
feat: 添加代码块复制按钮和修复显示器边框问题\n\n- 创建代码块复制按钮组件,支持一键复制代码\n- 修复显示器组件在电源开启状态下的边框问题\n- 优化安装页面的代码块样式和交互体验
1 parent 99fc152 commit dcf9b5f

File tree

8 files changed

+227
-9
lines changed

8 files changed

+227
-9
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
.codeBlockWrapper {
2+
position: relative;
3+
width: 100%;
4+
margin: 10px 0;
5+
}
6+
7+
.codeBlock {
8+
background-color: #2a2a2a;
9+
color: #f8f8f8;
10+
border-radius: 6px;
11+
padding: 12px 16px;
12+
font-family: 'JetBrains Mono', Menlo, Monaco, 'Courier New', monospace;
13+
font-size: 14px;
14+
line-height: 1.5;
15+
overflow-x: auto;
16+
white-space: pre;
17+
border: 1px solid rgba(255, 255, 255, 0.1);
18+
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
19+
transition: all 0.3s ease;
20+
width: 100%;
21+
max-width: 100%;
22+
box-sizing: border-box;
23+
margin: 0;
24+
}
25+
26+
.codeBlock:hover {
27+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
28+
border-color: rgba(79, 147, 255, 0.5);
29+
}
30+
31+
.codeBlock code {
32+
display: block;
33+
width: 100%;
34+
color: inherit;
35+
background: transparent;
36+
padding: 0;
37+
margin: 0;
38+
font-family: inherit;
39+
}
40+
41+
@media (max-width: 768px) {
42+
.codeBlock {
43+
padding: 10px 12px;
44+
font-size: 13px;
45+
}
46+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import React from 'react';
2+
import styles from './CodeBlock.module.css';
3+
import CopyButton from '../CopyButton';
4+
5+
interface CodeBlockProps {
6+
code: string;
7+
className?: string;
8+
}
9+
10+
const CodeBlock: React.FC<CodeBlockProps> = ({ code, className }) => {
11+
return (
12+
<div className={`${styles.codeBlockWrapper} codeBlockWrapper ${className || ''}`}>
13+
<pre className={styles.codeBlock}>
14+
<code>{code}</code>
15+
</pre>
16+
<CopyButton text={code} />
17+
</div>
18+
);
19+
};
20+
21+
export default CodeBlock;
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
.copyButton {
2+
position: absolute;
3+
top: 8px;
4+
right: 8px;
5+
background-color: rgba(255, 255, 255, 0.1);
6+
border: none;
7+
border-radius: 4px;
8+
padding: 4px 6px;
9+
cursor: pointer;
10+
display: flex;
11+
align-items: center;
12+
justify-content: center;
13+
transition: all 0.2s ease;
14+
color: #fff;
15+
opacity: 0;
16+
z-index: 10;
17+
}
18+
19+
.copyButton:hover {
20+
background-color: rgba(255, 255, 255, 0.2);
21+
}
22+
23+
.copyButton.copied {
24+
background-color: rgba(77, 171, 87, 0.3);
25+
color: #4dab57;
26+
}
27+
28+
.icon {
29+
width: 16px;
30+
height: 16px;
31+
}
32+
33+
.tooltip {
34+
position: absolute;
35+
top: -25px;
36+
right: 0;
37+
background-color: #333;
38+
color: white;
39+
padding: 2px 6px;
40+
border-radius: 3px;
41+
font-size: 12px;
42+
opacity: 0;
43+
transition: opacity 0.2s ease;
44+
pointer-events: none;
45+
}
46+
47+
.copyButton:hover .tooltip {
48+
opacity: 1;
49+
}
50+
51+
/* 父元素悬停时显示复制按钮 */
52+
:global(.codeBlockWrapper:hover) .copyButton {
53+
opacity: 1;
54+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import React, { useState } from 'react';
2+
import styles from './CopyButton.module.css';
3+
4+
interface CopyButtonProps {
5+
text: string;
6+
className?: string;
7+
}
8+
9+
const CopyButton: React.FC<CopyButtonProps> = ({ text, className }) => {
10+
const [copied, setCopied] = useState(false);
11+
12+
const handleCopy = () => {
13+
navigator.clipboard.writeText(text).then(
14+
() => {
15+
setCopied(true);
16+
setTimeout(() => {
17+
setCopied(false);
18+
}, 2000);
19+
},
20+
(err) => {
21+
console.error('无法复制内容: ', err);
22+
}
23+
);
24+
};
25+
26+
return (
27+
<button
28+
onClick={handleCopy}
29+
className={`${styles.copyButton} ${className || ''} ${copied ? styles.copied : ''}`}
30+
aria-label="复制代码"
31+
title="复制代码"
32+
>
33+
{copied ? (
34+
<svg className={styles.icon} viewBox="0 0 24 24" width="16" height="16">
35+
<path fill="currentColor" d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z" />
36+
</svg>
37+
) : (
38+
<svg className={styles.icon} viewBox="0 0 24 24" width="16" height="16">
39+
<path fill="currentColor" d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z" />
40+
</svg>
41+
)}
42+
<span className={styles.tooltip}>{copied ? '已复制' : '复制'}</span>
43+
</button>
44+
);
45+
};
46+
47+
export default CopyButton;

office-website/src/components/Monitor/Monitor.module.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
/* 屏幕电源状态 */
5555
.monitorScreen.powerOn {
5656
background-color: #fff;
57+
border-color: transparent;
5758
}
5859

5960
.monitorScreen.powerOff {

office-website/src/pages/Home/index.tsx

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import styles from './Home.module.css';
44
import Monitor from '../../components/Monitor/Monitor';
55
import Lightbox from "yet-another-react-lightbox";
66
import "yet-another-react-lightbox/styles.css";
7+
import CodeBlock from '../../components/CodeBlock';
78

89
const Home: React.FC = () => {
910
const { t } = useTranslation();
@@ -163,9 +164,7 @@ const Home: React.FC = () => {
163164
<li key={index}>
164165
<span>{step.text}</span>
165166
{step.code && (
166-
<pre className={styles.codeBlock}>
167-
<code>{step.code}</code>
168-
</pre>
167+
<CodeBlock code={step.code} />
169168
)}
170169
</li>
171170
))}
@@ -262,11 +261,13 @@ const Home: React.FC = () => {
262261
</div>
263262
</section>
264263

265-
<Lightbox
266-
open={!!openImage}
267-
close={() => setOpenImage(null)}
268-
slides={[{ src: openImage || "" }]}
269-
/>
264+
{openImage && (
265+
<Lightbox
266+
open={!!openImage}
267+
close={() => setOpenImage(null)}
268+
slides={[{ src: openImage }]}
269+
/>
270+
)}
270271
</div>
271272
);
272273
};
Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,27 @@
1-
1+
.compilationSteps {
2+
margin-top: 2rem;
3+
padding: 1.5rem;
4+
background-color: rgba(0, 0, 0, 0.03);
5+
border-radius: 8px;
6+
border: 1px solid rgba(0, 0, 0, 0.1);
7+
}
8+
9+
.compilationSteps h3 {
10+
margin-top: 0;
11+
margin-bottom: 1rem;
12+
color: #333;
13+
font-weight: 600;
14+
}
15+
16+
.compilationSteps ol {
17+
padding-left: 1.25rem;
18+
margin-bottom: 0;
19+
}
20+
21+
.compilationSteps li {
22+
margin-bottom: 1rem;
23+
}
24+
25+
.compilationSteps li:last-child {
26+
margin-bottom: 0;
27+
}

office-website/src/pages/Install/index.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
import React from 'react';
22
import { useTranslation } from 'react-i18next';
3+
import CodeBlock from '../../components/CodeBlock';
4+
import styles from './Install.module.css';
35

46
const Install: React.FC = () => {
57
const { t } = useTranslation();
68

9+
// 定义安装步骤中的代码块
10+
const cloneCommand = 'git clone https://github.com/JSREI/ast-explorer-helper.git';
11+
const installCommand = 'npm install';
12+
const buildCommand = 'npm run build';
13+
714
return (
815
<div className="install-page">
916
<section className="section">
@@ -59,6 +66,21 @@ const Install: React.FC = () => {
5966
<li>{t('install.step2.dragAndDrop')}</li>
6067
</ol>
6168
</p>
69+
70+
<div className={styles.compilationSteps}>
71+
<h3>自行编译安装</h3>
72+
<ol>
73+
<li>克隆仓库:
74+
<CodeBlock code={cloneCommand} />
75+
</li>
76+
<li>安装依赖:
77+
<CodeBlock code={installCommand} />
78+
</li>
79+
<li>构建项目:
80+
<CodeBlock code={buildCommand} />
81+
</li>
82+
</ol>
83+
</div>
6284
</div>
6385

6486
<div className="step">

0 commit comments

Comments
 (0)