@itwin/itwinui-react 3.0.0-dev.12 → 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 +43 -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/ColorPicker/ColorBuilder.js +2 -0
- package/cjs/core/ColorPicker/ColorInputPanel.js +24 -4
- package/cjs/core/ColorPicker/ColorPalette.js +2 -80
- package/cjs/core/ColorPicker/ColorSwatch.d.ts +1 -1
- package/cjs/core/ColorPicker/ColorSwatch.js +25 -15
- package/cjs/core/LabeledSelect/LabeledSelect.d.ts +1 -1
- package/cjs/core/LabeledSelect/LabeledSelect.js +3 -3
- package/cjs/core/Select/Select.d.ts +1 -1
- package/cjs/core/Select/Select.js +6 -4
- 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.d.ts +222 -52
- package/cjs/core/Tabs/Tabs.js +429 -375
- package/cjs/core/ThemeProvider/ThemeProvider.js +3 -1
- package/cjs/core/Tile/Tile.js +11 -10
- package/cjs/core/utils/hooks/useOverflow.js +3 -1
- package/cjs/index.d.ts +1 -2
- package/cjs/index.js +1 -2
- package/cjs/styles.js +10 -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/ColorPicker/ColorBuilder.js +2 -0
- package/esm/core/ColorPicker/ColorInputPanel.js +25 -5
- package/esm/core/ColorPicker/ColorPalette.js +3 -83
- package/esm/core/ColorPicker/ColorSwatch.d.ts +1 -1
- package/esm/core/ColorPicker/ColorSwatch.js +18 -12
- package/esm/core/LabeledSelect/LabeledSelect.d.ts +1 -1
- package/esm/core/LabeledSelect/LabeledSelect.js +3 -2
- package/esm/core/Select/Select.d.ts +1 -1
- package/esm/core/Select/Select.js +3 -3
- 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.d.ts +222 -52
- package/esm/core/Tabs/Tabs.js +424 -368
- package/esm/core/ThemeProvider/ThemeProvider.js +3 -1
- package/esm/core/Tile/Tile.js +11 -10
- package/esm/core/utils/hooks/useOverflow.js +3 -1
- package/esm/index.d.ts +1 -2
- package/esm/index.js +1 -2
- package/esm/styles.js +10 -10
- package/package.json +2 -2
- package/styles.css +33 -47
- package/cjs/core/Tabs/Tab.d.ts +0 -40
- package/cjs/core/Tabs/Tab.js +0 -65
- package/esm/core/Tabs/Tab.d.ts +0 -40
- package/esm/core/Tabs/Tab.js +0 -57
|
@@ -55,7 +55,9 @@ exports.ThemeProvider = React.forwardRef((props, forwardedRef) => {
|
|
|
55
55
|
const shouldApplyBackground = themeOptions?.applyBackground ?? !parentTheme;
|
|
56
56
|
const contextValue = React.useMemo(
|
|
57
57
|
() => ({ theme, themeOptions, portalContainer }),
|
|
58
|
-
|
|
58
|
+
// we do include all dependencies below, but we want to stringify the objects as they could be different on each render
|
|
59
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
60
|
+
[theme, JSON.stringify(themeOptions), portalContainer],
|
|
59
61
|
);
|
|
60
62
|
return React.createElement(
|
|
61
63
|
ThemeContext_js_1.ThemeContext.Provider,
|
package/cjs/core/Tile/Tile.js
CHANGED
|
@@ -324,16 +324,17 @@ const TileComponent = React.forwardRef((props, forwardedRef) => {
|
|
|
324
324
|
: name,
|
|
325
325
|
),
|
|
326
326
|
),
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
327
|
+
thumbnail &&
|
|
328
|
+
React.createElement(
|
|
329
|
+
TileThumbnailArea,
|
|
330
|
+
null,
|
|
331
|
+
typeof thumbnail !== 'string'
|
|
332
|
+
? React.createElement(TileThumbnailPicture, null, thumbnail)
|
|
333
|
+
: React.createElement(TileThumbnailPicture, { url: thumbnail }),
|
|
334
|
+
badge && React.createElement(TileBadgeContainer, null, badge),
|
|
335
|
+
leftIcon && React.createElement(TileTypeIndicator, null, leftIcon),
|
|
336
|
+
rightIcon && React.createElement(TileQuickAction, null, rightIcon),
|
|
337
|
+
),
|
|
337
338
|
React.createElement(
|
|
338
339
|
TileContentArea,
|
|
339
340
|
null,
|
|
@@ -73,7 +73,9 @@ const useOverflow = (items, disabled = false, orientation = 'horizontal') => {
|
|
|
73
73
|
if (availableSize < requiredSize) {
|
|
74
74
|
const avgItemSize = requiredSize / visibleCount;
|
|
75
75
|
const visibleItems = Math.floor(availableSize / avgItemSize);
|
|
76
|
-
|
|
76
|
+
/* When first item is larger than the container - visibleItems count is 0,
|
|
77
|
+
We can assume that at least some part of the first item is visible and return 1. */
|
|
78
|
+
setVisibleCount(visibleItems > 0 ? visibleItems : 1);
|
|
77
79
|
} else if (needsFullRerender.current) {
|
|
78
80
|
const childrenSize = Array.from(containerRef.current.children).reduce(
|
|
79
81
|
(sum, child) => sum + child[`offset${dimension}`],
|
package/cjs/index.d.ts
CHANGED
|
@@ -39,8 +39,7 @@ export { HeaderLogo } from './core/Header/HeaderLogo.js';
|
|
|
39
39
|
export { List } from './core/List/List.js';
|
|
40
40
|
export { ListItem } from './core/List/ListItem.js';
|
|
41
41
|
export { TransferList } from './core/TransferList/TransferList.js';
|
|
42
|
-
export { Tabs } from './core/Tabs/Tabs.js';
|
|
43
|
-
export { Tab } from './core/Tabs/Tab.js';
|
|
42
|
+
export { Tabs, Tab } from './core/Tabs/Tabs.js';
|
|
44
43
|
export { InformationPanel } from './core/InformationPanel/InformationPanel.js';
|
|
45
44
|
export { InformationPanelWrapper } from './core/InformationPanel/InformationPanelWrapper.js';
|
|
46
45
|
export { InformationPanelHeader } from './core/InformationPanel/InformationPanelHeader.js';
|
package/cjs/index.js
CHANGED
|
@@ -420,11 +420,10 @@ Object.defineProperty(exports, 'Tabs', {
|
|
|
420
420
|
return Tabs_js_1.Tabs;
|
|
421
421
|
},
|
|
422
422
|
});
|
|
423
|
-
var Tab_js_1 = require('./core/Tabs/Tab.js');
|
|
424
423
|
Object.defineProperty(exports, 'Tab', {
|
|
425
424
|
enumerable: true,
|
|
426
425
|
get: function () {
|
|
427
|
-
return
|
|
426
|
+
return Tabs_js_1.Tab;
|
|
428
427
|
},
|
|
429
428
|
});
|
|
430
429
|
var InformationPanel_js_1 = require('./core/InformationPanel/InformationPanel.js');
|
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',
|
|
@@ -326,9 +324,11 @@ const styles = {
|
|
|
326
324
|
'iui-tabs-wrapper': '_iui3-tabs-wrapper',
|
|
327
325
|
'iui-horizontal': '_iui3-horizontal',
|
|
328
326
|
'iui-tabs': '_iui3-tabs',
|
|
327
|
+
'scroll-shadow-inset-horizontal': '_iui3-scroll-shadow-inset-horizontal',
|
|
329
328
|
'iui-borderless': '_iui3-borderless',
|
|
330
329
|
'iui-tab': '_iui3-tab',
|
|
331
330
|
'iui-vertical': '_iui3-vertical',
|
|
331
|
+
'scroll-shadow-inset-vertical': '_iui3-scroll-shadow-inset-vertical',
|
|
332
332
|
'iui-tabs-content': '_iui3-tabs-content',
|
|
333
333
|
'iui-tabs-actions-wrapper': '_iui3-tabs-actions-wrapper',
|
|
334
334
|
'iui-default': '_iui3-default',
|
|
@@ -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,
|
|
@@ -273,6 +273,7 @@ export const ColorBuilder = React.forwardRef((props, ref) => {
|
|
|
273
273
|
},
|
|
274
274
|
min: 0,
|
|
275
275
|
max: 359,
|
|
276
|
+
thumbProps: () => ({ 'aria-label': 'Hue' }),
|
|
276
277
|
}),
|
|
277
278
|
showAlpha &&
|
|
278
279
|
React.createElement(Slider, {
|
|
@@ -294,6 +295,7 @@ export const ColorBuilder = React.forwardRef((props, ref) => {
|
|
|
294
295
|
style: {
|
|
295
296
|
'--iui-color-picker-selected-color': hueColorString,
|
|
296
297
|
},
|
|
298
|
+
thumbProps: () => ({ 'aria-label': 'Opacity' }),
|
|
297
299
|
}),
|
|
298
300
|
);
|
|
299
301
|
});
|
|
@@ -6,7 +6,7 @@ import * as React from 'react';
|
|
|
6
6
|
import cx from 'classnames';
|
|
7
7
|
import { IconButton } from '../Buttons/IconButton.js';
|
|
8
8
|
import { Input } from '../Input/Input.js';
|
|
9
|
-
import { ColorValue, SvgSwap, Box } from '../utils/index.js';
|
|
9
|
+
import { ColorValue, SvgSwap, Box, useId } from '../utils/index.js';
|
|
10
10
|
import { useColorPickerContext } from './ColorPickerContext.js';
|
|
11
11
|
/**
|
|
12
12
|
* `ColorInputPanel` shows input fields to enter precise color values in the specified format.
|
|
@@ -140,6 +140,7 @@ export const ColorInputPanel = React.forwardRef((props, ref) => {
|
|
|
140
140
|
maxLength: showAlpha ? 9 : 7,
|
|
141
141
|
minLength: 1,
|
|
142
142
|
placeholder: 'HEX',
|
|
143
|
+
'aria-label': 'Hex',
|
|
143
144
|
value: input[0],
|
|
144
145
|
onChange: (event) => {
|
|
145
146
|
const value = event.target.value.startsWith('#')
|
|
@@ -169,6 +170,7 @@ export const ColorInputPanel = React.forwardRef((props, ref) => {
|
|
|
169
170
|
max: '359',
|
|
170
171
|
step: '.1',
|
|
171
172
|
placeholder: 'H',
|
|
173
|
+
'aria-label': 'Hue',
|
|
172
174
|
value: input[0] ?? '',
|
|
173
175
|
onChange: (event) => {
|
|
174
176
|
setInput([event.target.value, input[1], input[2], input[3]]);
|
|
@@ -195,6 +197,7 @@ export const ColorInputPanel = React.forwardRef((props, ref) => {
|
|
|
195
197
|
max: '100',
|
|
196
198
|
step: '.1',
|
|
197
199
|
placeholder: 'S',
|
|
200
|
+
'aria-label': 'Saturation',
|
|
198
201
|
value: input[1] ?? '',
|
|
199
202
|
onChange: (event) => {
|
|
200
203
|
setInput([input[0], event.target.value, input[2], input[3]]);
|
|
@@ -221,6 +224,7 @@ export const ColorInputPanel = React.forwardRef((props, ref) => {
|
|
|
221
224
|
max: '100',
|
|
222
225
|
step: '.1',
|
|
223
226
|
placeholder: 'L',
|
|
227
|
+
'aria-label': 'Lightness',
|
|
224
228
|
value: input[2] ?? '',
|
|
225
229
|
onChange: (event) => {
|
|
226
230
|
setInput([input[0], input[1], event.target.value, input[3]]);
|
|
@@ -248,6 +252,7 @@ export const ColorInputPanel = React.forwardRef((props, ref) => {
|
|
|
248
252
|
max: '1',
|
|
249
253
|
step: '.01',
|
|
250
254
|
placeholder: 'A',
|
|
255
|
+
'aria-label': 'Alpha',
|
|
251
256
|
value: input[3] ?? '',
|
|
252
257
|
onChange: (event) => {
|
|
253
258
|
setInput([input[0], input[1], input[2], event.target.value]);
|
|
@@ -277,6 +282,7 @@ export const ColorInputPanel = React.forwardRef((props, ref) => {
|
|
|
277
282
|
min: '0',
|
|
278
283
|
max: '255',
|
|
279
284
|
placeholder: 'R',
|
|
285
|
+
'aria-label': 'Red',
|
|
280
286
|
value: input[0] ?? '',
|
|
281
287
|
onChange: (event) => {
|
|
282
288
|
setInput([event.target.value, input[1], input[2], input[3]]);
|
|
@@ -302,6 +308,7 @@ export const ColorInputPanel = React.forwardRef((props, ref) => {
|
|
|
302
308
|
min: '0',
|
|
303
309
|
max: '255',
|
|
304
310
|
placeholder: 'G',
|
|
311
|
+
'aria-label': 'Green',
|
|
305
312
|
value: input[1] ?? '',
|
|
306
313
|
onChange: (event) => {
|
|
307
314
|
setInput([input[0], event.target.value, input[2], input[3]]);
|
|
@@ -327,6 +334,7 @@ export const ColorInputPanel = React.forwardRef((props, ref) => {
|
|
|
327
334
|
min: '0',
|
|
328
335
|
max: '255',
|
|
329
336
|
placeholder: 'B',
|
|
337
|
+
'aria-label': 'Blue',
|
|
330
338
|
value: input[2] ?? '',
|
|
331
339
|
onChange: (event) => {
|
|
332
340
|
setInput([input[0], input[1], event.target.value, input[3]]);
|
|
@@ -354,6 +362,7 @@ export const ColorInputPanel = React.forwardRef((props, ref) => {
|
|
|
354
362
|
max: '1',
|
|
355
363
|
step: '.01',
|
|
356
364
|
placeholder: 'A',
|
|
365
|
+
'aria-label': 'Alpha',
|
|
357
366
|
value: input[3] ?? '',
|
|
358
367
|
onChange: (event) => {
|
|
359
368
|
setInput([input[0], input[1], input[2], event.target.value]);
|
|
@@ -374,13 +383,14 @@ export const ColorInputPanel = React.forwardRef((props, ref) => {
|
|
|
374
383
|
Number(input[3]) < 0 || Number(input[3]) > 1 ? 'negative' : undefined,
|
|
375
384
|
}),
|
|
376
385
|
);
|
|
386
|
+
const labelId = useId();
|
|
377
387
|
return React.createElement(
|
|
378
388
|
Box,
|
|
379
389
|
{ className: cx('iui-color-input-wrapper', className), ref: ref, ...rest },
|
|
380
390
|
React.createElement(
|
|
381
391
|
Box,
|
|
382
|
-
{ className: 'iui-color-picker-section-label' },
|
|
383
|
-
showAlpha && currentFormat
|
|
392
|
+
{ className: 'iui-color-picker-section-label', id: labelId },
|
|
393
|
+
showAlpha && currentFormat !== 'hex'
|
|
384
394
|
? currentFormat.toUpperCase() + 'A'
|
|
385
395
|
: currentFormat.toUpperCase(),
|
|
386
396
|
),
|
|
@@ -390,12 +400,22 @@ export const ColorInputPanel = React.forwardRef((props, ref) => {
|
|
|
390
400
|
allowedColorFormats.length > 1 &&
|
|
391
401
|
React.createElement(
|
|
392
402
|
IconButton,
|
|
393
|
-
{
|
|
403
|
+
{
|
|
404
|
+
styleType: 'borderless',
|
|
405
|
+
onClick: swapColorFormat,
|
|
406
|
+
size: 'small',
|
|
407
|
+
label: 'Switch format',
|
|
408
|
+
},
|
|
394
409
|
React.createElement(SvgSwap, null),
|
|
395
410
|
),
|
|
396
411
|
React.createElement(
|
|
397
412
|
Box,
|
|
398
|
-
{
|
|
413
|
+
{
|
|
414
|
+
ref: inputsContainerRef,
|
|
415
|
+
className: 'iui-color-input-fields',
|
|
416
|
+
role: currentFormat !== 'hex' ? 'group' : undefined,
|
|
417
|
+
'aria-labelledby': currentFormat !== 'hex' ? labelId : undefined,
|
|
418
|
+
},
|
|
399
419
|
currentFormat === 'hex' && hexInputField,
|
|
400
420
|
currentFormat === 'rgb' && rgbInputs,
|
|
401
421
|
currentFormat === 'hsl' && hslInputs,
|