@canonical/react-components 2.7.2 → 2.7.4

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.
@@ -30,7 +30,7 @@ const ActionButton = _ref => {
30
30
  appearance,
31
31
  children,
32
32
  className,
33
- disabled = false,
33
+ disabled = null,
34
34
  inline = false,
35
35
  loading = false,
36
36
  success = false,
@@ -41,11 +41,18 @@ const ActionButton = _ref => {
41
41
  const [showLoader, setShowLoader] = (0, _react.useState)(false);
42
42
  const [showSuccess, setShowSuccess] = (0, _react.useState)(false);
43
43
  const ref = (0, _react.useRef)(null);
44
+ const startLoadTime = (0, _react.useRef)(undefined);
44
45
 
45
46
  // Set up loader timer
46
47
  (0, _react.useEffect)(() => {
47
48
  let loaderTimeout;
48
49
  if (loading) {
50
+ // add a condition to prevent double set startLoadTime
51
+ // when showLoader changes.
52
+ if (startLoadTime.current === undefined) {
53
+ // Keep track of the time when loading starts
54
+ startLoadTime.current = new Date();
55
+ }
49
56
  // Explicitly set button dimensions
50
57
  if (ref.current && !!ref.current.getBoundingClientRect()) {
51
58
  setHeight(ref.current.getBoundingClientRect().height);
@@ -54,12 +61,27 @@ const ActionButton = _ref => {
54
61
  setShowLoader(true);
55
62
  }
56
63
  if (!loading && showLoader) {
57
- loaderTimeout = window.setTimeout(() => {
64
+ var _startLoadTime$curren;
65
+ const now = new Date();
66
+ // calculate elapsed loading time
67
+ const loadingMilliseconds = now.getTime() - ((_startLoadTime$curren = startLoadTime.current) !== null && _startLoadTime$curren !== void 0 ? _startLoadTime$curren : now).getTime();
68
+
69
+ // and subtract it from LOADER_MIN_DURATION,
70
+
71
+ // also add an edge case when time diff is less than 0 to be 0.
72
+ const timeoutDuration = Math.max(LOADER_MIN_DURATION - loadingMilliseconds, 0);
73
+ const loadFinishHandler = () => {
74
+ startLoadTime.current = undefined;
58
75
  setShowLoader(false);
59
76
  if (success) {
60
77
  setShowSuccess(true);
61
78
  }
62
- }, LOADER_MIN_DURATION);
79
+ };
80
+ if (timeoutDuration > 0) {
81
+ loaderTimeout = window.setTimeout(loadFinishHandler, timeoutDuration);
82
+ } else {
83
+ loadFinishHandler();
84
+ }
63
85
  }
64
86
  if (!loading && !showLoader) {
65
87
  setHeight(null);
@@ -82,7 +104,7 @@ const ActionButton = _ref => {
82
104
  }, [showSuccess]);
83
105
  const buttonClasses = (0, _classnames.default)(className, "p-action-button", appearance ? "p-button--".concat(appearance) : "p-button", {
84
106
  "is-processing": showLoader || showSuccess,
85
- "is-disabled": disabled,
107
+ "is-disabled": disabled === null ? showLoader : disabled,
86
108
  "is-inline": inline
87
109
  });
88
110
  const showIcon = showLoader || showSuccess;
@@ -95,7 +117,7 @@ const ActionButton = _ref => {
95
117
  // typescript generics.
96
118
  return /*#__PURE__*/_react.default.createElement("button", _extends({
97
119
  className: buttonClasses,
98
- disabled: disabled,
120
+ disabled: disabled === null ? showLoader : disabled,
99
121
  ref: ref,
100
122
  style: height && width ? {
101
123
  height: "".concat(height, "px"),
@@ -70,6 +70,8 @@ const TablePaginationControls = _ref => {
70
70
  const handlePageSizeChange = e => {
71
71
  onPageSizeChange(parseInt(e.target.value));
72
72
  };
73
+ const isInputDisabled = !totalPages || totalPages == 1;
74
+ const maxPageValue = typeof totalPages === "number" ? totalPages : 1;
73
75
  return /*#__PURE__*/_react.default.createElement("div", _extends({
74
76
  className: (0, _classnames.default)("pagination", className)
75
77
  }, divProps, {
@@ -82,7 +84,7 @@ const TablePaginationControls = _ref => {
82
84
  className: "back",
83
85
  appearance: "base",
84
86
  hasIcon: true,
85
- disabled: currentPage === 1,
87
+ disabled: isInputDisabled || currentPage === 1,
86
88
  onClick: () => handleDecrementPage(currentPage)
87
89
  }, previousButtonProps), previousButtonProps !== null && previousButtonProps !== void 0 && previousButtonProps.children ? previousButtonProps.children : /*#__PURE__*/_react.default.createElement(_Icon.default, {
88
90
  name: "chevron-down"
@@ -93,13 +95,16 @@ const TablePaginationControls = _ref => {
93
95
  className: "u-no-margin--bottom pagination-input",
94
96
  onChange: handleInputPageChange,
95
97
  value: currentPage,
96
- type: "number"
98
+ type: "number",
99
+ disabled: isInputDisabled,
100
+ min: 1,
101
+ max: maxPageValue
97
102
  }), " ", typeof totalPages === "number" ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, "of\xA0", totalPages) : null) : null, /*#__PURE__*/_react.default.createElement(_Button.default, _extends({
98
103
  "aria-label": Label.NEXT_PAGE,
99
104
  className: "next",
100
105
  appearance: "base",
101
106
  hasIcon: true,
102
- disabled: currentPage === totalPages,
107
+ disabled: isInputDisabled || currentPage === totalPages,
103
108
  onClick: () => handleIncrementPage(currentPage, totalPages)
104
109
  }, nextButtonProps), /*#__PURE__*/_react.default.createElement(_Icon.default, {
105
110
  name: "chevron-down"
@@ -25,7 +25,7 @@ var ActionButton = _ref => {
25
25
  appearance,
26
26
  children,
27
27
  className,
28
- disabled = false,
28
+ disabled = null,
29
29
  inline = false,
30
30
  loading = false,
31
31
  success = false
@@ -36,11 +36,18 @@ var ActionButton = _ref => {
36
36
  var [showLoader, setShowLoader] = useState(false);
37
37
  var [showSuccess, setShowSuccess] = useState(false);
38
38
  var ref = useRef(null);
39
+ var startLoadTime = useRef(undefined);
39
40
 
40
41
  // Set up loader timer
41
42
  useEffect(() => {
42
43
  var loaderTimeout;
43
44
  if (loading) {
45
+ // add a condition to prevent double set startLoadTime
46
+ // when showLoader changes.
47
+ if (startLoadTime.current === undefined) {
48
+ // Keep track of the time when loading starts
49
+ startLoadTime.current = new Date();
50
+ }
44
51
  // Explicitly set button dimensions
45
52
  if (ref.current && !!ref.current.getBoundingClientRect()) {
46
53
  setHeight(ref.current.getBoundingClientRect().height);
@@ -49,12 +56,27 @@ var ActionButton = _ref => {
49
56
  setShowLoader(true);
50
57
  }
51
58
  if (!loading && showLoader) {
52
- loaderTimeout = window.setTimeout(() => {
59
+ var _startLoadTime$curren;
60
+ var now = new Date();
61
+ // calculate elapsed loading time
62
+ var loadingMilliseconds = now.getTime() - ((_startLoadTime$curren = startLoadTime.current) !== null && _startLoadTime$curren !== void 0 ? _startLoadTime$curren : now).getTime();
63
+
64
+ // and subtract it from LOADER_MIN_DURATION,
65
+
66
+ // also add an edge case when time diff is less than 0 to be 0.
67
+ var timeoutDuration = Math.max(LOADER_MIN_DURATION - loadingMilliseconds, 0);
68
+ var loadFinishHandler = () => {
69
+ startLoadTime.current = undefined;
53
70
  setShowLoader(false);
54
71
  if (success) {
55
72
  setShowSuccess(true);
56
73
  }
57
- }, LOADER_MIN_DURATION);
74
+ };
75
+ if (timeoutDuration > 0) {
76
+ loaderTimeout = window.setTimeout(loadFinishHandler, timeoutDuration);
77
+ } else {
78
+ loadFinishHandler();
79
+ }
58
80
  }
59
81
  if (!loading && !showLoader) {
60
82
  setHeight(null);
@@ -77,7 +99,7 @@ var ActionButton = _ref => {
77
99
  }, [showSuccess]);
78
100
  var buttonClasses = classNames(className, "p-action-button", appearance ? "p-button--".concat(appearance) : "p-button", {
79
101
  "is-processing": showLoader || showSuccess,
80
- "is-disabled": disabled,
102
+ "is-disabled": disabled === null ? showLoader : disabled,
81
103
  "is-inline": inline
82
104
  });
83
105
  var showIcon = showLoader || showSuccess;
@@ -90,7 +112,7 @@ var ActionButton = _ref => {
90
112
  // typescript generics.
91
113
  return /*#__PURE__*/React.createElement("button", _extends({
92
114
  className: buttonClasses,
93
- disabled: disabled,
115
+ disabled: disabled === null ? showLoader : disabled,
94
116
  ref: ref,
95
117
  style: height && width ? {
96
118
  height: "".concat(height, "px"),
@@ -66,6 +66,8 @@ var TablePaginationControls = _ref => {
66
66
  var handlePageSizeChange = e => {
67
67
  onPageSizeChange(parseInt(e.target.value));
68
68
  };
69
+ var isInputDisabled = !totalPages || totalPages == 1;
70
+ var maxPageValue = typeof totalPages === "number" ? totalPages : 1;
69
71
  return /*#__PURE__*/React.createElement("div", _extends({
70
72
  className: classnames("pagination", className)
71
73
  }, divProps, {
@@ -78,7 +80,7 @@ var TablePaginationControls = _ref => {
78
80
  className: "back",
79
81
  appearance: "base",
80
82
  hasIcon: true,
81
- disabled: currentPage === 1,
83
+ disabled: isInputDisabled || currentPage === 1,
82
84
  onClick: () => handleDecrementPage(currentPage)
83
85
  }, previousButtonProps), previousButtonProps !== null && previousButtonProps !== void 0 && previousButtonProps.children ? previousButtonProps.children : /*#__PURE__*/React.createElement(Icon, {
84
86
  name: "chevron-down"
@@ -89,13 +91,16 @@ var TablePaginationControls = _ref => {
89
91
  className: "u-no-margin--bottom pagination-input",
90
92
  onChange: handleInputPageChange,
91
93
  value: currentPage,
92
- type: "number"
94
+ type: "number",
95
+ disabled: isInputDisabled,
96
+ min: 1,
97
+ max: maxPageValue
93
98
  }), " ", typeof totalPages === "number" ? /*#__PURE__*/React.createElement(React.Fragment, null, "of\xA0", totalPages) : null) : null, /*#__PURE__*/React.createElement(Button, _extends({
94
99
  "aria-label": Label.NEXT_PAGE,
95
100
  className: "next",
96
101
  appearance: "base",
97
102
  hasIcon: true,
98
- disabled: currentPage === totalPages,
103
+ disabled: isInputDisabled || currentPage === totalPages,
99
104
  onClick: () => handleIncrementPage(currentPage, totalPages)
100
105
  }, nextButtonProps), /*#__PURE__*/React.createElement(Icon, {
101
106
  name: "chevron-down"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@canonical/react-components",
3
- "version": "2.7.2",
3
+ "version": "2.7.4",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.js",
6
6
  "author": {