Skip to content

Commit

Permalink
a11y(select): better navigation
Browse files Browse the repository at this point in the history
Ability to navigate with up and down arrows
  • Loading branch information
ayZagen committed May 8, 2024
1 parent a22efb9 commit fbfa7a0
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 7 deletions.
1 change: 1 addition & 0 deletions dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ const auth = new PlusAuthWidget('#pa__app', {
username: {
type: 'text',
label: 'Username',
placeholder: 'Enter your username',
attrs: {
autocomplete: 'email'
},
Expand Down
7 changes: 6 additions & 1 deletion src/ui/components/PSelect/PSelect.css
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
.widget {
.input {
&-select {
@apply relative outline-none;
@apply relative outline-none
focus:ring-2 ring-primary/30 focus:outline-none;

&-arrow {
position: absolute;
Expand All @@ -27,6 +28,10 @@
bg-white;
text-decoration: none;

&:focus:not(&--selected){
@apply bg-gray-300/60;
box-shadow: inset 0px 0px 2px 0px theme('colors.gray.300/80');
}
&--selected {
@apply bg-primary/50;
}
Expand Down
59 changes: 53 additions & 6 deletions src/ui/components/PSelect/PSelect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
tabindex="0"
@keydown="onKeyDown"
@click="onClick"
@blur="onBlur"
>
<div
ref="containerRef"
class="pa__input--wrap"
tabindex="0"
>
<label
v-if="label"
Expand Down Expand Up @@ -40,9 +40,12 @@
<div
v-for="(item, ind) in items"
:key="ind"
:tabindex="-1"
class="pa__input-select-item"
:class="{'pa__input-select-item--selected': getItemValue(item) === internalValue }"
@blur="onBlur"
@click="onItemClick($event, item)"
@keydown.enter="onItemClick($event, item)"
>
{{ getItemText(item) }}
</div>
Expand All @@ -58,6 +61,7 @@ import preventOverflow from '@popperjs/core/lib/modifiers/preventOverflow';
import { createPopper } from '@popperjs/core/lib/popper-lite';
import type { Instance } from '@popperjs/core/lib/popper-lite';
import type { PropType } from 'vue';
import { nextTick } from 'vue';
import { inject, watch, computed, reactive, defineComponent, onMounted, ref } from 'vue';
import { makeFocusProps, useFocus } from '../../composables/focus';
Expand Down Expand Up @@ -123,6 +127,20 @@ export default defineComponent({
emit('update:modelValue', props.returnObject ? selectedItem.value : internalValue.value)
}, { immediate: true })
watch(() => state.open, (isOpen) => {
popperInstance.value.update()
if(isOpen){
nextTick(() => {
activate(popoverRef.value.querySelector('.pa__input-select-item--selected'))
})
} else {
popoverRef.value.querySelectorAll('.pa__input-select-item[tabindex="0"]').forEach(item => {
item.tabIndex = -1
})
}
})
const { blur, focus, focusClasses, isFocused } = useFocus(props, 'pa__input')
function onFocus() {
Expand All @@ -134,19 +152,16 @@ export default defineComponent({
const onClick = (e: Event) => {
state.open = !state.open
popperInstance.value.update()
emit('click', e)
}
const onBlur = (e: FocusEvent) => {
e.preventDefault()
e.stopPropagation()
if(!(e.target as Element).contains(e.relatedTarget as Element)){
// @ts-ignore
if(!inputRef.value?.contains(e.relatedTarget as Element)){
state.open = false
if (isFocused.value) blur()
}
}
const onItemClick = (event: MouseEvent, item) => {
Expand All @@ -156,8 +171,40 @@ export default defineComponent({
state.open = false
return
}
function activate(item) {
if(!item){
return
}
// Set all of the buttons to tabindex -1
popoverRef.value.querySelectorAll('.pa__input-select-item')
.forEach((btn) => btn.tabIndex = -1);
// Make the current button "active"
item.tabIndex = 0;
nextTick(()=> {
item.focus();
})
}
const onKeyDown = (e: KeyboardEvent) => {
if (e.code === '13') emit('change', internalValue.value)
if (e.key === 'Enter') {
state.open = true
}else if (e.code === '13') {
emit('change', internalValue.value)
} else if (e.key === 'ArrowDown'){
if(!state.open) {
state.open = true
}else {
activate(popoverRef.value.querySelector('.pa__input-select-item[tabindex="0"]')?.nextElementSibling)
}
} else if (e.key === 'ArrowUp'){
if(!state.open) {
state.open = true
}else {
activate(popoverRef.value.querySelector('.pa__input-select-item[tabindex="0"]')?.previousElementSibling)
}
}
emit('keydown', e)
}
Expand Down

0 comments on commit fbfa7a0

Please sign in to comment.