@instructure/ui-pagination 8.13.1-snapshot.9 → 8.14.0

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.
Files changed (65) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/es/Pagination/PaginationArrowButton/index.js +36 -4
  3. package/es/Pagination/PaginationArrowButton/props.js +6 -3
  4. package/es/Pagination/PaginationButton/props.js +9 -2
  5. package/es/Pagination/PaginationLocator.js +4 -0
  6. package/es/Pagination/PaginationPageInput/PaginationPageInputLocator.js +35 -0
  7. package/es/Pagination/PaginationPageInput/index.js +208 -0
  8. package/es/Pagination/PaginationPageInput/props.js +35 -0
  9. package/es/Pagination/PaginationPageInput/styles.js +55 -0
  10. package/es/Pagination/PaginationPageInput/theme.js +40 -0
  11. package/es/Pagination/index.js +178 -52
  12. package/es/Pagination/props.js +32 -2
  13. package/lib/Pagination/PaginationArrowButton/index.js +39 -3
  14. package/lib/Pagination/PaginationArrowButton/props.js +6 -3
  15. package/lib/Pagination/PaginationButton/props.js +9 -2
  16. package/lib/Pagination/PaginationLocator.js +5 -0
  17. package/lib/Pagination/PaginationPageInput/PaginationPageInputLocator.js +46 -0
  18. package/lib/Pagination/PaginationPageInput/index.js +202 -0
  19. package/lib/Pagination/PaginationPageInput/props.js +46 -0
  20. package/lib/Pagination/PaginationPageInput/styles.js +63 -0
  21. package/lib/Pagination/PaginationPageInput/theme.js +48 -0
  22. package/lib/Pagination/index.js +179 -52
  23. package/lib/Pagination/props.js +32 -2
  24. package/package.json +23 -22
  25. package/src/Pagination/PaginationArrowButton/index.tsx +32 -4
  26. package/src/Pagination/PaginationArrowButton/props.ts +22 -6
  27. package/src/Pagination/PaginationButton/props.ts +18 -2
  28. package/src/Pagination/PaginationLocator.ts +5 -1
  29. package/src/Pagination/PaginationPageInput/PaginationPageInputLocator.ts +42 -0
  30. package/src/Pagination/PaginationPageInput/index.tsx +242 -0
  31. package/src/Pagination/PaginationPageInput/props.ts +112 -0
  32. package/src/Pagination/PaginationPageInput/styles.ts +60 -0
  33. package/src/Pagination/PaginationPageInput/theme.ts +46 -0
  34. package/src/Pagination/README.md +116 -0
  35. package/src/Pagination/index.tsx +213 -80
  36. package/src/Pagination/props.ts +53 -4
  37. package/tsconfig.build.json +26 -2
  38. package/tsconfig.build.tsbuildinfo +1 -0
  39. package/types/Pagination/PaginationArrowButton/PaginationArrowButtonLocator.d.ts +57 -56
  40. package/types/Pagination/PaginationArrowButton/PaginationArrowButtonLocator.d.ts.map +1 -1
  41. package/types/Pagination/PaginationArrowButton/index.d.ts +9 -4
  42. package/types/Pagination/PaginationArrowButton/index.d.ts.map +1 -1
  43. package/types/Pagination/PaginationArrowButton/props.d.ts +5 -3
  44. package/types/Pagination/PaginationArrowButton/props.d.ts.map +1 -1
  45. package/types/Pagination/PaginationButton/index.d.ts +2 -0
  46. package/types/Pagination/PaginationButton/index.d.ts.map +1 -1
  47. package/types/Pagination/PaginationButton/props.d.ts +1 -0
  48. package/types/Pagination/PaginationButton/props.d.ts.map +1 -1
  49. package/types/Pagination/PaginationLocator.d.ts +944 -234
  50. package/types/Pagination/PaginationLocator.d.ts.map +1 -1
  51. package/types/Pagination/PaginationPageInput/PaginationPageInputLocator.d.ts +581 -0
  52. package/types/Pagination/PaginationPageInput/PaginationPageInputLocator.d.ts.map +1 -0
  53. package/types/Pagination/PaginationPageInput/index.d.ts +63 -0
  54. package/types/Pagination/PaginationPageInput/index.d.ts.map +1 -0
  55. package/types/Pagination/PaginationPageInput/props.d.ts +46 -0
  56. package/types/Pagination/PaginationPageInput/props.d.ts.map +1 -0
  57. package/types/Pagination/PaginationPageInput/styles.d.ts +15 -0
  58. package/types/Pagination/PaginationPageInput/styles.d.ts.map +1 -0
  59. package/types/Pagination/PaginationPageInput/theme.d.ts +10 -0
  60. package/types/Pagination/PaginationPageInput/theme.d.ts.map +1 -0
  61. package/types/Pagination/index.d.ts +50 -14
  62. package/types/Pagination/index.d.ts.map +1 -1
  63. package/types/Pagination/props.d.ts +13 -3
  64. package/types/Pagination/props.d.ts.map +1 -1
  65. package/LICENSE.md +0 -27
