@zendeskgarden/react-pagination 9.0.0-next.1 → 9.0.0-next.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -18,7 +18,7 @@ npm install react react-dom styled-components @zendeskgarden/react-theming
18
18
 
19
19
  ```jsx
20
20
  import { ThemeProvider } from '@zendeskgarden/react-theming';
21
- import { Pagination } from '@zendeskgarden/react-pagination';
21
+ import { OffsetPagination } from '@zendeskgarden/react-pagination';
22
22
 
23
23
  initialState = {
24
24
  currentPage: 1
@@ -28,7 +28,7 @@ initialState = {
28
28
  * Place a `ThemeProvider` at the root of your React application
29
29
  */
30
30
  <ThemeProvider>
31
- <Pagination
31
+ <OffsetPagination
32
32
  totalPages={11}
33
33
  currentPage={state.currentPage}
34
34
  onChange={currentPage => setState({ currentPage })}
package/dist/index.cjs.js CHANGED
@@ -9,10 +9,9 @@
9
9
 
10
10
  var React = require('react');
11
11
  var PropTypes = require('prop-types');
12
- var styled = require('styled-components');
13
- var containerPagination = require('@zendeskgarden/container-pagination');
14
12
  var containerUtilities = require('@zendeskgarden/container-utilities');
15
13
  var reactTheming = require('@zendeskgarden/react-theming');
14
+ var styled = require('styled-components');
16
15
  var polished = require('polished');
17
16
 
18
17
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
@@ -54,19 +53,31 @@ function _extends$4() {
54
53
  return _extends$4.apply(this, arguments);
55
54
  }
56
55
 
57
- const COMPONENT_ID$6 = 'pagination.pagination_view';
58
- const StyledPagination = styled__default.default.ul.attrs({
59
- 'data-garden-id': COMPONENT_ID$6,
60
- 'data-garden-version': '9.0.0-next.1'
56
+ const COMPONENT_ID$8 = 'pagination.list';
57
+ const StyledList = styled__default.default.ul.attrs({
58
+ 'data-garden-id': COMPONENT_ID$8,
59
+ 'data-garden-version': '9.0.0-next.3'
61
60
  }).withConfig({
62
- displayName: "StyledPagination",
63
- componentId: "sc-1b7nye9-0"
64
- })(["direction:", ";display:flex;justify-content:center;margin:0;padding:0;white-space:nowrap;color:", ";:focus{outline:none;}", ";"], props => props.theme.rtl && 'rtl', props => reactTheming.getColor('neutralHue', 600, props.theme), props => reactTheming.retrieveComponentStyles(COMPONENT_ID$6, props));
65
- StyledPagination.defaultProps = {
61
+ displayName: "StyledList",
62
+ componentId: "sc-1uz2jxo-0"
63
+ })(["direction:", ";display:flex;justify-content:center;margin:0;padding:0;list-style:none;white-space:nowrap;color:", ";:focus{outline:none;}", ";"], props => props.theme.rtl && 'rtl', props => reactTheming.getColor('neutralHue', 600, props.theme), props => reactTheming.retrieveComponentStyles(COMPONENT_ID$8, props));
64
+ StyledList.defaultProps = {
66
65
  theme: reactTheming.DEFAULT_THEME
67
66
  };
68
67
 
69
- const COMPONENT_ID$5 = 'pagination.page';
68
+ const COMPONENT_ID$7 = 'pagination.list_item';
69
+ const StyledListItem = styled__default.default.li.attrs({
70
+ 'data-garden-id': COMPONENT_ID$7,
71
+ 'data-garden-version': '9.0.0-next.3'
72
+ }).withConfig({
73
+ displayName: "StyledListItem",
74
+ componentId: "sc-16j4sju-0"
75
+ })(["box-sizing:border-box;margin-left:", ";user-select:none;&", "{margin-left:0;}", ";"], props => `${props.theme.space.base}px`, props => props.theme.rtl ? ':last-of-type' : ':first-of-type', props => reactTheming.retrieveComponentStyles(COMPONENT_ID$7, props));
76
+ StyledListItem.defaultProps = {
77
+ theme: reactTheming.DEFAULT_THEME
78
+ };
79
+
80
+ const COMPONENT_ID$6 = 'pagination.page';
70
81
  const colorStyles = props => {
71
82
  const defaultColor = reactTheming.getColor('neutralHue', 600, props.theme);
72
83
  const hoverForegroundColor = reactTheming.getColor('neutralHue', 700, props.theme);
@@ -77,7 +88,7 @@ const colorStyles = props => {
77
88
  const currentBackgroundColor = hoverBackgroundColor;
78
89
  const currentHoverBackgroundColor = reactTheming.getColor('primaryHue', 600, props.theme, 0.16);
79
90
  const currentActiveBackgroundColor = reactTheming.getColor('primaryHue', 600, props.theme, 0.28);
80
- return styled.css(["color:", ";&:hover{background-color:", ";color:", ";}", " &:active,&:focus-visible:active,&[data-garden-focus-visible]:active{background-color:", ";color:", ";}&[aria-current='true']{background-color:", ";color:", ";}&[aria-current='true']:hover{background-color:", ";}&[aria-current='true']:active{background-color:", ";}:disabled,[aria-disabled='true']{background-color:transparent;color:", ";}"], defaultColor, hoverBackgroundColor, hoverForegroundColor, reactTheming.focusStyles({
91
+ return styled.css(["border:none;background:transparent;color:", ";&:hover{background-color:", ";color:", ";}", " &:active,&:focus-visible:active,&[data-garden-focus-visible]:active{background-color:", ";color:", ";}&[aria-current='page']{background-color:", ";color:", ";}&[aria-current='page']:hover{background-color:", ";}&[aria-current='page']:active{background-color:", ";}:disabled,[aria-disabled='true']{background-color:transparent;color:", ";}"], defaultColor, hoverBackgroundColor, hoverForegroundColor, reactTheming.focusStyles({
81
92
  theme: props.theme,
82
93
  inset: true
83
94
  }), activeBackgroundColor, activeForegroundColor, currentBackgroundColor, currentForegroundColor, currentHoverBackgroundColor, currentActiveBackgroundColor, reactTheming.getColor('grey', 300, props.theme));
@@ -89,54 +100,54 @@ const sizeStyles$2 = props => {
89
100
  const padding = `${props.theme.space.base * 1.5}px`;
90
101
  return styled.css(["padding:0 ", ";height:", ";line-height:", ";font-size:", ";"], padding, height, lineHeight, fontSize);
91
102
  };
92
- const StyledPageBase = styled__default.default.li.attrs({
93
- 'data-garden-id': COMPONENT_ID$5,
94
- 'data-garden-version': '9.0.0-next.1'
103
+ const StyledPageBase = styled__default.default.button.attrs({
104
+ 'data-garden-id': COMPONENT_ID$6,
105
+ 'data-garden-version': '9.0.0-next.3'
95
106
  }).withConfig({
96
107
  displayName: "StyledPageBase",
97
- componentId: "sc-lw1w9j-0"
98
- })(["box-sizing:border-box;display:inline-block;transition:box-shadow 0.1s ease-in-out,background-color 0.25s ease-in-out,color 0.25s ease-in-out;visibility:", ";border-radius:", ";cursor:pointer;overflow:hidden;text-align:center;text-overflow:ellipsis;user-select:none;", ";&[aria-current='true']{font-weight:", ";}:disabled,[aria-disabled='true']{cursor:default;}", ";", ";"], props => props.hidden && 'hidden', props => props.theme.borderRadii.md, props => sizeStyles$2(props), props => props.theme.fontWeights.semibold, props => colorStyles(props), props => reactTheming.retrieveComponentStyles(COMPONENT_ID$5, props));
108
+ componentId: "sc-ttwj4u-0"
109
+ })(["box-sizing:border-box;display:inline-block;transition:box-shadow 0.1s ease-in-out,background-color 0.25s ease-in-out,color 0.25s ease-in-out;visibility:", ";border-radius:", ";cursor:pointer;overflow:hidden;text-align:center;text-overflow:ellipsis;font-family:inherit;user-select:none;", ";&[aria-current='page']{font-weight:", ";}&::-moz-focus-inner{border:0;}:disabled,[aria-disabled='true']{cursor:default;}", ";", ";"], props => props.hidden && 'hidden', props => props.theme.borderRadii.md, props => sizeStyles$2(props), props => props.theme.fontWeights.semibold, props => colorStyles(props), props => reactTheming.retrieveComponentStyles(COMPONENT_ID$6, props));
99
110
  StyledPageBase.defaultProps = {
100
111
  theme: reactTheming.DEFAULT_THEME
101
112
  };
102
113
 
103
- const COMPONENT_ID$4 = 'pagination.page';
114
+ const COMPONENT_ID$5 = 'pagination.page';
104
115
  const sizeStyles$1 = props => {
105
- const height = `${props.theme.space.base * 8}px`;
106
- return styled.css(["min-width:", ";max-width:", ";&[aria-current='true']{max-width:none;}"], height, polished.math(`${height} * 2`));
116
+ const height = props.theme.space.base * 8;
117
+ return styled.css(["min-width:", "px;max-width:", "px;&[aria-current='true']{max-width:none;}"], height, height * 2);
107
118
  };
108
119
  const StyledPage = styled__default.default(StyledPageBase).attrs({
109
- 'data-garden-id': COMPONENT_ID$4,
110
- 'data-garden-version': '9.0.0-next.1'
120
+ 'data-garden-id': COMPONENT_ID$5,
121
+ 'data-garden-version': '9.0.0-next.3'
111
122
  }).withConfig({
112
123
  displayName: "StyledPage",
113
- componentId: "sc-1k0een3-0"
114
- })(["margin-left:", ";", ";&[aria-current=\"true\"]{font-weight:", ";}&", "{margin-left:0;}", ";"], props => `${props.theme.space.base}px`, props => sizeStyles$1(props), props => props.theme.fontWeights.semibold, props => props.theme.rtl ? ':last-of-type' : ':first-of-type', props => reactTheming.retrieveComponentStyles(COMPONENT_ID$4, props));
124
+ componentId: "sc-sxjfwy-0"
125
+ })(["", ";&[aria-current=\"true\"]{font-weight:", ";}", ";"], props => sizeStyles$1(props), props => props.theme.fontWeights.semibold, props => reactTheming.retrieveComponentStyles(COMPONENT_ID$5, props));
115
126
  StyledPage.defaultProps = {
116
127
  theme: reactTheming.DEFAULT_THEME
117
128
  };
118
129
 
119
- const COMPONENT_ID$3 = 'cursor_pagination';
130
+ const COMPONENT_ID$4 = 'cursor_pagination';
120
131
  const StyledCursorPagination = styled__default.default.nav.attrs({
121
- 'data-garden-id': COMPONENT_ID$3,
122
- 'data-garden-version': '9.0.0-next.1'
132
+ 'data-garden-id': COMPONENT_ID$4,
133
+ 'data-garden-version': '9.0.0-next.3'
123
134
  }).withConfig({
124
135
  displayName: "StyledCursorPagination",
125
136
  componentId: "sc-qmfecg-0"
126
- })(["display:flex;justify-content:center;", ";"], props => reactTheming.retrieveComponentStyles(COMPONENT_ID$3, props));
137
+ })(["display:flex;justify-content:center;", ";"], props => reactTheming.retrieveComponentStyles(COMPONENT_ID$4, props));
127
138
  StyledCursorPagination.defaultProps = {
128
139
  theme: reactTheming.DEFAULT_THEME
129
140
  };
130
141
 
131
- const COMPONENT_ID$2 = 'cursor_pagination.cursor';
142
+ const COMPONENT_ID$3 = 'cursor_pagination.cursor';
132
143
  const StyledCursor = styled__default.default(StyledPageBase).attrs({
133
- 'data-garden-id': COMPONENT_ID$2,
134
- 'data-garden-version': '9.0.0-next.1',
144
+ 'data-garden-id': COMPONENT_ID$3,
145
+ 'data-garden-version': '9.0.0-next.3',
135
146
  as: 'button'
136
147
  }).withConfig({
137
148
  displayName: "StyledCursor",
138
149
  componentId: "sc-507ee-0"
139
- })(["display:flex;align-items:center;border:none;background:transparent;padding:", ";overflow:visible;&:not(", "-of-type){margin-right:", "px;}", ";"], props => `0px ${props.theme.space.base * 2}px`, props => props.theme.rtl ? ':first' : ':last', props => props.theme.space.base, props => reactTheming.retrieveComponentStyles(COMPONENT_ID$2, props));
150
+ })(["display:flex;align-items:center;border:none;background:transparent;padding:", ";overflow:visible;&:not(", "-of-type){margin-right:", "px;}", ";"], props => `0px ${props.theme.space.base * 2}px`, props => props.theme.rtl ? ':first' : ':last', props => props.theme.space.base, props => reactTheming.retrieveComponentStyles(COMPONENT_ID$3, props));
140
151
  StyledCursor.defaultProps = {
141
152
  theme: reactTheming.DEFAULT_THEME
142
153
  };
@@ -166,36 +177,50 @@ StyledIcon.defaultProps = {
166
177
  theme: reactTheming.DEFAULT_THEME
167
178
  };
168
179
 
169
- const COMPONENT_ID$1 = 'pagination.gap';
180
+ const COMPONENT_ID$2 = 'pagination.gap';
170
181
  const sizeStyles = props => {
171
182
  const shift = 2;
172
- const marginTop = `-${shift}px`;
173
183
  const fontSize = polished.math(`${props.theme.fontSizes.md} + ${shift}`);
174
- return styled.css(["margin-top:", ";font-size:", ";"], marginTop, fontSize);
184
+ const height = `${props.theme.space.base * 8}px`;
185
+ const lineHeight = reactTheming.getLineHeight(height, fontSize);
186
+ const padding = `${props.theme.space.base * 1.5}px`;
187
+ return styled.css(["padding:0 ", ";min-width:", ";max-width:", ";height:", ";line-height:", ";font-size:", ";"], padding, height, polished.math(`${height} * 2`), height, lineHeight, fontSize);
175
188
  };
176
- const StyledGap = styled__default.default(StyledPage).attrs({
177
- 'data-garden-id': COMPONENT_ID$1,
178
- 'data-garden-version': '9.0.0-next.1'
189
+ const StyledGapListItem = styled__default.default(StyledListItem).attrs({
190
+ 'data-garden-id': COMPONENT_ID$2,
191
+ 'data-garden-version': '9.0.0-next.3'
179
192
  }).withConfig({
180
- displayName: "StyledGap",
181
- componentId: "sc-1hqjltf-0"
182
- })(["cursor:default;", ";&:hover{background-color:transparent;color:inherit;}", ";"], props => sizeStyles(props), props => reactTheming.retrieveComponentStyles(COMPONENT_ID$1, props));
183
- StyledGap.defaultProps = {
193
+ displayName: "StyledGapListItem",
194
+ componentId: "sc-10wd0iz-0"
195
+ })(["display:inline-block;text-align:center;color:", ";", ";&:hover{color:inherit;}", ";"], p => reactTheming.getColor('neutralHue', 600, p.theme), props => sizeStyles(props), props => reactTheming.retrieveComponentStyles(COMPONENT_ID$2, props));
196
+ StyledGapListItem.defaultProps = {
184
197
  theme: reactTheming.DEFAULT_THEME
185
198
  };
186
199
 
187
- const COMPONENT_ID = 'pagination.navigation';
200
+ const COMPONENT_ID$1 = 'pagination.navigation';
188
201
  const StyledNavigation = styled__default.default(StyledPage).attrs({
189
- 'data-garden-id': COMPONENT_ID,
190
- 'data-garden-version': '9.0.0-next.1'
202
+ 'data-garden-id': COMPONENT_ID$1,
203
+ 'data-garden-version': '9.0.0-next.3'
191
204
  }).withConfig({
192
205
  displayName: "StyledNavigation",
193
- componentId: "sc-184uuwe-0"
194
- })(["display:flex;align-items:center;justify-content:center;", ";"], props => reactTheming.retrieveComponentStyles(COMPONENT_ID, props));
206
+ componentId: "sc-1lpl8pp-0"
207
+ })(["display:flex;align-items:center;justify-content:center;", ";"], props => reactTheming.retrieveComponentStyles(COMPONENT_ID$1, props));
195
208
  StyledNavigation.defaultProps = {
196
209
  theme: reactTheming.DEFAULT_THEME
197
210
  };
198
211
 
212
+ const COMPONENT_ID = 'pagination.pagination_view';
213
+ const StyledNav = styled__default.default.nav.attrs({
214
+ 'data-garden-id': COMPONENT_ID,
215
+ 'data-garden-version': '9.0.0-next.3'
216
+ }).withConfig({
217
+ displayName: "StyledNav",
218
+ componentId: "sc-ppnpkw-0"
219
+ })(["", ";"], props => reactTheming.retrieveComponentStyles(COMPONENT_ID, props));
220
+ StyledNav.defaultProps = {
221
+ theme: reactTheming.DEFAULT_THEME
222
+ };
223
+
199
224
  var _path$3;
200
225
  function _extends$3() { _extends$3 = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$3.apply(this, arguments); }
201
226
  var SvgChevronLeftStroke = function SvgChevronLeftStroke(props) {
@@ -231,7 +256,9 @@ var SvgChevronRightStroke = function SvgChevronRightStroke(props) {
231
256
  const PreviousComponent$1 = React.forwardRef((props, ref) => {
232
257
  const ariaLabel = reactTheming.useText(PreviousComponent$1, props, 'aria-label', 'Previous page');
233
258
  const theme = React.useContext(styled.ThemeContext);
234
- return React__namespace.default.createElement(StyledNavigation, _extends$4({}, props, {
259
+ return React__namespace.default.createElement(StyledNavigation, _extends$4({
260
+ type: "button"
261
+ }, props, {
235
262
  "aria-label": ariaLabel,
236
263
  ref: ref
237
264
  }), theme.rtl ? React__namespace.default.createElement(SvgChevronRightStroke, null) : React__namespace.default.createElement(SvgChevronLeftStroke, null));
@@ -242,7 +269,9 @@ const Previous$1 = PreviousComponent$1;
242
269
  const NextComponent$1 = React.forwardRef((props, ref) => {
243
270
  const ariaLabel = reactTheming.useText(NextComponent$1, props, 'aria-label', 'Next page');
244
271
  const theme = React.useContext(styled.ThemeContext);
245
- return React__namespace.default.createElement(StyledNavigation, _extends$4({}, props, {
272
+ return React__namespace.default.createElement(StyledNavigation, _extends$4({
273
+ type: "button"
274
+ }, props, {
246
275
  "aria-label": ariaLabel,
247
276
  ref: ref
248
277
  }), theme.rtl ? React__namespace.default.createElement(SvgChevronLeftStroke, null) : React__namespace.default.createElement(SvgChevronRightStroke, null));
@@ -251,9 +280,10 @@ NextComponent$1.displayName = 'Pagination.Next';
251
280
  const Next$1 = NextComponent$1;
252
281
 
253
282
  const PageComponent = React.forwardRef((props, ref) => {
254
- const text = props['aria-current'] ? `Current page, page ${props.children}` : `Page ${props.children}`;
255
- const ariaLabel = reactTheming.useText(PageComponent, props, 'aria-label', text);
256
- return React__namespace.default.createElement(StyledPage, _extends$4({}, props, {
283
+ const ariaLabel = reactTheming.useText(PageComponent, props, 'aria-label', `Page ${props.children}`);
284
+ return React__namespace.default.createElement(StyledPage, _extends$4({
285
+ type: "button"
286
+ }, props, {
257
287
  "aria-label": ariaLabel,
258
288
  ref: ref
259
289
  }));
@@ -261,131 +291,89 @@ const PageComponent = React.forwardRef((props, ref) => {
261
291
  PageComponent.displayName = 'Pagination.Page';
262
292
  const Page = PageComponent;
263
293
 
264
- const GapComponent = React.forwardRef((props, ref) => React__namespace.default.createElement(StyledGap, _extends$4({}, props, {
265
- ref: ref
266
- }), "\u2026"));
294
+ const GapComponent = React.forwardRef((props, ref) => {
295
+ const ariaLabel = reactTheming.useText(GapComponent, props, 'aria-label', 'Ellipsis indicating non-visible pages');
296
+ return React__namespace.default.createElement(StyledGapListItem, _extends$4({}, props, {
297
+ "aria-label": ariaLabel,
298
+ ref: ref
299
+ }), "\u2026");
300
+ });
267
301
  GapComponent.displayName = 'Pagination.Gap';
268
302
  const Gap = GapComponent;
269
303
 
270
304
  const PREVIOUS_KEY = 'previous';
271
305
  const NEXT_KEY = 'next';
272
- const Pagination = React.forwardRef((_ref, ref) => {
306
+ const OffsetPagination = React.forwardRef((_ref, ref) => {
273
307
  let {
274
308
  currentPage: controlledCurrentPage,
275
- transformPageProps,
276
309
  totalPages,
277
310
  pagePadding,
278
311
  pageGap,
279
312
  onChange,
313
+ 'aria-label': ariaLabel,
314
+ labels,
280
315
  ...otherProps
281
316
  } = _ref;
282
317
  const [focusedItem, setFocusedItem] = React.useState();
283
318
  const [internalCurrentPage, setInternalCurrentPage] = React.useState(1);
319
+ const navigationLabel = reactTheming.useText(OffsetPagination, {
320
+ 'aria-label': ariaLabel
321
+ }, 'aria-label', 'Pagination');
284
322
  const currentPage = containerUtilities.getControlledValue(controlledCurrentPage, internalCurrentPage);
285
- const theme = React.useContext(styled.ThemeContext);
286
- const {
287
- getContainerProps,
288
- getPageProps,
289
- getPreviousPageProps,
290
- getNextPageProps
291
- } = containerPagination.usePagination({
292
- rtl: theme.rtl,
293
- focusedItem,
294
- selectedItem: currentPage,
295
- onFocus: item => {
296
- setFocusedItem(item);
297
- },
298
- onSelect: item => {
299
- let updatedCurrentPage = item;
300
- let updatedFocusedKey = focusedItem;
301
- if (updatedCurrentPage === PREVIOUS_KEY && currentPage > 1) {
302
- updatedCurrentPage = currentPage - 1;
303
- if (updatedCurrentPage === 1 && focusedItem === PREVIOUS_KEY) {
304
- updatedFocusedKey = 1;
305
- }
306
- } else if (updatedCurrentPage === NEXT_KEY && currentPage < totalPages) {
307
- updatedCurrentPage = currentPage + 1;
308
- if (updatedCurrentPage === totalPages && updatedFocusedKey === NEXT_KEY) {
309
- updatedFocusedKey = totalPages;
310
- }
323
+ const handleFocus = React.useCallback(item => {
324
+ setFocusedItem(item);
325
+ }, []);
326
+ const handleSelect = React.useCallback(item => {
327
+ let updatedCurrentPage = item;
328
+ let updatedFocusedKey = focusedItem;
329
+ if (updatedCurrentPage === PREVIOUS_KEY && currentPage > 1) {
330
+ updatedCurrentPage = currentPage - 1;
331
+ if (updatedCurrentPage === 1 && focusedItem === PREVIOUS_KEY) {
332
+ updatedFocusedKey = 1;
311
333
  }
312
- if (onChange && updatedCurrentPage !== undefined) {
313
- onChange(updatedCurrentPage);
334
+ } else if (updatedCurrentPage === NEXT_KEY && currentPage < totalPages) {
335
+ updatedCurrentPage = currentPage + 1;
336
+ if (updatedCurrentPage === totalPages && updatedFocusedKey === NEXT_KEY) {
337
+ updatedFocusedKey = totalPages;
314
338
  }
315
- setFocusedItem(updatedFocusedKey);
316
- setInternalCurrentPage(updatedCurrentPage);
317
339
  }
318
- });
319
- const getTransformedProps = function (pageType) {
320
- let props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
321
- let pageNumber = arguments.length > 2 ? arguments[2] : undefined;
322
- if (transformPageProps) {
323
- return transformPageProps(pageType, props, pageNumber);
340
+ if (onChange && updatedCurrentPage !== undefined) {
341
+ onChange(updatedCurrentPage);
324
342
  }
325
- return props;
326
- };
343
+ setFocusedItem(updatedFocusedKey);
344
+ setInternalCurrentPage(updatedCurrentPage);
345
+ }, [currentPage, focusedItem, onChange, totalPages]);
327
346
  const renderPreviousPage = () => {
328
347
  const isFirstPageSelected = totalPages > 0 && currentPage === 1;
329
- const focusRef = React__namespace.default.createRef();
330
- const props = isFirstPageSelected ?
331
- {
332
- hidden: true
333
- } : {
334
- ...getPreviousPageProps({
335
- 'aria-label': '',
336
- role: null,
337
- item: PREVIOUS_KEY,
338
- focusRef
339
- }),
340
- 'aria-label': undefined
341
- };
342
- return React__namespace.default.createElement(Previous$1, _extends$4({
343
- isFocused: focusedItem === PREVIOUS_KEY
344
- }, getTransformedProps('previous', props), {
345
- ref: focusRef
348
+ return React__namespace.default.createElement(StyledListItem, null, React__namespace.default.createElement(Previous$1, {
349
+ hidden: isFirstPageSelected,
350
+ onFocus: () => handleFocus('previous'),
351
+ onClick: () => handleSelect('previous'),
352
+ "aria-label": labels?.previous
346
353
  }));
347
354
  };
348
355
  const renderNextPage = () => {
349
356
  const isLastPageSelected = currentPage === totalPages;
350
- const focusRef = React__namespace.default.createRef();
351
- const props = isLastPageSelected ?
352
- {
353
- hidden: true
354
- } : {
355
- ...getNextPageProps({
356
- 'aria-label': '',
357
- role: null,
358
- item: NEXT_KEY,
359
- focusRef
360
- }),
361
- 'aria-label': undefined
362
- };
363
- return React__namespace.default.createElement(Next$1, _extends$4({
364
- isFocused: focusedItem === NEXT_KEY
365
- }, getTransformedProps('next', props), {
366
- ref: focusRef
357
+ return React__namespace.default.createElement(StyledListItem, null, React__namespace.default.createElement(Next$1, {
358
+ hidden: isLastPageSelected,
359
+ onFocus: () => handleFocus('next'),
360
+ onClick: () => handleSelect('next'),
361
+ "aria-label": labels?.next
367
362
  }));
368
363
  };
369
- const createGap = pageIndex => React__namespace.default.createElement(Gap, _extends$4({
370
- key: `gap-${pageIndex}`
371
- }, getTransformedProps('gap')));
364
+ const createGap = pageIndex => React__namespace.default.createElement(Gap, {
365
+ key: `gap-${pageIndex}`,
366
+ "aria-label": labels?.gap
367
+ });
372
368
  const createPage = pageIndex => {
373
- const focusRef = React__namespace.default.createRef();
374
- const props = {
375
- ...getPageProps({
376
- 'aria-label': '',
377
- role: null,
378
- item: pageIndex,
379
- focusRef
380
- }),
381
- 'aria-label': undefined,
382
- title: pageIndex
383
- };
384
- return React__namespace.default.createElement(Page, _extends$4({
369
+ return React__namespace.default.createElement(StyledListItem, {
385
370
  key: pageIndex
386
- }, getTransformedProps('page', props, pageIndex), {
387
- ref: focusRef
388
- }), pageIndex);
371
+ }, React__namespace.default.createElement(Page, {
372
+ onFocus: () => handleFocus(pageIndex),
373
+ onClick: () => handleSelect(pageIndex),
374
+ "aria-current": currentPage === pageIndex ? 'page' : undefined,
375
+ "aria-label": labels?.renderPage?.(pageIndex)
376
+ }, pageIndex));
389
377
  };
390
378
  const renderPages = () => {
391
379
  const pages = [];
@@ -431,25 +419,25 @@ const Pagination = React.forwardRef((_ref, ref) => {
431
419
  }
432
420
  return pages;
433
421
  };
434
- return React__namespace.default.createElement(StyledPagination, _extends$4({}, getContainerProps({
435
- role: null
436
- }), otherProps, {
422
+ return React__namespace.default.createElement(StyledNav, {
423
+ "aria-label": navigationLabel
424
+ }, React__namespace.default.createElement(StyledList, _extends$4({}, otherProps, {
437
425
  ref: ref
438
- }), renderPreviousPage(), totalPages > 0 && renderPages(), renderNextPage());
426
+ }), renderPreviousPage(), totalPages > 0 && renderPages(), renderNextPage()));
439
427
  });
440
- Pagination.propTypes = {
428
+ OffsetPagination.propTypes = {
441
429
  currentPage: PropTypes__default.default.number.isRequired,
442
430
  totalPages: PropTypes__default.default.number.isRequired,
443
431
  pagePadding: PropTypes__default.default.number,
444
432
  pageGap: PropTypes__default.default.number,
445
433
  onChange: PropTypes__default.default.func,
446
- transformPageProps: PropTypes__default.default.func
434
+ labels: PropTypes__default.default.any
447
435
  };
448
- Pagination.defaultProps = {
436
+ OffsetPagination.defaultProps = {
449
437
  pagePadding: 2,
450
438
  pageGap: 2
451
439
  };
452
- Pagination.displayName = 'Pagination';
440
+ OffsetPagination.displayName = 'OffsetPagination';
453
441
 
454
442
  var _path$1;
455
443
  function _extends$1() { _extends$1 = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$1.apply(this, arguments); }
@@ -553,4 +541,4 @@ CursorPagination.Previous = Previous;
553
541
  CursorPagination.Last = Last;
554
542
 
555
543
  exports.CursorPagination = CursorPagination;
556
- exports.Pagination = Pagination;
544
+ exports.OffsetPagination = OffsetPagination;
package/dist/index.esm.js CHANGED
@@ -6,12 +6,11 @@
6
6
  */
7
7
 
8
8
  import * as React from 'react';
9
- import React__default, { cloneElement, Children, forwardRef, useContext, useState } from 'react';
9
+ import React__default, { cloneElement, Children, forwardRef, useContext, useState, useCallback } from 'react';
10
10
  import PropTypes from 'prop-types';
11
- import styled, { css, ThemeContext } from 'styled-components';
12
- import { usePagination } from '@zendeskgarden/container-pagination';
13
11
  import { getControlledValue } from '@zendeskgarden/container-utilities';
14
12
  import { getColor, retrieveComponentStyles, DEFAULT_THEME, focusStyles, getLineHeight, useText } from '@zendeskgarden/react-theming';
13
+ import styled, { css, ThemeContext } from 'styled-components';
15
14
  import { math } from 'polished';
16
15
 
17
16
  function _extends$4() {
@@ -29,19 +28,31 @@ function _extends$4() {
29
28
  return _extends$4.apply(this, arguments);
30
29
  }
31
30
 
32
- const COMPONENT_ID$6 = 'pagination.pagination_view';
33
- const StyledPagination = styled.ul.attrs({
34
- 'data-garden-id': COMPONENT_ID$6,
35
- 'data-garden-version': '9.0.0-next.1'
31
+ const COMPONENT_ID$8 = 'pagination.list';
32
+ const StyledList = styled.ul.attrs({
33
+ 'data-garden-id': COMPONENT_ID$8,
34
+ 'data-garden-version': '9.0.0-next.3'
36
35
  }).withConfig({
37
- displayName: "StyledPagination",
38
- componentId: "sc-1b7nye9-0"
39
- })(["direction:", ";display:flex;justify-content:center;margin:0;padding:0;white-space:nowrap;color:", ";:focus{outline:none;}", ";"], props => props.theme.rtl && 'rtl', props => getColor('neutralHue', 600, props.theme), props => retrieveComponentStyles(COMPONENT_ID$6, props));
40
- StyledPagination.defaultProps = {
36
+ displayName: "StyledList",
37
+ componentId: "sc-1uz2jxo-0"
38
+ })(["direction:", ";display:flex;justify-content:center;margin:0;padding:0;list-style:none;white-space:nowrap;color:", ";:focus{outline:none;}", ";"], props => props.theme.rtl && 'rtl', props => getColor('neutralHue', 600, props.theme), props => retrieveComponentStyles(COMPONENT_ID$8, props));
39
+ StyledList.defaultProps = {
41
40
  theme: DEFAULT_THEME
42
41
  };
43
42
 
44
- const COMPONENT_ID$5 = 'pagination.page';
43
+ const COMPONENT_ID$7 = 'pagination.list_item';
44
+ const StyledListItem = styled.li.attrs({
45
+ 'data-garden-id': COMPONENT_ID$7,
46
+ 'data-garden-version': '9.0.0-next.3'
47
+ }).withConfig({
48
+ displayName: "StyledListItem",
49
+ componentId: "sc-16j4sju-0"
50
+ })(["box-sizing:border-box;margin-left:", ";user-select:none;&", "{margin-left:0;}", ";"], props => `${props.theme.space.base}px`, props => props.theme.rtl ? ':last-of-type' : ':first-of-type', props => retrieveComponentStyles(COMPONENT_ID$7, props));
51
+ StyledListItem.defaultProps = {
52
+ theme: DEFAULT_THEME
53
+ };
54
+
55
+ const COMPONENT_ID$6 = 'pagination.page';
45
56
  const colorStyles = props => {
46
57
  const defaultColor = getColor('neutralHue', 600, props.theme);
47
58
  const hoverForegroundColor = getColor('neutralHue', 700, props.theme);
@@ -52,7 +63,7 @@ const colorStyles = props => {
52
63
  const currentBackgroundColor = hoverBackgroundColor;
53
64
  const currentHoverBackgroundColor = getColor('primaryHue', 600, props.theme, 0.16);
54
65
  const currentActiveBackgroundColor = getColor('primaryHue', 600, props.theme, 0.28);
55
- return css(["color:", ";&:hover{background-color:", ";color:", ";}", " &:active,&:focus-visible:active,&[data-garden-focus-visible]:active{background-color:", ";color:", ";}&[aria-current='true']{background-color:", ";color:", ";}&[aria-current='true']:hover{background-color:", ";}&[aria-current='true']:active{background-color:", ";}:disabled,[aria-disabled='true']{background-color:transparent;color:", ";}"], defaultColor, hoverBackgroundColor, hoverForegroundColor, focusStyles({
66
+ return css(["border:none;background:transparent;color:", ";&:hover{background-color:", ";color:", ";}", " &:active,&:focus-visible:active,&[data-garden-focus-visible]:active{background-color:", ";color:", ";}&[aria-current='page']{background-color:", ";color:", ";}&[aria-current='page']:hover{background-color:", ";}&[aria-current='page']:active{background-color:", ";}:disabled,[aria-disabled='true']{background-color:transparent;color:", ";}"], defaultColor, hoverBackgroundColor, hoverForegroundColor, focusStyles({
56
67
  theme: props.theme,
57
68
  inset: true
58
69
  }), activeBackgroundColor, activeForegroundColor, currentBackgroundColor, currentForegroundColor, currentHoverBackgroundColor, currentActiveBackgroundColor, getColor('grey', 300, props.theme));
@@ -64,54 +75,54 @@ const sizeStyles$2 = props => {
64
75
  const padding = `${props.theme.space.base * 1.5}px`;
65
76
  return css(["padding:0 ", ";height:", ";line-height:", ";font-size:", ";"], padding, height, lineHeight, fontSize);
66
77
  };
67
- const StyledPageBase = styled.li.attrs({
68
- 'data-garden-id': COMPONENT_ID$5,
69
- 'data-garden-version': '9.0.0-next.1'
78
+ const StyledPageBase = styled.button.attrs({
79
+ 'data-garden-id': COMPONENT_ID$6,
80
+ 'data-garden-version': '9.0.0-next.3'
70
81
  }).withConfig({
71
82
  displayName: "StyledPageBase",
72
- componentId: "sc-lw1w9j-0"
73
- })(["box-sizing:border-box;display:inline-block;transition:box-shadow 0.1s ease-in-out,background-color 0.25s ease-in-out,color 0.25s ease-in-out;visibility:", ";border-radius:", ";cursor:pointer;overflow:hidden;text-align:center;text-overflow:ellipsis;user-select:none;", ";&[aria-current='true']{font-weight:", ";}:disabled,[aria-disabled='true']{cursor:default;}", ";", ";"], props => props.hidden && 'hidden', props => props.theme.borderRadii.md, props => sizeStyles$2(props), props => props.theme.fontWeights.semibold, props => colorStyles(props), props => retrieveComponentStyles(COMPONENT_ID$5, props));
83
+ componentId: "sc-ttwj4u-0"
84
+ })(["box-sizing:border-box;display:inline-block;transition:box-shadow 0.1s ease-in-out,background-color 0.25s ease-in-out,color 0.25s ease-in-out;visibility:", ";border-radius:", ";cursor:pointer;overflow:hidden;text-align:center;text-overflow:ellipsis;font-family:inherit;user-select:none;", ";&[aria-current='page']{font-weight:", ";}&::-moz-focus-inner{border:0;}:disabled,[aria-disabled='true']{cursor:default;}", ";", ";"], props => props.hidden && 'hidden', props => props.theme.borderRadii.md, props => sizeStyles$2(props), props => props.theme.fontWeights.semibold, props => colorStyles(props), props => retrieveComponentStyles(COMPONENT_ID$6, props));
74
85
  StyledPageBase.defaultProps = {
75
86
  theme: DEFAULT_THEME
76
87
  };
77
88
 
78
- const COMPONENT_ID$4 = 'pagination.page';
89
+ const COMPONENT_ID$5 = 'pagination.page';
79
90
  const sizeStyles$1 = props => {
80
- const height = `${props.theme.space.base * 8}px`;
81
- return css(["min-width:", ";max-width:", ";&[aria-current='true']{max-width:none;}"], height, math(`${height} * 2`));
91
+ const height = props.theme.space.base * 8;
92
+ return css(["min-width:", "px;max-width:", "px;&[aria-current='true']{max-width:none;}"], height, height * 2);
82
93
  };
83
94
  const StyledPage = styled(StyledPageBase).attrs({
84
- 'data-garden-id': COMPONENT_ID$4,
85
- 'data-garden-version': '9.0.0-next.1'
95
+ 'data-garden-id': COMPONENT_ID$5,
96
+ 'data-garden-version': '9.0.0-next.3'
86
97
  }).withConfig({
87
98
  displayName: "StyledPage",
88
- componentId: "sc-1k0een3-0"
89
- })(["margin-left:", ";", ";&[aria-current=\"true\"]{font-weight:", ";}&", "{margin-left:0;}", ";"], props => `${props.theme.space.base}px`, props => sizeStyles$1(props), props => props.theme.fontWeights.semibold, props => props.theme.rtl ? ':last-of-type' : ':first-of-type', props => retrieveComponentStyles(COMPONENT_ID$4, props));
99
+ componentId: "sc-sxjfwy-0"
100
+ })(["", ";&[aria-current=\"true\"]{font-weight:", ";}", ";"], props => sizeStyles$1(props), props => props.theme.fontWeights.semibold, props => retrieveComponentStyles(COMPONENT_ID$5, props));
90
101
  StyledPage.defaultProps = {
91
102
  theme: DEFAULT_THEME
92
103
  };
93
104
 
94
- const COMPONENT_ID$3 = 'cursor_pagination';
105
+ const COMPONENT_ID$4 = 'cursor_pagination';
95
106
  const StyledCursorPagination = styled.nav.attrs({
96
- 'data-garden-id': COMPONENT_ID$3,
97
- 'data-garden-version': '9.0.0-next.1'
107
+ 'data-garden-id': COMPONENT_ID$4,
108
+ 'data-garden-version': '9.0.0-next.3'
98
109
  }).withConfig({
99
110
  displayName: "StyledCursorPagination",
100
111
  componentId: "sc-qmfecg-0"
101
- })(["display:flex;justify-content:center;", ";"], props => retrieveComponentStyles(COMPONENT_ID$3, props));
112
+ })(["display:flex;justify-content:center;", ";"], props => retrieveComponentStyles(COMPONENT_ID$4, props));
102
113
  StyledCursorPagination.defaultProps = {
103
114
  theme: DEFAULT_THEME
104
115
  };
105
116
 
106
- const COMPONENT_ID$2 = 'cursor_pagination.cursor';
117
+ const COMPONENT_ID$3 = 'cursor_pagination.cursor';
107
118
  const StyledCursor = styled(StyledPageBase).attrs({
108
- 'data-garden-id': COMPONENT_ID$2,
109
- 'data-garden-version': '9.0.0-next.1',
119
+ 'data-garden-id': COMPONENT_ID$3,
120
+ 'data-garden-version': '9.0.0-next.3',
110
121
  as: 'button'
111
122
  }).withConfig({
112
123
  displayName: "StyledCursor",
113
124
  componentId: "sc-507ee-0"
114
- })(["display:flex;align-items:center;border:none;background:transparent;padding:", ";overflow:visible;&:not(", "-of-type){margin-right:", "px;}", ";"], props => `0px ${props.theme.space.base * 2}px`, props => props.theme.rtl ? ':first' : ':last', props => props.theme.space.base, props => retrieveComponentStyles(COMPONENT_ID$2, props));
125
+ })(["display:flex;align-items:center;border:none;background:transparent;padding:", ";overflow:visible;&:not(", "-of-type){margin-right:", "px;}", ";"], props => `0px ${props.theme.space.base * 2}px`, props => props.theme.rtl ? ':first' : ':last', props => props.theme.space.base, props => retrieveComponentStyles(COMPONENT_ID$3, props));
115
126
  StyledCursor.defaultProps = {
116
127
  theme: DEFAULT_THEME
117
128
  };
@@ -141,36 +152,50 @@ StyledIcon.defaultProps = {
141
152
  theme: DEFAULT_THEME
142
153
  };
143
154
 
144
- const COMPONENT_ID$1 = 'pagination.gap';
155
+ const COMPONENT_ID$2 = 'pagination.gap';
145
156
  const sizeStyles = props => {
146
157
  const shift = 2;
147
- const marginTop = `-${shift}px`;
148
158
  const fontSize = math(`${props.theme.fontSizes.md} + ${shift}`);
149
- return css(["margin-top:", ";font-size:", ";"], marginTop, fontSize);
159
+ const height = `${props.theme.space.base * 8}px`;
160
+ const lineHeight = getLineHeight(height, fontSize);
161
+ const padding = `${props.theme.space.base * 1.5}px`;
162
+ return css(["padding:0 ", ";min-width:", ";max-width:", ";height:", ";line-height:", ";font-size:", ";"], padding, height, math(`${height} * 2`), height, lineHeight, fontSize);
150
163
  };
151
- const StyledGap = styled(StyledPage).attrs({
152
- 'data-garden-id': COMPONENT_ID$1,
153
- 'data-garden-version': '9.0.0-next.1'
164
+ const StyledGapListItem = styled(StyledListItem).attrs({
165
+ 'data-garden-id': COMPONENT_ID$2,
166
+ 'data-garden-version': '9.0.0-next.3'
154
167
  }).withConfig({
155
- displayName: "StyledGap",
156
- componentId: "sc-1hqjltf-0"
157
- })(["cursor:default;", ";&:hover{background-color:transparent;color:inherit;}", ";"], props => sizeStyles(props), props => retrieveComponentStyles(COMPONENT_ID$1, props));
158
- StyledGap.defaultProps = {
168
+ displayName: "StyledGapListItem",
169
+ componentId: "sc-10wd0iz-0"
170
+ })(["display:inline-block;text-align:center;color:", ";", ";&:hover{color:inherit;}", ";"], p => getColor('neutralHue', 600, p.theme), props => sizeStyles(props), props => retrieveComponentStyles(COMPONENT_ID$2, props));
171
+ StyledGapListItem.defaultProps = {
159
172
  theme: DEFAULT_THEME
160
173
  };
161
174
 
162
- const COMPONENT_ID = 'pagination.navigation';
175
+ const COMPONENT_ID$1 = 'pagination.navigation';
163
176
  const StyledNavigation = styled(StyledPage).attrs({
164
- 'data-garden-id': COMPONENT_ID,
165
- 'data-garden-version': '9.0.0-next.1'
177
+ 'data-garden-id': COMPONENT_ID$1,
178
+ 'data-garden-version': '9.0.0-next.3'
166
179
  }).withConfig({
167
180
  displayName: "StyledNavigation",
168
- componentId: "sc-184uuwe-0"
169
- })(["display:flex;align-items:center;justify-content:center;", ";"], props => retrieveComponentStyles(COMPONENT_ID, props));
181
+ componentId: "sc-1lpl8pp-0"
182
+ })(["display:flex;align-items:center;justify-content:center;", ";"], props => retrieveComponentStyles(COMPONENT_ID$1, props));
170
183
  StyledNavigation.defaultProps = {
171
184
  theme: DEFAULT_THEME
172
185
  };
173
186
 
187
+ const COMPONENT_ID = 'pagination.pagination_view';
188
+ const StyledNav = styled.nav.attrs({
189
+ 'data-garden-id': COMPONENT_ID,
190
+ 'data-garden-version': '9.0.0-next.3'
191
+ }).withConfig({
192
+ displayName: "StyledNav",
193
+ componentId: "sc-ppnpkw-0"
194
+ })(["", ";"], props => retrieveComponentStyles(COMPONENT_ID, props));
195
+ StyledNav.defaultProps = {
196
+ theme: DEFAULT_THEME
197
+ };
198
+
174
199
  var _path$3;
175
200
  function _extends$3() { _extends$3 = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$3.apply(this, arguments); }
176
201
  var SvgChevronLeftStroke = function SvgChevronLeftStroke(props) {
@@ -206,7 +231,9 @@ var SvgChevronRightStroke = function SvgChevronRightStroke(props) {
206
231
  const PreviousComponent$1 = forwardRef((props, ref) => {
207
232
  const ariaLabel = useText(PreviousComponent$1, props, 'aria-label', 'Previous page');
208
233
  const theme = useContext(ThemeContext);
209
- return React__default.createElement(StyledNavigation, _extends$4({}, props, {
234
+ return React__default.createElement(StyledNavigation, _extends$4({
235
+ type: "button"
236
+ }, props, {
210
237
  "aria-label": ariaLabel,
211
238
  ref: ref
212
239
  }), theme.rtl ? React__default.createElement(SvgChevronRightStroke, null) : React__default.createElement(SvgChevronLeftStroke, null));
@@ -217,7 +244,9 @@ const Previous$1 = PreviousComponent$1;
217
244
  const NextComponent$1 = forwardRef((props, ref) => {
218
245
  const ariaLabel = useText(NextComponent$1, props, 'aria-label', 'Next page');
219
246
  const theme = useContext(ThemeContext);
220
- return React__default.createElement(StyledNavigation, _extends$4({}, props, {
247
+ return React__default.createElement(StyledNavigation, _extends$4({
248
+ type: "button"
249
+ }, props, {
221
250
  "aria-label": ariaLabel,
222
251
  ref: ref
223
252
  }), theme.rtl ? React__default.createElement(SvgChevronLeftStroke, null) : React__default.createElement(SvgChevronRightStroke, null));
@@ -226,9 +255,10 @@ NextComponent$1.displayName = 'Pagination.Next';
226
255
  const Next$1 = NextComponent$1;
227
256
 
228
257
  const PageComponent = forwardRef((props, ref) => {
229
- const text = props['aria-current'] ? `Current page, page ${props.children}` : `Page ${props.children}`;
230
- const ariaLabel = useText(PageComponent, props, 'aria-label', text);
231
- return React__default.createElement(StyledPage, _extends$4({}, props, {
258
+ const ariaLabel = useText(PageComponent, props, 'aria-label', `Page ${props.children}`);
259
+ return React__default.createElement(StyledPage, _extends$4({
260
+ type: "button"
261
+ }, props, {
232
262
  "aria-label": ariaLabel,
233
263
  ref: ref
234
264
  }));
@@ -236,131 +266,89 @@ const PageComponent = forwardRef((props, ref) => {
236
266
  PageComponent.displayName = 'Pagination.Page';
237
267
  const Page = PageComponent;
238
268
 
239
- const GapComponent = forwardRef((props, ref) => React__default.createElement(StyledGap, _extends$4({}, props, {
240
- ref: ref
241
- }), "\u2026"));
269
+ const GapComponent = forwardRef((props, ref) => {
270
+ const ariaLabel = useText(GapComponent, props, 'aria-label', 'Ellipsis indicating non-visible pages');
271
+ return React__default.createElement(StyledGapListItem, _extends$4({}, props, {
272
+ "aria-label": ariaLabel,
273
+ ref: ref
274
+ }), "\u2026");
275
+ });
242
276
  GapComponent.displayName = 'Pagination.Gap';
243
277
  const Gap = GapComponent;
244
278
 
245
279
  const PREVIOUS_KEY = 'previous';
246
280
  const NEXT_KEY = 'next';
247
- const Pagination = forwardRef((_ref, ref) => {
281
+ const OffsetPagination = forwardRef((_ref, ref) => {
248
282
  let {
249
283
  currentPage: controlledCurrentPage,
250
- transformPageProps,
251
284
  totalPages,
252
285
  pagePadding,
253
286
  pageGap,
254
287
  onChange,
288
+ 'aria-label': ariaLabel,
289
+ labels,
255
290
  ...otherProps
256
291
  } = _ref;
257
292
  const [focusedItem, setFocusedItem] = useState();
258
293
  const [internalCurrentPage, setInternalCurrentPage] = useState(1);
294
+ const navigationLabel = useText(OffsetPagination, {
295
+ 'aria-label': ariaLabel
296
+ }, 'aria-label', 'Pagination');
259
297
  const currentPage = getControlledValue(controlledCurrentPage, internalCurrentPage);
260
- const theme = useContext(ThemeContext);
261
- const {
262
- getContainerProps,
263
- getPageProps,
264
- getPreviousPageProps,
265
- getNextPageProps
266
- } = usePagination({
267
- rtl: theme.rtl,
268
- focusedItem,
269
- selectedItem: currentPage,
270
- onFocus: item => {
271
- setFocusedItem(item);
272
- },
273
- onSelect: item => {
274
- let updatedCurrentPage = item;
275
- let updatedFocusedKey = focusedItem;
276
- if (updatedCurrentPage === PREVIOUS_KEY && currentPage > 1) {
277
- updatedCurrentPage = currentPage - 1;
278
- if (updatedCurrentPage === 1 && focusedItem === PREVIOUS_KEY) {
279
- updatedFocusedKey = 1;
280
- }
281
- } else if (updatedCurrentPage === NEXT_KEY && currentPage < totalPages) {
282
- updatedCurrentPage = currentPage + 1;
283
- if (updatedCurrentPage === totalPages && updatedFocusedKey === NEXT_KEY) {
284
- updatedFocusedKey = totalPages;
285
- }
298
+ const handleFocus = useCallback(item => {
299
+ setFocusedItem(item);
300
+ }, []);
301
+ const handleSelect = useCallback(item => {
302
+ let updatedCurrentPage = item;
303
+ let updatedFocusedKey = focusedItem;
304
+ if (updatedCurrentPage === PREVIOUS_KEY && currentPage > 1) {
305
+ updatedCurrentPage = currentPage - 1;
306
+ if (updatedCurrentPage === 1 && focusedItem === PREVIOUS_KEY) {
307
+ updatedFocusedKey = 1;
286
308
  }
287
- if (onChange && updatedCurrentPage !== undefined) {
288
- onChange(updatedCurrentPage);
309
+ } else if (updatedCurrentPage === NEXT_KEY && currentPage < totalPages) {
310
+ updatedCurrentPage = currentPage + 1;
311
+ if (updatedCurrentPage === totalPages && updatedFocusedKey === NEXT_KEY) {
312
+ updatedFocusedKey = totalPages;
289
313
  }
290
- setFocusedItem(updatedFocusedKey);
291
- setInternalCurrentPage(updatedCurrentPage);
292
314
  }
293
- });
294
- const getTransformedProps = function (pageType) {
295
- let props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
296
- let pageNumber = arguments.length > 2 ? arguments[2] : undefined;
297
- if (transformPageProps) {
298
- return transformPageProps(pageType, props, pageNumber);
315
+ if (onChange && updatedCurrentPage !== undefined) {
316
+ onChange(updatedCurrentPage);
299
317
  }
300
- return props;
301
- };
318
+ setFocusedItem(updatedFocusedKey);
319
+ setInternalCurrentPage(updatedCurrentPage);
320
+ }, [currentPage, focusedItem, onChange, totalPages]);
302
321
  const renderPreviousPage = () => {
303
322
  const isFirstPageSelected = totalPages > 0 && currentPage === 1;
304
- const focusRef = React__default.createRef();
305
- const props = isFirstPageSelected ?
306
- {
307
- hidden: true
308
- } : {
309
- ...getPreviousPageProps({
310
- 'aria-label': '',
311
- role: null,
312
- item: PREVIOUS_KEY,
313
- focusRef
314
- }),
315
- 'aria-label': undefined
316
- };
317
- return React__default.createElement(Previous$1, _extends$4({
318
- isFocused: focusedItem === PREVIOUS_KEY
319
- }, getTransformedProps('previous', props), {
320
- ref: focusRef
323
+ return React__default.createElement(StyledListItem, null, React__default.createElement(Previous$1, {
324
+ hidden: isFirstPageSelected,
325
+ onFocus: () => handleFocus('previous'),
326
+ onClick: () => handleSelect('previous'),
327
+ "aria-label": labels?.previous
321
328
  }));
322
329
  };
323
330
  const renderNextPage = () => {
324
331
  const isLastPageSelected = currentPage === totalPages;
325
- const focusRef = React__default.createRef();
326
- const props = isLastPageSelected ?
327
- {
328
- hidden: true
329
- } : {
330
- ...getNextPageProps({
331
- 'aria-label': '',
332
- role: null,
333
- item: NEXT_KEY,
334
- focusRef
335
- }),
336
- 'aria-label': undefined
337
- };
338
- return React__default.createElement(Next$1, _extends$4({
339
- isFocused: focusedItem === NEXT_KEY
340
- }, getTransformedProps('next', props), {
341
- ref: focusRef
332
+ return React__default.createElement(StyledListItem, null, React__default.createElement(Next$1, {
333
+ hidden: isLastPageSelected,
334
+ onFocus: () => handleFocus('next'),
335
+ onClick: () => handleSelect('next'),
336
+ "aria-label": labels?.next
342
337
  }));
343
338
  };
344
- const createGap = pageIndex => React__default.createElement(Gap, _extends$4({
345
- key: `gap-${pageIndex}`
346
- }, getTransformedProps('gap')));
339
+ const createGap = pageIndex => React__default.createElement(Gap, {
340
+ key: `gap-${pageIndex}`,
341
+ "aria-label": labels?.gap
342
+ });
347
343
  const createPage = pageIndex => {
348
- const focusRef = React__default.createRef();
349
- const props = {
350
- ...getPageProps({
351
- 'aria-label': '',
352
- role: null,
353
- item: pageIndex,
354
- focusRef
355
- }),
356
- 'aria-label': undefined,
357
- title: pageIndex
358
- };
359
- return React__default.createElement(Page, _extends$4({
344
+ return React__default.createElement(StyledListItem, {
360
345
  key: pageIndex
361
- }, getTransformedProps('page', props, pageIndex), {
362
- ref: focusRef
363
- }), pageIndex);
346
+ }, React__default.createElement(Page, {
347
+ onFocus: () => handleFocus(pageIndex),
348
+ onClick: () => handleSelect(pageIndex),
349
+ "aria-current": currentPage === pageIndex ? 'page' : undefined,
350
+ "aria-label": labels?.renderPage?.(pageIndex)
351
+ }, pageIndex));
364
352
  };
365
353
  const renderPages = () => {
366
354
  const pages = [];
@@ -406,25 +394,25 @@ const Pagination = forwardRef((_ref, ref) => {
406
394
  }
407
395
  return pages;
408
396
  };
409
- return React__default.createElement(StyledPagination, _extends$4({}, getContainerProps({
410
- role: null
411
- }), otherProps, {
397
+ return React__default.createElement(StyledNav, {
398
+ "aria-label": navigationLabel
399
+ }, React__default.createElement(StyledList, _extends$4({}, otherProps, {
412
400
  ref: ref
413
- }), renderPreviousPage(), totalPages > 0 && renderPages(), renderNextPage());
401
+ }), renderPreviousPage(), totalPages > 0 && renderPages(), renderNextPage()));
414
402
  });
415
- Pagination.propTypes = {
403
+ OffsetPagination.propTypes = {
416
404
  currentPage: PropTypes.number.isRequired,
417
405
  totalPages: PropTypes.number.isRequired,
418
406
  pagePadding: PropTypes.number,
419
407
  pageGap: PropTypes.number,
420
408
  onChange: PropTypes.func,
421
- transformPageProps: PropTypes.func
409
+ labels: PropTypes.any
422
410
  };
423
- Pagination.defaultProps = {
411
+ OffsetPagination.defaultProps = {
424
412
  pagePadding: 2,
425
413
  pageGap: 2
426
414
  };
427
- Pagination.displayName = 'Pagination';
415
+ OffsetPagination.displayName = 'OffsetPagination';
428
416
 
429
417
  var _path$1;
430
418
  function _extends$1() { _extends$1 = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$1.apply(this, arguments); }
@@ -527,4 +515,4 @@ CursorPagination.Next = Next;
527
515
  CursorPagination.Previous = Previous;
528
516
  CursorPagination.Last = Last;
529
517
 
530
- export { CursorPagination, Pagination };
518
+ export { CursorPagination, OffsetPagination };
@@ -9,4 +9,4 @@ import { IPaginationProps } from '../../types';
9
9
  /**
10
10
  * @extends HTMLAttributes<HTMLUListElement>
11
11
  */
12
- export declare const Pagination: React.ForwardRefExoticComponent<IPaginationProps & React.RefAttributes<HTMLUListElement>>;
12
+ export declare const OffsetPagination: React.ForwardRefExoticComponent<IPaginationProps & React.RefAttributes<HTMLUListElement>>;
@@ -6,6 +6,6 @@
6
6
  */
7
7
  import React from 'react';
8
8
  /**
9
- * @extends LiHTMLAttributes<HTMLLIElement>
9
+ * @extends ButtonHTMLAttributes<HTMLButtonElement>
10
10
  */
11
- export declare const Next: React.ForwardRefExoticComponent<React.LiHTMLAttributes<HTMLLIElement> & React.RefAttributes<HTMLLIElement>>;
11
+ export declare const Next: React.ForwardRefExoticComponent<React.ButtonHTMLAttributes<HTMLButtonElement> & React.RefAttributes<HTMLButtonElement>>;
@@ -6,6 +6,6 @@
6
6
  */
7
7
  import React from 'react';
8
8
  /**
9
- * @extends LiHTMLAttributes<HTMLLIElement>
9
+ * @extends ButtonHTMLAttributes<HTMLButtonElement>
10
10
  */
11
- export declare const Page: React.ForwardRefExoticComponent<React.LiHTMLAttributes<HTMLLIElement> & React.RefAttributes<HTMLLIElement>>;
11
+ export declare const Page: React.ForwardRefExoticComponent<React.ButtonHTMLAttributes<HTMLButtonElement> & React.RefAttributes<HTMLButtonElement>>;
@@ -6,6 +6,6 @@
6
6
  */
7
7
  import React from 'react';
8
8
  /**
9
- * @extends LiHTMLAttributes<HTMLLIElement>
9
+ * @extends ButtonHTMLAttributes<HTMLButtonElement>
10
10
  */
11
- export declare const Previous: React.ForwardRefExoticComponent<React.LiHTMLAttributes<HTMLLIElement> & React.RefAttributes<HTMLLIElement>>;
11
+ export declare const Previous: React.ForwardRefExoticComponent<React.ButtonHTMLAttributes<HTMLButtonElement> & React.RefAttributes<HTMLButtonElement>>;
@@ -4,6 +4,6 @@
4
4
  * Use of this source code is governed under the Apache License, Version 2.0
5
5
  * found at http://www.apache.org/licenses/LICENSE-2.0.
6
6
  */
7
- export { Pagination } from './elements/Pagination/Pagination';
7
+ export { OffsetPagination } from './elements/OffsetPagination/OffsetPagination';
8
8
  export { CursorPagination } from './elements/CursorPagination/CursorPagination';
9
- export type { IPaginationProps, PageType as PAGE_TYPE } from './types';
9
+ export type { IPaginationProps, PageType } from './types';
@@ -5,10 +5,7 @@
5
5
  * found at http://www.apache.org/licenses/LICENSE-2.0.
6
6
  */
7
7
  import { DefaultTheme } from 'styled-components';
8
- export declare const StyledGap: import("styled-components").StyledComponent<"li", DefaultTheme, {
9
- 'data-garden-id': string;
10
- 'data-garden-version': string;
11
- } & {
8
+ export declare const StyledGapListItem: import("styled-components").StyledComponent<"li", DefaultTheme, {
12
9
  'data-garden-id': string;
13
10
  'data-garden-version': string;
14
11
  } & {
@@ -8,7 +8,7 @@
8
8
  * 1. List reset.
9
9
  * 2. Text truncation.
10
10
  */
11
- export declare const StyledPagination: import("styled-components").StyledComponent<"ul", import("styled-components").DefaultTheme, {
11
+ export declare const StyledList: import("styled-components").StyledComponent<"ul", import("styled-components").DefaultTheme, {
12
12
  'data-garden-id': string;
13
13
  'data-garden-version': string;
14
14
  }, "data-garden-id" | "data-garden-version">;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Copyright Zendesk, Inc.
3
+ *
4
+ * Use of this source code is governed under the Apache License, Version 2.0
5
+ * found at http://www.apache.org/licenses/LICENSE-2.0.
6
+ */
7
+ export declare const StyledListItem: import("styled-components").StyledComponent<"li", import("styled-components").DefaultTheme, {
8
+ 'data-garden-id': string;
9
+ 'data-garden-version': string;
10
+ }, "data-garden-id" | "data-garden-version">;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Copyright Zendesk, Inc.
3
+ *
4
+ * Use of this source code is governed under the Apache License, Version 2.0
5
+ * found at http://www.apache.org/licenses/LICENSE-2.0.
6
+ */
7
+ export declare const StyledNav: import("styled-components").StyledComponent<"nav", import("styled-components").DefaultTheme, {
8
+ 'data-garden-id': string;
9
+ 'data-garden-version': string;
10
+ }, "data-garden-id" | "data-garden-version">;
@@ -4,7 +4,7 @@
4
4
  * Use of this source code is governed under the Apache License, Version 2.0
5
5
  * found at http://www.apache.org/licenses/LICENSE-2.0.
6
6
  */
7
- export declare const StyledNavigation: import("styled-components").StyledComponent<"li", import("styled-components").DefaultTheme, {
7
+ export declare const StyledNavigation: import("styled-components").StyledComponent<"button", import("styled-components").DefaultTheme, {
8
8
  'data-garden-id': string;
9
9
  'data-garden-version': string;
10
10
  } & {
@@ -5,7 +5,7 @@
5
5
  * found at http://www.apache.org/licenses/LICENSE-2.0.
6
6
  */
7
7
  import { DefaultTheme } from 'styled-components';
8
- export declare const StyledPage: import("styled-components").StyledComponent<"li", DefaultTheme, {
8
+ export declare const StyledPage: import("styled-components").StyledComponent<"button", DefaultTheme, {
9
9
  'data-garden-id': string;
10
10
  'data-garden-version': string;
11
11
  } & {
@@ -5,7 +5,11 @@
5
5
  * found at http://www.apache.org/licenses/LICENSE-2.0.
6
6
  */
7
7
  import { DefaultTheme } from 'styled-components';
8
- export declare const StyledPageBase: import("styled-components").StyledComponent<"li", DefaultTheme, {
8
+ /**
9
+ * 1. <button> override.
10
+ * 2. Remove dotted outline from Firefox on focus.
11
+ */
12
+ export declare const StyledPageBase: import("styled-components").StyledComponent<"button", DefaultTheme, {
9
13
  'data-garden-id': string;
10
14
  'data-garden-version': string;
11
15
  }, "data-garden-id" | "data-garden-version">;
@@ -4,10 +4,12 @@
4
4
  * Use of this source code is governed under the Apache License, Version 2.0
5
5
  * found at http://www.apache.org/licenses/LICENSE-2.0.
6
6
  */
7
- export { StyledPagination } from './Pagination/StyledPagination';
8
- export { StyledPage } from './Pagination/StyledPage';
7
+ export { StyledList } from './OffsetPagination/StyledList';
8
+ export { StyledListItem } from './OffsetPagination/StyledListItem';
9
+ export { StyledPage } from './OffsetPagination/StyledPage';
9
10
  export { StyledCursorPagination } from './CursorPagination/StyledCursorPagination';
10
11
  export { StyledCursor } from './CursorPagination/StyledCursor';
11
12
  export { StyledIcon, type IStyledIcon } from './CursorPagination/StyledIcon';
12
- export { StyledGap } from './Pagination/StyledGap';
13
- export { StyledNavigation } from './Pagination/StyledNavigation';
13
+ export { StyledGapListItem } from './OffsetPagination/StyledGapListItem';
14
+ export { StyledNavigation } from './OffsetPagination/StyledNavigation';
15
+ export { StyledNav } from './OffsetPagination/StyledNav';
@@ -7,9 +7,9 @@
7
7
  import { HTMLAttributes } from 'react';
8
8
  export declare const PAGE_TYPE: readonly ["next", "page", "gap", "previous"];
9
9
  export type PageType = (typeof PAGE_TYPE)[number];
10
- export interface IPaginationProps extends Omit<HTMLAttributes<HTMLUListElement>, 'onChange'> {
10
+ export interface IPaginationProps extends Omit<HTMLAttributes<HTMLElement>, 'onChange'> {
11
11
  /**
12
- * Sets the current page. Pages start at 1.
12
+ * Sets the current page. Pages start at 1
13
13
  */
14
14
  currentPage: number;
15
15
  /**
@@ -32,11 +32,9 @@ export interface IPaginationProps extends Omit<HTMLAttributes<HTMLUListElement>,
32
32
  */
33
33
  onChange?: (currentPage: number) => void;
34
34
  /**
35
- * Applies localized labels, test attributes, etc. to individual pages
36
- *
37
- * @param {string} pageType The type of the page accepting the props
38
- * @param {any} props Default page props to transform
39
- * @param {number} pageNumber The page number
35
+ * Provides localized labels to pagination elements
40
36
  */
41
- transformPageProps?: (pageType: PageType, props: any, pageNumber?: number) => any;
37
+ labels?: Record<Exclude<PageType, 'page'>, string> & {
38
+ renderPage: (p: number) => string;
39
+ };
42
40
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zendeskgarden/react-pagination",
3
- "version": "9.0.0-next.1",
3
+ "version": "9.0.0-next.3",
4
4
  "description": "Components relating to pagination in the Garden Design System",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Zendesk Garden <garden@zendesk.com>",
@@ -21,7 +21,6 @@
21
21
  "sideEffects": false,
22
22
  "types": "dist/typings/index.d.ts",
23
23
  "dependencies": {
24
- "@zendeskgarden/container-pagination": "^1.0.0",
25
24
  "@zendeskgarden/container-utilities": "^2.0.0",
26
25
  "polished": "^4.0.0",
27
26
  "prop-types": "^15.5.7"
@@ -33,7 +32,7 @@
33
32
  "styled-components": "^5.1.0"
34
33
  },
35
34
  "devDependencies": {
36
- "@zendeskgarden/react-theming": "^9.0.0-next.1",
35
+ "@zendeskgarden/react-theming": "^9.0.0-next.3",
37
36
  "@zendeskgarden/svg-icons": "7.0.0"
38
37
  },
39
38
  "keywords": [
@@ -46,5 +45,5 @@
46
45
  "access": "public"
47
46
  },
48
47
  "zendeskgarden:src": "src/index.ts",
49
- "gitHead": "a9e4e776bf6ad8860a198fc24f27b2b5cbc83320"
48
+ "gitHead": "d5086e8a3ae0c8608361966954bf434ef03005ec"
50
49
  }