@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.
- package/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +1112 -888
- package/es/components/ComboBox/ComboBox.js +12 -1
- package/es/components/ComposedModal/ComposedModal.js +3 -2
- package/es/components/DatePicker/plugins/rangePlugin.js +7 -5
- package/es/components/Dialog/index.d.ts +3 -4
- package/es/components/Modal/Modal.js +3 -2
- package/es/components/Search/Search.js +3 -3
- package/es/components/Slider/Slider.d.ts +1 -1
- package/es/components/Slider/Slider.js +3 -2
- package/es/components/Tabs/Tabs.d.ts +111 -1
- package/es/components/Tabs/Tabs.js +351 -18
- package/es/components/Tabs/index.d.ts +1 -1
- package/es/components/TextArea/TextArea.js +2 -1
- package/es/components/Tile/Tile.js +3 -1
- package/es/index.js +1 -1
- package/lib/components/ComboBox/ComboBox.js +12 -1
- package/lib/components/ComposedModal/ComposedModal.js +3 -2
- package/lib/components/DatePicker/plugins/rangePlugin.js +7 -5
- package/lib/components/Dialog/index.d.ts +3 -4
- package/lib/components/Modal/Modal.js +3 -2
- package/lib/components/Search/Search.js +3 -3
- package/lib/components/Slider/Slider.d.ts +1 -1
- package/lib/components/Slider/Slider.js +3 -2
- package/lib/components/Tabs/Tabs.d.ts +111 -1
- package/lib/components/Tabs/Tabs.js +350 -15
- package/lib/components/Tabs/index.d.ts +1 -1
- package/lib/components/TextArea/TextArea.js +2 -1
- package/lib/components/Tile/Tile.js +3 -1
- package/lib/index.js +2 -0
- package/package.json +5 -6
|
@@ -16,6 +16,12 @@ var cx = require('classnames');
|
|
|
16
16
|
var debounce = require('lodash.debounce');
|
|
17
17
|
var PropTypes = require('prop-types');
|
|
18
18
|
var React = require('react');
|
|
19
|
+
require('../Grid/FlexGrid.js');
|
|
20
|
+
var Grid = require('../Grid/Grid.js');
|
|
21
|
+
require('../Grid/Row.js');
|
|
22
|
+
require('../Grid/Column.js');
|
|
23
|
+
require('../Grid/ColumnHang.js');
|
|
24
|
+
require('../Grid/GridContext.js');
|
|
19
25
|
var reactIs = require('react-is');
|
|
20
26
|
require('../Tooltip/DefinitionTooltip.js');
|
|
21
27
|
var Tooltip = require('../Tooltip/Tooltip.js');
|
|
@@ -43,6 +49,7 @@ var PropTypes__default = /*#__PURE__*/_interopDefaultLegacy(PropTypes);
|
|
|
43
49
|
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
|
|
44
50
|
|
|
45
51
|
var _ChevronLeft, _ChevronRight;
|
|
52
|
+
const verticalTabHeight = 64;
|
|
46
53
|
|
|
47
54
|
// Used to manage the overall state of the Tabs
|
|
48
55
|
|
|
@@ -63,6 +70,7 @@ const TabContext = /*#__PURE__*/React__default["default"].createContext({
|
|
|
63
70
|
hasSecondaryLabel: false
|
|
64
71
|
});
|
|
65
72
|
const lgMediaQuery = `(min-width: ${layout.breakpoints.lg.width})`;
|
|
73
|
+
const smMediaQuery = `(max-width: ${layout.breakpoints.md.width})`;
|
|
66
74
|
|
|
67
75
|
// Used to keep track of position in a list of tab panels
|
|
68
76
|
const TabPanelContext = /*#__PURE__*/React__default["default"].createContext(0);
|
|
@@ -141,6 +149,72 @@ Tabs.propTypes = {
|
|
|
141
149
|
*/
|
|
142
150
|
selectedIndex: PropTypes__default["default"].number
|
|
143
151
|
};
|
|
152
|
+
function TabsVertical(_ref2) {
|
|
153
|
+
let {
|
|
154
|
+
children,
|
|
155
|
+
height,
|
|
156
|
+
defaultSelectedIndex = 0,
|
|
157
|
+
onChange,
|
|
158
|
+
selectedIndex: controlledSelectedIndex,
|
|
159
|
+
...rest
|
|
160
|
+
} = _ref2;
|
|
161
|
+
const [selectedIndex, setSelectedIndex] = useControllableState.useControllableState({
|
|
162
|
+
value: controlledSelectedIndex,
|
|
163
|
+
defaultValue: defaultSelectedIndex,
|
|
164
|
+
onChange: value => onChange?.({
|
|
165
|
+
selectedIndex: value
|
|
166
|
+
})
|
|
167
|
+
});
|
|
168
|
+
const props = {
|
|
169
|
+
...rest,
|
|
170
|
+
selectedIndex,
|
|
171
|
+
onChange: _ref3 => {
|
|
172
|
+
let {
|
|
173
|
+
selectedIndex
|
|
174
|
+
} = _ref3;
|
|
175
|
+
return setSelectedIndex(selectedIndex);
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
const isSm = useMatchMedia.useMatchMedia(smMediaQuery);
|
|
179
|
+
if (!isSm) {
|
|
180
|
+
return (
|
|
181
|
+
/*#__PURE__*/
|
|
182
|
+
// eslint-disable-next-line react/forbid-component-props
|
|
183
|
+
React__default["default"].createElement(Grid.Grid, {
|
|
184
|
+
style: {
|
|
185
|
+
height: height
|
|
186
|
+
}
|
|
187
|
+
}, /*#__PURE__*/React__default["default"].createElement(Tabs, props, children))
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
return /*#__PURE__*/React__default["default"].createElement(Tabs, props, children);
|
|
191
|
+
}
|
|
192
|
+
TabsVertical.propTypes = {
|
|
193
|
+
/**
|
|
194
|
+
* Provide child elements to be rendered inside the `TabsVertical`.
|
|
195
|
+
* These elements should render either `TabsListVertical` or `TabsPanels`
|
|
196
|
+
*/
|
|
197
|
+
children: PropTypes__default["default"].node,
|
|
198
|
+
/**
|
|
199
|
+
* Specify which content tab should be initially selected when the component
|
|
200
|
+
* is first rendered
|
|
201
|
+
*/
|
|
202
|
+
defaultSelectedIndex: PropTypes__default["default"].number,
|
|
203
|
+
/**
|
|
204
|
+
* Option to set a height style only if using vertical variation
|
|
205
|
+
*/
|
|
206
|
+
height: PropTypes__default["default"].string,
|
|
207
|
+
/**
|
|
208
|
+
* Provide an optional function which is called whenever the state of the
|
|
209
|
+
* `Tabs` changes
|
|
210
|
+
*/
|
|
211
|
+
onChange: PropTypes__default["default"].func,
|
|
212
|
+
/**
|
|
213
|
+
* Control which content panel is currently selected. This puts the component
|
|
214
|
+
* in a controlled mode and should be used along with `onChange`
|
|
215
|
+
*/
|
|
216
|
+
selectedIndex: PropTypes__default["default"].number
|
|
217
|
+
};
|
|
144
218
|
|
|
145
219
|
/**
|
|
146
220
|
* Get the next index for a given keyboard event
|
|
@@ -161,11 +235,30 @@ function getNextIndex(event, total, index) {
|
|
|
161
235
|
}
|
|
162
236
|
}
|
|
163
237
|
|
|
238
|
+
/**
|
|
239
|
+
* Get the next index for a given keyboard event
|
|
240
|
+
* given a count of the total items and the current index
|
|
241
|
+
*/
|
|
242
|
+
function getNextIndexVertical(event, total, index) {
|
|
243
|
+
switch (true) {
|
|
244
|
+
case match.match(event, keys.ArrowDown):
|
|
245
|
+
return (index + 1) % total;
|
|
246
|
+
case match.match(event, keys.ArrowUp):
|
|
247
|
+
return (total + index - 1) % total;
|
|
248
|
+
case match.match(event, keys.Home):
|
|
249
|
+
return 0;
|
|
250
|
+
case match.match(event, keys.End):
|
|
251
|
+
return total - 1;
|
|
252
|
+
default:
|
|
253
|
+
return index;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
164
257
|
/**
|
|
165
258
|
* TabList
|
|
166
259
|
*/
|
|
167
260
|
|
|
168
|
-
function TabList(
|
|
261
|
+
function TabList(_ref4) {
|
|
169
262
|
let {
|
|
170
263
|
activation = 'automatic',
|
|
171
264
|
'aria-label': label,
|
|
@@ -180,7 +273,7 @@ function TabList(_ref2) {
|
|
|
180
273
|
scrollDebounceWait = 200,
|
|
181
274
|
scrollIntoView,
|
|
182
275
|
...rest
|
|
183
|
-
} =
|
|
276
|
+
} = _ref4;
|
|
184
277
|
const {
|
|
185
278
|
activeIndex,
|
|
186
279
|
selectedIndex,
|
|
@@ -337,10 +430,10 @@ function TabList(_ref2) {
|
|
|
337
430
|
}
|
|
338
431
|
}, [activation, activeIndex, selectedIndex, isScrollable, children]);
|
|
339
432
|
usePressable.usePressable(previousButton, {
|
|
340
|
-
onPress(
|
|
433
|
+
onPress(_ref5) {
|
|
341
434
|
let {
|
|
342
435
|
longPress
|
|
343
|
-
} =
|
|
436
|
+
} = _ref5;
|
|
344
437
|
if (!longPress && ref.current) {
|
|
345
438
|
setScrollLeft(Math.max(scrollLeft - ref.current.scrollWidth / tabs.current.length * 1.5, 0));
|
|
346
439
|
}
|
|
@@ -350,10 +443,10 @@ function TabList(_ref2) {
|
|
|
350
443
|
}
|
|
351
444
|
});
|
|
352
445
|
usePressable.usePressable(nextButton, {
|
|
353
|
-
onPress(
|
|
446
|
+
onPress(_ref6) {
|
|
354
447
|
let {
|
|
355
448
|
longPress
|
|
356
|
-
} =
|
|
449
|
+
} = _ref6;
|
|
357
450
|
if (!longPress && ref.current) {
|
|
358
451
|
setScrollLeft(Math.min(scrollLeft + ref.current.scrollWidth / tabs.current.length * 1.5, ref.current.scrollWidth - ref.current.clientWidth));
|
|
359
452
|
}
|
|
@@ -456,6 +549,153 @@ TabList.propTypes = {
|
|
|
456
549
|
scrollIntoView: PropTypes__default["default"].bool
|
|
457
550
|
};
|
|
458
551
|
|
|
552
|
+
/**
|
|
553
|
+
* TabListVertical
|
|
554
|
+
*/
|
|
555
|
+
|
|
556
|
+
// type TabElement = HTMLElement & { disabled?: boolean };
|
|
557
|
+
|
|
558
|
+
function TabListVertical(_ref7) {
|
|
559
|
+
let {
|
|
560
|
+
activation = 'automatic',
|
|
561
|
+
'aria-label': label,
|
|
562
|
+
children,
|
|
563
|
+
className: customClassName,
|
|
564
|
+
scrollIntoView,
|
|
565
|
+
...rest
|
|
566
|
+
} = _ref7;
|
|
567
|
+
const {
|
|
568
|
+
activeIndex,
|
|
569
|
+
selectedIndex,
|
|
570
|
+
setSelectedIndex,
|
|
571
|
+
setActiveIndex
|
|
572
|
+
} = React__default["default"].useContext(TabsContext);
|
|
573
|
+
const prefix = usePrefix.usePrefix();
|
|
574
|
+
const ref = React.useRef(null);
|
|
575
|
+
const [isOverflowingBottom, setIsOverflowingBottom] = React.useState(false);
|
|
576
|
+
const [isOverflowingTop, setIsOverflowingTop] = React.useState(false);
|
|
577
|
+
const isSm = useMatchMedia.useMatchMedia(smMediaQuery);
|
|
578
|
+
const className = cx__default["default"](`${prefix}--tabs`, `${prefix}--tabs--vertical`, `${prefix}--tabs--contained`, customClassName);
|
|
579
|
+
const tabs = React.useRef([]);
|
|
580
|
+
function onKeyDown(event) {
|
|
581
|
+
if (match.matches(event, [keys.ArrowDown, keys.ArrowUp, keys.Home, keys.End])) {
|
|
582
|
+
event.preventDefault();
|
|
583
|
+
const filtredTabs = tabs.current.filter(tab => tab !== null);
|
|
584
|
+
const activeTabs = filtredTabs.filter(tab => !tab.disabled);
|
|
585
|
+
const currentIndex = activeTabs.indexOf(tabs.current[activation === 'automatic' ? selectedIndex : activeIndex]);
|
|
586
|
+
const nextIndex = tabs.current.indexOf(activeTabs[getNextIndexVertical(event, activeTabs.length, currentIndex)]);
|
|
587
|
+
if (activation === 'automatic') {
|
|
588
|
+
setSelectedIndex(nextIndex);
|
|
589
|
+
} else if (activation === 'manual') {
|
|
590
|
+
setActiveIndex(nextIndex);
|
|
591
|
+
}
|
|
592
|
+
tabs.current[nextIndex]?.focus();
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
useEffectOnce.useEffectOnce(() => {
|
|
596
|
+
if (tabs.current[selectedIndex]?.disabled) {
|
|
597
|
+
const activeTabs = tabs.current.filter(tab => {
|
|
598
|
+
return !tab.disabled;
|
|
599
|
+
});
|
|
600
|
+
if (activeTabs.length > 0) {
|
|
601
|
+
const tab = activeTabs[0];
|
|
602
|
+
setSelectedIndex(tabs.current.indexOf(tab));
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
});
|
|
606
|
+
React.useEffect(() => {
|
|
607
|
+
function handler() {
|
|
608
|
+
const containerHeight = ref.current?.offsetHeight;
|
|
609
|
+
const containerTop = ref.current?.getBoundingClientRect().top;
|
|
610
|
+
const selectedPositionTop = tabs.current[selectedIndex]?.getBoundingClientRect().top;
|
|
611
|
+
const halfTabHeight = verticalTabHeight / 2;
|
|
612
|
+
if (containerTop && containerHeight) {
|
|
613
|
+
// scrolls so selected tab is in view
|
|
614
|
+
if (selectedPositionTop - halfTabHeight < containerTop || selectedPositionTop - containerTop + verticalTabHeight + halfTabHeight > containerHeight) {
|
|
615
|
+
ref.current.scrollTo({
|
|
616
|
+
top: (selectedIndex - 1) * verticalTabHeight,
|
|
617
|
+
behavior: 'smooth'
|
|
618
|
+
});
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
window.addEventListener('resize', handler);
|
|
623
|
+
handler();
|
|
624
|
+
return () => {
|
|
625
|
+
window.removeEventListener('resize', handler);
|
|
626
|
+
};
|
|
627
|
+
}, [selectedIndex, scrollIntoView]);
|
|
628
|
+
React.useEffect(() => {
|
|
629
|
+
const element = ref.current;
|
|
630
|
+
if (!element) {
|
|
631
|
+
return;
|
|
632
|
+
}
|
|
633
|
+
const handler = () => {
|
|
634
|
+
const halfTabHeight = verticalTabHeight / 2;
|
|
635
|
+
setIsOverflowingBottom(element.scrollTop + element.clientHeight + halfTabHeight <= element.scrollHeight);
|
|
636
|
+
setIsOverflowingTop(element.scrollTop > halfTabHeight);
|
|
637
|
+
};
|
|
638
|
+
const resizeObserver = new ResizeObserver(() => handler());
|
|
639
|
+
resizeObserver.observe(element);
|
|
640
|
+
element.addEventListener('scroll', handler);
|
|
641
|
+
return () => {
|
|
642
|
+
resizeObserver.disconnect();
|
|
643
|
+
element.removeEventListener('scroll', handler);
|
|
644
|
+
};
|
|
645
|
+
});
|
|
646
|
+
if (isSm) {
|
|
647
|
+
return /*#__PURE__*/React__default["default"].createElement(TabList, _rollupPluginBabelHelpers["extends"]({}, rest, {
|
|
648
|
+
"aria-label": label,
|
|
649
|
+
contained: true
|
|
650
|
+
}), children);
|
|
651
|
+
}
|
|
652
|
+
return /*#__PURE__*/React__default["default"].createElement("div", {
|
|
653
|
+
className: className
|
|
654
|
+
}, isOverflowingTop && /*#__PURE__*/React__default["default"].createElement("div", {
|
|
655
|
+
className: `${prefix}--tab--list-gradient_top`
|
|
656
|
+
}), /*#__PURE__*/React__default["default"].createElement("div", _rollupPluginBabelHelpers["extends"]({}, rest, {
|
|
657
|
+
"aria-label": label,
|
|
658
|
+
ref: ref,
|
|
659
|
+
role: "tablist",
|
|
660
|
+
className: `${prefix}--tab--list`,
|
|
661
|
+
onKeyDown: onKeyDown
|
|
662
|
+
}), React__default["default"].Children.map(children, (child, index) => {
|
|
663
|
+
return !reactIs.isElement(child) ? null : /*#__PURE__*/React__default["default"].createElement(TabContext.Provider, {
|
|
664
|
+
value: {
|
|
665
|
+
index,
|
|
666
|
+
hasSecondaryLabel: false
|
|
667
|
+
}
|
|
668
|
+
}, /*#__PURE__*/React__default["default"].cloneElement(child, {
|
|
669
|
+
ref: node => {
|
|
670
|
+
tabs.current[index] = node;
|
|
671
|
+
}
|
|
672
|
+
}));
|
|
673
|
+
})), isOverflowingBottom && /*#__PURE__*/React__default["default"].createElement("div", {
|
|
674
|
+
className: `${prefix}--tab--list-gradient_bottom`
|
|
675
|
+
}));
|
|
676
|
+
}
|
|
677
|
+
TabListVertical.propTypes = {
|
|
678
|
+
/**
|
|
679
|
+
* Specify whether the content tab should be activated automatically or
|
|
680
|
+
* manually
|
|
681
|
+
*/
|
|
682
|
+
activation: PropTypes__default["default"].oneOf(['automatic', 'manual']),
|
|
683
|
+
/**
|
|
684
|
+
* Provide an accessible label to be read when a user interacts with this
|
|
685
|
+
* component
|
|
686
|
+
*/
|
|
687
|
+
'aria-label': PropTypes__default["default"].string.isRequired,
|
|
688
|
+
/**
|
|
689
|
+
* Provide child elements to be rendered inside `ContentTabs`.
|
|
690
|
+
* These elements should render a `ContentTab`
|
|
691
|
+
*/
|
|
692
|
+
children: PropTypes__default["default"].node,
|
|
693
|
+
/**
|
|
694
|
+
* Specify an optional className to be added to the container node
|
|
695
|
+
*/
|
|
696
|
+
className: PropTypes__default["default"].string
|
|
697
|
+
};
|
|
698
|
+
|
|
459
699
|
/**
|
|
460
700
|
* Helper function to set up the behavior when a button is "long pressed".
|
|
461
701
|
* This function will take a ref to the tablist, a direction, and a setter
|
|
@@ -501,7 +741,7 @@ function createLongPressBehavior(ref, direction, setScrollLeft) {
|
|
|
501
741
|
* Tab
|
|
502
742
|
*/
|
|
503
743
|
|
|
504
|
-
const Tab = /*#__PURE__*/React.forwardRef(function Tab(
|
|
744
|
+
const Tab = /*#__PURE__*/React.forwardRef(function Tab(_ref8, forwardRef) {
|
|
505
745
|
let {
|
|
506
746
|
as = 'button',
|
|
507
747
|
children,
|
|
@@ -512,7 +752,7 @@ const Tab = /*#__PURE__*/React.forwardRef(function Tab(_ref5, forwardRef) {
|
|
|
512
752
|
secondaryLabel,
|
|
513
753
|
renderIcon: Icon,
|
|
514
754
|
...rest
|
|
515
|
-
} =
|
|
755
|
+
} = _ref8;
|
|
516
756
|
const prefix = usePrefix.usePrefix();
|
|
517
757
|
const {
|
|
518
758
|
selectedIndex,
|
|
@@ -532,6 +772,11 @@ const Tab = /*#__PURE__*/React.forwardRef(function Tab(_ref5, forwardRef) {
|
|
|
532
772
|
const [ignoreHover, setIgnoreHover] = React.useState(false);
|
|
533
773
|
const id = `${baseId}-tab-${index}`;
|
|
534
774
|
const panelId = `${baseId}-tabpanel-${index}`;
|
|
775
|
+
const [isEllipsisApplied, setIsEllipsisApplied] = React.useState(false);
|
|
776
|
+
const isEllipsisActive = element => {
|
|
777
|
+
setIsEllipsisApplied(element.offsetHeight < element.scrollHeight);
|
|
778
|
+
return element.offsetHeight < element.scrollHeight;
|
|
779
|
+
};
|
|
535
780
|
const className = cx__default["default"](`${prefix}--tabs__nav-item`, `${prefix}--tabs__nav-link`, {
|
|
536
781
|
[`${prefix}--tabs__nav-item--selected`]: selectedIndex === index,
|
|
537
782
|
[`${prefix}--tabs__nav-item--disabled`]: disabled,
|
|
@@ -553,6 +798,18 @@ const Tab = /*#__PURE__*/React.forwardRef(function Tab(_ref5, forwardRef) {
|
|
|
553
798
|
};
|
|
554
799
|
useEvent.useEvent(dismissIconRef, 'mouseover', onDismissIconMouseEnter);
|
|
555
800
|
useEvent.useEvent(dismissIconRef, 'mouseleave', onDismissIconMouseLeave);
|
|
801
|
+
React.useLayoutEffect(() => {
|
|
802
|
+
function handler() {
|
|
803
|
+
const elementTabId = document.getElementById(`${id}`) || tabRef.current;
|
|
804
|
+
const newElement = elementTabId?.getElementsByClassName(`${prefix}--tabs__nav-item-label`)[0];
|
|
805
|
+
isEllipsisActive(newElement);
|
|
806
|
+
}
|
|
807
|
+
handler();
|
|
808
|
+
window.addEventListener('resize', handler);
|
|
809
|
+
return () => {
|
|
810
|
+
window.removeEventListener('resize', handler);
|
|
811
|
+
};
|
|
812
|
+
}, [prefix, id]);
|
|
556
813
|
const handleClose = evt => {
|
|
557
814
|
evt.stopPropagation();
|
|
558
815
|
onTabCloseRequest?.(index);
|
|
@@ -607,6 +864,46 @@ const Tab = /*#__PURE__*/React.forwardRef(function Tab(_ref5, forwardRef) {
|
|
|
607
864
|
"aria-label": `Press delete to remove ${typeof children === 'string' ? children : ''} tab`
|
|
608
865
|
})));
|
|
609
866
|
const hasIcon = Icon ?? dismissable;
|
|
867
|
+
|
|
868
|
+
// should only happen for vertical variation, so no dissimisamble icon is needed here
|
|
869
|
+
if (isEllipsisApplied) {
|
|
870
|
+
return /*#__PURE__*/React__default["default"].createElement(Tooltip.Tooltip, {
|
|
871
|
+
label: children,
|
|
872
|
+
align: "top",
|
|
873
|
+
leaveDelayMs: 0,
|
|
874
|
+
autoAlign: true,
|
|
875
|
+
onMouseEnter: () => false,
|
|
876
|
+
closeOnActivation: true
|
|
877
|
+
}, /*#__PURE__*/React__default["default"].createElement(BaseComponent, _rollupPluginBabelHelpers["extends"]({}, rest, {
|
|
878
|
+
"aria-controls": panelId,
|
|
879
|
+
"aria-disabled": disabled,
|
|
880
|
+
"aria-selected": selectedIndex === index,
|
|
881
|
+
ref: ref,
|
|
882
|
+
id: id,
|
|
883
|
+
role: "tab",
|
|
884
|
+
className: className,
|
|
885
|
+
disabled: disabled,
|
|
886
|
+
title: children,
|
|
887
|
+
onClick: evt => {
|
|
888
|
+
if (disabled) {
|
|
889
|
+
return;
|
|
890
|
+
}
|
|
891
|
+
setSelectedIndex(index);
|
|
892
|
+
onClick?.(evt);
|
|
893
|
+
},
|
|
894
|
+
onKeyDown: handleKeyDown,
|
|
895
|
+
tabIndex: selectedIndex === index ? '0' : '-1',
|
|
896
|
+
type: "button"
|
|
897
|
+
}), /*#__PURE__*/React__default["default"].createElement("div", {
|
|
898
|
+
className: `${prefix}--tabs__nav-item-label-wrapper`
|
|
899
|
+
}, /*#__PURE__*/React__default["default"].createElement(Text.Text, {
|
|
900
|
+
className: `${prefix}--tabs__nav-item-label`
|
|
901
|
+
}, children)), hasSecondaryLabel && secondaryLabel && /*#__PURE__*/React__default["default"].createElement(Text.Text, {
|
|
902
|
+
as: "div",
|
|
903
|
+
className: `${prefix}--tabs__nav-item-secondary-label`,
|
|
904
|
+
title: secondaryLabel
|
|
905
|
+
}, secondaryLabel)));
|
|
906
|
+
}
|
|
610
907
|
return /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, /*#__PURE__*/React__default["default"].createElement(BaseComponent, _rollupPluginBabelHelpers["extends"]({}, rest, {
|
|
611
908
|
"aria-controls": panelId,
|
|
612
909
|
"aria-disabled": disabled,
|
|
@@ -695,7 +992,7 @@ Tab.propTypes = {
|
|
|
695
992
|
* IconTab
|
|
696
993
|
*/
|
|
697
994
|
|
|
698
|
-
const IconTab = /*#__PURE__*/React__default["default"].forwardRef(function IconTab(
|
|
995
|
+
const IconTab = /*#__PURE__*/React__default["default"].forwardRef(function IconTab(_ref9, ref) {
|
|
699
996
|
let {
|
|
700
997
|
children,
|
|
701
998
|
className: customClassName,
|
|
@@ -704,7 +1001,7 @@ const IconTab = /*#__PURE__*/React__default["default"].forwardRef(function IconT
|
|
|
704
1001
|
leaveDelayMs,
|
|
705
1002
|
label,
|
|
706
1003
|
...rest
|
|
707
|
-
} =
|
|
1004
|
+
} = _ref9;
|
|
708
1005
|
const prefix = usePrefix.usePrefix();
|
|
709
1006
|
const classNames = cx__default["default"](`${prefix}--tabs__nav-item--icon-only`, customClassName);
|
|
710
1007
|
return /*#__PURE__*/React__default["default"].createElement(Tooltip.Tooltip, {
|
|
@@ -753,12 +1050,12 @@ IconTab.propTypes = {
|
|
|
753
1050
|
* TabPanel
|
|
754
1051
|
*/
|
|
755
1052
|
|
|
756
|
-
const TabPanel = /*#__PURE__*/React__default["default"].forwardRef(function TabPanel(
|
|
1053
|
+
const TabPanel = /*#__PURE__*/React__default["default"].forwardRef(function TabPanel(_ref10, forwardRef) {
|
|
757
1054
|
let {
|
|
758
1055
|
children,
|
|
759
1056
|
className: customClassName,
|
|
760
1057
|
...rest
|
|
761
|
-
} =
|
|
1058
|
+
} = _ref10;
|
|
762
1059
|
const prefix = usePrefix.usePrefix();
|
|
763
1060
|
const panel = React.useRef(null);
|
|
764
1061
|
const ref = useMergedRefs.useMergedRefs([forwardRef, panel]);
|
|
@@ -833,14 +1130,50 @@ TabPanel.propTypes = {
|
|
|
833
1130
|
* TabPanels
|
|
834
1131
|
*/
|
|
835
1132
|
|
|
836
|
-
function TabPanels(
|
|
1133
|
+
function TabPanels(_ref11) {
|
|
837
1134
|
let {
|
|
838
1135
|
children
|
|
839
|
-
} =
|
|
1136
|
+
} = _ref11;
|
|
1137
|
+
const prefix = usePrefix.usePrefix();
|
|
1138
|
+
const refs = React.useRef([]);
|
|
1139
|
+
const hiddenStates = React.useRef([]);
|
|
1140
|
+
React.useLayoutEffect(() => {
|
|
1141
|
+
const tabContainer = refs.current[0]?.previousElementSibling;
|
|
1142
|
+
const isVertical = tabContainer?.classList.contains(`${prefix}--tabs--vertical`);
|
|
1143
|
+
const parentHasHeight = tabContainer?.parentElement?.style.height;
|
|
1144
|
+
|
|
1145
|
+
// Should only apply same height to vertical Tab Panels without a given height
|
|
1146
|
+
if (isVertical && !parentHasHeight) {
|
|
1147
|
+
hiddenStates.current = refs.current.map(ref => ref?.hidden || false);
|
|
1148
|
+
|
|
1149
|
+
// un-hide hidden Tab Panels to get heights
|
|
1150
|
+
refs.current.forEach(ref => {
|
|
1151
|
+
if (ref) {
|
|
1152
|
+
ref.hidden = false;
|
|
1153
|
+
}
|
|
1154
|
+
});
|
|
1155
|
+
|
|
1156
|
+
// set max height to TabList
|
|
1157
|
+
const heights = refs.current.map(ref => ref?.offsetHeight || 0);
|
|
1158
|
+
const max = Math.max(...heights);
|
|
1159
|
+
tabContainer.style.height = max + 'px';
|
|
1160
|
+
|
|
1161
|
+
// re-hide hidden Tab Panels
|
|
1162
|
+
refs.current.forEach((ref, index) => {
|
|
1163
|
+
if (ref) {
|
|
1164
|
+
ref.hidden = hiddenStates.current[index];
|
|
1165
|
+
}
|
|
1166
|
+
});
|
|
1167
|
+
}
|
|
1168
|
+
});
|
|
840
1169
|
return /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, React__default["default"].Children.map(children, (child, index) => {
|
|
841
1170
|
return /*#__PURE__*/React__default["default"].createElement(TabPanelContext.Provider, {
|
|
842
1171
|
value: index
|
|
843
|
-
}, child
|
|
1172
|
+
}, /*#__PURE__*/React__default["default"].cloneElement(child, {
|
|
1173
|
+
ref: element => {
|
|
1174
|
+
refs.current[index] = element;
|
|
1175
|
+
}
|
|
1176
|
+
}));
|
|
844
1177
|
}));
|
|
845
1178
|
}
|
|
846
1179
|
TabPanels.propTypes = {
|
|
@@ -853,6 +1186,8 @@ TabPanels.propTypes = {
|
|
|
853
1186
|
exports.IconTab = IconTab;
|
|
854
1187
|
exports.Tab = Tab;
|
|
855
1188
|
exports.TabList = TabList;
|
|
1189
|
+
exports.TabListVertical = TabListVertical;
|
|
856
1190
|
exports.TabPanel = TabPanel;
|
|
857
1191
|
exports.TabPanels = TabPanels;
|
|
858
1192
|
exports.Tabs = Tabs;
|
|
1193
|
+
exports.TabsVertical = 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';
|
|
@@ -97,7 +97,7 @@ const TextArea = /*#__PURE__*/React__default["default"].forwardRef((props, forwa
|
|
|
97
97
|
onKeyDown: evt => {
|
|
98
98
|
if (!disabled && enableCounter && counterMode === 'word') {
|
|
99
99
|
const key = evt.which;
|
|
100
|
-
if (maxCount && textCount >= maxCount && key === 32) {
|
|
100
|
+
if (maxCount && textCount >= maxCount && key === 32 || maxCount && textCount >= maxCount && key === 13) {
|
|
101
101
|
evt.preventDefault();
|
|
102
102
|
}
|
|
103
103
|
}
|
|
@@ -230,6 +230,7 @@ const TextArea = /*#__PURE__*/React__default["default"].forwardRef((props, forwa
|
|
|
230
230
|
const ariaAnnouncement = useAnnouncer.useAnnouncer(textCount, maxCount, counterMode === 'word' ? 'words' : undefined);
|
|
231
231
|
const input = /*#__PURE__*/React__default["default"].createElement("textarea", _rollupPluginBabelHelpers["extends"]({}, other, textareaProps, {
|
|
232
232
|
placeholder: placeholder,
|
|
233
|
+
"aria-readonly": other.readOnly ? true : false,
|
|
233
234
|
className: textareaClasses,
|
|
234
235
|
"aria-invalid": invalid,
|
|
235
236
|
"aria-describedby": ariaDescribedBy,
|
|
@@ -400,6 +400,7 @@ const ExpandableTile = /*#__PURE__*/React__default["default"].forwardRef(functio
|
|
|
400
400
|
const [interactive, setInteractive] = React.useState(true);
|
|
401
401
|
const aboveTheFold = React.useRef(null);
|
|
402
402
|
const belowTheFold = React.useRef(null);
|
|
403
|
+
const chevronInteractiveRef = React.useRef(null);
|
|
403
404
|
const tileContent = React.useRef(null);
|
|
404
405
|
const tile = React.useRef(null);
|
|
405
406
|
const ref = useMergedRefs.useMergedRefs([forwardRef, tile]);
|
|
@@ -431,7 +432,7 @@ const ExpandableTile = /*#__PURE__*/React__default["default"].forwardRef(functio
|
|
|
431
432
|
setMaxHeight();
|
|
432
433
|
}
|
|
433
434
|
function handleKeyUp(evt) {
|
|
434
|
-
if (evt.target !== tile.current) {
|
|
435
|
+
if (evt.target !== tile.current && evt.target !== chevronInteractiveRef.current) {
|
|
435
436
|
if (match.matches(evt, [keys.Enter, keys.Space])) {
|
|
436
437
|
evt.preventDefault();
|
|
437
438
|
}
|
|
@@ -525,6 +526,7 @@ const ExpandableTile = /*#__PURE__*/React__default["default"].forwardRef(functio
|
|
|
525
526
|
onKeyUp: events.composeEventHandlers([onKeyUp, handleKeyUp]),
|
|
526
527
|
onClick: events.composeEventHandlers([onClick, handleClick]),
|
|
527
528
|
"aria-label": isExpanded ? tileExpandedIconText : tileCollapsedIconText,
|
|
529
|
+
ref: chevronInteractiveRef,
|
|
528
530
|
className: chevronInteractiveClassNames
|
|
529
531
|
}, _ChevronDown || (_ChevronDown = /*#__PURE__*/React__default["default"].createElement(iconsReact.ChevronDown, null))), /*#__PURE__*/React__default["default"].createElement("div", {
|
|
530
532
|
ref: belowTheFold,
|
package/lib/index.js
CHANGED
|
@@ -361,9 +361,11 @@ exports.IconSwitch = IconSwitch["default"];
|
|
|
361
361
|
exports.IconTab = Tabs.IconTab;
|
|
362
362
|
exports.Tab = Tabs.Tab;
|
|
363
363
|
exports.TabList = Tabs.TabList;
|
|
364
|
+
exports.TabListVertical = Tabs.TabListVertical;
|
|
364
365
|
exports.TabPanel = Tabs.TabPanel;
|
|
365
366
|
exports.TabPanels = Tabs.TabPanels;
|
|
366
367
|
exports.Tabs = Tabs.Tabs;
|
|
368
|
+
exports.TabsVertical = Tabs.TabsVertical;
|
|
367
369
|
exports.TabContent = TabContent["default"];
|
|
368
370
|
exports.TabsSkeleton = Tabs_Skeleton["default"];
|
|
369
371
|
exports.Tag = Tag["default"];
|
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.
|
|
4
|
+
"version": "1.62.0-rc.0",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"module": "es/index.js",
|
|
@@ -49,9 +49,9 @@
|
|
|
49
49
|
"dependencies": {
|
|
50
50
|
"@babel/runtime": "^7.18.3",
|
|
51
51
|
"@carbon/feature-flags": "^0.20.0",
|
|
52
|
-
"@carbon/icons-react": "^11.45.0
|
|
52
|
+
"@carbon/icons-react": "^11.45.0",
|
|
53
53
|
"@carbon/layout": "^11.23.0",
|
|
54
|
-
"@carbon/styles": "^1.61.0
|
|
54
|
+
"@carbon/styles": "^1.61.0",
|
|
55
55
|
"@floating-ui/react": "^0.26.0",
|
|
56
56
|
"@ibm/telemetry-js": "^1.5.0",
|
|
57
57
|
"classnames": "2.5.1",
|
|
@@ -68,7 +68,6 @@
|
|
|
68
68
|
"react-is": "^18.2.0",
|
|
69
69
|
"tabbable": "^6.2.0",
|
|
70
70
|
"use-resize-observer": "^6.0.0",
|
|
71
|
-
"wicg-inert": "^3.1.1",
|
|
72
71
|
"window-or-global": "^1.0.1"
|
|
73
72
|
},
|
|
74
73
|
"devDependencies": {
|
|
@@ -82,7 +81,7 @@
|
|
|
82
81
|
"@babel/preset-typescript": "^7.21.5",
|
|
83
82
|
"@carbon/test-utils": "^10.30.0",
|
|
84
83
|
"@carbon/themes": "^11.37.0",
|
|
85
|
-
"@figma/code-connect": "^1.0.
|
|
84
|
+
"@figma/code-connect": "^1.0.2",
|
|
86
85
|
"@rollup/plugin-babel": "^6.0.0",
|
|
87
86
|
"@rollup/plugin-commonjs": "^26.0.0",
|
|
88
87
|
"@rollup/plugin-node-resolve": "^15.0.0",
|
|
@@ -142,5 +141,5 @@
|
|
|
142
141
|
"**/*.scss",
|
|
143
142
|
"**/*.css"
|
|
144
143
|
],
|
|
145
|
-
"gitHead": "
|
|
144
|
+
"gitHead": "b12ac2e1e7eefce31f97062f5cc0c4a1579012e7"
|
|
146
145
|
}
|