Skip to content

Commit

Permalink
WEB-2079 a11y
Browse files Browse the repository at this point in the history
  • Loading branch information
Pedro Ladaria committed Nov 8, 2024
1 parent ca07704 commit 72a13b1
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 5 deletions.
11 changes: 10 additions & 1 deletion src/__stories__/meter-story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export default {
type MeterStoryArgs = {
type: MeterType;
reverse: boolean;
ariaLabel: string;
themeVariant: 'default' | 'inverse' | 'media';
fullWidth: boolean;
width: number;
Expand All @@ -79,6 +80,7 @@ export const MeterStory: StoryComponent<MeterStoryArgs> = ({
valuesCount,
fullWidth,
width,
ariaLabel,
...valuesArgs
}) => {
const values = Object.values(valuesArgs).slice(0, valuesCount);
Expand All @@ -92,7 +94,13 @@ export const MeterStory: StoryComponent<MeterStoryArgs> = ({
>
<ResponsiveLayout variant={themeVariant} fullWidth>
<Box padding={16}>
<Meter type={type} reverse={reverse} values={values} width={fullWidth ? '100%' : width} />
<Meter
aria-label={ariaLabel || undefined}
type={type}
reverse={reverse}
values={values}
width={fullWidth ? '100%' : width}
/>
</Box>
</ResponsiveLayout>
</div>
Expand All @@ -103,6 +111,7 @@ MeterStory.storyName = 'Meter';
MeterStory.args = {
type: 'angular',
reverse: false,
ariaLabel: '',
themeVariant: 'default',
fullWidth: false,
width: 400,
Expand Down
14 changes: 12 additions & 2 deletions src/meter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {useThemeVariant} from './theme-variant-context';
import {useElementDimensions, useTheme} from './hooks';

import type {DataAttributes} from './utils/types';
import {meterPercentageLabel, meterSegmentLabel} from './text-tokens';

const VIEW_BOX_WIDTH = 100;
const CENTER_X = VIEW_BOX_WIDTH / 2;
Expand Down Expand Up @@ -259,15 +260,24 @@ const MeterComponent = ({

const getColor = (index: number) => segmentColors[index % segmentColors.length];

const totalPercent = Math.round((segments.at(-1)?.end || 0) * 100);

return (
<div
ref={containerRef}
style={{width: widthProp}}
{...getPrefixedDataAttributes(dataAttributes, 'Meter')}
role="meter"
aria-label={ariaLabel}
aria-valuenow={values.length > 0 ? values[0] : undefined}
aria-valuetext={values.length > 0 ? values.map((v, i) => `${i + 1} ${v}`).join(' ') : ''}
aria-valuenow={totalPercent}
aria-valuemin={0}
aria-valuemax={100}
aria-live="polite"
aria-valuetext={
ariaLabel ||
values.map((v, i) => `${t(meterSegmentLabel, i + 1, Math.round(v * 100))}`).join(', ') +
`, ${t(meterPercentageLabel, totalPercent)}`
}
aria-hidden={ariaHidden}
>
<svg
Expand Down
21 changes: 21 additions & 0 deletions src/text-tokens.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -556,3 +556,24 @@ export const ratingQuantitativeLabel: TextToken = {
de: '1$s von 2$s',
pt: '1$s de 2$s',
};

/**
* 1$s: segment number
* 2$s: segment percentage value
*/
export const meterSegmentLabel: TextToken = {
es: 'Segmento 1$s 2$s%',
en: 'Segment 1$s 2$s%',
de: 'Segment 1$s 2$s%',
pt: 'Segmento 1$s 2$s%',
};

/**
* 1$s: percentage value
*/
export const meterPercentageLabel: TextToken = {
es: '1$s% de 0% a 100%',
en: '1$s% from 0% to 100%',
de: '1$s% von 0% bis 100%',
pt: '1$s% de 0% a 100%',
};
4 changes: 2 additions & 2 deletions src/theme-context-provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,10 @@ const ThemeContextProvider = ({theme, children, as, withoutStyles = false}: Prop

const translate = React.useCallback(
(token: TextToken, ...params: Array<string | number>): string => {
const text = token[language] || token.en;
let text = token[language] || token.en;
// reverse loop because we want to substitute 11$s before 1$s
for (let i = params.length - 1; i >= 0; i--) {
text.replaceAll(`${i + 1}$s`, String(params[i]));
text = text.replaceAll(`${i + 1}$s`, String(params[i]));
}
return text;
},
Expand Down

0 comments on commit 72a13b1

Please sign in to comment.