Skip to content

Commit db8ec6e

Browse files
committed
Add fade-in animation and screen reader announce
The card swap gets a subtle 200ms fade + slide animation on variant change. A visually-hidden aria-live region announces the active state so screen readers pick it up.
1 parent ceb79ee commit db8ec6e

2 files changed

Lines changed: 51 additions & 4 deletions

File tree

static/css/v3/install-card.css

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,15 @@
179179
display: none;
180180
}
181181

182+
@keyframes install-card-fade-in {
183+
from { opacity: 0; transform: translateY(4px); }
184+
to { opacity: 1; transform: translateY(0); }
185+
}
186+
187+
.install-card--entering {
188+
animation: install-card-fade-in 200ms ease-out;
189+
}
190+
182191
/* ── Older-version variant ───────────────────────────────── */
183192
.install-card--older {
184193
gap: var(--space-large);

static/js/install-card-version-sync.js

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,62 @@
1717
* - The header JS to dispatch `boost:version-changed` with detail
1818
* { slug, label, isLatest, docUrl }.
1919
*/
20+
21+
function _getOrCreateLiveRegion() {
22+
var el = document.getElementById("install-card-live");
23+
if (el) return el;
24+
el = document.createElement("span");
25+
el.id = "install-card-live";
26+
el.setAttribute("aria-live", "polite");
27+
el.style.cssText =
28+
"position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;";
29+
document.body.appendChild(el);
30+
return el;
31+
}
32+
2033
document.addEventListener("boost:version-changed", function (e) {
2134
var detail = e.detail || {};
2235
var isLatest = detail.isLatest === true;
2336
var docUrl = detail.docUrl || "";
37+
var label = detail.label || "";
2438

2539
document
2640
.querySelectorAll("[data-install-card-wrapper]")
2741
.forEach(function (wrapper) {
28-
wrapper.setAttribute(
29-
"data-active-variant",
30-
isLatest ? "latest" : "older"
31-
);
42+
var prev = wrapper.getAttribute("data-active-variant");
43+
var next = isLatest ? "latest" : "older";
44+
45+
wrapper.setAttribute("data-active-variant", next);
46+
3247
if (!isLatest && docUrl) {
3348
var linkWrapper = wrapper.querySelector(
3449
"[data-install-card-doc-link-wrapper]"
3550
);
3651
var link = linkWrapper && linkWrapper.querySelector("a");
3752
if (link) link.setAttribute("href", docUrl);
3853
}
54+
55+
if (prev !== next) {
56+
var visible = isLatest
57+
? wrapper.querySelector(".install-card:not(.install-card--older)")
58+
: wrapper.querySelector(".install-card--older");
59+
if (visible) {
60+
visible.classList.remove("install-card--entering");
61+
void visible.offsetWidth;
62+
visible.classList.add("install-card--entering");
63+
visible.addEventListener(
64+
"animationend",
65+
function () {
66+
visible.classList.remove("install-card--entering");
67+
},
68+
{ once: true }
69+
);
70+
}
71+
}
3972
});
73+
74+
var liveRegion = _getOrCreateLiveRegion();
75+
liveRegion.textContent = isLatest
76+
? "Showing install steps for the latest version."
77+
: "Showing documentation link for Boost " + label + ".";
4078
});

0 commit comments

Comments
 (0)