carbon-react 146.4.0 → 146.4.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.
@@ -0,0 +1 @@
1
+ export default function areObjectsEqual(obj1: Record<string, unknown>, obj2: Record<string, unknown>): boolean;
@@ -0,0 +1,20 @@
1
+ export default function areObjectsEqual(obj1, obj2) {
2
+ // Check if both arguments are objects
3
+ if (typeof obj1 !== "object" || typeof obj2 !== "object" || obj1 === null || obj2 === null) {
4
+ return false;
5
+ }
6
+ // Get the keys of both objects
7
+ const keys1 = Object.keys(obj1);
8
+ const keys2 = Object.keys(obj2);
9
+ // If the number of keys is different, objects aren't equal
10
+ if (keys1.length !== keys2.length) {
11
+ return false;
12
+ } // Compare keys and values
13
+ for (const key of keys1) {
14
+ // Check if obj2 has the key and values are strictly equal
15
+ if (!Object.prototype.hasOwnProperty.call(obj2, key) || obj1[key] !== obj2[key]) {
16
+ return false;
17
+ }
18
+ }
19
+ return true;
20
+ }
@@ -9,6 +9,7 @@ import withFilter from "../__internal__/utils/with-filter.hoc";
9
9
  import StyledSelect from "../select.style";
10
10
  import SelectList from "../__internal__/select-list/select-list.component";
11
11
  import isExpectedOption from "../__internal__/utils/is-expected-option";
12
+ import areObjectsEqual from "../__internal__/utils/are-objects-equal";
12
13
  import isNavigationKey from "../__internal__/utils/is-navigation-key";
13
14
  import Logger from "../../../__internal__/utils/logger";
14
15
  import useStableCallback from "../../../hooks/__internal__/useStableCallback";
