Skip to content

Add Pagination component#30

Merged
lifeiscontent merged 7 commits into
mainfrom
feat/pagination
Jun 10, 2026
Merged

Add Pagination component#30
lifeiscontent merged 7 commits into
mainfrom
feat/pagination

Conversation

@lifeiscontent

@lifeiscontent lifeiscontent commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

What

Adds a Pagination component to @plane/propel, built from Figma node 4762-503 (Global components).

It is a single composite navigation control rather than a variant matrix: the Figma "variant" axis (All pages visible / Near start / Middle / Near end) is a function of where the current page sits within the total, so it is derived at render time from page/pageCount, never a prop.

Structure (semantic HTML)

  • <nav aria-label="Pagination"> landmark
  • optional per-page selector (50 v per page, a layer-3 pill + native <select>)
  • optional range label (1-50 of 250)
  • an ordered <ul> of page controls: a previous button, first/last anchors with ellipses around a window of pages near the current one, and a next button

Props

  • page (required), pageCount (required), onPageChange (required)
  • loading?: renders the current page as a spinner while navigation is in flight
  • pageSize?: { value, options, onChange } shows/hides the per-page selector
  • range?: { current, total } shows/hides the range label
  • labels?: overrides for accessible names / visible selector text (i18n)

No cva defaultVariants; the essential axes are required props. cva + cx (no tailwind-merge), semantic tokens only.

Accessibility

  • current page marked aria-current="page" and disabled
  • prev/next are buttons with accessible names, disabled at the bounds
  • ellipsis is aria-hidden; lucide icons aria-hidden
  • axe a11y gate passes (gallery navs given unique labels to satisfy landmark-unique)

Tokens (match Figma)

24px square slots; page numbers radius/sm with a layer-transparent-active selected fill and layer-transparent-hover; prev/next radius/md 16px arrows; text/13; per-page pill layer-3 + chevron-down.

Verification (LTR + RTL)

Rendered the Variants story (the Figma frame) in a browser and compared both directions:

  • LTR: all four layouts match: 1 2 3 4 5 / 1 2 3 … 100 / 1 … 44 45 46 … 100 / 1 … 98 99 100; selected page greyed, prev disabled at start, next disabled at end, ellipsis dots in the placeholder color.
  • RTL (dir="rtl"): layout flips (selector + numbers right-to-left) and the prev/next arrows mirror via rtl:-scale-x-100, so "previous" still points toward the start of the run.

Gates

vp check, vp run -r test (axe a11y), vp run -r build (attw clean), vp run -r build-storybook all pass.

Dependencies

Optionally composed by: #15 (Table). Otherwise standalone.

Composite pagination nav built from semantic HTML: a <nav aria-label> landmark
holding an optional per-page selector, an optional range label, and an ordered
list of page controls (prev/next arrow buttons + page numbers with first/last
anchors and ellipses around a window near the current page).

The four Figma truncation layouts (all-visible / near-start / middle / near-end)
are derived from page/pageCount, not exposed as a variant. The current page is
marked aria-current="page" and disabled; prev/next disable at the bounds and
their arrows mirror under RTL. Tokens (24px slots, radius/sm pages, radius/md
arrows, text/13, transparent-active selected fill) match the Figma frame.
@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown

📚 Storybook preview: https://pr-30-propel-storybook.vamsi-906.workers.dev

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new Pagination component to the @plane/propel component set, including Storybook stories and interaction tests, intended to match the referenced Figma spec and support optional page-size + range UI.

Changes:

  • Introduces Pagination component (nav landmark + page tokens + prev/next + optional page-size selector and range label).
  • Adds Storybook stories covering default/variants/loading states and a basic behavioral play test.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
packages/propel/src/components/pagination/index.tsx Implements the new Pagination component, token generation, and accessibility labels.
packages/propel/src/components/pagination/pagination.stories.tsx Adds Storybook stories and a play-test validating basic navigation/a11y behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/propel/src/components/pagination/index.tsx
Comment thread packages/propel/src/components/pagination/index.tsx
@lifeiscontent lifeiscontent mentioned this pull request Jun 9, 2026
… ellipses

- slotBase: replace fixed size-6 with h-6 min-w-6 w-auto so single digits stay
  square (24px) but the slot grows for wider content — 100 no longer clips.
- buildPageTokens: only ellipsize gaps of 2+ pages; a lone skipped page is
  rendered as its own number, so pageCount=8/page=4 reads 1 2 3 4 5 … 8 (page 2
  no longer hidden) instead of 1 … 3 4 5 … 8.
- stories: add ThreeDigit (pageCount=100/page=100) and SingleGap play test
  (pageCount=8/page=4) covering both cases.

@bhaveshraja bhaveshraja left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image

text color of the selected tab is wrong. it should have text-primary

lifeiscontent and others added 2 commits June 10, 2026 11:48
The current/selected page is marked `disabled` to block re-navigation,
which triggered the base `disabled:text-disabled` dim. Figma's
"Selected" state (node 4762:550) keeps `text/primary`, so the current
variant now applies `disabled:text-primary` to override the dim while
staying on the `transparent-active` fill. Default/hover/disabled states
are unchanged and still match Figma.
@lifeiscontent

Copy link
Copy Markdown
Collaborator Author

@bhaveshraja fixed: selected page number now uses text-primary (matched to Figma 4762-503).

@lifeiscontent

Copy link
Copy Markdown
Collaborator Author

Added keyboard play tests: Enter/Space page activation fires onPageChange, prev/next disabled at the ends, aria-current on the selected page.

Replace the interim native <select> with the propel Dropdown: the layer-3
pill becomes a DropdownTrigger labeled "N per page" and the menu lists the
page-size options as single-select DropdownItems (current one checked), with
selection reporting through the existing pageSize.onChange. Same pageSize API
({ value, options, onChange }); keyboard (ArrowDown/Enter opens, arrows +
Enter select) and the labeled trigger keep it accessible. Adds a play-tested
PageSizeSelector story covering open/select/keyboard.
@lifeiscontent

Copy link
Copy Markdown
Collaborator Author

Replaced the native page-size select with the propel Dropdown (composition, per #41).

@lifeiscontent lifeiscontent merged commit 7d358e4 into main Jun 10, 2026
2 checks passed
@lifeiscontent lifeiscontent deleted the feat/pagination branch June 10, 2026 15:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants