@itwin/itwinui-react 3.0.0-dev.13 → 3.0.0-dev.14
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/CHANGELOG.md +23 -0
- package/cjs/core/Carousel/Carousel.d.ts +12 -5
- package/cjs/core/Carousel/Carousel.js +9 -39
- package/cjs/core/Carousel/CarouselContext.d.ts +0 -4
- package/cjs/core/Carousel/CarouselDot.js +1 -1
- package/cjs/core/Carousel/CarouselDotsList.js +26 -2
- package/cjs/core/Carousel/CarouselNavigation.d.ts +1 -1
- package/cjs/core/Carousel/CarouselNavigation.js +4 -17
- package/cjs/core/Carousel/CarouselSlide.d.ts +1 -1
- package/cjs/core/Carousel/CarouselSlide.js +12 -2
- package/cjs/core/Carousel/CarouselSlider.d.ts +1 -1
- package/cjs/core/Carousel/CarouselSlider.js +2 -2
- package/cjs/core/Slider/Slider.d.ts +2 -6
- package/cjs/core/Slider/Slider.js +8 -22
- package/cjs/core/Slider/Thumb.d.ts +1 -2
- package/cjs/core/Slider/Thumb.js +1 -5
- package/cjs/core/Tabs/Tabs.js +12 -18
- package/cjs/core/Tile/Tile.js +11 -10
- package/cjs/core/utils/hooks/useOverflow.js +3 -1
- package/cjs/styles.js +8 -10
- package/esm/core/Carousel/Carousel.d.ts +12 -5
- package/esm/core/Carousel/Carousel.js +9 -39
- package/esm/core/Carousel/CarouselContext.d.ts +0 -4
- package/esm/core/Carousel/CarouselDot.js +1 -1
- package/esm/core/Carousel/CarouselDotsList.js +26 -2
- package/esm/core/Carousel/CarouselNavigation.d.ts +1 -1
- package/esm/core/Carousel/CarouselNavigation.js +5 -22
- package/esm/core/Carousel/CarouselSlide.d.ts +1 -1
- package/esm/core/Carousel/CarouselSlide.js +15 -3
- package/esm/core/Carousel/CarouselSlider.d.ts +1 -1
- package/esm/core/Carousel/CarouselSlider.js +2 -2
- package/esm/core/Slider/Slider.d.ts +2 -6
- package/esm/core/Slider/Slider.js +8 -19
- package/esm/core/Slider/Thumb.d.ts +1 -2
- package/esm/core/Slider/Thumb.js +1 -5
- package/esm/core/Tabs/Tabs.js +13 -17
- package/esm/core/Tile/Tile.js +11 -10
- package/esm/core/utils/hooks/useOverflow.js +3 -1
- package/esm/styles.js +8 -10
- package/package.json +2 -2
- package/styles.css +28 -42
package/cjs/styles.js
CHANGED
|
@@ -72,9 +72,7 @@ const styles = {
|
|
|
72
72
|
'iui-color-selection-wrapper': '_iui3-color-selection-wrapper',
|
|
73
73
|
'iui-color-field': '_iui3-color-field',
|
|
74
74
|
'iui-hue-slider': '_iui3-hue-slider',
|
|
75
|
-
'iui-slider
|
|
76
|
-
'iui-slider-rail': '_iui3-slider-rail',
|
|
77
|
-
'iui-slider-thumb': '_iui3-slider-thumb',
|
|
75
|
+
'iui-slider': '_iui3-slider',
|
|
78
76
|
'iui-opacity-slider': '_iui3-opacity-slider',
|
|
79
77
|
'iui-color-dot': '_iui3-color-dot',
|
|
80
78
|
'iui-date-picker': '_iui3-date-picker',
|
|
@@ -215,10 +213,10 @@ const styles = {
|
|
|
215
213
|
'iui-overlay-exiting': '_iui3-overlay-exiting',
|
|
216
214
|
closeAnimation,
|
|
217
215
|
'iui-progress-indicator-radial': '_iui3-progress-indicator-radial',
|
|
218
|
-
'iui-
|
|
216
|
+
'iui-ua1bwgp': '_iui3-ua1bwgp',
|
|
219
217
|
'iui-progress-indicator-linear-label':
|
|
220
218
|
'_iui3-progress-indicator-linear-label',
|
|
221
|
-
'iui-
|
|
219
|
+
'iui-ua1bwhh': '_iui3-ua1bwhh',
|
|
222
220
|
'iui-radio': '_iui3-radio',
|
|
223
221
|
'iui-radio-tile': '_iui3-radio-tile',
|
|
224
222
|
'iui-radio-tile-icon': '_iui3-radio-tile-icon',
|
|
@@ -230,6 +228,7 @@ const styles = {
|
|
|
230
228
|
'iui-expandable-searchbox': '_iui3-expandable-searchbox',
|
|
231
229
|
'iui-searchbox-open-button': '_iui3-searchbox-open-button',
|
|
232
230
|
'iui-search-icon': '_iui3-search-icon',
|
|
231
|
+
'iui-search-input': '_iui3-search-input',
|
|
233
232
|
'iui-placeholder': '_iui3-placeholder',
|
|
234
233
|
'iui-select-tag': '_iui3-select-tag',
|
|
235
234
|
'iui-select-tag-label': '_iui3-select-tag-label',
|
|
@@ -257,15 +256,14 @@ const styles = {
|
|
|
257
256
|
'_iui3-side-navigation-submenu-header-actions',
|
|
258
257
|
'iui-side-navigation-wrapper': '_iui3-side-navigation-wrapper',
|
|
259
258
|
'iui-skip-to-content-link': '_iui3-skip-to-content-link',
|
|
260
|
-
'iui-slider-
|
|
261
|
-
'iui-slider-track': '_iui3-slider-track',
|
|
259
|
+
'iui-slider-container': '_iui3-slider-container',
|
|
262
260
|
'iui-slider-min': '_iui3-slider-min',
|
|
263
261
|
'iui-slider-max': '_iui3-slider-max',
|
|
262
|
+
'iui-slider-ticks': '_iui3-slider-ticks',
|
|
264
263
|
'iui-slider-tick': '_iui3-slider-tick',
|
|
264
|
+
'iui-slider-track': '_iui3-slider-track',
|
|
265
|
+
'iui-slider-thumb': '_iui3-slider-thumb',
|
|
265
266
|
'iui-grabbing': '_iui3-grabbing',
|
|
266
|
-
'iui-slider-ticks': '_iui3-slider-ticks',
|
|
267
|
-
'iui-slider-horizontal': '_iui3-slider-horizontal',
|
|
268
|
-
'iui-slider-vertical': '_iui3-slider-vertical',
|
|
269
267
|
'iui-stepper': '_iui3-stepper',
|
|
270
268
|
'iui-stepper-step': '_iui3-stepper-step',
|
|
271
269
|
'iui-current': '_iui3-current',
|
|
@@ -14,7 +14,8 @@ type CarouselProps = {
|
|
|
14
14
|
};
|
|
15
15
|
/**
|
|
16
16
|
* The Carousel component consists of a set of slides, normally displayed one at a time. A navigation section is
|
|
17
|
-
*
|
|
17
|
+
* shown below the slides, consisting of "dots" and "previous"/"next" buttons, used for changing slides; this navigation
|
|
18
|
+
* section must be present _before_ the slides in DOM order, even though it is visually shown below the slides.
|
|
18
19
|
*
|
|
19
20
|
* The currently shown slide can also be changed using the left/right arrow keys or by dragging on a touch device.
|
|
20
21
|
*
|
|
@@ -22,20 +23,23 @@ type CarouselProps = {
|
|
|
22
23
|
*
|
|
23
24
|
* @example
|
|
24
25
|
* <Carousel>
|
|
26
|
+
* <Carousel.Navigation />
|
|
25
27
|
* <Carousel.Slider>
|
|
26
28
|
* <Carousel.Slide>...</Carousel.Slide>
|
|
27
29
|
* <Carousel.Slide>...</Carousel.Slide>
|
|
28
30
|
* <Carousel.Slide>...</Carousel.Slide>
|
|
29
31
|
* </Carousel.Slider>
|
|
30
|
-
* <Carousel.Navigation />
|
|
31
32
|
* </Carousel>
|
|
32
33
|
*/
|
|
33
34
|
export declare const Carousel: PolymorphicForwardRefComponent<"section", CarouselProps> & {
|
|
34
|
-
Slider: PolymorphicForwardRefComponent<"
|
|
35
|
-
Slide: PolymorphicForwardRefComponent<"
|
|
35
|
+
Slider: PolymorphicForwardRefComponent<"div", {}>;
|
|
36
|
+
Slide: PolymorphicForwardRefComponent<"div", {
|
|
36
37
|
index?: number | undefined;
|
|
37
38
|
}>;
|
|
38
|
-
|
|
39
|
+
/**
|
|
40
|
+
* Contains the dots and previous/next buttons for navigating the slides. Must be present _before_ the slides in DOM.
|
|
41
|
+
*/
|
|
42
|
+
Navigation: PolymorphicForwardRefComponent<"div", {}> & {
|
|
39
43
|
PreviousButton: PolymorphicForwardRefComponent<"button", Omit<Omit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & {
|
|
40
44
|
ref?: ((instance: HTMLButtonElement | null) => void) | React.RefObject<HTMLButtonElement> | null | undefined;
|
|
41
45
|
}, "label" | "as" | "size" | "htmlDisabled" | "styleType" | "isActive" | "iconProps"> & {
|
|
@@ -55,6 +59,9 @@ export declare const Carousel: PolymorphicForwardRefComponent<"section", Carouse
|
|
|
55
59
|
as?: "button" | undefined;
|
|
56
60
|
}>;
|
|
57
61
|
};
|
|
62
|
+
/**
|
|
63
|
+
* Contains the dots for activating the slides. Must be present _before_ the slides in DOM.
|
|
64
|
+
*/
|
|
58
65
|
DotsList: PolymorphicForwardRefComponent<"div", {
|
|
59
66
|
length?: number | undefined;
|
|
60
67
|
currentIndex?: number | undefined;
|
|
@@ -39,42 +39,9 @@ const CarouselComponent = React.forwardRef((props, ref) => {
|
|
|
39
39
|
scrollToSlide.current(userActiveIndex, {
|
|
40
40
|
instant: justMounted.current,
|
|
41
41
|
});
|
|
42
|
-
// re-focus the carousel for keyboard nav, but not on first mount
|
|
43
|
-
// because it shows outline and might interfere with other components
|
|
44
|
-
if (!justMounted.current) {
|
|
45
|
-
carouselRef.current?.focus({ preventScroll: true });
|
|
46
|
-
}
|
|
47
42
|
justMounted.current = false;
|
|
48
43
|
}, [userActiveIndex]);
|
|
49
44
|
const [slideCount, setSlideCount] = React.useState(0);
|
|
50
|
-
const [keysPressed, setKeysPressed] = React.useState({});
|
|
51
|
-
const handleKeyDown = (event) => {
|
|
52
|
-
if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) {
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
const key = event.key;
|
|
56
|
-
if (key === 'ArrowLeft' || key === 'ArrowRight') {
|
|
57
|
-
setKeysPressed((old) => ({ ...old, [key]: true }));
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
const handleKeyUp = (event) => {
|
|
61
|
-
switch (event.key) {
|
|
62
|
-
case 'ArrowLeft': {
|
|
63
|
-
setKeysPressed((old) => ({ ...old, ArrowLeft: false }));
|
|
64
|
-
const prevIndex = (slideCount + currentIndex - 1) % slideCount;
|
|
65
|
-
scrollToSlide.current(prevIndex);
|
|
66
|
-
setCurrentIndex(prevIndex);
|
|
67
|
-
break;
|
|
68
|
-
}
|
|
69
|
-
case 'ArrowRight': {
|
|
70
|
-
setKeysPressed((old) => ({ ...old, ArrowRight: false }));
|
|
71
|
-
const nextIndex = (slideCount + currentIndex + 1) % slideCount;
|
|
72
|
-
scrollToSlide.current(nextIndex);
|
|
73
|
-
setCurrentIndex(nextIndex);
|
|
74
|
-
break;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
};
|
|
78
45
|
const userOnSlideChange = useLatestRef(onSlideChange);
|
|
79
46
|
React.useEffect(() => {
|
|
80
47
|
userOnSlideChange.current?.(currentIndex);
|
|
@@ -84,9 +51,6 @@ const CarouselComponent = React.forwardRef((props, ref) => {
|
|
|
84
51
|
{
|
|
85
52
|
as: 'section',
|
|
86
53
|
'aria-roledescription': 'carousel',
|
|
87
|
-
tabIndex: 0,
|
|
88
|
-
onKeyDown: handleKeyDown,
|
|
89
|
-
onKeyUp: handleKeyUp,
|
|
90
54
|
ref: refs,
|
|
91
55
|
className: cx('iui-carousel', className),
|
|
92
56
|
...rest,
|
|
@@ -100,7 +64,6 @@ const CarouselComponent = React.forwardRef((props, ref) => {
|
|
|
100
64
|
setCurrentIndex,
|
|
101
65
|
slideCount,
|
|
102
66
|
setSlideCount,
|
|
103
|
-
keysPressed,
|
|
104
67
|
idPrefix: id,
|
|
105
68
|
isManuallyUpdating,
|
|
106
69
|
scrollToSlide,
|
|
@@ -112,7 +75,8 @@ const CarouselComponent = React.forwardRef((props, ref) => {
|
|
|
112
75
|
});
|
|
113
76
|
/**
|
|
114
77
|
* The Carousel component consists of a set of slides, normally displayed one at a time. A navigation section is
|
|
115
|
-
*
|
|
78
|
+
* shown below the slides, consisting of "dots" and "previous"/"next" buttons, used for changing slides; this navigation
|
|
79
|
+
* section must be present _before_ the slides in DOM order, even though it is visually shown below the slides.
|
|
116
80
|
*
|
|
117
81
|
* The currently shown slide can also be changed using the left/right arrow keys or by dragging on a touch device.
|
|
118
82
|
*
|
|
@@ -120,18 +84,24 @@ const CarouselComponent = React.forwardRef((props, ref) => {
|
|
|
120
84
|
*
|
|
121
85
|
* @example
|
|
122
86
|
* <Carousel>
|
|
87
|
+
* <Carousel.Navigation />
|
|
123
88
|
* <Carousel.Slider>
|
|
124
89
|
* <Carousel.Slide>...</Carousel.Slide>
|
|
125
90
|
* <Carousel.Slide>...</Carousel.Slide>
|
|
126
91
|
* <Carousel.Slide>...</Carousel.Slide>
|
|
127
92
|
* </Carousel.Slider>
|
|
128
|
-
* <Carousel.Navigation />
|
|
129
93
|
* </Carousel>
|
|
130
94
|
*/
|
|
131
95
|
export const Carousel = Object.assign(CarouselComponent, {
|
|
132
96
|
Slider: CarouselSlider,
|
|
133
97
|
Slide: CarouselSlide,
|
|
98
|
+
/**
|
|
99
|
+
* Contains the dots and previous/next buttons for navigating the slides. Must be present _before_ the slides in DOM.
|
|
100
|
+
*/
|
|
134
101
|
Navigation: CarouselNavigation,
|
|
102
|
+
/**
|
|
103
|
+
* Contains the dots for activating the slides. Must be present _before_ the slides in DOM.
|
|
104
|
+
*/
|
|
135
105
|
DotsList: CarouselDotsList,
|
|
136
106
|
Dot: CarouselDot,
|
|
137
107
|
});
|
|
@@ -16,10 +16,6 @@ export declare const CarouselContext: React.Context<{
|
|
|
16
16
|
* State updater for slideCount.
|
|
17
17
|
*/
|
|
18
18
|
setSlideCount: (length: number | ((old: number) => void)) => void;
|
|
19
|
-
/**
|
|
20
|
-
* Stateful value of the left/right arrow keys currently pressed.
|
|
21
|
-
*/
|
|
22
|
-
keysPressed: Record<string, boolean>;
|
|
23
19
|
/**
|
|
24
20
|
* Prefix used for setting id for internal carousel components.
|
|
25
21
|
*/
|
|
@@ -13,7 +13,7 @@ export const CarouselDot = React.forwardRef((props, ref) => {
|
|
|
13
13
|
const { isActive, isSmaller, isSmall, className, ...rest } = props;
|
|
14
14
|
return React.createElement(ButtonBase, {
|
|
15
15
|
role: 'tab',
|
|
16
|
-
tabIndex: -1,
|
|
16
|
+
tabIndex: isActive ? 0 : -1,
|
|
17
17
|
className: cx(
|
|
18
18
|
'iui-carousel-navigation-dot',
|
|
19
19
|
{
|
|
@@ -55,6 +55,7 @@ export const CarouselDotsList = React.forwardRef((props, ref) => {
|
|
|
55
55
|
context.setCurrentIndex(index);
|
|
56
56
|
context.scrollToSlide.current(index);
|
|
57
57
|
}
|
|
58
|
+
listRef.current?.children[index]?.focus();
|
|
58
59
|
onSlideChange?.(index);
|
|
59
60
|
},
|
|
60
61
|
[context, onSlideChange],
|
|
@@ -105,13 +106,12 @@ export const CarouselDotsList = React.forwardRef((props, ref) => {
|
|
|
105
106
|
index < firstVisibleDotIndex || index > lastVisibleDotIndex;
|
|
106
107
|
return React.createElement(CarouselDot, {
|
|
107
108
|
key: index,
|
|
108
|
-
'aria-label': `Slide ${index}`,
|
|
109
|
+
'aria-label': `Slide ${index + 1}`,
|
|
109
110
|
isActive: index === currentIndex,
|
|
110
111
|
onClick: () => handleSlideChange(index),
|
|
111
112
|
isSmall: isSecondSmallDot,
|
|
112
113
|
isSmaller: isFirstSmallDot || isClipped,
|
|
113
114
|
id: idPrefix && `${idPrefix}--dot-${index}`,
|
|
114
|
-
'aria-controls': idPrefix && `${idPrefix}--slide-${index}`,
|
|
115
115
|
});
|
|
116
116
|
});
|
|
117
117
|
}, [
|
|
@@ -138,6 +138,27 @@ export const CarouselDotsList = React.forwardRef((props, ref) => {
|
|
|
138
138
|
justMounted.current = false;
|
|
139
139
|
}
|
|
140
140
|
}, [currentIndex, firstVisibleDotIndex, slideCount, visibleCount, width]);
|
|
141
|
+
const handleKeyDown = (event) => {
|
|
142
|
+
if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
const key = event.key;
|
|
146
|
+
if (key === 'ArrowLeft' || key === 'ArrowRight') {
|
|
147
|
+
event.preventDefault();
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
const handleKeyUp = (event) => {
|
|
151
|
+
switch (event.key) {
|
|
152
|
+
case 'ArrowLeft': {
|
|
153
|
+
handleSlideChange((slideCount + currentIndex - 1) % slideCount);
|
|
154
|
+
break;
|
|
155
|
+
}
|
|
156
|
+
case 'ArrowRight': {
|
|
157
|
+
handleSlideChange((slideCount + currentIndex + 1) % slideCount);
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
};
|
|
141
162
|
return React.createElement(
|
|
142
163
|
React.Fragment,
|
|
143
164
|
null,
|
|
@@ -148,6 +169,9 @@ export const CarouselDotsList = React.forwardRef((props, ref) => {
|
|
|
148
169
|
role: 'tablist',
|
|
149
170
|
'aria-label': 'Slides',
|
|
150
171
|
ref: refs,
|
|
172
|
+
onKeyDown: handleKeyDown,
|
|
173
|
+
onKeyUp: handleKeyUp,
|
|
174
|
+
tabIndex: -1,
|
|
151
175
|
...rest,
|
|
152
176
|
},
|
|
153
177
|
children ?? dots,
|
|
@@ -6,7 +6,7 @@ import type { PolymorphicForwardRefComponent } from '../utils/index.js';
|
|
|
6
6
|
*
|
|
7
7
|
* `children` can be specified to override what is shown in this navigation section.
|
|
8
8
|
*/
|
|
9
|
-
export declare const CarouselNavigation: PolymorphicForwardRefComponent<"
|
|
9
|
+
export declare const CarouselNavigation: PolymorphicForwardRefComponent<"div", {}> & {
|
|
10
10
|
PreviousButton: PolymorphicForwardRefComponent<"button", Omit<Omit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & {
|
|
11
11
|
ref?: ((instance: HTMLButtonElement | null) => void) | React.RefObject<HTMLButtonElement> | null | undefined;
|
|
12
12
|
}, "label" | "as" | "size" | "htmlDisabled" | "styleType" | "isActive" | "iconProps"> & {
|
|
@@ -12,12 +12,7 @@ const CarouselNavigationComponent = React.forwardRef((props, ref) => {
|
|
|
12
12
|
const { className, children, ...rest } = props;
|
|
13
13
|
return React.createElement(
|
|
14
14
|
Box,
|
|
15
|
-
{
|
|
16
|
-
as: 'nav',
|
|
17
|
-
className: cx('iui-carousel-navigation', className),
|
|
18
|
-
ref: ref,
|
|
19
|
-
...rest,
|
|
20
|
-
},
|
|
15
|
+
{ className: cx('iui-carousel-navigation', className), ref: ref, ...rest },
|
|
21
16
|
children ??
|
|
22
17
|
React.createElement(
|
|
23
18
|
React.Fragment,
|
|
@@ -42,20 +37,14 @@ const PreviousButton = React.forwardRef((props, ref) => {
|
|
|
42
37
|
if (!context) {
|
|
43
38
|
throw new Error('CarouselNavigation should be used inside Carousel');
|
|
44
39
|
}
|
|
45
|
-
const {
|
|
46
|
-
slideCount,
|
|
47
|
-
currentIndex,
|
|
48
|
-
setCurrentIndex,
|
|
49
|
-
keysPressed,
|
|
50
|
-
scrollToSlide,
|
|
51
|
-
} = context;
|
|
40
|
+
const { slideCount, currentIndex, setCurrentIndex, scrollToSlide } = context;
|
|
52
41
|
return React.createElement(
|
|
53
42
|
IconButton,
|
|
54
43
|
{
|
|
55
44
|
styleType: 'borderless',
|
|
56
45
|
size: 'small',
|
|
57
46
|
tabIndex: -1,
|
|
58
|
-
'
|
|
47
|
+
'aria-label': 'Previous',
|
|
59
48
|
ref: ref,
|
|
60
49
|
...props,
|
|
61
50
|
onClick: (e) => {
|
|
@@ -74,20 +63,14 @@ const NextButton = React.forwardRef((props, ref) => {
|
|
|
74
63
|
if (!context) {
|
|
75
64
|
throw new Error('CarouselNavigation should be used inside Carousel');
|
|
76
65
|
}
|
|
77
|
-
const {
|
|
78
|
-
slideCount,
|
|
79
|
-
currentIndex,
|
|
80
|
-
setCurrentIndex,
|
|
81
|
-
keysPressed,
|
|
82
|
-
scrollToSlide,
|
|
83
|
-
} = context;
|
|
66
|
+
const { slideCount, currentIndex, setCurrentIndex, scrollToSlide } = context;
|
|
84
67
|
return React.createElement(
|
|
85
68
|
IconButton,
|
|
86
69
|
{
|
|
87
70
|
styleType: 'borderless',
|
|
88
71
|
size: 'small',
|
|
89
72
|
tabIndex: -1,
|
|
90
|
-
'
|
|
73
|
+
'aria-label': 'Next',
|
|
91
74
|
ref: ref,
|
|
92
75
|
...props,
|
|
93
76
|
onClick: (e) => {
|
|
@@ -12,5 +12,5 @@ type CarouselSlideProps = {
|
|
|
12
12
|
* It is recommended that the slide content bring its own dimensions (esp. height) and that
|
|
13
13
|
* the dimensions should be the same for all slides.
|
|
14
14
|
*/
|
|
15
|
-
export declare const CarouselSlide: PolymorphicForwardRefComponent<"
|
|
15
|
+
export declare const CarouselSlide: PolymorphicForwardRefComponent<"div", CarouselSlideProps>;
|
|
16
16
|
export {};
|
|
@@ -4,7 +4,12 @@
|
|
|
4
4
|
*--------------------------------------------------------------------------------------------*/
|
|
5
5
|
import * as React from 'react';
|
|
6
6
|
import cx from 'classnames';
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
Box,
|
|
9
|
+
mergeEventHandlers,
|
|
10
|
+
useIntersection,
|
|
11
|
+
useMergedRefs,
|
|
12
|
+
} from '../utils/index.js';
|
|
8
13
|
import { CarouselContext } from './CarouselContext.js';
|
|
9
14
|
/**
|
|
10
15
|
* `CarouselSlide` is used for the actual slide content. The content can be specified through `children`.
|
|
@@ -18,7 +23,7 @@ export const CarouselSlide = React.forwardRef((props, ref) => {
|
|
|
18
23
|
if (!context || index == null) {
|
|
19
24
|
throw new Error('CarouselSlide must be used within Carousel');
|
|
20
25
|
}
|
|
21
|
-
const { isManuallyUpdating, setCurrentIndex } = context;
|
|
26
|
+
const { isManuallyUpdating, currentIndex, setCurrentIndex } = context;
|
|
22
27
|
const updateActiveIndexOnScroll = React.useCallback(() => {
|
|
23
28
|
// only update index if scroll was triggered by browser
|
|
24
29
|
if (!isManuallyUpdating.current) {
|
|
@@ -34,12 +39,19 @@ export const CarouselSlide = React.forwardRef((props, ref) => {
|
|
|
34
39
|
return React.createElement(
|
|
35
40
|
Box,
|
|
36
41
|
{
|
|
37
|
-
as: 'li',
|
|
38
42
|
className: cx('iui-carousel-slider-item', className),
|
|
39
43
|
role: 'tabpanel',
|
|
40
44
|
'aria-roledescription': 'slide',
|
|
45
|
+
tabIndex: index === currentIndex ? 0 : undefined,
|
|
41
46
|
ref: refs,
|
|
47
|
+
inert: index !== currentIndex ? '' : undefined,
|
|
42
48
|
...rest,
|
|
49
|
+
onKeyDown: mergeEventHandlers(props.onKeyDown, (event) => {
|
|
50
|
+
// prevent default browser scrolling on arrow keys because focus will get lost when slide switches
|
|
51
|
+
if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') {
|
|
52
|
+
event.preventDefault();
|
|
53
|
+
}
|
|
54
|
+
}),
|
|
43
55
|
},
|
|
44
56
|
children,
|
|
45
57
|
);
|
|
@@ -2,4 +2,4 @@ import type { PolymorphicForwardRefComponent } from '../utils/index.js';
|
|
|
2
2
|
/**
|
|
3
3
|
* `CarouselSlider` is the scrollable list that should consist of `CarouselSlide` components.
|
|
4
4
|
*/
|
|
5
|
-
export declare const CarouselSlider: PolymorphicForwardRefComponent<"
|
|
5
|
+
export declare const CarouselSlider: PolymorphicForwardRefComponent<"div", {}>;
|
|
@@ -28,6 +28,7 @@ export const CarouselSlider = React.forwardRef((props, ref) => {
|
|
|
28
28
|
React.isValidElement(child)
|
|
29
29
|
? React.cloneElement(child, {
|
|
30
30
|
id: `${idPrefix}--slide-${index}`,
|
|
31
|
+
'aria-labelledby': `${idPrefix}--dot-${index}`,
|
|
31
32
|
index,
|
|
32
33
|
})
|
|
33
34
|
: child,
|
|
@@ -66,11 +67,10 @@ export const CarouselSlider = React.forwardRef((props, ref) => {
|
|
|
66
67
|
return React.createElement(
|
|
67
68
|
Box,
|
|
68
69
|
{
|
|
69
|
-
as: 'ol',
|
|
70
|
-
'aria-live': 'polite',
|
|
71
70
|
className: cx('iui-carousel-slider', className),
|
|
72
71
|
ref: refs,
|
|
73
72
|
onScroll: handleOnScroll,
|
|
73
|
+
tabIndex: -1,
|
|
74
74
|
...rest,
|
|
75
75
|
},
|
|
76
76
|
items,
|
|
@@ -65,9 +65,9 @@ export type SliderProps = {
|
|
|
65
65
|
*/
|
|
66
66
|
maxLabel?: React.ReactNode;
|
|
67
67
|
/**
|
|
68
|
-
* Additional props for container `<div>` that hold the slider
|
|
68
|
+
* Additional props for container `<div>` that hold the slider thumbs, and tracks.
|
|
69
69
|
*/
|
|
70
|
-
|
|
70
|
+
trackContainerProps?: React.HTMLAttributes<HTMLDivElement>;
|
|
71
71
|
/**
|
|
72
72
|
* Allows props to be passed for slider-min
|
|
73
73
|
*/
|
|
@@ -76,10 +76,6 @@ export type SliderProps = {
|
|
|
76
76
|
* Allows props to be passed for slider-max
|
|
77
77
|
*/
|
|
78
78
|
maxProps?: React.ComponentProps<'span'>;
|
|
79
|
-
/**
|
|
80
|
-
* Allows props to be passed for slider-rail
|
|
81
|
-
*/
|
|
82
|
-
railProps?: React.ComponentProps<'div'>;
|
|
83
79
|
/**
|
|
84
80
|
* Allows props to be passed for slider-track
|
|
85
81
|
*/
|
|
@@ -78,10 +78,9 @@ export const Slider = React.forwardRef((props, ref) => {
|
|
|
78
78
|
onUpdate,
|
|
79
79
|
thumbProps,
|
|
80
80
|
className,
|
|
81
|
-
|
|
81
|
+
trackContainerProps,
|
|
82
82
|
minProps,
|
|
83
83
|
maxProps,
|
|
84
|
-
railProps,
|
|
85
84
|
trackProps,
|
|
86
85
|
tickProps,
|
|
87
86
|
ticksProps,
|
|
@@ -306,12 +305,9 @@ export const Slider = React.forwardRef((props, ref) => {
|
|
|
306
305
|
Box,
|
|
307
306
|
{
|
|
308
307
|
ref: ref,
|
|
309
|
-
className: cx(
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
{ 'iui-disabled': disabled },
|
|
313
|
-
className,
|
|
314
|
-
),
|
|
308
|
+
className: cx('iui-slider-container', className),
|
|
309
|
+
'data-iui-orientation': orientation,
|
|
310
|
+
'data-iui-disabled': disabled ? 'true' : undefined,
|
|
315
311
|
...rest,
|
|
316
312
|
},
|
|
317
313
|
minValueLabel &&
|
|
@@ -327,23 +323,17 @@ export const Slider = React.forwardRef((props, ref) => {
|
|
|
327
323
|
React.createElement(
|
|
328
324
|
Box,
|
|
329
325
|
{
|
|
330
|
-
as: 'div',
|
|
331
326
|
ref: containerRef,
|
|
332
|
-
...
|
|
327
|
+
...trackContainerProps,
|
|
333
328
|
className: cx(
|
|
334
|
-
'iui-slider
|
|
329
|
+
'iui-slider',
|
|
335
330
|
{
|
|
336
331
|
'iui-grabbing': undefined !== activeThumbIndex,
|
|
337
332
|
},
|
|
338
|
-
|
|
333
|
+
trackContainerProps?.className,
|
|
339
334
|
),
|
|
340
335
|
onPointerDown: handlePointerDownOnSlider,
|
|
341
336
|
},
|
|
342
|
-
React.createElement(Box, {
|
|
343
|
-
as: 'div',
|
|
344
|
-
...railProps,
|
|
345
|
-
className: cx('iui-slider-rail', railProps?.className),
|
|
346
|
-
}),
|
|
347
337
|
currentValues.map((thumbValue, index) => {
|
|
348
338
|
const [minVal, maxVal] = getAllowableThumbRange(index);
|
|
349
339
|
const thisThumbProps = thumbProps?.(index);
|
|
@@ -362,7 +352,6 @@ export const Slider = React.forwardRef((props, ref) => {
|
|
|
362
352
|
step: step,
|
|
363
353
|
sliderMin: min,
|
|
364
354
|
sliderMax: max,
|
|
365
|
-
orientation: orientation,
|
|
366
355
|
});
|
|
367
356
|
}),
|
|
368
357
|
React.createElement(Track, {
|
|
@@ -373,8 +362,8 @@ export const Slider = React.forwardRef((props, ref) => {
|
|
|
373
362
|
orientation: orientation,
|
|
374
363
|
...trackProps,
|
|
375
364
|
}),
|
|
376
|
-
tickMarkArea,
|
|
377
365
|
),
|
|
366
|
+
tickMarkArea,
|
|
378
367
|
maxValueLabel &&
|
|
379
368
|
React.createElement(
|
|
380
369
|
Box,
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { Tooltip } from '../Tooltip/Tooltip.js';
|
|
3
|
-
import type { SliderProps } from './Slider.js';
|
|
4
3
|
type ThumbProps = {
|
|
5
4
|
/**
|
|
6
5
|
* Thumb value.
|
|
@@ -54,7 +53,7 @@ type ThumbProps = {
|
|
|
54
53
|
* Additional props for Thumb.
|
|
55
54
|
*/
|
|
56
55
|
thumbProps?: React.HTMLAttributes<HTMLDivElement>;
|
|
57
|
-
}
|
|
56
|
+
};
|
|
58
57
|
/**
|
|
59
58
|
* Thumb is a local component used to show and modify the values maintained by the Slider.
|
|
60
59
|
* Only one Thumb can be active at a time. A Thumb is made active when the user selects
|
package/esm/core/Slider/Thumb.js
CHANGED
|
@@ -26,7 +26,6 @@ export const Thumb = (props) => {
|
|
|
26
26
|
tooltipProps,
|
|
27
27
|
thumbProps,
|
|
28
28
|
disabled,
|
|
29
|
-
orientation,
|
|
30
29
|
} = props;
|
|
31
30
|
const thumbRef = React.useRef(null);
|
|
32
31
|
const handleOnKeyboardEvent = React.useCallback(
|
|
@@ -93,13 +92,10 @@ export const Thumb = (props) => {
|
|
|
93
92
|
},
|
|
94
93
|
React.createElement(Box, {
|
|
95
94
|
...rest,
|
|
96
|
-
'data-index': index,
|
|
97
95
|
ref: thumbRef,
|
|
98
96
|
style: {
|
|
99
97
|
...style,
|
|
100
|
-
|
|
101
|
-
? { insetInlineStart: `${lowPercent}%` }
|
|
102
|
-
: { insetBlockEnd: `${lowPercent}%` }),
|
|
98
|
+
'--iui-slider-thumb-position': `${lowPercent}%`,
|
|
103
99
|
},
|
|
104
100
|
className: cx('iui-slider-thumb', { 'iui-active': isActive }, className),
|
|
105
101
|
role: 'slider',
|
package/esm/core/Tabs/Tabs.js
CHANGED
|
@@ -16,12 +16,9 @@ import {
|
|
|
16
16
|
mergeEventHandlers,
|
|
17
17
|
useControlledState,
|
|
18
18
|
useId,
|
|
19
|
-
|
|
19
|
+
useLatestRef,
|
|
20
20
|
} from '../utils/index.js';
|
|
21
21
|
import { Icon } from '../Icon/Icon.js';
|
|
22
|
-
// Checking user motion preference for scroll into view animation
|
|
23
|
-
const isMotionOk = () =>
|
|
24
|
-
getWindow()?.matchMedia?.('(prefers-reduced-motion: no-preference)')?.matches;
|
|
25
22
|
const TabsWrapper = React.forwardRef((props, ref) => {
|
|
26
23
|
const {
|
|
27
24
|
className,
|
|
@@ -123,21 +120,19 @@ const Tab = React.forwardRef((props, forwardedRef) => {
|
|
|
123
120
|
const { tabsWidth } = useSafeContext(TabListContext);
|
|
124
121
|
const tabRef = React.useRef();
|
|
125
122
|
const isActive = activeValue === value;
|
|
123
|
+
const isActiveRef = useLatestRef(isActive);
|
|
124
|
+
// Scroll to active tab only on initial render
|
|
126
125
|
useIsomorphicLayoutEffect(() => {
|
|
127
|
-
if (
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
block: 'center',
|
|
136
|
-
behavior: isMotionOk() ? 'smooth' : 'auto',
|
|
137
|
-
});
|
|
138
|
-
}
|
|
126
|
+
if (isActiveRef.current) {
|
|
127
|
+
tabRef.current?.parentElement?.scrollTo({
|
|
128
|
+
[orientation === 'horizontal' ? 'left' : 'top']:
|
|
129
|
+
tabRef.current?.[
|
|
130
|
+
orientation === 'horizontal' ? 'offsetLeft' : 'offsetTop'
|
|
131
|
+
] - 4,
|
|
132
|
+
behavior: 'instant', // not using 'smooth' to reduce layout shift on page load
|
|
133
|
+
});
|
|
139
134
|
}
|
|
140
|
-
}, [
|
|
135
|
+
}, []);
|
|
141
136
|
const updateStripe = () => {
|
|
142
137
|
const currentTabRect = tabRef.current?.getBoundingClientRect();
|
|
143
138
|
setStripeProperties({
|
|
@@ -231,6 +226,7 @@ const Tab = React.forwardRef((props, forwardedRef) => {
|
|
|
231
226
|
onClick: mergeEventHandlers(props.onClick, () => setActiveValue(value)),
|
|
232
227
|
onKeyDown: mergeEventHandlers(props.onKeyDown, onKeyDown),
|
|
233
228
|
onFocus: mergeEventHandlers(props.onFocus, () => {
|
|
229
|
+
tabRef.current?.scrollIntoView({ block: 'nearest', inline: 'nearest' });
|
|
234
230
|
if (focusActivationMode === 'auto' && !props.disabled) {
|
|
235
231
|
setActiveValue(value);
|
|
236
232
|
}
|
package/esm/core/Tile/Tile.js
CHANGED
|
@@ -308,16 +308,17 @@ const TileComponent = React.forwardRef((props, forwardedRef) => {
|
|
|
308
308
|
: name,
|
|
309
309
|
),
|
|
310
310
|
),
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
311
|
+
thumbnail &&
|
|
312
|
+
React.createElement(
|
|
313
|
+
TileThumbnailArea,
|
|
314
|
+
null,
|
|
315
|
+
typeof thumbnail !== 'string'
|
|
316
|
+
? React.createElement(TileThumbnailPicture, null, thumbnail)
|
|
317
|
+
: React.createElement(TileThumbnailPicture, { url: thumbnail }),
|
|
318
|
+
badge && React.createElement(TileBadgeContainer, null, badge),
|
|
319
|
+
leftIcon && React.createElement(TileTypeIndicator, null, leftIcon),
|
|
320
|
+
rightIcon && React.createElement(TileQuickAction, null, rightIcon),
|
|
321
|
+
),
|
|
321
322
|
React.createElement(
|
|
322
323
|
TileContentArea,
|
|
323
324
|
null,
|
|
@@ -68,7 +68,9 @@ export const useOverflow = (
|
|
|
68
68
|
if (availableSize < requiredSize) {
|
|
69
69
|
const avgItemSize = requiredSize / visibleCount;
|
|
70
70
|
const visibleItems = Math.floor(availableSize / avgItemSize);
|
|
71
|
-
|
|
71
|
+
/* When first item is larger than the container - visibleItems count is 0,
|
|
72
|
+
We can assume that at least some part of the first item is visible and return 1. */
|
|
73
|
+
setVisibleCount(visibleItems > 0 ? visibleItems : 1);
|
|
72
74
|
} else if (needsFullRerender.current) {
|
|
73
75
|
const childrenSize = Array.from(containerRef.current.children).reduce(
|
|
74
76
|
(sum, child) => sum + child[`offset${dimension}`],
|