Accessibilty, first pass (#17)
* Placeholder color contrast @ WCAG 2.0 level AA * Trailing whitespace removed. * Remove redundant labels. * Logo is a link in mobile, if not-embedded; otherwise, span. Fix link labels. * HREF mandatory on A; menu behaves like a popup button. * Hide icons from screen readers. * About icon id keyboard-operarable and is labeled. * Note about inaccessible modal. * Missing closing tag. * Fix nesting/indentation. * Fix nesting/indentation; add missing closing tag. * Trailing whitespace removed. * Don't use NAV landmark for non-nav; add heading for page structure. * Hide icon. * Load archive form's buttons visibly receive keyboard focus. * Trailing whitespace removed. * "Hide" header button is keyboard-operable, and more-verbosely labeled for screenreader users. * Don't use NAV landmark for non-nav; add heading for page structure. * Sort order announced to screen reader users. * Trailing whitespace removed. * Delete button only a button when it can be pressed; announce in progress deletion. * Trailing whitespace removed. * Use a NAV landmark for replay controls. * Remove "menu" role, to avoid having to implement arrow key support https://www.w3.org/WAI/GL/wiki/Using_ARIA_menus * Hide icons. * Label buttons. * Links in disguise as buttons need HREF, and to respond to spacebar. * Re-dub "main menu" to distinguish from replay menu * Replay nav buttons visually get keyboard focus. * Trailing whitespace removed. * Hiding icons; button labels; links-as-buttons are operable. * Use type=search for additional clarity. * Add appropriate landmarks and a heading for structure and clarity. * Tab selection is a nav, and is keyboard operable. * Indentation; missing closing tag. * Trailing whitespace removed. * Title iframe. * Not a navigation. * Per discussion, rename tab to "URLs" (label only; route etc. the same while experimenting). * Announce when expanded/collapsed. * Remove "menu" to avoid having to implement expected keyboard support. * Use correct heading level when in sidebar and when main. * Trailing whitespace removed. * Semantic markup of table; headings and captions; link-buttons are keyboard operable. * Skip links for keyboard users. * Title iframe; hide icon. * Just a list, not an aside. * Not an article. * Remove trailing whitespace. * Make each page in the list a heading. * link-buttons are keyboard operable. * Use semantic list for page list. * Announce changes to search results. * More wayfinding tweaks. * Landmark and heading for replay. * Dynamic page titles. * Remove redundant labels from main landmarks. * additional tweaks after rebase - add 'role' to each of the tabs, dependent if sidebar or not - add 'role=main' for replay - add sr-only headers to each tab * fix typos * remaining tweaks: - url-resources: fix sorter getting moved into notification - url-resources: fix border for mobile view - add screenreader labels to expand/hide buttons * Show hover effect on focus. * Wrap the whole sidebar is role=complementary, including the tab navigation. * Make buttons keyboard operable; fix typos. * Programmatically associate sidebar toggle button with sidebar. * Per discusson, try calling this "URLs" * Different heading levels for sidebar and main. * Announce changes to search results. * Correct dynamic page title, whe not in sidebar. * Remove hyperlink focus decoration; reveal obscured focus indicator. * Focus on replay, when replay changes. * Make buttons keyboard operable. * Move spacebar helper to misc instead of duplicating. * Bump compiled assets. * Use disabled attribute to match css; update label to describe new sidebar. * Adjust replay focus styles. * Adjust replay nav button focus, so visuals onclick in Chrome are less prominent. * Put wordmark with logo on non-embed desktop, so that logo and wordmark make a single link. Co-authored-by: Ilya Kreymer <ikreymer@gmail.com>
This commit is contained in:
co-authored by
Ilya Kreymer
parent
7d9ce2b952
commit
05adead57c
+41
-25
@@ -1,5 +1,5 @@
|
||||
import { LitElement, html, css } from 'lit-element';
|
||||
import { wrapCss } from './misc';
|
||||
import { wrapCss, clickOnSpacebarPress } from './misc';
|
||||
|
||||
import fasSearch from '@fortawesome/fontawesome-free/svgs/solid/search.svg';
|
||||
|
||||
@@ -47,6 +47,7 @@ class URLResources extends LitElement
|
||||
constructor() {
|
||||
super();
|
||||
this.collInfo = null;
|
||||
this.isSidebar = false;
|
||||
|
||||
this.currMime = "";
|
||||
this.query = "";
|
||||
@@ -69,6 +70,7 @@ class URLResources extends LitElement
|
||||
static get properties() {
|
||||
return {
|
||||
collInfo: { type: Object },
|
||||
isSidebar: { type: Boolean },
|
||||
currMime: { type: String },
|
||||
query: { type: String },
|
||||
urlSearchType: { type: String },
|
||||
@@ -95,7 +97,7 @@ class URLResources extends LitElement
|
||||
}
|
||||
|
||||
updated(changedProperties) {
|
||||
if (changedProperties.has("query") ||
|
||||
if (changedProperties.has("query") ||
|
||||
changedProperties.has("urlSearchType") ||
|
||||
changedProperties.has("currMime")) {
|
||||
|
||||
@@ -257,7 +259,13 @@ class URLResources extends LitElement
|
||||
}
|
||||
.columns {
|
||||
margin: 0px;
|
||||
}
|
||||
}
|
||||
thead {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
table th:not([align]) {
|
||||
text-align: left;
|
||||
}
|
||||
.result {
|
||||
border-bottom: 1px #dbdbdb solid;
|
||||
min-height: fit-content;
|
||||
@@ -266,6 +274,8 @@ class URLResources extends LitElement
|
||||
border-bottom: 2px #dbdbdb solid;
|
||||
margin-right: 16px;
|
||||
min-height: fit-content;
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
.results-head a {
|
||||
color: black;
|
||||
@@ -298,6 +308,9 @@ class URLResources extends LitElement
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<div role="heading" aria-level="${this.isSidebar ? "2": "1"}" class="is-sr-only">URLs in ${this.collInfo.title}</div>
|
||||
|
||||
<div role="heading" aria-level="${this.isSidebar ? "3": "2"}" class="is-sr-only">Search and Filter</div>
|
||||
<div class="notification level is-marginless">
|
||||
<div class="level-left flex-auto">
|
||||
<div class="level-item flex-auto">
|
||||
@@ -325,14 +338,13 @@ class URLResources extends LitElement
|
||||
<label class="radio has-text-left"><input type="radio" name="urltype" value="" ?checked="${this.urlSearchType === 'contains'}" @click="${this.onClickUrlType}"> Contains</label>
|
||||
<label class="radio has-text-left"><input type="radio" name="urltype" value="prefix" ?checked="${this.urlSearchType === 'prefix'}" @click="${this.onClickUrlType}"> Prefix</label>
|
||||
<label class="radio has-text-left"><input type="radio" name="urltype" value="exact" ?checked="${this.urlSearchType === 'exact'}" @click="${this.onClickUrlType}"> Exact</label>
|
||||
<span class="num-results" is-pulled-right">${this.filteredResults.length} Result(s)</span>
|
||||
<span id="num-results" class="num-results" is-pulled-right" aria-live="polite" aria-atomic="true">${this.filteredResults.length} Result(s)</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sort-header is-hidden-tablet">
|
||||
<wr-sorter id="urls"
|
||||
defaultKey="url"
|
||||
defaultKey="${this.sortKey ? this.sortKey : "url"}"
|
||||
?defaultDesc="${this.sortDesc !== null ? this.sortDesc : false}"
|
||||
.sortKeys="${URLResources.sortKeys}"
|
||||
@@ -340,28 +352,32 @@ class URLResources extends LitElement
|
||||
@sort-changed="${this.onSortChanged}">
|
||||
</wr-sorter>
|
||||
</div>
|
||||
|
||||
<div class="all-results">
|
||||
<div class="columns results-head has-text-weight-bold">
|
||||
<a @click="${this.onSort}" data-key="url" class="column col-url is-6 is-hidden-mobile ${this.sortKey === "url" ? (this.sortDesc ? "desc" : "asc") : ''}">URL</a>
|
||||
<a @click="${this.onSort}" data-key="ts" class="column col-ts is-2 is-hidden-mobile ${this.sortKey === "ts" ? (this.sortDesc ? "desc" : "asc") : ''}">Date</a>
|
||||
<a @click="${this.onSort}" data-key="mime" class="column col-mime is-3 is-hidden-mobile ${this.sortKey === "mime" ? (this.sortDesc ? "desc" : "asc") : ''}">Mime Type</a>
|
||||
<a @click="${this.onSort}" data-key="status" class="column col-status is-1 is-hidden-mobile ${this.sortKey === "status" ? (this.sortDesc ? "desc" : "asc") : ''}">Status</a>
|
||||
</div>
|
||||
|
||||
<div class="main-scroll" @scroll="${this.onScroll}">
|
||||
${this.sortedResults.length ?
|
||||
<div role="heading" aria-level="${this.isSidebar ? "3": "2"}" id="results-heading" class="is-sr-only">Results</div>
|
||||
|
||||
<table class="all-results" aria-labelledby="results-heading num-results">
|
||||
<thead>
|
||||
<tr class="columns results-head has-text-weight-bold">
|
||||
<th scope="col" class="column col-url is-6 is-hidden-mobile"><a role="button" href="#" @click="${this.onSort}" @keyup="${clickOnSpacebarPress}" data-key="url" class="${this.sortKey === "url" ? (this.sortDesc ? "desc" : "asc") : ''}">URL</a></th>
|
||||
<th scope="col" class="column col-ts is-2 is-hidden-mobile"><a role="button" href="#" @click="${this.onSort}" @keyup="${clickOnSpacebarPress}" data-key="ts" class="${this.sortKey === "ts" ? (this.sortDesc ? "desc" : "asc") : ''}">Date</a></th>
|
||||
<th scope="col" class="column col-mime is-3 is-hidden-mobile"><a role="button" href="#" @click="${this.onSort}" @keyup="${clickOnSpacebarPress}" data-key="mime" class="${this.sortKey === "mime" ? (this.sortDesc ? "desc" : "asc") : ''}">Mime Type</a></th>
|
||||
<th scope="col" class="column col-status is-1 is-hidden-mobile"><a role="button" href="#" @click="${this.onSort}" @keyup="${clickOnSpacebarPress}" data-key="status" class="${this.sortKey === "status" ? (this.sortDesc ? "desc" : "asc") : ''}">Status</a></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody class="main-scroll" @scroll="${this.onScroll}">
|
||||
${this.sortedResults.length ?
|
||||
this.sortedResults.map((result) => html`
|
||||
<div class="columns result">
|
||||
<div class="column col-url is-6"><p class="minihead is-hidden-tablet">URL</p><a @click="${this.onReplay}" data-url="${result.url}" data-ts="${result.ts}" href="#">${result.url}</a></div>
|
||||
<div class="column col-ts is-2"><p class="minihead is-hidden-tablet">Date</p>${new Date(result.date).toLocaleString()}</div>
|
||||
<div class="column col-mime is-3"><p class="minihead is-hidden-tablet">Mime Type</p>${result.mime}</div>
|
||||
<div class="column col-status is-1"><p class="minihead is-hidden-tablet">Status</p>${result.status}</div>
|
||||
</div>
|
||||
`) : html`<div class="section"><i>No Results Found.</i></div>`}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
<tr class="columns result">
|
||||
<td class="column col-url is-6"><p class="minihead is-hidden-tablet">URL</p><a @click="${this.onReplay}" data-url="${result.url}" data-ts="${result.ts}" href="#">${result.url}</a></td>
|
||||
<td class="column col-ts is-2"><p class="minihead is-hidden-tablet">Date</p>${new Date(result.date).toLocaleString()}</td>
|
||||
<td class="column col-mime is-3"><p class="minihead is-hidden-tablet">Mime Type</p>${result.mime}</td>
|
||||
<td class="column col-status is-1"><p class="minihead is-hidden-tablet">Status</p>${result.status}</td>
|
||||
</tr>
|
||||
`) : html`<tr class="section"><td colspan="4"><i>No Results Found.</i></td></tr>`}
|
||||
</tbody>
|
||||
</table>
|
||||
`;
|
||||
}
|
||||
|
||||
onSort(event) {
|
||||
|
||||
Reference in New Issue
Block a user