@@ -69,6 +70,7 @@ const FilterableSelect = /*#__PURE__*/React.forwardRef(({
69
70
  const [isOpen, setOpen] = useState(false);
70
71
  const [textValue, setTextValue] = useState("");
71
72
  const [selectedValue, setSelectedValue] = useState(value || defaultValue || "");
73
+ const receivedValue = useRef(value);
72
74
  const [highlightedValue, setHighlightedValue] = useState("");
73
75
  const [filterText, setFilterText] = useState("");
74
76
  const inputId = useRef(id || guid());
@@ -234,15 +236,27 @@ const FilterableSelect = /*#__PURE__*/React.forwardRef(({
234
236
  const onListActionMissingMessage = "onListAction prop required when using listActionButton prop";
235
237
  !(!hasListActionButton || hasListActionButton && onListAction) ? process.env.NODE_ENV !== "production" ? invariant(false, onListActionMissingMessage) : invariant(false) : void 0;
236
238
  }, [listActionButton, onListAction]);
239
+ const isFirstRender = useRef(true);
237
240
  useEffect(() => {
241
+ // when we render for the first time, we run setMatchingText to populate the input with the correct text
242
+ if (isFirstRender.current) {
243
+ setMatchingText(selectedValue);
244
+ }
238
245
  if (isControlled.current) {
239
- setMatchingText(value);
246
+ // when value is an object we should only run setMatchingText if the object changes between renders
247
+ if (typeof value === "object" && typeof receivedValue.current === "object") {
248
+ if (!areObjectsEqual(value, receivedValue.current)) {
249
+ setMatchingText(value);
250
+ receivedValue.current = value;
251
+ }
252
+ } else {
253
+ setMatchingText(value);
254
+ }
240
255
  }
241
256
  // update text value only when children are changing
242
257
  // eslint-disable-next-line react-hooks/exhaustive-deps
243
258
  }, [value, children]);
244
259
  const onFilterChange = useStableCallback(onFilterChangeProp);
245
- const isFirstRender = useRef(true);
246
260
  useEffect(() => {
247
261
  if (onFilterChange && !isFirstRender.current) {
248
262
  onFilterChange(filterText);
@@ -0,0 +1 @@
1
+ export default function areObjectsEqual(obj1: Record<string, unknown>, obj2: Record<string, unknown>): boolean;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = areObjectsEqual;
7
+ function areObjectsEqual(obj1, obj2) {
8
+ // Check if both arguments are objects
9
+ if (typeof obj1 !== "object" || typeof obj2 !== "object" || obj1 === null || obj2 === null) {
10
+ return false;
11
+ }
12
+ // Get the keys of both objects
13
+ const keys1 = Object.keys(obj1);
14
+ const keys2 = Object.keys(obj2);
15
+ // If the number of keys is different, objects aren't equal
16
+ if (keys1.length !== keys2.length) {
17
+ return false;
18
+ } // Compare keys and values
19
+ for (const key of keys1) {
20
+ // Check if obj2 has the key and values are strictly equal
21
+ if (!Object.prototype.hasOwnProperty.call(obj2, key) || obj1[key] !== obj2[key]) {
22
+ return false;
23
+ }
24
+ }
25
+ return true;
26
+ }
@@ -14,6 +14,7 @@ var _withFilter = _interopRequireDefault(require("../__internal__/utils/with-fil
14
14
  var _select = _interopRequireDefault(require("../select.style"));
15
15
  var _selectList = _interopRequireDefault(require("../__internal__/select-list/select-list.component"));
16
16
  var _isExpectedOption = _interopRequireDefault(require("../__internal__/utils/is-expected-option"));
17
+ var _areObjectsEqual = _interopRequireDefault(require("../__internal__/utils/are-objects-equal"));
17
18
  var _isNavigationKey = _interopRequireDefault(require("../__internal__/utils/is-navigation-key"));
18
19
  var _logger = _interopRequireDefault(require("../../../__internal__/utils/logger"));
19
20
  var _useStableCallback = _interopRequireDefault(require("../../../hooks/__internal__/useStableCallback"));
@@ -78,6 +79,7 @@ const FilterableSelect = exports.FilterableSelect = /*#__PURE__*/_react.default.
78
79
  const [isOpen, setOpen] = (0, _react.useState)(false);
79
80
  const [textValue, setTextValue] = (0, _react.useState)("");
80
81
  const [selectedValue, setSelectedValue] = (0, _react.useState)(value || defaultValue || "");
82
+ const receivedValue = (0, _react.useRef)(value);
81
83
  const [highlightedValue, setHighlightedValue] = (0, _react.useState)("");
82
84
  const [filterText, setFilterText] = (0, _react.useState)("");
83
85
  const inputId = (0, _react.useRef)(id || (0, _guid.default)());
@@ -243,15 +245,27 @@ const FilterableSelect = exports.FilterableSelect = /*#__PURE__*/_react.default.
243
245
  const onListActionMissingMessage = "onListAction prop required when using listActionButton prop";
244
246
  !(!hasListActionButton || hasListActionButton && onListAction) ? process.env.NODE_ENV !== "production" ? (0, _invariant.default)(false, onListActionMissingMessage) : (0, _invariant.default)(false) : void 0;
245
247
  }, [listActionButton, onListAction]);
248
+ const isFirstRender = (0, _react.useRef)(true);
246
249
  (0, _react.useEffect)(() => {
250
+ // when we render for the first time, we run setMatchingText to populate the input with the correct text
251
+ if (isFirstRender.current) {
252
+ setMatchingText(selectedValue);
253
+ }
247
254
  if (isControlled.current) {
248
- setMatchingText(value);
255
+ // when value is an object we should only run setMatchingText if the object changes between renders
256
+ if (typeof value === "object" && typeof receivedValue.current === "object") {
257
+ if (!(0, _areObjectsEqual.default)(value, receivedValue.current)) {
258
+ setMatchingText(value);
259
+ receivedValue.current = value;
260
+ }
261
+ } else {
262
+ setMatchingText(value);
263
+ }
249
264
  }
250
265
  // update text value only when children are changing
251
266
  // eslint-disable-next-line react-hooks/exhaustive-deps
252
267
  }, [value, children]);
253
268
  const onFilterChange = (0, _useStableCallback.default)(onFilterChangeProp);
254
- const isFirstRender = (0, _react.useRef)(true);
255
269
  (0, _react.useEffect)(() => {
256
270
  if (onFilterChange && !isFirstRender.current) {
257
271
  onFilterChange(filterText);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "carbon-react",
3
- "version": "146.4.0",
3
+ "version": "146.4.1",
4
4
  "description": "A library of reusable React components for easily building user interfaces.",
5
5
  "files": [
6
6
  "lib",