Skip to content

Commit 1956d86

Browse files
authored
Merge pull request #92 from sag1v/support-all-props-from-breakpoint
Support all props through breakpoints (resolve #91 )
2 parents 9a5c91f + 0ece10a commit 1956d86

File tree

3 files changed

+65
-72
lines changed

3 files changed

+65
-72
lines changed

src/docs/mdx/breakpoints.mdx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@ _This is the coolest feature and one of the main reasons that `react-elastic-car
1414
The `breakPoints` array, allows you to set different `props` for different sizes of the element, regardless to the window's size.
1515
This is due to the fact that `react-elastic-carousel` is listening to the element's `resize` event instead of the window.
1616

17-
#### You can pass an array of objects that will signal `react-elastic-carousel` to change props like `itemsToShow` and `itemsToScroll` on different `width` values.
17+
#### You can pass an array of objects that will signal `react-elastic-carousel` to change props like `itemsToShow` and `itemsToScroll` (and others) on different `width` values.
18+
19+
**ANY** prop can be passed directly to React Elastic Carousel or via a the breakpoint object. Keep in mind that a prop passed via a breakpoint will override a direct prop.
1820

1921
## Example
20-
(_Drag or use the resize buttons to see the changes..._)
22+
(_Resize the container to see the changes..._)
2123

2224
<Playground >
2325
{
@@ -26,7 +28,7 @@ This is due to the fact that `react-elastic-carousel` is listening to the elemen
2628
super(props);
2729
this.breakPoints = [
2830
{ width: 1, itemsToShow: 1 },
29-
{ width: 550, itemsToShow: 2, itemsToScroll: 2 },
31+
{ width: 550, itemsToShow: 2, itemsToScroll: 2, pagination: false },
3032
{ width: 850, itemsToShow: 3 },
3133
{ width: 1150, itemsToShow: 4, itemsToScroll: 2 },
3234
{ width: 1450, itemsToShow: 5 },

src/docs/mdx/onResize.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import breakPoints from '../components/breakPoints';
1717
```
1818

1919
<Playground >
20-
<Carousel breakPoints={breakPoints} onResize={currentBreakPoint => console.log(JSON.stringify(currentBreakPoint))}>
20+
<Carousel breakPoints={breakPoints} onResize={currentBreakPoint => console.log(currentBreakPoint)}>
2121
<Item>1</Item>
2222
<Item>2</Item>
2323
<Item>3</Item>

src/react-elastic-carousel/components/Carousel.js

Lines changed: 59 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -137,13 +137,12 @@ class Carousel extends React.Component {
137137
this.slider.removeEventListener("transitionend", fn);
138138
};
139139

140-
getCurrentBreakpoint = () => {
141-
const { breakPoints, itemsToShow, itemsToScroll } = this.props;
140+
getDerivedPropsFromBreakPoint = () => {
141+
const { breakPoints, ...restOfProps } = this.props;
142142
const { sliderContainerWidth } = this.state;
143143

144144
// default breakpoint from individual props
145-
let currentBreakPoint = { itemsToScroll, itemsToShow };
146-
145+
let currentBreakPoint;
147146
// if breakpoints were added as props override the individual props
148147
if (breakPoints && breakPoints.length > 0) {
149148
currentBreakPoint = breakPoints
@@ -157,45 +156,22 @@ class Carousel extends React.Component {
157156
currentBreakPoint = breakPoints[0];
158157
}
159158
}
160-
return currentBreakPoint;
161-
};
162-
163-
/** We might get itemsToShow as a direct prop
164-
** Or we might get it as a prop inside a selected breakpoint.
165-
***/
166-
getCalculatedItemsToShow = () => {
167-
const { itemsToShow } = this.props;
168-
let visibleItems = itemsToShow;
169-
170-
const currentBreakPoint = this.getCurrentBreakpoint();
171-
if (currentBreakPoint) {
172-
visibleItems = currentBreakPoint.itemsToShow;
173-
}
174-
return visibleItems;
175-
};
176-
177-
/** We might get itemsToScroll as a direct prop
178-
** Or we might get it as a prop inside a selected breakpoint.
179-
***/
180-
getItemsToScroll = () => {
181-
const { itemsToScroll } = this.props;
182-
const currentBreakPoint = this.getCurrentBreakpoint();
183-
let effectiveItemsToScroll = itemsToScroll;
184-
if (currentBreakPoint && currentBreakPoint.itemsToScroll) {
185-
effectiveItemsToScroll = currentBreakPoint.itemsToScroll;
186-
}
187-
return effectiveItemsToScroll;
159+
// merge direct props with current breakpoint Props
160+
return { ...restOfProps, ...currentBreakPoint };
188161
};
189162

190163
updateSliderPosition = () => {
191-
this.setState((state, props) => {
192-
const { children, verticalMode } = props;
164+
this.setState(state => {
165+
const {
166+
children,
167+
verticalMode,
168+
itemsToShow
169+
} = this.getDerivedPropsFromBreakPoint();
193170
const { childWidth, childHeight, activeIndex } = state;
194171
const totalItems = children.length;
195-
const numOfVisibleItems = this.getCalculatedItemsToShow();
196-
const hiddenSlots = totalItems - numOfVisibleItems;
172+
const hiddenSlots = totalItems - itemsToShow;
197173
let moveBy = activeIndex * -1;
198-
const emptySlots = numOfVisibleItems - (totalItems - activeIndex);
174+
const emptySlots = itemsToShow - (totalItems - activeIndex);
199175
if (emptySlots > 0 && hiddenSlots > 0) {
200176
moveBy = emptySlots + activeIndex * -1;
201177
}
@@ -210,13 +186,16 @@ class Carousel extends React.Component {
210186
};
211187

212188
onSliderResize = sliderNode => {
213-
const { verticalMode, children } = this.props;
189+
const {
190+
verticalMode,
191+
children,
192+
itemsToShow
193+
} = this.getDerivedPropsFromBreakPoint();
214194
const { height } = sliderNode.contentRect;
215195
const nextState = {};
216196
if (verticalMode) {
217-
const numOfVisibleItems = this.getCalculatedItemsToShow();
218197
const childHeight = height / children.length;
219-
nextState.rootHeight = childHeight * numOfVisibleItems;
198+
nextState.rootHeight = childHeight * itemsToShow;
220199
nextState.childHeight = childHeight;
221200
} else {
222201
nextState.rootHeight = height;
@@ -225,15 +204,18 @@ class Carousel extends React.Component {
225204
};
226205

227206
onContainerResize = sliderContainerNode => {
228-
const { onResize, verticalMode } = this.props;
207+
const {
208+
onResize,
209+
verticalMode,
210+
itemsToShow
211+
} = this.getDerivedPropsFromBreakPoint();
229212
const { width } = sliderContainerNode.contentRect;
230213
// update slider container width
231214
this.setState({ sliderContainerWidth: width }, () => {
232215
/* based on slider container's width, get num of items to show
233216
* and calculate child's width (and update it in state)
234217
*/
235-
const visibleItems = this.getCalculatedItemsToShow();
236-
const childWidth = verticalMode ? width : width / visibleItems;
218+
const childWidth = verticalMode ? width : width / itemsToShow;
237219
this.setState(
238220
state => ({ childWidth }),
239221
() => {
@@ -243,7 +225,7 @@ class Carousel extends React.Component {
243225
* pass the current breakpoint to the consumer's callback
244226
*/
245227
this.updateSliderPosition();
246-
const currentBreakPoint = this.getCurrentBreakpoint();
228+
const currentBreakPoint = this.getDerivedPropsFromBreakPoint();
247229
onResize(currentBreakPoint);
248230
}
249231
);
@@ -274,13 +256,15 @@ class Carousel extends React.Component {
274256
};
275257

276258
getNextItemIndex = (currentIndex, getPrev) => {
277-
const { children } = this.props;
278-
const itemsToScroll = this.getItemsToScroll();
279-
const numOfvisibleItems = this.getCalculatedItemsToShow();
280-
const notEnoughItemsToshow = numOfvisibleItems > children.length;
281-
let limit = getPrev ? 0 : children.length - numOfvisibleItems;
259+
const {
260+
children,
261+
itemsToShow,
262+
itemsToScroll
263+
} = this.getDerivedPropsFromBreakPoint();
264+
const notEnoughItemsToShow = itemsToShow > children.length;
265+
let limit = getPrev ? 0 : children.length - itemsToShow;
282266

283-
if (notEnoughItemsToshow) {
267+
if (notEnoughItemsToShow) {
284268
limit = 0; // basically don't move
285269
}
286270
const nextAction = getPrev
@@ -312,15 +296,19 @@ class Carousel extends React.Component {
312296
onSwiping = data => {
313297
const { deltaX, absX, deltaY, absY, dir } = data;
314298

315-
this.setState((state, props) => {
299+
this.setState(state => {
316300
const {
317301
rootHeight,
318302
activeIndex,
319303
sliderPosition,
320304
sliderContainerWidth
321305
} = state;
322-
const { verticalMode, children, isRTL } = props;
323-
const itemsToShow = this.getCalculatedItemsToShow();
306+
const {
307+
itemsToShow,
308+
verticalMode,
309+
children,
310+
isRTL
311+
} = this.getDerivedPropsFromBreakPoint();
324312

325313
// determine how far can user swipe
326314
const isOnStart = activeIndex === 0;
@@ -519,23 +507,26 @@ class Carousel extends React.Component {
519507
};
520508

521509
goTo = nextItemId => {
522-
const { children, verticalMode } = this.props;
510+
const {
511+
children,
512+
verticalMode,
513+
itemsToShow
514+
} = this.getDerivedPropsFromBreakPoint();
523515
const { activeIndex } = this.state;
524516
const isPrev = activeIndex > nextItemId;
525517
const nextAvailbaleItem = this.getNextItemIndex(activeIndex, isPrev);
526-
const itemsToshow = this.getCalculatedItemsToShow();
527518
const noChange = nextAvailbaleItem === activeIndex;
528-
const outOfBoundry = nextItemId + itemsToshow >= children.length;
519+
const outOfBoundry = nextItemId + itemsToShow >= children.length;
529520
if (noChange) {
530521
return;
531522
}
532523
if (outOfBoundry) {
533-
if (children.length - itemsToshow > 0) {
534-
nextItemId = children.length - itemsToshow;
524+
if (children.length - itemsToShow > 0) {
525+
nextItemId = children.length - itemsToShow;
535526
} else {
536527
nextItemId = Math.max(
537528
children.length - 1,
538-
children.length - itemsToshow
529+
children.length - itemsToShow
539530
);
540531
}
541532
}
@@ -563,26 +554,25 @@ class Carousel extends React.Component {
563554
};
564555

565556
getNumOfPages = () => {
566-
const { children } = this.props;
567-
const numOfVisibleItems = this.getCalculatedItemsToShow();
568-
const numOfPages = Math.ceil(children.length / numOfVisibleItems);
557+
const { children, itemsToShow } = this.getDerivedPropsFromBreakPoint();
558+
const numOfPages = Math.ceil(children.length / itemsToShow);
569559
return numOfPages || 1;
570560
};
571561

572562
updateActivePage = () => {
573563
this.setState(state => {
564+
const { itemsToShow } = this.getDerivedPropsFromBreakPoint();
574565
const { activeIndex, activePage } = state;
575-
const numOfVisibleItems = this.getCalculatedItemsToShow();
576-
const newActivePage = Math.ceil(activeIndex / numOfVisibleItems);
566+
const newActivePage = Math.ceil(activeIndex / itemsToShow);
577567
if (activePage !== newActivePage) {
578568
return { activePage: newActivePage };
579569
}
580570
});
581571
};
582572

583573
onIndicatorClick = indicatorId => {
584-
const numOfVisibleItems = this.getCalculatedItemsToShow();
585-
const gotoIndex = indicatorId * numOfVisibleItems;
574+
const { itemsToShow } = this.getDerivedPropsFromBreakPoint();
575+
const gotoIndex = indicatorId * itemsToShow;
586576
this.setState({ activePage: indicatorId });
587577
this.goTo(gotoIndex);
588578
};
@@ -601,6 +591,7 @@ class Carousel extends React.Component {
601591
const {
602592
className,
603593
style,
594+
itemsToShow,
604595
verticalMode,
605596
isRTL,
606597
easing,
@@ -619,7 +610,7 @@ class Carousel extends React.Component {
619610
preventDefaultTouchmoveEvent,
620611
renderArrow,
621612
renderPagination
622-
} = this.props;
613+
} = this.getDerivedPropsFromBreakPoint();
623614

624615
const numOfPages = this.getNumOfPages();
625616

@@ -677,7 +668,7 @@ class Carousel extends React.Component {
677668
childWidth={childWidth}
678669
currentItem={activeIndex}
679670
autoTabIndexVisibleItems={autoTabIndexVisibleItems}
680-
itemsToShow={this.getCalculatedItemsToShow()}
671+
itemsToShow={itemsToShow}
681672
itemPosition={itemPosition}
682673
itemPadding={itemPadding}
683674
enableSwipe={enableSwipe}

0 commit comments

Comments
 (0)