@canonical/react-components 2.1.0 → 2.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.
Files changed (55) hide show
  1. package/dist/components/Card/Card.stories.d.ts +2 -2
  2. package/dist/components/CodeSnippet/CodeSnippet.stories.js +3 -2
  3. package/dist/components/Col/Col.stories.d.ts +2 -1
  4. package/dist/components/ConfirmationButton/ConfirmationButton.d.ts +7 -2
  5. package/dist/components/ConfirmationButton/ConfirmationButton.js +9 -1
  6. package/dist/components/ConfirmationButton/ConfirmationButton.stories.d.ts +1 -0
  7. package/dist/components/ConfirmationButton/ConfirmationButton.stories.js +23 -1
  8. package/dist/components/ContextualMenu/ContextualMenu.js +3 -3
  9. package/dist/components/ContextualMenu/ContextualMenu.stories.d.ts +1 -0
  10. package/dist/components/ContextualMenu/ContextualMenu.stories.js +19 -1
  11. package/dist/components/ContextualMenu/ContextualMenuDropdown/ContextualMenuDropdown.d.ts +1 -0
  12. package/dist/components/ContextualMenu/ContextualMenuDropdown/ContextualMenuDropdown.js +30 -3
  13. package/dist/components/CustomSelect/CustomSelectDropdown/CustomSelectDropdown.d.ts +0 -1
  14. package/dist/components/CustomSelect/CustomSelectDropdown/CustomSelectDropdown.js +1 -23
  15. package/dist/components/MainTable/MainTable.d.ts +3 -1
  16. package/dist/components/ModularTable/ModularTable.d.ts +1 -1
  17. package/dist/components/ModularTable/ModularTable.js +1 -1
  18. package/dist/components/ModularTable/ModularTable.stories.js +2 -2
  19. package/dist/components/Navigation/Navigation.d.ts +1 -1
  20. package/dist/components/Notification/Notification.d.ts +1 -1
  21. package/dist/components/Notification/Notification.js +3 -1
  22. package/dist/components/NotificationProvider/NotificationProvider.js +2 -2
  23. package/dist/components/SearchAndFilter/SearchAndFilter.js +1 -4
  24. package/dist/components/SearchAndFilter/utils.d.ts +3 -2
  25. package/dist/components/SideNavigation/SideNavigation.js +1 -1
  26. package/dist/components/Tooltip/Tooltip.js +1 -1
  27. package/dist/esm/components/Card/Card.stories.d.ts +2 -2
  28. package/dist/esm/components/CodeSnippet/CodeSnippet.stories.js +3 -2
  29. package/dist/esm/components/Col/Col.stories.d.ts +2 -1
  30. package/dist/esm/components/ConfirmationButton/ConfirmationButton.d.ts +7 -2
  31. package/dist/esm/components/ConfirmationButton/ConfirmationButton.js +11 -3
  32. package/dist/esm/components/ConfirmationButton/ConfirmationButton.stories.d.ts +1 -0
  33. package/dist/esm/components/ConfirmationButton/ConfirmationButton.stories.js +22 -0
  34. package/dist/esm/components/ContextualMenu/ContextualMenu.js +3 -3
  35. package/dist/esm/components/ContextualMenu/ContextualMenu.stories.d.ts +1 -0
  36. package/dist/esm/components/ContextualMenu/ContextualMenu.stories.js +18 -0
  37. package/dist/esm/components/ContextualMenu/ContextualMenuDropdown/ContextualMenuDropdown.d.ts +1 -0
  38. package/dist/esm/components/ContextualMenu/ContextualMenuDropdown/ContextualMenuDropdown.js +28 -2
  39. package/dist/esm/components/CustomSelect/CustomSelectDropdown/CustomSelectDropdown.d.ts +0 -1
  40. package/dist/esm/components/CustomSelect/CustomSelectDropdown/CustomSelectDropdown.js +0 -21
  41. package/dist/esm/components/MainTable/MainTable.d.ts +3 -1
  42. package/dist/esm/components/ModularTable/ModularTable.d.ts +1 -1
  43. package/dist/esm/components/ModularTable/ModularTable.js +1 -1
  44. package/dist/esm/components/ModularTable/ModularTable.stories.js +60 -12
  45. package/dist/esm/components/Navigation/Navigation.d.ts +1 -1
  46. package/dist/esm/components/Notification/Notification.d.ts +1 -1
  47. package/dist/esm/components/Notification/Notification.js +4 -2
  48. package/dist/esm/components/NotificationProvider/NotificationProvider.js +2 -2
  49. package/dist/esm/components/SearchAndFilter/SearchAndFilter.js +1 -4
  50. package/dist/esm/components/SearchAndFilter/utils.d.ts +3 -2
  51. package/dist/esm/components/SideNavigation/SideNavigation.js +1 -1
  52. package/dist/esm/components/Tooltip/Tooltip.js +1 -1
  53. package/dist/esm/hooks/useWindowFitment.js +2 -2
  54. package/dist/hooks/useWindowFitment.js +2 -2
  55. package/package.json +36 -37
