Skip to content

Commit 5d0fc0b

Browse files
committed
Support copy installation command
1 parent 450e169 commit 5d0fc0b

File tree

2 files changed

+102
-3
lines changed

2 files changed

+102
-3
lines changed

theme/components/version-card/index.module.scss

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,54 @@
4242
border-radius: 8px;
4343
width: 100%;
4444
text-align: center;
45+
position: relative;
46+
cursor: pointer;
47+
transition: background-color 0.2s;
48+
49+
&:hover {
50+
background: rgba(255, 255, 255, 0.15);
51+
52+
.copyButton {
53+
opacity: 1;
54+
}
55+
}
56+
}
57+
58+
.copyButton {
59+
position: absolute;
60+
right: 12px;
61+
top: 50%;
62+
transform: translateY(-50%);
63+
background: rgba(255, 255, 255, 0.2);
64+
border: none;
65+
border-radius: 4px;
66+
padding: 4px 8px;
67+
color: white;
68+
font-size: 12px;
69+
cursor: pointer;
70+
opacity: 0;
71+
transition: all 0.2s;
72+
73+
&:hover {
74+
background: rgba(255, 255, 255, 0.3);
75+
}
76+
}
77+
78+
.copied .copyButton {
79+
background: rgba(76, 175, 80, 0.3);
4580
}
4681

4782
.commandText {
83+
display: block;
84+
transition: opacity 0.3s ease;
4885
font-family: monospace;
4986
font-weight: bold;
5087
font-size: 14px;
88+
opacity: 1;
89+
}
90+
91+
.commandText.fade {
92+
opacity: 0;
5193
}
5294

5395
@media screen and (max-width: 600px) {

theme/components/version-card/index.tsx

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,75 @@
11
import { type FC } from 'react';
22
import styles from './index.module.scss';
3+
import { useState, useCallback, useEffect, useRef } from 'react';
34

45
const VersionCard: FC = () => {
6+
const [copied, setCopied] = useState(false);
7+
const [currentCommand, setCurrentCommand] = useState(0);
8+
const [isHovered, setIsHovered] = useState(false);
9+
const [isFading, setIsFading] = useState(false);
10+
const intervalRef = useRef<NodeJS.Timeout>();
11+
12+
const commands = [
13+
'curl https://aiscript.dev/install.sh | sh',
14+
'cargo install aiscript'
15+
];
16+
17+
const handleCopy = useCallback(() => {
18+
navigator.clipboard.writeText(commands[currentCommand]).then(() => {
19+
setCopied(true);
20+
setTimeout(() => setCopied(false), 2000);
21+
});
22+
}, [currentCommand, commands]);
23+
24+
const switchCommand = useCallback(() => {
25+
setIsFading(true);
26+
setTimeout(() => {
27+
setCurrentCommand((prev) => (prev + 1) % commands.length);
28+
setIsFading(false);
29+
}, 300);
30+
}, [commands.length]);
31+
32+
useEffect(() => {
33+
if (!isHovered) {
34+
intervalRef.current = setInterval(switchCommand, 3000);
35+
}
36+
return () => {
37+
if (intervalRef.current) {
38+
clearInterval(intervalRef.current);
39+
}
40+
};
41+
}, [isHovered, switchCommand]);
42+
43+
const handleMouseEnter = useCallback(() => {
44+
setIsHovered(true);
45+
}, []);
46+
47+
const handleMouseLeave = useCallback(() => {
48+
setIsHovered(false);
49+
}, []);
50+
551
return (
652
<div className={styles.versionCard}>
753
<div className={styles.content}>
854
<div className={styles.version}>
955
<span className={styles.label}>Latest Version</span>
1056
<span className={styles.value}>v0.1.0</span>
1157
</div>
12-
<div className={styles.command}>
13-
<code className={styles.commandText}>
14-
curl https://aiscript.dev/install.sh | sh
58+
<div
59+
className={`${styles.command} ${copied ? styles.copied : ''}`}
60+
onMouseEnter={handleMouseEnter}
61+
onMouseLeave={handleMouseLeave}
62+
>
63+
<code className={`${styles.commandText} ${isFading ? styles.fade : ''}`}>
64+
{commands[currentCommand]}
1565
</code>
66+
<button
67+
className={styles.copyButton}
68+
onClick={handleCopy}
69+
title="Copy to clipboard"
70+
>
71+
{copied ? 'Copied!' : 'Copy'}
72+
</button>
1673
</div>
1774
</div>
1875
</div>

0 commit comments

Comments
 (0)