Docs
   Pagination 
 Pagination
Pagination with page navigation, next and previous links.
import {
	Pagination,
	PaginationEllipsis,
	PaginationItem,
	PaginationItems,
	PaginationNext,
	PaginationPrevious,
} from "@repo/tailwindcss/ui/pagination";
 
const PaginationDemo = () => {
	return (
		<Pagination
			fixedItems
			count={10}
			itemComponent={(props) => (
				<PaginationItem page={props.page}>{props.page}</PaginationItem>
			)}
			ellipsisComponent={() => <PaginationEllipsis />}
		>
			<PaginationPrevious />
			<PaginationItems />
			<PaginationNext />
		</Pagination>
	);
};
 
export default PaginationDemo; Installation
npx shadcn-solid@latest add pagination  Install the following dependencies:
npm install @kobalte/core  Copy and paste the following code into your project:
import { cn } from "@/libs/cn";
import type {
	PaginationEllipsisProps,
	PaginationItemProps,
	PaginationPreviousProps,
	PaginationRootProps,
} from "@kobalte/core/pagination";
import { Pagination as PaginationPrimitive } from "@kobalte/core/pagination";
import type { PolymorphicProps } from "@kobalte/core/polymorphic";
import type { VariantProps } from "class-variance-authority";
import type { ValidComponent, VoidProps } from "solid-js";
import { mergeProps, splitProps } from "solid-js";
import { buttonVariants } from "./button";
 
export const PaginationItems = PaginationPrimitive.Items;
 
type paginationProps<T extends ValidComponent = "nav"> =
	PaginationRootProps<T> & {
		class?: string;
	};
 
export const Pagination = <T extends ValidComponent = "nav">(
	props: PolymorphicProps<T, paginationProps<T>>,
) => {
	const [local, rest] = splitProps(props as paginationProps, ["class"]);
 
	return (
		<PaginationPrimitive
			class={cn(
				"mx-auto flex w-full justify-center [&>ul]:flex [&>ul]:flex-row [&>ul]:items-center [&>ul]:gap-1",
				local.class,
			)}
			{...rest}
		/>
	);
};
 
type paginationItemProps<T extends ValidComponent = "button"> =
	PaginationItemProps<T> &
		Pick<VariantProps<typeof buttonVariants>, "size"> & {
			class?: string;
		};
 
export const PaginationItem = <T extends ValidComponent = "button">(
	props: PolymorphicProps<T, paginationItemProps<T>>,
) => {
	// @ts-expect-error - required `page`
	const merge = mergeProps<paginationItemProps[]>({ size: "icon" }, props);
	const [local, rest] = splitProps(merge as paginationItemProps, [
		"class",
		"size",
	]);
 
	return (
		<PaginationPrimitive.Item
			class={cn(
				buttonVariants({
					variant: "ghost",
					size: local.size,
				}),
				"aria-[current=page]:border aria-[current=page]:border-input aria-[current=page]:bg-background aria-[current=page]:shadow-sm aria-[current=page]:hover:bg-accent aria-[current=page]:hover:text-accent-foreground",
				local.class,
			)}
			{...rest}
		/>
	);
};
 
type paginationEllipsisProps<T extends ValidComponent = "div"> = VoidProps<
	PaginationEllipsisProps<T> & {
		class?: string;
	}
>;
 
export const PaginationEllipsis = <T extends ValidComponent = "div">(
	props: PolymorphicProps<T, paginationEllipsisProps<T>>,
) => {
	const [local, rest] = splitProps(props as paginationEllipsisProps, ["class"]);
 
	return (
		<PaginationPrimitive.Ellipsis
			class={cn("flex h-9 w-9 items-center justify-center", local.class)}
			{...rest}
		>
			<svg
				xmlns="http://www.w3.org/2000/svg"
				viewBox="0 0 24 24"
				class="h-4 w-4"
			>
				<path
					fill="none"
					stroke="currentColor"
					stroke-linecap="round"
					stroke-linejoin="round"
					stroke-width="2"
					d="M4 12a1 1 0 1 0 2 0a1 1 0 1 0-2 0m7 0a1 1 0 1 0 2 0a1 1 0 1 0-2 0m7 0a1 1 0 1 0 2 0a1 1 0 1 0-2 0"
				/>
				<title>More pages</title>
			</svg>
		</PaginationPrimitive.Ellipsis>
	);
};
 
