Enables quick access to the first or last page. Allows the option to show edges constantly or not. NPagination is used to divide content into pages by displaying a subset of data at a time. Please refer to the Radix-ui pagination for more API information.
Prop Type Default Description totalnumber0The total number of items in your list. pagenumber-The value that controls the current page and can be bound with v-model. itemsPerPagenumber10The number of items displayed per page. showEdgesbooleanfalseWhen set to true, the first page, last page, and ellipsis will always be displayed. disabledbooleanfalseDisables pagination functionality.
< script setup lang = "ts" >
const currentPage = ref ( 1 )
</ script >
< template >
< div class = "flex" >
< NPagination
v-model : page = " currentPage "
: total = " 100 "
show-edges
/>
</ div >
</ template >
Copy to clipboard Prop Type Default Description showFirstbooleantrueDisplays the first page button. showLastbooleantrueDisplays the last page button. showPrevbooleantrueDisplays the previous page button. showNextbooleantrueDisplays the next page button. showListItembooleantrueDisplays the list items.
< script setup lang = "ts" >
const currentPage = ref ( 1 )
</ script >
< template >
< div class = "flex flex-col space-y-4" >
< span >Current Page: {{ currentPage }}</ span >
< NPagination
v-model : page = " currentPage "
: total = " 100 "
: show-list-item = " false "
/>
</ div >
</ template >
Copy to clipboard Prop Default Description sizesmAdjusts the size of the entire pagination. _pagination-first.sizesmCustomizes the size of the first page button. _pagination-last.sizesmCustomizes the size of the last page button. _pagination-prev.sizesmCustomizes the size of the previous page button. _pagination-next.sizesmCustomizes the size of the next page button. _pagination-list-item.sizesmCustomizes the size of the page list items. _pagination-ellipsis.sizesmCustomizes the size of the ellipsis indicator.
๐ You can freely adjust the size of the pagination using any size imaginable. No limits exist, and you aan use breakpoints such as sm:sm, xs:lg to change size based on screen size or states such as hover:lg, focus:3xl to change size based on input state and more.
The
height and
width of the pagination scale depends on the
size. If you want to change the
height and
width simultaneously, you can always customize it using utility classes or you can use the
square prop.
< script lang = "ts" setup >
const currentPage = ref ( 1 )
</ script >
< template >
< div class = "flex flex-col space-y-4" >
< NPagination
v-model : page = " currentPage "
: total = " 100 "
size = "xs"
/>
< NPagination
v-model : page = " currentPage "
: total = " 100 "
size = "sm"
/>
< NPagination
v-model : page = " currentPage "
: total = " 100 "
size = "md"
/>
< NPagination
v-model : page = " currentPage "
: total = " 100 "
size = "lg"
/>
</ div >
</ template >
Copy to clipboard Prop Type Default Description siblingCountnumber2The number of surrounding pages displayed around the current page.
< script lang = "ts" setup >
const currentPage = ref ( 1 )
</ script >
< template >
< div class = "flex flex-col space-y-4" >
< NPagination
v-model : page = " currentPage "
: total = " 300 "
: sibling-count = " 3 "
/>
< NPagination
v-model : page = " currentPage "
: total = " 300 "
: sibling-count = " 1 "
/>
</ div >
</ template >
Copy to clipboard Prop Type Default Description pagination-selected{variant}-{color}solid-primaryThe color of the selected page. pagination-unselected{variant}-{color}solid-whiteThe color of the unselected page. pagination-ellipsis{variant}-{color}text-blackThe color of the ellipsis.
Some
NPagination subcomponents are wrapped around the
NButton component. This means that all the props and slots of
NButton are available. Please refer to the
Props section for more information.
< script lang = "ts" setup >
const currentPage = ref ( 1 )
</ script >
< template >
< div class = "flex flex-col" >
< NPagination
v-model : page = " currentPage "
: total = " 100 "
pagination-selected = "solid-black"
pagination-unselected = "ghost-gray"
show-edges
/>
< NSeparator />
< NPagination
v-model : page = " currentPage "
: total = " 100 "
pagination-selected = "soft-primary"
pagination-unselected = "link-primary"
pagination-ellipsis = "text-primary"
show-edges
/>
< NSeparator />
< NPagination
v-model : page = " currentPage "
: total = " 100 "
pagination-selected = "solid-pink"
pagination-unselected = "outline-pink"
pagination-ellipsis = "text-pink"
show-edges
/>
< NSeparator />
< NPagination
v-model : page = " currentPage "
: total = " 100 "
pagination-selected = "solid-indigo"
pagination-unselected = "soft-indigo"
pagination-ellipsis = "text-indigo"
show-edges
/>
</ div >
</ template >
Copy to clipboard rounded="{size}" - changes the border-radius of the pagination.
๐ You can freely adjust the size of the rounded corners using any size imaginable. There are no limits, and you can use breakpoints such as sm:sm, xs:lg to change size based on screen size or states such as hover:lg, focus:3xl to change size based on input state, and more.
You can use any size provided by the
Tailwind CSS border-radius scale; the default is
md. You can also add your own sizes to the scale through the
Configuration section .
< script lang = "ts" setup >
const currentPage = ref ( 1 )
</ script >
< template >
< div class = "flex flex-col" >
< NPagination
v-model : page = " currentPage "
: total = " 100 "
pagination-selected = "solid-white"
pagination-unselected = "ghost-gray"
rounded = "b-2xl"
/>
< NSeparator />
< NPagination
v-model : page = " currentPage "
: total = " 100 "
pagination-selected = "solid-orange"
pagination-unselected = "outline-white"
/>
< NSeparator />
< NPagination
v-model : page = " currentPage "
: total = " 100 "
pagination-selected = "solid-yellow"
pagination-unselected = "outline-white"
rounded = "t-full"
/>
</ div >
</ template >
Copy to clipboard Prop Description _pagination-list-itemCustomizes the pagination list item component. _pagination-prevCustomizes the previous page navigation button. _pagination-nextCustomizes the next page navigation button. _pagination-firstCustomizes the first page navigation button. _pagination-lastCustomizes the last page navigation button. _pagination-ellipsisCustomizes the ellipsis indicator in the pagination. _pagination-listCustomizes the pagination list component.
For the sub-components' props, please refer to the
Props section. Refer to the
Radix-ui pagination for more information.
< template >
< div class = "flex items-start" >
< NPagination
: total = " 100 "
: show-first = " false "
: show-last = " false "
show-edges
rounded = "none"
: _pagination-list = " {
class: 'gap-0 divide-x divide-base border-1 border-base' ,
rounded: 'r-full l-full' ,
} "
: _pagination-prev = " {
icon: false ,
square: false ,
paginationUnselected: 'ghost-white' ,
label: 'Previous' ,
leading: 'i-lucide-arrow-left' ,
} "
: _pagination-list-item = " {
paginationUnselected: 'ghost-white' ,
paginationSelected: 'solid-black' ,
} "
: _pagination-next = " {
icon: false ,
square: false ,
paginationUnselected: 'ghost-white' ,
label: 'Next' ,
trailing: 'i-lucide-arrow-right' ,
} "
/>
</ div >
</ template >
Copy to clipboard Slot Description Props firstCustomizes the first page navigation button. - lastCustomizes the last page navigation button. - prevCustomizes the previous page navigation button. - nextCustomizes the next page navigation button. - list-itemCustomizes the pagination list item component. item pageellipsisCustomizes the ellipsis indicator in the pagination. -
< template >
< div class = "flex items-start" >
< NPagination
: total = " 100 "
: show-first = " false "
: show-last = " false "
show-edges
>
< template # prev >
< NButton
btn = "ghost-gray"
label = "Previous"
leading = "i-lucide-chevron-left"
/>
</ template >
< template # list-item = " { item, page } " >
< NPaginationListItem
: square = " false "
pagination-unselected = "ghost-gray"
pagination-selected = "solid-white"
: value = " item.value "
class = "gap-0"
leading = "i-lucide-hash"
: label = "`${ item . value }`"
: page
: una = " {
btnLeading: 'text-10px' ,
} "
/>
</ template >
< template # ellipsis >
< NIcon
name = "i-lucide-chevrons-left-right-ellipsis"
size = "xs"
/>
</ template >
< template # next >
< NButton
btn = "ghost-gray"
label = "Next"
trailing = "i-lucide-chevron-right"
/>
</ template >
</ NPagination >
</ div >
</ template >
Copy to clipboard import type { PaginationEllipsisProps, PaginationFirstProps, PaginationLastProps, PaginationListItemProps, PaginationListProps, PaginationNextProps, PaginationPrevProps, PaginationRootProps } from 'radix-vue'
import type { HTMLAttributes } from 'vue'
import type { NButtonProps } from './button'
interface BaseExtensionProps {
square ?: HTMLAttributes [ 'class' ]
class ?: HTMLAttributes [ 'class' ]
rounded ?: HTMLAttributes [ 'class' ]
size ?: HTMLAttributes [ 'class' ]
}
type isVisible = boolean
export interface NPaginationProps extends
PaginationRootProps ,
BaseExtensionProps ,
Pick < NButtonProps , 'paginationSelected' | 'paginationUnselected' >,
Pick < NPaginationEllipsisProps , 'paginationEllipsis' > {
showFirst ?: isVisible
showPrev ?: isVisible
showNext ?: isVisible
showLast ?: isVisible
showListItem ?: isVisible
// sub-components
_paginationList ?: Partial < NPaginationListProps >
_paginationListItem ?: Partial < NPaginationListItemProps >
_paginationEllipsis ?: Partial < NPaginationEllipsisProps >
_paginationFirst ?: Partial < NPaginationFirstProps >
_paginationPrev ?: Partial < NPaginationPrevProps >
_paginationNext ?: Partial < NPaginationNextProps >
_paginationLast ?: Partial < NPaginationLastProps >
una ?: NPaginationUnaProps
}
export interface NPaginationListProps extends PaginationListProps , BaseExtensionProps {
una ?: Pick < NPaginationUnaProps , 'paginationList' >
}
export interface NPaginationListItemProps extends PaginationListItemProps , NButtonProps {
isSelected ?: boolean
page ?: PaginationRootProps [ 'page' ]
}
export interface NPaginationEllipsisProps extends PaginationEllipsisProps , BaseExtensionProps {
paginationEllipsis ?: HTMLAttributes [ 'class' ]
una ?: Pick < NPaginationUnaProps , 'paginationEllipsis' | 'paginationEllipsisIconBase' | 'paginationEllipsisIcon' >
}
export interface NPaginationFirstProps extends PaginationFirstProps , NButtonProps {
}
export interface NPaginationPrevProps extends PaginationPrevProps , NButtonProps {
}
export interface NPaginationNextProps extends PaginationNextProps , NButtonProps {
}
export interface NPaginationLastProps extends PaginationLastProps , NButtonProps {
}
interface NPaginationUnaProps {
paginationRoot ?: HTMLAttributes [ 'class' ]
paginationList ?: HTMLAttributes [ 'class' ]
paginationListItem ?: HTMLAttributes [ 'class' ]
paginationEllipsis ?: HTMLAttributes [ 'class' ]
paginationEllipsisIconBase ?: HTMLAttributes [ 'class' ]
paginationEllipsisIcon ?: HTMLAttributes [ 'class' ]
}
Copy to clipboard type PaginationPrefix = 'pagination'
export const staticPagination : Record < `${ PaginationPrefix }-${ string }` | PaginationPrefix , string > = {
// configurations
'pagination' : 'overflow-hidden' ,
'pagination-list' : 'flex items-center gap-1 overflow-hidden' ,
// components
'pagination-root' : '' ,
'pagination-list-item' : 'pagination' ,
'pagination-ellipsis-base' : 'btn flex items-center justify-center' ,
'pagination-ellipsis-icon-base' : 'w-1em h-1em' ,
'pagination-ellipsis-icon' : 'i-lucide-ellipsis' ,
'pagination-first' : 'pagination' ,
'pagination-first-icon' : 'i-lucide-chevrons-left' ,
'pagination-prev' : 'pagination' ,
'pagination-prev-icon' : 'i-lucide-chevron-left' ,
'pagination-next' : 'pagination' ,
'pagination-next-icon' : 'i-lucide-chevron-right' ,
'pagination-last' : 'pagination' ,
'pagination-last-icon' : 'i-lucide-chevrons-right' ,
}
export const dynamicPagination = [
[
/ ^ pagination-ellipsis(?:-( [ ^ -] + )) ? (?:-( [ ^ -] + )) ?$ / ,
([, variant = 'text' , color = 'black' ]) =>
`btn-${ variant }-${ color }` ,
],
[
/ ^ pagination-selected(?:-( [ ^ -] + )) ? (?:-( [ ^ -] + )) ?$ / ,
([, variant = 'solid' , color = 'primary' ]) =>
`data-[selected=true]:btn-${ variant }-${ color }` ,
],
[
/ ^ pagination-unselected(?:-( [ ^ -] + )) ? (?:-( [ ^ -] + )) ?$ / ,
([, variant = 'solid' , color = 'white' ]) =>
`data-[selected=false]:btn-${ variant }-${ color }` ,
],
]
export const pagination = [
... dynamicPagination,
staticPagination,
]
Copy to clipboard < script setup lang = "ts" >
import type { NPaginationProps } from '../../../types'
import { reactivePick } from '@vueuse/core'
import { PaginationList, PaginationRoot, type PaginationRootEmits, useForwardPropsEmits } from 'radix-vue'
import { cn } from '../../../utils'
import PaginationEllipsis from './PaginationEllipsis.vue'
import PaginationFirst from './PaginationFirst.vue'
import PaginationLast from './PaginationLast.vue'
import PaginationListItem from './PaginationListItem.vue'
import PaginationNext from './PaginationNext.vue'
import PaginationPrev from './PaginationPrev.vue'
const props = withDefaults ( defineProps < NPaginationProps >(), {
showFirst: true ,
showLast: true ,
showListItem: true ,
showNext: true ,
showPrev: true ,
})
const emits = defineEmits < PaginationRootEmits >()
const rootProps = useForwardPropsEmits ( reactivePick (props, 'as' , 'defaultPage' , 'disabled' , 'itemsPerPage' , 'page' , 'showEdges' , 'siblingCount' , 'total' ), emits)
</ script >
< template >
< PaginationRoot
v-slot = " { page } "
v-bind = " rootProps "
: class = " cn (
'pagination-root' ,
props.class,
props.una?.paginationRoot,
) "
>
< PaginationList
v-slot = " { items } "
: class = " cn (
'pagination-list' ,
props?._paginationList?.class,
props.una?.paginationList,
) "
v-bind = " _paginationList "
>
< slot >
< PaginationFirst
v-if = " showFirst "
: rounded
: size
: pagination-selected
: pagination-unselected
v-bind = " _paginationFirst "
>
< slot
name = "first"
/ >
</ PaginationFirst >
< PaginationPrev
v-if = " showPrev "
: rounded
: pagination-selected
: pagination-unselected
: size
v-bind = " _paginationPrev "
>
< slot
name = "prev"
/ >
</ PaginationPrev >
< template v-if = " showListItem " >
< template v-for = " (item, index) in items " >
< slot
v-if = " item.type === 'page'"
name = "list-item"
: item = " item "
: page = " page "
>
< PaginationListItem
: key = " index "
: value = " item.value "
: page
: rounded
: size
: pagination-selected
: pagination-unselected
v-bind = " _paginationListItem "
/>
</ slot >
< PaginationEllipsis
v-else
: key = " item.type "
: index = " index "
: rounded
: size
: pagination-ellipsis
: una
v-bind = " _paginationEllipsis "
>
< slot
name = "ellipsis"
/ >
</ PaginationEllipsis >
</ template >
</ template >
< PaginationNext
v-if = " showNext "
: rounded
: size
: pagination-selected
: pagination-unselected
v-bind = " _paginationNext "
>
< slot
name = "next"
/ >
</ PaginationNext >
< PaginationLast
v-if = " showLast "
: rounded
: size
: pagination-selected
: pagination-unselected
v-bind = " _paginationLast "
>
< slot
name = "last"
/ >
</ PaginationLast >
</ slot >
</ PaginationList >
</ PaginationRoot >
</ template >
Copy to clipboard < script setup lang = "ts" >
import type { NPaginationEllipsisProps } from '../../../types'
import { PaginationEllipsis, useForwardProps } from 'radix-vue'
import { computed } from 'vue'
import { cn } from '../../../utils'
import Icon from '../../elements/Icon.vue'
const props = withDefaults ( defineProps < NPaginationEllipsisProps >(), {
paginationEllipsis: '~' ,
})
const delegatedProps = computed (() => {
const { class : _ , ... delegated } = props
return delegated
})
const forwardedProps = useForwardProps (delegatedProps)
</ script >
< template >
< PaginationEllipsis
v-bind = " forwardedProps "
: pagination-ellipsis
: class = " cn (
'pagination-ellipsis-base' ,
props.una?.paginationEllipsis,
props.class,
) "
>
< slot >
< Icon
: class = " cn (
'pagination-ellipsis-icon-base' ,
props.una?.paginationEllipsisIconBase,
) "
: name = " forwardedProps?.una?.paginationEllipsisIcon || 'pagination-ellipsis-icon'"
/>
</ slot >
</ PaginationEllipsis >
</ template >
Copy to clipboard < script setup lang = "ts" >
import type { NPaginationListItemProps } from '../../../types'
import { PaginationListItem, useForwardProps } from 'radix-vue'
import { computed } from 'vue'
import { cn } from '../../../utils'
import Button from '../../elements/Button.vue'
const props = withDefaults ( defineProps < NPaginationListItemProps >(), {
paginationSelected: '~' ,
paginationUnselected: '~' ,
square: true ,
})
const delegatedProps = computed (() => {
const { value : __ , class : _ , ... delegated } = props
return delegated
})
const label = computed (() => {
return props.label || props.value. toString ()
})
const forwardedProps = useForwardProps (delegatedProps)
</ script >
< template >
< PaginationListItem
: value
as-child
: data-selected = " value === page "
>
< Button
v-bind = " forwardedProps "
: label
: class = " cn (
'pagination-list-item' ,
props.class,
) "
>
< template v-for = " (_, name) in $slots " #[name]= " slotData " >
< slot : name = " name " v-bind = " slotData " / >
</ template >
</ Button >
</ PaginationListItem >
</ template >
Copy to clipboard < script setup lang = "ts" >
import type { NPaginationFirstProps } from '../../../types'
import { PaginationFirst, useForwardProps } from 'radix-vue'
import { computed } from 'vue'
import { cn } from '../../../utils'
import Button from '../../elements/Button.vue'
const props = withDefaults ( defineProps < NPaginationFirstProps >(), {
square: true ,
paginationUnselected: '~' ,
icon: true ,
label: 'pagination-first-icon' ,
})
const delegatedProps = computed (() => {
const { class : _ , ... delegated } = props
return delegated
})
const forwardedProps = useForwardProps (delegatedProps)
</ script >
< template >
< PaginationFirst
as-child
>
< slot >
< Button
: data-selected = " false "
v-bind = " forwardedProps "
: class = " cn (
'pagination-first' ,
props.class,
) "
/ >
</ slot >
</ PaginationFirst >
</ template >
Copy to clipboard < script setup lang = "ts" >
import type { NPaginationLastProps } from '../../../types'
import { PaginationLast, useForwardProps } from 'radix-vue'
import { computed } from 'vue'
import { cn } from '../../../utils'
import Button from '../../elements/Button.vue'
const props = withDefaults ( defineProps < NPaginationLastProps >(), {
paginationUnselected: '~' ,
icon: true ,
square: true ,
label: 'pagination-last-icon' ,
})
const delegatedProps = computed (() => {
const { class : _ , ... delegated } = props
return delegated
})
const forwardedProps = useForwardProps (delegatedProps)
</ script >
< template >
< PaginationLast as-child >
< slot >
< Button
: data-selected = " false "
v-bind = " forwardedProps "
: class = " cn (
'pagination-last' ,
props.class,
) "
/ >
</ slot >
</ paginationlast >
</ template >
Copy to clipboard < script setup lang = "ts" >
import type { NPaginationNextProps } from '../../../types'
import { PaginationNext, useForwardProps } from 'radix-vue'
import { computed } from 'vue'
import { cn } from '../../../utils'
import Button from '../../elements/Button.vue'
const props = withDefaults ( defineProps < NPaginationNextProps >(), {
paginationUnselected: '~' ,
square: true ,
icon: true ,
label: 'pagination-next-icon' ,
})
const delegatedProps = computed (() => {
const { class : _ , ... delegated } = props
return delegated
})
const forwardedProps = useForwardProps (delegatedProps)
</ script >
< template >
< PaginationNext as-child >
< slot >
< Button
: data-selected = " false "
v-bind = " forwardedProps "
: class = " cn (
'pagination-next' ,
props.class) "
/ >
</ slot >
</ PaginationNext >
</ template >
Copy to clipboard < script setup lang = "ts" >
import type { NPaginationPrevProps } from '../../../types'
import { PaginationPrev, useForwardProps } from 'radix-vue'
import { computed } from 'vue'
import { cn } from '../../../utils'
import Button from '../../elements/Button.vue'
const props = withDefaults ( defineProps < NPaginationPrevProps >(), {
paginationUnselected: '~' ,
square: true ,
icon: true ,
label: 'pagination-prev-icon' ,
})
const delegatedProps = computed (() => {
const { class : _ , ... delegated } = props
return delegated
})
const forwardedProps = useForwardProps (delegatedProps)
</ script >
< template >
< PaginationPrev as-child >
< slot >
< Button
: data-selected = " false "
v-bind = " forwardedProps "
: class = " cn (
'pagination-prev' ,
props.class,
) "
/ >
</ slot >
</ PaginationPrev >
</ template >
Copy to clipboard