@carbon/react 1.91.0 → 1.92.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 (161) hide show
  1. package/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +951 -976
  2. package/es/components/Accordion/AccordionItem.d.ts +12 -1
  3. package/es/components/Accordion/AccordionItem.js +9 -2
  4. package/es/components/Breadcrumb/BreadcrumbItem.js +1 -1
  5. package/es/components/Checkbox/Checkbox.js +2 -2
  6. package/es/components/ComboBox/ComboBox.js +39 -23
  7. package/es/components/ComboButton/index.js +1 -1
  8. package/es/components/ComposedModal/ComposedModal.js +66 -17
  9. package/es/components/ComposedModal/ComposedModalPresence.d.ts +34 -0
  10. package/es/components/ComposedModal/ComposedModalPresence.js +42 -0
  11. package/es/components/ComposedModal/index.d.ts +1 -0
  12. package/es/components/ComposedModal/useComposedModalState.d.ts +7 -0
  13. package/es/components/ComposedModal/useComposedModalState.js +24 -0
  14. package/es/components/DataTable/TableBatchActions.js +2 -2
  15. package/es/components/DatePickerInput/DatePickerInput.js +2 -2
  16. package/es/components/Dialog/Dialog.js +2 -2
  17. package/es/components/Dropdown/Dropdown.js +5 -5
  18. package/es/components/ExpandableSearch/ExpandableSearch.d.ts +1 -1
  19. package/es/components/ExpandableSearch/ExpandableSearch.js +1 -1
  20. package/es/components/FeatureFlags/index.d.ts +2 -1
  21. package/es/components/FeatureFlags/index.js +3 -1
  22. package/es/components/FileUploader/FileUploader.js +2 -2
  23. package/es/components/FileUploader/FileUploaderItem.js +2 -2
  24. package/es/components/FluidTextInput/FluidPasswordInput.js +24 -5
  25. package/es/components/FluidTextInput/index.js +1 -1
  26. package/es/components/FormLabel/FormLabel.js +1 -1
  27. package/es/components/ListBox/ListBox.d.ts +1 -1
  28. package/es/components/ListBox/ListBox.js +1 -2
  29. package/es/components/ListItem/ListItem.js +1 -1
  30. package/es/components/Menu/MenuItem.js +2 -2
  31. package/es/components/MenuButton/index.d.ts +1 -1
  32. package/es/components/MenuButton/index.js +1 -1
  33. package/es/components/Modal/Modal.js +60 -10
  34. package/es/components/Modal/ModalPresence.d.ts +32 -0
  35. package/es/components/Modal/ModalPresence.js +37 -0
  36. package/es/components/Modal/index.d.ts +2 -1
  37. package/es/components/Modal/index.js +1 -0
  38. package/es/components/MultiSelect/FilterableMultiSelect.js +3 -3
  39. package/es/components/MultiSelect/MultiSelect.js +6 -5
  40. package/es/components/Notification/Notification.js +2 -2
  41. package/es/components/NumberInput/NumberInput.d.ts +21 -11
  42. package/es/components/NumberInput/NumberInput.js +40 -26
  43. package/es/components/OverflowMenu/OverflowMenu.js +2 -3
  44. package/es/components/OverflowMenu/next/index.js +1 -1
  45. package/es/components/OverflowMenuItem/OverflowMenuItem.js +1 -1
  46. package/es/components/PageHeader/PageHeader.js +2 -2
  47. package/es/components/ProgressIndicator/ProgressIndicator.js +1 -1
  48. package/es/components/RadioButton/RadioButton.js +3 -3
  49. package/es/components/RadioButtonGroup/RadioButtonGroup.js +2 -2
  50. package/es/components/RadioTile/RadioTile.js +2 -2
  51. package/es/components/Select/Select.js +2 -2
  52. package/es/components/Slider/Slider.js +2 -2
  53. package/es/components/StructuredList/StructuredList.js +2 -2
  54. package/es/components/Tabs/Tabs.js +2 -2
  55. package/es/components/Tag/DismissibleTag.js +3 -3
  56. package/es/components/Tag/OperationalTag.js +3 -3
  57. package/es/components/Tag/SelectableTag.js +3 -3
  58. package/es/components/Tag/Tag.js +2 -2
  59. package/es/components/Text/Text.d.ts +1 -1
  60. package/es/components/Text/Text.js +0 -1
  61. package/es/components/Text/TextDirection.d.ts +1 -1
  62. package/es/components/Text/TextDirection.js +0 -1
  63. package/es/components/Text/createTextComponent.d.ts +2 -8
  64. package/es/components/Text/createTextComponent.js +2 -2
  65. package/es/components/Text/index.d.ts +0 -8
  66. package/es/components/TextArea/TextArea.js +2 -2
  67. package/es/components/TextInput/TextInput.js +2 -2
  68. package/es/components/Tile/Tile.js +2 -2
  69. package/es/components/Toggle/Toggle.js +2 -2
  70. package/es/components/UIShell/Switcher.js +0 -26
  71. package/es/index.d.ts +1 -1
  72. package/es/index.js +6 -4
  73. package/es/internal/useNormalizedInputProps.js +2 -2
  74. package/es/internal/usePresence.d.ts +17 -0
  75. package/es/internal/usePresence.js +66 -0
  76. package/es/internal/usePresenceContext.d.ts +25 -0
  77. package/es/internal/usePresenceContext.js +46 -0
  78. package/es/tools/mergeRefs.d.ts +5 -5
  79. package/es/tools/mergeRefs.js +16 -12
  80. package/lib/components/Accordion/AccordionItem.d.ts +12 -1
  81. package/lib/components/Accordion/AccordionItem.js +9 -2
  82. package/lib/components/Breadcrumb/BreadcrumbItem.js +1 -1
  83. package/lib/components/Checkbox/Checkbox.js +2 -2
  84. package/lib/components/ComboBox/ComboBox.js +39 -23
  85. package/lib/components/ComboButton/index.js +1 -1
  86. package/lib/components/ComposedModal/ComposedModal.js +65 -16
  87. package/lib/components/ComposedModal/ComposedModalPresence.d.ts +34 -0
  88. package/lib/components/ComposedModal/ComposedModalPresence.js +46 -0
  89. package/lib/components/ComposedModal/index.d.ts +1 -0
  90. package/lib/components/ComposedModal/useComposedModalState.d.ts +7 -0
  91. package/lib/components/ComposedModal/useComposedModalState.js +26 -0
  92. package/lib/components/DataTable/TableBatchActions.js +2 -2
  93. package/lib/components/DatePickerInput/DatePickerInput.js +2 -2
  94. package/lib/components/Dialog/Dialog.js +2 -2
  95. package/lib/components/Dropdown/Dropdown.js +3 -3
  96. package/lib/components/ExpandableSearch/ExpandableSearch.d.ts +1 -1
  97. package/lib/components/ExpandableSearch/ExpandableSearch.js +1 -1
  98. package/lib/components/FeatureFlags/index.d.ts +2 -1
  99. package/lib/components/FeatureFlags/index.js +3 -1
  100. package/lib/components/FileUploader/FileUploader.js +2 -2
  101. package/lib/components/FileUploader/FileUploaderItem.js +2 -2
  102. package/lib/components/FluidTextInput/FluidPasswordInput.js +26 -5
  103. package/lib/components/FluidTextInput/index.js +2 -1
  104. package/lib/components/FormLabel/FormLabel.js +1 -1
  105. package/lib/components/ListBox/ListBox.d.ts +1 -1
  106. package/lib/components/ListBox/ListBox.js +1 -2
  107. package/lib/components/ListItem/ListItem.js +1 -1
  108. package/lib/components/Menu/MenuItem.js +2 -2
  109. package/lib/components/MenuButton/index.d.ts +1 -1
  110. package/lib/components/MenuButton/index.js +1 -1
  111. package/lib/components/Modal/Modal.js +59 -9
  112. package/lib/components/Modal/ModalPresence.d.ts +32 -0
  113. package/lib/components/Modal/ModalPresence.js +41 -0
  114. package/lib/components/Modal/index.d.ts +2 -1
  115. package/lib/components/Modal/index.js +1 -0
  116. package/lib/components/MultiSelect/FilterableMultiSelect.js +3 -3
  117. package/lib/components/MultiSelect/MultiSelect.js +4 -3
  118. package/lib/components/Notification/Notification.js +2 -2
  119. package/lib/components/NumberInput/NumberInput.d.ts +21 -11
  120. package/lib/components/NumberInput/NumberInput.js +40 -26
  121. package/lib/components/OverflowMenu/OverflowMenu.js +2 -3
  122. package/lib/components/OverflowMenu/next/index.js +1 -1
  123. package/lib/components/OverflowMenuItem/OverflowMenuItem.js +1 -1
  124. package/lib/components/PageHeader/PageHeader.js +2 -2
  125. package/lib/components/ProgressIndicator/ProgressIndicator.js +1 -1
  126. package/lib/components/RadioButton/RadioButton.js +3 -3
  127. package/lib/components/RadioButtonGroup/RadioButtonGroup.js +3 -3
  128. package/lib/components/RadioTile/RadioTile.js +2 -2
  129. package/lib/components/Select/Select.js +2 -2
  130. package/lib/components/Slider/Slider.js +2 -2
  131. package/lib/components/StructuredList/StructuredList.js +2 -2
  132. package/lib/components/Tabs/Tabs.js +2 -2
  133. package/lib/components/Tag/DismissibleTag.js +3 -3
  134. package/lib/components/Tag/OperationalTag.js +3 -3
  135. package/lib/components/Tag/SelectableTag.js +3 -3
  136. package/lib/components/Tag/Tag.js +2 -2
  137. package/lib/components/Text/Text.d.ts +1 -1
  138. package/lib/components/Text/Text.js +0 -1
  139. package/lib/components/Text/TextDirection.d.ts +1 -1
  140. package/lib/components/Text/TextDirection.js +0 -1
  141. package/lib/components/Text/createTextComponent.d.ts +2 -8
  142. package/lib/components/Text/createTextComponent.js +2 -2
  143. package/lib/components/Text/index.d.ts +0 -8
  144. package/lib/components/TextArea/TextArea.js +2 -2
  145. package/lib/components/TextInput/TextInput.js +2 -2
  146. package/lib/components/Tile/Tile.js +2 -2
  147. package/lib/components/Toggle/Toggle.js +2 -2
  148. package/lib/components/UIShell/Switcher.js +0 -26
  149. package/lib/index.d.ts +1 -1
  150. package/lib/index.js +13 -8
  151. package/lib/internal/useNormalizedInputProps.js +2 -2
  152. package/lib/internal/usePresence.d.ts +17 -0
  153. package/lib/internal/usePresence.js +68 -0
  154. package/lib/internal/usePresenceContext.d.ts +25 -0
  155. package/lib/internal/usePresenceContext.js +48 -0
  156. package/lib/tools/mergeRefs.d.ts +5 -5
  157. package/lib/tools/mergeRefs.js +16 -14
  158. package/package.json +7 -7
  159. package/telemetry.yml +4 -0
  160. package/es/components/Text/index.js +0 -16
  161. package/lib/components/Text/index.js +0 -20
