fix(theming): App order selector should keep the focus on click

Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
pull/41197/head
Ferdinand Thiessen 2023-10-30 16:22:27 +07:00
parent 51eb44dbfe
commit 3e31022840
2 changed files with 24 additions and 5 deletions

@ -2,6 +2,7 @@
<ol ref="listElement" data-cy-app-order class="order-selector">
<AppOrderSelectorElement v-for="app,index in appList"
:key="`${app.id}${renderCount}`"
ref="selectorElements"
:app="app"
:is-first="index === 0 || !!appList[index - 1].default"
:is-last="index === value.length - 1"
@ -14,7 +15,7 @@
<script lang="ts">
import { useSortable } from '@vueuse/integrations/useSortable'
import { PropType, computed, defineComponent, ref } from 'vue'
import { PropType, computed, defineComponent, onUpdated, ref } from 'vue'
import AppOrderSelectorElement from './AppOrderSelectorElement.vue'
@ -81,6 +82,19 @@ export default defineComponent({
*/
useSortable(listElement, appList, { filter: '.order-selector-element--disabled' })
/**
* Array of all AppOrderSelectorElement components used to for keeping the focus after button click
*/
const selectorElements = ref<InstanceType<typeof AppOrderSelectorElement>[]>([])
/**
* We use the updated hook here to verify all selector elements keep the focus on the last pressed button
* This is needed to be done in this component to make sure Sortable.JS has finished sorting the elements before focussing an element
*/
onUpdated(() => {
selectorElements.value.forEach(element => element.keepFocus())
})
/**
* Handle element is moved up
* @param index The index of the element that is moved
@ -119,6 +133,7 @@ export default defineComponent({
moveUp,
renderCount,
selectorElements,
}
},
})

@ -52,7 +52,7 @@
import type { PropType } from 'vue'
import { translate as t } from '@nextcloud/l10n'
import { defineComponent, nextTick, onUpdated, ref } from 'vue'
import { defineComponent, nextTick, ref } from 'vue'
import IconArrowDown from 'vue-material-design-icons/ArrowDown.vue'
import IconArrowUp from 'vue-material-design-icons/ArrowUp.vue'
@ -116,10 +116,12 @@ export default defineComponent({
}
/**
* onUpdated hook is used to reset the focus on the last used button (if requested)
* Reset the focus on the last used button.
* If the button is now visible anymore (because this element is the first/last) then the opposite button is focussed
*
* This function is exposed to the "AppOrderSelector" component which triggers this when the list was successfully rerendered
*/
onUpdated(() => {
const keepFocus = () => {
if (needsFocus !== 0) {
// focus requested
if ((needsFocus === 1 || props.isLast) && !props.isFirst) {
@ -130,7 +132,7 @@ export default defineComponent({
}
}
needsFocus = 0
})
}
return {
buttonUp,
@ -139,6 +141,8 @@ export default defineComponent({
moveUp,
moveDown,
keepFocus,
t,
}
},