type paginationPreviousProps<T extends ValidComponent = "button"> =
	PaginationPreviousProps<T> &
		Pick<VariantProps<typeof buttonVariants>, "size"> & {
			class?: string;
		};
 
export const PaginationPrevious = <T extends ValidComponent = "button">(
	props: PolymorphicProps<T, paginationPreviousProps<T>>,
) => {
	const merge = mergeProps<paginationPreviousProps<T>[]>(
		{ size: "icon" },
		props,
	);
	const [local, rest] = splitProps(merge as paginationPreviousProps, [
		"class",
		"size",
	]);
 
	return (
		<PaginationPrimitive.Previous
			class={cn(
				buttonVariants({
					variant: "ghost",
					size: local.size,
				}),
				"aria-[current=page]:border aria-[current=page]:border-input aria-[current=page]:bg-background aria-[current=page]:shadow-sm aria-[current=page]:hover:bg-accent aria-[current=page]:hover:text-accent-foreground",
				local.class,
			)}
			{...rest}
		>
			<svg
				xmlns="http://www.w3.org/2000/svg"
				viewBox="0 0 24 24"
				class="h-4 w-4"
			>
				<path
					fill="none"
					stroke="currentColor"
					stroke-linecap="round"
					stroke-linejoin="round"
					stroke-width="2"
					d="m15 6l-6 6l6 6"
				/>
				<title>Previous page</title>
			</svg>
		</PaginationPrimitive.Previous>
	);
};
 
type paginationNextProps<T extends ValidComponent = "button"> =
	paginationPreviousProps<T>;
 
export const PaginationNext = <T extends ValidComponent = "button">(
	props: PolymorphicProps<T, paginationNextProps<T>>,
) => {
	const merge = mergeProps<paginationNextProps<T>[]>({ size: "icon" }, props);
	const [local, rest] = splitProps(merge as paginationNextProps, [
		"class",
		"size",
	]);
 
	return (
		<PaginationPrimitive.Next
			class={cn(
				buttonVariants({
					variant: "ghost",
					size: local.size,
				}),
				"aria-[current=page]:border aria-[current=page]:border-input aria-[current=page]:bg-background aria-[current=page]:shadow-sm aria-[current=page]:hover:bg-accent aria-[current=page]:hover:text-accent-foreground",
				local.class,
			)}
			{...rest}
		>
			<svg
				xmlns="http://www.w3.org/2000/svg"
				class="h-4 w-4"
				viewBox="0 0 24 24"
			>
				<path
					fill="none"
					stroke="currentColor"
					stroke-linecap="round"
					stroke-linejoin="round"
					stroke-width="2"
					d="m9 6l6 6l-6 6"
				/>
				<title>Next page</title>
			</svg>
		</PaginationPrimitive.Next>
	);
}; Install the following dependencies:
npm install @kobalte/core  Copy and paste the following code into your project:
import { cn } from "@/libs/cn";
import type {
	PaginationEllipsisProps,
	PaginationItemProps,
	PaginationPreviousProps,
	PaginationRootProps,
} from "@kobalte/core/pagination";
import { Pagination as PaginationPrimitive } from "@kobalte/core/pagination";
import type { PolymorphicProps } from "@kobalte/core/polymorphic";
import type { VariantProps } from "class-variance-authority";
import type { ValidComponent, VoidProps } from "solid-js";
import { mergeProps, splitProps } from "solid-js";
import { buttonVariants } from "./button";
 
export const PaginationItems = PaginationPrimitive.Items;
 
type paginationProps<T extends ValidComponent = "nav"> =
	PaginationRootProps<T> & {
		class?: string;
	};
 
export const Pagination = <T extends ValidComponent = "nav">(
	props: PolymorphicProps<T, paginationProps<T>>,
) => {
	const [local, rest] = splitProps(props as paginationProps, ["class"]);
 
	return (
		<PaginationPrimitive
			class={cn(
				"mx-auto flex w-full justify-center [&>ul]:(flex flex-row items-center gap-1)",
				local.class,
			)}
			{...rest}
		/>
	);
};
 
type paginationItemProps<T extends ValidComponent = "button"> =
	PaginationItemProps<T> &
		Pick<VariantProps<typeof buttonVariants>, "size"> & {
			class?: string;
		};
 
