pinafore/src/routes/_components/compose/ComposeAutosuggestionList.html
Nolan Lawson 8d0db2c97c
fix: make autosuggestion accessible (#1183)
* fix: make autosuggestion accessible

fixes #129

* remove tabindexes, fix aria-hidden
2019-05-05 22:08:54 -07:00

132 lines
3.8 KiB
HTML

<!-- accessible autocomplete, based on https://haltersweb.github.io/Accessibility/autocomplete.html -->
<ul id="compose-autosuggest-list-{realm}"
class="compose-autosuggest-list"
role="listbox"
>
{#each items as item, i (item.shortcode ? `emoji-${item.shortcode}` : `account-${item.id}`)}
<li id="{i === selected ? `compose-autosuggest-active-item-${realm}` : ''}"
class="compose-autosuggest-list-item {i === selected ? 'selected' : ''}"
role="option"
aria-selected="{i === selected}"
aria-label="{ariaLabels[i]}"
on:click="onClick(event, item)"
>
<div class="compose-autosuggest-list-grid" aria-hidden="true">
{#if type === 'account'}
<div class="compose-autosuggest-list-item-avatar">
<Avatar
size="small"
account={item}
/>
</div>
<span class="compose-autosuggest-list-display-name">
<AccountDisplayName account={item} />
</span>
<span class="compose-autosuggest-list-username">
{'@' + item.acct}
</span>
{:else}
<img src={$autoplayGifs ? item.url : item.static_url}
class="compose-autosuggest-list-item-icon"
alt="{':' + item.shortcode + ':'}"
/>
<span class="compose-autosuggest-list-display-name">
{':' + item.shortcode + ':'}
</span>
{/if}
</div>
</li>
{/each}
</ul>
<style>
.compose-autosuggest-list {
list-style: none;
width: 100%;
border-radius: 2px;
box-sizing: border-box;
border: 1px solid var(--compose-autosuggest-outline);
}
.compose-autosuggest-list-item {
border-bottom: 1px solid var(--compose-autosuggest-outline);
display: flex;
padding: 10px;
background: var(--settings-list-item-bg);
margin: 0;
flex: 1;
cursor: pointer;
}
.compose-autosuggest-list-item:last-child {
border-bottom: none;
}
.compose-autosuggest-list-grid {
display: grid;
width: 100%;
grid-template-areas: "icon display-name"
"icon username";
grid-template-columns: min-content 1fr;
grid-column-gap: 10px;
grid-row-gap: 5px;
}
:global(.compose-autosuggest-list-item-avatar) {
grid-area: icon;
}
.compose-autosuggest-list-item-icon {
grid-area: icon;
width: 48px;
height: 48px;
object-fit: contain;
}
.compose-autosuggest-list-display-name {
grid-area: display-name;
font-size: 1.1em;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
min-width: 0;
text-align: left;
}
.compose-autosuggest-list-username {
grid-area: username;
font-size: 1em;
color: var(--deemphasized-text-color);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
text-align: left;
}
.compose-autosuggest-list-item:hover, .compose-autosuggest-list-item.selected {
background: var(--compose-autosuggest-item-hover);
}
.compose-autosuggest-list-item:active {
background: var(--compose-autosuggest-item-active);
}
</style>
<script>
import Avatar from '../Avatar.html'
import { store } from '../../_store/store'
import AccountDisplayName from '../profile/AccountDisplayName.html'
import { createAutosuggestAccessibleLabel } from '../../_utils/createAutosuggestAccessibleLabel'
export default {
store: () => store,
computed: {
ariaLabels: ({ items, type, $omitEmojiInDisplayNames }) => {
return items.map((item, i) => {
return createAutosuggestAccessibleLabel(type, $omitEmojiInDisplayNames, i, items)
})
}
},
methods: {
onClick (event, item) {
event.preventDefault()
event.stopPropagation()
this.fire('click', item)
}
},
components: {
Avatar,
AccountDisplayName
}
}
</script>