Merge pull request #50 from reuters-graphics/scroller

Accessibility updates to Scroller
This commit is contained in:
MinamiFunakoshiTR 2023-01-18 16:08:54 -06:00 committed by GitHub
commit 86e0924bcc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 130 additions and 23 deletions

View file

@ -5,11 +5,11 @@ import type { ComponentType } from 'svelte';
*/ */
export type ContainerWidth = 'narrower' | 'narrow' | 'normal' | 'wide' | 'wider' | 'widest' | 'fluid'; export type ContainerWidth = 'narrower' | 'narrow' | 'normal' | 'wide' | 'wider' | 'widest' | 'fluid';
/** /**
* A step in the Scroller component. * A step in the Scroller component.
*/ */
export interface ScrollerStep { export interface ScrollerStep {
altText?: string;
/** /**
* A background component * A background component
* @required * @required

View file

@ -8,8 +8,8 @@
import Block from '../../Block/Block.svelte'; import Block from '../../Block/Block.svelte';
</script> </script>
<Block width={backgroundWidth} cls="background-container step-{index + 1}"> <Block width="{backgroundWidth}" cls="background-container step-{index + 1}">
<div class="embedded-background step-{index + 1}"> <div class="embedded-background step-{index + 1}" aria-hidden="true">
<svelte:component <svelte:component
this="{step.background}" this="{step.background}"
{...step.backgroundProps || {}} {...step.backgroundProps || {}}

View file

@ -11,11 +11,23 @@
{#if step.foreground === '' || !step.foreground} {#if step.foreground === '' || !step.foreground}
<!-- Empty foreground --> <!-- Empty foreground -->
<div class="empty-step-foreground step-{index + 1}"></div> <div class="empty-step-foreground step-{index + 1}"></div>
{#if typeof step.altText === 'string'}
<div class="background-alt-text visually-hidden">
{@html marked.parse(step.altText)}
</div>
{/if}
{:else if typeof step.foreground === 'string'} {:else if typeof step.foreground === 'string'}
<Block cls="body-text step-{index + 1}"> <Block cls="body-text step-{index + 1}">
<div class="embedded-foreground step-{index + 1}"> <div class="embedded-foreground step-{index + 1}">
{@html marked.parse(step.foreground)} {@html marked.parse(step.foreground)}
</div> </div>
{#if typeof step.altText === 'string'}
<div class="background-alt-text visually-hidden">
{@html marked.parse(step.altText)}
</div>
{/if}
</Block> </Block>
{:else} {:else}
<div class="embedded-foreground step-{index + 1}"> <div class="embedded-foreground step-{index + 1}">
@ -27,7 +39,7 @@
{/if} {/if}
<style lang="scss"> <style lang="scss">
@import "./../../../scss/mixins"; @import './../../../scss/mixins';
div.embedded-foreground { div.embedded-foreground {
:global { :global {
@include body-text; @include body-text;
@ -36,4 +48,8 @@
margin-bottom: 0; margin-bottom: 0;
} }
} }
.visually-hidden {
@include visually-hidden;
}
</style> </style>

View file

@ -1,5 +1,5 @@
<script lang="ts"> <script lang="ts">
import type { ScrollerStep } from '../@types/global'; import type { ScrollerStep } from '../@types/global';
export let steps: ScrollerStep[] = []; export let steps: ScrollerStep[] = [];
@ -11,6 +11,11 @@
{#if step.foreground === '' || !step.foreground} {#if step.foreground === '' || !step.foreground}
<!-- Empty foreground --> <!-- Empty foreground -->
<div class="empty-step-foreground"></div> <div class="empty-step-foreground"></div>
{#if typeof step.altText === 'string'}
<div class="background-alt-text visually-hidden">
{@html marked.parse(step.altText)}
</div>
{/if}
{:else} {:else}
<div class="step-foreground"> <div class="step-foreground">
{#if typeof step.foreground === 'string'} {#if typeof step.foreground === 'string'}
@ -22,11 +27,18 @@
/> />
{/if} {/if}
</div> </div>
{#if typeof step.altText === 'string'}
<div class="background-alt-text visually-hidden">
{@html marked.parse(step.altText)}
</div>
{/if}
{/if} {/if}
</div> </div>
{/each} {/each}
<style lang="scss"> <style lang="scss">
@import './../../scss/mixins';
div.step-foreground-container { div.step-foreground-container {
height: 100vh; height: 100vh;
width: initial; width: initial;
@ -45,4 +57,8 @@
} }
} }
} }
.visually-hidden {
@include visually-hidden;
}
</style> </style>

View file

@ -38,9 +38,22 @@
ID: 'my-scroller', ID: 'my-scroller',
StackBackground: 'true', StackBackground: 'true',
Steps: [ Steps: [
{ Background: 'AiMap1', Text: '#### Step 1\n\nLorem ipsum' }, {
{ Background: 'AiMap2', Text: '#### Step 2\n\nLorem ipsum' }, Background: 'AiMap1',
{ Background: 'AiMap3', Text: '#### Step 3\n\nLorem ipsum' }, Text: '#### Step 1\n\nLorem ipsum',
AltText: 'A map showing the Upper West side in New York City.',
},
{
Background: 'AiMap2',
Text: '#### Step 2\n\nLorem ipsum',
AltText: 'The same map now highlights 98th Street.',
},
{
Background: 'AiMap3',
Text: '#### Step 3\n\nLorem ipsum',
AltText:
'The same map now highlights three locations near 98th Street where something particulary important happened.',
},
], ],
}; };
@ -80,16 +93,19 @@
background: BasicStep, background: BasicStep,
backgroundProps: { colour: 'red' }, backgroundProps: { colour: 'red' },
foreground: '#### Step 1\n\nLorem ipsum red', foreground: '#### Step 1\n\nLorem ipsum red',
altText: 'Red background',
}, },
{ {
background: BasicStep, background: BasicStep,
backgroundProps: { colour: 'blue' }, backgroundProps: { colour: 'blue' },
foreground: '#### Step 2\n\nLorem ipsum blue', foreground: '#### Step 2\n\nLorem ipsum blue',
altText: 'Blue background',
}, },
{ {
background: BasicStep, background: BasicStep,
backgroundProps: { colour: 'green' }, backgroundProps: { colour: 'green' },
foreground: '#### Step 3\n\nLorem ipsum green', foreground: '#### Step 3\n\nLorem ipsum green',
altText: 'Green background',
}, },
], ],
foregroundPosition: 'middle', foregroundPosition: 'middle',
@ -142,16 +158,21 @@
background: AiMap1, background: AiMap1,
backgroundProps: { colour: 'red' }, backgroundProps: { colour: 'red' },
foreground: '#### Step 1\n\nLorem ipsum', foreground: '#### Step 1\n\nLorem ipsum',
altText: 'A map showing the Upper West side in New York City.',
}, },
{ {
background: AiMap2, background: AiMap2,
backgroundProps: { colour: 'blue' }, backgroundProps: { colour: 'blue' },
foreground: '#### Step 2\n\nLorem ipsum', foreground: '#### Step 2\n\nLorem ipsum',
altText:
'The same map now highlights 98th Street where something interesting happened.',
}, },
{ {
background: AiMap3, background: AiMap3,
backgroundProps: { colour: 'green' }, backgroundProps: { colour: 'green' },
foreground: '#### Step 3\n\nLorem ipsum', foreground: '#### Step 3\n\nLorem ipsum',
altText:
'The same map now highlights three locations near 98th Street where something particulary important happened.',
}, },
], ],
foregroundPosition: 'middle', foregroundPosition: 'middle',

View file

@ -12,9 +12,10 @@
* *
* Each step object in the array can have: * Each step object in the array can have:
* *
* - `background` A background component **REQUIRED** * - `background` A background component. **REQUIRED**
* - `backgroundProps` An object of props given to the background component * - `backgroundProps` An object of props given to the background component
* - `foreground` Either a markdown-formatted string or a foreground component **REQUIRED** * - `foreground` Either a markdown-formatted string or a foreground component **REQUIRED**
* - `altText` A string describing the background graphic, which is read aloud after the foreground blurb. You can add it to each step or, if you want to add just one alt text to describe all graphics in the scroll section, add it to just the first step. **RECOMMENDED**
* - `foregroundProps` An object of props given to the foreground component * - `foregroundProps` An object of props given to the foreground component
* *
* @required * @required
@ -116,6 +117,7 @@
class="background" class="background"
class:right="{foregroundPosition === 'left opposite'}" class:right="{foregroundPosition === 'left opposite'}"
class:left="{foregroundPosition === 'right opposite'}" class:left="{foregroundPosition === 'right opposite'}"
aria-hidden="true"
> >
<div class="scroller-graphic-well"> <div class="scroller-graphic-well">
<Block <Block

View file

@ -1,6 +1,7 @@
import type { ComponentType } from 'svelte'; import type { ComponentType } from 'svelte';
interface BlockStep { interface BlockStep {
AltText?: string;
Background: string; Background: string;
Text: string; Text: string;
} }
@ -30,6 +31,7 @@ export const getScrollerPropsFromDoc = (docBlock: Block, aiCharts: AiCharts, ass
background: aiCharts[step.Background], background: aiCharts[step.Background],
backgroundProps: { assetsPath }, backgroundProps: { assetsPath },
foreground: step.Text, foreground: step.Text,
altText: step.AltText,
})), })),
}; };
}; };

View file

@ -15,16 +15,19 @@ A more detailed example of using `Scroller` with graphics created by [ai2svelte]
background: MyAiMap1, background: MyAiMap1,
backgroundProps: { assetsPath: assets }, backgroundProps: { assetsPath: assets },
foreground: '#### Step 1\n\nLorem ipsum', foreground: '#### Step 1\n\nLorem ipsum',
altText: 'A map showing TKTK',
}, },
{ {
background: MyAiMap2, background: MyAiMap2,
backgroundProps: { assetsPath: assets }, backgroundProps: { assetsPath: assets },
foreground: '#### Step 2\n\nLorem ipsum', foreground: '#### Step 2\n\nLorem ipsum',
altText: 'The same map now highlights something interesting.',
}, },
{ {
background: MyAiMap3, background: MyAiMap3,
backgroundProps: { assetsPath: assets }, backgroundProps: { assetsPath: assets },
foreground: '#### Step 3\n\nLorem ipsum', foreground: '#### Step 3\n\nLorem ipsum',
altText: 'The same map now shows something else that is interesting.',
}, },
]; ];
</script> </script>
@ -48,14 +51,22 @@ Step1Text: #### Step 1
Lorem Ipsum Lorem Ipsum
:end :end
AltText1: A map showing the Upper West side in New York City.
:end
Step2Text: #### Step 2 Step2Text: #### Step 2
Lorem Ipsum Lorem Ipsum
:end :end
AltText2: The same map now highlights 98th Street.
:end
Step3Text: #### Step 3 Step3Text: #### Step 3
Lorem Ipsum Lorem Ipsum
:end :end
AltText3: The same map now highlights three locations near 98th Street where something particulary important happened.
:end
``` ```
```svelte ```svelte
@ -77,16 +88,19 @@ Lorem Ipsum
background: MyAiMap1, background: MyAiMap1,
backgroundProps: { basePath: assets }, backgroundProps: { basePath: assets },
foreground: scrollerBlock.Step1Text, foreground: scrollerBlock.Step1Text,
altText: scrollerBlock.AltText1,
}, },
{ {
background: MyAiMap2, background: MyAiMap2,
backgroundProps: { basePath: assets }, backgroundProps: { basePath: assets },
foreground: scrollerBlock.Step2Text, foreground: scrollerBlock.Step2Text,
altText: scrollerBlock.AltText2,
}, },
{ {
background: MyAiMap3, background: MyAiMap3,
backgroundProps: { basePath: assets }, backgroundProps: { basePath: assets },
foreground: scrollerBlock.Step3Text, foreground: scrollerBlock.Step3Text,
altText: scrollerBlock.AltText3,
}, },
]; ];
</script> </script>

View file

@ -11,17 +11,31 @@ Check out the "Canvas" tab to play with the layout options available on this com
import MyColourBackground from './MyColourBackground.svelte'; import MyColourBackground from './MyColourBackground.svelte';
const steps = [ const steps = [
{ background: MyColourBackground, backgroundProps: { colour: 'red' }, foreground: '#### Step 1\n\nLorem ipsum red' }, {
{ background: MyColourBackground, backgroundProps: { colour: 'blue' }, foreground: '#### Step 2\n\nLorem ipsum blue' }, background: MyColourBackground,
{ background: MyColourBackground, backgroundProps: { colour: 'green' }, foreground: '#### Step 3\n\nLorem ipsum green' }, backgroundProps: { colour: 'red' },
] foreground: '#### Step 1\n\nLorem ipsum red',
altText: 'Red background',
},
{
background: MyColourBackground,
backgroundProps: { colour: 'blue' },
foreground: '#### Step 2\n\nLorem ipsum blue',
altText: 'Blue background',
},
{
background: MyColourBackground,
backgroundProps: { colour: 'green' },
foreground: '#### Step 3\n\nLorem ipsum green',
altText: 'Green background',
},
];
</script> </script>
<Scroller <Scroller
steps="{steps}" steps="{steps}"
backgroundWidth="fluid" backgroundWidth="fluid"
foregroundPosition="middle" foregroundPosition="middle"
embedded={false} embedded="{false}"
/> />
``` ```

View file

@ -1,22 +1,36 @@
Instead of just text, you can use any component in the foreground, too, and pass whatever props you need to it. Instead of just text, you can use any component in the foreground, too, and pass whatever props you need to it.
If you're making your own custom foreground component, remember to add alt text describing the background graphic.
```svelte ```svelte
<script> <script>
// ... // ...
import MyCounter from './MyCounter.svelte'; import MyCounter from './MyCounter.svelte';
const steps = [ const steps = [
{ background: MyColourBackground, backgroundProps: { colour: 'red' }, foreground: MyCounter }, {
{ background: MyColourBackground, backgroundProps: { colour: 'blue' }, foreground: '#### Step 2\n\nLorem ipsum blue' }, background: MyColourBackground,
{ background: MyColourBackground, backgroundProps: { colour: 'green' }, foreground: MyCounter, foregroundProps: { count: 100 } }, backgroundProps: { colour: 'red' },
] foreground: MyCounter,
},
{
background: MyColourBackground,
backgroundProps: { colour: 'blue' },
foreground: '#### Step 2\n\nLorem ipsum blue',
},
{
background: MyColourBackground,
backgroundProps: { colour: 'green' },
foreground: MyCounter,
foregroundProps: { count: 100 },
},
];
</script> </script>
<Scroller <Scroller
steps="{steps}" steps="{steps}"
backgroundWidth="fluid" backgroundWidth="fluid"
foregroundPosition="middle" foregroundPosition="middle"
embedded={false} embedded="{false}"
/> />
``` ```

View file

@ -35,18 +35,26 @@ StackBackground: true
Lorem ipsum Lorem ipsum
:end :end
AltText: A map showing the Upper West side in New York City.
Can add paragraphs of alt text if you want to break up sentences.
:end
Background: AiMap2 Background: AiMap2
Text: #### Step 2 Text: #### Step 2
Lorem ipsum Lorem ipsum
:end :end
AltText: The same map now highlights 98th Street.
:end
Background: AiMap3 Background: AiMap3
Text: #### Step 3 Text: #### Step 3
Lorem ipsum Lorem ipsum
:end :end
AltText: The same map now highlights three locations near 98th Street where something particulary important happened.
:end
[] []
``` ```