Skip to content

Commit 5ba48d2

Browse files
committed
feat(pages): toggle copy actions on keystoke Command / Ctrl
1 parent 0c17706 commit 5ba48d2

2 files changed

Lines changed: 110 additions & 5 deletions

File tree

src/components/custom/CopyText.astro

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
---
2+
type Props = {
3+
text: string;
4+
label: string;
5+
};
6+
27
const { text, label } = Astro.props;
38
---
49

@@ -9,8 +14,11 @@ const { text, label } = Astro.props;
914
data-copy-label={label}
1015
onclick="
1116
navigator.clipboard.writeText(this.getAttribute('data-copy-text'));
12-
this.innerText = 'Copied!';
13-
setTimeout(() => {this.innerText = this.getAttribute('data-copy-label')}, 1000)
17+
const element = this;
18+
element.innerText = 'Copied!';
19+
setTimeout(() => {
20+
element.innerText = element.getAttribute('data-copy-label') || '';
21+
}, 1000)
1422
">
1523
{ label }
1624
</span>

src/pages/blog/[...slug].astro

Lines changed: 100 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,10 @@ const { Content } = await post.render();
6262
)
6363
}
6464

65-
<div class="flex items-center">
65+
<div
66+
class="hidden md:flex items-center opacity-0 transition-opacity duration-300 ease-in-out pointer-events-none"
67+
id="copy-section"
68+
>
6669
<span>&bull;</span>
6770
<div class="ml-1.5 font-base text-sm">
6871
Copy
@@ -73,17 +76,20 @@ const { Content } = await post.render();
7376
"\n\n👇点击 **阅读原文** 查看网页版"}
7477
label={"Content"}
7578
/>
79+
/
7680
<CopyText
7781
text={post.data.title + " | c13n"}
7882
label={"Title"}
7983
/>
84+
<!-- /
8085
<CopyText
8186
text={post.data.author}
8287
label={"Author"}
83-
/>
88+
/> -->
89+
/
8490
<CopyText
8591
text={post.data.description}
86-
label={"Description"}
92+
label={"Desc"}
8793
/>
8894
</span>
8995
</div>
@@ -103,3 +109,94 @@ const { Content } = await post.render();
103109
</article>
104110
</Container>
105111
</PageLayout>
112+
113+
<script>
114+
let cleanupCopyToggle: (() => void) | null = null;
115+
116+
function initCopyToggle(): void {
117+
// Clean up previous event listeners if they exist
118+
if (cleanupCopyToggle) {
119+
cleanupCopyToggle();
120+
}
121+
122+
const copySection = document.getElementById(
123+
"copy-section",
124+
) as HTMLElement | null;
125+
if (!copySection) return;
126+
127+
let isCommandPressed = false;
128+
129+
function showCopySection(): void {
130+
if (!isCommandPressed && copySection) {
131+
isCommandPressed = true;
132+
copySection.classList.remove(
133+
"opacity-0",
134+
"pointer-events-none",
135+
);
136+
copySection.classList.add("opacity-100", "pointer-events-auto");
137+
}
138+
}
139+
140+
function hideCopySection(): void {
141+
if (isCommandPressed && copySection) {
142+
isCommandPressed = false;
143+
copySection.classList.remove(
144+
"opacity-100",
145+
"pointer-events-auto",
146+
);
147+
copySection.classList.add("opacity-0", "pointer-events-none");
148+
}
149+
}
150+
151+
function handleKeyDown(event: KeyboardEvent): void {
152+
if (event.metaKey || event.ctrlKey) {
153+
showCopySection();
154+
}
155+
}
156+
157+
function handleKeyUp(event: KeyboardEvent): void {
158+
if (!event.metaKey && !event.ctrlKey) {
159+
hideCopySection();
160+
}
161+
}
162+
163+
function handleWindowBlur(): void {
164+
hideCopySection();
165+
}
166+
167+
function handleWindowFocus(): void {
168+
// Reset state when window regains focus
169+
hideCopySection();
170+
}
171+
172+
function handleVisibilityChange(): void {
173+
if (document.hidden) {
174+
hideCopySection();
175+
}
176+
}
177+
178+
// Event listeners
179+
document.addEventListener("keydown", handleKeyDown);
180+
document.addEventListener("keyup", handleKeyUp);
181+
window.addEventListener("blur", handleWindowBlur);
182+
window.addEventListener("focus", handleWindowFocus);
183+
document.addEventListener("visibilitychange", handleVisibilityChange);
184+
185+
// Store cleanup
186+
cleanupCopyToggle = (): void => {
187+
document.removeEventListener("keydown", handleKeyDown);
188+
document.removeEventListener("keyup", handleKeyUp);
189+
window.removeEventListener("blur", handleWindowBlur);
190+
window.removeEventListener("focus", handleWindowFocus);
191+
document.removeEventListener(
192+
"visibilitychange",
193+
handleVisibilityChange,
194+
);
195+
};
196+
}
197+
198+
// Initialize on page load
199+
document.addEventListener("DOMContentLoaded", initCopyToggle);
200+
// Re-initialize on Astro page transitions
201+
document.addEventListener("astro:after-swap", initCopyToggle);
202+
</script>

0 commit comments

Comments
 (0)