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

Improve accessibility (a11y) for screen-readers #70

Merged
merged 3 commits into from
Sep 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions _sass/spec/base.scss
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,14 @@ $Z_INDEX_SIDEBAR: 4;

// These are section headers in the sidebar
.primer-spec-toc {
&-list {
list-style-type: none;
}
&-item {
// Prevent header items from ending too near the border of the Sidebar
padding-right: 1em;
}

&-h1 {
margin-left: auto;
margin-top: 0.7em;
Expand Down Expand Up @@ -208,14 +216,10 @@ $Z_INDEX_SIDEBAR: 4;
}

// Attribute selector for all primer-spec-toc-* classes
div[class^='primer-spec-toc-'] {
div[class^='primer-spec-toc-'],
.primer-spec-toc-section {
padding-left: 0.5em;
margin-left: 0em;

// Header items in the sidebar still need padding
&.primer-spec-toc-item {
padding-right: 1em;
}
}

.primer-spec-settings {
Expand Down
2 changes: 1 addition & 1 deletion assets/v1.4/js/primer_spec_plugin.min.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions src_js/components/MainContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ export default function MainContent(props: PropsType) {
const is_print_in_progress = usePrintInProgress();

return (
<div
<main
id={Config.PRIMER_SPEC_CONTENT_PREACT_NODE_ID}
class={`container-lg px-3 my-5 markdown-body ${
props.sidebarShown && !props.isSmallScreen && !is_print_in_progress
? 'primer-spec-content-margin-extra'
: ''
} ${props.isSmallScreen ? 'primer-spec-content-mobile' : ''}`}
dangerouslySetInnerHTML={{ __html: props.innerHTML }}
></div>
></main>
);
}
12 changes: 6 additions & 6 deletions src_js/components/PrimerSpec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,6 @@ export default function PrimerSpec(props: PropsType) {

return (
<Fragment>
<MainContent
innerHTML={props.contentHTML}
isSmallScreen={is_small_screen}
sidebarShown={sidebar_shown}
/>
{sidebar}
<Topbar
isSmallScreen={is_small_screen}
showSidebarToggle={!Config.DISABLE_SIDEBAR}
Expand All @@ -90,6 +84,12 @@ export default function PrimerSpec(props: PropsType) {
onToggleSidebar={toggleSidebarShown}
onToggleSettings={toggleSettingsShown}
/>
<MainContent
innerHTML={props.contentHTML}
isSmallScreen={is_small_screen}
sidebarShown={sidebar_shown}
/>
{sidebar}
<Settings
isSmallScreen={is_small_screen}
sidebarShown={sidebar_shown}
Expand Down
2 changes: 1 addition & 1 deletion src_js/components/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export default function Settings(props: PropsType) {

<p>
<small>
{'Does the spec display incorrectly?'}
{'Does the spec display incorrectly? '}
<a href="https://github.com/eecs485staff/primer-spec/issues">
{'Let us know by adding a new "issue" here.'}
</a>
Expand Down
25 changes: 14 additions & 11 deletions src_js/components/Topbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,15 @@ export default function Topbar(props: PropsType) {

let sidebar_toggle = null;
if (props.showSidebarToggle) {
sidebar_toggle =
props.isSmallScreen && props.sidebarShown ? null : (
<div class={`primer-spec-sidebar-toggle-fixed primer-spec-float-left`}>
<InlineButton
icon={IconType.SIDEBAR}
onClick={props.onToggleSidebar}
/>
</div>
);
sidebar_toggle = props.sidebarShown ? null : (
<div class={`primer-spec-sidebar-toggle-fixed primer-spec-float-left`}>
<InlineButton
icon={IconType.SIDEBAR}
onClick={props.onToggleSidebar}
ariaLabel={'Open navigation pane'}
/>
</div>
);
}

let settings_toggle = null;
Expand All @@ -50,20 +50,23 @@ export default function Topbar(props: PropsType) {
<InlineButton
icon={props.settingsShown ? IconType.CLOSE : IconType.SETTINGS}
onClick={props.onToggleSettings}
ariaLabel={
props.settingsShown ? 'Close settings pane' : 'Open settings pane'
}
/>
</div>
);
}

return (
<div
<header
ref={topbarRef}
class={`primer-spec-topbar position-fixed width-full top-0 left-0 py-2 no-print ${
props.isSmallScreen ? 'primer-spec-topbar-mobile' : ''
} ${props.settingsShown ? 'primer-spec-topbar-settings-shown' : ''}`}
>
{sidebar_toggle}
{settings_toggle}
</div>
</header>
);
}
2 changes: 2 additions & 0 deletions src_js/components/common/InlineButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import IconType from './IconType';
export type PropsType = {
icon: IconType;
onClick: () => void;
ariaLabel?: string;
};

export default function InlineButton(props: PropsType) {
Expand All @@ -16,6 +17,7 @@ export default function InlineButton(props: PropsType) {
event.preventDefault();
props.onClick();
}}
aria-label={props.ariaLabel}
>
<i class={props.icon}></i>
</a>
Expand Down
16 changes: 13 additions & 3 deletions src_js/components/sidebar/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,24 @@ export default function Sidebar(props: SidebarProps) {

// The explicit onClick handler is needed to force Safari (iOS) to propagate
// click events for the sidebar.
// We use an <aside> element to indicate to screen-readers that the Sidebar
// only contains complementary content.
// We also need to unset the Sidebar's `tabIndex` to make its border
// unfocusable.
return (
<div
<aside
class="primer-spec-sidebar position-fixed top-0 py-5 no-print"
onClick={() => true}
aria-label="Table of Contents"
tabIndex={-1}
>
<h2 class="primer-spec-toc-ignore" id="primer-spec-toc-contents">
Contents
<InlineButton icon={IconType.SIDEBAR} onClick={props.onToggleSidebar} />
<InlineButton
icon={IconType.SIDEBAR}
onClick={props.onToggleSidebar}
ariaLabel="Close navigation pane"
/>
</h2>
<br />
<TableOfContents
Expand All @@ -73,6 +83,6 @@ export default function Sidebar(props: SidebarProps) {
onToggleSidebar={props.onToggleSidebar}
onToggleSettings={props.onToggleSettings}
/>
</div>
</aside>
);
}
18 changes: 11 additions & 7 deletions src_js/components/sidebar/TableOfContents.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { h, Fragment } from 'preact';
import { h } from 'preact';
import { useState, useEffect } from 'preact/hooks';
import unflattenHeadings, { HeadingsSectionType } from './unflattenHeadings';

Expand Down Expand Up @@ -50,7 +50,7 @@ export default function TableOfContents(props: PropsType) {
props.activeSectionOffsetY,
);

return <div id="primer-spec-toc">{tocNodes}</div>;
return <nav id="primer-spec-toc">{tocNodes}</nav>;
}

function generateTocNodesForContentNode(
Expand Down Expand Up @@ -96,24 +96,28 @@ function generateTocNodesForContentNode(
*/
function generateTocNodes(headings: Element[], activeHeadingIndex: number) {
const unflattened = unflattenHeadings(headings, activeHeadingIndex);
return unflattened.map((section) => generateTocNodesHelper(section));
return (
<ul class="primer-spec-toc-list">
{unflattened.map((section) => generateTocNodesHelper(section))}
</ul>
);
}

function generateTocNodesHelper(section: HeadingsSectionType) {
const heading = section.heading as HTMLElement;
return (
<Fragment>
<li>
<div
class={`primer-spec-toc-item primer-spec-toc-${heading.tagName.toLowerCase()} ${
section.active ? 'primer-spec-toc-active' : ''
}`}
>
<a href={getAnchorLink(heading)}>{heading.textContent}</a>
</div>
<div class="primer-spec-toc-section">
<ul class="primer-spec-toc-section primer-spec-toc-list">
{section.section.map((_section) => generateTocNodesHelper(_section))}
</div>
</Fragment>
</ul>
</li>
);
}

Expand Down