@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
|
@@ -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(
|
|
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
|
-
} =
|
|
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(
|
|
422
|
+
onPress(_ref5) {
|
|
330
423
|
let {
|
|
331
424
|
longPress
|
|
332
|
-
} =
|
|
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(
|
|
435
|
+
onPress(_ref6) {
|
|
343
436
|
let {
|
|
344
437
|
longPress
|
|
345
|
-
} =
|
|
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(
|
|
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
|
-
} =
|
|
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(
|
|
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
|
-
} =
|
|
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(
|
|
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
|
-
} =
|
|
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(
|
|
1122
|
+
function TabPanels(_ref11) {
|
|
826
1123
|
let {
|
|
827
1124
|
children
|
|
828
|
-
} =
|
|
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
|
|
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
|
-
|
|
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:
|
|
38
|
+
_input: inputFrom
|
|
39
39
|
} = fp;
|
|
40
|
-
const
|
|
41
|
-
|
|
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
|
|
30
|
-
export {
|
|
31
|
-
export default
|
|
28
|
+
declare const unstable__Dialog: React.ForwardRefExoticComponent<DialogProps & React.RefAttributes<unknown>>;
|
|
29
|
+
export { unstable__Dialog };
|
|
30
|
+
export default unstable__Dialog;
|