@@ -38,6 +38,8 @@ var _PaginationButton = require("./PaginationButton");
38
38
 
39
39
  var _PaginationArrowButton = require("./PaginationArrowButton");
40
40
 
41
+ var _PaginationPageInput = require("./PaginationPageInput");
42
+
41
43
  var _styles = _interopRequireDefault(require("./styles"));
42
44
 
43
45
  var _props = require("./props");
@@ -47,30 +49,35 @@ var _dec, _dec2, _class, _class2, _temp, _span, _span2;
47
49
  /** This is an [].findIndex optimized to work on really big, but sparse, arrays */
48
50
  const fastFindIndex = (arr, fn) => Number(Object.keys(arr).find(k => fn(arr[Number(k)])));
49
51
 
50
- function propsHaveCompactView(props) {
51
- var _props$children;
52
+ const childrenArray = props => {
53
+ const children = props.children;
52
54
 
53
- return props.variant === 'compact' && (props === null || props === void 0 ? void 0 : (_props$children = props.children) === null || _props$children === void 0 ? void 0 : _props$children.length) > 5;
54
- }
55
+ if (!children) {
56
+ return [];
57
+ }
55
58
 
56
- function shouldShowPrevButton(props, currentPageIndex) {
57
- return propsHaveCompactView(props) && currentPageIndex > 0;
58
- }
59
+ return Array.isArray(children) ? children : [children];
60
+ };
59
61
 
