diff --git a/apps/theming/src/components/AppOrderSelector.vue b/apps/theming/src/components/AppOrderSelector.vue
index bd4e4e7760de6..392519de25ee6 100644
--- a/apps/theming/src/components/AppOrderSelector.vue
+++ b/apps/theming/src/components/AppOrderSelector.vue
@@ -2,6 +2,7 @@
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[]>([])
+
+ /**
+ * 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,
}
},
})
diff --git a/apps/theming/src/components/AppOrderSelectorElement.vue b/apps/theming/src/components/AppOrderSelectorElement.vue
index 73da7579d59c9..4c7266eb798b1 100644
--- a/apps/theming/src/components/AppOrderSelectorElement.vue
+++ b/apps/theming/src/components/AppOrderSelectorElement.vue
@@ -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,
}
},