@canonical/react-components 1.2.0 → 1.2.1

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
@@ -41,13 +41,13 @@ You might want to:
41
41
 
42
42
  You may wish to link this library directly to your projects while developing locally.
43
43
 
44
- You can do this by cloning this repo to your local workspace;
44
+ You can do this by cloning this repo to your local workspace:
45
45
 
46
46
  ```shell
47
47
  git clone https://github.com/canonical/react-components
48
48
  ```
49
49
 
50
- If you then drop into that folder and run;
50
+ If you then drop into that folder and run:
51
51
 
52
52
  ```shell
53
53
  yarn run link-packages
@@ -55,7 +55,7 @@ yarn run link-packages
55
55
 
56
56
  ...this will add this project, `react` and `react-dom` to a local yarn registry.
57
57
 
58
- Switching back to the project you are developing, run;
58
+ Switching back to the project you are developing, run:
59
59
 
60
60
  ```shell
61
61
  yarn install
@@ -66,7 +66,7 @@ yarn link @canonical/react-components
66
66
 
67
67
  ...to pull the linked deps from the local registry. If you now run `yarn build-watch` in your `react-components` folder, your project should pick up any changes on refresh or hot module reload.
68
68
 
69
- **Note:** When you're finished working locally - don't forget to go back and unlink;
69
+ **Note:** When you're finished working locally - don't forget to go back and unlink:
70
70
 
