Skip to content

feat(pagination) - update pagination component to use new SHINE design system - #2035

Merged
ttaylor-stack merged 34 commits into
betafrom
spark-73/update-pagination-component
Nov 19, 2025
Merged

feat(pagination) - update pagination component to use new SHINE design system#2035
ttaylor-stack merged 34 commits into
betafrom
spark-73/update-pagination-component

Conversation

@ttaylor-stack

@ttaylor-stack ttaylor-stack commented Nov 4, 2025

Copy link
Copy Markdown
Collaborator

Story: https://stackoverflow.atlassian.net/browse/SPARK-73

Updated the pagination component in classic and svelte.

NOTE: I added a new assertion function in assertions.ts. The logic looks sound to me and the test is passing but could it be double checked to ensure its correct. cc @giamir

NOTE: Will need to update color of nav buttons to tonal once button changes are in

@changeset-bot

changeset-bot Bot commented Nov 4, 2025

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 02c6935

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@netlify

netlify Bot commented Nov 4, 2025

Copy link
Copy Markdown

Deploy Preview for stacks ready!

Name Link
🔨 Latest commit 02c6935
🔍 Latest deploy log https://app.netlify.com/projects/stacks/deploys/691cf89c93dceb0008854a3c
😎 Deploy Preview https://deploy-preview-2035--stacks.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify

netlify Bot commented Nov 4, 2025

Copy link
Copy Markdown

Deploy Preview for stacks-svelte ready!

Name Link
🔨 Latest commit 02c6935
🔍 Latest deploy log https://app.netlify.com/projects/stacks-svelte/deploys/691cf89c7429e2000826f58b
😎 Deploy Preview https://deploy-preview-2035--stacks-svelte.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@ttaylor-stack
ttaylor-stack marked this pull request as ready for review November 6, 2025 12:50
Comment thread packages/stacks-classic/lib/components/pagination/pagination.less Outdated
--_pa-item-bg-hover: #F0EFED;
--_pa-item-bc-hover: var(--bc-darker);
--_pa-item-fc-hover: var(--fc-dark);
--_pa-item-bb: var(--su-static0);

@dancormier dancormier Nov 6, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

--su-static0 doesn't exist so 0 should be used instead. That said, I noticed a layout shift related to this border width that can be addressed with a few tweaks.

20251106-044931

I suggest always having a bottom border on the pagination item where the color is set with one of these sort of custom properties. I'd suggest having the default color be transparent and and set to black* on the selected pagination item. with a consistent width around the pagination item to prevent layout shift.


* I'm not sure if this updated component is intended to get theme colors. I've asked a question on the figma here).

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.

Layout shift related to the focus state as well (shifts the number horizontally a bit). I think the focused state width is larger than non-focused width. I'd suggest adding some margin to non-focused state so it matches the same width — like an invisible container/box for each numbered item that's always ~20px and we remove the gutter spacing in between the items (spacing attaching to individual item itself.

Comment thread packages/stacks-classic/lib/components/pagination/pagination.less Outdated
Comment thread packages/stacks-classic/lib/components/pagination/pagination.less Outdated
@CGuindon

CGuindon commented Nov 7, 2025

Copy link
Copy Markdown
Collaborator

+1 to Dan's comments, will review again after those get resolved

},
};

const WCAGBoxShadowContrast: AdditionalAssertion = {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I am working on the Navigation component which have a similar way to highlight selected state but in there we won't be able to use the box shadow directly to the element. Instead we will likely need a pseudo element. All of this to say that it might be sensible to remove the check all together from this PR and have this code you created in a branch and linked to a new ticket with context. The assertion we have at the moment is too specific and should probably be generalized. If we cannot do it in a sensible way maybe even accept that it is not worth testing.

In a nutshell my recommendation would be to extract this in a new branch and create a related ticket for the backlog. Thanks @ttaylor-stack for experimenting with this. ❤️

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Thank you, I'll do that now

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This ticket has been created in the backlog https://stackoverflow.atlassian.net/browse/SPARK-110

@CGuindon CGuindon 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.

  1. The "Prev" should be replaced by an arrow button (like we do on the right side) but pointed left.
  2. The arrows for Prev/Next should use a button component and be styled with .s-btn .s-btn__filled .s-btn__muted. It will have the grey circle on default (not just hover like the numbers). (only an issue in Svelte not Classic)
Screenshot 2025-11-12 at 1 28 06 PM

@dancormier dancormier left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for your work here @ttaylor-stack. I have a few suggestions mostly around documentation and the "next"/"previous" buttons. Let me know if anything needs clarification or if you want to pair up on my suggestions.

background-color: var(--_pa-item-bg);
}
border-radius: var(--_pa-item-br);
box-shadow: var(--_pa-item-bs);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@giamir implemented a similar selected state for the navigation component that I think could be a more reliable approach.

