# Pagination Navigation

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

`<b-pagination-nav>` is used for navigating to new page URLs. For controlling in page component
pagination (such as table or list pagination), use the
[`<b-pagination>`](/docs/components/pagination) component instead.

```html
<template>
  <div style="overflow-x:auto;">
    <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 />

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

<script>
  export default {
    data() {
      return {
        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 content in generated page number strings is **not** supported.

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

```html
<template>
  <div style="overflow-x:auto;">
    <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 {
    computed: {
      pageLink() {
        return this.linkGen(this.currentPage)
      }
    },
    data() {
      return {
        currentPage: 1,
        links: ['#foo', '#bar', '#baz', '#faz']
      }
    },
    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 style="overflow-x:auto;">
    <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() {
      return {
        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                                                                                                      |
| `hide-ellipsis`         | never show ellipsis indicators                                                                                                 |
| `hide-goto-end-buttons` | never display goto first/last buttons                                                                                          |

And provides several props for setting the content of the bookend buttons:

| Prop            | Description                                                 |
| --------------- | ----------------------------------------------------------- |
| `first-text`    | The "goto first page" button text (plain html supported)    |
| `prev-text`     | The "goto previous page" button text (plain html supported) |
| `next-text`     | The "goto next page" button text (plain html supported)     |
| `last-text`     | The "goto last page" button text (plain html supported)     |
| `ellipsis-text` | the `...` indicator text (plain html supported)             |

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.

**Note:** HTML is supported via the bookend content props. If allowing user supplied content to
populate these props, you should use named slots (see below) instead to avoid possible XSS attacks.

### Named slots

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

| Slot            | Description                                                          |
| --------------- | -------------------------------------------------------------------- |
| `first-text`    | The "goto first page" button text (html/sub-components supported)    |
| `prev-text`     | The "goto previous page" button text (html/sub-components supported) |
| `next-text`     | The "goto next page" button text (html/sub-components supported)     |
| `last-text`     | The "goto last page" button text (html/sub-components supported)     |
| `ellipsis-text` | the `...` indicator text (html/sub-components supported)             |

## 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() {
      return {
        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>`](/docs/components/pagination) component instead.

<!-- Component reference added automatically from component package.json -->
