@canonical/react-components 2.1.0 → 2.2.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 (41) 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/ContextualMenuDropdown/ContextualMenuDropdown.js +2 -2
  10. package/dist/components/MainTable/MainTable.d.ts +3 -1
  11. package/dist/components/ModularTable/ModularTable.stories.js +2 -2
  12. package/dist/components/Navigation/Navigation.d.ts +1 -1
  13. package/dist/components/Notification/Notification.d.ts +1 -1
  14. package/dist/components/Notification/Notification.js +3 -1
  15. package/dist/components/NotificationProvider/NotificationProvider.js +2 -2
  16. package/dist/components/SearchAndFilter/SearchAndFilter.js +1 -4
  17. package/dist/components/SearchAndFilter/utils.d.ts +3 -2
  18. package/dist/components/SideNavigation/SideNavigation.js +1 -1
  19. package/dist/components/Tooltip/Tooltip.js +1 -1
  20. package/dist/esm/components/Card/Card.stories.d.ts +2 -2
  21. package/dist/esm/components/CodeSnippet/CodeSnippet.stories.js +3 -2
  22. package/dist/esm/components/Col/Col.stories.d.ts +2 -1
  23. package/dist/esm/components/ConfirmationButton/ConfirmationButton.d.ts +7 -2
  24. package/dist/esm/components/ConfirmationButton/ConfirmationButton.js +11 -3
  25. package/dist/esm/components/ConfirmationButton/ConfirmationButton.stories.d.ts +1 -0
  26. package/dist/esm/components/ConfirmationButton/ConfirmationButton.stories.js +22 -0
  27. package/dist/esm/components/ContextualMenu/ContextualMenu.js +3 -3
  28. package/dist/esm/components/ContextualMenu/ContextualMenuDropdown/ContextualMenuDropdown.js +2 -2
  29. package/dist/esm/components/MainTable/MainTable.d.ts +3 -1
  30. package/dist/esm/components/ModularTable/ModularTable.stories.js +60 -12
  31. package/dist/esm/components/Navigation/Navigation.d.ts +1 -1
  32. package/dist/esm/components/Notification/Notification.d.ts +1 -1
  33. package/dist/esm/components/Notification/Notification.js +4 -2
  34. package/dist/esm/components/NotificationProvider/NotificationProvider.js +2 -2
  35. package/dist/esm/components/SearchAndFilter/SearchAndFilter.js +1 -4
  36. package/dist/esm/components/SearchAndFilter/utils.d.ts +3 -2
  37. package/dist/esm/components/SideNavigation/SideNavigation.js +1 -1
  38. package/dist/esm/components/Tooltip/Tooltip.js +1 -1
  39. package/dist/esm/hooks/useWindowFitment.js +2 -2
  40. package/dist/hooks/useWindowFitment.js +2 -2
  41. package/package.json +36 -37
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
  import type { Meta } from "@storybook/react";
3
- import Card from "./";
3
+ import Card, { CardProps } from "./";
4
4
  declare const meta: Meta<typeof Card>;
5
5
  export default meta;
6
6
  export declare const Default: {
@@ -29,5 +29,5 @@ export declare const Overlay: {
29
29
  overlay: boolean;
30
30
  children: string;
31
31
  };
32
- render: (args: any) => React.JSX.Element;
32
+ render: (args: CardProps) => React.JSX.Element;
33
33
  };