Instead of using box-shadow, he's using a pseudo-element (:before) to achieve the bottom border. The implementation here would be slightly different. We'd want it to:

  • Be slightly outside the element (so top: 100% instead of bottom: 0)
  • Only apply when :not(:hover) and :not(focus-visible)
  • We shouldn't need any pseudo-private custom properties for this since the style shouldn't change with different variants/modifiers

Let me know if this needs clarification or if you want any feedback 🙂

Comment on lines +78 to +79
<a class="s-pagination--item s-pagination--item__nav" href="…">
{% icon "ArrowRight" %}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The descriptive text in span.v-visible-sr should be something like next page

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Since this new design includes custom styles for next/previous, I'd suggest including a "←" button in the example with a page between the first and last selected. Something like this:

image

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@CGuindon should we include an example with "15 / 30 / 50 items per page" like this?

image

Comment thread MIGRATION_GUIDE.md Outdated
Comment on lines +83 to +84
<Icon src={IconArrowLeft} title={i18nPrevText} />
<span class="v-visible-sr">{i18nPageText}</span>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Including both title on the icon and the screen reader span will result in some assistive tech reading out the contents of i18nPrevText twice. I'd recommend removing the span.

Comment on lines +107 to +108
<Icon src={IconArrowRight} title={i18nNextText} />
<span class="v-visible-sr">{i18nPageText}</span>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Same as the previous comment

Including both title on the icon and the screen reader span will result in some assistive tech reading out the contents of i18nPrevText twice. I'd recommend removing the span.

Comment on lines +36 to +49
// Only used for the button variant so we're making it generic for now
const getClasses = (selected: boolean, itemNav: boolean) => {
let classes = "s-pagination--item";
const base = classes;
if (selected) {
classes += ` is-selected`;
}
if (itemNav) {
classes += ` ${base}__nav`;
}
return classes;
};

const classes = $derived(getClasses(selected, itemNav));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If we remove the Button below, I think we could remove this function altogether and just rely on conditional classes on the anchor.

Comment on lines +27 to +75
<a
class="s-pagination--item"
class:is-selected={selected}
aria-current={selected ? "page" : undefined}
href={url}
{onclick}
>
{@render children?.()}
</a>
{#if itemNav}
<!-- Update variant from muted to tonal when button PR goes in-->
<Button
variant="muted"
weight="filled"
class={classes}
aria-current={selected ? "page" : undefined}
href={url}
{onclick}
>
{@render children?.()}
</Button>
{:else}
<a
class="s-pagination--item"
class:is-selected={selected}
aria-current={selected ? "page" : undefined}
href={url}
{onclick}
>
{@render children?.()}
</a>
{/if}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I don't think there's a need for the Button element here. We should be able to just use an anchor. We'd probably want to add class:s-pagination--item__nav={itemNav} to apply the nav class.

--_pa-item-bg-hover: var(--_pa-item-bg);
--_pa-item-fc-hover: var(--_pa-item-fc);
&.s-pagination--item__nav {
--_pa-item-bg: unset;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think this is because of #2035 (comment)

I'd set this as a psuedo private custom property with a value of unset at the top of the file and reset the value here to prevent cascade issues.

I was intending the base background color (line 11) to be set to unset and I now realize saying "reset the value here" is unclear. Sorry about that!

For the nav items, --_pa-item-bg should be set to --black-150.

Suggested change
--_pa-item-bg: unset;
--_pa-item-bg: var(--black-150);

@dancormier dancormier left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Great work @ttaylor-stack! I'm happy with where this landed 🙂

@ttaylor-stack
ttaylor-stack merged commit 0b1841d into beta Nov 19, 2025
18 checks passed
@ttaylor-stack
ttaylor-stack deleted the spark-73/update-pagination-component branch November 19, 2025 09:40
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.

4 participants