60
- function shouldShowNextButton(props, currentPageIndex) {
61
- return propsHaveCompactView(props) && currentPageIndex < props.children.length - 1;
62
+ function propsHaveCompactView(props) {
63
+ return props.variant === 'compact' && childrenArray(props).length > 5;
62
64
  }
65
+
63
66
  /**
64
67
  ---
65
68
  category: components
66
69
  ---
67
70
  **/
68
-
69
-
70
71
  let Pagination = (_dec = (0, _emotion.withStyle)(_styles.default, null), _dec2 = (0, _testable.testable)(), _dec(_class = _dec2(_class = (_temp = _class2 = class Pagination extends _react.Component {
71
72
  constructor() {
72
73
  super(...arguments);
74
+ this._labelId = void 0;
73
75
  this.ref = null;
76
+ this._inputRef = null;
77
+ this._firstButton = null;
78
+ this._prevButton = null;
79
+ this._nextButton = null;
80
+ this._lastButton = null;
74
81
 
75
82
  this.handleElementRef = el => {
76
83
  this.ref = el;
@@ -82,42 +89,87 @@ let Pagination = (_dec = (0, _emotion.withStyle)(_styles.default, null), _dec2 =
82
89
  }
83
90
  };
84
91
 
92
+ this.handleInputRef = el => {
93
+ this._inputRef = el;
94
+ };
95
+
85
96
  this._labelId = (0, _uid.uid)('Pagination');
86
- this._prevButton = null;
87
- this._nextButton = null;
88
97
  }
89
98
 
90
99
  get _root() {
91
100
  return this.ref;
92
101
  }
93
102
 
103
+ get inputMode() {
104
+ return this.props.variant === 'input';
105
+ }
106
+
107
+ get childPages() {
108
+ return childrenArray(this.props);
109
+ }
110
+
111
+ get withFirstAndLastButton() {
112
+ return this.inputMode || this.props.withFirstAndLastButton;
113
+ }
114
+
115
+ get showDisabledButtons() {
116
+ return this.inputMode || this.props.showDisabledButtons;
117
+ }
118
+
94
119
  getSnapshotBeforeUpdate() {
95
120
  const activeElement = (0, _getActiveElement.getActiveElement)();
96
- return {
97
- prevButtonFocused: this._prevButton === activeElement,
98
- nextButtonFocused: this._nextButton === activeElement
99
- };
121
+
122
+ if (activeElement === this._firstButton || activeElement === this._prevButton || activeElement === this._nextButton || activeElement === this._lastButton) {
123
+ return {
124
+ lastFocusedButton: activeElement
125
+ };
126
+ } else {
127
+ return {
128
+ lastFocusedButton: void 0
129
+ };
130
+ }
100
131
  }
101
132
 
102
133
  componentDidMount() {
103
- this.props.makeStyles();
134
+ var _this$props$makeStyle, _this$props;
135
+
136
+ (_this$props$makeStyle = (_this$props = this.props).makeStyles) === null || _this$props$makeStyle === void 0 ? void 0 : _this$props$makeStyle.call(_this$props);
104
137
  }
105
138
 
106
- componentDidUpdate(prevProps, prevState, snapshot) {
107
- this.props.makeStyles();
139
+ componentDidUpdate(prevProps, _prevState, snapshot) {
140
+ var _this$props$makeStyle2, _this$props2;
141
+
142
+ (_this$props$makeStyle2 = (_this$props2 = this.props).makeStyles) === null || _this$props$makeStyle2 === void 0 ? void 0 : _this$props$makeStyle2.call(_this$props2);
108
143
 
109
144
  if (!this.props.shouldHandleFocus || !propsHaveCompactView(prevProps) && !propsHaveCompactView(this.props)) {
110
145
  return;
146
+ } else {
147
+ this.focusElementAfterUpdate(snapshot);
111
148
  }
149
+ }
112
150
 
113
- const _ref = snapshot || {},
114
- prevButtonFocused = _ref.prevButtonFocused,
115
- nextButtonFocused = _ref.nextButtonFocused;
151
+ focusElementAfterUpdate(snapshot) {
152
+ const lastFocusedButton = snapshot.lastFocusedButton;
116
153
 
117
- if (prevButtonFocused || nextButtonFocused) {
154
+ if (lastFocusedButton) {
118
155
  const focusable = (0, _findTabbable.findTabbable)(this.ref);
119
- const focusIndex = prevButtonFocused ? 0 : focusable.length - 1;
120
- focusable[focusIndex].focus();
156
+ const direction = lastFocusedButton.dataset.direction; // By default we want to focus the previously focused button
157
+
158
+ let nextFocusElement = lastFocusedButton; // In case the button is not focusable anymore
159
+ // (disabled or not in the DOM), we focus to the next available page
160
+
161
+ if (!focusable.includes(nextFocusElement)) {
162
+ if (direction === 'first' || direction === 'prev') {
163
+ nextFocusElement = focusable[0];
164
+ }
165
+
166
+ if (direction === 'next' || direction === 'last') {
167
+ nextFocusElement = focusable[focusable.length - 1];
168
+ }
169
+ }
170
+
171
+ ;
172
+ nextFocusElement.focus();
121
173
  }
122
174
  }
123
175
 
@@ -126,13 +178,13 @@ let Pagination = (_dec = (0, _emotion.withStyle)(_styles.default, null), _dec2 =
126
178
  }
127
179
 
128
180
  transferDisabledPropToChildren(children) {
129
- return this.props.disabled ? _react.default.Children.map(children, page => /*#__PURE__*/_react.default.cloneElement(page, {
181
+ return children && this.props.disabled ? _react.default.Children.map(children, page => /*#__PURE__*/_react.default.cloneElement(page, {
130
182
  disabled: this.props.disabled
131
183
  })) : children;
132
184
  }
133
185
 
134
186
  renderLabel() {
135
- const display = this.props.variant === 'compact' ? 'block' : 'inline-block';
187
+ const display = this.props.variant === 'full' ? 'inline-block' : 'block';
136
188
  const visibleLabel = (0, _hasVisibleChildren.hasVisibleChildren)(this.props.label);
137
189
  return (0, _emotion.jsx)(_View.View, {
138
190
  as: "span",
@@ -142,8 +194,26 @@ let Pagination = (_dec = (0, _emotion.withStyle)(_styles.default, null), _dec2 =
142
194
  }, this.props.label);
143
195
  }
144
196
 
197
+ renderPageInput(currentPageIndex) {
198
+ return (0, _emotion.jsx)(_PaginationPageInput.PaginationPageInput, {
199
+ numberOfPages: this.childPages.length,
200
+ currentPageIndex: currentPageIndex,
201
+ onChange: this.handleInputChange.bind(this),
202
+ screenReaderLabel: this.props.screenReaderLabelNumberInput,
203
+ label: this.props.labelNumberInput,
204
+ disabled: this.props.disabled,
205
+ inputRef: this.handleInputRef
206
+ });
207
+ }
208
+
209
+ handleInputChange(event, pageIndex) {
210
+ var _this$childPages$page, _this$childPages$page2;
211
+
212
+ (_this$childPages$page = (_this$childPages$page2 = this.childPages[pageIndex].props).onClick) === null || _this$childPages$page === void 0 ? void 0 : _this$childPages$page.call(_this$childPages$page2, event);
213
+ }
214
+
145
215
  renderPages(currentPageIndex) {
146
- const allPages = this.props.children;
216
+ const allPages = this.childPages;
147
217
  let visiblePages = allPages;
148
218
 
149
219
  if (this.compactView) {
@@ -155,14 +225,14 @@ let Pagination = (_dec = (0, _emotion.withStyle)(_styles.default, null), _dec2 =
155
225
  const firstPage = allPages[firstIndex];
156
226
  const lastPage = allPages[lastIndex];
157
227
  if (sliceStart - firstIndex > 1) visiblePages.unshift(_span || (_span = (0, _emotion.jsx)("span", {
158
- key: "first",
159
- "aria-hidden": "true"
160
- }, "\u2026")));
228
+ key: "first",
229
+ "aria-hidden": "true"
230
+ }, "\u2026")));
161
231
  if (sliceStart - firstIndex > 0) visiblePages.unshift(firstPage);
162
232
  if (lastIndex - sliceEnd + 1 > 1) visiblePages.push(_span2 || (_span2 = (0, _emotion.jsx)("span", {
163
- key: "last",
164
- "aria-hidden": "true"
165
- }, "\u2026")));
233
+ key: "last",
234
+ "aria-hidden": "true"
235
+ }, "\u2026")));
166
236
  if (lastIndex - sliceEnd + 1 > 0) visiblePages.push(lastPage);
167
237
  }
168
238
 
@@ -171,27 +241,80 @@ let Pagination = (_dec = (0, _emotion.withStyle)(_styles.default, null), _dec2 =
171
241
  }, this.transferDisabledPropToChildren(visiblePages));
172
242
  }
173
243
 
174
- renderArrowButton(label, direction, currentPageIndex) {
175
- // eslint-disable-next-line react/prop-types
176
- const _this$props$children$ = this.props.children[currentPageIndex + direction].props,
177
- onClick = _this$props$children$.onClick,
178
- disabled = _this$props$children$.disabled;
244
+ getArrowVariant(direction, currentPageIndex, pagesCount) {
245
+ switch (direction) {
246
+ case 'first':
247
+ return {
248
+ pageIndex: 0,
249
+ label: this.props.labelFirst || 'First Page',
250
+ shouldEnableIcon: currentPageIndex > 1,
251
+ handleButtonRef: el => {
252
+ this._firstButton = el;
253
+ }
254
+ };
255
+
256
+ case 'prev':
257
+ return {
258
+ pageIndex: currentPageIndex - 1,
259
+ label: this.props.labelPrev || 'Previous Page',
260
+ shouldEnableIcon: currentPageIndex > 0,
261
+ handleButtonRef: el => {
262
+ this._prevButton = el;
263
+ }
264
+ };
265
+
266
+ case 'next':
267
+ return {
268
+ pageIndex: currentPageIndex + 1,
269
+ label: this.props.labelNext || 'Next Page',
270
+ shouldEnableIcon: currentPageIndex < pagesCount - 1,
271
+ handleButtonRef: el => {
272
+ this._nextButton = el;
273
+ }
274
+ };
275
+
276
+ case 'last':
277
+ return {
278
+ pageIndex: pagesCount - 1,
279
+ label: this.props.labelLast || 'Last Page',
280
+ shouldEnableIcon: currentPageIndex < pagesCount - 2,
281
+ handleButtonRef: el => {
282
+ this._lastButton = el;
283
+ }
284
+ };
285
+ }
286
+ }
179
287
 
180
- const handleButtonRef = el => {
181
- if (direction < 0) {
182
- this._prevButton = el;
183
- } else {
184
- this._nextButton = el;
185
- }
186
- };
288
+ renderArrowButton(direction, currentPageIndex) {
289
+ var _page$props, _page$props2;
187
290
 
188
- return (0, _emotion.jsx)(_PaginationArrowButton.PaginationArrowButton, {
189
- direction: direction === -1 ? 'prev' : 'next',
291
+ const childPages = this.childPages; // We don't display the arrows in "compact" variant under 6 items
292
+
293
+ if (!(propsHaveCompactView(this.props) || this.inputMode)) {
294
+ return null;
295
+ }
296
+
297
+ if (!this.withFirstAndLastButton && (direction === 'first' || direction === 'last')) {
298
+ return null;
299
+ }
300
+
301
+ const _this$getArrowVariant = this.getArrowVariant(direction, currentPageIndex, childPages.length),
302
+ pageIndex = _this$getArrowVariant.pageIndex,
303
+ label = _this$getArrowVariant.label,
304
+ shouldEnableIcon = _this$getArrowVariant.shouldEnableIcon,
305
+ handleButtonRef = _this$getArrowVariant.handleButtonRef;
306
+
307
+ const page = childPages[pageIndex];
308
+ const disabled = (page === null || page === void 0 ? void 0 : (_page$props = page.props) === null || _page$props === void 0 ? void 0 : _page$props.disabled) || this.props.disabled || !shouldEnableIcon;
309
+ const onClick = page === null || page === void 0 ? void 0 : (_page$props2 = page.props) === null || _page$props2 === void 0 ? void 0 : _page$props2.onClick;
310
+ return shouldEnableIcon || this.showDisabledButtons ? (0, _emotion.jsx)(_PaginationArrowButton.PaginationArrowButton, {
311
+ direction: direction,
312
+ "data-direction": direction,
190
313
  label: label,
191
314
  onClick: onClick,
192
315
  disabled: disabled,
193
316
  buttonRef: handleButtonRef
194
- });
317
+ }) : null;
195
318
  }
196
319
 
197
320
  render() {
@@ -208,19 +331,23 @@ let Pagination = (_dec = (0, _emotion.withStyle)(_styles.default, null), _dec2 =
208
331
  elementRef: this.handleElementRef,
209
332
  margin: this.props.margin,
210
333
  css: (_this$props$styles = this.props.styles) === null || _this$props$styles === void 0 ? void 0 : _this$props$styles.pagination,
211
- "aria-labelledby": this.props.label && this._labelId
334
+ "aria-labelledby": this.props.label ? this._labelId : void 0
212
335
  }), this.props.label && this.renderLabel(), (0, _emotion.jsx)(_View.View, {
213
336
  display: "inline-block",
214
337
  css: (_this$props$styles2 = this.props.styles) === null || _this$props$styles2 === void 0 ? void 0 : _this$props$styles2.pages
215
- }, shouldShowPrevButton(this.props, currentPageIndex) && this.renderArrowButton(this.props.labelPrev, -1, currentPageIndex), this.renderPages(currentPageIndex), shouldShowNextButton(this.props, currentPageIndex) && this.renderArrowButton(this.props.labelNext, 1, currentPageIndex)));
338
+ }, this.renderArrowButton('first', currentPageIndex), this.renderArrowButton('prev', currentPageIndex), this.inputMode ? this.renderPageInput(currentPageIndex) : this.renderPages(currentPageIndex), this.renderArrowButton('next', currentPageIndex), this.renderArrowButton('last', currentPageIndex)));
216
339
  }
