1
1
import React from 'react'
2
- import styled from 'styled-components'
3
2
import Box from '../Box'
4
- import { get } from '../constants'
5
- import type { SxProp } from '../sx'
6
- import sx from '../sx'
7
3
import { buildComponentData , buildPaginationModel , type PageDataProps } from './model'
8
4
import type { ResponsiveValue } from '../hooks/useResponsiveValue'
9
5
import { viewportRanges } from '../hooks/useResponsiveValue'
10
- import { toggleStyledComponent } from '../internal/utils/toggleStyledComponent'
11
- import { useFeatureFlag } from '../FeatureFlags'
12
6
import { clsx } from 'clsx'
13
7
import classes from './Pagination.module.css'
14
-
15
- const CSS_MODULES_FEATURE_FLAG = 'primer_react_css_modules_ga'
8
+ import { BoxWithFallback } from '../internal/components/BoxWithFallback'
16
9
17
10
const getViewportRangesToHidePages = ( showPages : PaginationProps [ 'showPages' ] ) => {
18
11
if ( showPages && typeof showPages !== 'boolean' ) {
@@ -28,124 +21,6 @@ const getViewportRangesToHidePages = (showPages: PaginationProps['showPages']) =
28
21
}
29
22
}
30
23
31
- const Page = toggleStyledComponent (
32
- CSS_MODULES_FEATURE_FLAG ,
33
- 'a' ,
34
- styled . a `
35
- display: inline-block;
36
- min-width: 32px; /* primer.control.medium.size */
37
- height: 32px; /* primer.control.medium.size */
38
- padding: 0.5rem calc((2rem - 1.25rem) / 2); /* primer.control.medium.paddingInline.condensed primer.control.medium.paddingBlock */
39
- font-style: normal;
40
- line-height: 1;
41
- color: ${ get ( 'colors.fg.default' ) } ;
42
- text-align: center;
43
- white-space: nowrap;
44
- vertical-align: middle;
45
- cursor: pointer;
46
- user-select: none;
47
- text-decoration: none;
48
-
49
- margin-right: ${ get ( 'space.1' ) } ;
50
-
51
- &:last-child {
52
- margin-right: 0;
53
- }
54
-
55
- background-color: transparent;
56
- border-radius: ${ get ( 'radii.2' ) } ;
57
- transition: background-color 0.2s cubic-bezier(0.3, 0, 0.5, 1);
58
-
59
- &:hover,
60
- &:focus {
61
- text-decoration: none;
62
- background-color: ${ get ( 'colors.actionListItem.default.hoverBg' ) } ;
63
- outline: 0;
64
- transition-duration: 0.1s;
65
- }
66
-
67
- &:focus-visible {
68
- outline: 2px solid ${ get ( 'colors.accent.emphasis' ) } ;
69
- outline-offset: -2px;
70
- }
71
-
72
- &:active {
73
- border-color: ${ get ( 'colors.border.muted' ) } ;
74
- }
75
-
76
- &[rel='prev'],
77
- &[rel='next'] {
78
- color: ${ get ( 'colors.accent.fg' ) } ;
79
- }
80
-
81
- &[aria-current],
82
- &[aria-current]:hover {
83
- color: ${ get ( 'colors.fg.onEmphasis' ) } ;
84
- background-color: ${ get ( 'colors.accent.emphasis' ) } ;
85
- border-color: transparent;
86
- }
87
-
88
- &[aria-current]:focus-visible {
89
- outline: 2px solid ${ get ( 'colors.accent.emphasis' ) } ;
90
- outline-offset: -2px;
91
- box-shadow: inset 0 0 0 3px ${ get ( 'colors.fg.onEmphasis' ) } ;
92
- }
93
-
94
- &[aria-hidden],
95
- &[aria-hidden]:hover,
96
- &[role='presentation'],
97
- &[role='presentation']:hover {
98
- color: ${ get ( 'colors.primer.fg.disabled' ) } ; // check
99
- cursor: default;
100
- background-color: transparent;
101
- }
102
-
103
- @supports (clip-path: polygon(50% 0, 100% 50%, 50% 100%)) {
104
- &[rel='prev']::before,
105
- &[rel='next']::after {
106
- display: inline-block;
107
- width: 16px;
108
- height: 16px;
109
- vertical-align: text-bottom;
110
- content: '';
111
- background-color: currentColor;
112
- }
113
-
114
- // chevron-left
115
- &[rel='prev']::before {
116
- margin-right: ${ get ( 'space.1' ) } ;
117
- clip-path: polygon(
118
- 9.8px 12.8px,
119
- 8.7px 12.8px,
120
- 4.5px 8.5px,
121
- 4.5px 7.5px,
122
- 8.7px 3.2px,
123
- 9.8px 4.3px,
124
- 6.1px 8px,
125
- 9.8px 11.7px,
126
- 9.8px 12.8px
127
- );
128
- }
129
-
130
- // chevron-right
131
- &[rel='next']::after {
132
- margin-left: ${ get ( 'space.1' ) } ;
133
- clip-path: polygon(
134
- 6.2px 3.2px,
135
- 7.3px 3.2px,
136
- 11.5px 7.5px,
137
- 11.5px 8.5px,
138
- 7.3px 12.8px,
139
- 6.2px 11.7px,
140
- 9.9px 8px,
141
- 6.2px 4.3px,
142
- 6.2px 3.2px
143
- );
144
- }
145
- }
146
- ` ,
147
- )
148
-
149
24
export type PageProps = {
150
25
/* Unique key for the page number */
151
26
key : string
@@ -182,8 +57,6 @@ function usePaginationPages({
182
57
} : UsePaginationPagesParameters ) {
183
58
const pageChange = React . useCallback ( ( n : number ) => ( e : React . MouseEvent ) => onPageChange ( e , n ) , [ onPageChange ] )
184
59
185
- const enabled = useFeatureFlag ( CSS_MODULES_FEATURE_FLAG )
186
-
187
60
const model = React . useMemo ( ( ) => {
188
61
return buildPaginationModel ( pageCount , currentPage , ! ! showPages , marginPageCount , surroundingPageCount )
189
62
} , [ pageCount , currentPage , showPages , marginPageCount , surroundingPageCount ] )
@@ -196,52 +69,19 @@ function usePaginationPages({
196
69
}
197
70
198
71
return (
199
- < Page { ...props } key = { key } theme = { theme } className = { clsx ( enabled && classes . Page ) } >
72
+ // @ts -ignore giving me grief about children and "as" props
73
+ < BoxWithFallback as = "a" key = { key } theme = { theme } className = { clsx ( classes . Page ) } { ...props } >
200
74
{ content }
201
- </ Page >
75
+ </ BoxWithFallback >
202
76
)
203
77
} )
204
- } , [ model , hrefBuilder , pageChange , renderPage , theme , enabled ] )
78
+ } , [ model , hrefBuilder , pageChange , renderPage , theme ] )
205
79
206
80
return children
207
81
}
208
82
209
- const PaginationContainer = toggleStyledComponent (
210
- CSS_MODULES_FEATURE_FLAG ,
211
- 'nav' ,
212
- styled . nav < SxProp > `
213
- margin-top: 20px;
214
- margin-bottom: 15px;
215
- text-align: center;
216
-
217
- ${
218
- // Hides pages based on the viewport range passed to `showPages`
219
- Object . keys ( viewportRanges )
220
- . map ( viewportRangeKey => {
221
- return `
222
- @media (${ viewportRanges [ viewportRangeKey as keyof typeof viewportRanges ] } ) {
223
- .TablePaginationSteps[data-hidden-viewport-ranges*='${ viewportRangeKey } '] > *:not(:first-child):not(:last-child) {
224
- display: none;
225
- }
226
-
227
- .TablePaginationSteps[data-hidden-viewport-ranges*='${ viewportRangeKey } '] > *:first-child {
228
- margin-inline-end: 0;
229
- }
230
-
231
- .TablePaginationSteps[data-hidden-viewport-ranges*='${ viewportRangeKey } '] > *:last-child {
232
- margin-inline-start: 0;
233
- }
234
- }
235
- `
236
- } )
237
- . join ( '' )
238
- }
239
-
240
- ${ sx } ;
241
- ` ,
242
- )
243
-
244
83
export type PaginationProps = {
84
+ className ?: string
245
85
theme ?: Record < string , unknown >
246
86
pageCount : number
247
87
currentPage : number
@@ -254,7 +94,8 @@ export type PaginationProps = {
254
94
}
255
95
256
96
function Pagination ( {
257
- theme,
97
+ className,
98
+ theme : _theme ,
258
99
pageCount,
259
100
currentPage,
260
101
onPageChange = noop ,
@@ -266,7 +107,7 @@ function Pagination({
266
107
...rest
267
108
} : PaginationProps ) {
268
109
const pageElements = usePaginationPages ( {
269
- theme,
110
+ theme : _theme ,
270
111
pageCount,
271
112
currentPage,
272
113
onPageChange,
@@ -277,24 +118,21 @@ function Pagination({
277
118
renderPage,
278
119
} )
279
120
280
- const enabled = useFeatureFlag ( CSS_MODULES_FEATURE_FLAG )
281
-
282
121
return (
283
- < PaginationContainer
284
- className = { clsx ( enabled && classes . PaginationContainer ) }
122
+ < BoxWithFallback
123
+ as = "nav"
124
+ className = { clsx ( classes . PaginationContainer , className ) }
285
125
aria-label = "Pagination"
286
126
{ ...rest }
287
- theme = { theme }
288
127
>
289
128
< Box
290
129
display = "inline-block"
291
- theme = { theme }
292
130
className = { classes . TablePaginationSteps }
293
131
data-hidden-viewport-ranges = { getViewportRangesToHidePages ( showPages ) . join ( ' ' ) }
294
132
>
295
133
{ pageElements }
296
134
</ Box >
297
- </ PaginationContainer >
135
+ </ BoxWithFallback >
298
136
)
299
137
}
300
138
0 commit comments