feat(a11y): add keyboard prev/next to photo strip and region landmark
This commit is contained in:
@@ -246,6 +246,32 @@ body::after {
|
|||||||
background: var(--color-ink-muted);
|
background: var(--color-ink-muted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.strip-controls {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
gap: var(--space-3);
|
||||||
|
margin-top: calc(-1 * var(--space-2));
|
||||||
|
margin-bottom: var(--space-4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.strip-prev,
|
||||||
|
.strip-next {
|
||||||
|
background: transparent;
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
color: var(--color-ink-2);
|
||||||
|
border-radius: var(--radius-sm);
|
||||||
|
padding: var(--space-1) var(--space-3);
|
||||||
|
font-size: var(--text-md);
|
||||||
|
line-height: 1;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.strip-prev:hover,
|
||||||
|
.strip-next:hover {
|
||||||
|
border-color: var(--color-accent);
|
||||||
|
color: var(--color-accent);
|
||||||
|
}
|
||||||
|
|
||||||
.journal-post-body {
|
.journal-post-body {
|
||||||
font-size: var(--text-base);
|
font-size: var(--text-base);
|
||||||
line-height: var(--leading-normal);
|
line-height: var(--leading-normal);
|
||||||
|
|||||||
@@ -30,13 +30,42 @@
|
|||||||
<script>
|
<script>
|
||||||
(function () {
|
(function () {
|
||||||
document.querySelectorAll('.journal-photo-strip').forEach(function (strip) {
|
document.querySelectorAll('.journal-photo-strip').forEach(function (strip) {
|
||||||
|
strip.setAttribute('role', 'region');
|
||||||
|
strip.setAttribute('aria-label', 'Photo strip');
|
||||||
|
|
||||||
|
var slideCount = parseInt(strip.dataset.slides, 10) || 1;
|
||||||
var dots = strip.nextElementSibling;
|
var dots = strip.nextElementSibling;
|
||||||
if (!dots || !dots.classList.contains('journal-photo-dots')) return;
|
if (!dots || !dots.classList.contains('journal-photo-dots')) return;
|
||||||
var dotEls = Array.from(dots.querySelectorAll('.journal-photo-dot'));
|
var dotEls = Array.from(dots.querySelectorAll('.journal-photo-dot'));
|
||||||
|
|
||||||
strip.addEventListener('scroll', function () {
|
strip.addEventListener('scroll', function () {
|
||||||
var idx = Math.round(strip.scrollLeft / strip.offsetWidth);
|
var idx = Math.round(strip.scrollLeft / strip.offsetWidth);
|
||||||
dotEls.forEach(function (d, i) { d.classList.toggle('is-active', i === idx); });
|
dotEls.forEach(function (d, i) { d.classList.toggle('is-active', i === idx); });
|
||||||
}, { passive: true });
|
}, { passive: true });
|
||||||
|
|
||||||
|
if (slideCount < 2) return;
|
||||||
|
|
||||||
|
var prev = document.createElement('button');
|
||||||
|
prev.className = 'strip-prev';
|
||||||
|
prev.setAttribute('aria-label', 'Previous photo');
|
||||||
|
prev.textContent = '‹';
|
||||||
|
prev.addEventListener('click', function () {
|
||||||
|
strip.scrollBy({ left: -strip.offsetWidth, behavior: 'smooth' });
|
||||||
|
});
|
||||||
|
|
||||||
|
var next = document.createElement('button');
|
||||||
|
next.className = 'strip-next';
|
||||||
|
next.setAttribute('aria-label', 'Next photo');
|
||||||
|
next.textContent = '›';
|
||||||
|
next.addEventListener('click', function () {
|
||||||
|
strip.scrollBy({ left: strip.offsetWidth, behavior: 'smooth' });
|
||||||
|
});
|
||||||
|
|
||||||
|
var controls = document.createElement('div');
|
||||||
|
controls.className = 'strip-controls';
|
||||||
|
controls.appendChild(prev);
|
||||||
|
controls.appendChild(next);
|
||||||
|
dots.insertAdjacentElement('afterend', controls);
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user