@@ -97,4 +97,26 @@ export var BaseAppearance = {
97
97
  }));
98
98
  },
99
99
  name: "Base appearance"
100
+ };
101
+ export var WithPreModalOpenHook = {
102
+ render: () => {
103
+ var dontOpenModal = () => false;
104
+ var openModal = () => true;
105
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ConfirmationButton, {
106
+ preModalOpenHook: dontOpenModal,
107
+ confirmationModalProps: {
108
+ title: "Confirm delete",
109
+ confirmButtonLabel: "Delete",
110
+ children: /*#__PURE__*/React.createElement("p", null, "This will permanently delete the user \"Simon\".", /*#__PURE__*/React.createElement("br", null), "You cannot undo this action.")
111
+ }
112
+ }, "Don't open modal"), /*#__PURE__*/React.createElement(ConfirmationButton, {
113
+ preModalOpenHook: openModal,
114
+ confirmationModalProps: {
115
+ title: "Confirm delete",
116
+ confirmButtonLabel: "Delete",
117
+ children: /*#__PURE__*/React.createElement("p", null, "This will permanently delete the user \"Simon\".", /*#__PURE__*/React.createElement("br", null), "You cannot undo this action.")
118
+ }
119
+ }, "Open modal"));
120
+ },
121
+ name: "With preModalOpenHook handler"
100
122
  };
@@ -87,7 +87,7 @@ var ContextualMenu = _ref => {
87
87
  var updatePositionCoords = useCallback(() => {
88
88
  var parent = getPositionNode(wrapper.current, positionNode);
89
89
  if (!parent) {
90
- return null;
90
+ return;
91
91
  }
92
92
  setPositionCoords(parent.getBoundingClientRect());
93
93
  }, [wrapper, positionNode]);
@@ -139,13 +139,13 @@ var ContextualMenu = _ref => {
139
139
  }
140
140
  }
141
141
  }, [closePortal, openPortal, visible, isOpen, previousVisible]);
