Skip to content

Commit 3f3c1ad

Browse files
jonrohanjoshblackprimer[bot]
authored andcommitted
chore(DataTable.Pagination): Convert DataTable.Pagination to CSS modules (#6273)
Co-authored-by: Josh Black <[email protected]> Co-authored-by: primer[bot] <119360173+primer[bot]@users.noreply.github.com>
1 parent d33ef5e commit 3f3c1ad

File tree

5 files changed

+185
-154
lines changed

5 files changed

+185
-154
lines changed

.changeset/polite-pandas-tie.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@primer/react": minor
3+
---
4+
5+
chore(DataTable.Pagination): Convert DataTable.Pagination to CSS modules
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
.TablePagination {
2+
display: flex;
3+
align-items: center;
4+
justify-content: space-between;
5+
column-gap: 1rem;
6+
width: 100%;
7+
grid-area: footer;
8+
padding: var(--base-size-8) var(--base-size-16);
9+
border: var(--borderWidth-thin) solid var(--borderColor-default);
10+
border-top-width: 0;
11+
border-end-start-radius: var(--borderRadius-medium);
12+
border-end-end-radius: var(--borderRadius-medium);
13+
}
14+
15+
@media ((max-width: calc(768px - 0.02px))) {
16+
.TablePaginationSteps[data-hidden-viewport-ranges*='narrow'] > *:not(:first-child):not(:last-child) {
17+
display: none;
18+
}
19+
20+
.TablePaginationSteps[data-hidden-viewport-ranges*='narrow'] > *:first-child {
21+
margin-inline-end: 0;
22+
}
23+
24+
.TablePaginationSteps[data-hidden-viewport-ranges*='narrow'] > *:last-child {
25+
margin-inline-start: 0;
26+
}
27+
}
28+
29+
@media ((min-width: 768px)) {
30+
.TablePaginationSteps[data-hidden-viewport-ranges*='regular'] > *:not(:first-child):not(:last-child) {
31+
display: none;
32+
}
33+
34+
.TablePaginationSteps[data-hidden-viewport-ranges*='regular'] > *:first-child {
35+
margin-inline-end: 0;
36+
}
37+
38+
.TablePaginationSteps[data-hidden-viewport-ranges*='regular'] > *:last-child {
39+
margin-inline-start: 0;
40+
}
41+
}
42+
43+
@media ((min-width: 1400px)) {
44+
.TablePaginationSteps[data-hidden-viewport-ranges*='wide'] > *:not(:first-child):not(:last-child) {
45+
display: none;
46+
}
47+
48+
.TablePaginationSteps[data-hidden-viewport-ranges*='wide'] > *:first-child {
49+
margin-inline-end: 0;
50+
}
51+
52+
.TablePaginationSteps[data-hidden-viewport-ranges*='wide'] > *:last-child {
53+
margin-inline-start: 0;
54+
}
55+
}
56+
57+
.TablePaginationRange {
58+
color: var(--fgColor-muted);
59+
font-size: var(--text-body-size-small);
60+
margin: 0;
61+
}
62+
63+
.TablePaginationSteps {
64+
display: flex;
65+
align-items: center;
66+
flex-wrap: wrap;
67+
list-style: none;
68+
color: var(--fgColor-default);
69+
font-size: var(--text-body-size-medium);
70+
margin: 0;
71+
padding: 0;
72+
}
73+
74+
.TablePaginationStep:first-of-type {
75+
margin-right: var(--base-size-16);
76+
}
77+
78+
.TablePaginationStep:last-of-type {
79+
margin-left: var(--base-size-16);
80+
}
81+
82+
.TablePaginationAction {
83+
display: flex;
84+
align-items: center;
85+
color: var(--fgColor-muted);
86+
font-size: var(--text-body-size-medium);
87+
/* stylelint-disable-next-line primer/typography */
88+
line-height: calc(20 / 14);
89+
user-select: none;
90+
padding: var(--base-size-8);
91+
border-radius: var(--borderRadius-medium);
92+
}
93+
94+
.TablePaginationAction[data-has-page] {
95+
color: var(--fgColor-accent);
96+
}
97+
98+
.TablePaginationPage {
99+
min-width: 2rem;
100+
min-height: 2rem;
101+
display: flex;
102+
align-items: center;
103+
justify-content: center;
104+
font-size: var(--text-body-size-medium);
105+
/* stylelint-disable-next-line primer/typography */
106+
line-height: calc(20 / 14);
107+
user-select: none;
108+
border-radius: var(--borderRadius-medium);
109+
padding: var(--base-size-8) calc((var(--base-size-32) - var(--base-size-20)) / 2); /* primer.control.medium.paddingInline.condensed primer.control.medium.paddingBlock */
110+
}
111+
112+
.TablePaginationAction[data-has-page]:hover,
113+
.TablePaginationAction[data-has-page]:focus,
114+
.TablePaginationPage:hover,
115+
.TablePaginationPage:focus {
116+
background-color: var(--control-transparent-bgColor-hover);
117+
}
118+
119+
.TablePaginationPage[data-active='true'] {
120+
background-color: var(--bgColor-accent-emphasis);
121+
color: var(--fgColor-onEmphasis);
122+
}
123+
124+
.TablePaginationPage[data-active='true']:focus-visible {
125+
outline: 2px solid var(--bgColor-accent-emphasis);
126+
outline-offset: -2px;
127+
/* stylelint-disable-next-line primer/box-shadow */
128+
box-shadow: inset 0 0 0 3px var(--fgColor-onEmphasis);
129+
}
130+
131+
.TablePaginationTruncationStep {
132+
display: flex;
133+
align-items: center;
134+
justify-content: center;
135+
min-width: 2rem;
136+
min-height: 2rem;
137+
user-select: none;
138+
}

packages/react/src/DataTable/Pagination.tsx

Lines changed: 16 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -1,132 +1,15 @@
11
import {ChevronLeftIcon, ChevronRightIcon} from '@primer/octicons-react'
22
import type React from 'react'
33
import {useCallback, useMemo, useState} from 'react'
4-
import styled from 'styled-components'
5-
import {get} from '../constants'
64
import {Button} from '../internal/components/ButtonReset'
75
import {LiveRegion, LiveRegionOutlet, Message} from '../internal/components/LiveRegion'
86
import {VisuallyHidden} from '../VisuallyHidden'
97
import {warning} from '../utils/warning'
108
import type {ResponsiveValue} from '../hooks/useResponsiveValue'
119
import {viewportRanges} from '../hooks/useResponsiveValue'
1210
import {buildPaginationModel} from '../Pagination/model'
13-
14-
const StyledPagination = styled.nav`
15-
display: flex;
16-
align-items: center;
17-
justify-content: space-between;
18-
column-gap: 1rem;
19-
width: 100%;
20-
grid-area: footer;
21-
padding: 0.5rem 1rem;
22-
border: 1px solid ${get('colors.border.default')};
23-
border-top-width: 0;
24-
border-end-start-radius: 6px;
25-
border-end-end-radius: 6px;
26-
27-
.TablePaginationRange {
28-
color: ${get('colors.fg.muted')};
29-
font-size: 0.75rem;
30-
margin: 0;
31-
}
32-
33-
.TablePaginationSteps {
34-
display: flex;
35-
align-items: center;
36-
flex-wrap: wrap;
37-
list-style: none;
38-
color: ${get('colors.fg.default')};
39-
font-size: 0.875rem;
40-
margin: 0;
41-
padding: 0;
42-
}
43-
44-
.TablePaginationStep:first-of-type {
45-
margin-right: 1rem;
46-
}
47-
48-
.TablePaginationStep:last-of-type {
49-
margin-left: 1rem;
50-
}
51-
52-
.TablePaginationAction {
53-
display: flex;
54-
align-items: center;
55-
color: ${get('colors.fg.muted')};
56-
font-size: 0.875rem;
57-
line-height: calc(20 / 14);
58-
user-select: none;
59-
padding: 0.5rem;
60-
border-radius: 6px;
61-
}
62-
63-
.TablePaginationAction[data-has-page] {
64-
color: ${get('colors.accent.fg')};
65-
}
66-
67-
.TablePaginationPage {
68-
min-width: 2rem;
69-
min-height: 2rem;
70-
display: flex;
71-
align-items: center;
72-
justify-content: center;
73-
font-size: 0.875rem;
74-
line-height: calc(20 / 14);
75-
user-select: none;
76-
border-radius: 6px;
77-
padding: 0.5rem calc((2rem - 1.25rem) / 2); /* primer.control.medium.paddingInline.condensed primer.control.medium.paddingBlock */
78-
}
79-
80-
.TablePaginationAction[data-has-page]:hover,
81-
.TablePaginationAction[data-has-page]:focus,
82-
.TablePaginationPage:hover,
83-
.TablePaginationPage:focus {
84-
background-color: ${get('colors.actionListItem.default.hoverBg')};
85-
}
86-
87-
.TablePaginationPage[data-active='true'] {
88-
background-color: ${get('colors.accent.emphasis')};
89-
color: ${get('colors.fg.onEmphasis')};
90-
}
91-
92-
.TablePaginationPage[data-active='true']:focus-visible {
93-
outline: 2px solid var(--bgColor-accent-emphasis);
94-
outline-offset: -2px;
95-
box-shadow: inset 0 0 0 3px var(--fgColor-onEmphasis);
96-
}
97-
98-
.TablePaginationTruncationStep {
99-
display: flex;
100-
align-items: center;
101-
justify-content: center;
102-
min-width: 2rem;
103-
min-height: 2rem;
104-
user-select: none;
105-
}
106-
107-
${
108-
// Hides pages based on the viewport range passed to `showPages`
109-
Object.keys(viewportRanges)
110-
.map(viewportRangeKey => {
111-
return `
112-
@media (${viewportRanges[viewportRangeKey as keyof typeof viewportRanges]}) {
113-
.TablePaginationSteps[data-hidden-viewport-ranges*='${viewportRangeKey}'] > *:not(:first-child):not(:last-child) {
114-
display: none;
115-
}
116-
117-
.TablePaginationSteps[data-hidden-viewport-ranges*='${viewportRangeKey}'] > *:first-child {
118-
margin-inline-end: 0;
119-
}
120-
121-
.TablePaginationSteps[data-hidden-viewport-ranges*='${viewportRangeKey}'] > *:last-child {
122-
margin-inline-start: 0;
123-
}
124-
}
125-
`
126-
})
127-
.join('')
128-
}
129-
`
11+
import classes from './Pagination.module.css'
12+
import {clsx} from 'clsx'
13013

13114
export type PaginationProps = Omit<React.ComponentPropsWithoutRef<'nav'>, 'onChange'> & {
13215
/**
@@ -218,12 +101,15 @@ export function Pagination({
218101
return (
219102
<LiveRegion>
220103
<LiveRegionOutlet />
221-
<StyledPagination aria-label={label} className="TablePagination" id={id}>
104+
<nav aria-label={label} className={clsx('TablePagination', classes.TablePagination)} id={id}>
222105
<Range pageStart={pageStart} pageEnd={pageEnd} totalCount={totalCount} />
223-
<ol className="TablePaginationSteps" data-hidden-viewport-ranges={getViewportRangesToHidePages().join(' ')}>
106+
<ol
107+
className={clsx('TablePaginationSteps', classes.TablePaginationSteps)}
108+
data-hidden-viewport-ranges={getViewportRangesToHidePages().join(' ')}
109+
>
224110
<Step>
225111
<Button
226-
className="TablePaginationAction"
112+
className={clsx('TablePaginationAction', classes.TablePaginationAction)}
227113
type="button"
228114
data-has-page={hasPreviousPage ? true : undefined}
229115
aria-disabled={!hasPreviousPage ? true : undefined}
@@ -235,7 +121,7 @@ export function Pagination({
235121
}}
236122
>
237123
{hasPreviousPage ? <ChevronLeftIcon /> : null}
238-
<span className="TablePaginationActionLabel">Previous</span>
124+
<span>Previous</span>
239125
<VisuallyHidden>&nbsp;page</VisuallyHidden>
240126
</Button>
241127
</Step>
@@ -260,7 +146,7 @@ export function Pagination({
260146
})}
261147
<Step>
262148
<Button
263-
className="TablePaginationAction"
149+
className={clsx('TablePaginationAction', classes.TablePaginationAction)}
264150
type="button"
265151
data-has-page={hasNextPage ? true : undefined}
266152
aria-disabled={!hasNextPage ? true : undefined}
@@ -271,13 +157,13 @@ export function Pagination({
271157
selectNextPage()
272158
}}
273159
>
274-
<span className="TablePaginationActionLabel">Next</span>
160+
<span>Next</span>
275161
<VisuallyHidden>&nbsp;page</VisuallyHidden>
276162
{hasNextPage ? <ChevronRightIcon /> : null}
277163
</Button>
278164
</Step>
279165
</ol>
280-
</StyledPagination>
166+
</nav>
281167
</LiveRegion>
282168
)
283169
}
@@ -294,7 +180,7 @@ function Range({pageStart, pageEnd, totalCount}: RangeProps) {
294180
return (
295181
<>
296182
<Message value={`Showing ${start} through ${end} of ${totalCount}`} />
297-
<p className="TablePaginationRange">
183+
<p className={clsx('TablePaginationRange', classes.TablePaginationRange)}>
298184
{start}
299185
<VisuallyHidden>&nbsp;through&nbsp;</VisuallyHidden>
300186
<span aria-hidden="true"></span>
@@ -306,14 +192,14 @@ function Range({pageStart, pageEnd, totalCount}: RangeProps) {
306192

307193
function TruncationStep() {
308194
return (
309-
<li aria-hidden="true" className="TablePaginationTruncationStep">
195+
<li aria-hidden="true" className={clsx('TablePaginationTruncationStep', classes.TablePaginationTruncationStep)}>
310196
311197
</li>
312198
)
313199
}
314200

315201
function Step({children}: React.PropsWithChildren) {
316-
return <li className="TablePaginationStep">{children}</li>
202+
return <li className={clsx('TablePaginationStep', classes.TablePaginationStep)}>{children}</li>
317203
}
318204

319205
type PageProps = React.PropsWithChildren<{
@@ -324,7 +210,7 @@ type PageProps = React.PropsWithChildren<{
324210
function Page({active, children, onClick}: PageProps) {
325211
return (
326212
<Button
327-
className="TablePaginationPage"
213+
className={clsx('TablePaginationPage', classes.TablePaginationPage)}
328214
type="button"
329215
data-active={active ? true : undefined}
330216
aria-current={active ? true : undefined}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
.ButtonReset {
2+
margin: 0;
3+
display: inline-flex;
4+
padding: 0;
5+
border: 0;
6+
appearance: none;
7+
background: none;
8+
cursor: pointer;
9+
text-align: start;
10+
font: inherit;
11+
color: inherit;
12+
align-items: center;
13+
14+
&::-moz-focus-inner {
15+
border: 0;
16+
}
17+
}

0 commit comments

Comments
 (0)