Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: updated accessibility section #4161

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 14 additions & 0 deletions packages/accordion/accessibility.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
### Keyboard interactions

Each accordion is a tab stop. Space or Enter keys expand or collapse accordions, which are collapsed by default. Interactive elements within expanded accordions integrate into the tab order automatically.

### Development considerations

Keep these considerations in mind if you are modifying Spectrum Web Components or creating a custom component:

- The accordion header has a role of `<sp-button>`, with an aria-expanded attribute set to "true" or "false".
- The button has an aria-controls property set to the unique id of the panel it controls.
- Since accordions are typically grouped together, Spectrum Web Components puts each button inside a list item in an unordered list, which provides additional context to screen reader users; where only one accordion is used, it should not be put in a list.
- When accordion titles are used as headings, the buttons are also wrapped in an element with an appropriate heading level; ARIA can be used to set both the heading role and the level (via aria-level).

See the [ARIA authoring practices](https://www.w3.org/TR/wai-aria-practices-1.2/#accordion) for more guidance.
12 changes: 12 additions & 0 deletions projects/documentation/content/_includes/accessibility.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
layout: component-partial.njk
---
<sp-tabs
selected="accessibility"
direction="horizontal"
aria-labelledby="component-name"
>
<sp-tab value="examples">Examples</sp-tab>
<sp-tab value="api">API</sp-tab>
<sp-tab value="accessibility">Accessibility</sp-tab>

3 changes: 2 additions & 1 deletion projects/documentation/content/_includes/api.njk
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ layout: component-partial.njk
aria-labelledby="component-name"
>
<sp-tab value="examples">Examples</sp-tab>
<sp-tab value="api">API</sp-tab>
<sp-tab value="api">API</sp-tab>
<sp-tab value="accessibility">Accessibility</sp-tab>
3 changes: 3 additions & 0 deletions projects/documentation/content/_includes/component.njk
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ layout: layout.njk
{% for part in collections[componentName] %}
<sp-tab-panel class="section" value="{{ part.data.partType }}">
{{ part.templateContent | safe }}
{% if isComponentTemplate and part.data.partType === 'accessibility' %}
{% include "partials/accessibility.njk" %}
{% endif %}
</sp-tab-panel>
{% endfor %}
</sp-tabs>
Expand Down
3 changes: 2 additions & 1 deletion projects/documentation/content/_includes/examples.njk
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ layout: component.njk
{% endfor %}
{% if hasAPI === true %}
<sp-tab value="api">API</sp-tab>
{% endif %}
{% endif %}
<sp-tab value="accessibility">Accessibility</sp-tab>
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<div class="headerContainer">
<h2 id="accessibility" tabindex="-1" class="spectrum-Heading spectrum-Heading--sizeM">Accessibility testing status&nbsp;<sp-link class="header-anchor" href="#accessibility" aria-label="Accessibility" dir="ltr" focusable="">#</sp-link></h2>
<sp-divider size="l" dir="ltr" role="separator"></sp-divider>
</div>
<sp-table quiet style="--mod-table-row-background-color-hover: none">
<sp-table-head>
<sp-table-head-cell>Component</sp-table-head-cell>
<sp-table-head-cell>Accessibility test</sp-table-head-cell>
<sp-table-head-cell>Accessibility Contract</sp-table-head-cell>
<sp-table-head-cell>Status</sp-table-head-cell>
</sp-table-head>
<sp-table-body>
<sp-table-row value="row1">
<sp-table-cell><sp-link href="https://opensource.adobe.com/spectrum-web-components/components/{{componentName}}/#usage">{{componentName}}</sp-link></sp-table-cell>
<sp-table-cell>
<sp-button static="white" style="--mod-bold-font-weight:400">Default state</sp-button>
</sp-table-cell>
Comment on lines +15 to +17
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't use a button for static cell content. Also, static="white" is meant to render a button over a dark colored background, so that the border and focus ring will be white. Using it in this case makes the border and focus ring render as white on white, which makes it impossible to track focus.

Suggested change
<sp-table-cell>
<sp-button static="white" style="--mod-bold-font-weight:400">Default state</sp-button>
</sp-table-cell>
<sp-table-cell>
Default state
</sp-table-cell>

<sp-table-cell>
<sp-button static="white" style="--mod-bold-font-weight:400">Test(s) that ensure the initial render state of a component is accessible.</sp-button></sp-table-cell>
<sp-table-cell>
<sp-button id="trigger-1" variant="secondary" style="--mod-button-background-color-default: #a7f0ba;">Tested</sp-button>
<sp-overlay trigger="trigger-1@hover" placement="bottom">
<sp-tooltip>
Passes all automated tests with no reported accessibility violations.
</sp-tooltip>
</sp-overlay>
</sp-table-cell>
</sp-table-row>
<sp-table-row value="row2">
<sp-table-cell></sp-table-cell>
<sp-table-cell>
<sp-button static="white" style="--mod-bold-font-weight:400">Advanced states</sp-button>
</sp-table-cell>
<sp-table-cell>
<sp-button static="white" style="--mod-bold-font-weight:400">Tests that ensure additional states of the component are accessible.
This could be interactive states of a component or its multiple variants.</sp-button>
</sp-table-cell>
<sp-table-cell>
<sp-button id="trigger-2" variant="secondary" style="--mod-button-background-color-default: #a7f0ba;">Tested</sp-button>
<sp-overlay trigger="trigger-2@hover" placement="bottom">
<sp-tooltip>
Passes all automated tests with no reported accessibility violations.
</sp-tooltip>
</sp-overlay>
</sp-table-cell>
</sp-table-row>
<sp-table-row value="row2">
<sp-table-cell></sp-table-cell>
<sp-table-cell>
<sp-button static="white" style="--mod-bold-font-weight:400">Keyboard navigation</sp-button>
</sp-table-cell>
<sp-table-cell>
<sp-button static="white" style="--mod-bold-font-weight:400">Tests that ensure focus is properly managed, and all interactive functions of a
component have a proper keyboard-accessible equivalent.</sp-button>
</sp-table-cell>
<sp-table-cell>
<sp-button id="trigger-3" variant="secondary" style="--mod-button-background-color-default: #a7f0ba;">Tested</sp-button>
<sp-overlay trigger="trigger-3@hover" placement="bottom">
<sp-tooltip>
Passes all automated tests with no reported accessibility violations.
</sp-tooltip>
</sp-overlay>
</sp-table-cell>
</sp-table-row>
<sp-table-row value="row3">
<sp-table-cell></sp-table-cell>
<sp-table-cell>
<sp-button static="white" style="--mod-bold-font-weight:400">Screen reader</sp-button>
</sp-table-cell>
<sp-table-cell>
<sp-button static="white" style="--mod-bold-font-weight:400">This manual testing ensures that the visual information on the screen
is properly conveyed and read correctly by screen readers such as JAWS, VoiceOver, and NVDA.</sp-button>
</sp-table-cell>
<sp-table-cell>
<sp-button id="trigger-4" variant="secondary" style="--mod-button-background-color-default: #9ef0f0;">Manually Tested</sp-button>
<sp-overlay trigger="trigger-4@hover" placement="bottom">
<sp-tooltip>
A human has manually tested this component, e.g. screen reader testing.
</sp-tooltip>
</sp-overlay>
</sp-table-cell>
</sp-table-row>
</sp-table-body>
</sp-table>
Comment on lines +5 to +84
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<sp-table quiet style="--mod-table-row-background-color-hover: none">
<sp-table-head>
<sp-table-head-cell>Component</sp-table-head-cell>
<sp-table-head-cell>Accessibility test</sp-table-head-cell>
<sp-table-head-cell>Accessibility Contract</sp-table-head-cell>
<sp-table-head-cell>Status</sp-table-head-cell>
</sp-table-head>
<sp-table-body>
<sp-table-row value="row1">
<sp-table-cell><sp-link href="https://opensource.adobe.com/spectrum-web-components/components/{{componentName}}/#usage">{{componentName}}</sp-link></sp-table-cell>
<sp-table-cell>
<sp-button static="white" style="--mod-bold-font-weight:400">Default state</sp-button>
</sp-table-cell>
<sp-table-cell>
<sp-button static="white" style="--mod-bold-font-weight:400">Test(s) that ensure the initial render state of a component is accessible.</sp-button></sp-table-cell>
<sp-table-cell>
<sp-button id="trigger-1" variant="secondary" style="--mod-button-background-color-default: #a7f0ba;">Tested</sp-button>
<sp-overlay trigger="trigger-1@hover" placement="bottom">
<sp-tooltip>
Passes all automated tests with no reported accessibility violations.
</sp-tooltip>
</sp-overlay>
</sp-table-cell>
</sp-table-row>
<sp-table-row value="row2">
<sp-table-cell></sp-table-cell>
<sp-table-cell>
<sp-button static="white" style="--mod-bold-font-weight:400">Advanced states</sp-button>
</sp-table-cell>
<sp-table-cell>
<sp-button static="white" style="--mod-bold-font-weight:400">Tests that ensure additional states of the component are accessible.
This could be interactive states of a component or its multiple variants.</sp-button>
</sp-table-cell>
<sp-table-cell>
<sp-button id="trigger-2" variant="secondary" style="--mod-button-background-color-default: #a7f0ba;">Tested</sp-button>
<sp-overlay trigger="trigger-2@hover" placement="bottom">
<sp-tooltip>
Passes all automated tests with no reported accessibility violations.
</sp-tooltip>
</sp-overlay>
</sp-table-cell>
</sp-table-row>
<sp-table-row value="row2">
<sp-table-cell></sp-table-cell>
<sp-table-cell>
<sp-button static="white" style="--mod-bold-font-weight:400">Keyboard navigation</sp-button>
</sp-table-cell>
<sp-table-cell>
<sp-button static="white" style="--mod-bold-font-weight:400">Tests that ensure focus is properly managed, and all interactive functions of a
component have a proper keyboard-accessible equivalent.</sp-button>
</sp-table-cell>
<sp-table-cell>
<sp-button id="trigger-3" variant="secondary" style="--mod-button-background-color-default: #a7f0ba;">Tested</sp-button>
<sp-overlay trigger="trigger-3@hover" placement="bottom">
<sp-tooltip>
Passes all automated tests with no reported accessibility violations.
</sp-tooltip>
</sp-overlay>
</sp-table-cell>
</sp-table-row>
<sp-table-row value="row3">
<sp-table-cell></sp-table-cell>
<sp-table-cell>
<sp-button static="white" style="--mod-bold-font-weight:400">Screen reader</sp-button>
</sp-table-cell>
<sp-table-cell>
<sp-button static="white" style="--mod-bold-font-weight:400">This manual testing ensures that the visual information on the screen
is properly conveyed and read correctly by screen readers such as JAWS, VoiceOver, and NVDA.</sp-button>
</sp-table-cell>
<sp-table-cell>
<sp-button id="trigger-4" variant="secondary" style="--mod-button-background-color-default: #9ef0f0;">Manually Tested</sp-button>
<sp-overlay trigger="trigger-4@hover" placement="bottom">
<sp-tooltip>
A human has manually tested this component, e.g. screen reader testing.
</sp-tooltip>
</sp-overlay>
</sp-table-cell>
</sp-table-row>
</sp-table-body>
</sp-table>
<sp-table role="table" quiet style="--mod-table-row-background-color-hover: none">
<sp-table-head>
<sp-table-head-cell>Component</sp-table-head-cell>
<sp-table-head-cell>Accessibility test</sp-table-head-cell>
<sp-table-head-cell>Accessibility Contract</sp-table-head-cell>
<sp-table-head-cell>Status</sp-table-head-cell>
</sp-table-head>
<sp-table-body>
<sp-table-row value="row1">
<sp-table-cell role="cell"><sp-link href="https://opensource.adobe.com/spectrum-web-components/components/{{componentName}}/#usage">{{componentName}}</sp-link></sp-table-cell>
<sp-table-cell role="rowheader">
Default state
</sp-table-cell>
<sp-table-cell role="cell">
Test(s) that ensure the initial render state of a component is accessible.
</sp-table-cell>
<sp-table-cell role="cell">
<sp-button id="trigger-1" variant="secondary" style="--mod-button-background-color-default: #a7f0ba;">Tested</sp-button>
<sp-overlay trigger="trigger-1@hover" placement="bottom">
<sp-tooltip>
Passes all automated tests with no reported accessibility violations.
</sp-tooltip>
</sp-overlay>
</sp-table-cell>
</sp-table-row>
<sp-table-row value="row2">
<sp-table-cell role="cell"></sp-table-cell>
<sp-table-cell role="rowheader">
Advanced states
</sp-table-cell>
<sp-table-cell role="cell">
Tests that ensure additional states of the component are accessible.
This could be interactive states of a component or its multiple variants.
</sp-table-cell>
<sp-table-cell role="cell">
<sp-button id="trigger-2" variant="secondary" style="--mod-button-background-color-default: #a7f0ba;">Tested</sp-button>
<sp-overlay trigger="trigger-2@hover" placement="bottom">
<sp-tooltip>
Passes all automated tests with no reported accessibility violations.
</sp-tooltip>
</sp-overlay>
</sp-table-cell>
</sp-table-row>
<sp-table-row value="row2">
<sp-table-cell role="cell"></sp-table-cell>
<sp-table-cell role="rowheader">
Keyboard navigation
</sp-table-cell>
<sp-table-cell role="cell">
Tests that ensure focus is properly managed, and all interactive functions of a
component have a proper keyboard-accessible equivalent.
</sp-table-cell>
<sp-table-cell role="cell">
<sp-button id="trigger-3" variant="secondary" style="--mod-button-background-color-default: #a7f0ba;">Tested</sp-button>
<sp-overlay trigger="trigger-3@hover" placement="bottom">
<sp-tooltip>
Passes all automated tests with no reported accessibility violations.
</sp-tooltip>
</sp-overlay>
</sp-table-cell>
</sp-table-row>
<sp-table-row value="row3">
<sp-table-cell role="cell"></sp-table-cell>
<sp-table-cell role="rowheader">
Screen reader
</sp-table-cell>
<sp-table-cell role="cell">
This manual testing ensures that the visual information on the screen
is properly conveyed and read correctly by screen readers such as JAWS, VoiceOver, and NVDA.
</sp-table-cell>
<sp-table-cell role="cell">
<sp-button id="trigger-4" variant="secondary" style="--mod-button-background-color-default: #9ef0f0;">Manually Tested</sp-button>
<sp-overlay trigger="trigger-4@hover" placement="bottom">
<sp-tooltip>
A human has manually tested this component, e.g. screen reader testing.
</sp-tooltip>
</sp-overlay>
</sp-table-cell>
</sp-table-row>
</sp-table-body>
</sp-table>

1 change: 1 addition & 0 deletions projects/documentation/content/shell-start.njk
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ permalink: 'shell-start.html'
<sp-tabs selected="examples" direction="horizontal">
<sp-tab value="examples" label="Examples"></sp-tab>
<sp-tab value="api" label="API"></sp-tab>
<sp-tab value="accessibility" label="Accessibility"></sp-tab>
</sp-tabs>
<div class="parts">
<helper class="shell-remove-after"></helper>
32 changes: 32 additions & 0 deletions projects/documentation/scripts/component-template-parts.js
Original file line number Diff line number Diff line change
Expand Up @@ -254,3 +254,35 @@ tags:
---
${body}`;
}

export function accessibilityDestinationTemplate(
componentName,
componentHeading
) {
return `---
layout: accessibility.njk
title: '${nameToTitle(componentName)} API: Spectrum Web Components'
displayName: ${nameToTitle(componentName)}
componentName: ${componentName}
componentHeading: ${componentHeading}
tags:
- component-accessibility
---`;
}

export function accessibilityPartialTemplate(
componentName,
componentHeading,
body
) {
return `---
layout: partial.njk
title: '${nameToTitle(componentName)}: Spectrum Web Components'
displayName: ${nameToTitle(componentName)}
componentName: ${componentName}
partType: accessibility
tags:
- ${componentName}
---
${body}`;
}
61 changes: 44 additions & 17 deletions projects/documentation/scripts/copy-component-docs.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import path from 'path';
import { fileURLToPath } from 'url';

import {
accessibilityDestinationTemplate,
accessibilityPartialTemplate,
apiDestinationTemplate,
apiPartialTemplate,
exampleDestinationTemplate,
Expand Down Expand Up @@ -73,10 +75,9 @@ export async function processREADME(mdPath) {
return;
}
const packageName = extractPackageNameRegExp.exec(mdPath)[1];
let componentName =
fileName !== 'README.md'
? fileName.replace('.md', '')
: extractPackageNameRegExp.exec(mdPath)[1];
let componentName = !['README.md', 'accessibility.md'].includes(fileName)
? fileName.replace('.md', '')
: extractPackageNameRegExp.exec(mdPath)[1];
const parent =
fileName === 'README.md' ? 'root' : packageName + '-children';
let componentHeading = componentName;
Expand Down Expand Up @@ -160,20 +161,45 @@ export async function processREADME(mdPath) {
}
const tagType = isComponent ? 'component-examples' : 'tool-examples';
const body = fs.readFileSync(mdPath);
fs.writeFileSync(
exampleDestinationFile,
exampleDestinationTemplate(
if (fileName === 'accessibility.md') {
const accessibilityDestinationFile = path.resolve(
destinationPath,
componentName,
componentHeading,
tagType,
parent,
packageName
)
);
fs.writeFileSync(
examplePartialFile,
examplePartialTemplate(componentName, componentHeading, body)
);
'accessibility.md'
);
const accessibilityPartialFile = path.resolve(
destinationPath,
componentName,
'accessibility-content.md'
);
fs.writeFileSync(
accessibilityDestinationFile,
accessibilityDestinationTemplate(componentName, componentHeading)
);
fs.writeFileSync(
accessibilityPartialFile,
accessibilityPartialTemplate(
componentName,
componentHeading,
fs.readFileSync(mdPath, 'utf8')
)
);
} else {
fs.writeFileSync(
exampleDestinationFile,
exampleDestinationTemplate(
componentName,
componentHeading,
tagType,
parent,
packageName
)
);
fs.writeFileSync(
examplePartialFile,
examplePartialTemplate(componentName, componentHeading, body)
);
}
const hasArgs = fs.existsSync(
path.resolve(
__dirname,
Expand Down Expand Up @@ -210,6 +236,7 @@ export async function processREADME(mdPath) {
}export default {
hasDemoControls: ${hasArgs},
hasDemoTemplate: ${hasTemplate},
isComponentTemplate: ${isComponent},
deprecationNotice: ${JSON.stringify(deprecationNotice)},
${hasArgs ? 'demoControls: Object.values(argTypes),' : ''}
};
Expand Down