package/es/index.js CHANGED
@@ -26,6 +26,7 @@ export { default as CodeSnippetSkeleton } from './components/CodeSnippet/CodeSni
26
26
  export { default as ComboBox } from './components/ComboBox/ComboBox.js';
27
27
  export { ComboButton } from './components/ComboButton/index.js';
28
28
  export { default as ComposedModal, ModalBody } from './components/ComposedModal/ComposedModal.js';
29
+ export { ComposedModalPresence } from './components/ComposedModal/ComposedModalPresence.js';
29
30
  export { ModalHeader } from './components/ComposedModal/ModalHeader.js';
30
31
  export { ModalFooter } from './components/ComposedModal/ModalFooter.js';
31
32
  import './components/ContainedList/index.js';
@@ -95,6 +96,7 @@ export { Menu } from './components/Menu/Menu.js';
95
96
  export { MenuItem, MenuItemDivider, MenuItemGroup, MenuItemRadioGroup, MenuItemSelectable } from './components/Menu/MenuItem.js';
96
97
  export { MenuButton } from './components/MenuButton/index.js';
97
98
  export { default as Modal } from './components/Modal/Modal.js';
99
+ export { ModalPresence } from './components/Modal/ModalPresence.js';
98
100
  export { default as ModalWrapper } from './components/ModalWrapper/ModalWrapper.js';
