@lumx/react 2.2.5 → 2.2.8
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/esm/_internal/AutocompleteMultiple.js.map +1 -1
- package/esm/_internal/DatePickerField.js.map +1 -1
- package/esm/_internal/Icon2.js +5 -2
- package/esm/_internal/Icon2.js.map +1 -1
- package/esm/_internal/Lightbox2.js +6 -4
- package/esm/_internal/Lightbox2.js.map +1 -1
- package/esm/_internal/List2.js.map +1 -1
- package/esm/_internal/Notification2.js +2 -1
- package/esm/_internal/Notification2.js.map +1 -1
- package/esm/_internal/SelectMultiple.js.map +1 -1
- package/esm/_internal/SlideshowControls.js +234 -94
- package/esm/_internal/SlideshowControls.js.map +1 -1
- package/esm/_internal/Thumbnail2.js +1 -1
- package/esm/_internal/Thumbnail2.js.map +1 -1
- package/esm/_internal/Tooltip2.js +110 -113
- package/esm/_internal/Tooltip2.js.map +1 -1
- package/esm/_internal/autocomplete.js +0 -1
- package/esm/_internal/autocomplete.js.map +1 -1
- package/esm/_internal/button.js +0 -1
- package/esm/_internal/button.js.map +1 -1
- package/esm/_internal/constants.js.map +1 -1
- package/esm/_internal/date-picker.js +0 -1
- package/esm/_internal/date-picker.js.map +1 -1
- package/esm/_internal/expansion-panel.js +0 -1
- package/esm/_internal/expansion-panel.js.map +1 -1
- package/esm/_internal/getRootClassName.js +19 -1
- package/esm/_internal/getRootClassName.js.map +1 -1
- package/esm/_internal/lightbox.js +0 -1
- package/esm/_internal/lightbox.js.map +1 -1
- package/esm/_internal/mergeRefs.js.map +1 -1
- package/esm/_internal/select.js +0 -1
- package/esm/_internal/select.js.map +1 -1
- package/esm/_internal/side-navigation.js +0 -1
- package/esm/_internal/side-navigation.js.map +1 -1
- package/esm/_internal/slideshow.js +1 -1
- package/esm/_internal/text-field.js +0 -1
- package/esm/_internal/text-field.js.map +1 -1
- package/esm/_internal/tooltip.js +0 -1
- package/esm/_internal/tooltip.js.map +1 -1
- package/esm/_internal/useRovingTabIndex.js.map +1 -1
- package/esm/index.js +1 -1
- package/package.json +4 -4
- package/src/components/alert-dialog/AlertDialog.test.tsx +1 -0
- package/src/components/autocomplete/AutocompleteMultiple.tsx +3 -1
- package/src/components/button/__snapshots__/IconButton.test.tsx.snap +0 -5
- package/src/components/icon/Icon.tsx +6 -2
- package/src/components/image-block/ImageBlock.stories.tsx +1 -2
- package/src/components/lightbox/Lightbox.stories.tsx +1 -0
- package/src/components/lightbox/Lightbox.tsx +5 -3
- package/src/components/notification/Notification.tsx +1 -0
- package/src/components/select/SelectMultiple.tsx +0 -1
- package/src/components/slideshow/Slideshow.stories.tsx +1 -1
- package/src/components/slideshow/Slideshow.tsx +76 -112
- package/src/components/slideshow/SlideshowControls.stories.tsx +18 -12
- package/src/components/slideshow/SlideshowControls.tsx +11 -7
- package/src/components/slideshow/SlideshowItem.tsx +4 -1
- package/src/components/slideshow/__snapshots__/Slideshow.test.tsx.snap +52 -17
- package/src/components/tabs/state.ts +0 -1
- package/src/components/thumbnail/Thumbnail.stories.tsx +25 -1
- package/src/components/thumbnail/Thumbnail.test.tsx +9 -1
- package/src/components/thumbnail/Thumbnail.tsx +3 -0
- package/src/components/thumbnail/__snapshots__/Thumbnail.test.tsx.snap +26 -0
- package/src/components/tooltip/Tooltip.tsx +1 -2
- package/src/components/tooltip/useTooltipOpen.tsx +90 -91
- package/src/constants.ts +7 -1
- package/src/hooks/useFocusWithin.ts +33 -0
- package/src/hooks/useSlideshowControls.ts +213 -0
- package/src/utils/browserDoesNotSupportHover.test.js +24 -0
- package/src/utils/browserDoesNotSupportHover.ts +2 -0
- package/src/utils/index.tsx +0 -2
- package/src/utils/mergeRefs.ts +1 -1
- package/types.d.ts +62 -8
- package/src/utils/htmlDecode.ts +0 -13
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import React, { CSSProperties, forwardRef
|
|
1
|
+
import React, { CSSProperties, forwardRef } from 'react';
|
|
2
2
|
|
|
3
3
|
import classNames from 'classnames';
|
|
4
4
|
|
|
5
5
|
import { SlideshowControls, SlideshowControlsProps, Theme } from '@lumx/react';
|
|
6
|
-
|
|
7
|
-
import {
|
|
8
|
-
import { useInterval } from '@lumx/react/hooks/useInterval';
|
|
6
|
+
import { DEFAULT_OPTIONS } from '@lumx/react/hooks/useSlideshowControls';
|
|
7
|
+
import { FULL_WIDTH_PERCENT } from '@lumx/react/components/slideshow/constants';
|
|
9
8
|
import { Comp, GenericProps, getRootClassName, handleBasicClasses } from '@lumx/react/utils';
|
|
10
9
|
import { mergeRefs } from '@lumx/react/utils/mergeRefs';
|
|
11
10
|
|
|
@@ -39,6 +38,10 @@ export interface SlideshowProps extends GenericProps {
|
|
|
39
38
|
theme?: Theme;
|
|
40
39
|
/** Callback when slide changes */
|
|
41
40
|
onChange?(index: number): void;
|
|
41
|
+
/** slideshow HTML id attribute */
|
|
42
|
+
id?: string;
|
|
43
|
+
/** slides wrapper HTML id attribute */
|
|
44
|
+
slidesId?: string;
|
|
42
45
|
}
|
|
43
46
|
|
|
44
47
|
/**
|
|
@@ -55,9 +58,7 @@ const CLASSNAME = getRootClassName(COMPONENT_NAME);
|
|
|
55
58
|
* Component default props.
|
|
56
59
|
*/
|
|
57
60
|
const DEFAULT_PROPS: Partial<SlideshowProps> = {
|
|
58
|
-
|
|
59
|
-
groupBy: 1,
|
|
60
|
-
interval: AUTOPLAY_DEFAULT_INTERVAL,
|
|
61
|
+
...DEFAULT_OPTIONS,
|
|
61
62
|
theme: Theme.light,
|
|
62
63
|
};
|
|
63
64
|
|
|
@@ -80,122 +81,76 @@ export const Slideshow: Comp<SlideshowProps, HTMLDivElement> = forwardRef((props
|
|
|
80
81
|
onChange,
|
|
81
82
|
slideshowControlsProps,
|
|
82
83
|
theme,
|
|
84
|
+
id,
|
|
85
|
+
slidesId,
|
|
83
86
|
...forwardedProps
|
|
84
87
|
} = props;
|
|
85
|
-
const [currentIndex, setCurrentIndex] = useState(activeIndex as number);
|
|
86
|
-
// Use state instead of a ref to make the slideshow controls update directly when the element is set.
|
|
87
|
-
const [element, setElement] = useState<HTMLDivElement>();
|
|
88
|
-
|
|
89
88
|
// Number of slideshow items.
|
|
90
89
|
const itemsCount = React.Children.count(children);
|
|
91
|
-
// Number of slides when using groupBy prop.
|
|
92
|
-
const slidesCount = Math.ceil(itemsCount / Math.min(groupBy as number, itemsCount));
|
|
93
|
-
// Inline style of wrapper element.
|
|
94
|
-
const wrapperStyle: CSSProperties = { transform: `translateX(-${FULL_WIDTH_PERCENT * currentIndex}%)` };
|
|
95
|
-
|
|
96
|
-
// Change current index to display next slide.
|
|
97
|
-
const goToNextSlide = useCallback(
|
|
98
|
-
(loopback = true) => {
|
|
99
|
-
setCurrentIndex((index) => {
|
|
100
|
-
if (loopback && index === slidesCount - 1) {
|
|
101
|
-
// Loopback to the start.
|
|
102
|
-
return 0;
|
|
103
|
-
}
|
|
104
|
-
if (index < slidesCount - 1) {
|
|
105
|
-
// Next slide.
|
|
106
|
-
return index + 1;
|
|
107
|
-
}
|
|
108
|
-
return index;
|
|
109
|
-
});
|
|
110
|
-
},
|
|
111
|
-
[slidesCount, setCurrentIndex],
|
|
112
|
-
);
|
|
113
|
-
|
|
114
|
-
// Change current index to display previous slide.
|
|
115
|
-
const goToPreviousSlide = useCallback(
|
|
116
|
-
(loopback = true) => {
|
|
117
|
-
setCurrentIndex((index) => {
|
|
118
|
-
if (loopback && index === 0) {
|
|
119
|
-
// Loopback to the end.
|
|
120
|
-
return slidesCount - 1;
|
|
121
|
-
}
|
|
122
|
-
if (index > 0) {
|
|
123
|
-
// Previous slide.
|
|
124
|
-
return index - 1;
|
|
125
|
-
}
|
|
126
|
-
return index;
|
|
127
|
-
});
|
|
128
|
-
},
|
|
129
|
-
[slidesCount, setCurrentIndex],
|
|
130
|
-
);
|
|
131
|
-
|
|
132
|
-
// Auto play
|
|
133
|
-
const [isAutoPlaying, setIsAutoPlaying] = useState(Boolean(autoPlay));
|
|
134
|
-
// Start
|
|
135
|
-
useInterval(goToNextSlide, isAutoPlaying && slidesCount > 1 ? (interval as number) : null);
|
|
136
|
-
|
|
137
|
-
// Reset current index if it become invalid.
|
|
138
|
-
useEffect(() => {
|
|
139
|
-
if (currentIndex > slidesCount - 1) {
|
|
140
|
-
setCurrentIndex(DEFAULT_PROPS.activeIndex as number);
|
|
141
|
-
}
|
|
142
|
-
}, [currentIndex, slidesCount]);
|
|
143
|
-
|
|
144
|
-
// Handle click on a bullet to go to a specific slide.
|
|
145
|
-
const handleControlGotToSlide = useCallback(
|
|
146
|
-
(index: number) => {
|
|
147
|
-
setIsAutoPlaying(false);
|
|
148
|
-
|
|
149
|
-
if (index >= 0 && index < slidesCount) {
|
|
150
|
-
setCurrentIndex(index);
|
|
151
|
-
}
|
|
152
|
-
},
|
|
153
|
-
[slidesCount, setCurrentIndex],
|
|
154
|
-
);
|
|
155
90
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
91
|
+
const {
|
|
92
|
+
activeIndex: currentIndex,
|
|
93
|
+
slideshowId,
|
|
94
|
+
setSlideshow,
|
|
95
|
+
isAutoPlaying,
|
|
96
|
+
slideshowSlidesId,
|
|
97
|
+
setIsAutoPlaying,
|
|
98
|
+
startIndexVisible,
|
|
99
|
+
endIndexVisible,
|
|
100
|
+
slidesCount,
|
|
101
|
+
onNextClick,
|
|
102
|
+
onPaginationClick,
|
|
103
|
+
onPreviousClick,
|
|
104
|
+
slideshow,
|
|
105
|
+
} = SlideshowControls.useSlideshowControls({
|
|
106
|
+
activeIndex,
|
|
107
|
+
defaultActiveIndex: DEFAULT_PROPS.activeIndex as number,
|
|
108
|
+
autoPlay: Boolean(autoPlay),
|
|
109
|
+
itemsCount,
|
|
110
|
+
groupBy,
|
|
111
|
+
id,
|
|
112
|
+
interval,
|
|
113
|
+
onChange,
|
|
114
|
+
slidesId,
|
|
115
|
+
});
|
|
178
116
|
|
|
179
|
-
//
|
|
180
|
-
|
|
181
|
-
if (!onChange) return;
|
|
182
|
-
onChange(currentIndex);
|
|
183
|
-
}, [currentIndex, onChange]);
|
|
117
|
+
// Inline style of wrapper element.
|
|
118
|
+
const wrapperStyle: CSSProperties = { transform: `translateX(-${FULL_WIDTH_PERCENT * currentIndex}%)` };
|
|
184
119
|
|
|
185
120
|
/* eslint-disable jsx-a11y/no-noninteractive-tabindex */
|
|
186
121
|
return (
|
|
187
|
-
<
|
|
188
|
-
|
|
122
|
+
<section
|
|
123
|
+
id={slideshowId}
|
|
124
|
+
ref={mergeRefs(ref, setSlideshow)}
|
|
189
125
|
{...forwardedProps}
|
|
190
126
|
className={classNames(className, handleBasicClasses({ prefix: CLASSNAME, theme }), {
|
|
191
127
|
[`${CLASSNAME}--fill-height`]: fillHeight,
|
|
192
128
|
[`${CLASSNAME}--group-by-${groupBy}`]: Boolean(groupBy),
|
|
193
129
|
})}
|
|
194
|
-
|
|
130
|
+
aria-roledescription="carousel"
|
|
131
|
+
aria-live={isAutoPlaying ? 'off' : 'polite'}
|
|
195
132
|
>
|
|
196
|
-
<div
|
|
133
|
+
<div
|
|
134
|
+
id={slideshowSlidesId}
|
|
135
|
+
className={`${CLASSNAME}__slides`}
|
|
136
|
+
onMouseEnter={() => setIsAutoPlaying(false)}
|
|
137
|
+
onMouseLeave={() => setIsAutoPlaying(Boolean(autoPlay))}
|
|
138
|
+
>
|
|
197
139
|
<div className={`${CLASSNAME}__wrapper`} style={wrapperStyle}>
|
|
198
|
-
{children
|
|
140
|
+
{React.Children.map(children, (child: React.ReactNode, index: number) => {
|
|
141
|
+
if (React.isValidElement(child)) {
|
|
142
|
+
const isCurrentlyVisible = index >= startIndexVisible && index <= endIndexVisible;
|
|
143
|
+
|
|
144
|
+
return React.cloneElement(child, {
|
|
145
|
+
style: !isCurrentlyVisible
|
|
146
|
+
? { visibility: 'hidden', ...(child.props.style || {}) }
|
|
147
|
+
: child.props.style || {},
|
|
148
|
+
'aria-hidden': !isCurrentlyVisible,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return null;
|
|
153
|
+
})}
|
|
199
154
|
</div>
|
|
200
155
|
</div>
|
|
201
156
|
|
|
@@ -204,18 +159,27 @@ export const Slideshow: Comp<SlideshowProps, HTMLDivElement> = forwardRef((props
|
|
|
204
159
|
<SlideshowControls
|
|
205
160
|
{...slideshowControlsProps}
|
|
206
161
|
activeIndex={currentIndex}
|
|
207
|
-
onPaginationClick={
|
|
208
|
-
onNextClick={
|
|
209
|
-
onPreviousClick={
|
|
162
|
+
onPaginationClick={onPaginationClick}
|
|
163
|
+
onNextClick={onNextClick}
|
|
164
|
+
onPreviousClick={onPreviousClick}
|
|
210
165
|
slidesCount={slidesCount}
|
|
211
|
-
parentRef={
|
|
166
|
+
parentRef={slideshow}
|
|
212
167
|
theme={theme}
|
|
168
|
+
nextButtonProps={{
|
|
169
|
+
'aria-controls': slideshowSlidesId,
|
|
170
|
+
...slideshowControlsProps.nextButtonProps,
|
|
171
|
+
}}
|
|
172
|
+
previousButtonProps={{
|
|
173
|
+
'aria-controls': slideshowSlidesId,
|
|
174
|
+
...slideshowControlsProps.previousButtonProps,
|
|
175
|
+
}}
|
|
213
176
|
/>
|
|
214
177
|
</div>
|
|
215
178
|
)}
|
|
216
|
-
</
|
|
179
|
+
</section>
|
|
217
180
|
);
|
|
218
181
|
});
|
|
182
|
+
|
|
219
183
|
Slideshow.displayName = COMPONENT_NAME;
|
|
220
184
|
Slideshow.className = CLASSNAME;
|
|
221
185
|
Slideshow.defaultProps = DEFAULT_PROPS;
|
|
@@ -6,13 +6,15 @@ import { thumbnailsKnob } from '@lumx/react/stories/knobs/thumbnailsKnob';
|
|
|
6
6
|
export default { title: 'LumX components/slideshow/Slideshow controls' };
|
|
7
7
|
|
|
8
8
|
export const Simple = () => {
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
9
|
+
const {
|
|
10
|
+
activeIndex,
|
|
11
|
+
slidesCount,
|
|
12
|
+
onNextClick,
|
|
13
|
+
onPreviousClick,
|
|
14
|
+
onPaginationClick,
|
|
15
|
+
} = SlideshowControls.useSlideshowControls({
|
|
16
|
+
itemsCount: 9,
|
|
17
|
+
});
|
|
16
18
|
|
|
17
19
|
return (
|
|
18
20
|
<SlideshowControls
|
|
@@ -29,15 +31,19 @@ export const Simple = () => {
|
|
|
29
31
|
|
|
30
32
|
export const ControllingSlideshow = ({ theme }: any) => {
|
|
31
33
|
const items = thumbnailsKnob(6);
|
|
32
|
-
const [activeIndex, setActiveIndex] = React.useState(0);
|
|
33
|
-
const maxIndex = items.length - 1;
|
|
34
34
|
const slideshowStyle = {
|
|
35
35
|
width: '50%',
|
|
36
36
|
};
|
|
37
37
|
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
const {
|
|
39
|
+
activeIndex,
|
|
40
|
+
setActiveIndex,
|
|
41
|
+
onNextClick,
|
|
42
|
+
onPreviousClick,
|
|
43
|
+
onPaginationClick,
|
|
44
|
+
} = SlideshowControls.useSlideshowControls({
|
|
45
|
+
itemsCount: 6,
|
|
46
|
+
});
|
|
41
47
|
|
|
42
48
|
return (
|
|
43
49
|
<div style={{ height: 400, width: 500, position: 'relative' }}>
|
|
@@ -7,6 +7,7 @@ import { mdiChevronLeft, mdiChevronRight } from '@lumx/icons';
|
|
|
7
7
|
import { Emphasis, IconButton, IconButtonProps, Theme } from '@lumx/react';
|
|
8
8
|
import { Comp, GenericProps, getRootClassName, handleBasicClasses } from '@lumx/react/utils';
|
|
9
9
|
import { WINDOW } from '@lumx/react/constants';
|
|
10
|
+
import { useSlideshowControls, DEFAULT_OPTIONS } from '@lumx/react/hooks/useSlideshowControls';
|
|
10
11
|
|
|
11
12
|
import { useSwipeNavigate } from './useSwipeNavigate';
|
|
12
13
|
import { useKeyNavigate } from './useKeyNavigate';
|
|
@@ -64,7 +65,7 @@ const DEFAULT_PROPS: Partial<SlideshowControlsProps> = {
|
|
|
64
65
|
* @param ref Component ref.
|
|
65
66
|
* @return React element.
|
|
66
67
|
*/
|
|
67
|
-
|
|
68
|
+
const InternalSlideshowControls: Comp<SlideshowControlsProps, HTMLDivElement> = forwardRef((props, ref) => {
|
|
68
69
|
const {
|
|
69
70
|
activeIndex,
|
|
70
71
|
className,
|
|
@@ -116,7 +117,6 @@ export const SlideshowControls: Comp<SlideshowControlsProps, HTMLDivElement> = f
|
|
|
116
117
|
color={theme === Theme.dark ? 'light' : 'dark'}
|
|
117
118
|
emphasis={Emphasis.low}
|
|
118
119
|
onClick={onPreviousClick}
|
|
119
|
-
tabIndex={-1}
|
|
120
120
|
/>
|
|
121
121
|
<div className={`${CLASSNAME}__pagination`}>
|
|
122
122
|
<div className={`${CLASSNAME}__pagination-items`} style={wrapperStyle}>
|
|
@@ -143,7 +143,6 @@ export const SlideshowControls: Comp<SlideshowControlsProps, HTMLDivElement> = f
|
|
|
143
143
|
key={index}
|
|
144
144
|
type="button"
|
|
145
145
|
onClick={() => onPaginationClick?.(index)}
|
|
146
|
-
tabIndex={-1}
|
|
147
146
|
/>
|
|
148
147
|
);
|
|
149
148
|
}),
|
|
@@ -158,11 +157,16 @@ export const SlideshowControls: Comp<SlideshowControlsProps, HTMLDivElement> = f
|
|
|
158
157
|
color={theme === Theme.dark ? 'light' : 'dark'}
|
|
159
158
|
emphasis={Emphasis.low}
|
|
160
159
|
onClick={onNextClick}
|
|
161
|
-
tabIndex={-1}
|
|
162
160
|
/>
|
|
163
161
|
</div>
|
|
164
162
|
);
|
|
165
163
|
});
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
164
|
+
|
|
165
|
+
InternalSlideshowControls.displayName = COMPONENT_NAME;
|
|
166
|
+
InternalSlideshowControls.className = CLASSNAME;
|
|
167
|
+
InternalSlideshowControls.defaultProps = DEFAULT_PROPS;
|
|
168
|
+
|
|
169
|
+
export const SlideshowControls = Object.assign(InternalSlideshowControls, {
|
|
170
|
+
useSlideshowControls,
|
|
171
|
+
useSlideshowControlsDefaultOptions: DEFAULT_OPTIONS,
|
|
172
|
+
});
|
|
@@ -32,17 +32,20 @@ export const SlideshowItem: Comp<SlideshowItemProps, HTMLDivElement> = forwardRe
|
|
|
32
32
|
return (
|
|
33
33
|
<div
|
|
34
34
|
ref={ref}
|
|
35
|
-
{...forwardedProps}
|
|
36
35
|
className={classNames(
|
|
37
36
|
className,
|
|
38
37
|
handleBasicClasses({
|
|
39
38
|
prefix: CLASSNAME,
|
|
40
39
|
}),
|
|
41
40
|
)}
|
|
41
|
+
aria-roledescription="slide"
|
|
42
|
+
role="group"
|
|
43
|
+
{...forwardedProps}
|
|
42
44
|
>
|
|
43
45
|
{children}
|
|
44
46
|
</div>
|
|
45
47
|
);
|
|
46
48
|
});
|
|
49
|
+
|
|
47
50
|
SlideshowItem.displayName = COMPONENT_NAME;
|
|
48
51
|
SlideshowItem.className = CLASSNAME;
|
|
@@ -2,17 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
exports[`<Slideshow> Snapshots and structure should render story 'Simple' 1`] = `
|
|
4
4
|
Array [
|
|
5
|
-
<
|
|
5
|
+
<section
|
|
6
|
+
aria-live="polite"
|
|
7
|
+
aria-roledescription="carousel"
|
|
6
8
|
className="lumx-slideshow lumx-slideshow--theme-light lumx-slideshow--group-by-1"
|
|
9
|
+
id="slideshow1"
|
|
7
10
|
style={
|
|
8
11
|
Object {
|
|
9
12
|
"width": "50%",
|
|
10
13
|
}
|
|
11
14
|
}
|
|
12
|
-
tabIndex={0}
|
|
13
15
|
>
|
|
14
16
|
<div
|
|
15
17
|
className="lumx-slideshow__slides"
|
|
18
|
+
id="slideshow-slides2"
|
|
19
|
+
onMouseEnter={[Function]}
|
|
20
|
+
onMouseLeave={[Function]}
|
|
16
21
|
>
|
|
17
22
|
<div
|
|
18
23
|
className="lumx-slideshow__wrapper"
|
|
@@ -23,7 +28,9 @@ Array [
|
|
|
23
28
|
}
|
|
24
29
|
>
|
|
25
30
|
<SlideshowItem
|
|
26
|
-
|
|
31
|
+
aria-hidden={false}
|
|
32
|
+
key=".$/demo-assets/landscape1.jpg-0"
|
|
33
|
+
style={Object {}}
|
|
27
34
|
>
|
|
28
35
|
<ImageBlock
|
|
29
36
|
align="left"
|
|
@@ -34,12 +41,15 @@ Array [
|
|
|
34
41
|
thumbnailProps={
|
|
35
42
|
Object {
|
|
36
43
|
"aspectRatio": "horizontal",
|
|
44
|
+
"loading": "eager",
|
|
37
45
|
}
|
|
38
46
|
}
|
|
39
47
|
/>
|
|
40
48
|
</SlideshowItem>
|
|
41
49
|
<SlideshowItem
|
|
42
|
-
|
|
50
|
+
aria-hidden={false}
|
|
51
|
+
key=".$/demo-assets/landscape1-s200.jpg-1"
|
|
52
|
+
style={Object {}}
|
|
43
53
|
>
|
|
44
54
|
<ImageBlock
|
|
45
55
|
align="left"
|
|
@@ -50,12 +60,19 @@ Array [
|
|
|
50
60
|
thumbnailProps={
|
|
51
61
|
Object {
|
|
52
62
|
"aspectRatio": "horizontal",
|
|
63
|
+
"loading": "eager",
|
|
53
64
|
}
|
|
54
65
|
}
|
|
55
66
|
/>
|
|
56
67
|
</SlideshowItem>
|
|
57
68
|
<SlideshowItem
|
|
58
|
-
|
|
69
|
+
aria-hidden={true}
|
|
70
|
+
key=".$/demo-assets/landscape2.jpg-2"
|
|
71
|
+
style={
|
|
72
|
+
Object {
|
|
73
|
+
"visibility": "hidden",
|
|
74
|
+
}
|
|
75
|
+
}
|
|
59
76
|
>
|
|
60
77
|
<ImageBlock
|
|
61
78
|
align="left"
|
|
@@ -66,12 +83,19 @@ Array [
|
|
|
66
83
|
thumbnailProps={
|
|
67
84
|
Object {
|
|
68
85
|
"aspectRatio": "horizontal",
|
|
86
|
+
"loading": "eager",
|
|
69
87
|
}
|
|
70
88
|
}
|
|
71
89
|
/>
|
|
72
90
|
</SlideshowItem>
|
|
73
91
|
<SlideshowItem
|
|
74
|
-
|
|
92
|
+
aria-hidden={true}
|
|
93
|
+
key=".$/demo-assets/landscape3.jpg-3"
|
|
94
|
+
style={
|
|
95
|
+
Object {
|
|
96
|
+
"visibility": "hidden",
|
|
97
|
+
}
|
|
98
|
+
}
|
|
75
99
|
>
|
|
76
100
|
<ImageBlock
|
|
77
101
|
align="left"
|
|
@@ -82,12 +106,19 @@ Array [
|
|
|
82
106
|
thumbnailProps={
|
|
83
107
|
Object {
|
|
84
108
|
"aspectRatio": "horizontal",
|
|
109
|
+
"loading": "eager",
|
|
85
110
|
}
|
|
86
111
|
}
|
|
87
112
|
/>
|
|
88
113
|
</SlideshowItem>
|
|
89
114
|
<SlideshowItem
|
|
90
|
-
|
|
115
|
+
aria-hidden={true}
|
|
116
|
+
key=".$/demo-assets/portrait1.jpg-4"
|
|
117
|
+
style={
|
|
118
|
+
Object {
|
|
119
|
+
"visibility": "hidden",
|
|
120
|
+
}
|
|
121
|
+
}
|
|
91
122
|
>
|
|
92
123
|
<ImageBlock
|
|
93
124
|
align="left"
|
|
@@ -98,12 +129,19 @@ Array [
|
|
|
98
129
|
thumbnailProps={
|
|
99
130
|
Object {
|
|
100
131
|
"aspectRatio": "horizontal",
|
|
132
|
+
"loading": "eager",
|
|
101
133
|
}
|
|
102
134
|
}
|
|
103
135
|
/>
|
|
104
136
|
</SlideshowItem>
|
|
105
137
|
<SlideshowItem
|
|
106
|
-
|
|
138
|
+
aria-hidden={true}
|
|
139
|
+
key=".$/demo-assets/portrait1-s200.jpg-5"
|
|
140
|
+
style={
|
|
141
|
+
Object {
|
|
142
|
+
"visibility": "hidden",
|
|
143
|
+
}
|
|
144
|
+
}
|
|
107
145
|
>
|
|
108
146
|
<ImageBlock
|
|
109
147
|
align="left"
|
|
@@ -114,6 +152,7 @@ Array [
|
|
|
114
152
|
thumbnailProps={
|
|
115
153
|
Object {
|
|
116
154
|
"aspectRatio": "horizontal",
|
|
155
|
+
"loading": "eager",
|
|
117
156
|
}
|
|
118
157
|
}
|
|
119
158
|
/>
|
|
@@ -127,6 +166,7 @@ Array [
|
|
|
127
166
|
activeIndex={0}
|
|
128
167
|
nextButtonProps={
|
|
129
168
|
Object {
|
|
169
|
+
"aria-controls": "slideshow-slides2",
|
|
130
170
|
"label": "Next",
|
|
131
171
|
}
|
|
132
172
|
}
|
|
@@ -135,6 +175,7 @@ Array [
|
|
|
135
175
|
onPreviousClick={[Function]}
|
|
136
176
|
previousButtonProps={
|
|
137
177
|
Object {
|
|
178
|
+
"aria-controls": "slideshow-slides2",
|
|
138
179
|
"label": "Previous",
|
|
139
180
|
}
|
|
140
181
|
}
|
|
@@ -142,11 +183,12 @@ Array [
|
|
|
142
183
|
theme="light"
|
|
143
184
|
/>
|
|
144
185
|
</div>
|
|
145
|
-
</
|
|
186
|
+
</section>,
|
|
146
187
|
<div
|
|
147
188
|
className="lumx-slideshow-controls lumx-slideshow-controls--theme-light lumx-slideshow-controls--has-infinite-pagination"
|
|
148
189
|
>
|
|
149
190
|
<IconButton
|
|
191
|
+
aria-controls="slideshow-slides4"
|
|
150
192
|
className="lumx-slideshow-controls__navigation"
|
|
151
193
|
color="dark"
|
|
152
194
|
emphasis="low"
|
|
@@ -154,7 +196,6 @@ Array [
|
|
|
154
196
|
label="Previous"
|
|
155
197
|
onClick={[Function]}
|
|
156
198
|
size="m"
|
|
157
|
-
tabIndex={-1}
|
|
158
199
|
theme="light"
|
|
159
200
|
/>
|
|
160
201
|
<div
|
|
@@ -172,47 +213,42 @@ Array [
|
|
|
172
213
|
className="lumx-slideshow-controls__pagination-item lumx-slideshow-controls__pagination-item--is-active"
|
|
173
214
|
key="0"
|
|
174
215
|
onClick={[Function]}
|
|
175
|
-
tabIndex={-1}
|
|
176
216
|
type="button"
|
|
177
217
|
/>
|
|
178
218
|
<button
|
|
179
219
|
className="lumx-slideshow-controls__pagination-item"
|
|
180
220
|
key="1"
|
|
181
221
|
onClick={[Function]}
|
|
182
|
-
tabIndex={-1}
|
|
183
222
|
type="button"
|
|
184
223
|
/>
|
|
185
224
|
<button
|
|
186
225
|
className="lumx-slideshow-controls__pagination-item"
|
|
187
226
|
key="2"
|
|
188
227
|
onClick={[Function]}
|
|
189
|
-
tabIndex={-1}
|
|
190
228
|
type="button"
|
|
191
229
|
/>
|
|
192
230
|
<button
|
|
193
231
|
className="lumx-slideshow-controls__pagination-item"
|
|
194
232
|
key="3"
|
|
195
233
|
onClick={[Function]}
|
|
196
|
-
tabIndex={-1}
|
|
197
234
|
type="button"
|
|
198
235
|
/>
|
|
199
236
|
<button
|
|
200
237
|
className="lumx-slideshow-controls__pagination-item lumx-slideshow-controls__pagination-item--is-on-edge"
|
|
201
238
|
key="4"
|
|
202
239
|
onClick={[Function]}
|
|
203
|
-
tabIndex={-1}
|
|
204
240
|
type="button"
|
|
205
241
|
/>
|
|
206
242
|
<button
|
|
207
243
|
className="lumx-slideshow-controls__pagination-item lumx-slideshow-controls__pagination-item--is-out-range"
|
|
208
244
|
key="5"
|
|
209
245
|
onClick={[Function]}
|
|
210
|
-
tabIndex={-1}
|
|
211
246
|
type="button"
|
|
212
247
|
/>
|
|
213
248
|
</div>
|
|
214
249
|
</div>
|
|
215
250
|
<IconButton
|
|
251
|
+
aria-controls="slideshow-slides4"
|
|
216
252
|
className="lumx-slideshow-controls__navigation"
|
|
217
253
|
color="dark"
|
|
218
254
|
emphasis="low"
|
|
@@ -220,7 +256,6 @@ Array [
|
|
|
220
256
|
label="Next"
|
|
221
257
|
onClick={[Function]}
|
|
222
258
|
size="m"
|
|
223
|
-
tabIndex={-1}
|
|
224
259
|
theme="light"
|
|
225
260
|
/>
|
|
226
261
|
</div>,
|
|
@@ -18,7 +18,6 @@ import { enumKnob } from '@lumx/react/stories/knobs/enumKnob';
|
|
|
18
18
|
import { focusKnob } from '@lumx/react/stories/knobs/focusKnob';
|
|
19
19
|
import { sizeKnob } from '@lumx/react/stories/knobs/sizeKnob';
|
|
20
20
|
import { action } from '@storybook/addon-actions';
|
|
21
|
-
import classNames from 'classnames';
|
|
22
21
|
import { CustomLink } from '@lumx/react/stories/utils/CustomLink';
|
|
23
22
|
|
|
24
23
|
export default { title: 'LumX components/thumbnail/Thumbnail' };
|
|
@@ -84,6 +83,31 @@ export const WithBadge = () => {
|
|
|
84
83
|
);
|
|
85
84
|
};
|
|
86
85
|
|
|
86
|
+
export const WithCustomImageClassName = () => {
|
|
87
|
+
const thumbnailSize = sizeKnob('Size', Size.l);
|
|
88
|
+
const variant = select('Variant', ThumbnailVariant, ThumbnailVariant.rounded);
|
|
89
|
+
const badgeColor = select('Badge color', ColorPalette, ColorPalette.primary);
|
|
90
|
+
const activateFallback = boolean('Activate fallback', false);
|
|
91
|
+
const image = imageKnob();
|
|
92
|
+
return (
|
|
93
|
+
<Thumbnail
|
|
94
|
+
alt="Image alt text"
|
|
95
|
+
image={activateFallback ? '' : image}
|
|
96
|
+
variant={variant}
|
|
97
|
+
aspectRatio={AspectRatio.square}
|
|
98
|
+
size={thumbnailSize}
|
|
99
|
+
badge={
|
|
100
|
+
<Badge color={badgeColor}>
|
|
101
|
+
<Icon icon={mdiAbTesting} />
|
|
102
|
+
</Badge>
|
|
103
|
+
}
|
|
104
|
+
imgProps={{
|
|
105
|
+
className: 'custom-image-class-name',
|
|
106
|
+
}}
|
|
107
|
+
/>
|
|
108
|
+
);
|
|
109
|
+
};
|
|
110
|
+
|
|
87
111
|
export const FocusPoint = () => {
|
|
88
112
|
const focusPoint = { x: focusKnob('Focus X ', -0.2), y: focusKnob('Focus Y', -0.3) };
|
|
89
113
|
const aspectRatio = enumKnob('Aspect ratio', [undefined, ...Object.values(AspectRatio)], AspectRatio.wide);
|
|
@@ -5,7 +5,14 @@ import 'jest-enzyme';
|
|
|
5
5
|
import { commonTestsSuite, itShouldRenderStories } from '@lumx/react/testing/utils';
|
|
6
6
|
|
|
7
7
|
import { Thumbnail, ThumbnailProps } from './Thumbnail';
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
Clickable,
|
|
10
|
+
ClickableCustomLink,
|
|
11
|
+
ClickableLink,
|
|
12
|
+
Default,
|
|
13
|
+
WithBadge,
|
|
14
|
+
WithCustomImageClassName,
|
|
15
|
+
} from './Thumbnail.stories';
|
|
9
16
|
|
|
10
17
|
const CLASSNAME = Thumbnail.className as string;
|
|
11
18
|
|
|
@@ -28,6 +35,7 @@ describe(`<${Thumbnail.displayName}>`, () => {
|
|
|
28
35
|
ClickableLink,
|
|
29
36
|
ClickableCustomLink,
|
|
30
37
|
WithBadge,
|
|
38
|
+
WithCustomImageClassName,
|
|
31
39
|
},
|
|
32
40
|
Thumbnail,
|
|
33
41
|
);
|