@@ -105,13 +105,14 @@ const WrapLines = exports.WrapLines = {
105
105
  */
106
106
  const Dropdown = exports.Dropdown = {
107
107
  render: () => {
108
- // eslint-disable-next-line react-hooks/rules-of-hooks
109
- const [lang, setLang] = (0, _react.useState)("html");
110
108
  const code = {
111
109
  js: "console.log(\"Example 1\");",
112
110
  css: ".p-heading--2 { color: red; }",
113
111
  html: "<h1 class=\"p-heading--2\">How to use code snippets</h1>"
114
112
  };
113
+
114
+ // eslint-disable-next-line react-hooks/rules-of-hooks
115
+ const [lang, setLang] = (0, _react.useState)("html");
115
116
  return /*#__PURE__*/_react.default.createElement(_CodeSnippet.default, {
116
117
  blocks: [{
117
118
  code: code[lang],
@@ -1,7 +1,8 @@
1
1
  import React from "react";
2
2
  import { Meta, StoryObj } from "@storybook/react";
3
3
  import Col from "./Col";
4
- declare const Template: (args: any) => React.JSX.Element;
4
+ import { ColProps } from ".";
5
+ declare const Template: (args: ColProps) => React.JSX.Element;
5
6
  declare const meta: Meta<typeof Template>;
6
7
  export default meta;
7
8
  type Story = StoryObj<typeof Col>;
@@ -1,4 +1,4 @@
1
- import React from "react";
1
+ import React, { MouseEvent } from "react";
2
2
  import { PropsWithSpread, SubComponentProps } from "../../types";
3
3
  import { ActionButtonProps } from "../ActionButton";
4
4
  import { ConfirmationModalProps } from "../ConfirmationModal";
@@ -20,9 +20,14 @@ export type Props = PropsWithSpread<{
20
20
  * Whether to show a hint about the SHIFT+Click shortcut to skip the confirmation modal.
21
21
  */
22
22
  showShiftClickHint?: boolean;
23
+ /**
24
+ * A handler that determines whether the confirmation modal should be shown.
25
+ * If it returns `true`, the modal is shown. If it returns `false`, the modal is not shown.
26
+ */
27
+ preModalOpenHook?: (event: MouseEvent<HTMLButtonElement>) => boolean;
23
28
  }, ActionButtonProps>;
24
29
  /**
25
30
  * `ConfirmationButton` is a specialised version of the [ActionButton](?path=/docs/actionbutton--default-story) component that uses a [ConfirmationModal](?path=/docs/confirmationmodal--default-story) to prompt a confirmation from the user before executing an action.
26
31
  */
27
- export declare const ConfirmationButton: ({ confirmationModalProps, onHoverText, shiftClickEnabled, showShiftClickHint, ...actionButtonProps }: Props) => React.JSX.Element;
32
+ export declare const ConfirmationButton: ({ confirmationModalProps, onHoverText, shiftClickEnabled, showShiftClickHint, preModalOpenHook, ...actionButtonProps }: Props) => React.JSX.Element;
28
33
  export default ConfirmationButton;
@@ -28,6 +28,7 @@ const ConfirmationButton = _ref => {
28
28
  onHoverText,
29
29
  shiftClickEnabled = false,
30
30
  showShiftClickHint = false,
31
+ preModalOpenHook,
31
32
  ...actionButtonProps
32
33
  } = _ref;
33
34
  const {
@@ -53,6 +54,13 @@ const ConfirmationButton = _ref => {
53
54
  openPortal(e);
54
55
  }
55
56
  };
57
+ const handleClick = e => {
58
+ if (preModalOpenHook) {
59
+ const result = preModalOpenHook(e);
60
+ if (!result) return;
61
+ }
62
+ shiftClickEnabled ? handleShiftClick(e) : openPortal(e);
63
+ };
56
64
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, isOpen && /*#__PURE__*/_react.default.createElement(Portal, null, /*#__PURE__*/_react.default.createElement(_ConfirmationModal.default, _extends({}, confirmationModalProps, {
57
65
  close: handleCancelModal,
58
66
  confirmButtonLabel: confirmationModalProps.confirmButtonLabel,
@@ -60,7 +68,7 @@ const ConfirmationButton = _ref => {
60
68
  }), confirmationModalProps.children, showShiftClickHint && /*#__PURE__*/_react.default.createElement("p", {
61
69
  className: "p-text--small u-text--muted u-hide--small"
62
70
  }, "Next time, you can skip this confirmation by holding", " ", /*#__PURE__*/_react.default.createElement("code", null, "SHIFT"), " and clicking the action."))), /*#__PURE__*/_react.default.createElement(_ActionButton.default, _extends({}, actionButtonProps, {
63
- onClick: shiftClickEnabled ? handleShiftClick : openPortal,
71
+ onClick: handleClick,
64
72
  title: generateTitle(onHoverText !== null && onHoverText !== void 0 ? onHoverText : confirmationModalProps.confirmButtonLabel)
65
73
  }), actionButtonProps.children));
66
74
  };
@@ -7,3 +7,4 @@ type Story = StoryObj<typeof ConfirmationButton>;
7
7
  export declare const IconAndLabel: Story;
8
8
  export declare const IconOnly: Story;
9
9
  export declare const BaseAppearance: Story;
10
+ export declare const WithPreModalOpenHook: Story;
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.default = exports.IconOnly = exports.IconAndLabel = exports.Default = exports.BaseAppearance = void 0;
6
+ exports.default = exports.WithPreModalOpenHook = exports.IconOnly = exports.IconAndLabel = exports.Default = exports.BaseAppearance = void 0;
7
7
  var _react = _interopRequireWildcard(require("react"));
8
8
  var _ConfirmationButton = _interopRequireDefault(require("./ConfirmationButton"));
9
9
  var _Icon = _interopRequireWildcard(require("../Icon"));
@@ -105,4 +105,26 @@ const BaseAppearance = exports.BaseAppearance = {
105
105
  }));
106
106
  },
107
107
  name: "Base appearance"
108
+ };
109
+ const WithPreModalOpenHook = exports.WithPreModalOpenHook = {
110
+ render: () => {
111
+ const dontOpenModal = () => false;
112
+ const openModal = () => true;
113
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_ConfirmationButton.default, {
114
+ preModalOpenHook: dontOpenModal,
115
+ confirmationModalProps: {
116
+ title: "Confirm delete",
117
+ confirmButtonLabel: "Delete",
118
+ children: /*#__PURE__*/_react.default.createElement("p", null, "This will permanently delete the user \"Simon\".", /*#__PURE__*/_react.default.createElement("br", null), "You cannot undo this action.")
119
+ }
120
+ }, "Don't open modal"), /*#__PURE__*/_react.default.createElement(_ConfirmationButton.default, {
121
+ preModalOpenHook: openModal,
122
+ confirmationModalProps: {
123
+ title: "Confirm delete",
124
+ confirmButtonLabel: "Delete",
125
+ children: /*#__PURE__*/_react.default.createElement("p", null, "This will permanently delete the user \"Simon\".", /*#__PURE__*/_react.default.createElement("br", null), "You cannot undo this action.")
126
+ }
127
+ }, "Open modal"));
128
+ },
129
+ name: "With preModalOpenHook handler"
108
130
  };
