diff --git a/packages/bootstrap-vue-next/src/components/BPagination/BPagination.vue b/packages/bootstrap-vue-next/src/components/BPagination/BPagination.vue
index 38f321373..bc65ab132 100644
--- a/packages/bootstrap-vue-next/src/components/BPagination/BPagination.vue
+++ b/packages/bootstrap-vue-next/src/components/BPagination/BPagination.vue
@@ -7,7 +7,13 @@
:aria-label="props.ariaLabel || undefined"
@keydown="handleKeyNav"
>
-
+
({
const pageClick = (event: Readonly, pageNumber: number) => {
if (pageNumber === computedModelValue.value) return
-
const clickEvent = new BvEvent('page-click', {
cancelable: true,
target: event.target,
@@ -315,6 +320,13 @@ const pageClick = (event: Readonly, pageNumber: number) => {
modelValue.value = pageNumber
+ nextTick(() => {
+ if (pageNumber === 1) {
+ focusFirst()
+ } else if (pageNumber === pagination.value.numberOfPages) {
+ focusLast()
+ }
+ })
// nextTick(() => {
// if (isVisible(target) && un_element.contains(target)) {
// attemptFocus(target)
@@ -332,18 +344,24 @@ const isDisabled = (el: HTMLButtonElement) => {
return !isElement || el.disabled || hasAttr || hasClass
}
-const getButtons = () =>
- pageElements.value
- ?.map((page) => page.children[0] as HTMLButtonElement)
- .filter((btn) => {
- if (btn.getAttribute('display') === 'none') {
+const getButtons = (): HTMLButtonElement[] =>
+ [...(pageElements.value ?? [])]
+ ?.sort(
+ (a, b) =>
+ parseInt(a.getAttribute('displayIndex') || '0') -
+ parseInt(b.getAttribute('displayIndex') || '0')
+ )
+ ?.map((page) => page.children[0])
+ ?.filter((el) => {
+ if (el.getAttribute('display') === 'none' || el.tagName.toUpperCase() !== 'BUTTON') {
return false
}
- const bcr = btn.getBoundingClientRect()
+ const bcr = el.getBoundingClientRect()
- return !!(bcr && bcr.height > 0 && bcr.width > 0)
- }) ?? []
+ return true || !!(bcr && bcr.height > 0 && bcr.width > 0)
+ })
+ ?.map((el) => el as HTMLButtonElement)
const focusFirst = () => {
nextTick(() => {
@@ -376,7 +394,6 @@ const focusNext = () => {
nextTick(() => {
const buttons = getButtons()
const index = buttons.indexOf(getActiveElement() as HTMLButtonElement)
-
if (index < buttons.length - 1 && !isDisabled(buttons[index + 1])) {
buttons[index + 1]?.focus()
}
@@ -385,7 +402,6 @@ const focusNext = () => {
const handleKeyNav = (event: KeyboardEvent) => {
const {code, shiftKey} = event
-
if (code === CODE_LEFT || code === CODE_UP) {
stopEvent(event)
if (shiftKey) {
diff --git a/packages/bootstrap-vue-next/src/components/BPagination/pagination.spec.ts b/packages/bootstrap-vue-next/src/components/BPagination/pagination.spec.ts
index 5a618711a..591f5a395 100644
--- a/packages/bootstrap-vue-next/src/components/BPagination/pagination.spec.ts
+++ b/packages/bootstrap-vue-next/src/components/BPagination/pagination.spec.ts
@@ -466,6 +466,25 @@ describe('pagination', () => {
expect(await TestScenariosAgainstInvariants(wrapper)).toBe(0)
})
+ it('can navigate to different pages using the left and right arrow keys', async () => {
+ const wrapper = mount(BPagination, {
+ props: {totalRows: 7, perPage: 1, modelValue: 1},
+ attachTo: document.body,
+ })
+ await wrapper.find('li.active > button').element?.focus()
+ expect(document.activeElement?.textContent).toBe('1')
+ await wrapper.find('ul').trigger('keydown', {code: 'ArrowRight'})
+ expect(document.activeElement?.textContent).toBe('2')
+ await wrapper.find('ul').trigger('keydown', {code: 'ArrowRight'})
+ expect(document.activeElement?.textContent).toBe('3')
+ await wrapper.find('ul').trigger('keydown', {code: 'ArrowRight'})
+ expect(document.activeElement?.textContent).toBe('4')
+ await wrapper.find('button[aria-posinset="4"]').trigger('click')
+ await wrapper.find('ul').trigger('keydown', {code: 'ArrowRight'})
+ expect(document.activeElement?.textContent).toBe('5')
+ await wrapper.find('ul').trigger('keydown', {code: 'ArrowLeft'})
+ expect(document.activeElement?.textContent).toBe('4')
+ })
})
// eslint-disable-next-line @typescript-eslint/no-explicit-any