Skip to content

Commit 89bf6bb

Browse files
committed
Add loop function
1 parent 8990db7 commit 89bf6bb

File tree

5 files changed

+45
-11
lines changed

5 files changed

+45
-11
lines changed

.eslintrc.json

+9-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,15 @@
1616
"ecmaVersion": 2018,
1717
"sourceType": "module"
1818
},
19-
"plugins": ["react"],
19+
"plugins": ["react", "react-hooks"],
2020
"rules": {
21-
"react/prop-types": 0
21+
"react/prop-types": 0,
22+
"react-hooks/rules-of-hooks": "error",
23+
"react-hooks/exhaustive-deps": "warn"
24+
},
25+
"settings": {
26+
"react": {
27+
"version": "detect"
28+
}
2229
}
2330
}

package-lock.json

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
"babel-plugin-styled-components": "^1.10.6",
3535
"eslint": "^6.8.0",
3636
"eslint-plugin-react": "^7.18.0",
37+
"eslint-plugin-react-hooks": "^2.3.0",
3738
"husky": "^4.0.10",
3839
"lint-staged": "^10.0.1",
3940
"prettier": "^1.19.1",

src/components/Carousel.js

+25-7
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ const Item = ({ children }) => {
100100
}
101101

102102
const CAROUSEL_ITEM = 'CAROUSEL_ITEM'
103-
const Carousel = ({ cols = 1, rows = 1, gap = 10, children }) => {
103+
const Carousel = ({ cols = 1, rows = 1, gap = 10, loop = false, children }) => {
104104
const [currentPage, setCurrentPage] = useState(0)
105105
const itemList = React.Children.toArray(children).filter(
106106
child => child.type.displayName === CAROUSEL_ITEM
@@ -120,16 +120,34 @@ const Carousel = ({ cols = 1, rows = 1, gap = 10, children }) => {
120120
const page = Math.ceil(itemList.length / itemAmountPerSet)
121121

122122
const handlePrev = useCallback(() => {
123-
setCurrentPage(p => p - 1)
124-
}, [])
123+
setCurrentPage(p => {
124+
const prevPage = p - 1
125+
if (loop && prevPage < 0) {
126+
return page - 1
127+
}
128+
129+
return prevPage
130+
})
131+
}, [loop, page])
125132

126133
const handleNext = useCallback(() => {
127-
setCurrentPage(p => p + 1)
128-
}, [])
134+
setCurrentPage(p => {
135+
const nextPage = p + 1
136+
if (loop && nextPage >= page) {
137+
return 0
138+
}
139+
140+
return nextPage
141+
})
142+
}, [loop, page])
129143

130144
return (
131145
<Container>
132-
<NextBtn type="prev" hidden={currentPage <= 0} onClick={handlePrev} />
146+
<NextBtn
147+
type="prev"
148+
hidden={!loop && currentPage <= 0}
149+
onClick={handlePrev}
150+
/>
133151
<RailWrapper>
134152
<Rail
135153
cols={cols}
@@ -149,7 +167,7 @@ const Carousel = ({ cols = 1, rows = 1, gap = 10, children }) => {
149167
</RailWrapper>
150168
<NextBtn
151169
type="next"
152-
hidden={currentPage === page - 1}
170+
hidden={!loop && currentPage === page - 1}
153171
onClick={handleNext}
154172
/>
155173
</Container>

stories/Carousel.stories.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React from 'react'
22
import Carousel from '../src/components/Carousel'
33
import styled from 'styled-components'
4-
import { withKnobs, number } from '@storybook/addon-knobs'
4+
import { withKnobs, number, boolean } from '@storybook/addon-knobs'
55

66
const randomImageUrl = 'https://picsum.photos/800/600?random='
77

@@ -197,8 +197,10 @@ export const CustomProps = () => {
197197
range: true
198198
})
199199

200+
const loop = boolean('loop', false)
201+
200202
return (
201-
<Carousel cols={cols} rows={rows} gap={gap}>
203+
<Carousel cols={cols} rows={rows} gap={gap} loop={loop}>
202204
{[...Array(cols * rows * pages)].map((_, i) => (
203205
<Carousel.Item key={i}>
204206
<Item img={randomImageUrl + i} />

0 commit comments

Comments
 (0)