# Pagination Navigation

> Quick first, previous, next, last, and page buttons for pagination based navigation, supporting
regular links or router links.

```html
<template>
<div>
    <h6>Default</h6>
    <b-pagination-nav base-url="#" :number-of-pages="10" v-model="currentPage" />

    <h6 class="mt-4">With link generator function</h6>
    <b-pagination-nav :link-gen="linkGen" :number-of-pages="10" v-model="currentPage" />
    <br>

    <div class="mt-4">currentPage: {{currentPage}}</div>
</div>
</template>

<script>
export default {
    data: {
        currentPage: 1
    },
    methods: {
        linkGen(pageNum) {
            return '#page/' + pageNum + '/foobar';
        }
    }
}
</script>

<!-- pagination-1.vue -->
```

`<b-pagination-nav>` is a custom input component that provides navigational
pagination. The current page should be set via the `value` prop (or `v-model`),
and the total number of pages set with `number-of-pages`. Page numbers are indexed
from 1 through `number-of-pages`.

## Current page

You should **always** set the current page number by setting the prop `value` (or
using `v-model`) to ensure that correct active page number is highlighted.

## Link generation

By default, `<b-pagination-nav>` generates plain link tags, setting the HREF attribute
to `base-url` concatenated with the page number. The `base-url` prop defaults to '/'.

### Router links

To generate page links as [`<router link>`](https://router.vuejs.org/en/api/router-link.html)
components, set the `use-router` prop. The HREF will then become the `to` prop of
the router link.

### Link Generator function

If you need finer grained control over the generated link URLs or `<router-link>` `to` props,
you may set the `link-gen` prop to a function reference that accepts one argument which
is a page number. The `link-gen` function should return either a string (for HREF) or a
router `to` object. If the returned value is an object, then a router-link will always
be generated. If the return value is a string, a link is generated by default unless
the `use-router` prop is set.

```js
// For regular HREF (or string `to` prop if `use-router` is set)
linkGen(pageNum) {
    return '/foo/page/' + pageNum
}

// Returning a router-link `to` object
linkGen(pageNum) {
    return {
        path: '/foo/page/' + pageNum
    };
}
```

### Page number generation

By default, `<b-pagination-nav>` renders page numbers (1-N) in the page link
buttons. You can override this behaviour by supplying a function reference to
the `page-gen` property. The function reference should accept a single argument
which is a page number (1-N). The `page-gen` function should return a string.

Note HTML strings are currently not supported.

**Example: Using an array of links to generate pagination:**

```html
<template>
  <div>
    <b-pagination-nav :link-gen="linkGen"
                      :page-gen="pageGen"
                      :number-of-pages="links.length"
                      v-model="currentPage" />
    <br>
    <p>
      Page #: {{ currentPage }}<br>
      Page Link: {{ pageLink }}
    </p>
  </div>
</template>

<script>
export default {
  data: {
    currentPage: 1,
    links: ['#foo','#bar', '#baz', '#faz']
  },
  computed: {
    pageLink() {
      return this.linkGen(this.currentPage);
    }
  },
  methods: {
    linkGen(pageNum) {
      return this.links[pageNum - 1];
    },
    pageGen(pageNum) {
      return this.links[pageNum - 1].slice(1);
    }
  }
}
</script>

<!-- pagination-nav-links.vue -->
```
## Button Size
Optionally change from the default button size by setting the `size`
prop to eiter `'am` for smaller buttons or `'lg'` for larger buttons.

```html
<template>
<div>
    <h6>Small</h6>
    <b-pagination-nav size="sm" base-url="#" :number-of-pages="5" v-model="currentPage" />

    <h6>Default</h6>
    <b-pagination-nav base-url="#" :number-of-pages="5" v-model="currentPage" />

    <h6>Large</h6>
    <b-pagination-nav size="lg" base-url="#" :number-of-pages="5" v-model="currentPage" />
</div>
</template>

<script>
export default {
    data: {
        currentPage: 1
    }
}
</script>

<!-- pagination-size.vue -->
```

## Customizing

`<b-pagination-nav>` supports several props that allow you to customize the appearance.

| Prop | Description
| ---- | -----------
| `limit` | Limit the maximum number of displayed page buttons (including ellipsis if present, and excluding first/prev/next/last buttons)
| `number-of-pages` | The total number of pages
| `first-text` | The "goto first page" button text (html supported)
| `prev-text` | The "goto previous page" button text (html supported)
| `next-text` | The "goto next page" button text (html supported)
| `last-text` | The "goto last page" button text (html supported)
| `ellipsis-text` | the `...` indicator text (html supported)
| `hide-ellipsis` | never show ellipsis indicators
| `hide-goto-end-buttons` | never display goto first/last buttons

Ellipsis indicator(s) will only be ever shown at the front and/or end of
the page number buttons. For `limit` values less than or equal to `3`, the ellipsis
indicator(s) will never be shown for practical display reasons.

## Alignment

By default the pagination component is left aligned. Change the alignment to
`center` or `right` (`right` is an alias for `end`) by setting the prop
`align` to the appropriate value.

```html
<template>
<div>
    <h6>Left alignment (default)</h6>
    <b-pagination-nav :number-of-pages="10" base-url="#" v-model="currentPage" />
    <br>

    <h6>Center alignment</h6>
    <b-pagination-nav align="center" :number-of-pages="10" base-url="#" v-model="currentPage" />
    <br>

    <h6>Right (end) alignment</h6>
    <b-pagination-nav align="right" :number-of-pages="10" base-url="#" v-model="currentPage" />
    <br>

    <div>currentPage: {{currentPage}}</div>
</div>
</template>

<script>
export default {
    data: {
        currentPage: 1
    }
}
</script>

<!-- pagination-align.vue -->
```

## Small screen support

On smaller screens (i.e. mobile), some of the `<b-pagination>` buttons will be hidden to
minimize the potential of the pagination interface wrapping onto multiple lines:

- The ellipsis indicators will be hidden on screens `xs` and smaller.
- Page number buttons will be limited to a maximum of 3 visible on `xs` screens and smaller.

This ensures that no more than 3 page number buttons are visible,
along with the goto _first_, _prev_, _next_, and _last_ buttons.


## Accessibility

The `<b-pagination>` component provides many features to support assistive technology users,
such as `aria-` attributes and keyboard navigation.

### ARIA labels:

`<b-pagination>` provides various `*-label-*` props which are used to set the `aria-label`
attributes on the various elements within the component, which will help users of
assistive technology.

| Prop | `aria-label` content default
| ---- | -----------
| `label-first-page` | "Go to first page"
| `label-prev-page` | "Go to previous page"
| `label-next-page` | "Go to next page"
| `label-last-page` | "Go to last page"
| `label-page` | "Go to page", appended with the page number
| `aria-label` | "Pagination", applied to the outer pagination container

### Keyboard navigtion support:

`<b-pagination>` supports keyboard navigation out of the box.
- Tabbing into the pagination component will auto-focus the current page button
- <kbd>LEFT</kbd> and <kbd>RIGHT</kbd> arrow keys will focus the previous and next buttons in the page
list, respectively, and <kbd>ENTER</kbd> or <kbd>SPACE</kbd> keys will select (click) the focused page button

## See also

For pagination control of a component (such as `<b-table>`), use the
[`<b-pagination>`](./pagination) component instead.

## Component Reference
