This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 819 KiB |
@@ -0,0 +1,62 @@
|
||||
(() => {
|
||||
const announce = (component, message) => {
|
||||
const status = component.querySelector("[data-share-status]");
|
||||
if (!status) return;
|
||||
status.textContent = "";
|
||||
window.requestAnimationFrame(() => {
|
||||
status.textContent = message;
|
||||
});
|
||||
};
|
||||
|
||||
const fallbackCopy = (url) => {
|
||||
const field = document.createElement("textarea");
|
||||
field.value = url;
|
||||
field.setAttribute("readonly", "");
|
||||
field.style.position = "fixed";
|
||||
field.style.opacity = "0";
|
||||
document.body.appendChild(field);
|
||||
field.select();
|
||||
const copied = document.execCommand("copy");
|
||||
field.remove();
|
||||
return copied;
|
||||
};
|
||||
|
||||
const copyLink = async (component) => {
|
||||
const url = component.dataset.shareUrl;
|
||||
try {
|
||||
if (navigator.clipboard && window.isSecureContext) {
|
||||
await navigator.clipboard.writeText(url);
|
||||
} else if (!fallbackCopy(url)) {
|
||||
throw new Error("Copy command unavailable");
|
||||
}
|
||||
announce(component, "Link copied.");
|
||||
} catch (_error) {
|
||||
window.prompt("Copy this link:", url);
|
||||
announce(component, "Copy the link from the dialog.");
|
||||
}
|
||||
};
|
||||
|
||||
document.querySelectorAll("[data-share-component]").forEach((component) => {
|
||||
component.querySelector("[data-share-native]")?.addEventListener("click", async (event) => {
|
||||
event.preventDefault();
|
||||
if (!navigator.share) {
|
||||
await copyLink(component);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await navigator.share({
|
||||
title: component.dataset.shareTitle,
|
||||
text: component.dataset.shareDescription,
|
||||
url: component.dataset.shareUrl,
|
||||
});
|
||||
} catch (error) {
|
||||
if (error.name !== "AbortError") await copyLink(component);
|
||||
}
|
||||
});
|
||||
|
||||
component.querySelector("[data-share-copy]")?.addEventListener("click", async (event) => {
|
||||
event.preventDefault();
|
||||
await copyLink(component);
|
||||
});
|
||||
});
|
||||
})();
|
||||
+49
-2
@@ -432,7 +432,8 @@ h1 { max-width: 880px; margin: 0; font-size: clamp(30px, 4vw, 45px); font-style:
|
||||
grid-template-columns: minmax(0, 640px) minmax(230px, 280px);
|
||||
grid-template-areas:
|
||||
"header info"
|
||||
"body info";
|
||||
"body info"
|
||||
"share info";
|
||||
gap: 34px clamp(54px, 7vw, 92px);
|
||||
align-items: start;
|
||||
padding-block: 68px 90px;
|
||||
@@ -486,6 +487,45 @@ h1 { max-width: 880px; margin: 0; font-size: clamp(30px, 4vw, 45px); font-style:
|
||||
.publication-links a:hover,
|
||||
.publication-links a:focus-visible { text-decoration: underline; text-underline-offset: 3px; }
|
||||
|
||||
.share-panel {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(150px, .55fr) minmax(0, 1.45fr);
|
||||
gap: 12px 28px;
|
||||
border-block: 1px solid var(--rule);
|
||||
padding-block: 22px;
|
||||
}
|
||||
.blog-post-layout > .share-panel,
|
||||
.article-post-layout > .share-panel { grid-area: share; }
|
||||
.share-panel-heading { align-self: center; }
|
||||
.share-kicker {
|
||||
margin: 0 0 5px;
|
||||
color: var(--magenta);
|
||||
font: 500 9px var(--mono);
|
||||
letter-spacing: .14em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.share-panel h2 { margin: 0; font: 600 17px/1.3 var(--serif); }
|
||||
.share-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
|
||||
.share-action {
|
||||
border: 1px solid var(--rule);
|
||||
padding: 7px 9px;
|
||||
color: var(--muted);
|
||||
font: 500 9px var(--mono);
|
||||
letter-spacing: .07em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.share-action:hover,
|
||||
.share-action:focus-visible { border-color: var(--teal); color: var(--teal); outline-color: var(--teal); }
|
||||
.share-action-primary { border-color: rgba(81,182,165,.6); color: var(--teal); }
|
||||
.share-status {
|
||||
grid-column: 2;
|
||||
min-height: 1.3em;
|
||||
margin: 0;
|
||||
color: var(--teal);
|
||||
font: 500 9px var(--mono);
|
||||
letter-spacing: .06em;
|
||||
}
|
||||
|
||||
.narration-player {
|
||||
border: 1px solid var(--rule);
|
||||
padding: 18px 20px;
|
||||
@@ -548,6 +588,7 @@ h1 { max-width: 880px; margin: 0; font-size: clamp(30px, 4vw, 45px); font-style:
|
||||
padding-block: 68px 78px;
|
||||
}
|
||||
.project-narrative { width: 100%; }
|
||||
.project-content > .share-panel { grid-column: 1 / -1; }
|
||||
.repository-card { border: 1px solid var(--rule); background: var(--panel); padding: 24px; }
|
||||
.repository-card dl { margin: 0; }
|
||||
.repository-card a { color: var(--teal); }
|
||||
@@ -601,6 +642,7 @@ h1 { max-width: 880px; margin: 0; font-size: clamp(30px, 4vw, 45px); font-style:
|
||||
grid-template-areas:
|
||||
"header info"
|
||||
"body info"
|
||||
"share share"
|
||||
"navigation navigation"
|
||||
"back back";
|
||||
gap: 34px clamp(54px, 7vw, 92px);
|
||||
@@ -610,6 +652,7 @@ h1 { max-width: 880px; margin: 0; font-size: clamp(30px, 4vw, 45px); font-style:
|
||||
.devlog-entry-header { grid-area: header; }
|
||||
.devlog-entry-header h1 { font-style: normal; }
|
||||
.devlog-entry-body { grid-area: body; width: 100%; }
|
||||
.devlog-entry-layout > .share-panel { grid-area: share; }
|
||||
.devlog-info { grid-area: info; }
|
||||
.devlog-info .post-info-title { color: var(--violet); }
|
||||
.devlog-navigation { grid-area: navigation; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1px; margin-top: 38px; border: 1px solid var(--rule); background: var(--rule); }
|
||||
@@ -702,6 +745,7 @@ h1 { max-width: 880px; margin: 0; font-size: clamp(30px, 4vw, 45px); font-style:
|
||||
"header"
|
||||
"info"
|
||||
"body"
|
||||
"share"
|
||||
"navigation"
|
||||
"back";
|
||||
gap: 30px;
|
||||
@@ -716,11 +760,14 @@ h1 { max-width: 880px; margin: 0; font-size: clamp(30px, 4vw, 45px); font-style:
|
||||
grid-template-areas:
|
||||
"header"
|
||||
"info"
|
||||
"body";
|
||||
"body"
|
||||
"share";
|
||||
gap: 30px;
|
||||
padding-block: 44px 65px;
|
||||
}
|
||||
.post-info { padding: 20px; }
|
||||
.share-panel { grid-template-columns: 1fr; }
|
||||
.share-status { grid-column: 1; }
|
||||
.narration-player { padding: 18px; }
|
||||
.narration-details { align-items: flex-start; flex-direction: column-reverse; }
|
||||
.footer-inner { align-items: flex-start; flex-direction: column; padding-block: 28px; }
|
||||
|
||||
Reference in New Issue
Block a user