-
Notifications
You must be signed in to change notification settings - Fork 26
fix(kselect): keyboard operation issues #2780
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -28,7 +28,7 @@ | |
| hide-close-icon | ||
| @close="() => onClose(toggle, isToggled.value)" | ||
| @open="() => onOpen(toggle)" | ||
| @popover-click="() => onPopoverClick(toggle)" | ||
| @popover-click="toggle" | ||
| > | ||
| <div | ||
| :id="selectWrapperId" | ||
|
|
@@ -58,9 +58,9 @@ | |
| @blur="onInputBlur" | ||
| @click="onInputClick" | ||
| @focus="onInputFocus" | ||
| @keydown="(evt: KeyboardEvent) => triggerFocus(evt, isToggled)" | ||
| @keydown.enter="onInputEnter" | ||
| @keypress="onInputKeypress" | ||
| @keyup="(evt: any) => triggerFocus(evt, isToggled)" | ||
| @keyup.enter.stop | ||
| @update:model-value="onQueryChange" | ||
| > | ||
|
|
@@ -448,20 +448,32 @@ const clearSelection = (): void => { | |
| } | ||
|
|
||
| const selectItemsRef = useTemplateRef('kSelectItems') | ||
| const NAVIGATION_KEYS = ['ArrowDown', 'ArrowUp'] | ||
| const OPEN_KEYS = [' ', 'Enter', ...NAVIGATION_KEYS] | ||
|
|
||
| const triggerFocus = (evt: any, isToggled: Ref<boolean>): void => { | ||
| const triggerFocus = (evt: KeyboardEvent, isToggled: Ref<boolean>): void => { | ||
| // Ignore `esc` key | ||
| if (evt.keyCode === 27) { | ||
| if (evt.key === 'Escape' && isToggled.value) { | ||
| isToggled.value = false | ||
| popperRef.value?.hidePopover?.() | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't setting
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually the
|
||
| return | ||
| } | ||
|
|
||
| const inputElem = selectWrapperRef.value?.children[0] as HTMLInputElement | ||
| if (!isToggled.value && inputElem) { // simulate click to trigger dropdown open | ||
| inputElem.click() | ||
| // per https://www.w3.org/WAI/ARIA/apg/patterns/combobox/examples/combobox-select-only/ | ||
| if (!isToggled.value && OPEN_KEYS.includes(evt.key)) { // simulate click to trigger dropdown open | ||
| if (NAVIGATION_KEYS.includes(evt.key)) { | ||
| evt.preventDefault() | ||
| } | ||
| // TODO: when it is opened by 'Home', 'End', 'ArrowUp', 'ArrowDown' keys, it should handle | ||
| // setting focus to different item | ||
|
Comment on lines
+467
to
+468
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure I understand this comment. |
||
| popperRef.value?.showPopover?.() | ||
| nextTick(() => selectItemsRef.value?.setFocus('current')) | ||
| } | ||
|
|
||
| if ((evt.key === 'ArrowDown' || evt.key === 'ArrowUp') && isToggled.value) { | ||
| // TODO: we need to remove this part since the popover should trap the focus | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How do you then escape the popover? |
||
| // when it got opened, the focus should not be set on the input element. | ||
| if (NAVIGATION_KEYS.includes(evt.key) && isToggled.value) { | ||
| evt.preventDefault() | ||
| selectItemsRef.value?.setFocus(evt.key === 'ArrowDown' ? 'down' : 'up') | ||
| } | ||
| } | ||
|
|
@@ -501,10 +513,6 @@ const onSelectWrapperClick = (event: Event): void => { | |
| } | ||
| } | ||
|
|
||
| const onPopoverClick = (toggle: () => void) => { | ||
| toggle() | ||
| } | ||
|
|
||
| const onClose = (toggle: () => void, isToggled: boolean) => { | ||
| isDropdownOpen.value = false | ||
|
|
||
|
|
@@ -518,6 +526,10 @@ const onClose = (toggle: () => void, isToggled: boolean) => { | |
| if (isToggled) { | ||
| toggle() | ||
| } | ||
|
|
||
| nextTick(() => { | ||
| inputRef.value?.focus?.() | ||
| }) | ||
| } | ||
|
|
||
| const onOpen = (toggle: () => void) => { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,7 @@ | ||
| <template> | ||
| <div ref="itemsContainer"> | ||
| <div | ||
| ref="itemsContainer" | ||
| > | ||
|
Comment on lines
+2
to
+4
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: this formatting change isn't necessary |
||
| <KSelectItem | ||
| v-for="item in nonGroupedItems" | ||
| :key="item.key" | ||
|
|
@@ -89,7 +91,7 @@ const getGroupItems = (group: string) => items?.filter(item => item.group === gr | |
|
|
||
| const itemsContainerRef = useTemplateRef('itemsContainer') | ||
|
|
||
| const moveItemFocus = (direction: 'down' | 'up'): void => { | ||
| const moveItemFocus = (direction: 'down' | 'up' | 'current'): void => { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| const container = itemsContainerRef.value | ||
| if (!container) { | ||
| return | ||
|
|
@@ -102,6 +104,11 @@ const moveItemFocus = (direction: 'down' | 'up'): void => { | |
|
|
||
| const selectedItem = container.querySelector<HTMLButtonElement>(SELECTED_ITEM_SELECTOR) | ||
|
|
||
| if (selectedItem && direction === 'current') { | ||
| selectedItem.focus() | ||
| return | ||
| } | ||
|
|
||
| if (selectedItem) { | ||
| const index = [...items].indexOf(selectedItem) | ||
| items[direction === 'down' ? index + 1 : index - 1]?.focus() | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: can we just expose the input ref rather than focus and blur methods?