-
-
Notifications
You must be signed in to change notification settings - Fork 93
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add pagination components (#223)
Co-authored-by: Hunter Johnston <johnstonhuntera@gmail.com> Co-authored-by: Hunter Johnston <64506580+huntabyte@users.noreply.github.com>
- Loading branch information
1 parent
e94129c
commit ad6ba3a
Showing
24 changed files
with
610 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"bits-ui": patch | ||
--- | ||
|
||
feat: add `Pagination` component |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
--- | ||
title: Pagination | ||
description: Facilitates navigation between pages. | ||
--- | ||
|
||
<script> | ||
import { APISection, ComponentPreview, PaginationDemo } from '@/components' | ||
export let schemas | ||
</script> | ||
|
||
<ComponentPreview name="pagination-demo" comp="Pagination"> | ||
|
||
<PaginationDemo slot="preview" /> | ||
|
||
</ComponentPreview> | ||
|
||
## Structure | ||
|
||
```svelte | ||
<script lang="ts"> | ||
import { Pagination } from "bits-ui"; | ||
</script> | ||
<Pagination.Root let:pages> | ||
<Pagination.PrevButton /> | ||
{#each pages as page (page.key)} | ||
<Pagination.Page {page} /> | ||
{/each} | ||
<Pagination.NextButton /> | ||
</Pagination.Root> | ||
``` | ||
|
||
<APISection {schemas} /> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
<script lang="ts"> | ||
import { Pagination } from "$lib"; | ||
import { CaretLeft, CaretRight, DotsThree } from "phosphor-svelte"; | ||
</script> | ||
|
||
<Pagination.Root count={100} perPage={10} let:pages let:range> | ||
<p class="text-sm text-muted-foreground"> | ||
Showing {range.start} - {range.end} | ||
</p> | ||
<div class="mt-4 flex items-center justify-center gap-1.5"> | ||
<Pagination.PrevButton | ||
class="inline-flex items-center justify-center rounded-[9px] bg-transparent transition-all sq-10 hover:bg-foreground/5 active:scale-98 active:bg-dark-10 disabled:cursor-not-allowed disabled:opacity-50 hover:disabled:bg-transparent" | ||
> | ||
<CaretLeft class="sq-6" /> | ||
</Pagination.PrevButton> | ||
{#each pages as page (page.key)} | ||
{#if page.type === "ellipsis"} | ||
<div class="self-end"> | ||
<DotsThree class="sq-5" weight="bold" /> | ||
</div> | ||
{:else} | ||
<Pagination.Page | ||
{page} | ||
class="inline-flex items-center justify-center rounded-[9px] border border-border bg-background shadow-mini sq-10 hover:bg-muted active:scale-98 active:bg-dark-10 data-[selected]:bg-foreground data-[selected]:text-background" | ||
> | ||
{page.value} | ||
</Pagination.Page> | ||
{/if} | ||
{/each} | ||
<Pagination.NextButton | ||
class="inline-flex items-center justify-center rounded-[9px] bg-transparent transition-all sq-10 hover:bg-foreground/5 active:scale-98 active:bg-dark-10 disabled:cursor-not-allowed hover:disabled:bg-transparent" | ||
> | ||
<CaretRight class="sq-6" /> | ||
</Pagination.NextButton> | ||
</div> | ||
</Pagination.Root> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
export type Page = { | ||
type: "page"; | ||
/** The page number the `PageItem` represents */ | ||
value: number; | ||
}; | ||
|
||
export type Ellipsis = { | ||
type: "ellipsis"; | ||
}; | ||
|
||
export type PageItem = (Page | Ellipsis) & { | ||
/** Unique key for the item, for svelte #each block */ | ||
key: string; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
import type { APISchema } from "@/types"; | ||
import type * as Pagination from "$lib/bits/pagination/_types.js"; | ||
import * as C from "@/content/constants.js"; | ||
import { asChild } from "@/content/api-reference/helpers.js"; | ||
import { builderAndAttrsSlotProps } from "./helpers"; | ||
import { pageItemProp } from "./extended-types"; | ||
|
||
export const root: APISchema<Pagination.Props> = { | ||
title: "Root", | ||
description: "The root pagination component which contains all other pagination components.", | ||
props: { | ||
count: { | ||
type: C.NUMBER, | ||
description: "The total number of items.", | ||
required: true | ||
}, | ||
perPage: { | ||
type: C.NUMBER, | ||
description: "The number of items per page.", | ||
default: "1" | ||
}, | ||
siblingCount: { | ||
type: C.NUMBER, | ||
description: "The number of page triggers to show on either side of the current page.", | ||
default: "1" | ||
}, | ||
page: { | ||
type: C.NUMBER, | ||
description: | ||
"The selected page. You can bind this to a variable to control the selected page from outside the component." | ||
}, | ||
onPageChange: { | ||
type: { | ||
type: C.FUNCTION, | ||
definition: "(page: number) => void" | ||
}, | ||
description: "A function called when the selected page changes." | ||
}, | ||
asChild | ||
} | ||
}; | ||
|
||
export const page: APISchema<Pagination.PageProps> = { | ||
title: "Page", | ||
description: "A button that triggers a page change.", | ||
props: { | ||
page: { | ||
type: pageItemProp, | ||
description: "The page item this component represents." | ||
}, | ||
asChild | ||
}, | ||
slotProps: { | ||
...builderAndAttrsSlotProps | ||
}, | ||
dataAttributes: [ | ||
{ | ||
name: "selected", | ||
description: "Present on the current page element." | ||
}, | ||
{ | ||
name: "pagination-page", | ||
description: "Present on the page trigger element." | ||
} | ||
] | ||
}; | ||
|
||
export const prevButton: APISchema<Pagination.PrevButtonProps> = { | ||
title: "PrevButton", | ||
description: "The previous button of the pagination.", | ||
props: { | ||
asChild | ||
}, | ||
slotProps: { | ||
...builderAndAttrsSlotProps | ||
}, | ||
dataAttributes: [ | ||
{ | ||
name: "pagination-prev-button", | ||
description: "Present on the previous button element." | ||
} | ||
] | ||
}; | ||
|
||
export const nextButton: APISchema<Pagination.NextButtonProps> = { | ||
title: "NextButton", | ||
description: "The next button of the pagination.", | ||
props: { | ||
asChild | ||
}, | ||
slotProps: { | ||
...builderAndAttrsSlotProps | ||
}, | ||
dataAttributes: [ | ||
{ | ||
name: "pagination-next-button", | ||
description: "Present on the next button element." | ||
} | ||
] | ||
}; | ||
|
||
export const pagination = [root, page, prevButton, nextButton]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
export type { | ||
Props as PaginationProps, | ||
PrevButtonProps as PaginationPrevButtonProps, | ||
NextButtonProps as PaginationNextButtonProps, | ||
PageProps as PaginationPageProps, | ||
// | ||
Events as PaginationEvents, | ||
PrevButtonEvents as PaginationPrevButtonEvents, | ||
NextButtonEvents as PaginationNextButtonEvents, | ||
PageEvents as PaginationPageEvents | ||
} from "./types.js"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
/** | ||
* We define prop types without the HTMLAttributes here so that we can use them | ||
* to type-check our API documentation, which requires we document each prop, | ||
* but we don't want to document the HTML attributes. | ||
*/ | ||
|
||
import type { AsChild, Expand, OnChangeFn } from "$lib/internal"; | ||
import type { CreatePaginationProps, Page } from "@melt-ui/svelte"; | ||
|
||
type OmitPaginationProps<T> = Omit<T, "page" | "defaultPage" | "onPageChange">; | ||
|
||
type Props = Expand< | ||
OmitPaginationProps<CreatePaginationProps> & { | ||
/** | ||
* The selected page. This updates as the users selects new pages. | ||
* | ||
* You can bind this to a value to programmatically control the value state. | ||
*/ | ||
page?: number; | ||
|
||
/** | ||
* A callback function called when the page changes. | ||
*/ | ||
onPageChange?: OnChangeFn<number>; | ||
} & AsChild | ||
>; | ||
|
||
type PageProps = { | ||
page: Page; | ||
} & AsChild; | ||
|
||
type PrevButtonProps = AsChild; | ||
|
||
type NextButtonProps = AsChild; | ||
|
||
export type { Props, PrevButtonProps, NextButtonProps, PageProps }; |
35 changes: 35 additions & 0 deletions
35
src/lib/bits/pagination/components/pagination-next-button.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
<script lang="ts"> | ||
import type { NextButtonEvents, NextButtonProps } from "../types.js"; | ||
import { createDispatcher } from "$lib/internal/events.js"; | ||
import { getAttrs, getCtx } from "../ctx.js"; | ||
import { melt } from "@melt-ui/svelte"; | ||
type $$Props = NextButtonProps; | ||
type $$Events = NextButtonEvents; | ||
export let asChild: $$Props["asChild"] = undefined; | ||
const { | ||
elements: { nextButton } | ||
} = getCtx(); | ||
const attrs = getAttrs("next-button"); | ||
$: builder = $nextButton; | ||
$: Object.assign(builder, attrs); | ||
const dispatch = createDispatcher(); | ||
</script> | ||
|
||
{#if asChild} | ||
<slot {builder} /> | ||
{:else} | ||
<button | ||
use:melt={builder} | ||
type="button" | ||
{...$$restProps} | ||
on:m-click={dispatch} | ||
> | ||
<slot {builder} /> | ||
</button> | ||
{/if} |
Oops, something went wrong.