142
- var onResize = useCallback(evt => {
142
+ var onResize = useCallback(() => {
143
143
  var parent = getPositionNode(wrapper.current, positionNode);
144
144
  if (parent && !getPositionNodeVisible(parent)) {
145
145
  // Hide the menu if the item has become hidden. This might happen in
146
146
  // a responsive table when columns become hidden as the page
147
147
  // becomes smaller.
148
- closePortal(evt);
148
+ closePortal();
149
149
  } else {
150
150
  // Update the coordinates so that the menu stays relative to the
151
151
  // toggle button.
@@ -11,3 +11,4 @@ export declare const Toggle: Story;
11
11
  export declare const OverflowingContainer: Story;
12
12
  export declare const ChildFunction: Story;
13
13
  export declare const ChildElement: Story;
14
+ export declare const InsideModal: Story;
@@ -1,6 +1,7 @@
1
1
  import React from "react";
2
2
  import Button from "../Button";
3
3
  import ContextualMenu from "./ContextualMenu";
4
+ import Modal from "../Modal";
4
5
  var ScrollTemplate = args => /*#__PURE__*/React.createElement("div", {
5
6
  style: {
6
7
  maxWidth: "30rem",
@@ -97,4 +98,21 @@ export var ChildElement = {
97
98
  position: "right",
98
99
  toggleLabel: "Click me!"
99
100
  }
101
+ };
102
+ export var InsideModal = {
103
+ name: "Inside modal",
104
+ args: {
105
+ links: Array.from({
106
+ length: 5
107
+ }, (_, index) => ({
108
+ children: "Link ".concat(index + 1),
109
+ onClick: () => {}
110
+ })),
111
+ hasToggleIcon: true,
112
+ position: "right",
113
+ toggleLabel: "Click me!"
114
+ },
115
+ render: args => /*#__PURE__*/React.createElement(Modal, {
116
+ title: "Contextual Menu inside Modal"
117
+ }, /*#__PURE__*/React.createElement(Template, args))
100
118
  };
@@ -39,5 +39,6 @@ export type Props<L = null> = {
39
39
  * @return The new position.
40
40
  */
41
41
  export declare const adjustForWindow: (position: Position, fitsWindow: WindowFitment) => Position;
42
+ export declare const getNearestParentsZIndex: (element: HTMLElement | null) => string;
42
43
  declare const ContextualMenuDropdown: <L>({ adjustedPosition, autoAdjust, handleClose, constrainPanelWidth, dropdownClassName, dropdownContent, id, isOpen, links, position, positionCoords, positionNode, scrollOverflow, setAdjustedPosition, contextualMenuClassName, ...props }: Props<L>) => React.JSX.Element;
43
44
  export default ContextualMenuDropdown;
@@ -134,6 +134,21 @@ var getClosestScrollableParent = node => {
134
134
  }
135
135
  return document.body;
136
136
  };
137
+
138
+ // nearest parents z-index that is not 0 or auto
139
+ export var getNearestParentsZIndex = element => {
140
+ if (!window || !element) {
141
+ return "0";
142
+ }
143
+ var zIndex = window.getComputedStyle(element, null).getPropertyValue("z-index");
144
+ if (!element.parentElement) {
145
+ return zIndex;
146
+ }
147
+ if (zIndex === "auto" || zIndex === "0" || zIndex === "") {
148
+ return getNearestParentsZIndex(element.parentElement);
149
+ }
150
+ return zIndex;
151
+ };
137
152
  var ContextualMenuDropdown = _ref => {
138
153
  var {
139
154
  adjustedPosition,
@@ -164,11 +179,11 @@ var ContextualMenuDropdown = _ref => {
164
179
  var updateVerticalPosition = useCallback(() => {
165
180
  var _dropdown$current$get;
166
181
  if (!positionNode) {
167
- return null;
182
+ return;
168
183
  }
169
184
  var scrollableParent = getClosestScrollableParent(positionNode);
170
185
  if (!scrollableParent) {
171
- return null;
186
+ return;
172
187
  }
173
188
  var scrollableParentRect = scrollableParent.getBoundingClientRect();
174
189
  var toggleRect = positionNode.getBoundingClientRect();
@@ -206,6 +221,17 @@ var ContextualMenuDropdown = _ref => {
206
221
  useEffect(() => {
207
222
  updateVerticalPosition();
208
223
  }, [updateVerticalPosition]);
224
+ useEffect(() => {
225
+ if (!dropdown.current) return;
226
+
227
+ // align z-index: when we are in a modal context, we want the dropdown to be above the modal
228
+ // apply the nearest parents z-index + 1
229
+ var zIndex = getNearestParentsZIndex(positionNode);
230
+ if (parseInt(zIndex) > 0) {
231
+ var _dropdown$current$par;
232
+ (_dropdown$current$par = dropdown.current.parentElement) === null || _dropdown$current$par === void 0 || _dropdown$current$par.style.setProperty("z-index", zIndex + 1);
233
+ }
234
+ }, [positionNode]);
209
235
  return (
210
236
  /*#__PURE__*/
211
237
  // Vanilla Framework uses .p-contextual-menu parent modifier classnames to determine the correct position of the .p-contextual-menu__dropdown dropdown (left, center, right).
@@ -19,7 +19,6 @@ export declare const adjustDropdownHeightBelow: (dropdown: HTMLUListElement) =>
19
19
  export declare const adjustDropdownHeightAbove: (dropdown: HTMLUListElement, search: HTMLInputElement | null) => void;
20
20
  export declare const dropdownIsAbove: (dropdown: HTMLUListElement) => boolean;
21
21
  export declare const adjustDropdownHeight: (dropdown: HTMLUListElement | null, search: HTMLInputElement | null) => void;
22
- export declare const getNearestParentsZIndex: (element: HTMLElement | null) => string;
23
22
  export declare const getOptionText: (option: CustomSelectOption) => string;
24
23
  declare const CustomSelectDropdown: FC<Props>;
25
24
  export default CustomSelectDropdown;
@@ -74,19 +74,6 @@ export var adjustDropdownHeight = (dropdown, search) => {
74
74
  }
75
75
  adjustDropdownHeightBelow(dropdown);
76
76
  };
77
- export var getNearestParentsZIndex = element => {
78
- if (!document.defaultView || !element) {
79
- return "0";
80
- }
81
- var zIndex = document.defaultView.getComputedStyle(element, null).getPropertyValue("z-index");
82
- if (!element.parentElement) {
83
- return zIndex;
84
- }
85
- if (zIndex === "auto" || zIndex === "0" || zIndex === "") {
86
- return getNearestParentsZIndex(element.parentElement);
87
- }
88
- return zIndex;
89
- };
90
77
  export var getOptionText = option => {
91
78
  if (option.text) {
92
79
  return option.text;
@@ -124,14 +111,6 @@ var CustomSelectDropdown = _ref => {
124
111
  // align width with wrapper toggle width
125
112
  var toggleWidth = (_toggle$getBoundingCl = toggle === null || toggle === void 0 || (_toggle$getBoundingCl2 = toggle.getBoundingClientRect()) === null || _toggle$getBoundingCl2 === void 0 ? void 0 : _toggle$getBoundingCl2.width) !== null && _toggle$getBoundingCl !== void 0 ? _toggle$getBoundingCl : 0;
126
113
  dropdownRef.current.style.setProperty("min-width", "".concat(toggleWidth, "px"));
127
-
128
- // align z-index: when we are in a modal context, we want the dropdown to be above the modal
129
- // apply the nearest parents z-index + 1
130
- var zIndex = getNearestParentsZIndex(toggle);
131
- if (parseInt(zIndex) > 0) {
132
- var _dropdownRef$current$;
133
- (_dropdownRef$current$ = dropdownRef.current.parentElement) === null || _dropdownRef$current$ === void 0 || _dropdownRef$current$.style.setProperty("z-index", zIndex + 1);
134
- }
135
114
  }
136
115
  setTimeout(() => {
137
116
  var _dropdownRef$current;
@@ -26,7 +26,9 @@ export type MainTableCell = PropsWithSpread<{
26
26
  * The content of the table cell.
27
27
  */
28
28
  content?: ReactNode;
29
- }, Omit<TableCellProps, "children">>;
29
+ }, Omit<TableCellProps, "children"> & {
30
+ [data: `data-${string}`]: string;
31
+ }>;
30
32
  export type MainTableRow = PropsWithSpread<{
31
33
  /**
32
34
  * Optional class(es) to apply to the row.
@@ -57,7 +57,7 @@ ModularTable components accepts `columns` and `data` arguments in the same forma
57
57
  `columns` - The core columns configuration object for the entire table. https://react-table.tanstack.com/docs/api/useTable#column-options
58
58
  `data` - The data array that you want to display on the table.
59
59
  ### Important note!
60
- Values passed to both of these params have to me memoized (for example via{" "}
60
+ Values passed to both of these params have to be memoized (for example via{" "}
61
61
  <code>React.useMemo</code>). Memoization ensures that our data isn't recreated
62
62
  on every render. If we didn't use <code>React.useMemo</code>, the table would
63
63
  think it was receiving new data on every render and attempt to recalulate a
@@ -50,7 +50,7 @@ ModularTable components accepts `columns` and `data` arguments in the same forma
50
50
  `columns` - The core columns configuration object for the entire table. https://react-table.tanstack.com/docs/api/useTable#column-options
51
51
  `data` - The data array that you want to display on the table.
52
52
  ### Important note!
53
- Values passed to both of these params have to me memoized (for example via{" "}
53
+ Values passed to both of these params have to be memoized (for example via{" "}
54
54
  <code>React.useMemo</code>). Memoization ensures that our data isn't recreated
55
55
  on every render. If we didn't use <code>React.useMemo</code>, the table would
56
56
  think it was receiving new data on every render and attempt to recalulate a
@@ -37,14 +37,22 @@ export var Default = {
37
37
  columns: React.useMemo(() => [{
38
38
  Header: "ID",
39
39
  accessor: "buildId",
40
- Cell: _ref2 => {
40
+ Cell: function (_Cell) {
41
+ function Cell(_x) {
42
+ return _Cell.apply(this, arguments);
43
+ }
44
+ Cell.toString = function () {
45
+ return _Cell.toString();
46
+ };
47
+ return Cell;
48
+ }(_ref2 => {
41
49
  var {
42
50
  value
43
51
  } = _ref2;
44
52
  return /*#__PURE__*/React.createElement("a", {
45
53
  href: "#test"
46
54
  }, "#", value);
47
- }
55
+ })
48
56
  }, {
49
57
  Header: "Architecture",
50
58
  accessor: "arch"
@@ -55,7 +63,15 @@ export var Default = {
55
63
  }, {
56
64
  Header: "Result",
57
65
  accessor: "result",
58
- Cell: _ref3 => {
66
+ Cell: function (_Cell2) {
67
+ function Cell(_x2) {
68
+ return _Cell2.apply(this, arguments);
69
+ }
70
+ Cell.toString = function () {
71
+ return _Cell2.toString();
72
+ };
73
+ return Cell;
74
+ }(_ref3 => {
59
75
  var {
60
76
  value
61
77
  } = _ref3;
@@ -67,7 +83,7 @@ export var Default = {
67
83
  default:
68
84
  return "Unknown";
69
85
  }
70
- },
86
+ }),
71
87
  getCellIcon: _ref4 => {
72
88
  var {
73
89
  value
@@ -155,14 +171,22 @@ export var Sortable = {
155
171
  Header: "ID",
156
172
  accessor: "buildId",
157
173
  sortType: "basic",
158
- Cell: _ref6 => {
174
+ Cell: function (_Cell3) {
175
+ function Cell(_x3) {
176
+ return _Cell3.apply(this, arguments);
177
+ }
178
+ Cell.toString = function () {
179
+ return _Cell3.toString();
180
+ };
181
+ return Cell;
182
+ }(_ref6 => {
159
183
  var {
160
184
  value
161
185
  } = _ref6;
162
186
  return /*#__PURE__*/React.createElement("a", {
163
187
  href: "#test"
164
188
  }, "#", value);
165
- }
189
+ })
166
190
  }, {
167
191
  Header: "Architecture",
168
192
  accessor: "arch",
@@ -176,7 +200,15 @@ export var Sortable = {
176
200
  Header: "Result",
177
201
  accessor: "result",
178
202
  sortType: "basic",
179
- Cell: _ref7 => {
203
+ Cell: function (_Cell4) {
204
+ function Cell(_x4) {
205
+ return _Cell4.apply(this, arguments);
206
+ }
207
+ Cell.toString = function () {
208
+ return _Cell4.toString();
209
+ };
210
+ return Cell;
211
+ }(_ref7 => {
180
212
  var {
181
213
  value
182
214
  } = _ref7;
@@ -188,7 +220,7 @@ export var Sortable = {
188
220
  default:
189
221
  return "Unknown";
190
222
  }
191
- },
223
+ }),
192
224
  getCellIcon: _ref8 => {
193
225
  var {
194
226
  value
@@ -247,16 +279,32 @@ export var Subrows = {
247
279
  Header: "Flavour",
248
280
  accessor: "flavour",
249
281
  sortType: "basic",
250
- Cell: props => props.row.depth === 0 ? /*#__PURE__*/React.createElement("strong", null, props.value) : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("input", {
282
+ Cell: function (_Cell5) {
283
+ function Cell(_x5) {
284
+ return _Cell5.apply(this, arguments);
285
+ }
286
+ Cell.toString = function () {
287
+ return _Cell5.toString();
288
+ };
289
+ return Cell;
290
+ }(props => "depth" in props.row && props.row.depth === 0 ? /*#__PURE__*/React.createElement("strong", null, props.value) : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("input", {
251
291
  type: "checkbox"
252
- }), " ", props.value)
292
+ }), " ", props.value))
253
293
  }, {
254
294
  Header: "Scoops",
255
295
  accessor: "scoops",
256
296
  sortType: "basic",
257
- Cell: props => props.row.depth === 0 ? /*#__PURE__*/React.createElement("span", {
297
+ Cell: function (_Cell6) {
298
+ function Cell(_x6) {
299
+ return _Cell6.apply(this, arguments);
300
+ }
301
+ Cell.toString = function () {
302
+ return _Cell6.toString();
303
+ };
304
+ return Cell;
305
+ }(props => "depth" in props.row && props.row.depth === 0 ? /*#__PURE__*/React.createElement("span", {
258
306
  className: "u-text--muted"
259
- }, props.value) : props.value
307
+ }, props.value) : props.value)
260
308
  }], [])
261
309
  // eslint-disable-next-line react-hooks/rules-of-hooks
262
310
  ,
@@ -1,6 +1,6 @@
1
1
  import { ReactNode, HTMLProps } from "react";
2
2
  import React from "react";
3
- import type { GenerateLink, NavItem, LogoProps } from "./types";
3
+ import { GenerateLink, NavItem, LogoProps } from "./types";
4
4
  import { PropsWithSpread, SubComponentProps } from "../../types";
5
5
  import { SearchBoxProps } from "../SearchBox";
6
6
  import { Theme } from "../../enums";
@@ -27,7 +27,7 @@ export type Props = PropsWithSpread<{
27
27
  /**
28
28
  * A list of up to two actions that the notification can perform.
29
29
  */
30
- actions?: NotificationAction[];
30
+ actions?: (NotificationAction | ReactNode)[];
31
31
  /**
32
32
  * Whether the notification should not have a border.
33
33
  */
@@ -5,7 +5,7 @@ function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) r
5
5
  import classNames from "classnames";
6
6
  import React, { useEffect, useRef } from "react";
7
7
  import Button, { ButtonAppearance } from "../Button";
8
- import { IS_DEV } from "../../utils";
8
+ import { IS_DEV, isReactNode } from "../../utils";
9
9
  export var Label = /*#__PURE__*/function (Label) {
10
10
  Label["Close"] = "Close notification";
11
11
  return Label;
@@ -97,6 +97,7 @@ var Notification = _ref => {
97
97
  }, title), inline && /*#__PURE__*/React.createElement(React.Fragment, null, "\u2002"), /*#__PURE__*/React.createElement("p", {
98
98
  className: "p-notification__message"
99
99
  }, children), onDismiss && /*#__PURE__*/React.createElement("button", {
100
+ type: "button",
100
101
  className: "p-notification__close",
101
102
  "data-testid": "notification-close-button",
102
103
  onClick: onDismiss
@@ -108,7 +109,8 @@ var Notification = _ref => {
108
109
  "data-testid": "notification-timestamp"
109
110
  }, timestamp), hasActions ? /*#__PURE__*/React.createElement("div", {
110
111
  className: "p-notification__actions"
111
- }, actions.map((action, i) => /*#__PURE__*/React.createElement(Button, {
112
+ }, actions.map((action, i) => isReactNode(action) ? action : /*#__PURE__*/React.createElement(Button, {
113
+ type: "button",
112
114
  appearance: ButtonAppearance.LINK,
113
115
  className: "p-notification__action",
114
116
  "data-testid": "notification-action",
@@ -1,5 +1,5 @@
1
1
  import React, { createContext, useContext, useEffect, useRef, useState } from "react";
2
- import isEqual from "lodash/isEqual";
2
+ import fastDeepEqual from "fast-deep-equal";
3
3
  import { info as _info, failure as _failure, success as _success, queue } from "./messageBuilder";
4
4
  import Notification, { DefaultTitles } from "../Notification/Notification";
5
5
  var NotifyContext = /*#__PURE__*/createContext({
@@ -20,7 +20,7 @@ export var NotificationProvider = _ref => {
20
20
  var [notification, setNotification] = useState(null);
21
21
  var clear = () => notification !== null && setNotification(null);
22
22
  var setDeduplicated = value => {
23
- if (!isEqual(value, notification)) {
23
+ if (!fastDeepEqual(value, notification)) {
24
24
  setNotification(value);
25
25
  }
26
26
  return value;
@@ -52,9 +52,6 @@ var SearchAndFilter = _ref => {
52
52
  mounted = false;
53
53
  };
54
54
  }, [searchData, returnSearchData]);
55
- var searchOnChange = searchTerm => {
56
- setSearchTerm(searchTerm);
57
- };
58
55
 
59
56
  // Hide manual input form field when search container is inactive
60
57
  useEffect(() => {
@@ -236,7 +233,7 @@ var SearchAndFilter = _ref => {
236
233
  className: "p-search-and-filter__input",
237
234
  id: "search-and-filter-input",
238
235
  name: "search",
239
- onChange: e => searchOnChange(e.target.value),
236
+ onChange: e => setSearchTerm(e.target.value),
240
237
  placeholder: placeholder,
241
238
  type: "search",
242
239
  value: searchTerm
@@ -1,13 +1,14 @@
1
+ import { SearchAndFilterChip } from "./types";
1
2
  /**
2
3
  * Return number of overflowing chips given a row threshold
3
4
  * @param {array} chips - An array of chips
4
5
  * @param {Integer} overflowRowLimit - Number of rows to show before counting
5
6
  * overflow
6
7
  */
7
- export declare const overflowingChipsCount: (chips: any, overflowRowLimit: any) => number;
8
+ export declare const overflowingChipsCount: (chips: NodeListOf<HTMLElement>, overflowRowLimit: number) => number;
8
9
  /**
9
10
  * Check if supplied chip object already exists in searchData prop
10
11
  * @param {Object} chip - A chip object {lead: 'foo', value: 'bar'}
11
12
  * @param {Array} existingArr - An array of chip objects
12
13
  */
13
- export declare const isChipInArray: (chip: any, existingArr: any) => any;
14
+ export declare const isChipInArray: (chip: SearchAndFilterChip, existingArr: SearchAndFilterChip[]) => boolean;
@@ -58,7 +58,7 @@ var generateItems = (groups, listClassName, linkComponent, dark) => {
58
58
  };
59
59
  var getHasIcons = groups => groups === null || groups === void 0 ? void 0 : groups.some(group => {
60
60
  var _ref;
61
- return (_ref = group && "items" in group ? group.items : group) === null || _ref === void 0 ? void 0 : _ref.some(item => isReactNode(item) ? false : item && "icon" in item && !!item.icon);
61
+ return group && ((_ref = "items" in group ? group.items : group) === null || _ref === void 0 ? void 0 : _ref.some(item => isReactNode(item) ? false : item && "icon" in item && !!item.icon));
62
62
  });
63
63
 
64
64
  /**
@@ -194,7 +194,7 @@ var Tooltip = _ref => {
194
194
  return;
195
195
  }
196
196
  e.target.focus();
197
- openPortal(e);
197
+ openPortal();
198
198
  };
199
199
  var delayedOpenPortal = useCallback(() => {
200
200
  if (isOpen) {
@@ -23,8 +23,8 @@ export var useWindowFitment = function useWindowFitment(targetNode, referenceNod
23
23
  referenceCoordinates = {
24
24
  // The mouse is a single point so use 0 for the height and width.
25
25
  height: 0,
26
- left: evt.x || 0,
27
- top: evt.y || 0,
26
+ left: ("x" in evt && typeof evt.x === "number" ? evt.x : null) || 0,
27
+ top: ("y" in evt && typeof evt.y === "number" ? evt.y : null) || 0,
28
28
  width: 0
29
29
  };
30
30
  }
@@ -29,8 +29,8 @@ const useWindowFitment = function (targetNode, referenceNode, callback) {
29
29
  referenceCoordinates = {
30
30
  // The mouse is a single point so use 0 for the height and width.
31
31
  height: 0,
32
- left: evt.x || 0,
33
- top: evt.y || 0,
32
+ left: ("x" in evt && typeof evt.x === "number" ? evt.x : null) || 0,
33
+ top: ("y" in evt && typeof evt.y === "number" ? evt.y : null) || 0,
34
34
  width: 0
35
35
  };
36
36
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@canonical/react-components",
3
- "version": "2.1.0",
3
+ "version": "2.2.1",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.js",
6
6
  "author": {
@@ -26,87 +26,86 @@
26
26
  "homepage": "https://canonical.github.io/react-components",
27
27
  "devDependencies": {
28
28
  "@babel/cli": "7.26.4",
29
- "@babel/eslint-parser": "7.26.5",
30
- "@babel/plugin-proposal-class-properties": "7.18.6",
31
- "@babel/preset-env": "7.26.0",
29
+ "@babel/eslint-parser": "7.26.8",
30
+ "@babel/plugin-transform-class-properties": "7.25.9",
31
+ "@babel/preset-env": "7.26.9",
32
32
  "@babel/preset-react": "7.26.3",
33
33
  "@babel/preset-typescript": "7.26.0",
34
- "@eslint/compat": "1.2.5",
34
+ "@eslint/compat": "1.2.6",
35
35
  "@eslint/eslintrc": "3.2.0",
36
- "@eslint/js": "9.18.0",
37
- "@percy/cli": "1.30.6",
36
+ "@eslint/js": "9.20.0",
37
+ "@percy/cli": "1.30.7",
38
38
  "@percy/storybook": "6.0.3",
39
39
  "@semantic-release/changelog": "6.0.3",
40
40
  "@semantic-release/git": "10.0.1",
41
- "@storybook/addon-a11y": "8.4.7",
42
- "@storybook/addon-essentials": "8.4.7",
43
- "@storybook/addon-interactions": "8.4.7",
44
- "@storybook/addon-links": "8.5.0",
45
- "@storybook/addon-onboarding": "8.5.0",
41
+ "@storybook/addon-a11y": "8.5.6",
42
+ "@storybook/addon-essentials": "8.5.6",
43
+ "@storybook/addon-interactions": "8.5.6",
44
+ "@storybook/addon-links": "8.5.6",
45
+ "@storybook/addon-onboarding": "8.5.6",
46
46
  "@storybook/addon-webpack5-compiler-babel": "3.0.5",
47
- "@storybook/blocks": "8.4.7",
48
- "@storybook/react": "8.4.7",
49
- "@storybook/react-webpack5": "8.5.0",
50
- "@testing-library/cypress": "10.0.2",
47
+ "@storybook/blocks": "8.5.6",
48
+ "@storybook/react": "8.5.6",
49
+ "@storybook/react-webpack5": "8.5.6",
50
+ "@testing-library/cypress": "10.0.3",
51
51
  "@testing-library/dom": "10.4.0",
52
52
  "@testing-library/jest-dom": "6.6.3",
53
- "@testing-library/react": "16.1.0",
54
- "@testing-library/user-event": "14.5.2",
55
- "@types/lodash.isequal": "4",
53
+ "@testing-library/react": "16.2.0",
54
+ "@testing-library/user-event": "14.6.1",
56
55
  "babel-jest": "29.7.0",
57
56
  "babel-loader": "9.2.1",
58
57
  "babel-plugin-module-resolver": "5.0.2",
59
58
  "babel-plugin-typescript-to-proptypes": "2.1.0",
60
59
  "concurrently": "9.1.2",
61
60
  "css-loader": "7.1.2",
62
- "cypress": "14.0.1",
61
+ "cypress": "14.0.3",
63
62
  "deepmerge": "4.3.1",
64
- "eslint": "9.18.0",
63
+ "eslint": "9.20.1",
65
64
  "eslint-config-prettier": "10.0.1",
66
65
  "eslint-plugin-cypress": "4.1.0",
67
66
  "eslint-plugin-flowtype": "8.0.3",
68
67
  "eslint-plugin-import": "2.31.0",
69
68
  "eslint-plugin-jsx-a11y": "6.10.2",
70
- "eslint-plugin-prettier": "5.2.2",
69
+ "eslint-plugin-prettier": "5.2.3",
71
70
  "eslint-plugin-react": "7.37.4",
72
71
  "eslint-plugin-react-hooks": "5.1.0",
73
- "eslint-plugin-storybook": "0.11.2",
72
+ "eslint-plugin-storybook": "0.11.3",
74
73
  "eslint-plugin-testing-library": "7.1.1",
75
74
  "formik": "2.4.6",
76
75
  "jest": "29.7.0",
77
76
  "npm-package-json-lint": "8.0.0",
78
- "prettier": "3.4.2",
77
+ "prettier": "3.5.1",
79
78
  "react": "19.0.0",
80
79
  "react-docgen-typescript-loader": "3.7.2",
81
80
  "react-dom": "19.0.0",
82
- "sass": "1.83.4",
83
- "sass-loader": "16.0.4",
84
- "semantic-release": "24.2.1",
85
- "storybook": "8.4.7",
81
+ "sass": "1.85.0",
82
+ "sass-loader": "16.0.5",
83
+ "semantic-release": "24.2.3",
84
+ "storybook": "8.5.6",
86
85
  "strip-ansi": "7.1.0",
87
86
  "style-loader": "4.0.0",
88
- "stylelint": "16.13.2",
87
+ "stylelint": "16.14.1",
89
88
  "stylelint-config-prettier": "9.0.5",
90
89
  "stylelint-config-recommended-scss": "14.1.0",
91
90
  "stylelint-order": "6.0.4",
92
- "stylelint-prettier": "5.0.2",
91
+ "stylelint-prettier": "5.0.3",
93
92
  "ts-jest": "29.2.5",
94
93
  "tsc-alias": "1.8.10",
95
94
  "typescript": "5.7.3",
96
- "typescript-eslint": "8.20.0",
97
- "vanilla-framework": "4.20.2",
95
+ "typescript-eslint": "8.24.1",
96
+ "vanilla-framework": "4.21.0",
98
97
  "wait-on": "8.0.2",
99
- "webpack": "5.97.1"
98
+ "webpack": "5.98.0"
100
99
  },
101
100
  "dependencies": {
102
101
  "@types/jest": "29.5.14",
103
- "@types/node": "20.17.13",
104
- "@types/react": "19.0.8",
105
- "@types/react-dom": "19.0.3",
102
+ "@types/node": "20.17.19",
103
+ "@types/react": "19.0.10",
104
+ "@types/react-dom": "19.0.4",
106
105
  "@types/react-table": "7.7.20",
107
106
  "classnames": "2.5.1",
107
+ "fast-deep-equal": "3.1.3",
108
108
  "jest-environment-jsdom": "29.7.0",
109
- "lodash.isequal": "4.5.0",
110
109
  "prop-types": "15.8.1",
111
110
  "react-table": "7.8.0"
112
111
  },