mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-18 00:56:30 +03:00
Add site copy feedback and command block fixes (#200)
* Add copy confirmation animation * Add live mode copy confirmation * Add Neo Mirai copy confirmation * Fix Neo Mirai command overflow on narrow screens * Link footer logo to homepage * Fix copy feedback helper --------- Co-authored-by: Paul Bakaus <43004+pbakaus@users.noreply.github.com>
This commit is contained in:
co-authored by
Paul Bakaus
parent
08d50f215b
commit
397d3cb4b7
+2
-20
@@ -5,6 +5,7 @@ import {
|
||||
import { initFrameworkViz } from "./components/framework-viz.js";
|
||||
import { initScrollReveal } from "./utils/reveal.js";
|
||||
import { initAnchorScroll, initHashTracking } from "./utils/scroll.js";
|
||||
import { initCopyFeedback } from "./utils/copy-feedback.js";
|
||||
import { initSectionNav } from "./components/section-nav.js";
|
||||
import { initFoundationGrid } from "./components/foundation-grid.js";
|
||||
import { initLiveDemo, initGbarPageChat } from "./components/live-demo.js";
|
||||
@@ -208,26 +209,6 @@ document.addEventListener("click", (e) => {
|
||||
const bundleName = bundleBtn.dataset.bundle;
|
||||
window.location.href = `/api/download/bundle/${bundleName}`;
|
||||
}
|
||||
|
||||
// Handle copy button clicks
|
||||
const copyBtn = e.target.closest("[data-copy]");
|
||||
if (copyBtn) {
|
||||
const textToCopy = copyBtn.dataset.copy;
|
||||
const onCopied = () => {
|
||||
copyBtn.classList.add('copied');
|
||||
setTimeout(() => copyBtn.classList.remove('copied'), 1500);
|
||||
};
|
||||
if (navigator.clipboard?.writeText) {
|
||||
navigator.clipboard.writeText(textToCopy).then(onCopied).catch(() => {});
|
||||
} else {
|
||||
// Fallback for non-HTTPS or older browsers
|
||||
const ta = Object.assign(document.createElement('textarea'), { value: textToCopy, style: 'position:fixed;left:-9999px' });
|
||||
document.body.appendChild(ta);
|
||||
ta.select();
|
||||
try { document.execCommand('copy'); onCopied(); } catch {}
|
||||
ta.remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -261,6 +242,7 @@ function initHeaderScroll() {
|
||||
function init() {
|
||||
initAnchorScroll();
|
||||
initHashTracking();
|
||||
initCopyFeedback();
|
||||
initHeaderScroll();
|
||||
initScrollReveal();
|
||||
initGlassTerminal();
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
const copyResetTimers = new WeakMap();
|
||||
|
||||
function copyWithTextareaFallback(text) {
|
||||
const ta = Object.assign(document.createElement('textarea'), {
|
||||
value: text,
|
||||
style: 'position:fixed;left:-9999px',
|
||||
});
|
||||
|
||||
document.body.appendChild(ta);
|
||||
ta.focus();
|
||||
ta.select();
|
||||
|
||||
try {
|
||||
return document.execCommand('copy');
|
||||
} catch {
|
||||
return false;
|
||||
} finally {
|
||||
ta.remove();
|
||||
}
|
||||
}
|
||||
|
||||
function showCopiedState(button, { copiedClass = 'copied', resetMs = 1200 } = {}) {
|
||||
window.clearTimeout(copyResetTimers.get(button));
|
||||
button.classList.remove(copiedClass);
|
||||
void button.offsetWidth;
|
||||
button.classList.add(copiedClass);
|
||||
copyResetTimers.set(
|
||||
button,
|
||||
window.setTimeout(() => button.classList.remove(copiedClass), resetMs),
|
||||
);
|
||||
}
|
||||
|
||||
async function copyText(text) {
|
||||
if (navigator.clipboard?.writeText) {
|
||||
try {
|
||||
await navigator.clipboard.writeText(text);
|
||||
return true;
|
||||
} catch {}
|
||||
}
|
||||
|
||||
return copyWithTextareaFallback(text);
|
||||
}
|
||||
|
||||
export function initCopyFeedback({
|
||||
selector = '[data-copy]',
|
||||
copiedClass = 'copied',
|
||||
resetMs = 1200,
|
||||
} = {}) {
|
||||
document.addEventListener('click', async (event) => {
|
||||
if (!(event.target instanceof Element)) return;
|
||||
|
||||
const button = event.target.closest(selector);
|
||||
if (!(button instanceof HTMLElement)) return;
|
||||
|
||||
const text = button.getAttribute('data-copy');
|
||||
if (!text) return;
|
||||
|
||||
if (await copyText(text)) {
|
||||
showCopiedState(button, { copiedClass, resetMs });
|
||||
}
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user