diff --git a/packages/propel/src/components/pagination/pagination.stories.tsx b/packages/propel/src/components/pagination/pagination.stories.tsx index 761bb29c..a844039c 100644 --- a/packages/propel/src/components/pagination/pagination.stories.tsx +++ b/packages/propel/src/components/pagination/pagination.stories.tsx @@ -2,11 +2,39 @@ import type { Meta, StoryObj } from "@storybook/react-vite"; import * as React from "react"; import { expect, fn, userEvent, waitFor, within } from "storybook/test"; +import { + PaginationArrowButton, + PaginationEllipsis, + PaginationItem, + PaginationList, + PaginationPageButton, + PaginationPerPage, + PaginationPerPageIndicator, + PaginationPerPageLabel, + PaginationPerPageTrigger, + PaginationRange, + PaginationRangeCurrent, + PaginationSpinner, +} from "../../ui/pagination/index"; import { Pagination } from "./index"; const meta = { title: "Components/Pagination", component: Pagination, + subcomponents: { + PaginationList, + PaginationItem, + PaginationPageButton, + PaginationArrowButton, + PaginationEllipsis, + PaginationSpinner, + PaginationPerPage, + PaginationPerPageTrigger, + PaginationPerPageIndicator, + PaginationPerPageLabel, + PaginationRange, + PaginationRangeCurrent, + }, parameters: { design: { type: "figma", diff --git a/packages/propel/src/components/pagination/pagination.tsx b/packages/propel/src/components/pagination/pagination.tsx index 013845bd..3c03d3f4 100644 --- a/packages/propel/src/components/pagination/pagination.tsx +++ b/packages/propel/src/components/pagination/pagination.tsx @@ -1,12 +1,21 @@ -import { ArrowLeft, ArrowRight, ChevronDown, LoaderCircle } from "lucide-react"; +import { ArrowLeft, ArrowRight, ChevronDown, LoaderCircle, MoreHorizontal } from "lucide-react"; import * as React from "react"; import { Menu, MenuTrigger } from "../../ui/menu/index"; import { + Pagination as PaginationRoot, PaginationArrowButton, PaginationEllipsis, + PaginationItem, + PaginationList, PaginationPageButton, + PaginationPerPage, + PaginationPerPageIndicator, + PaginationPerPageLabel, PaginationPerPageTrigger, + PaginationRange, + PaginationRangeCurrent, + PaginationSpinner, } from "../../ui/pagination/index"; import { MenuContent, MenuItem } from "../menu/index"; @@ -16,17 +25,8 @@ import { MenuContent, MenuItem } from "../menu/index"; // at render time from `page`/`pageCount` — never a prop. What designers can toggle is // genuinely additive: an optional per-page selector and an optional range label. // -// Tokens (Figma node 4762-503): -// - page-number button: 24px square, radius/sm (4px), text/13, transparent bg that -// fills to `layer-transparent-hover` on hover and `layer-transparent-active` when -// it is the current page; disabled/loading dim to the placeholder/disabled colors. -// - prev/next: 24px square icon buttons, radius/md (6px), 16px arrows. The arrows are -// directional, so they mirror in RTL via `rtl:-scale-x-100`. -// - ellipsis: a non-interactive 24px slot holding a 14px more-horizontal glyph. -// - per-page selector: a `layer-3` pill, 24px tall, radius/md, "50" + chevron-down, -// followed by "per page" tertiary text. The pill is the trigger for a propel -// Menu (single-select) whose menu lists the page-size options; picking one -// reports it through `pageSize.onValueChange`. +// This components tier only COMPOSES the `ui/pagination` parts (each a single styled +// element); all chrome lives in their cva — there is no className/cva/cx here. // Builds the sequence of visible page tokens. Always shows the first and last page; // shows up to one neighbour either side of the current page; inserts an ellipsis @@ -89,7 +89,7 @@ export type PaginationLabels = { /** Visible text on the per-page selector trigger, given the size. Defaults to `"50"`. */ perPageValue: (pageSize: number) => React.ReactNode; /** Trailing text after the per-page selector. Defaults to `"per page"`. */ - perPage: React.ReactNode; + perPage: string; }; const DEFAULT_LABELS: PaginationLabels = { @@ -165,22 +165,25 @@ export function Pagination({ const atEnd = page >= pageCount; return ( - + + + ); } diff --git a/packages/propel/src/ui/pagination/index.tsx b/packages/propel/src/ui/pagination/index.tsx index 724a07b7..13369b6e 100644 --- a/packages/propel/src/ui/pagination/index.tsx +++ b/packages/propel/src/ui/pagination/index.tsx @@ -1,13 +1,40 @@ +export { Pagination, type PaginationProps } from "./pagination"; export { PaginationArrowButton, type PaginationArrowButtonProps } from "./pagination-arrow-button"; -export { PaginationEllipsis } from "./pagination-ellipsis"; +export { PaginationEllipsis, type PaginationEllipsisProps } from "./pagination-ellipsis"; +export { PaginationItem, type PaginationItemProps } from "./pagination-item"; +export { PaginationList, type PaginationListProps } from "./pagination-list"; export { PaginationPageButton, type PaginationPageButtonProps } from "./pagination-page-button"; +export { PaginationPerPage, type PaginationPerPageProps } from "./pagination-per-page"; +export { + PaginationPerPageIndicator, + type PaginationPerPageIndicatorProps, +} from "./pagination-per-page-indicator"; +export { + PaginationPerPageLabel, + type PaginationPerPageLabelProps, +} from "./pagination-per-page-label"; export { PaginationPerPageTrigger, type PaginationPerPageTriggerProps, } from "./pagination-per-page-trigger"; +export { PaginationRange, type PaginationRangeProps } from "./pagination-range"; +export { + PaginationRangeCurrent, + type PaginationRangeCurrentProps, +} from "./pagination-range-current"; +export { PaginationSpinner, type PaginationSpinnerProps } from "./pagination-spinner"; export { - arrowButtonVariants, - pageButtonVariants, - perPageTriggerVariants, - slotBase, + paginationArrowButtonVariants, + paginationEllipsisVariants, + paginationItemVariants, + paginationListVariants, + paginationPageButtonVariants, + paginationPerPageIndicatorVariants, + paginationPerPageLabelVariants, + paginationPerPageTriggerVariants, + paginationPerPageVariants, + paginationRangeCurrentVariants, + paginationRangeVariants, + paginationSpinnerVariants, + paginationVariants, } from "./variants"; diff --git a/packages/propel/src/ui/pagination/pagination-arrow-button.tsx b/packages/propel/src/ui/pagination/pagination-arrow-button.tsx index 9f7fbd16..918922ea 100644 --- a/packages/propel/src/ui/pagination/pagination-arrow-button.tsx +++ b/packages/propel/src/ui/pagination/pagination-arrow-button.tsx @@ -1,6 +1,6 @@ import type * as React from "react"; -import { arrowButtonVariants } from "./variants"; +import { paginationArrowButtonVariants } from "./variants"; export type PaginationArrowButtonProps = Omit< React.ComponentProps<"button">, @@ -8,9 +8,10 @@ export type PaginationArrowButtonProps = Omit< >; /** - * A styled prev/next arrow button. Applies `arrowButtonVariants()`; pass the (directional, - * RTL-mirrored) arrow icon as `children` and wire `aria-label`/`disabled`/`onClick` through props. + * A styled prev/next arrow button. Applies `paginationArrowButtonVariants()`; pass the + * (directional, RTL-mirrored) arrow icon as `children` and wire `aria-label`/`disabled`/`onClick` + * through props. */ export function PaginationArrowButton(props: PaginationArrowButtonProps) { - return