217
340
 
218
341
  }, _class2.displayName = "Pagination", _class2.componentId = 'Pagination', _class2.propTypes = _props.propTypes, _class2.allowedProps = _props.allowedProps, _class2.defaultProps = {
219
342
  children: null,
220
343
  disabled: false,
344
+ withFirstAndLastButton: false,
345
+ showDisabledButtons: false,
221
346
  variant: 'full',
222
347
  as: 'div',
223
348
  elementRef: el => {},
349
+ labelNumberInput: numberOfPages => `of ${numberOfPages}`,
350
+ screenReaderLabelNumberInput: (currentPage, numberOfPages) => `Select page (${currentPage} of ${numberOfPages})`,
224
351
  shouldHandleFocus: true
225
352
  }, _class2.Page = _PaginationButton.PaginationButton, _class2.Navigation = _PaginationArrowButton.PaginationArrowButton, _temp)) || _class) || _class);
226
353
  exports.Pagination = Pagination;
@@ -49,6 +49,16 @@ const propTypes = {
49
49
  */
50
50
  disabled: _propTypes.default.bool,
51
51
 
52
+ /**
53
+ * Displays "jump to first" and "jump to last" buttons. Always turned on with `input` variant.
54
+ */
55
+ withFirstAndLastButton: _propTypes.default.bool,
56
+
57
+ /**
58
+ * Displays the unavailable navigation buttons as disabled instead of hiding them. Always turned on with `input` variant.
59
+ */
60
+ showDisabledButtons: _propTypes.default.bool,
61
+
52
62
  /**
53
63
  * Visible label for component
54
64
  */
@@ -64,12 +74,32 @@ const propTypes = {
64
74
  */
65
75
  labelPrev: _propTypes.default.string,
66
76
 
77
+ /**
78
+ * Accessible label for "jump to first" button
79
+ */
80
+ labelFirst: _propTypes.default.string,
81
+
82
+ /**
83
+ * Accessible label for "jump to last" button
84
+ */
85
+ labelLast: _propTypes.default.string,
86
+
87
+ /**
88
+ * Label for number input (for `input` variant)
89
+ */
90
+ labelNumberInput: _propTypes.default.func,
91
+
92
+ /**
93
+ * ScreenReaderLabel for number input (for `input` variant)
94
+ */
95
+ screenReaderLabelNumberInput: _propTypes.default.func,
96
+
67
97
  /**
68
98
  * The compact variant truncates the page navigation to show only the first,
69
99
  * last, and pages immediately surrounding the current page. Fewer than 5 pages,
70
100
  * no next/previous arrow buttons will be shown, and all pages will be listed
71
101
  */
72
- variant: _propTypes.default.oneOf(['full', 'compact']),
102
+ variant: _propTypes.default.oneOf(['full', 'compact', 'input']),
73
103
 
74
104
  /**
75
105
  * Valid values are `0`, `none`, `auto`, `xxx-small`, `xx-small`, `x-small`,
@@ -96,5 +126,5 @@ const propTypes = {
96
126
  shouldHandleFocus: _propTypes.default.bool
97
127
  };
98
128
  exports.propTypes = propTypes;
99
- const allowedProps = ['children', 'disabled', 'label', 'labelNext', 'labelPrev', 'variant', 'margin', 'as', 'elementRef', 'shouldHandleFocus'];
129
+ const allowedProps = ['children', 'disabled', 'withFirstAndLastButton', 'showDisabledButtons', 'label', 'labelNext', 'labelPrev', 'labelFirst', 'labelLast', 'labelNumberInput', 'screenReaderLabelNumberInput', 'variant', 'margin', 'as', 'elementRef', 'shouldHandleFocus'];
100
130
  exports.allowedProps = allowedProps;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@instructure/ui-pagination",
3
- "version": "8.13.1-snapshot.9+f32ba918e",
3
+ "version": "8.14.0",
4
4
  "description": "A UI component library made by Instructure Inc.",
5
5
  "author": "Instructure, Inc. Engineering and Product Design",
6
6
  "type": "commonjs",
@@ -24,28 +24,30 @@
24
24
  },
25
25
  "license": "MIT",
26
26
  "devDependencies": {
27
- "@instructure/ui-babel-preset": "8.13.1-snapshot.9+f32ba918e",
28
- "@instructure/ui-test-locator": "8.13.1-snapshot.9+f32ba918e",
29
- "@instructure/ui-test-queries": "8.13.1-snapshot.9+f32ba918e",
30
- "@instructure/ui-test-utils": "8.13.1-snapshot.9+f32ba918e"
27
+ "@instructure/ui-babel-preset": "8.14.0",
28
+ "@instructure/ui-test-locator": "8.14.0",
29
+ "@instructure/ui-test-queries": "8.14.0",
30
+ "@instructure/ui-test-utils": "8.14.0"
31
31
  },
32
32
  "dependencies": {
33
33
  "@babel/runtime": "^7.13.10",
34
- "@instructure/emotion": "8.13.1-snapshot.9+f32ba918e",
35
- "@instructure/shared-types": "8.13.1-snapshot.9+f32ba918e",
36
- "@instructure/ui-a11y-content": "8.13.1-snapshot.9+f32ba918e",
37
- "@instructure/ui-a11y-utils": "8.13.1-snapshot.9+f32ba918e",
38
- "@instructure/ui-buttons": "8.13.1-snapshot.9+f32ba918e",
39
- "@instructure/ui-dom-utils": "8.13.1-snapshot.9+f32ba918e",
40
- "@instructure/ui-icons": "8.13.1-snapshot.9+f32ba918e",
41
- "@instructure/ui-portal": "8.13.1-snapshot.9+f32ba918e",
42
- "@instructure/ui-prop-types": "8.13.1-snapshot.9+f32ba918e",
43
- "@instructure/ui-react-utils": "8.13.1-snapshot.9+f32ba918e",
44
- "@instructure/ui-testable": "8.13.1-snapshot.9+f32ba918e",
45
- "@instructure/ui-tooltip": "8.13.1-snapshot.9+f32ba918e",
46
- "@instructure/ui-utils": "8.13.1-snapshot.9+f32ba918e",
47
- "@instructure/ui-view": "8.13.1-snapshot.9+f32ba918e",
48
- "@instructure/uid": "8.13.1-snapshot.9+f32ba918e",
34
+ "@instructure/emotion": "8.14.0",
35
+ "@instructure/shared-types": "8.14.0",
36
+ "@instructure/ui-a11y-content": "8.14.0",
37
+ "@instructure/ui-a11y-utils": "8.14.0",
38
+ "@instructure/ui-buttons": "8.14.0",
39
+ "@instructure/ui-dom-utils": "8.14.0",
40
+ "@instructure/ui-icons": "8.14.0",
41
+ "@instructure/ui-number-input": "8.14.0",
42
+ "@instructure/ui-portal": "8.14.0",
43
+ "@instructure/ui-prop-types": "8.14.0",
44
+ "@instructure/ui-react-utils": "8.14.0",
45
+ "@instructure/ui-testable": "8.14.0",
46
+ "@instructure/ui-tooltip": "8.14.0",
47
+ "@instructure/ui-utils": "8.14.0",
48
+ "@instructure/ui-view": "8.14.0",
49
+ "@instructure/uid": "8.14.0",
50
+ "keycode": "^2",
49
51
  "prop-types": "^15"
50
52
  },
51
53
  "peerDependencies": {
@@ -54,6 +56,5 @@
54
56
  "publishConfig": {
55
57
  "access": "public"
56
58
  },
57
- "sideEffects": false,
58
- "gitHead": "f32ba918e4d3ce76c6ee95c856584d00a9d80958"
59
+ "sideEffects": false
59
60
  }
@@ -29,9 +29,12 @@ import { PresentationContent } from '@instructure/ui-a11y-content'
29
29
  import { Tooltip } from '@instructure/ui-tooltip'
30
30
  import {
31
31
  IconArrowOpenStartSolid,
32
- IconArrowOpenEndSolid
32
+ IconArrowOpenEndSolid,
33
+ IconArrowDoubleStartSolid,
34
+ IconArrowDoubleEndSolid
33
35
  } from '@instructure/ui-icons'
34
36
  import { testable } from '@instructure/ui-testable'
37
+
35
38
  import type { PaginationNavigationProps } from './props'
36
39
  import { allowedProps, propTypes } from './props'
37
40
 
@@ -59,10 +62,34 @@ class PaginationArrowButton extends Component<PaginationNavigationProps> {
59
62
  this.ref = el
60
63
  }
61
64
 
65
+ get margin() {
66
+ switch (this.props.direction) {
67
+ case 'first':
68
+ return '0 xx-small 0 0'
69
+ case 'last':
70
+ return '0 0 0 xx-small'
71
+ default:
72
+ return undefined
73
+ }
74
+ }
75
+
76
+ get Icon() {
77
+ switch (this.props.direction) {
78
+ case 'first':
79
+ return IconArrowDoubleStartSolid
80
+ case 'prev':
81
+ return IconArrowOpenStartSolid
82
+ case 'next':
83
+ return IconArrowOpenEndSolid
84
+ case 'last':
85
+ return IconArrowDoubleEndSolid
86
+ default:
87
+ return null
88
+ }
89
+ }
90
+
62
91
  render() {
63
92
  const { label, direction, buttonRef, ...props } = this.props
64
- const Icon =
65
- direction === 'prev' ? IconArrowOpenStartSolid : IconArrowOpenEndSolid
66
93
  return (
67
94
  <Tooltip
68
95
  on={['hover', 'focus']}
@@ -82,8 +109,9 @@ class PaginationArrowButton extends Component<PaginationNavigationProps> {
82
109
  // @ts-expect-error ts-migrate(2339) FIXME: Property 'href' does not exist on type '{ children... Remove this comment to see the full error message
83
110
  rel={props.href || props.to ? direction : undefined}
84
111
  elementRef={buttonRef}
112
+ margin={this.margin}
85
113
  >
86
- {Icon}
114
+ {this.Icon}
87
115
  </IconButton>
88
116
  </Tooltip>
89
117
  )
@@ -30,10 +30,18 @@ import type {
30
30
  PropValidators
31
31
  } from '@instructure/shared-types'
32
32
 
33
+ type PaginationArrowDirections = 'first' | 'prev' | 'next' | 'last'
34
+
33
35
  type PaginationNavigationOwnProps = {
34
- direction?: 'next' | 'prev'
35
- label: string | React.ReactNode
36
+ direction?: PaginationArrowDirections
37
+ label: string | React.ReactChild | React.ReactFragment
36
38
  buttonRef?: (...args: any[]) => any
39
+ onClick?: (
40
+ event:
41
+ | React.KeyboardEvent<HTMLInputElement>
42
+ | React.MouseEvent<HTMLButtonElement>
43
+ | React.FocusEvent<HTMLInputElement>
44
+ ) => void
37
45
  }
38
46
 
39
47
  type PropKeys = keyof PaginationNavigationOwnProps
@@ -44,12 +52,20 @@ type PaginationNavigationProps = PaginationNavigationOwnProps &
44
52
  OtherHTMLAttributes<PaginationNavigationOwnProps>
45
53
 
46
54
  const propTypes: PropValidators<PropKeys> = {
47
- direction: PropTypes.oneOf(['next', 'prev']),
55
+ direction: PropTypes.oneOf(['first', 'prev', 'next', 'last']),
48
56
  label: PropTypes.oneOfType([PropTypes.string, PropTypes.node]).isRequired,
49
- buttonRef: PropTypes.func
57
+ buttonRef: PropTypes.func,
58
+ onClick: PropTypes.func
50
59
  }
51
60
 
52
- const allowedProps: AllowedPropKeys = ['direction', 'label', 'buttonRef']
61
+ const allowedProps: AllowedPropKeys = [
62
+ 'direction',
63
+ 'label',
64
+ 'buttonRef'
65
+
66
+ // we don't want to pass onClick
67
+ // 'onClick'
68
+ ]
53
69
 
54
- export type { PaginationNavigationProps }
70
+ export type { PaginationNavigationProps, PaginationArrowDirections }
55
71
  export { propTypes, allowedProps }
@@ -33,6 +33,12 @@ import type {
33
33
  type PaginationPageOwnProps = {
34
34
  children: React.ReactNode
35
35
  current?: boolean
36
+ onClick?: (
37
+ event:
38
+ | React.KeyboardEvent<HTMLInputElement>
39
+ | React.MouseEvent<HTMLButtonElement>
40
+ | React.FocusEvent<HTMLInputElement>
41
+ ) => void
36
42
  }
37
43
 
38
44
  type PropKeys = keyof PaginationPageOwnProps
@@ -50,10 +56,20 @@ const propTypes: PropValidators<PropKeys> = {
50
56
  /**
51
57
  * Whether the page is currently displayed
52
58
  */
53
- current: PropTypes.bool
59
+ current: PropTypes.bool,
60
+ /**
61
+ * Whether the page is currently displayed
62
+ */
63
+ onClick: PropTypes.func
54
64
  }
55
65
 
56
- const allowedProps: AllowedPropKeys = ['children', 'current']
66
+ const allowedProps: AllowedPropKeys = [
67
+ 'children',
68
+ 'current'
69
+
70
+ // we don't want to pass onClick
71
+ // 'onClick'
72
+ ]
57
73
 
58
74
  export type { PaginationPageProps }
59
75
  export { propTypes, allowedProps }
@@ -23,6 +23,7 @@
23
23
  */
24
24
  import { locator } from '@instructure/ui-test-locator'
25
25
 
26
+ import { PaginationPageInputLocator } from './PaginationPageInput/PaginationPageInputLocator'
26
27
  import { PaginationArrowButtonLocator } from './PaginationArrowButton/PaginationArrowButtonLocator'
27
28
  import { Pagination } from './index'
28
29
 
@@ -38,5 +39,8 @@ export const PaginationLocator = locator(Pagination.selector, {
38
39
  PaginationButtonLocator.find(...args),
39
40
 
40
41
  findArrowButton: async (...args: any[]) =>
41
- PaginationArrowButtonLocator.find(...args)
42
+ PaginationArrowButtonLocator.find(...args),
43
+
44
+ findPageInput: async (...args: any[]) =>
45
+ PaginationPageInputLocator.find(...args)
42
46
  })
@@ -0,0 +1,42 @@
1
+ /*
2
+ * The MIT License (MIT)
3
+ *
4
+ * Copyright (c) 2015 - present Instructure, Inc.
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ * of this software and associated documentation files (the "Software"), to deal
8
+ * in the Software without restriction, including without limitation the rights
9
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ * copies of the Software, and to permit persons to whom the Software is
11
+ * furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in all
14
+ * copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ * SOFTWARE.
23
+ */
24
+
25
+ import { locator } from '@instructure/ui-test-locator'
26
+
27
+ // @ts-expect-error ts-migrate(7016) FIXME: Could not find a declaration file for module '@ins... Remove this comment to see the full error message
28
+ import { NumberInputLocator } from '@instructure/ui-number-input/es/NumberInput/NumberInputLocator' // eslint-disable-line no-restricted-imports
29
+
30
+ import { PaginationPageInput } from './index'
31
+
32
+ export const PaginationPageInputLocator = locator(
33
+ // @ts-expect-error ts-migrate(2339) FIXME: Property 'selector' does not exist on type 'typeof... Remove this comment to see the full error message
34
+ PaginationPageInput.selector,
35
+
36
+ {
37
+ findInput: (...args: any[]) => NumberInputLocator.findInput(...args),
38
+
39
+ findNumberInputArrows: (...args: any[]) =>
40
+ NumberInputLocator.findArrowButtons(...args)
41
+ }
42
+ )