fix: improve autosuggest a11y (#1630)
* fix: improve autosuggest a11y some progress on #1629 - works in Chrome on NVDA now - works in Chrome on VoiceOver now - shorter aria-labels, don't repeat information like "1 of 3", because it causes the screen reader to speak too frequently, e.g. when the selected result hasn't changed but the number of results has. Also both NVDA and VoiceOver already speak this information - stop doing a fancy fade animation, just show and hide the input instantly. I worry it confuses screen readers to have the aria-hidden attribute in there at all - stop using a single id to identify the active descendant - give immutable IDs and then update the aria-activedescendant instead. I think this is what fixed Chrome. * fix test
This commit is contained in:
parent
c5a005186c
commit
07facea505
|
@ -1,6 +1,4 @@
|
|||
<div class="compose-autosuggest {shown ? 'shown' : ''} {realm === 'dialog' ? 'is-dialog' : ''}"
|
||||
aria-hidden={!shown}
|
||||
>
|
||||
<div class="compose-autosuggest {shown ? '' : 'not-shown'} {realm === 'dialog' ? 'is-dialog' : ''}">
|
||||
<ComposeAutosuggestionList
|
||||
items={autosuggestSearchResults}
|
||||
on:click="onClick(event)"
|
||||
|
@ -15,17 +13,13 @@
|
|||
position: absolute;
|
||||
left: 5px;
|
||||
top: 0;
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
transition: opacity 0.1s linear;
|
||||
z-index: 7000;
|
||||
}
|
||||
.compose-autosuggest.is-dialog {
|
||||
z-index: 11000;
|
||||
}
|
||||
.compose-autosuggest.shown {
|
||||
pointer-events: auto;
|
||||
opacity: 1;
|
||||
.compose-autosuggest.not-shown {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (min-width: 480px) {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
role="listbox"
|
||||
>
|
||||
{#each items as item, i (item.shortcode || item.id || item.name)}
|
||||
<li id="{i === selected ? `compose-autosuggest-active-item-${realm}` : ''}"
|
||||
<li id="compose-autosuggest-active-item-{realm}-{i}"
|
||||
class="compose-autosuggest-list-item {i === selected ? 'selected' : ''}"
|
||||
role="option"
|
||||
aria-selected="{i === selected}"
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
class="compose-box-input compose-box-input-realm-{realm}"
|
||||
placeholder="What's on your mind?"
|
||||
aria-describedby="compose-box-input-description-{realm}"
|
||||
aria-owns="{autosuggestShownForThisInput ? `compose-autosuggest-list-${realm}` : undefined}"
|
||||
aria-owns="compose-autosuggest-list-{realm}"
|
||||
aria-expanded={autosuggestShownForThisInput}
|
||||
aria-autocomplete="both"
|
||||
aria-activedescendant="{autosuggestShownForThisInput ? `compose-autosuggest-active-item-${realm}` : undefined}"
|
||||
aria-activedescendant={activeDescendant}
|
||||
ref:textarea
|
||||
bind:value=rawText
|
||||
on:blur="onBlur()"
|
||||
|
@ -268,10 +268,17 @@
|
|||
composeFocused: ({ $autosuggestData_composeFocused, $currentInstance, realm }) => (
|
||||
get($autosuggestData_composeFocused, [$currentInstance, realm], false)
|
||||
),
|
||||
/* eslint-enable camelcase */
|
||||
autosuggestShownForThisInput: ({ realm, $autosuggestShown, composeFocused }) => (
|
||||
|
||||
autosuggestShownForThisInput: ({ $autosuggestShown, composeFocused }) => (
|
||||
!!($autosuggestShown && composeFocused)
|
||||
),
|
||||
autosuggestSelected: ({ $autosuggestData_autosuggestSelected, $currentInstance, realm }) => (
|
||||
get($autosuggestData_autosuggestSelected, [$currentInstance, realm], 0)
|
||||
),
|
||||
activeDescendant: ({ autosuggestSelected, autosuggestShownForThisInput, realm }) => (
|
||||
autosuggestShownForThisInput ? `compose-autosuggest-active-item-${realm}-${autosuggestSelected}` : undefined
|
||||
)
|
||||
/* eslint-enable camelcase */
|
||||
},
|
||||
events: {
|
||||
selectionChange
|
||||
|
|
|
@ -17,6 +17,5 @@ export function createAutosuggestAccessibleLabel (
|
|||
: displayName
|
||||
label = `${displayName} @${selected.acct}`
|
||||
}
|
||||
return `${label} (${selectedIndex + 1} of ${searchResults.length}). ` +
|
||||
'Press up and down arrows to review and enter to select.'
|
||||
return label
|
||||
}
|
||||
|
|
|
@ -110,7 +110,7 @@ test('autosuggest only shows for one input', async t => {
|
|||
.selectText(getNthComposeReplyInput(1))
|
||||
.pressKey('delete')
|
||||
.typeText(getNthComposeReplyInput(1), 'uu')
|
||||
.expect($('.compose-autosuggest.shown').exists).notOk()
|
||||
.expect($('.compose-autosuggest').visible).notOk()
|
||||
})
|
||||
|
||||
test('autosuggest only shows for one input part 2', async t => {
|
||||
|
@ -118,7 +118,7 @@ test('autosuggest only shows for one input part 2', async t => {
|
|||
await t
|
||||
.hover(composeInput)
|
||||
.typeText(composeInput, '@adm')
|
||||
.expect($('.compose-autosuggest.shown').exists).ok({ timeout })
|
||||
.expect($('.compose-autosuggest').visible).ok({ timeout })
|
||||
.expect(getNthAutosuggestionResult(1).innerText).contains('@admin')
|
||||
.hover(getNthStatus(1))
|
||||
.click(getNthReplyButton(1))
|
||||
|
@ -127,7 +127,7 @@ test('autosuggest only shows for one input part 2', async t => {
|
|||
.typeText(getNthComposeReplyInput(1), '@dd')
|
||||
await sleep(1000)
|
||||
await t.pressKey('backspace')
|
||||
.expect($('.compose-autosuggest.shown').exists).notOk()
|
||||
.expect($('.compose-autosuggest').visible).notOk()
|
||||
})
|
||||
|
||||
test('autocomplete disappears on blur', async t => {
|
||||
|
@ -135,7 +135,7 @@ test('autocomplete disappears on blur', async t => {
|
|||
await t
|
||||
.hover(composeInput)
|
||||
.typeText(composeInput, '@adm')
|
||||
.expect($('.compose-autosuggest.shown').exists).ok({ timeout })
|
||||
.expect($('.compose-autosuggest').visible).ok({ timeout })
|
||||
.click(composeLengthIndicator)
|
||||
.expect($('.compose-autosuggest.shown').exists).notOk()
|
||||
.expect($('.compose-autosuggest').visible).notOk()
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue