@carbon/react 1.86.0 → 1.87.0-rc.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 (47) hide show
  1. package/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +838 -838
  2. package/es/components/Button/Button.Skeleton.js +2 -1
  3. package/es/components/Button/Button.d.ts +1 -1
  4. package/es/components/Button/Button.js +2 -2
  5. package/es/components/Button/ButtonBase.js +2 -0
  6. package/es/components/CodeSnippet/CodeSnippet.js +1 -0
  7. package/es/components/ComboBox/ComboBox.d.ts +7 -0
  8. package/es/components/ComboBox/ComboBox.js +10 -1
  9. package/es/components/ContainedList/ContainedList.d.ts +1 -1
  10. package/es/components/ContainedList/ContainedList.js +3 -3
  11. package/es/components/Dropdown/Dropdown.Skeleton.js +4 -4
  12. package/es/components/FluidNumberInput/FluidNumberInput.d.ts +3 -2
  13. package/es/components/FluidNumberInput/FluidNumberInput.js +3 -2
  14. package/es/components/IconButton/index.d.ts +1 -1
  15. package/es/components/MultiSelect/FilterableMultiSelect.d.ts +7 -0
  16. package/es/components/MultiSelect/FilterableMultiSelect.js +17 -7
  17. package/es/components/NumberInput/NumberInput.d.ts +3 -2
  18. package/es/components/NumberInput/NumberInput.js +4 -3
  19. package/es/components/Popover/index.js +5 -4
  20. package/es/components/Toggletip/index.d.ts +1 -1
  21. package/es/components/Toggletip/index.js +1 -1
  22. package/es/internal/useEvent.d.ts +2 -2
  23. package/es/internal/useEvent.js +4 -3
  24. package/lib/components/Button/Button.Skeleton.js +2 -1
  25. package/lib/components/Button/Button.d.ts +1 -1
  26. package/lib/components/Button/Button.js +2 -2
  27. package/lib/components/Button/ButtonBase.js +2 -0
  28. package/lib/components/CodeSnippet/CodeSnippet.js +1 -0
  29. package/lib/components/ComboBox/ComboBox.d.ts +7 -0
  30. package/lib/components/ComboBox/ComboBox.js +10 -1
  31. package/lib/components/ContainedList/ContainedList.d.ts +1 -1
  32. package/lib/components/ContainedList/ContainedList.js +3 -3
  33. package/lib/components/Dropdown/Dropdown.Skeleton.js +4 -4
  34. package/lib/components/FluidNumberInput/FluidNumberInput.d.ts +3 -2
  35. package/lib/components/FluidNumberInput/FluidNumberInput.js +3 -2
  36. package/lib/components/IconButton/index.d.ts +1 -1
  37. package/lib/components/MultiSelect/FilterableMultiSelect.d.ts +7 -0
  38. package/lib/components/MultiSelect/FilterableMultiSelect.js +17 -7
  39. package/lib/components/NumberInput/NumberInput.d.ts +3 -2
  40. package/lib/components/NumberInput/NumberInput.js +4 -3
  41. package/lib/components/Popover/index.js +4 -3
  42. package/lib/components/Toggletip/index.d.ts +1 -1
  43. package/lib/components/Toggletip/index.js +1 -1
  44. package/lib/internal/useEvent.d.ts +2 -2
  45. package/lib/internal/useEvent.js +4 -3
  46. package/package.json +5 -5
  47. package/telemetry.yml +1 -0
@@ -191,6 +191,13 @@ export interface FilterableMultiSelectProps<ItemType> extends MultiSelectSorting
191
191
  * Provide the text that is displayed when the control is in warning state
192
192
  */
193
193
  warnText?: ReactNode;
194
+ /**
195
+ * Specify native input attributes to place on the `<input>`, like maxLength.
196
+ * These are passed to downshift's getInputProps() and will override the
197
+ * internal input props.
198
+ * https://github.com/downshift-js/downshift?tab=readme-ov-file#getinputprops
199
+ */
200
+ inputProps?: React.InputHTMLAttributes<HTMLInputElement>;
194
201
  }
195
202
  export declare const FilterableMultiSelect: {
196
203
  <ItemType>(props: FilterableMultiSelectProps<ItemType>): ReactElement<any>;
@@ -114,7 +114,8 @@ const FilterableMultiSelect = /*#__PURE__*/React.forwardRef(function FilterableM
114
114
  useTitleInItem,
115
115
  warn,
116
116
  warnText,
117
- slug
117
+ slug,
118
+ inputProps
118
119
  }, ref) {
119
120
  const {
120
121
  isFluid
@@ -350,7 +351,7 @@ const FilterableMultiSelect = /*#__PURE__*/React.forwardRef(function FilterableM
350
351
  }
351
352
  return {
352
353
  ...changes,
353
- highlightedIndex: null
354
+ highlightedIndex: controlledSelectedItems.length > 0 ? 0 : -1
354
355
  };
355
356
  case InputChange:
356
357
  if (onInputValueChange) {
@@ -363,6 +364,7 @@ const FilterableMultiSelect = /*#__PURE__*/React.forwardRef(function FilterableM
363
364
  highlightedIndex: 0
364
365
  };
365
366
  case InputClick:
367
+ setIsOpen(changes.isOpen || false);
366
368
  validateHighlightFocus();
367
369
  if (changes.isOpen && !changes.selectedItem) {
368
370
  return {
@@ -372,7 +374,7 @@ const FilterableMultiSelect = /*#__PURE__*/React.forwardRef(function FilterableM
372
374
  return {
373
375
  ...changes,
374
376
  isOpen: false,
375
- highlightedIndex: null
377
+ highlightedIndex: controlledSelectedItems.length > 0 ? 0 : -1
376
378
  };
377
379
  case MenuMouseLeave:
378
380
  return {
@@ -494,7 +496,7 @@ const FilterableMultiSelect = /*#__PURE__*/React.forwardRef(function FilterableM
494
496
  }
495
497
  }
496
498
  });
497
- const inputProps = getInputProps(getDropdownProps({
499
+ const inputProp = getInputProps(getDropdownProps({
498
500
  'aria-controls': isOpen ? menuId : undefined,
499
501
  'aria-describedby': helperText ? helperId : undefined,
500
502
  'aria-haspopup': 'listbox',
@@ -504,6 +506,7 @@ const FilterableMultiSelect = /*#__PURE__*/React.forwardRef(function FilterableM
504
506
  disabled,
505
507
  placeholder,
506
508
  preventKeyAction: isOpen,
509
+ ...inputProps,
507
510
  onClick: () => handleMenuChange(true),
508
511
  onKeyDown(event) {
509
512
  const $input = event.target;
@@ -557,7 +560,7 @@ const FilterableMultiSelect = /*#__PURE__*/React.forwardRef(function FilterableM
557
560
  setIsFocused(evt?.type === 'focus' ? true : false);
558
561
  }
559
562
  };
560
- const mergedRef = mergeRefs["default"](textInput, inputProps.ref);
563
+ const mergedRef = mergeRefs["default"](textInput, inputProp.ref);
561
564
  const readOnlyEventHandlers = readOnly ? {
562
565
  onClick: evt => {
563
566
  // NOTE: does not prevent click
@@ -612,7 +615,7 @@ const FilterableMultiSelect = /*#__PURE__*/React.forwardRef(function FilterableM
612
615
  disabled: disabled
613
616
  }), /*#__PURE__*/React__default["default"].createElement("input", _rollupPluginBabelHelpers["extends"]({
614
617
  className: inputClasses
615
- }, inputProps, {
618
+ }, inputProp, {
616
619
  ref: mergedRef
617
620
  }, readOnlyEventHandlers, {
618
621
  readOnly: readOnly
@@ -827,7 +830,14 @@ FilterableMultiSelect.propTypes = {
827
830
  /**
828
831
  * Provide the text that is displayed when the control is in warning state
829
832
  */
830
- warnText: PropTypes__default["default"].node
833
+ warnText: PropTypes__default["default"].node,
834
+ /**
835
+ * Specify native input attributes to place on the `<input>`, like maxLength.
836
+ * These are passed to downshift's getInputProps() and will override the
837
+ * internal input props.
838
+ * https://github.com/downshift-js/downshift?tab=readme-ov-file#getinputprops
839
+ */
840
+ inputProps: PropTypes__default["default"].object
831
841
  };
832
842
 
833
843
  exports.FilterableMultiSelect = FilterableMultiSelect;
@@ -72,8 +72,9 @@ export interface NumberInputProps extends Omit<React.InputHTMLAttributes<HTMLInp
72
72
  */
73
73
  id: string;
74
74
  /**
75
- * Instruct the browser which keyboard to display on mobile devices. Note that
76
- * standard numeric keyboards vary across devices and operating systems.
75
+ * Instruct the browser which keyboard to display on mobile devices. Defaults
76
+ * to `decimal`, but note that standard numeric keyboards vary across devices
77
+ * and operating systems.
77
78
  * @see https://css-tricks.com/everything-you-ever-wanted-to-know-about-inputmode/
78
79
  */
79
80
  inputMode?: React.HTMLAttributes<HTMLInputElement>['inputMode'];
@@ -64,7 +64,7 @@ const NumberInput = /*#__PURE__*/React__default["default"].forwardRef(function N
64
64
  hideSteppers,
65
65
  iconDescription,
66
66
  id,
67
- inputMode,
67
+ inputMode = 'decimal',
68
68
  invalid = false,
69
69
  invalidText,
70
70
  label,
@@ -505,8 +505,9 @@ NumberInput.propTypes = {
505
505
  */
506
506
  id: PropTypes__default["default"].string.isRequired,
507
507
  /**
508
- * Instruct the browser which keyboard to display on mobile devices. Note that
509
- * standard numeric keyboards vary across devices and operating systems.
508
+ * Instruct the browser which keyboard to display on mobile devices. Defaults
509
+ * to `decimal`, but note that standard numeric keyboards vary across devices
510
+ * and operating systems.
510
511
  * @see https://css-tricks.com/everything-you-ever-wanted-to-know-about-inputmode/
511
512
  */
512
513
  inputMode: PropTypes__default["default"].oneOf(['none', 'text', 'tel', 'url', 'email', 'numeric', 'decimal', 'search']),
@@ -69,9 +69,10 @@ forwardRef) {
69
69
  const enableFloatingStyles = index.useFeatureFlag('enable-v12-dynamic-floating-styles') || autoAlign;
70
70
  let align = mapPopoverAlign.mapPopoverAlign(initialAlign);
71
71
 
72
- // If the `Popover` is the last focusable item in the tab order, it should also close when the browser window loses focus (#12922)
73
- useEvent.useWindowEvent('blur', () => {
74
- if (open) {
72
+ // The `Popover` should close whenever it and its children loses focus
73
+ useEvent.useEvent(popover, 'focusout', event => {
74
+ const relatedTarget = event.relatedTarget;
75
+ if (!popover.current?.contains(relatedTarget)) {
75
76
  onRequestClose?.();
76
77
  }
77
78
  });
@@ -58,7 +58,7 @@ export declare namespace Toggletip {
58
58
  */
59
59
  align: PropTypes.Requireable<string>;
60
60
  /**
61
- * Provide an offset value for alignment axis.
61
+ * **Experimental:** Provide an offset value for alignment axis. Only takes effect when `autoalign` is enabled.
62
62
  */
63
63
  alignmentAxisOffset: PropTypes.Requireable<number>;
64
64
  /**
@@ -186,7 +186,7 @@ Toggletip.propTypes = {
186
186
  // new values to match floating-ui
187
187
  'top-start', 'top-end', 'bottom-start', 'bottom-end', 'left-end', 'left-start', 'right-end', 'right-start']),
188
188
  /**
189
- * Provide an offset value for alignment axis.
189
+ * **Experimental:** Provide an offset value for alignment axis. Only takes effect when `autoalign` is enabled.
190
190
  */
191
191
  alignmentAxisOffset: PropTypes__default["default"].number,
192
192
  /**
@@ -4,6 +4,6 @@
4
4
  * This source code is licensed under the Apache-2.0 license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- import { type MutableRefObject } from 'react';
8
- export declare const useEvent: <E extends keyof GlobalEventHandlersEventMap>(elementOrRef: HTMLElement | MutableRefObject<HTMLElement | null>, eventName: E, callback: (event: GlobalEventHandlersEventMap[E]) => void) => void;
7
+ import { RefObject } from 'react';
8
+ export declare const useEvent: <E extends keyof GlobalEventHandlersEventMap>(elementOrRef: HTMLElement | RefObject<Element | null>, eventName: E, callback: (event: GlobalEventHandlersEventMap[E]) => void) => void;
9
9
  export declare const useWindowEvent: <E extends keyof WindowEventMap>(eventName: E, callback: (event: WindowEventMap[E]) => void) => void;
@@ -17,15 +17,16 @@ const useEvent = (elementOrRef, eventName, callback) => {
17
17
  savedCallback.current = callback;
18
18
  }, [callback]);
19
19
  React.useEffect(() => {
20
+ const element = 'current' in elementOrRef ? elementOrRef.current : elementOrRef;
21
+ if (!element) return;
20
22
  const handler = event => {
21
23
  if (savedCallback.current) {
22
24
  savedCallback.current(event);
23
25
  }
24
26
  };
25
- const element = 'current' in elementOrRef ? elementOrRef.current : elementOrRef;
26
- element?.addEventListener(eventName, handler);
27
+ element.addEventListener(eventName, handler);
27
28
  return () => {
28
- element?.removeEventListener(eventName, handler);
29
+ element.removeEventListener(eventName, handler);
29
30
  };
30
31
  }, [elementOrRef, eventName]);
31
32
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@carbon/react",
3
3
  "description": "React components for the Carbon Design System",
4
- "version": "1.86.0",
4
+ "version": "1.87.0-rc.0",
5
5
  "license": "Apache-2.0",
6
6
  "main": "lib/index.js",
7
7
  "types": "lib/index.d.ts",
@@ -52,10 +52,10 @@
52
52
  },
53
53
  "dependencies": {
54
54
  "@babel/runtime": "^7.27.3",
55
- "@carbon/feature-flags": "^0.27.0",
55
+ "@carbon/feature-flags": "^0.28.0-rc.0",
56
56
  "@carbon/icons-react": "^11.62.0",
57
57
  "@carbon/layout": "^11.36.0",
58
- "@carbon/styles": "^1.85.0",
58
+ "@carbon/styles": "^1.86.0-rc.0",
59
59
  "@carbon/utilities": "^0.7.0",
60
60
  "@floating-ui/react": "^0.27.4",
61
61
  "@ibm/telemetry-js": "^1.5.0",
@@ -94,7 +94,7 @@
94
94
  "@types/react-is": "^19.0.0",
95
95
  "@types/use-sync-external-store": "^1",
96
96
  "autoprefixer": "^10.4.0",
97
- "babel-loader": "^9.0.0",
97
+ "babel-loader": "^10.0.0",
98
98
  "babel-plugin-dev-expression": "^0.2.3",
99
99
  "babel-preset-carbon": "^0.7.0",
100
100
  "browserify-zlib": "^0.2.0",
@@ -139,5 +139,5 @@
139
139
  "**/*.scss",
140
140
  "**/*.css"
141
141
  ],
142
- "gitHead": "62119bab35028f3935a28e7bb09d2c234f061302"
142
+ "gitHead": "ae3d208825a90cb5c4ee316fabaa3282679a0b59"
143
143
  }
package/telemetry.yml CHANGED
@@ -95,6 +95,7 @@ collect:
95
95
  - inline
96
96
  - innerRef
97
97
  - inputMode
98
+ - inputProps
98
99
  - invalid
99
100
  - invalidText
100
101
  - isActive