71
71
  ```
72
72
  cd react-components
@@ -9,5 +9,5 @@ export type Props<L = LinkDefaultElement> = Omit<SideNavigationBaseProps<L>, "co
9
9
  */
10
10
  component?: SideNavigationBaseProps<L>["component"];
11
11
  };
12
- declare const SideNavigationLink: <L = LinkDefaultElement>({ component, ...props }: Props<L>) => React.JSX.Element;
12
+ declare const SideNavigationLink: React.ForwardRefExoticComponent<Omit<Props<LinkDefaultElement>, "ref"> & React.RefAttributes<HTMLAnchorElement>>;
13
13
  export default SideNavigationLink;
@@ -4,14 +4,17 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
- var _react = _interopRequireDefault(require("react"));
7
+ var _react = _interopRequireWildcard(require("react"));
8
8
  var _classnames = _interopRequireDefault(require("classnames"));
9
9
  var _SideNavigationBase = _interopRequireDefault(require("../SideNavigationBase"));
10
10
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
12
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
11
13
  function _extends() { _extends = 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.apply(this, arguments); }
12
- const SideNavigationLink = _ref => {
14
+ const SideNavigationLink = /*#__PURE__*/(0, _react.forwardRef)(_ref => {
13
15
  let {
14
16
  component,
17
+ ref,
15
18
  ...props
16
19
  } = _ref;
17
20
  let className = null;
@@ -23,5 +26,5 @@ const SideNavigationLink = _ref => {
23
26
  className: (0, _classnames.default)("p-side-navigation__link", className),
24
27
  component: component !== null && component !== void 0 ? component : "a"
25
28
  }, props));
26
- };
29
+ });
27
30
  var _default = exports.default = SideNavigationLink;
@@ -4,7 +4,7 @@ export type BasePaginationProps = {
4
4
  /**
5
5
  * list of data elements to be paginated. This component is un-opinionated about
6
6
  * the structure of the data but it should be identical to the data structure
7
- * reuiqred by the child table component
7
+ * required by the child table component
8
8
  */
9
9
  data: unknown[];
10
10
  /**
@@ -94,7 +94,7 @@ const TablePagination = props => {
94
94
  };
95
95
  const clonedChildren = (0, _utils.renderChildren)(children, dataForwardProp, controlData);
96
96
  const controls = /*#__PURE__*/_react.default.createElement(_TablePaginationControls.default, _extends({}, divProps, {
97
- data: controlData,
97
+ visibleCount: controlData.length,
98
98
  className: className,
99
99
  itemName: itemName,
100
100
  description: description,
@@ -18,7 +18,7 @@
18
18
  }
19
19
 
20
20
  .back {
21
- margin: 0 $spv--large;
21
+ margin: 0 0 0 $spv--large;
22
22
 
23
23
  .p-icon--chevron-down {
24
24
  rotate: 90deg;
@@ -34,7 +34,7 @@
34
34
  }
35
35
 
36
36
  .pagination-input {
37
- margin-right: $spv--small;
37
+ margin: 0 $spv--small 0 $spv--large;
38
38
  min-width: 0;
39
39
  width: 3rem;
40
40
  }
@@ -8,3 +8,7 @@ export declare const CustomPageLimit: Story;
8
8
  export declare const CustomDisplayTitle: Story;
9
9
  export declare const RenderAbove: Story;
10
10
  export declare const RenderBelow: Story;
11
+ /** The table pagination controls can be used without wrapping MainTable by
12
+ * using the `TablePaginationControls` component.
13
+ */
14
+ export declare const ControlsOnly: Story;
@@ -3,10 +3,11 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.default = exports.RenderBelow = exports.RenderAbove = exports.Default = exports.CustomPageLimit = exports.CustomDisplayTitle = void 0;
6
+ exports.default = exports.RenderBelow = exports.RenderAbove = exports.Default = exports.CustomPageLimit = exports.CustomDisplayTitle = exports.ControlsOnly = void 0;
7
7
  var _react = _interopRequireDefault(require("react"));
8
8
  var _TablePagination = _interopRequireDefault(require("./TablePagination"));
9
9
  var _MainTable = _interopRequireDefault(require("../MainTable"));
10
+ var _TablePaginationControls = _interopRequireDefault(require("./TablePaginationControls"));
10
11
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
12
  const meta = {
12
13
  component: _TablePagination.default,
@@ -299,4 +300,31 @@ const RenderBelow = exports.RenderBelow = {
299
300
  }));
300
301
  },
301
302
  name: "RenderBelow"
303
+ };
304
+
305
+ /** The table pagination controls can be used without wrapping MainTable by
306
+ * using the `TablePaginationControls` component.
307
+ */
308
+ const ControlsOnly = exports.ControlsOnly = {
309
+ render: () => {
310
+ return /*#__PURE__*/_react.default.createElement(_TablePaginationControls.default, {
311
+ currentPage: 1,
312
+ itemName: "row",
313
+ nextButtonProps: {
314
+ disabled: false
315
+ },
316
+ onInputPageChange: console.log,
317
+ onNextPage: console.log,
318
+ onPageSizeChange: console.log,
319
+ onPreviousPage: console.log,
320
+ pageLimits: [10, 25, 50],
321
+ pageSize: 20,
322
+ previousButtonProps: {
323
+ disabled: false
324
+ },
325
+ showPageInput: true,
326
+ totalItems: 100,
327
+ visibleCount: 10
328
+ });
329
+ }
302
330
  };
@@ -1,6 +1,24 @@
1
+ import { ButtonProps } from "../../Button";
1
2
  import { HTMLAttributes } from "react";
2
3
  import { BasePaginationProps, ExternalControlProps, InternalControlProps } from "../TablePagination";
4
+ export declare enum Label {
5
+ NEXT_PAGE = "Next page",
6
+ PREVIOUS_PAGE = "Previous page",
7
+ PAGE_NUMBER = "Page number"
8
+ }
3
9
  export type AllProps = BasePaginationProps & InternalControlProps & ExternalControlProps;
4
- export type Props = Omit<AllProps, "externallyControlled" | "dataForwardProp" | "position"> & HTMLAttributes<HTMLDivElement>;
5
- declare const TablePaginationControls: ({ data, className, itemName, description, pageLimits, totalItems, currentPage, pageSize, onPageChange, onPageSizeChange, ...divProps }: Props) => JSX.Element;
10
+ export type Props = Omit<AllProps, "currentPage" | "data" | "dataForwardProp" | "externallyControlled" | "onPageChange" | "position" | "totalItems"> & {
11
+ currentPage?: AllProps["currentPage"];
12
+ displayDescription?: boolean;
13
+ onInputPageChange?: (page: number) => void;
14
+ nextButtonProps?: Partial<ButtonProps>;
15
+ onNextPage?: (page: number) => void;
16
+ onPageChange?: AllProps["onPageChange"];
17
+ onPreviousPage?: (page: number) => void;
18
+ previousButtonProps?: Partial<ButtonProps>;
19
+ totalItems?: AllProps["totalItems"];
20
+ visibleCount?: number;
21
+ showPageInput?: boolean;
22
+ } & HTMLAttributes<HTMLDivElement>;
23
+ declare const TablePaginationControls: ({ className, currentPage, description, displayDescription, onInputPageChange, itemName, nextButtonProps, onNextPage, onPageChange, onPageSizeChange, onPreviousPage, pageLimits, pageSize, previousButtonProps, showPageInput, totalItems, visibleCount, ...divProps }: Props) => JSX.Element;
6
24
  export default TablePaginationControls;
@@ -3,7 +3,8 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.default = void 0;
6
+ exports.default = exports.Label = void 0;
7
+ var _propTypes = _interopRequireDefault(require("prop-types"));
7
8
  var _Button = _interopRequireDefault(require("../../Button"));
8
9
  var _Icon = _interopRequireDefault(require("../../Icon"));
9
10
  var _Input = _interopRequireDefault(require("../../Input"));
@@ -13,42 +14,58 @@ var _classnames = _interopRequireDefault(require("classnames"));
13
14
  var _utils = require("../utils");
14
15
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
16
  function _extends() { _extends = 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.apply(this, arguments); }
17
+ let Label = exports.Label = /*#__PURE__*/function (Label) {
18
+ Label["NEXT_PAGE"] = "Next page";
19
+ Label["PREVIOUS_PAGE"] = "Previous page";
20
+ Label["PAGE_NUMBER"] = "Page number";
21
+ return Label;
22
+ }({});
16
23
  const TablePaginationControls = _ref => {
17
24
  let {
18
- data,
19
25
  className,
20
- itemName,
21
- description,
22
- pageLimits,
23
- totalItems,
24
26
  currentPage,
25
- pageSize,
27
+ description,
28
+ displayDescription = true,
29
+ onInputPageChange,
30
+ itemName,
31
+ nextButtonProps,
32
+ onNextPage,
26
33
  onPageChange,
27
34
  onPageSizeChange,
35
+ onPreviousPage,
36
+ pageLimits,
37
+ pageSize,
38
+ previousButtonProps,
39
+ showPageInput = true,
40
+ totalItems,
41
+ visibleCount,
28
42
  ...divProps
29
43
  } = _ref;
30
44
  const isSmallScreen = (0, _utils.useFigureSmallScreen)();
31
- const totalPages = Math.ceil(totalItems / pageSize);
45
+ const totalPages = totalItems ? Math.ceil(totalItems / pageSize) : null;
32
46
  const descriptionDisplay = (0, _utils.getDescription)({
33
47
  description,
34
- data,
48
+ visibleCount,
35
49
  isSmallScreen,
36
50
  totalItems,
37
51
  itemName
38
52
  });
39
53
  const handleDecrementPage = currentPage => {
40
54
  if (currentPage > 1) {
41
- onPageChange(currentPage - 1);
55
+ onPageChange === null || onPageChange === void 0 || onPageChange(currentPage - 1);
42
56
  }
57
+ onPreviousPage === null || onPreviousPage === void 0 || onPreviousPage(typeof currentPage === "number" ? currentPage - 1 : null);
43
58
  };
44
59
  const handleIncrementPage = (currentPage, totalPages) => {
45
60
  if (currentPage < totalPages) {
46
- onPageChange(currentPage + 1);
61
+ onPageChange === null || onPageChange === void 0 || onPageChange(currentPage + 1);
47
62
  }
63
+ onNextPage === null || onNextPage === void 0 || onNextPage(typeof currentPage === "number" ? currentPage + 1 : null);
48
64
  };
49
65
  const handleInputPageChange = e => {
50
66
  const newPage = Math.min(totalPages, Math.max(1, parseInt(e.target.value)));
51
- onPageChange(newPage);
67
+ onPageChange === null || onPageChange === void 0 || onPageChange(newPage);
68
+ onInputPageChange === null || onInputPageChange === void 0 || onInputPageChange(Number(e.target.value));
52
69
  };
53
70
  const handlePageSizeChange = e => {
54
71
  onPageSizeChange(parseInt(e.target.value));
@@ -60,31 +77,31 @@ const TablePaginationControls = _ref => {
60
77
  }), /*#__PURE__*/_react.default.createElement("div", {
61
78
  className: "description",
62
79
  id: "pagination-description"
63
- }, descriptionDisplay), /*#__PURE__*/_react.default.createElement(_Button.default, {
64
- "aria-label": "Previous page",
80
+ }, displayDescription ? descriptionDisplay : null), /*#__PURE__*/_react.default.createElement(_Button.default, _extends({
81
+ "aria-label": Label.PREVIOUS_PAGE,
65
82
  className: "back",
66
83
  appearance: "base",
67
84
  hasIcon: true,
68
85
  disabled: currentPage === 1,
69
86
  onClick: () => handleDecrementPage(currentPage)
70
- }, /*#__PURE__*/_react.default.createElement(_Icon.default, {
87
+ }, previousButtonProps), previousButtonProps !== null && previousButtonProps !== void 0 && previousButtonProps.children ? previousButtonProps.children : /*#__PURE__*/_react.default.createElement(_Icon.default, {
71
88
  name: "chevron-down"
72
- })), /*#__PURE__*/_react.default.createElement(_Input.default, {
89
+ })), showPageInput ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_Input.default, {
73
90
  id: "paginationPageInput",
74
- label: "Page number",
91
+ label: Label.PAGE_NUMBER,
75
92
  labelClassName: "u-off-screen",
76
93
  className: "u-no-margin--bottom pagination-input",
77
94
  onChange: handleInputPageChange,
78
95
  value: currentPage,
79
96
  type: "number"
80
- }), " ", "of\xA0", totalPages, /*#__PURE__*/_react.default.createElement(_Button.default, {
81
- "aria-label": "Next page",
97
+ }), " ") : null, typeof totalPages === "number" ? "of ".concat(totalPages) : null, /*#__PURE__*/_react.default.createElement(_Button.default, _extends({
98
+ "aria-label": Label.NEXT_PAGE,
82
99
  className: "next",
83
100
  appearance: "base",
84
101
  hasIcon: true,
85
102
  disabled: currentPage === totalPages,
86
103
  onClick: () => handleIncrementPage(currentPage, totalPages)
87
- }, /*#__PURE__*/_react.default.createElement(_Icon.default, {
104
+ }, nextButtonProps), /*#__PURE__*/_react.default.createElement(_Icon.default, {
88
105
  name: "chevron-down"
89
106
  })), /*#__PURE__*/_react.default.createElement(_Select.default, {
90
107
  className: "u-no-margin--bottom",
@@ -96,4 +113,12 @@ const TablePaginationControls = _ref => {
96
113
  value: pageSize
97
114
  }));
98
115
  };
116
+ TablePaginationControls.propTypes = {
117
+ displayDescription: _propTypes.default.bool,
118
+ onInputPageChange: _propTypes.default.func,
119
+ onNextPage: _propTypes.default.func,
120
+ onPreviousPage: _propTypes.default.func,
121
+ visibleCount: _propTypes.default.number,
122
+ showPageInput: _propTypes.default.bool
123
+ };
99
124
  var _default = exports.default = TablePaginationControls;
@@ -17,11 +17,11 @@ export declare const generatePagingOptions: (pageLimits: number[]) => {
17
17
  value: number;
18
18
  label: string;
19
19
  }[];
20
- export declare const getDescription: ({ description, data, isSmallScreen, totalItems, itemName, }: {
20
+ export declare const getDescription: ({ description, isSmallScreen, totalItems, itemName, visibleCount, }: {
21
21
  description: ReactNode;
22
- data: unknown[];
23
22
  isSmallScreen: boolean;
24
23
  totalItems: number;
25
24
  itemName: string;
25
+ visibleCount: number;
26
26
  }) => string | number | true | ReactElement<any, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode>;
27
27
  export declare const useFigureSmallScreen: () => boolean;
@@ -44,15 +44,14 @@ exports.generatePagingOptions = generatePagingOptions;
44
44
  const getDescription = _ref => {
45
45
  let {
46
46
  description,
47
- data,
48
47
  isSmallScreen,
49
48
  totalItems,
50
- itemName
49
+ itemName,
50
+ visibleCount
51
51
  } = _ref;
52
52
  if (description) {
53
53
  return description;
54
54
  }
55
- const visibleCount = data.length;
56
55
  if (isSmallScreen) {
57
56
  return "".concat(visibleCount, " out of ").concat(totalItems);
58
57
  }
package/dist/index.d.ts CHANGED
@@ -63,6 +63,7 @@ export { default as Tabs } from "./components/Tabs";
63
63
  export { default as Textarea } from "./components/Textarea";
64
64
  export { default as Tooltip } from "./components/Tooltip";
65
65
  export { default as TablePagination } from "./components/TablePagination";
66
+ export { default as TablePaginationControls } from "./components/TablePagination/TablePaginationControls";
66
67
  export type { AccordionProps } from "./components/Accordion";
67
68
  export type { ActionButtonProps } from "./components/ActionButton";
68
69
  export type { ArticlePaginationProps } from "./components/ArticlePagination";
package/dist/index.js CHANGED
@@ -79,6 +79,7 @@ var _exportNames = {
79
79
  Textarea: true,
80
80
  Tooltip: true,
81
81
  TablePagination: true,
82
+ TablePaginationControls: true,
82
83
  useOnClickOutside: true,
83
84
  useClickOutside: true,
84
85
  useId: true,
@@ -488,6 +489,12 @@ Object.defineProperty(exports, "TablePagination", {
488
489
  return _TablePagination.default;
489
490
  }
490
491
  });
492
+ Object.defineProperty(exports, "TablePaginationControls", {
493
+ enumerable: true,
494
+ get: function () {
495
+ return _TablePaginationControls.default;
496
+ }
497
+ });
491
498
  Object.defineProperty(exports, "TableRow", {
492
499
  enumerable: true,
493
500
  get: function () {
@@ -690,6 +697,7 @@ var _Tabs = _interopRequireDefault(require("./components/Tabs"));
690
697
  var _Textarea = _interopRequireDefault(require("./components/Textarea"));
691
698
  var _Tooltip = _interopRequireDefault(require("./components/Tooltip"));
692
699
  var _TablePagination = _interopRequireDefault(require("./components/TablePagination"));
700
+ var _TablePaginationControls = _interopRequireDefault(require("./components/TablePagination/TablePaginationControls"));
693
701
  var _hooks = require("./hooks");
694
702
  var _utils = require("./utils");
695
703
  var _enums = require("./enums");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@canonical/react-components",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.js",
6
6
  "author": {
@@ -89,9 +89,9 @@
89
89
  "ts-jest": "29.1.2",
90
90
  "tsc-alias": "1.8.8",
91
91
  "typescript": "5.4.5",
92
- "vanilla-framework": "4.11.0",
92
+ "vanilla-framework": "4.15.0",
93
93
  "wait-on": "7.2.0",
94
- "webpack": "5.91.0"
94
+ "webpack": "5.94.0"
95
95
  },
96
96
  "dependencies": {
97
97
  "@types/jest": "29.5.12",
@@ -113,11 +113,11 @@
113
113
  "jackspeak": "2.1.1"
114
114
  },
115
115
  "peerDependencies": {
116
- "@types/react": "^17.0.2 || ^18.0.0",
117
- "@types/react-dom": "^17.0.2 || ^18.0.0",
116
+ "@types/react": "^18.0.0",
117
+ "@types/react-dom": "^18.0.0",
118
118
  "formik": "^2.4.5",
119
- "react": "^17.0.2 || ^18.0.0",
120
- "react-dom": "^17.0.2 || ^18.0.0",
119
+ "react": "^18.0.0",
120
+ "react-dom": "^18.0.0",
121
121
  "vanilla-framework": "^3.15.1 || ^4.0.0"
122
122
  },
123
123
  "scripts": {