export const PaginationItem = <T extends ValidComponent = "button">(
	props: PolymorphicProps<T, paginationItemProps<T>>,
) => {
	// @ts-expect-error - required `page`
	const merge = mergeProps<paginationItemProps[]>({ size: "icon" }, props);
	const [local, rest] = splitProps(merge as paginationItemProps, [
		"class",
		"size",
	]);
 
	return (
		<PaginationPrimitive.Item
			class={cn(
				buttonVariants({
					variant: "ghost",
					size: local.size,
				}),
				"aria-[current=page]:(border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground)",
				local.class,
			)}
			{...rest}
		/>
	);
};
 
type paginationEllipsisProps<T extends ValidComponent = "div"> = VoidProps<
	PaginationEllipsisProps<T> & {
		class?: string;
	}
>;
 
export const PaginationEllipsis = <T extends ValidComponent = "div">(
	props: PolymorphicProps<T, paginationEllipsisProps<T>>,
) => {
	const [local, rest] = splitProps(props as paginationEllipsisProps, ["class"]);
 
	return (
		<PaginationPrimitive.Ellipsis
			class={cn("flex h-9 w-9 items-center justify-center", local.class)}
			{...rest}
		>
			<svg
				xmlns="http://www.w3.org/2000/svg"
				viewBox="0 0 24 24"
				class="h-4 w-4"
			>
				<path
					fill="none"
					stroke="currentColor"
					stroke-linecap="round"
					stroke-linejoin="round"
					stroke-width="2"
					d="M4 12a1 1 0 1 0 2 0a1 1 0 1 0-2 0m7 0a1 1 0 1 0 2 0a1 1 0 1 0-2 0m7 0a1 1 0 1 0 2 0a1 1 0 1 0-2 0"
				/>
				<title>More pages</title>
			</svg>
		</PaginationPrimitive.Ellipsis>
	);
};
 
type paginationPreviousProps<T extends ValidComponent = "button"> =
	PaginationPreviousProps<T> &
		Pick<VariantProps<typeof buttonVariants>, "size"> & {
			class?: string;
		};
 
export const PaginationPrevious = <T extends ValidComponent = "button">(
	props: PolymorphicProps<T, paginationPreviousProps<T>>,
) => {
	const merge = mergeProps<paginationPreviousProps<T>[]>(
		{ size: "icon" },
		props,
	);
	const [local, rest] = splitProps(merge as paginationPreviousProps, [
		"class",
		"size",
	]);
 
	return (
		<PaginationPrimitive.Previous
			class={cn(
				buttonVariants({
					variant: "ghost",
					size: local.size,
				}),
				"aria-[current=page]:(border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground)",
				local.class,
			)}
			{...rest}
		>
			<svg
				xmlns="http://www.w3.org/2000/svg"
				viewBox="0 0 24 24"
				class="h-4 w-4"
			>
				<path
					fill="none"
					stroke="currentColor"
					stroke-linecap="round"
					stroke-linejoin="round"
					stroke-width="2"
					d="m15 6l-6 6l6 6"
				/>
				<title>Previous page</title>
			</svg>
		</PaginationPrimitive.Previous>
	);
};
 
type paginationNextProps<T extends ValidComponent = "button"> =
	paginationPreviousProps<T>;
 
export const PaginationNext = <T extends ValidComponent = "button">(
	props: PolymorphicProps<T, paginationNextProps<T>>,
) => {
	const merge = mergeProps<paginationNextProps<T>[]>({ size: "icon" }, props);
	const [local, rest] = splitProps(merge as paginationNextProps, [
		"class",
		"size",
	]);
 
	return (
		<PaginationPrimitive.Next
			class={cn(
				buttonVariants({
					variant: "ghost",
					size: local.size,
				}),
				"aria-[current=page]:(border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground)",
				local.class,
			)}
			{...rest}
		>
			<svg
				xmlns="http://www.w3.org/2000/svg"
				class="h-4 w-4"
				viewBox="0 0 24 24"
			>
				<path
					fill="none"
					stroke="currentColor"
					stroke-linecap="round"
					stroke-linejoin="round"
					stroke-width="2"
					d="m9 6l6 6l-6 6"
				/>
				<title>Next page</title>
			</svg>
		</PaginationPrimitive.Next>
	);
}; Usage
import {
  Pagination,
  PaginationEllipsis,
  PaginationItem,
  PaginationItems,
  PaginationNext,
  PaginationPrevious
} from "@/components/ui/pagination"; <Pagination
  count={10}
  itemComponent={props => <PaginationItem page={props.page}>{props.page}</PaginationItem>}
  ellipsisComponent={() => <PaginationEllipsis />}
>
  <PaginationPrevious />
  <PaginationItems />
  <PaginationNext />
</Pagination>