a11y fixes

This commit is contained in:
MinamiFunakoshiTR 2025-03-13 10:50:46 -07:00
parent bf1415ea3c
commit 607f0af7fe
Failed to extract signature
3 changed files with 33 additions and 34 deletions

View file

@ -3,7 +3,7 @@
import BeforeAfter from './BeforeAfter.svelte';
const { Story } = defineMeta({
title: 'Components/Graphics/BeforeAfter',
title: 'Components/Multimedia/BeforeAfter',
component: BeforeAfter,
argTypes: {
handleColour: { control: 'color' },
@ -40,13 +40,13 @@
afterAlt="Satellite image of Russian base at Myrne taken on Oct. 20, 2020."
>
{#snippet beforeOverlay()}
<div class="overlay p-3 before">
<div class="overlay p-3 before text-left">
<p class="h4 font-bold">July 7, 2020</p>
<p class="body-note">Initially, this site was far smaller.</p>
</div>
{/snippet}
{#snippet afterOverlay()}
<div class="overlay p-3 after">
<div class="overlay p-3 after text-right">
<p class="h4 font-bold">Oct. 20, 2020</p>
<p class="body-note">But then forces built up.</p>
</div>
@ -60,9 +60,6 @@
.overlay {
background: rgba(0, 0, 0, 0.45);
max-width: 350px;
&.after {
text-align: right;
}
p {
color: #ffffff;
}
@ -78,14 +75,14 @@
afterAlt="Satellite image of Russian base at Myrne taken on Oct. 20, 2020."
>
{#snippet beforeOverlay()}
<div class="overlay p-3">
<div class="overlay p-3 text-left">
<p class="body-caption" id="aria-description-before">
On July 7, 2020, the base contained only a few transport vehicles.
</p>
</div>
{/snippet}
{#snippet afterOverlay()}
<div class="overlay p-3">
<div class="overlay p-3 text-right">
<p class="body-caption" id="aria-description-after">
But by October, tanks and artillery could be seen.
</p>

View file

@ -6,12 +6,7 @@
import Block from '../Block/Block.svelte';
import PaddingReset from '../PaddingReset/PaddingReset.svelte';
import type { ContainerWidth } from '../@types/global';
/** Helper function to generate a random 4-character string */
const random4 = () =>
Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
import { random4 } from '../../utils/';
interface Props {
/** Width of the chart within the text well. Options: wide, wider, widest, fluid */
@ -98,7 +93,7 @@
let figure: HTMLElement | undefined = $state(undefined);
let beforeOverlayWidth = $state(0);
let isFocused = false;
let containerWidth: number = $state(0); // check if this should be undefined
let containerWidth: number = $state(0); // Defaults to 0
let containerHeight = $derived(
containerWidth && heightRatio ? containerWidth * heightRatio : height
@ -112,6 +107,7 @@
x < beforeOverlayWidth ? Math.abs(x - beforeOverlayWidth) : 0
);
/** Toggle `isFocused` */
const onfocus = () => (isFocused = true);
const onblur = () => (isFocused = false);
@ -127,10 +123,12 @@
}
};
/** Measure image and set image offset */
const measureImage = () => {
if (img && img.complete) imgOffset = img.getBoundingClientRect();
};
/** Reset image offset on resize */
const resize = () => {
measureImage();
};
@ -142,6 +140,7 @@
}
};
/** Move the slider */
const move = (e: MouseEvent | TouchEvent) => {
if (sliding && imgOffset) {
const el =
@ -158,11 +157,14 @@
offset = x / w;
}
};
/** Starts the slider */
const start = (e: MouseEvent | TouchEvent) => {
sliding = true;
move(e);
};
/** Sets `sliding` to `false`*/
const end = () => {
sliding = false;
};
@ -177,46 +179,41 @@
</script>
<svelte:window
on:touchmove={move}
on:touchend={end}
on:mousemove={move}
on:mouseup={end}
on:resize={throttle(resize, 100)}
on:keydown={handleKeyDown}
ontouchmove={move}
ontouchend={end}
onmousemove={move}
onmouseup={end}
onresize={throttle(resize, 100)}
onkeydown={handleKeyDown}
/>
<!-- Since we usually read these values from ArchieML, check that they exist -->
{#if beforeSrc && beforeAlt && afterSrc && afterAlt}
<Block {width} {id} class="photo before-after fmy-6 {cls}">
<div style="height: {containerHeight}px;" bind:clientWidth={containerWidth}>
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
<figure
<button
style={figStyle}
class="before-after-container relative overflow-hidden my-0 mx-auto"
ontouchstart={start}
onmousedown={start}
bind:this={figure}
aria-labelledby={(caption && `${id}-caption`) || undefined}
aria-labelledby={(caption && `${id}-caption`) || ''}
>
<!-- onmousedown={start || (e) => e.preventDefault()} -->
<img
bind:this={img}
src={afterSrc}
alt={afterAlt}
onload={measureLoadedImage}
onmousedown={start}
style={imgStyle}
class="after absolute block m-0 max-w-full object-cover"
aria-describedby={(beforeOverlay && `${id}-before`) || undefined}
aria-describedby={(beforeOverlay && `${id}-before`) || ''}
/>
<!-- onmousedown={start || (e) => e.preventDefault()} -->
<img
src={beforeSrc}
alt={beforeAlt}
onmousedown={start}
style="clip: rect(0 {x}px {containerHeight}px 0);{imgStyle}"
class="before absolute block m-0 max-w-full object-cover"
aria-describedby={(afterOverlay && `${id}-after`) || undefined}
aria-describedby={(afterOverlay && `${id}-after`) || ''}
/>
{#if beforeOverlay}
<div
@ -248,7 +245,7 @@
<div class="arrow-left"></div>
<div class="arrow-right"></div>
</div>
</figure>
</button>
</div>
{#if caption}
<PaddingReset containerIsFluid={width === 'fluid'}>
@ -264,7 +261,7 @@
<style lang="scss">
@use '../../scss/mixins' as mixins;
figure.before-after-container {
button.before-after-container {
box-sizing: content-box;
img {
@ -280,7 +277,7 @@
user-select: none;
}
.overlay-container {
position: absolute;
top: 0;
:global(:first-child) {
margin-top: 0;
}

5
src/utils/index.ts Normal file
View file

@ -0,0 +1,5 @@
/** Helper function to generate a random 4-character string */
export const random4 = () =>
Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);