@carbon/react 1.61.0-rc.1 → 1.62.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.
@@ -11,7 +11,13 @@ import { breakpoints } from '@carbon/layout';
11
11
  import cx from 'classnames';
12
12
  import debounce from 'lodash.debounce';
13
13
  import PropTypes from 'prop-types';
14
- import React__default, { useState, useRef, useCallback, useEffect, forwardRef } from 'react';
14
+ import React__default, { useState, useRef, useCallback, useEffect, forwardRef, useLayoutEffect } from 'react';
15
+ import '../Grid/FlexGrid.js';
16
+ import { Grid as GridAsGridComponent } from '../Grid/Grid.js';
17
+ import '../Grid/Row.js';
18
+ import '../Grid/Column.js';
19
+ import '../Grid/ColumnHang.js';
20
+ import '../Grid/GridContext.js';
15
21
  import { isElement } from 'react-is';
16
22
  import '../Tooltip/DefinitionTooltip.js';
17
23
  import { Tooltip } from '../Tooltip/Tooltip.js';
@@ -29,9 +35,10 @@ import { useMatchMedia } from '../../internal/useMatchMedia.js';
29
35
  import '../Text/index.js';
30
36
  import { Text } from '../Text/Text.js';
31
37
  import { matches, match } from '../../internal/keyboard/match.js';
32
- import { ArrowRight, ArrowLeft, Home, End, Delete } from '../../internal/keyboard/keys.js';
38
+ import { ArrowRight, ArrowLeft, Home, End, ArrowDown, ArrowUp, Delete } from '../../internal/keyboard/keys.js';
33
39
 
34
40
  var _ChevronLeft, _ChevronRight;
41
+ const verticalTabHeight = 64;
35
42
 
36
43
  // Used to manage the overall state of the Tabs
37
44
 
@@ -52,6 +59,7 @@ const TabContext = /*#__PURE__*/React__default.createContext({
52
59
  hasSecondaryLabel: false
53
60
  });
54
61
  const lgMediaQuery = `(min-width: ${breakpoints.lg.width})`;
62
+ const smMediaQuery = `(max-width: ${breakpoints.md.width})`;
55
63
 
56
64
  // Used to keep track of position in a list of tab panels
57
65
  const TabPanelContext = /*#__PURE__*/React__default.createContext(0);
@@ -130,6 +138,72 @@ Tabs.propTypes = {
130
138
  */
131
139
  selectedIndex: PropTypes.number
132
140
  };
141
+ function TabsVertical(_ref2) {
142
+ let {
143
+ children,
144
+ height,
145
+ defaultSelectedIndex = 0,
146
+ onChange,
147
+ selectedIndex: controlledSelectedIndex,
148
+ ...rest
149
+ } = _ref2;
150
+ const [selectedIndex, setSelectedIndex] = useControllableState({
151
+ value: controlledSelectedIndex,
152
+ defaultValue: defaultSelectedIndex,
153
+ onChange: value => onChange?.({
154
+ selectedIndex: value
155
+ })
156
+ });
157
+ const props = {
158
+ ...rest,
159
+ selectedIndex,
160
+ onChange: _ref3 => {
161
+ let {
162
+ selectedIndex
163
+ } = _ref3;
164
+ return setSelectedIndex(selectedIndex);
165
+ }
166
+ };
167
+ const isSm = useMatchMedia(smMediaQuery);
168
+ if (!isSm) {
169
+ return (
170
+ /*#__PURE__*/
171
+ // eslint-disable-next-line react/forbid-component-props
172
+ React__default.createElement(GridAsGridComponent, {
173
+ style: {
174
+ height: height
175
+ }
176
+ }, /*#__PURE__*/React__default.createElement(Tabs, props, children))
177
+ );
178
+ }
179
+ return /*#__PURE__*/React__default.createElement(Tabs, props, children);
180
+ }
181
+ TabsVertical.propTypes = {
182
+ /**
183
+ * Provide child elements to be rendered inside the `TabsVertical`.
184
+ * These elements should render either `TabsListVertical` or `TabsPanels`
185
+ */
186
+ children: PropTypes.node,
187
+ /**
188
+ * Specify which content tab should be initially selected when the component
189
+ * is first rendered
190
+ */
191
+ defaultSelectedIndex: PropTypes.number,
192
+ /**
193
+ * Option to set a height style only if using vertical variation
194
+ */
195
+ height: PropTypes.string,
196
+ /**
197
+ * Provide an optional function which is called whenever the state of the
198
+ * `Tabs` changes
199
+ */
200
+ onChange: PropTypes.func,
201
+ /**
202
+ * Control which content panel is currently selected. This puts the component
203
+ * in a controlled mode and should be used along with `onChange`
204
+ */
205
+ selectedIndex: PropTypes.number
206
+ };
133
207
 
