Skip to content

Commit 70b0930

Browse files
authored
Fix carousel selected state and dots (#179)
* fixes css specificity issue preventing selected dot styles from applying * fixes carousel loop-around behavior * fix the selected thumbnail state * simplified the next index loop-around calculations logic
1 parent 64b5469 commit 70b0930

File tree

4 files changed

+43
-13
lines changed

4 files changed

+43
-13
lines changed

src/carousel/Carousel.js

+19-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { Fragment, useState } from 'react'
1+
import React, { Fragment, useCallback, useState } from 'react'
22
import clsx from 'clsx'
33
import { makeStyles } from '@material-ui/core/styles'
44
import SwipeableViews from 'react-swipeable-views'
@@ -108,6 +108,23 @@ const Carousel = React.forwardRef((props, ref) => {
108108
return <Fragment key={key}>{slide}</Fragment>
109109
}
110110

111+
const onChangeIndex = useCallback((index) => {
112+
if (!infinite) {
113+
setSelected(index)
114+
return
115+
}
116+
117+
// carousel loop-around calculations
118+
let nextSelectedIndex = index;
119+
if (nextSelectedIndex + 1 > count) {
120+
nextSelectedIndex = 0;
121+
} else if (nextSelectedIndex < 0) {
122+
nextSelectedIndex = count - 1;
123+
}
124+
125+
setSelected(nextSelectedIndex)
126+
}, [infinite, count, selected, setSelected])
127+
111128
return (
112129
<div
113130
ref={ref}
@@ -122,7 +139,7 @@ const Carousel = React.forwardRef((props, ref) => {
122139
<div className={classes.swipeWrap}>
123140
<Tag
124141
index={selected}
125-
onChangeIndex={setSelected}
142+
onChangeIndex={onChangeIndex}
126143
className={classes.autoPlaySwipeableViews}
127144
style={swipeStyle}
128145
slideStyle={slideStyle}

src/carousel/CarouselArrows.js

+16-2
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,23 @@ export default function CarouselArrows({
6161
const createOnClickArrow = useCallback(
6262
idxChange => evt => {
6363
evt.preventDefault()
64-
setSelected(selected + idxChange)
64+
65+
if (!infinite) {
66+
setSelected(selected + idxChange);
67+
return;
68+
}
69+
70+
// carousel loop-around calculations
71+
let nextSelectedIndex = selected + idxChange;
72+
if (nextSelectedIndex + 1 > count) {
73+
nextSelectedIndex = 0;
74+
} else if (nextSelectedIndex < 0) {
75+
nextSelectedIndex = count - 1;
76+
}
77+
78+
setSelected(nextSelectedIndex);
6579
},
66-
[selected, setSelected],
80+
[selected, setSelected, count, infinite],
6781
)
6882

6983
return (

src/carousel/CarouselDots.js

+7-7
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,6 @@ const styles = theme => ({
1515
width: '100%',
1616
},
1717

18-
/**
19-
* Styles applied to the dot representing the selected slide.
20-
*/
21-
dotSelected: {
22-
backgroundColor: theme.palette.text.primary,
23-
},
24-
2518
/**
2619
* Styles applied to each dot element.
2720
*/
@@ -38,6 +31,13 @@ const styles = theme => ({
3831
// Same duration as SwipeableViews animation
3932
transitionDuration: '0.35s',
4033
},
34+
35+
/**
36+
* Styles applied to the dot representing the selected slide.
37+
*/
38+
dotSelected: {
39+
backgroundColor: theme.palette.text.primary,
40+
}
4141
})
4242

4343
const useStyles = makeStyles(styles, { name: 'RSFCarouselDots' })

src/carousel/CarouselThumbnails.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import Tab from '@material-ui/core/Tab'
66
import { makeStyles, useTheme } from '@material-ui/core/styles'
77
import useMediaQuery from '@material-ui/core/useMediaQuery'
88
import Image from '../Image'
9-
import mod from '../utils/mod'
109

1110
export const styles = theme => ({
1211
/**
@@ -139,7 +138,7 @@ function CarouselThumbnails({
139138
return (
140139
<div className={clsx(className, styles.thumbs)}>
141140
<Tabs
142-
value={selected ? mod(selected, count) : false}
141+
value={selected}
143142
variant="scrollable"
144143
onChange={(_, index) => setSelected(index)}
145144
orientation={isVertical ? 'vertical' : 'horizontal'}

0 commit comments

Comments
 (0)