@canonical/react-components 0.34.1 → 0.36.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.
- package/dist/components/Field/Field.d.ts +5 -1
- package/dist/components/Field/Field.js +6 -1
- package/dist/components/Input/Input.d.ts +5 -1
- package/dist/components/Input/Input.js +3 -1
- package/dist/components/MainTable/MainTable.js +96 -77
- package/dist/components/Tooltip/Tooltip.js +30 -1
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.js +9 -1
- package/dist/hooks/usePagination.d.ts +19 -0
- package/dist/hooks/usePagination.js +74 -0
- package/package.json +5 -5
|
@@ -28,6 +28,10 @@ export declare type Props = {
|
|
|
28
28
|
* Help text to show below the field.
|
|
29
29
|
*/
|
|
30
30
|
help?: ReactNode;
|
|
31
|
+
/**
|
|
32
|
+
* Optional class(es) to pass to the help text element.
|
|
33
|
+
*/
|
|
34
|
+
helpClassName?: ReactNode;
|
|
31
35
|
/**
|
|
32
36
|
* An id to give to the help element.
|
|
33
37
|
*/
|
|
@@ -69,5 +73,5 @@ export declare type Props = {
|
|
|
69
73
|
*/
|
|
70
74
|
validationId?: string;
|
|
71
75
|
};
|
|
72
|
-
declare const Field: ({ caution, children, className, error, forId, help, helpId, isSelect, isTickElement, label, labelClassName, labelFirst, required, stacked, success, validationId, }: Props) => JSX.Element;
|
|
76
|
+
declare const Field: ({ caution, children, className, error, forId, help, helpClassName, helpId, isSelect, isTickElement, label, labelClassName, labelFirst, required, stacked, success, validationId, }: Props) => JSX.Element;
|
|
73
77
|
export default Field;
|
|
@@ -18,9 +18,10 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
|
18
18
|
var generateHelpText = function generateHelpText(_ref) {
|
|
19
19
|
var help = _ref.help,
|
|
20
20
|
helpId = _ref.helpId,
|
|
21
|
+
helpClassName = _ref.helpClassName,
|
|
21
22
|
isTickElement = _ref.isTickElement;
|
|
22
23
|
return help ? /*#__PURE__*/_react.default.createElement("p", {
|
|
23
|
-
className: (0, _classnames.default)("p-form-help-text", {
|
|
24
|
+
className: (0, _classnames.default)("p-form-help-text", helpClassName, {
|
|
24
25
|
"is-tick-element": isTickElement
|
|
25
26
|
}),
|
|
26
27
|
id: helpId
|
|
@@ -65,6 +66,7 @@ var generateContent = function generateContent(_ref2) {
|
|
|
65
66
|
labelFirst = _ref2.labelFirst,
|
|
66
67
|
labelNode = _ref2.labelNode,
|
|
67
68
|
help = _ref2.help,
|
|
69
|
+
helpClassName = _ref2.helpClassName,
|
|
68
70
|
error = _ref2.error,
|
|
69
71
|
caution = _ref2.caution,
|
|
70
72
|
success = _ref2.success,
|
|
@@ -78,6 +80,7 @@ var generateContent = function generateContent(_ref2) {
|
|
|
78
80
|
}, children) : children, !labelFirst && labelNode, generateHelpText({
|
|
79
81
|
helpId: helpId,
|
|
80
82
|
help: help,
|
|
83
|
+
helpClassName: helpClassName,
|
|
81
84
|
isTickElement: isTickElement
|
|
82
85
|
}), generateError(error, caution, success, validationId));
|
|
83
86
|
};
|
|
@@ -89,6 +92,7 @@ var Field = function Field(_ref3) {
|
|
|
89
92
|
error = _ref3.error,
|
|
90
93
|
forId = _ref3.forId,
|
|
91
94
|
help = _ref3.help,
|
|
95
|
+
helpClassName = _ref3.helpClassName,
|
|
92
96
|
helpId = _ref3.helpId,
|
|
93
97
|
isSelect = _ref3.isSelect,
|
|
94
98
|
isTickElement = _ref3.isTickElement,
|
|
@@ -108,6 +112,7 @@ var Field = function Field(_ref3) {
|
|
|
108
112
|
labelFirst: labelFirst,
|
|
109
113
|
labelNode: labelNode,
|
|
110
114
|
help: help,
|
|
115
|
+
helpClassName: helpClassName,
|
|
111
116
|
error: error,
|
|
112
117
|
caution: caution,
|
|
113
118
|
success: success,
|
|
@@ -20,6 +20,10 @@ export declare type Props = PropsWithSpread<{
|
|
|
20
20
|
* Help text to show below the field.
|
|
21
21
|
*/
|
|
22
22
|
help?: ReactNode;
|
|
23
|
+
/**
|
|
24
|
+
* Optional class(es) to pass to the help text element.
|
|
25
|
+
*/
|
|
26
|
+
helpClassName?: ReactNode;
|
|
23
27
|
/**
|
|
24
28
|
* The id of the input.
|
|
25
29
|
*/
|
|
@@ -53,5 +57,5 @@ export declare type Props = PropsWithSpread<{
|
|
|
53
57
|
*/
|
|
54
58
|
wrapperClassName?: string;
|
|
55
59
|
}, InputHTMLAttributes<HTMLInputElement>>;
|
|
56
|
-
declare const Input: ({ caution, className, error, help, id, label, labelClassName, required, stacked, success, takeFocus, type, wrapperClassName, ...inputProps }: Props) => JSX.Element;
|
|
60
|
+
declare const Input: ({ caution, className, error, help, helpClassName, id, label, labelClassName, required, stacked, success, takeFocus, type, wrapperClassName, ...inputProps }: Props) => JSX.Element;
|
|
57
61
|
export default Input;
|
|
@@ -19,7 +19,7 @@ var _RadioInput = _interopRequireDefault(require("../RadioInput"));
|
|
|
19
19
|
|
|
20
20
|
var _hooks = require("../../hooks");
|
|
21
21
|
|
|
22
|
-
var _excluded = ["caution", "className", "error", "help", "id", "label", "labelClassName", "required", "stacked", "success", "takeFocus", "type", "wrapperClassName"];
|
|
22
|
+
var _excluded = ["caution", "className", "error", "help", "helpClassName", "id", "label", "labelClassName", "required", "stacked", "success", "takeFocus", "type", "wrapperClassName"];
|
|
23
23
|
|
|
24
24
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
25
25
|
|
|
@@ -44,6 +44,7 @@ var Input = function Input(_ref) {
|
|
|
44
44
|
className = _ref.className,
|
|
45
45
|
error = _ref.error,
|
|
46
46
|
help = _ref.help,
|
|
47
|
+
helpClassName = _ref.helpClassName,
|
|
47
48
|
id = _ref.id,
|
|
48
49
|
label = _ref.label,
|
|
49
50
|
labelClassName = _ref.labelClassName,
|
|
@@ -101,6 +102,7 @@ var Input = function Input(_ref) {
|
|
|
101
102
|
error: error,
|
|
102
103
|
forId: id,
|
|
103
104
|
help: help,
|
|
105
|
+
helpClassName: helpClassName,
|
|
104
106
|
helpId: helpId,
|
|
105
107
|
isTickElement: type === "checkbox" || type === "radio",
|
|
106
108
|
label: fieldLabel,
|
|
@@ -19,6 +19,8 @@ var _TableHeader = _interopRequireDefault(require("../TableHeader"));
|
|
|
19
19
|
|
|
20
20
|
var _TableCell = _interopRequireDefault(require("../TableCell"));
|
|
21
21
|
|
|
22
|
+
var _hooks = require("../../hooks");
|
|
23
|
+
|
|
22
24
|
var _excluded = ["content", "sortKey"],
|
|
23
25
|
_excluded2 = ["columns", "expanded", "expandedContent", "key", "sortData"],
|
|
24
26
|
_excluded3 = ["content"],
|
|
@@ -102,10 +104,59 @@ var generateHeaders = function generateHeaders(currentSortKey, currentSortDirect
|
|
|
102
104
|
})));
|
|
103
105
|
};
|
|
104
106
|
|
|
105
|
-
var generateRows = function generateRows(
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
107
|
+
var generateRows = function generateRows(_ref2) {
|
|
108
|
+
var rows = _ref2.rows,
|
|
109
|
+
headers = _ref2.headers,
|
|
110
|
+
responsive = _ref2.responsive,
|
|
111
|
+
expanding = _ref2.expanding;
|
|
112
|
+
return rows.map(function (_ref3, index) {
|
|
113
|
+
var columns = _ref3.columns,
|
|
114
|
+
expanded = _ref3.expanded,
|
|
115
|
+
expandedContent = _ref3.expandedContent,
|
|
116
|
+
key = _ref3.key,
|
|
117
|
+
sortData = _ref3.sortData,
|
|
118
|
+
rowProps = _objectWithoutProperties(_ref3, _excluded2);
|
|
119
|
+
|
|
120
|
+
var cellItems = columns === null || columns === void 0 ? void 0 : columns.map(function (_ref4, index) {
|
|
121
|
+
var content = _ref4.content,
|
|
122
|
+
cellProps = _objectWithoutProperties(_ref4, _excluded3);
|
|
123
|
+
|
|
124
|
+
var headerContent = headers && headers[index]["content"];
|
|
125
|
+
var headerReplacement = headers && headers[index]["heading"];
|
|
126
|
+
|
|
127
|
+
if (responsive) {
|
|
128
|
+
cellProps["data-heading"] = typeof headerContent === "string" ? headerContent : headerReplacement;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return /*#__PURE__*/_react.default.createElement(_TableCell.default, _extends({
|
|
132
|
+
key: index
|
|
133
|
+
}, cellProps), content);
|
|
134
|
+
}); // if key was not provided as a prop, use row's index instead
|
|
135
|
+
|
|
136
|
+
if (key === null || typeof key === "undefined") {
|
|
137
|
+
key = index;
|
|
138
|
+
} // The expanding cell is alway created to match the correct number of
|
|
139
|
+
// table cells in rows that do have expanding content.
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
return /*#__PURE__*/_react.default.createElement(_TableRow.default, _extends({
|
|
143
|
+
key: key
|
|
144
|
+
}, rowProps), cellItems, expanding && /*#__PURE__*/_react.default.createElement(_TableCell.default, {
|
|
145
|
+
expanding: true,
|
|
146
|
+
hidden: !expanded
|
|
147
|
+
}, expandedContent));
|
|
148
|
+
});
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
var sortRows = function sortRows(_ref5) {
|
|
152
|
+
var currentSortDirection = _ref5.currentSortDirection,
|
|
153
|
+
currentSortKey = _ref5.currentSortKey,
|
|
154
|
+
rows = _ref5.rows,
|
|
155
|
+
sortable = _ref5.sortable,
|
|
156
|
+
sortFunction = _ref5.sortFunction;
|
|
157
|
+
|
|
158
|
+
if (!rows) {
|
|
159
|
+
return [];
|
|
109
160
|
} // Clone the rows so we can restore the original order.
|
|
110
161
|
|
|
111
162
|
|
|
@@ -133,74 +184,23 @@ var generateRows = function generateRows(currentSortDirection, currentSortKey, e
|
|
|
133
184
|
});
|
|
134
185
|
}
|
|
135
186
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
if (paginate) {
|
|
139
|
-
var startIndex = (currentPage - 1) * paginate;
|
|
140
|
-
|
|
141
|
-
if (startIndex > rows.length) {
|
|
142
|
-
// If the rows have changed e.g. when filtering and the user is on a page
|
|
143
|
-
// that no longer exists then send them to the start.
|
|
144
|
-
setCurrentPage(1);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
slicedRows = sortedRows.slice(startIndex, startIndex + paginate);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
var rowItems = slicedRows.map(function (_ref2, index) {
|
|
151
|
-
var columns = _ref2.columns,
|
|
152
|
-
expanded = _ref2.expanded,
|
|
153
|
-
expandedContent = _ref2.expandedContent,
|
|
154
|
-
key = _ref2.key,
|
|
155
|
-
sortData = _ref2.sortData,
|
|
156
|
-
rowProps = _objectWithoutProperties(_ref2, _excluded2);
|
|
157
|
-
|
|
158
|
-
var cellItems = columns.map(function (_ref3, index) {
|
|
159
|
-
var content = _ref3.content,
|
|
160
|
-
cellProps = _objectWithoutProperties(_ref3, _excluded3);
|
|
161
|
-
|
|
162
|
-
var headerContent = headers && headers[index]["content"];
|
|
163
|
-
var headerReplacement = headers && headers[index]["heading"];
|
|
164
|
-
|
|
165
|
-
if (responsive) {
|
|
166
|
-
cellProps["data-heading"] = typeof headerContent === "string" ? headerContent : headerReplacement;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
return /*#__PURE__*/_react.default.createElement(_TableCell.default, _extends({
|
|
170
|
-
key: index
|
|
171
|
-
}, cellProps), content);
|
|
172
|
-
}); // if key was not provided as a prop, use row's index instead
|
|
173
|
-
|
|
174
|
-
if (key === null || typeof key === "undefined") {
|
|
175
|
-
key = index;
|
|
176
|
-
} // The expanding cell is alway created to match the correct number of
|
|
177
|
-
// table cells in rows that do have expanding content.
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
return /*#__PURE__*/_react.default.createElement(_TableRow.default, _extends({
|
|
181
|
-
key: key
|
|
182
|
-
}, rowProps), cellItems, expanding && /*#__PURE__*/_react.default.createElement(_TableCell.default, {
|
|
183
|
-
expanding: true,
|
|
184
|
-
hidden: !expanded
|
|
185
|
-
}, expandedContent));
|
|
186
|
-
});
|
|
187
|
-
return /*#__PURE__*/_react.default.createElement("tbody", null, rowItems);
|
|
187
|
+
return sortedRows;
|
|
188
188
|
};
|
|
189
189
|
|
|
190
|
-
var MainTable = function MainTable(
|
|
191
|
-
var defaultSort =
|
|
192
|
-
defaultSortDirection =
|
|
193
|
-
|
|
194
|
-
emptyStateMsg =
|
|
195
|
-
expanding =
|
|
196
|
-
headers =
|
|
197
|
-
onUpdateSort =
|
|
198
|
-
paginate =
|
|
199
|
-
rows =
|
|
200
|
-
responsive =
|
|
201
|
-
sortable =
|
|
202
|
-
sortFunction =
|
|
203
|
-
props = _objectWithoutProperties(
|
|
190
|
+
var MainTable = function MainTable(_ref6) {
|
|
191
|
+
var defaultSort = _ref6.defaultSort,
|
|
192
|
+
defaultSortDirection = _ref6.defaultSortDirection,
|
|
193
|
+
_ref6$emptyStateMsg = _ref6.emptyStateMsg,
|
|
194
|
+
emptyStateMsg = _ref6$emptyStateMsg === void 0 ? "" : _ref6$emptyStateMsg,
|
|
195
|
+
expanding = _ref6.expanding,
|
|
196
|
+
headers = _ref6.headers,
|
|
197
|
+
onUpdateSort = _ref6.onUpdateSort,
|
|
198
|
+
paginate = _ref6.paginate,
|
|
199
|
+
rows = _ref6.rows,
|
|
200
|
+
responsive = _ref6.responsive,
|
|
201
|
+
sortable = _ref6.sortable,
|
|
202
|
+
sortFunction = _ref6.sortFunction,
|
|
203
|
+
props = _objectWithoutProperties(_ref6, _excluded4);
|
|
204
204
|
|
|
205
205
|
var _useState = (0, _react.useState)(defaultSort),
|
|
206
206
|
_useState2 = _slicedToArray(_useState, 2),
|
|
@@ -210,12 +210,7 @@ var MainTable = function MainTable(_ref4) {
|
|
|
210
210
|
var _useState3 = (0, _react.useState)(defaultSortDirection),
|
|
211
211
|
_useState4 = _slicedToArray(_useState3, 2),
|
|
212
212
|
currentSortDirection = _useState4[0],
|
|
213
|
-
setSortDirection = _useState4[1];
|
|
214
|
-
|
|
215
|
-
var _useState5 = (0, _react.useState)(1),
|
|
216
|
-
_useState6 = _slicedToArray(_useState5, 2),
|
|
217
|
-
currentPage = _useState6[0],
|
|
218
|
-
setCurrentPage = _useState6[1]; // Update the current sort state if the prop changes.
|
|
213
|
+
setSortDirection = _useState4[1]; // Update the current sort state if the prop changes.
|
|
219
214
|
|
|
220
215
|
|
|
221
216
|
(0, _react.useEffect)(function () {
|
|
@@ -231,10 +226,34 @@ var MainTable = function MainTable(_ref4) {
|
|
|
231
226
|
onUpdateSort && onUpdateSort(newSort);
|
|
232
227
|
};
|
|
233
228
|
|
|
229
|
+
var sortedRows = (0, _react.useMemo)(function () {
|
|
230
|
+
return sortRows({
|
|
231
|
+
currentSortDirection: currentSortDirection,
|
|
232
|
+
currentSortKey: currentSortKey,
|
|
233
|
+
rows: rows,
|
|
234
|
+
sortable: sortable,
|
|
235
|
+
sortFunction: sortFunction
|
|
236
|
+
});
|
|
237
|
+
}, [currentSortDirection, currentSortKey, rows, sortable, sortFunction]);
|
|
238
|
+
|
|
239
|
+
var _usePagination = (0, _hooks.usePagination)(sortedRows, {
|
|
240
|
+
itemsPerPage: paginate,
|
|
241
|
+
autoResetPage: true
|
|
242
|
+
}),
|
|
243
|
+
finalRows = _usePagination.pageData,
|
|
244
|
+
currentPage = _usePagination.currentPage,
|
|
245
|
+
setCurrentPage = _usePagination.paginate;
|
|
246
|
+
|
|
234
247
|
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_Table.default, _extends({
|
|
235
248
|
expanding: expanding,
|
|
236
249
|
responsive: responsive
|
|
237
|
-
}, props), !!headers && generateHeaders(currentSortKey, currentSortDirection, expanding, headers, sortable, updateSort, setSortDirection),
|
|
250
|
+
}, props), !!headers && generateHeaders(currentSortKey, currentSortDirection, expanding, headers, sortable, updateSort, setSortDirection), // If the table has no rows, return empty state message
|
|
251
|
+
Object.entries(finalRows).length === 0 && emptyStateMsg ? /*#__PURE__*/_react.default.createElement("caption", null, emptyStateMsg) : /*#__PURE__*/_react.default.createElement("tbody", null, generateRows({
|
|
252
|
+
rows: finalRows,
|
|
253
|
+
headers: headers,
|
|
254
|
+
responsive: responsive,
|
|
255
|
+
expanding: expanding
|
|
256
|
+
}))), paginate && rows && rows.length > 0 && /*#__PURE__*/_react.default.createElement(_Pagination.default, {
|
|
238
257
|
currentPage: currentPage,
|
|
239
258
|
itemsPerPage: paginate,
|
|
240
259
|
paginate: setCurrentPage,
|
|
@@ -223,18 +223,47 @@ var Tooltip = function Tooltip(_ref) {
|
|
|
223
223
|
(0, _hooks.useListener)(wrapperRef.current, mouseHandler, "mousemove", true, followMouse && isOpen); // Handle adjusting the position of the tooltip so that it remains on screen.
|
|
224
224
|
|
|
225
225
|
(0, _hooks.useWindowFitment)(messageRef.current, wrapperRef.current, onUpdateWindowFitment, 20, isOpen, autoAdjust && followMouse);
|
|
226
|
+
var handleKeyPress = (0, _react.useCallback)(function (event) {
|
|
227
|
+
if (event.key === "Escape") {
|
|
228
|
+
closePortal();
|
|
229
|
+
}
|
|
230
|
+
}, [closePortal]);
|
|
231
|
+
(0, _react.useEffect)(function () {
|
|
232
|
+
window.addEventListener("keypress", handleKeyPress);
|
|
233
|
+
return function () {
|
|
234
|
+
window.removeEventListener("keypress", handleKeyPress);
|
|
235
|
+
};
|
|
236
|
+
}, [handleKeyPress]);
|
|
226
237
|
|
|
227
238
|
var handleBlur = function handleBlur(e) {
|
|
228
|
-
var _messageRef$current;
|
|
239
|
+
var _wrapperRef$current, _messageRef$current;
|
|
240
|
+
|
|
241
|
+
// do not close if the focus is within the tooltip wrapper
|
|
242
|
+
if (wrapperRef !== null && wrapperRef !== void 0 && (_wrapperRef$current = wrapperRef.current) !== null && _wrapperRef$current !== void 0 && _wrapperRef$current.contains(document.activeElement)) {
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
229
245
|
|
|
230
246
|
if (e.relatedTarget ? !((_messageRef$current = messageRef.current) !== null && _messageRef$current !== void 0 && _messageRef$current.contains(e.relatedTarget)) : e.target !== messageRef.current) {
|
|
231
247
|
closePortal();
|
|
232
248
|
}
|
|
233
249
|
};
|
|
234
250
|
|
|
251
|
+
var handleClick = function handleClick(e) {
|
|
252
|
+
var _messageRef$current2;
|
|
253
|
+
|
|
254
|
+
// ignore clicks within the tooltip message
|
|
255
|
+
if ((_messageRef$current2 = messageRef.current) !== null && _messageRef$current2 !== void 0 && _messageRef$current2.contains(e.target)) {
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
e.target.focus();
|
|
260
|
+
openPortal();
|
|
261
|
+
};
|
|
262
|
+
|
|
235
263
|
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, message ? /*#__PURE__*/_react.default.createElement("span", {
|
|
236
264
|
className: className,
|
|
237
265
|
onBlur: handleBlur,
|
|
266
|
+
onClick: handleClick,
|
|
238
267
|
onFocus: openPortal,
|
|
239
268
|
onMouseOut: handleBlur,
|
|
240
269
|
onMouseOver: openPortal
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -3,4 +3,5 @@ export { useListener } from "./useListener";
|
|
|
3
3
|
export { usePrevious } from "./usePrevious";
|
|
4
4
|
export { useThrottle } from "./useThrottle";
|
|
5
5
|
export { useId } from "./useId";
|
|
6
|
+
export { usePagination } from "./usePagination";
|
|
6
7
|
export type { WindowFitment } from "./useWindowFitment";
|
package/dist/hooks/index.js
CHANGED
|
@@ -15,6 +15,12 @@ Object.defineProperty(exports, "useListener", {
|
|
|
15
15
|
return _useListener.useListener;
|
|
16
16
|
}
|
|
17
17
|
});
|
|
18
|
+
Object.defineProperty(exports, "usePagination", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function get() {
|
|
21
|
+
return _usePagination.usePagination;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
18
24
|
Object.defineProperty(exports, "usePrevious", {
|
|
19
25
|
enumerable: true,
|
|
20
26
|
get: function get() {
|
|
@@ -42,4 +48,6 @@ var _usePrevious = require("./usePrevious");
|
|
|
42
48
|
|
|
43
49
|
var _useThrottle = require("./useThrottle");
|
|
44
50
|
|
|
45
|
-
var _useId = require("./useId");
|
|
51
|
+
var _useId = require("./useId");
|
|
52
|
+
|
|
53
|
+
var _usePagination = require("./usePagination");
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A hook that handles pagination.
|
|
3
|
+
* @param data - The data array to paginate.
|
|
4
|
+
* @param {Object} options
|
|
5
|
+
* @param {number} [options.itemsPerPage] - Number of items per page. Returns all items if no value has been provided.
|
|
6
|
+
* @param {number} [options.initialPage=1] - Initial page number. Defaults to 1.
|
|
7
|
+
* @param {boolean} [options.autoResetPage=false] - Whether to reset the page number to 1 when the data changes.
|
|
8
|
+
*/
|
|
9
|
+
export declare function usePagination<D, I = number | null>(data: Array<D>, options?: {
|
|
10
|
+
itemsPerPage: I;
|
|
11
|
+
initialPage?: number;
|
|
12
|
+
autoResetPage?: boolean;
|
|
13
|
+
}): {
|
|
14
|
+
pageData: Array<D>;
|
|
15
|
+
currentPage: number;
|
|
16
|
+
paginate: (pageNumber: number) => void;
|
|
17
|
+
itemsPerPage: I;
|
|
18
|
+
totalItems: number;
|
|
19
|
+
};
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.usePagination = usePagination;
|
|
7
|
+
|
|
8
|
+
var _react = require("react");
|
|
9
|
+
|
|
10
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
11
|
+
|
|
12
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
13
|
+
|
|
14
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
15
|
+
|
|
16
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
17
|
+
|
|
18
|
+
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
19
|
+
|
|
20
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* A hook that handles pagination.
|
|
24
|
+
* @param data - The data array to paginate.
|
|
25
|
+
* @param {Object} options
|
|
26
|
+
* @param {number} [options.itemsPerPage] - Number of items per page. Returns all items if no value has been provided.
|
|
27
|
+
* @param {number} [options.initialPage=1] - Initial page number. Defaults to 1.
|
|
28
|
+
* @param {boolean} [options.autoResetPage=false] - Whether to reset the page number to 1 when the data changes.
|
|
29
|
+
*/
|
|
30
|
+
function usePagination(data, options) {
|
|
31
|
+
var _data$length;
|
|
32
|
+
|
|
33
|
+
var defaultOptions = {
|
|
34
|
+
initialPage: 1,
|
|
35
|
+
autoResetPage: false
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
var _Object$assign = Object.assign(defaultOptions, options),
|
|
39
|
+
itemsPerPage = _Object$assign.itemsPerPage,
|
|
40
|
+
initialPage = _Object$assign.initialPage,
|
|
41
|
+
autoResetPage = _Object$assign.autoResetPage;
|
|
42
|
+
|
|
43
|
+
var totalItems = (_data$length = data === null || data === void 0 ? void 0 : data.length) !== null && _data$length !== void 0 ? _data$length : 0;
|
|
44
|
+
var initialPageIndex = initialPage > 0 ? initialPage - 1 : 0;
|
|
45
|
+
|
|
46
|
+
var _useState = (0, _react.useState)(initialPageIndex),
|
|
47
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
48
|
+
pageIndex = _useState2[0],
|
|
49
|
+
setPageIndex = _useState2[1];
|
|
50
|
+
|
|
51
|
+
var startIndex = typeof itemsPerPage === "number" ? pageIndex * itemsPerPage : 0;
|
|
52
|
+
|
|
53
|
+
var paginate = function paginate(pageNumber) {
|
|
54
|
+
return setPageIndex(pageNumber - 1);
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
(0, _react.useEffect)(function () {
|
|
58
|
+
if (typeof itemsPerPage === "number" && startIndex >= totalItems) {
|
|
59
|
+
!autoResetPage && Math.floor(totalItems / itemsPerPage) > 0 ? // go to the last available page if the current page is out of bounds
|
|
60
|
+
setPageIndex(Math.floor(totalItems / itemsPerPage) - 1) : // go to the initial page if autoResetPage is true
|
|
61
|
+
setPageIndex(0);
|
|
62
|
+
}
|
|
63
|
+
}, [pageIndex, startIndex, setPageIndex, totalItems, itemsPerPage, autoResetPage]);
|
|
64
|
+
var pageData = (0, _react.useMemo)(function () {
|
|
65
|
+
return typeof itemsPerPage === "number" ? data === null || data === void 0 ? void 0 : data.slice(startIndex, startIndex + itemsPerPage) : data;
|
|
66
|
+
}, [startIndex, data, itemsPerPage]);
|
|
67
|
+
return {
|
|
68
|
+
pageData: pageData,
|
|
69
|
+
currentPage: pageIndex + 1,
|
|
70
|
+
paginate: paginate,
|
|
71
|
+
itemsPerPage: itemsPerPage,
|
|
72
|
+
totalItems: totalItems
|
|
73
|
+
};
|
|
74
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@canonical/react-components",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.36.0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"module": "dist/index.js",
|
|
6
6
|
"author": "Huw Wilkins <huw.wilkins@canonical.com>",
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
"ts-jest": "27.1.4",
|
|
82
82
|
"tsc-alias": "1.6.5",
|
|
83
83
|
"typescript": "4.6.3",
|
|
84
|
-
"vanilla-framework": "3.
|
|
84
|
+
"vanilla-framework": "3.3.0",
|
|
85
85
|
"wait-on": "5.3.0"
|
|
86
86
|
},
|
|
87
87
|
"dependencies": {
|
|
@@ -102,7 +102,7 @@
|
|
|
102
102
|
"peerDependencies": {
|
|
103
103
|
"react": "17.0.2",
|
|
104
104
|
"react-dom": "17.0.2",
|
|
105
|
-
"vanilla-framework": "3.
|
|
105
|
+
"vanilla-framework": "3.3.0"
|
|
106
106
|
},
|
|
107
107
|
"scripts": {
|
|
108
108
|
"build": "rm -rf dist && yarn build-local; yarn build-declaration",
|
|
@@ -125,8 +125,8 @@
|
|
|
125
125
|
"test-cypress": "concurrently 'yarn run docs' 'yarn run cypress:test' -k -s first",
|
|
126
126
|
"unlink-packages": "yarn unlink && cd node_modules/react && yarn unlink && cd ../react-dom && yarn unlink",
|
|
127
127
|
"cypress:test": "wait-on http://localhost:${PORT:-9009} && cypress run --env port=${PORT:-9009}",
|
|
128
|
-
"cypress:run": "cypress run",
|
|
129
|
-
"cypress:open": "cypress open"
|
|
128
|
+
"cypress:run": "cypress run --env port=${PORT:-9009}",
|
|
129
|
+
"cypress:open": "cypress open --env port=${PORT:-9009}"
|
|
130
130
|
},
|
|
131
131
|
"eslintConfig": {
|
|
132
132
|
"extends": "react-app"
|