134
208
  /**
135
209
  * Get the next index for a given keyboard event
@@ -150,11 +224,30 @@ function getNextIndex(event, total, index) {
150
224
  }
151
225
  }
152
226
 
227
+ /**
228
+ * Get the next index for a given keyboard event
229
+ * given a count of the total items and the current index
230
+ */
231
+ function getNextIndexVertical(event, total, index) {
232
+ switch (true) {
233
+ case match(event, ArrowDown):
234
+ return (index + 1) % total;
235
+ case match(event, ArrowUp):
236
+ return (total + index - 1) % total;
237
+ case match(event, Home):
238
+ return 0;
239
+ case match(event, End):
240
+ return total - 1;
241
+ default:
242
+ return index;
243
+ }
244
+ }
245
+
153
246
  /**
154
247
  * TabList
155
248
  */
156
249
 
157
- function TabList(_ref2) {
250
+ function TabList(_ref4) {
158
251
  let {
159
252
  activation = 'automatic',
160
253
  'aria-label': label,
@@ -169,7 +262,7 @@ function TabList(_ref2) {
169
262
  scrollDebounceWait = 200,
170
263
  scrollIntoView,
171
264
  ...rest
172
- } = _ref2;
265
+ } = _ref4;
173
266
  const {
174
267
  activeIndex,
175
268
  selectedIndex,
@@ -326,10 +419,10 @@ function TabList(_ref2) {
326
419
  }
327
420
  }, [activation, activeIndex, selectedIndex, isScrollable, children]);
328
421
  usePressable(previousButton, {
329
- onPress(_ref3) {
422
+ onPress(_ref5) {
330
423
  let {
331
424
  longPress
332
- } = _ref3;
425
+ } = _ref5;
333
426
  if (!longPress && ref.current) {
334
427
  setScrollLeft(Math.max(scrollLeft - ref.current.scrollWidth / tabs.current.length * 1.5, 0));
335
428
  }
@@ -339,10 +432,10 @@ function TabList(_ref2) {
339
432
  }
340
433
  });
341
434
  usePressable(nextButton, {
342
- onPress(_ref4) {
435
+ onPress(_ref6) {
343
436
  let {
344
437
  longPress
345
- } = _ref4;
438
+ } = _ref6;
346
439
  if (!longPress && ref.current) {
347
440
  setScrollLeft(Math.min(scrollLeft + ref.current.scrollWidth / tabs.current.length * 1.5, ref.current.scrollWidth - ref.current.clientWidth));
348
441
  }
@@ -445,6 +538,153 @@ TabList.propTypes = {
445
538
  scrollIntoView: PropTypes.bool
446
539
  };
447
540
 
541
+ /**
542
+ * TabListVertical
543
+ */
544
+
545
+ // type TabElement = HTMLElement & { disabled?: boolean };
546
+
547
+ function TabListVertical(_ref7) {
548
+ let {
549
+ activation = 'automatic',
550
+ 'aria-label': label,
551
+ children,
552
+ className: customClassName,
553
+ scrollIntoView,
554
+ ...rest
555
+ } = _ref7;
556
+ const {
557
+ activeIndex,
558
+ selectedIndex,
559
+ setSelectedIndex,
560
+ setActiveIndex
561
+ } = React__default.useContext(TabsContext);
562
+ const prefix = usePrefix();
563
+ const ref = useRef(null);
564
+ const [isOverflowingBottom, setIsOverflowingBottom] = useState(false);
565
+ const [isOverflowingTop, setIsOverflowingTop] = useState(false);
566
+ const isSm = useMatchMedia(smMediaQuery);
567
+ const className = cx(`${prefix}--tabs`, `${prefix}--tabs--vertical`, `${prefix}--tabs--contained`, customClassName);
568
+ const tabs = useRef([]);
569
+ function onKeyDown(event) {
570
+ if (matches(event, [ArrowDown, ArrowUp, Home, End])) {
571
+ event.preventDefault();
572
+ const filtredTabs = tabs.current.filter(tab => tab !== null);
573
+ const activeTabs = filtredTabs.filter(tab => !tab.disabled);
574
+ const currentIndex = activeTabs.indexOf(tabs.current[activation === 'automatic' ? selectedIndex : activeIndex]);
575
+ const nextIndex = tabs.current.indexOf(activeTabs[getNextIndexVertical(event, activeTabs.length, currentIndex)]);
576
+ if (activation === 'automatic') {
577
+ setSelectedIndex(nextIndex);
578
+ } else if (activation === 'manual') {
579
+ setActiveIndex(nextIndex);
580
+ }
581
+ tabs.current[nextIndex]?.focus();
582
+ }
583
+ }
584
+ useEffectOnce(() => {
585
+ if (tabs.current[selectedIndex]?.disabled) {
586
+ const activeTabs = tabs.current.filter(tab => {
587
+ return !tab.disabled;
588
+ });
589
+ if (activeTabs.length > 0) {
590
+ const tab = activeTabs[0];
591
+ setSelectedIndex(tabs.current.indexOf(tab));
592
+ }
593
+ }
594
+ });
595
+ useEffect(() => {
596
+ function handler() {
597
+ const containerHeight = ref.current?.offsetHeight;
598
+ const containerTop = ref.current?.getBoundingClientRect().top;
599
+ const selectedPositionTop = tabs.current[selectedIndex]?.getBoundingClientRect().top;
600
+ const halfTabHeight = verticalTabHeight / 2;
601
+ if (containerTop && containerHeight) {
602
+ // scrolls so selected tab is in view
603
+ if (selectedPositionTop - halfTabHeight < containerTop || selectedPositionTop - containerTop + verticalTabHeight + halfTabHeight > containerHeight) {
604
+ ref.current.scrollTo({
605
+ top: (selectedIndex - 1) * verticalTabHeight,
606
+ behavior: 'smooth'
607
+ });
608
+ }
609
+ }
610
+ }
611
+ window.addEventListener('resize', handler);
612
+ handler();
613
+ return () => {
614
+ window.removeEventListener('resize', handler);
615
+ };
616
+ }, [selectedIndex, scrollIntoView]);
617
+ useEffect(() => {
618
+ const element = ref.current;
619
+ if (!element) {
620
+ return;
621
+ }
622
+ const handler = () => {
623
+ const halfTabHeight = verticalTabHeight / 2;
624
+ setIsOverflowingBottom(element.scrollTop + element.clientHeight + halfTabHeight <= element.scrollHeight);
625
+ setIsOverflowingTop(element.scrollTop > halfTabHeight);
626
+ };
627
+ const resizeObserver = new ResizeObserver(() => handler());
628
+ resizeObserver.observe(element);
629
+ element.addEventListener('scroll', handler);
630
+ return () => {
631
+ resizeObserver.disconnect();
632
+ element.removeEventListener('scroll', handler);
633
+ };
634
+ });
635
+ if (isSm) {
636
+ return /*#__PURE__*/React__default.createElement(TabList, _extends({}, rest, {
637
+ "aria-label": label,
638
+ contained: true
639
+ }), children);
640
+ }
641
+ return /*#__PURE__*/React__default.createElement("div", {
642
+ className: className
643
+ }, isOverflowingTop && /*#__PURE__*/React__default.createElement("div", {
644
+ className: `${prefix}--tab--list-gradient_top`
645
+ }), /*#__PURE__*/React__default.createElement("div", _extends({}, rest, {
646
+ "aria-label": label,
647
+ ref: ref,
648
+ role: "tablist",
649
+ className: `${prefix}--tab--list`,
650
+ onKeyDown: onKeyDown
651
+ }), React__default.Children.map(children, (child, index) => {
652
+ return !isElement(child) ? null : /*#__PURE__*/React__default.createElement(TabContext.Provider, {
653
+ value: {
654
+ index,
655
+ hasSecondaryLabel: false
656
+ }
657
+ }, /*#__PURE__*/React__default.cloneElement(child, {
658
+ ref: node => {
659
+ tabs.current[index] = node;
660
+ }
661
+ }));
662
+ })), isOverflowingBottom && /*#__PURE__*/React__default.createElement("div", {
663
+ className: `${prefix}--tab--list-gradient_bottom`
664
+ }));
665
+ }
666
+ TabListVertical.propTypes = {
667
+ /**
668
+ * Specify whether the content tab should be activated automatically or
669
+ * manually
670
+ */
671
+ activation: PropTypes.oneOf(['automatic', 'manual']),
672
+ /**
673
+ * Provide an accessible label to be read when a user interacts with this
674
+ * component
675
+ */
676
+ 'aria-label': PropTypes.string.isRequired,
677
+ /**
678
+ * Provide child elements to be rendered inside `ContentTabs`.
679
+ * These elements should render a `ContentTab`
680
+ */
681
+ children: PropTypes.node,
682
+ /**
683
+ * Specify an optional className to be added to the container node
684
+ */
685
+ className: PropTypes.string
686
+ };
687
+
448
688
  /**
449
689
  * Helper function to set up the behavior when a button is "long pressed".
450
690
  * This function will take a ref to the tablist, a direction, and a setter
@@ -490,7 +730,7 @@ function createLongPressBehavior(ref, direction, setScrollLeft) {
490
730
  * Tab
491
731
  */
492
732
 
493
- const Tab = /*#__PURE__*/forwardRef(function Tab(_ref5, forwardRef) {
733
+ const Tab = /*#__PURE__*/forwardRef(function Tab(_ref8, forwardRef) {
494
734
  let {
495
735
  as = 'button',
496
736
  children,
@@ -501,7 +741,7 @@ const Tab = /*#__PURE__*/forwardRef(function Tab(_ref5, forwardRef) {
501
741
  secondaryLabel,
502
742
  renderIcon: Icon,
503
743
  ...rest
504
- } = _ref5;
744
+ } = _ref8;
505
745
  const prefix = usePrefix();
506
746
  const {
507
747
  selectedIndex,
@@ -521,6 +761,11 @@ const Tab = /*#__PURE__*/forwardRef(function Tab(_ref5, forwardRef) {
521
761
  const [ignoreHover, setIgnoreHover] = useState(false);
522
762
  const id = `${baseId}-tab-${index}`;
523
763
  const panelId = `${baseId}-tabpanel-${index}`;
764
+ const [isEllipsisApplied, setIsEllipsisApplied] = useState(false);
765
+ const isEllipsisActive = element => {
766
+ setIsEllipsisApplied(element.offsetHeight < element.scrollHeight);
767
+ return element.offsetHeight < element.scrollHeight;
768
+ };
524
769
  const className = cx(`${prefix}--tabs__nav-item`, `${prefix}--tabs__nav-link`, {
525
770
  [`${prefix}--tabs__nav-item--selected`]: selectedIndex === index,
526
771
  [`${prefix}--tabs__nav-item--disabled`]: disabled,
@@ -542,6 +787,18 @@ const Tab = /*#__PURE__*/forwardRef(function Tab(_ref5, forwardRef) {
542
787
  };
543
788
  useEvent(dismissIconRef, 'mouseover', onDismissIconMouseEnter);
544
789
  useEvent(dismissIconRef, 'mouseleave', onDismissIconMouseLeave);
790
+ useLayoutEffect(() => {
791
+ function handler() {
792
+ const elementTabId = document.getElementById(`${id}`) || tabRef.current;
793
+ const newElement = elementTabId?.getElementsByClassName(`${prefix}--tabs__nav-item-label`)[0];
794
+ isEllipsisActive(newElement);
795
+ }
796
+ handler();
797
+ window.addEventListener('resize', handler);
798
+ return () => {
799
+ window.removeEventListener('resize', handler);
800
+ };
801
+ }, [prefix, id]);
545
802
  const handleClose = evt => {
546
803
  evt.stopPropagation();
547
804
  onTabCloseRequest?.(index);
@@ -596,6 +853,46 @@ const Tab = /*#__PURE__*/forwardRef(function Tab(_ref5, forwardRef) {
596
853
  "aria-label": `Press delete to remove ${typeof children === 'string' ? children : ''} tab`
597
854
  })));
598
855
  const hasIcon = Icon ?? dismissable;
856
+
857
+ // should only happen for vertical variation, so no dissimisamble icon is needed here
858
+ if (isEllipsisApplied) {
859
+ return /*#__PURE__*/React__default.createElement(Tooltip, {
860
+ label: children,
861
+ align: "top",
862
+ leaveDelayMs: 0,
863
+ autoAlign: true,
864
+ onMouseEnter: () => false,
865
+ closeOnActivation: true
866
+ }, /*#__PURE__*/React__default.createElement(BaseComponent, _extends({}, rest, {
867
+ "aria-controls": panelId,
868
+ "aria-disabled": disabled,
869
+ "aria-selected": selectedIndex === index,
870
+ ref: ref,
871
+ id: id,
872
+ role: "tab",
873
+ className: className,
874
+ disabled: disabled,
875
+ title: children,
876
+ onClick: evt => {
877
+ if (disabled) {
878
+ return;
879
+ }
880
+ setSelectedIndex(index);
881
+ onClick?.(evt);
882
+ },
883
+ onKeyDown: handleKeyDown,
884
+ tabIndex: selectedIndex === index ? '0' : '-1',
885
+ type: "button"
886
+ }), /*#__PURE__*/React__default.createElement("div", {
887
+ className: `${prefix}--tabs__nav-item-label-wrapper`
888
+ }, /*#__PURE__*/React__default.createElement(Text, {
889
+ className: `${prefix}--tabs__nav-item-label`
890
+ }, children)), hasSecondaryLabel && secondaryLabel && /*#__PURE__*/React__default.createElement(Text, {
891
+ as: "div",
892
+ className: `${prefix}--tabs__nav-item-secondary-label`,
893
+ title: secondaryLabel
894
+ }, secondaryLabel)));
895
+ }
599
896
  return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement(BaseComponent, _extends({}, rest, {
600
897
  "aria-controls": panelId,
601
898
  "aria-disabled": disabled,
@@ -684,7 +981,7 @@ Tab.propTypes = {
684
981
  * IconTab
685
982
  */
686
983
 
687
- const IconTab = /*#__PURE__*/React__default.forwardRef(function IconTab(_ref6, ref) {
984
+ const IconTab = /*#__PURE__*/React__default.forwardRef(function IconTab(_ref9, ref) {
688
985
  let {
689
986
  children,
690
987
  className: customClassName,
@@ -693,7 +990,7 @@ const IconTab = /*#__PURE__*/React__default.forwardRef(function IconTab(_ref6, r
693
990
  leaveDelayMs,
694
991
  label,
695
992
  ...rest
696
- } = _ref6;
993
+ } = _ref9;
697
994
  const prefix = usePrefix();
698
995
  const classNames = cx(`${prefix}--tabs__nav-item--icon-only`, customClassName);
699
996
  return /*#__PURE__*/React__default.createElement(Tooltip, {
@@ -742,12 +1039,12 @@ IconTab.propTypes = {
742
1039
  * TabPanel
743
1040
  */
744
1041
 
745
- const TabPanel = /*#__PURE__*/React__default.forwardRef(function TabPanel(_ref7, forwardRef) {
1042
+ const TabPanel = /*#__PURE__*/React__default.forwardRef(function TabPanel(_ref10, forwardRef) {
746
1043
  let {
747
1044
  children,
748
1045
  className: customClassName,
749
1046
  ...rest
750
- } = _ref7;
1047
+ } = _ref10;
751
1048
  const prefix = usePrefix();
752
1049
  const panel = useRef(null);
753
1050
  const ref = useMergedRefs([forwardRef, panel]);
@@ -822,14 +1119,50 @@ TabPanel.propTypes = {
822
1119
  * TabPanels
823
1120
  */
824
1121
 
825
- function TabPanels(_ref8) {
1122
+ function TabPanels(_ref11) {
826
1123
  let {
827
1124
  children
828
- } = _ref8;
1125
+ } = _ref11;
1126
+ const prefix = usePrefix();
1127
+ const refs = useRef([]);
1128
+ const hiddenStates = useRef([]);
1129
+ useLayoutEffect(() => {
1130
+ const tabContainer = refs.current[0]?.previousElementSibling;
1131
+ const isVertical = tabContainer?.classList.contains(`${prefix}--tabs--vertical`);
1132
+ const parentHasHeight = tabContainer?.parentElement?.style.height;
1133
+
1134
+ // Should only apply same height to vertical Tab Panels without a given height
1135
+ if (isVertical && !parentHasHeight) {
1136
+ hiddenStates.current = refs.current.map(ref => ref?.hidden || false);
1137
+
1138
+ // un-hide hidden Tab Panels to get heights
1139
+ refs.current.forEach(ref => {
1140
+ if (ref) {
1141
+ ref.hidden = false;
1142
+ }
1143
+ });
1144
+
1145
+ // set max height to TabList
1146
+ const heights = refs.current.map(ref => ref?.offsetHeight || 0);
1147
+ const max = Math.max(...heights);
1148
+ tabContainer.style.height = max + 'px';
1149
+
1150
+ // re-hide hidden Tab Panels
1151
+ refs.current.forEach((ref, index) => {
1152
+ if (ref) {
1153
+ ref.hidden = hiddenStates.current[index];
1154
+ }
1155
+ });
1156
+ }
1157
+ });
829
1158
  return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, React__default.Children.map(children, (child, index) => {
830
1159
  return /*#__PURE__*/React__default.createElement(TabPanelContext.Provider, {
831
1160
  value: index
832
- }, child);
1161
+ }, /*#__PURE__*/React__default.cloneElement(child, {
1162
+ ref: element => {
1163
+ refs.current[index] = element;
1164
+ }
1165
+ }));
833
1166
  }));
834
1167
  }
835
1168
  TabPanels.propTypes = {
@@ -839,4 +1172,4 @@ TabPanels.propTypes = {
839
1172
  children: PropTypes.node
840
1173
  };
841
1174
 
842
- export { IconTab, Tab, TabList, TabPanel, TabPanels, Tabs };
1175
+ export { IconTab, Tab, TabList, TabListVertical, TabPanel, TabPanels, Tabs, TabsVertical };
@@ -7,4 +7,4 @@
7
7
  import { Tabs } from './Tabs';
8
8
  export default Tabs;
9
9
  export { default as TabsSkeleton } from './Tabs.Skeleton';
10
- export { TabPanels, type TabPanelsProps, TabPanel, type TabPanelProps, TabList, type TabListProps, IconTab, type IconTabProps, Tabs, type TabsProps, } from './Tabs';
10
+ export { TabPanels, type TabPanelsProps, TabPanel, type TabPanelProps, TabList, type TabListProps, TabListVertical, type TabListVerticalProps, IconTab, type IconTabProps, Tabs, type TabsProps, TabsVertical, type TabsVerticalProps, } from './Tabs';
@@ -87,7 +87,7 @@ const TextArea = /*#__PURE__*/React__default.forwardRef((props, forwardRef) => {
87
87
  onKeyDown: evt => {
88
88
  if (!disabled && enableCounter && counterMode === 'word') {
89
89
  const key = evt.which;
90
- if (maxCount && textCount >= maxCount && key === 32) {
90
+ if (maxCount && textCount >= maxCount && key === 32 || maxCount && textCount >= maxCount && key === 13) {
91
91
  evt.preventDefault();
92
92
  }
93
93
  }
@@ -220,6 +220,7 @@ const TextArea = /*#__PURE__*/React__default.forwardRef((props, forwardRef) => {
220
220
  const ariaAnnouncement = useAnnouncer(textCount, maxCount, counterMode === 'word' ? 'words' : undefined);
221
221
  const input = /*#__PURE__*/React__default.createElement("textarea", _extends({}, other, textareaProps, {
222
222
  placeholder: placeholder,
223
+ "aria-readonly": other.readOnly ? true : false,
223
224
  className: textareaClasses,
224
225
  "aria-invalid": invalid,
225
226
  "aria-describedby": ariaDescribedBy,
@@ -390,6 +390,7 @@ const ExpandableTile = /*#__PURE__*/React__default.forwardRef(function Expandabl
390
390
  const [interactive, setInteractive] = useState(true);
391
391
  const aboveTheFold = useRef(null);
392
392
  const belowTheFold = useRef(null);
393
+ const chevronInteractiveRef = useRef(null);
393
394
  const tileContent = useRef(null);
394
395
  const tile = useRef(null);
395
396
  const ref = useMergedRefs([forwardRef, tile]);
@@ -421,7 +422,7 @@ const ExpandableTile = /*#__PURE__*/React__default.forwardRef(function Expandabl
421
422
  setMaxHeight();
422
423
  }
423
424
  function handleKeyUp(evt) {
424
- if (evt.target !== tile.current) {
425
+ if (evt.target !== tile.current && evt.target !== chevronInteractiveRef.current) {
425
426
  if (matches(evt, [Enter, Space])) {
426
427
  evt.preventDefault();
427
428
  }
@@ -515,6 +516,7 @@ const ExpandableTile = /*#__PURE__*/React__default.forwardRef(function Expandabl
515
516
  onKeyUp: composeEventHandlers([onKeyUp, handleKeyUp]),
516
517
  onClick: composeEventHandlers([onClick, handleClick]),
517
518
  "aria-label": isExpanded ? tileExpandedIconText : tileCollapsedIconText,
519
+ ref: chevronInteractiveRef,
518
520
  className: chevronInteractiveClassNames
519
521
  }, _ChevronDown || (_ChevronDown = /*#__PURE__*/React__default.createElement(ChevronDown, null))), /*#__PURE__*/React__default.createElement("div", {
520
522
  ref: belowTheFold,
package/es/index.js CHANGED
@@ -107,7 +107,7 @@ export { StructuredListBody, StructuredListCell, StructuredListHead, StructuredL
107
107
  export { default as StructuredListSkeleton } from './components/StructuredList/StructuredList.Skeleton.js';
108
108
  export { default as Switch } from './components/Switch/Switch.js';
109
109
  export { default as IconSwitch } from './components/Switch/IconSwitch.js';
110
- export { IconTab, Tab, TabList, TabPanel, TabPanels, Tabs } from './components/Tabs/Tabs.js';
110
+ export { IconTab, Tab, TabList, TabListVertical, TabPanel, TabPanels, Tabs, TabsVertical } from './components/Tabs/Tabs.js';
111
111
  export { default as TabContent } from './components/TabContent/TabContent.js';
112
112
  export { default as TabsSkeleton } from './components/Tabs/Tabs.Skeleton.js';
113
113
  export { default as Tag } from './components/Tag/Tag.js';
@@ -227,7 +227,8 @@ const ComboBox = /*#__PURE__*/React.forwardRef((props, ref) => {
227
227
  setHighlightedIndex(changes.selectedItem);
228
228
  if (onChange) {
229
229
  onChange({
230
- selectedItem: changes.selectedItem
230
+ selectedItem: changes.selectedItem,
231
+ inputValue
231
232
  });
232
233
  }
233
234
  return changes;
@@ -440,6 +441,16 @@ const ComboBox = /*#__PURE__*/React.forwardRef((props, ref) => {
440
441
  if (highlightedIndex !== -1) {
441
442
  selectItem(filterItems(items, itemToString, inputValue)[highlightedIndex]);
442
443
  }
444
+
445
+ // Since `onChange` does not normally fire when the menu is closed, we should
446
+ // manually fire it when `allowCustomValue` is provided, the menu is closing,
447
+ // and there is a value.
448
+ if (allowCustomValue && isOpen && inputValue) {
449
+ onChange({
450
+ selectedItem,
451
+ inputValue
452
+ });
453
+ }
443
454
  event.preventDownshiftDefault = true;
444
455
  event?.persist?.();
445
456
  }
@@ -25,6 +25,7 @@ var requiredIfGivenPropIsTruthy = require('../../prop-types/requiredIfGivenPropI
25
25
  var wrapFocus = require('../../internal/wrapFocus.js');
26
26
  var usePrefix = require('../../internal/usePrefix.js');
27
27
  var index$1 = require('../FeatureFlags/index.js');
28
+ var events = require('../../tools/events.js');
28
29
  var match = require('../../internal/keyboard/match.js');
29
30
  var keys = require('../../internal/keyboard/keys.js');
30
31
 
@@ -159,7 +160,7 @@ const ComposedModal = /*#__PURE__*/React__default["default"].forwardRef(function
159
160
  }
160
161
  onKeyDown?.(event);
161
162
  }
162
- function handleMousedown(evt) {
163
+ function handleOnClick(evt) {
163
164
  const target = evt.target;
164
165
  evt.stopPropagation();
165
166
  if (!preventCloseOnClickOutside && !wrapFocus.elementOrParentIsFloatingMenu(target, selectorsFloatingMenus) && innerModal.current && !innerModal.current.contains(target)) {
@@ -267,7 +268,7 @@ const ComposedModal = /*#__PURE__*/React__default["default"].forwardRef(function
267
268
  ref: ref,
268
269
  "aria-hidden": !open,
269
270
  onBlur: !focusTrapWithoutSentinels ? handleBlur : () => {},
270
- onMouseDown: handleMousedown,
271
+ onClick: events.composeEventHandlers([rest?.onClick, handleOnClick]),
271
272
  onKeyDown: handleKeyDown,
272
273
  className: modalClass
273
274
  }), /*#__PURE__*/React__default["default"].createElement("div", {
@@ -33,14 +33,16 @@ var carbonFlatpickrRangePlugin = (config => {
33
33
  origSetDate.call(this, dates, triggerChange, format);
34
34
  // If `triggerChange` is `true`, `onValueUpdate` Flatpickr event is fired
35
35
  // where Flatpickr's range plugin takes care of fixing the first `<input>`
36
- if (!triggerChange) {
36
+ if (!triggerChange && dates.length === 2) {
37
37
  const {
38
- _input: inputDates
38
+ _input: inputFrom
39
39
  } = fp;
40
- const inputDatesArray = inputDates.value.split(' ');
41
- [inputDatesArray[0], inputDatesArray[2]].forEach((input, i) => {
40
+ const {
41
+ input: inputTo
42
+ } = config;
43
+ [inputFrom, inputTo].forEach((input, i) => {
42
44
  if (input) {
43
- input = !dates[i] ? '' : fp.formatDate(new Date(dates[i]), fp.config.dateFormat);
45
+ input.value = !dates[i] ? '' : fp.formatDate(new Date(dates[i]), fp.config.dateFormat);
44
46
  }
45
47
  });
46
48
  }
@@ -4,7 +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 'wicg-inert';
8
7
  import React from 'react';
9
8
  import { ReactAttr } from '../../types/common';
10
9
  export interface DialogProps extends ReactAttr<HTMLDialogElement> {
@@ -26,6 +25,6 @@ export interface DialogProps extends ReactAttr<HTMLDialogElement> {
26
25
  */
27
26
  open?: boolean;
28
27
  }
29
- declare const Dialog: React.ForwardRefExoticComponent<DialogProps & React.RefAttributes<unknown>>;
30
- export { Dialog };
31
- export default Dialog;
28
+ declare const unstable__Dialog: React.ForwardRefExoticComponent<DialogProps & React.RefAttributes<unknown>>;
29
+ export { unstable__Dialog };
30
+ export default unstable__Dialog;