99
101
  export { FilterableMultiSelect } from './components/MultiSelect/FilterableMultiSelect.js';
100
102
  export { MultiSelect } from './components/MultiSelect/MultiSelect.js';
@@ -208,7 +210,7 @@ export { default as FluidSearchSkeleton, default as preview__FluidSearchSkeleton
208
210
  export { default as FluidTextArea, default as preview__FluidTextArea, default as unstable__FluidTextArea } from './components/FluidTextArea/FluidTextArea.js';
209
211
  export { default as FluidTextAreaSkeleton, default as preview__FluidTextAreaSkeleton, default as unstable__FluidTextAreaSkeleton } from './components/FluidTextArea/FluidTextArea.Skeleton.js';
210
212
  export { default as FluidTextInput, default as preview__FluidTextInput, default as unstable__FluidTextInput } from './components/FluidTextInput/FluidTextInput.js';
211
- import './components/FluidTextInput/FluidPasswordInput.js';
213
+ export { default as FluidPasswordInput } from './components/FluidTextInput/FluidPasswordInput.js';
212
214
  export { default as FluidTextInputSkeleton, default as preview__FluidTextInputSkeleton, default as unstable__FluidTextInputSkeleton } from './components/FluidTextInput/FluidTextInput.Skeleton.js';
213
215
  export { default as FluidNumberInput, default as preview__FluidNumberInput, default as unstable__FluidNumberInput } from './components/FluidNumberInput/FluidNumberInput.js';
214
216
  export { default as FluidNumberInputSkeleton, default as preview__FluidNumberInputSkeleton, default as unstable__FluidNumberInputSkeleton } from './components/FluidNumberInput/FluidNumberInput.Skeleton.js';
@@ -234,7 +236,9 @@ export { default as AISkeletonIcon, default as preview__AiSkeletonIcon, default
234
236
  export { default as AISkeletonText, default as preview__AiSkeletonText, default as unstable__AiSkeletonText } from './components/AISkeleton/AISkeletonText.js';
235
237
  export { DefinitionTooltip } from './components/Tooltip/DefinitionTooltip.js';
236
238
  export { Tooltip } from './components/Tooltip/Tooltip.js';
237
- import './components/Text/index.js';
239
+ export { Text as preview_Text, Text as unstable_Text } from './components/Text/Text.js';
240
+ export { TextDirection as preview_TextDirection, TextDirection as unstable_TextDirection } from './components/Text/TextDirection.js';
241
+ import 'react';
238
242
  export { GlobalTheme, Theme, ThemeContext, usePrefersDarkScheme, useTheme } from './components/Theme/index.js';
239
243
  export { PrefixContext, usePrefix } from './internal/usePrefix.js';
240
244
  export { useIdPrefix } from './internal/useIdPrefix.js';
@@ -242,5 +246,3 @@ export { default as preview_PageSelector, default as unstable_PageSelector } fro
242
246
  export { default as preview_Pagination, default as unstable_Pagination } from './components/Pagination/experimental/Pagination.js';
243
247
  export { default as ContainedListItem } from './components/ContainedList/ContainedListItem/ContainedListItem.js';
244
248
  export { default as ContainedList } from './components/ContainedList/ContainedList.js';
245
- export { Text as preview_Text, Text as unstable_Text } from './components/Text/Text.js';
246
- export { TextDirection as preview_TextDirection, TextDirection as unstable_TextDirection } from './components/Text/TextDirection.js';
@@ -7,9 +7,9 @@
7
7
 
8
8
  import React from 'react';
9
9
  import { WarningFilled, WarningAltFilled } from '@carbon/icons-react';
10
- import '../components/Text/index.js';
11
- import { usePrefix } from './usePrefix.js';
12
10
  import { Text } from '../components/Text/Text.js';
11
+ import '../components/Text/TextDirection.js';
12
+ import { usePrefix } from './usePrefix.js';
13
13
 
14
14
  /**
15
15
  * Returns an object containing normalized properties for an input component.
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Copyright IBM Corp. 2025
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ import { type RefObject } from 'react';
8
+ export declare const usePresence: (ref: RefObject<HTMLElement | null>, isOpen: boolean) => {
9
+ /**
10
+ * Indicates whether the ref object is supposed to be mounted
11
+ */
12
+ isPresent: boolean;
13
+ /**
14
+ * Indicates whether the ref object is currently exiting
15
+ */
16
+ isExiting: boolean;
17
+ };
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Copyright IBM Corp. 2016, 2023
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ import { useState, useCallback, useLayoutEffect } from 'react';
9
+ import { usePrefix } from './usePrefix.js';
10
+
11
+ const usePresence = (ref, isOpen) => {
12
+ const prefix = usePrefix();
13
+ const [exitState, setExitState] = useState(isOpen ? 'idle' : 'finished');
14
+ const isExiting = exitState === 'active';
15
+
16
+ // element is exiting
17
+ if (!isOpen && exitState === 'idle') {
18
+ setExitState('active');
19
+ }
20
+
21
+ // element exit was interrupted
22
+ if (isOpen && exitState !== 'idle') {
23
+ setExitState('idle');
24
+ }
25
+ const handleAnimationEnd = useCallback(() => {
26
+ setExitState('finished');
27
+ }, []);
28
+ useLayoutEffect(() => {
29
+ if (!ref.current || !isExiting) return;
30
+
31
+ // resolve for JSDOM
32
+ if (!('getAnimations' in ref.current)) {
33
+ handleAnimationEnd();
34
+ return;
35
+ }
36
+
37
+ // cover all animations that start with the presence prefix
38
+ const animations = ref.current.getAnimations({
39
+ subtree: true
40
+ }).filter(animation => animation instanceof CSSAnimation && animation.animationName.startsWith(`${prefix}--presence`));
41
+ if (!animations.length) {
42
+ handleAnimationEnd();
43
+ return;
44
+ }
45
+ let cancelled = false;
46
+ Promise.all(animations.map(animation => animation.finished)).finally(() => {
47
+ if (cancelled) return;
48
+ handleAnimationEnd();
49
+ });
50
+ return () => {
51
+ cancelled = true;
52
+ };
53
+ }, [ref, isExiting, prefix, handleAnimationEnd]);
54
+ return {
55
+ /**
56
+ * Indicates whether the ref object is supposed to be mounted
57
+ */
58
+ isPresent: isOpen || exitState !== 'finished',
59
+ /**
60
+ * Indicates whether the ref object is currently exiting
61
+ */
62
+ isExiting
63
+ };
64
+ };
65
+
66
+ export { usePresence };
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Copyright IBM Corp. 2025
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ import { type RefObject } from 'react';
8
+ export interface PresenceContext {
9
+ /**
10
+ * The ref object the presence mode is mounted with
11
+ */
12
+ presenceRef: RefObject<HTMLDivElement | null>;
13
+ /**
14
+ * Indicates whether the ref object is currently exiting
15
+ */
16
+ isExiting: boolean;
17
+ /**
18
+ * Returns if the caller is exclusive to this presence context
19
+ */
20
+ isPresenceExclusive: (id: string) => boolean;
21
+ }
22
+ /**
23
+ * Returns if the presence node is present and the context value to be used by a presence context, e.g. ModalPresence.
24
+ */
25
+ export declare const usePresenceContext: (open: boolean, initialPresenceId?: string) => readonly [boolean, PresenceContext];
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Copyright IBM Corp. 2016, 2023
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ import { useRef, useCallback, useMemo } from 'react';
9
+ import { usePresence } from './usePresence.js';
10
+
11
+ /**
12
+ * Returns if the presence node is present and the context value to be used by a presence context, e.g. ModalPresence.
13
+ */
14
+ const usePresenceContext = (open, initialPresenceId) => {
15
+ const presenceIdRef = useRef(initialPresenceId);
16
+ const presenceRef = useRef(null);
17
+ const prevPresenceRef = useRef(null);
18
+
19
+ // clean up the presence id, if not predefined and if the presence node was unmounted
20
+ if (!initialPresenceId && prevPresenceRef.current && !presenceRef.current) {
21
+ presenceIdRef.current = null;
22
+ }
23
+ prevPresenceRef.current = presenceRef.current;
24
+ const {
25
+ isPresent,
26
+ isExiting
27
+ } = usePresence(presenceRef, open);
28
+ const isPresenceExclusive = useCallback(id => {
29
+ if (!id) return false;
30
+
31
+ // return false if the presence context is occupied
32
+ if (presenceIdRef.current && presenceIdRef.current !== id) return false;
33
+
34
+ // otherwise occupy presence context and return true
35
+ presenceIdRef.current = id;
36
+ return true;
37
+ }, []);
38
+ const contextValue = useMemo(() => ({
39
+ presenceRef,
40
+ isPresenceExclusive,
41
+ isExiting
42
+ }), [presenceRef, isPresenceExclusive, isExiting]);
43
+ return [isPresent, contextValue];
44
+ };
45
+
46
+ export { usePresenceContext };
@@ -1,12 +1,12 @@
1
- export default mergeRefs;
2
1
  /**
3
- * Copyright IBM Corp. 2016, 2023
2
+ * Copyright IBM Corp. 2016, 2025
4
3
  *
5
4
  * This source code is licensed under the Apache-2.0 license found in the
6
5
  * LICENSE file in the root directory of this source tree.
7
6
  */
7
+ import type { Ref, RefCallback } from 'react';
8
8
  /**
9
- * @param {...Ref<Element>} refs List of React refs to merge.
10
- * @returns {Ref<Element>} Merged React ref.
9
+ * @param refs Refs to merge.
10
+ * @returns Merged ref.
11
11
  */
12
- declare function mergeRefs(...refs: Ref<Element>[]): Ref<Element>;
12
+ export declare const mergeRefs: <T>(...refs: (Ref<T> | null | undefined)[]) => RefCallback<T>;
@@ -6,18 +6,22 @@
6
6
  */
7
7
 
8
8
  /**
9
- * @param {...Ref<Element>} refs List of React refs to merge.
10
- * @returns {Ref<Element>} Merged React ref.
9
+ * @param refs Refs to merge.
10
+ * @returns Merged ref.
11
11
  */
12
- const mergeRefs = (...refs) => el => {
13
- refs.forEach(ref => {
14
- // https://github.com/facebook/react/issues/13029#issuecomment-410002316
15
- if (typeof ref === 'function') {
16
- ref(el);
17
- } else if (Object(ref) === ref) {
18
- ref.current = el;
19
- }
20
- });
12
+ const mergeRefs = (...refs) => {
13
+ return value => {
14
+ refs.forEach(ref => {
15
+ if (!ref) return;
16
+
17
+ // https://github.com/facebook/react/issues/13029#issuecomment-410002316
18
+ if (typeof ref === 'function') {
19
+ ref(value);
20
+ } else if (typeof ref === 'object' && 'current' in ref) {
21
+ ref.current = value;
22
+ }
23
+ });
24
+ };
21
25
  };
22
26
 
23
- export { mergeRefs as default };
27
+ export { mergeRefs };
@@ -12,6 +12,11 @@ export interface AccordionItemProps {
12
12
  * this value will be managed by the parent Accordion.
13
13
  */
14
14
  disabled?: boolean;
15
+ /**
16
+ * Specify a custom label for the accordion button.
17
+ * This is important for accessibility when the accordion has no visible title.
18
+ */
19
+ 'aria-label'?: AriaAttributes['aria-label'];
15
20
  /**
16
21
  * The handler of the massaged `click` event.
17
22
  */
@@ -52,6 +57,7 @@ export interface AccordionItemProps {
52
57
  export interface AccordionToggleProps {
53
58
  'aria-controls'?: AriaAttributes['aria-controls'];
54
59
  'aria-expanded'?: AriaAttributes['aria-expanded'];
60
+ 'aria-label'?: AriaAttributes['aria-label'];
55
61
  className?: string;
56
62
  disabled?: boolean;
57
63
  onClick?: MouseEventHandler<HTMLButtonElement>;
@@ -59,7 +65,7 @@ export interface AccordionToggleProps {
59
65
  type?: 'button';
60
66
  }
61
67
  declare function AccordionItem({ children, className: customClassName, open, onHeadingClick, renderExpando, // remove renderExpando in next major release
62
- renderToggle, title, disabled: controlledDisabled, handleAnimationEnd, ...rest }: PropsWithChildren<AccordionItemProps>): import("react/jsx-runtime").JSX.Element;
68
+ renderToggle, title, disabled: controlledDisabled, handleAnimationEnd, 'aria-label': ariaLabel, ...rest }: PropsWithChildren<AccordionItemProps>): import("react/jsx-runtime").JSX.Element;
63
69
  declare namespace AccordionItem {
64
70
  var propTypes: {
65
71
  /**
@@ -74,6 +80,11 @@ declare namespace AccordionItem {
74
80
  * Specify whether an individual AccordionItem should be disabled
75
81
  */
76
82
  disabled: PropTypes.Requireable<boolean>;
83
+ /**
84
+ * Specify a custom label for the accordion button.
85
+ * This is important for accessibility when the accordion has no visible title.
86
+ */
87
+ 'aria-label': PropTypes.Requireable<string>;
77
88
  /**
78
89
  * The handler of the massaged `click` event.
79
90
  */
@@ -14,14 +14,14 @@ var iconsReact = require('@carbon/icons-react');
14
14
  var cx = require('classnames');
15
15
  var PropTypes = require('prop-types');
16
16
  var React = require('react');
17
- require('../Text/index.js');
17
+ var Text = require('../Text/Text.js');
18
+ require('../Text/TextDirection.js');
18
19
  var keys = require('../../internal/keyboard/keys.js');
19
20
  var match = require('../../internal/keyboard/match.js');
20
21
  var useId = require('../../internal/useId.js');
21
22
  var deprecate = require('../../prop-types/deprecate.js');
22
23
  var usePrefix = require('../../internal/usePrefix.js');
23
24
  var AccordionProvider = require('./AccordionProvider.js');
24
- var Text = require('../Text/Text.js');
25
25
 
26
26
  const defaultRenderToggle = props => /*#__PURE__*/React.createElement("button", _rollupPluginBabelHelpers.extends({
27
27
  type: "button"
@@ -37,6 +37,7 @@ function AccordionItem({
37
37
  title = 'title',
38
38
  disabled: controlledDisabled,
39
39
  handleAnimationEnd,
40
+ 'aria-label': ariaLabel,
40
41
  ...rest
41
42
  }) {
42
43
  const [isOpen, setIsOpen] = React.useState(open);
@@ -100,6 +101,7 @@ function AccordionItem({
100
101
  disabled: disabled,
101
102
  "aria-controls": id,
102
103
  "aria-expanded": isOpen,
104
+ "aria-label": ariaLabel,
103
105
  className: `${prefix}--accordion__heading`,
104
106
  onClick: onClick,
105
107
  onKeyDown: onKeyDown,
@@ -131,6 +133,11 @@ AccordionItem.propTypes = {
131
133
  * Specify whether an individual AccordionItem should be disabled
132
134
  */
133
135
  disabled: PropTypes.bool,
136
+ /**
137
+ * Specify a custom label for the accordion button.
138
+ * This is important for accessibility when the accordion has no visible title.
139
+ */
140
+ 'aria-label': PropTypes.string,
134
141
  /**
135
142
  * The handler of the massaged `click` event.
136
143
  */
@@ -16,8 +16,8 @@ var cx = require('classnames');
16
16
  var Link = require('../Link/Link.js');
17
17
  var iconsReact = require('@carbon/icons-react');
18
18
  var usePrefix = require('../../internal/usePrefix.js');
19
- require('../Text/index.js');
20
19
  var Text = require('../Text/Text.js');
20
+ require('../Text/TextDirection.js');
21
21
 
22
22
  const frFn = React.forwardRef;
23
23
  const BreadcrumbItem = frFn((props, ref) => {
@@ -13,7 +13,8 @@ var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelper
13
13
  var PropTypes = require('prop-types');
14
14
  var React = require('react');
15
15
  var cx = require('classnames');
16
- require('../Text/index.js');
16
+ var Text = require('../Text/Text.js');
17
+ require('../Text/TextDirection.js');
17
18
  var deprecate = require('../../prop-types/deprecate.js');
18
19
  var usePrefix = require('../../internal/usePrefix.js');
19
20
  var iconsReact = require('@carbon/icons-react');
@@ -21,7 +22,6 @@ var useId = require('../../internal/useId.js');
21
22
  var noopFn = require('../../internal/noopFn.js');
22
23
  var index = require('../AILabel/index.js');
23
24
  var utils = require('../../internal/utils.js');
24
- var Text = require('../Text/Text.js');
25
25
 
26
26
  const Checkbox = /*#__PURE__*/React.forwardRef(({
27
27
  className,
@@ -14,7 +14,8 @@ var cx = require('classnames');
14
14
  var Downshift = require('downshift');
15
15
  var PropTypes = require('prop-types');
16
16
  var React = require('react');
17
- require('../Text/index.js');
17
+ var Text = require('../Text/Text.js');
18
+ require('../Text/TextDirection.js');
18
19
  var iconsReact = require('@carbon/icons-react');
19
20
  var isEqual = require('react-fast-compare');
20
21
  var index$2 = require('../ListBox/index.js');
@@ -34,7 +35,6 @@ var index$1 = require('../AILabel/index.js');
34
35
  var defaultItemToString = require('../../internal/defaultItemToString.js');
35
36
  var utils = require('../../internal/utils.js');
36
37
  var ListBoxPropTypes = require('../ListBox/ListBoxPropTypes.js');
37
- var Text = require('../Text/Text.js');
38
38
 
39
39
  const {
40
40
  InputBlur,
@@ -285,9 +285,13 @@ const ComboBox = /*#__PURE__*/React.forwardRef((props, ref) => {
285
285
  switch (type) {
286
286
  case InputBlur:
287
287
  {
288
- if (allowCustomValue && highlightedIndex == '-1') {
289
- const customValue = inputValue;
290
- changes.selectedItem = customValue;
288
+ // If custom values are allowed, treat whatever the user typed as
289
+ // the value.
290
+ if (allowCustomValue && highlightedIndex === -1) {
291
+ const {
292
+ inputValue
293
+ } = state;
294
+ changes.selectedItem = inputValue;
291
295
  if (onChange) {
292
296
  onChange({
293
297
  selectedItem: inputValue,
@@ -296,17 +300,28 @@ const ComboBox = /*#__PURE__*/React.forwardRef((props, ref) => {
296
300
  }
297
301
  return changes;
298
302
  }
299
- if (state.inputValue && highlightedIndex == '-1' && changes.selectedItem) {
303
+
304
+ // If a new item was selected, keep its label in the input.
305
+ if (state.inputValue && highlightedIndex === -1 && changes.selectedItem) {
300
306
  return {
301
307
  ...changes,
302
308
  inputValue: itemToString(changes.selectedItem)
303
309
  };
304
310
  }
305
- if (state.inputValue && highlightedIndex == '-1' && !allowCustomValue && !changes.selectedItem) {
306
- return {
307
- ...changes,
308
- inputValue: ''
309
- };
311
+
312
+ // If custom values are not allowed, normalize any non-matching
313
+ // text. If the input isn’t an exact item label, restore the
314
+ // selected label if there is one, or clear it.
315
+ if (!allowCustomValue) {
316
+ const currentInput = state.inputValue ?? '';
317
+ const hasExactMatch = !!currentInput && items.some(item => itemToString(item) === currentInput);
318
+ if (!hasExactMatch) {
319
+ const restoredInput = state.selectedItem !== null ? itemToString(state.selectedItem) : '';
320
+ return {
321
+ ...changes,
322
+ inputValue: restoredInput
323
+ };
324
+ }
310
325
  }
311
326
  return changes;
312
327
  }
@@ -359,16 +374,17 @@ const ComboBox = /*#__PURE__*/React.forwardRef((props, ref) => {
359
374
  };
360
375
  case FunctionToggleMenu:
361
376
  case ToggleButtonClick:
362
- if (!changes.isOpen && state.inputValue && highlightedIndex === -1 && !allowCustomValue) {
363
- return {
364
- ...changes,
365
- inputValue: '' // Clear the input
366
- };
367
- }
368
- if (changes.isOpen && !changes.selectedItem) {
369
- return {
370
- ...changes
371
- };
377
+ // When closing the menu, apply the same normalization as blur.
378
+ if (state.isOpen && !changes.isOpen && !allowCustomValue) {
379
+ const currentInput = state.inputValue ?? '';
380
+ const hasExactMatch = !!currentInput && items.some(item => itemToString(item) === currentInput);
381
+ if (!hasExactMatch) {
382
+ const restoredInput = state.selectedItem !== null ? itemToString(state.selectedItem) : '';
383
+ return {
384
+ ...changes,
385
+ inputValue: restoredInput
386
+ };
387
+ }
372
388
  }
373
389
  return changes;
374
390
  case MenuMouseLeave:
@@ -395,7 +411,7 @@ const ComboBox = /*#__PURE__*/React.forwardRef((props, ref) => {
395
411
  }
396
412
  },
397
413
  // eslint-disable-next-line react-hooks/exhaustive-deps
398
- [allowCustomValue, inputValue, onChange]);
414
+ [allowCustomValue, inputValue, itemToString, items, onChange]);
399
415
  const handleToggleClick = isOpen => event => {
400
416
  if (onToggleClick) {
401
417
  onToggleClick(event);
@@ -639,7 +655,7 @@ const ComboBox = /*#__PURE__*/React.forwardRef((props, ref) => {
639
655
  setInputValue(newValue);
640
656
  downshiftSetInputValue(newValue);
641
657
  },
642
- ref: mergeRefs.default(textInput, ref, inputRef),
658
+ ref: mergeRefs.mergeRefs(textInput, ref, inputRef),
643
659
  onKeyDown: event => {
644
660
  if (match.match(event, keys.Space)) {
645
661
  event.stopPropagation();
@@ -91,7 +91,7 @@ const ComboButton = /*#__PURE__*/React.forwardRef(function ComboButton({
91
91
  middleware: middlewares,
92
92
  whileElementsMounted: react.autoUpdate
93
93
  });
94
- const ref = mergeRefs.default(forwardRef, containerRef, refs.setReference);
94
+ const ref = mergeRefs.mergeRefs(forwardRef, containerRef, refs.setReference);
95
95
  const {
96
96
  open,
97
97
  handleClick: hookOnClick,