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 total
number
0
The total number of items in your list. page
number
-
The value that controls the current page and can be bound with v-model
. itemsPerPage
number
10
The number of items displayed per page. showEdges
boolean
false
When set to true
, the first page, last page, and ellipsis will always be displayed. disabled
boolean
false
Disables 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 showFirst
boolean
true
Displays the first page button. showLast
boolean
true
Displays the last page button. showPrev
boolean
true
Displays the previous page button. showNext
boolean
true
Displays the next page button. showListItem
boolean
true
Displays 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 size
sm
Adjusts the size of the entire pagination. _pagination-first.size
sm
Customizes the size of the first page button. _pagination-last.size
sm
Customizes the size of the last page button. _pagination-prev.size
sm
Customizes the size of the previous page button. _pagination-next.size
sm
Customizes the size of the next page button. _pagination-list-item.size
sm
Customizes the size of the page list items. _pagination-ellipsis.size
sm
Customizes 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 siblingCount
number
2
The 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-primary
The color of the selected page. pagination-unselected
{variant}-{color}
solid-white
The color of the unselected page. pagination-ellipsis
{variant}-{color}
text-black
The 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-item
Customizes the pagination list item component. _pagination-prev
Customizes the previous page navigation button. _pagination-next
Customizes the next page navigation button. _pagination-first
Customizes the first page navigation button. _pagination-last
Customizes the last page navigation button. _pagination-ellipsis
Customizes the ellipsis indicator in the pagination. _pagination-list
Customizes 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 first
Customizes the first page navigation button. - last
Customizes the last page navigation button. - prev
Customizes the previous page navigation button. - next
Customizes the next page navigation button. - list-item
Customizes the pagination list item component. item
page
ellipsis
Customizes 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