Skip to content

Commit

Permalink
feat: switch pagination to kobalte primitives
Browse files Browse the repository at this point in the history
  • Loading branch information
stefan-karger committed Apr 21, 2024
1 parent 08f4111 commit 257a2b2
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 108 deletions.
3 changes: 3 additions & 0 deletions apps/docs/public/registry/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,9 @@
},
{
"name": "pagination",
"dependencies": [
"@kobalte/core"
],
"files": [
"ui/pagination.tsx"
],
Expand Down
5 changes: 4 additions & 1 deletion apps/docs/public/registry/ui/pagination.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
{
"name": "pagination",
"dependencies": [
"@kobalte/core"
],
"files": [
{
"name": "pagination.tsx",
"content": "import type { Component, ComponentProps } from \"solid-js\"\nimport { mergeProps, splitProps } from \"solid-js\"\n\nimport { cn } from \"~/lib/utils\"\nimport { buttonVariants, type ButtonProps } from \"~/registry/ui/button\"\n\nconst Pagination: Component<ComponentProps<\"nav\">> = (props) => {\n const [, rest] = splitProps(props, [\"class\"])\n return (\n <nav\n role=\"navigation\"\n aria-label=\"pagination\"\n class={cn(\"mx-auto flex w-full justify-center\", props.class)}\n {...rest}\n />\n )\n}\n\nconst PaginationContent: Component<ComponentProps<\"ul\">> = (props) => {\n const [, rest] = splitProps(props, [\"class\"])\n return <ul class={cn(\"flex flex-row items-center gap-1\", props.class)} {...rest} />\n}\n\nconst PaginationItem: Component<ComponentProps<\"li\">> = (props) => {\n const [, rest] = splitProps(props, [\"class\"])\n return <li class={cn(\"\", props.class)} {...rest} />\n}\n\ntype PaginationLinkProps = {\n isActive?: boolean\n} & Pick<ButtonProps, \"size\"> &\n ComponentProps<\"a\">\n\nconst PaginationLink: Component<PaginationLinkProps> = (rawProps) => {\n const props = mergeProps({ size: \"icon\" } as PaginationLinkProps, rawProps)\n const [, rest] = splitProps(props, [\"class\", \"isActive\", \"size\"])\n return (\n <PaginationItem>\n <a\n aria-current={props.isActive ? \"page\" : undefined}\n class={cn(\n buttonVariants({\n variant: props.isActive ? \"outline\" : \"ghost\",\n size: props.size\n }),\n props.class\n )}\n {...rest}\n />\n </PaginationItem>\n )\n}\n\nconst PaginationPrevious: typeof PaginationLink = (props) => {\n const [, rest] = splitProps(props, [\"class\"])\n return (\n <PaginationLink\n aria-label=\"Go to previous page\"\n size=\"default\"\n class={cn(\"gap-1 pl-2.5\", props.class)}\n {...rest}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n class=\"size-4\"\n >\n <path d=\"M15 6l-6 6l6 6\" />\n </svg>\n <span>Previous</span>\n </PaginationLink>\n )\n}\n\nconst PaginationNext: typeof PaginationLink = (props) => {\n const [, rest] = splitProps(props, [\"class\"])\n return (\n <PaginationLink\n aria-label=\"Go to next page\"\n size=\"default\"\n class={cn(\"gap-1 pr-2.5\", props.class)}\n {...rest}\n >\n <span>Next</span>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n class=\"size-4\"\n >\n <path d=\"M9 6l6 6l-6 6\" />\n </svg>\n </PaginationLink>\n )\n}\n\nconst PaginationEllipsis: Component<ComponentProps<\"span\">> = (props) => {\n const [, rest] = splitProps(props, [\"class\"])\n return (\n <span aria-hidden class={cn(\"flex size-9 items-center justify-center\", props.class)} {...rest}>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n class=\"size-4\"\n >\n <path d=\"M5 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0\" />\n <path d=\"M12 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0\" />\n <path d=\"M19 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0\" />\n </svg>\n <span class=\"sr-only\">More pages</span>\n </span>\n )\n}\n\nexport {\n Pagination,\n PaginationContent,\n PaginationEllipsis,\n PaginationItem,\n PaginationLink,\n PaginationNext,\n PaginationPrevious\n}\n"
"content": "import type { Component } from \"solid-js\"\nimport { splitProps } from \"solid-js\"\n\nimport { Pagination as PaginationPrimitive } from \"@kobalte/core\"\n\nimport { cn } from \"~/lib/utils\"\nimport { buttonVariants } from \"~/registry/ui/button\"\n\nconst Pagination: Component<PaginationPrimitive.PaginationRootProps> = (props) => {\n const [, rest] = splitProps(props, [\"class\"])\n return (\n <PaginationPrimitive.Root\n class={cn(\"[&>*]:flex [&>*]:flex-row [&>*]:items-center [&>*]:gap-1\", props.class)}\n {...rest}\n />\n )\n}\n\nconst PaginationItems = PaginationPrimitive.Items\n\nconst PaginationItem: Component<PaginationPrimitive.PaginationItemProps> = (props) => {\n const [, rest] = splitProps(props, [\"class\"])\n return (\n <PaginationPrimitive.Item\n class={cn(\n buttonVariants({\n variant: \"ghost\"\n }),\n \"size-10 data-[current]:border\"\n )}\n {...rest}\n />\n )\n}\n\ntype EllipsisProps = Exclude<PaginationPrimitive.PaginationEllipsisProps, \"children\">\n\nconst PaginationEllipsis: Component<EllipsisProps> = (props) => {\n const [, rest] = splitProps(props, [\"class\"])\n return (\n <PaginationPrimitive.Ellipsis\n class={cn(\"flex size-10 items-center justify-center\", props.class)}\n {...rest}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n class=\"size-4\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"1\" />\n <circle cx=\"19\" cy=\"12\" r=\"1\" />\n <circle cx=\"5\" cy=\"12\" r=\"1\" />\n </svg>\n <span class=\"sr-only\">More pages</span>\n </PaginationPrimitive.Ellipsis>\n )\n}\n\ntype PreviousProps = Exclude<PaginationPrimitive.PaginationPreviousProps, \"children\">\n\nconst PaginationPrevious: Component<PreviousProps> = (props) => {\n const [, rest] = splitProps(props, [\"class\"])\n return (\n <PaginationPrimitive.Previous\n class={cn(\n buttonVariants({\n variant: \"ghost\"\n }),\n \"gap-1 pl-2.5\",\n props.class\n )}\n {...rest}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n class=\"size-4\"\n >\n <path d=\"M15 6l-6 6l6 6\" />\n </svg>\n <span>Previous</span>\n </PaginationPrimitive.Previous>\n )\n}\n\ntype NextProps = Exclude<PaginationPrimitive.PaginationNextProps, \"children\">\n\nconst PaginationNext: Component<NextProps> = (props) => {\n const [, rest] = splitProps(props, [\"class\"])\n return (\n <PaginationPrimitive.Next\n class={cn(\n buttonVariants({\n variant: \"ghost\"\n }),\n \"gap-1 pl-2.5\",\n props.class\n )}\n {...rest}\n >\n <span>Next</span>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n class=\"size-4\"\n >\n <path d=\"M9 6l6 6l-6 6\" />\n </svg>\n </PaginationPrimitive.Next>\n )\n}\n\nexport {\n Pagination,\n PaginationItems,\n PaginationItem,\n PaginationEllipsis,\n PaginationPrevious,\n PaginationNext\n}\n"
}
],
"type": "ui"
Expand Down
35 changes: 10 additions & 25 deletions apps/docs/src/registry/example/pagination-demo.tsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,23 @@
import {
Pagination,
PaginationContent,
PaginationEllipsis,
PaginationItem,
PaginationLink,
PaginationItems,
PaginationNext,
PaginationPrevious
} from "~/registry/ui/pagination"

export default function PaginationDemo() {
return (
<Pagination>
<PaginationContent>
<PaginationItem>
<PaginationPrevious href="#" />
</PaginationItem>
<PaginationItem>
<PaginationLink href="#">1</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationLink href="#" isActive>
2
</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationLink href="#">3</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationEllipsis />
</PaginationItem>
<PaginationItem>
<PaginationNext href="#" />
</PaginationItem>
</PaginationContent>
<Pagination
count={10}
fixedItems
itemComponent={(props) => <PaginationItem page={props.page}>{props.page}</PaginationItem>}
ellipsisComponent={() => <PaginationEllipsis />}
>
<PaginationPrevious />
<PaginationItems />
<PaginationNext />
</Pagination>
)
}
1 change: 1 addition & 0 deletions apps/docs/src/registry/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ const ui: Registry = [
{
name: "pagination",
type: "ui",
dependencies: ["@kobalte/core"],
files: ["ui/pagination.tsx"]
},
{
Expand Down
128 changes: 63 additions & 65 deletions apps/docs/src/registry/ui/pagination.tsx
Original file line number Diff line number Diff line change
@@ -1,63 +1,45 @@
import type { Component, ComponentProps } from "solid-js"
import { mergeProps, splitProps } from "solid-js"
import type { Component } from "solid-js"
import { splitProps } from "solid-js"

import { Pagination as PaginationPrimitive } from "@kobalte/core"

import { cn } from "~/lib/utils"
import { buttonVariants, type ButtonProps } from "~/registry/ui/button"
import { buttonVariants } from "~/registry/ui/button"

const Pagination: Component<ComponentProps<"nav">> = (props) => {
const Pagination: Component<PaginationPrimitive.PaginationRootProps> = (props) => {
const [, rest] = splitProps(props, ["class"])
return (
<nav
role="navigation"
aria-label="pagination"
class={cn("mx-auto flex w-full justify-center", props.class)}
<PaginationPrimitive.Root
class={cn("[&>*]:flex [&>*]:flex-row [&>*]:items-center [&>*]:gap-1", props.class)}
{...rest}
/>
)
}

const PaginationContent: Component<ComponentProps<"ul">> = (props) => {
const [, rest] = splitProps(props, ["class"])
return <ul class={cn("flex flex-row items-center gap-1", props.class)} {...rest} />
}
const PaginationItems = PaginationPrimitive.Items

const PaginationItem: Component<ComponentProps<"li">> = (props) => {
const PaginationItem: Component<PaginationPrimitive.PaginationItemProps> = (props) => {
const [, rest] = splitProps(props, ["class"])
return <li class={cn("", props.class)} {...rest} />
}

type PaginationLinkProps = {
isActive?: boolean
} & Pick<ButtonProps, "size"> &
ComponentProps<"a">

const PaginationLink: Component<PaginationLinkProps> = (rawProps) => {
const props = mergeProps({ size: "icon" } as PaginationLinkProps, rawProps)
const [, rest] = splitProps(props, ["class", "isActive", "size"])
return (
<PaginationItem>
<a
aria-current={props.isActive ? "page" : undefined}
class={cn(
buttonVariants({
variant: props.isActive ? "outline" : "ghost",
size: props.size
}),
props.class
)}
{...rest}
/>
</PaginationItem>
<PaginationPrimitive.Item
class={cn(
buttonVariants({
variant: "ghost"
}),
"size-10 data-[current]:border"
)}
{...rest}
/>
)
}

const PaginationPrevious: typeof PaginationLink = (props) => {
type EllipsisProps = Exclude<PaginationPrimitive.PaginationEllipsisProps, "children">

const PaginationEllipsis: Component<EllipsisProps> = (props) => {
const [, rest] = splitProps(props, ["class"])
return (
<PaginationLink
aria-label="Go to previous page"
size="default"
class={cn("gap-1 pl-2.5", props.class)}
<PaginationPrimitive.Ellipsis
class={cn("flex size-10 items-center justify-center", props.class)}
{...rest}
>
<svg
Expand All @@ -70,23 +52,30 @@ const PaginationPrevious: typeof PaginationLink = (props) => {
stroke-linejoin="round"
class="size-4"
>
<path d="M15 6l-6 6l6 6" />
<circle cx="12" cy="12" r="1" />
<circle cx="19" cy="12" r="1" />
<circle cx="5" cy="12" r="1" />
</svg>
<span>Previous</span>
</PaginationLink>
<span class="sr-only">More pages</span>
</PaginationPrimitive.Ellipsis>
)
}

const PaginationNext: typeof PaginationLink = (props) => {
type PreviousProps = Exclude<PaginationPrimitive.PaginationPreviousProps, "children">

const PaginationPrevious: Component<PreviousProps> = (props) => {
const [, rest] = splitProps(props, ["class"])
return (
<PaginationLink
aria-label="Go to next page"
size="default"
class={cn("gap-1 pr-2.5", props.class)}
<PaginationPrimitive.Previous
class={cn(
buttonVariants({
variant: "ghost"
}),
"gap-1 pl-2.5",
props.class
)}
{...rest}
>
<span>Next</span>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
Expand All @@ -97,16 +86,29 @@ const PaginationNext: typeof PaginationLink = (props) => {
stroke-linejoin="round"
class="size-4"
>
<path d="M9 6l6 6l-6 6" />
<path d="M15 6l-6 6l6 6" />
</svg>
</PaginationLink>
<span>Previous</span>
</PaginationPrimitive.Previous>
)
}

const PaginationEllipsis: Component<ComponentProps<"span">> = (props) => {
type NextProps = Exclude<PaginationPrimitive.PaginationNextProps, "children">

const PaginationNext: Component<NextProps> = (props) => {
const [, rest] = splitProps(props, ["class"])
return (
<span aria-hidden class={cn("flex size-9 items-center justify-center", props.class)} {...rest}>
<PaginationPrimitive.Next
class={cn(
buttonVariants({
variant: "ghost"
}),
"gap-1 pl-2.5",
props.class
)}
{...rest}
>
<span>Next</span>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
Expand All @@ -117,21 +119,17 @@ const PaginationEllipsis: Component<ComponentProps<"span">> = (props) => {
stroke-linejoin="round"
class="size-4"
>
<path d="M5 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" />
<path d="M12 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" />
<path d="M19 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" />
<path d="M9 6l6 6l-6 6" />
</svg>
<span class="sr-only">More pages</span>
</span>
</PaginationPrimitive.Next>
)
}

export {
Pagination,
PaginationContent,
PaginationEllipsis,
PaginationItems,
PaginationItem,
PaginationLink,
PaginationNext,
PaginationPrevious
PaginationEllipsis,
PaginationPrevious,
PaginationNext
}
32 changes: 15 additions & 17 deletions apps/docs/src/routes/docs/components/pagination.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<MDXHeader
title="Pagination"
description="Pagination with page navigation, next and previous links."
docs="https://kobalte.dev/docs/core/components/pagination"
/>

<ComponentPreview name="pagination-demo" />
Expand All @@ -25,6 +26,12 @@ npx solidui-cli@latest add pagination
<TabsContent value="manual">
<Steps>

<Step>Install the following dependencies: </Step>

```bash
npm install @kobalte/core
```

<Step>Copy and paste the following code into your project: </Step>

<ComponentSource name="pagination" />
Expand All @@ -39,30 +46,21 @@ npx solidui-cli@latest add pagination
```tsx
import {
Pagination,
PaginationContent,
PaginationEllipsis,
PaginationItem,
PaginationLink,
PaginationItems,
PaginationNext,
PaginationPrevious
} from "~/components/ui/pagination"
```

```tsx
<Pagination>
<PaginationContent>
<PaginationItem>
<PaginationPrevious href="#" />
</PaginationItem>
<PaginationItem>
<PaginationLink href="#">1</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationEllipsis />
</PaginationItem>
<PaginationItem>
<PaginationNext href="#" />
</PaginationItem>
</PaginationContent>
<Pagination
itemComponent={(props) => <PaginationItem page={props.page}>{props.page}</PaginationItem>}
ellipsisComponent={() => <PaginationEllipsis />}
>
<PaginationPrevious />
<PaginationItems />
<PaginationNext />
</Pagination>
```

0 comments on commit 257a2b2

Please sign in to comment.