@@ -91,7 +91,7 @@ const ContextualMenu = _ref => {
91
91
  const updatePositionCoords = (0, _react.useCallback)(() => {
92
92
  const parent = getPositionNode(wrapper.current, positionNode);
93
93
  if (!parent) {
94
- return null;
94
+ return;
95
95
  }
96
96
  setPositionCoords(parent.getBoundingClientRect());
97
97
  }, [wrapper, positionNode]);
@@ -143,13 +143,13 @@ const ContextualMenu = _ref => {
143
143
  }
144
144
  }
145
145
  }, [closePortal, openPortal, visible, isOpen, previousVisible]);
146
- const onResize = (0, _react.useCallback)(evt => {
146
+ const onResize = (0, _react.useCallback)(() => {
147
147
  const parent = getPositionNode(wrapper.current, positionNode);
148
148
  if (parent && !getPositionNodeVisible(parent)) {
149
149
  // Hide the menu if the item has become hidden. This might happen in
150
150
  // a responsive table when columns become hidden as the page
151
151
  // becomes smaller.
152
- closePortal(evt);
152
+ closePortal();
153
153
  } else {
154
154
  // Update the coordinates so that the menu stays relative to the
155
155
  // toggle button.
@@ -164,11 +164,11 @@ const ContextualMenuDropdown = _ref => {
164
164
  const updateVerticalPosition = (0, _react.useCallback)(() => {
165
165
  var _dropdown$current$get;
166
166
  if (!positionNode) {
167
- return null;
167
+ return;
168
168
  }
169
169
  const scrollableParent = getClosestScrollableParent(positionNode);
170
170
  if (!scrollableParent) {
171
- return null;
171
+ return;
172
172
  }
173
173
  const scrollableParentRect = scrollableParent.getBoundingClientRect();
174
174
  const toggleRect = positionNode.getBoundingClientRect();
@@ -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.
@@ -255,14 +255,14 @@ const Subrows = exports.Subrows = {
255
255
  Header: "Flavour",
256
256
  accessor: "flavour",
257
257
  sortType: "basic",
258
- Cell: props => props.row.depth === 0 ? /*#__PURE__*/_react.default.createElement("strong", null, props.value) : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("input", {
258
+ Cell: props => "depth" in props.row && props.row.depth === 0 ? /*#__PURE__*/_react.default.createElement("strong", null, props.value) : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("input", {
259
259
  type: "checkbox"
260
260
  }), " ", props.value)
261
261
  }, {
262
262
  Header: "Scoops",
263
263
  accessor: "scoops",
264
264
  sortType: "basic",
265
- Cell: props => props.row.depth === 0 ? /*#__PURE__*/_react.default.createElement("span", {
265
+ Cell: props => "depth" in props.row && props.row.depth === 0 ? /*#__PURE__*/_react.default.createElement("span", {
266
266
  className: "u-text--muted"
267
267
  }, props.value) : props.value
268
268
  }], [])
@@ -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
  */
@@ -103,6 +103,7 @@ const Notification = _ref => {
103
103
  }, title), inline && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, "\u2002"), /*#__PURE__*/_react.default.createElement("p", {
104
104
  className: "p-notification__message"
105
105
  }, children), onDismiss && /*#__PURE__*/_react.default.createElement("button", {
106
+ type: "button",
106
107
  className: "p-notification__close",
107
108
  "data-testid": "notification-close-button",
108
109
  onClick: onDismiss
@@ -114,7 +115,8 @@ const Notification = _ref => {
114
115
  "data-testid": "notification-timestamp"
115
116
  }, timestamp), hasActions ? /*#__PURE__*/_react.default.createElement("div", {
116
117
  className: "p-notification__actions"
117
- }, actions.map((action, i) => /*#__PURE__*/_react.default.createElement(_Button.default, {
118
+ }, actions.map((action, i) => (0, _utils.isReactNode)(action) ? action : /*#__PURE__*/_react.default.createElement(_Button.default, {
119
+ type: "button",
118
120
  appearance: _Button.ButtonAppearance.LINK,
119
121
  className: "p-notification__action",
120
122
  "data-testid": "notification-action",
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.NotificationProvider = exports.NotificationConsumer = void 0;
7
7
  exports.useNotify = useNotify;
8
8
  var _react = _interopRequireWildcard(require("react"));
9
- var _isEqual = _interopRequireDefault(require("lodash/isEqual"));
9
+ var _fastDeepEqual = _interopRequireDefault(require("fast-deep-equal"));
10
10
  var _messageBuilder = require("./messageBuilder");
11
11
  var _Notification = _interopRequireWildcard(require("../Notification/Notification"));
12
12
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -30,7 +30,7 @@ const NotificationProvider = _ref => {
30
30
  const [notification, setNotification] = (0, _react.useState)(null);
31
31
  const clear = () => notification !== null && setNotification(null);
32
32
  const setDeduplicated = value => {
33
- if (!(0, _isEqual.default)(value, notification)) {
33
+ if (!(0, _fastDeepEqual.default)(value, notification)) {
34
34
  setNotification(value);
35
35
  }
36
36
  return value;
@@ -58,9 +58,6 @@ const SearchAndFilter = _ref => {
58
58
  mounted = false;
59
59
  };
60
60
  }, [searchData, returnSearchData]);
61
- const searchOnChange = searchTerm => {
62
- setSearchTerm(searchTerm);
63
- };
64
61
 
65
62
  // Hide manual input form field when search container is inactive
66
63
  (0, _react.useEffect)(() => {
@@ -242,7 +239,7 @@ const SearchAndFilter = _ref => {
242
239
  className: "p-search-and-filter__input",
243
240
  id: "search-and-filter-input",
244
241
  name: "search",
245
- onChange: e => searchOnChange(e.target.value),
242
+ onChange: e => setSearchTerm(e.target.value),
246
243
  placeholder: placeholder,
247
244
  type: "search",
248
245
  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;
@@ -59,7 +59,7 @@ const generateItems = (groups, listClassName, linkComponent, dark) => {
59
59
  };
60
60
  const getHasIcons = groups => groups === null || groups === void 0 ? void 0 : groups.some(group => {
61
61
  var _ref;
62
- return (_ref = group && "items" in group ? group.items : group) === null || _ref === void 0 ? void 0 : _ref.some(item => (0, _utils.isReactNode)(item) ? false : item && "icon" in item && !!item.icon);
62
+ return group && ((_ref = "items" in group ? group.items : group) === null || _ref === void 0 ? void 0 : _ref.some(item => (0, _utils.isReactNode)(item) ? false : item && "icon" in item && !!item.icon));
63
63
  });
64
64
 
65
65
  /**
@@ -204,7 +204,7 @@ const Tooltip = _ref => {
204
204
  return;
205
205
  }
206
206
  e.target.focus();
207
- openPortal(e);
207
+ openPortal();
208
208
  };
209
209
  const delayedOpenPortal = (0, _react.useCallback)(() => {
210
210
  if (isOpen) {
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
  import type { Meta } from "@storybook/react";
3
- import Card from "./";
3
+ import Card, { CardProps } from "./";
4
4
  declare const meta: Meta<typeof Card>;
5
5
  export default meta;
6
6
  export declare const Default: {
@@ -29,5 +29,5 @@ export declare const Overlay: {
29
29
  overlay: boolean;
30
30
  children: string;
31
31
  };
32
- render: (args: any) => React.JSX.Element;
32
+ render: (args: CardProps) => React.JSX.Element;
33
33
  };
@@ -97,13 +97,14 @@ export var WrapLines = {
97
97
  */
98
98
  export var Dropdown = {
99
99
  render: () => {
100
- // eslint-disable-next-line react-hooks/rules-of-hooks
101
- var [lang, setLang] = useState("html");
102
100
  var code = {
103
101
  js: "console.log(\"Example 1\");",
104
102
  css: ".p-heading--2 { color: red; }",
105
103
  html: "<h1 class=\"p-heading--2\">How to use code snippets</h1>"
106
104
  };
105
+
106
+ // eslint-disable-next-line react-hooks/rules-of-hooks
107
+ var [lang, setLang] = useState("html");
107
108
  return /*#__PURE__*/React.createElement(CodeSnippet, {
108
109
  blocks: [{
109
110
  code: code[lang],
@@ -1,7 +1,8 @@
1
1
  import React from "react";
2
2
  import { Meta, StoryObj } from "@storybook/react";
3
3
  import Col from "./Col";
4
- declare const Template: (args: any) => React.JSX.Element;
4
+ import { ColProps } from ".";
5
+ declare const Template: (args: ColProps) => React.JSX.Element;
5
6
  declare const meta: Meta<typeof Template>;
6
7
  export default meta;
7
8
  type Story = StoryObj<typeof Col>;
@@ -1,4 +1,4 @@
1
- import React from "react";
1
+ import React, { MouseEvent } from "react";
2
2
  import { PropsWithSpread, SubComponentProps } from "../../types";
3
3
  import { ActionButtonProps } from "../ActionButton";
4
4
  import { ConfirmationModalProps } from "../ConfirmationModal";
@@ -20,9 +20,14 @@ export type Props = PropsWithSpread<{
20
20
  * Whether to show a hint about the SHIFT+Click shortcut to skip the confirmation modal.
21
21
  */
22
22
  showShiftClickHint?: boolean;
23
+ /**
24
+ * A handler that determines whether the confirmation modal should be shown.
25
+ * If it returns `true`, the modal is shown. If it returns `false`, the modal is not shown.
26
+ */
27
+ preModalOpenHook?: (event: MouseEvent<HTMLButtonElement>) => boolean;
23
28
  }, ActionButtonProps>;
24
29
  /**
25
30
  * `ConfirmationButton` is a specialised version of the [ActionButton](?path=/docs/actionbutton--default-story) component that uses a [ConfirmationModal](?path=/docs/confirmationmodal--default-story) to prompt a confirmation from the user before executing an action.
26
31
  */
27
- export declare const ConfirmationButton: ({ confirmationModalProps, onHoverText, shiftClickEnabled, showShiftClickHint, ...actionButtonProps }: Props) => React.JSX.Element;
32
+ export declare const ConfirmationButton: ({ confirmationModalProps, onHoverText, shiftClickEnabled, showShiftClickHint, preModalOpenHook, ...actionButtonProps }: Props) => React.JSX.Element;
28
33
  export default ConfirmationButton;
@@ -1,4 +1,4 @@
1
- var _excluded = ["confirmationModalProps", "onHoverText", "shiftClickEnabled", "showShiftClickHint"];
1
+ var _excluded = ["confirmationModalProps", "onHoverText", "shiftClickEnabled", "showShiftClickHint", "preModalOpenHook"];
2
2
  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); }
3
3
  function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
4
4
  function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
@@ -23,7 +23,8 @@ export var ConfirmationButton = _ref => {
23
23
  confirmationModalProps,
24
24
  onHoverText,
25
25
  shiftClickEnabled = false,
26
- showShiftClickHint = false
26
+ showShiftClickHint = false,
27
+ preModalOpenHook
27
28
  } = _ref,
28
29
  actionButtonProps = _objectWithoutProperties(_ref, _excluded);
29
30
  var {
@@ -49,6 +50,13 @@ export var ConfirmationButton = _ref => {
49
50
  openPortal(e);
50
51
  }
51
52
  };
53
+ var handleClick = e => {
54
+ if (preModalOpenHook) {
55
+ var result = preModalOpenHook(e);
56
+ if (!result) return;
57
+ }
58
+ shiftClickEnabled ? handleShiftClick(e) : openPortal(e);
59
+ };
52
60
  return /*#__PURE__*/React.createElement(React.Fragment, null, isOpen && /*#__PURE__*/React.createElement(Portal, null, /*#__PURE__*/React.createElement(ConfirmationModal, _extends({}, confirmationModalProps, {
53
61
  close: handleCancelModal,
54
62
  confirmButtonLabel: confirmationModalProps.confirmButtonLabel,
@@ -56,7 +64,7 @@ export var ConfirmationButton = _ref => {
56
64
  }), confirmationModalProps.children, showShiftClickHint && /*#__PURE__*/React.createElement("p", {
57
65
  className: "p-text--small u-text--muted u-hide--small"
58
66
  }, "Next time, you can skip this confirmation by holding", " ", /*#__PURE__*/React.createElement("code", null, "SHIFT"), " and clicking the action."))), /*#__PURE__*/React.createElement(ActionButton, _extends({}, actionButtonProps, {
59
- onClick: shiftClickEnabled ? handleShiftClick : openPortal,
67
+ onClick: handleClick,
60
68
  title: generateTitle(onHoverText !== null && onHoverText !== void 0 ? onHoverText : confirmationModalProps.confirmButtonLabel)
61
69
  }), actionButtonProps.children));
62
70
  };
@@ -7,3 +7,4 @@ type Story = StoryObj<typeof ConfirmationButton>;
7
7
  export declare const IconAndLabel: Story;
8
8
  export declare const IconOnly: Story;
9
9
  export declare const BaseAppearance: Story;
10
+ export declare const WithPreModalOpenHook: Story;
@@ -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.
@@ -164,11 +164,11 @@ var ContextualMenuDropdown = _ref => {
164
164
  var updateVerticalPosition = useCallback(() => {
165
165
  var _dropdown$current$get;
166
166
  if (!positionNode) {
167
- return null;
167
+ return;
168
168
  }
169
169
  var scrollableParent = getClosestScrollableParent(positionNode);
170
170
  if (!scrollableParent) {
171
- return null;
171
+ return;
172
172
  }
173
173
  var scrollableParentRect = scrollableParent.getBoundingClientRect();
174
174
  var toggleRect = positionNode.getBoundingClientRect();
@@ -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.
@@ -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.0",
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
  },