Skip to content

Commit

Permalink
fic(Carousel): fix animation direction when using CarouselIndicators (
Browse files Browse the repository at this point in the history
#749)

Closes #748
  • Loading branch information
bmey authored and TheSharpieOne committed Mar 23, 2018
1 parent 21663c9 commit 0a15fe7
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 6 deletions.
18 changes: 14 additions & 4 deletions src/Carousel.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ class Carousel extends React.Component {
this.renderItems = this.renderItems.bind(this);
this.hoverStart = this.hoverStart.bind(this);
this.hoverEnd = this.hoverEnd.bind(this);
this.state = { direction: 'right' };
this.state = {
direction: 'right',
indicatorClicked: false,
};
}

getChildContext() {
Expand All @@ -36,10 +39,11 @@ class Carousel extends React.Component {
} else if (this.props.activeIndex - 1 === nextProps.activeIndex) {
this.setState({ direction: 'left' });
} else if (this.props.activeIndex > nextProps.activeIndex) {
this.setState({ direction: 'right' });
this.setState({ direction: this.state.indicatorClicked ? 'left' : 'right' });
} else if (this.props.activeIndex !== nextProps.activeIndex) {
this.setState({ direction: 'left' });
this.setState({ direction: this.state.indicatorClicked ? 'right' : 'left' });
}
this.setState({ indicatorClicked: false });
}

componentWillUnmount() {
Expand Down Expand Up @@ -145,13 +149,19 @@ class Carousel extends React.Component {

// Rendering indicators, slides and controls
const indicators = children[0];
const wrappedOnClick = (e) => {
if (typeof indicators.props.onClickHandler === 'function') {
this.setState({ indicatorClicked: true }, () => indicators.props.onClickHandler(e));
}
};
const wrappedIndicators = React.cloneElement(indicators, { onClickHandler: wrappedOnClick });
const carouselItems = children[1];
const controlLeft = children[2];
const controlRight = children[3];

return (
<div className={outerClasses} onMouseEnter={this.hoverStart} onMouseLeave={this.hoverEnd}>
{indicators}
{wrappedIndicators}
{this.renderItems(carouselItems, innerClasses)}
{controlLeft}
{controlRight}
Expand Down
78 changes: 76 additions & 2 deletions src/__tests__/Carousel.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,30 @@ describe('Carousel', () => {
});

describe('carouseling', () => {
it('should set indicatorClicked to true if indicator clicked', () => {
const slides = items.map((item, idx) => {
return (
<CarouselItem
key={idx}
>
<CarouselCaption captionText={item.caption} captionHeader={item.caption} />
</CarouselItem>
);
});

const wrapper = mount(
<Carousel activeIndex={0} next={() => { }} previous={() => { }}>
<CarouselIndicators items={items} activeIndex={0} onClickHandler={() => function () {}} />
{slides}
<CarouselControl direction="prev" directionText="Previous" onClickHandler={() => { }} />
<CarouselControl direction="next" directionText="Next" onClickHandler={() => { }} />
</Carousel>
);

wrapper.find(CarouselIndicators).find('li').first().simulate('click');
expect(wrapper.state().indicatorClicked).toEqual(true);
});

it('should go right when the index increases', () => {
const slides = items.map((item, idx) => {
return (
Expand Down Expand Up @@ -276,7 +300,7 @@ describe('Carousel', () => {
expect(wrapper.state().direction).toEqual('left');
});

it('should go right if transitioning from the last to first slide', () => {
it('should go right if transitioning from the last to first slide by non-indicator', () => {
const slides = items.map((item, idx) => {
return (
<CarouselItem
Expand All @@ -297,7 +321,32 @@ describe('Carousel', () => {
expect(wrapper.state().direction).toEqual('right');
});

it('should go left if transitioning from the first to last slide', () => {
it('should go left if transitioning from the last to first slide by indicator', () => {
const slides = items.map((item, idx) => {
return (
<CarouselItem
key={idx}
>
<CarouselCaption captionText={item.caption} captionHeader={item.caption} />
</CarouselItem>
);
});

const wrapper = mount(
<Carousel interval={1000} activeIndex={2} next={() => { }} previous={() => { }}>
<CarouselIndicators items={items} activeIndex={2} onClickHandler={() => { }} />
{slides}
<CarouselControl direction="prev" directionText="Previous" onClickHandler={() => { }} />
<CarouselControl direction="next" directionText="Next" onClickHandler={() => { }} />
</Carousel>
);

wrapper.setState({ indicatorClicked: true });
wrapper.setProps({ activeIndex: 0 });
expect(wrapper.state().direction).toEqual('left');
});

it('should go left if transitioning from the first to last slide by non-indicator', () => {
const slides = items.map((item, idx) => {
return (
<CarouselItem
Expand All @@ -319,6 +368,31 @@ describe('Carousel', () => {
});
});

it('should go right if transitioning from the first to last slide by indicator', () => {
const slides = items.map((item, idx) => {
return (
<CarouselItem
key={idx}
>
<CarouselCaption captionText={item.caption} captionHeader={item.caption} />
</CarouselItem>
);
});

const wrapper = mount(
<Carousel interval={1000} activeIndex={0} next={() => { }} previous={() => { }}>
<CarouselIndicators items={items} activeIndex={0} onClickHandler={() => { }} />
{slides}
<CarouselControl direction="prev" directionText="Previous" onClickHandler={() => { }} />
<CarouselControl direction="next" directionText="Next" onClickHandler={() => { }} />
</Carousel>
);

wrapper.setState({ indicatorClicked: true });
wrapper.setProps({ activeIndex: 2 });
expect(wrapper.state().direction).toEqual('right');
});

describe('interval', () => {
it('should not autoplay by default', () => {
const next = jest.fn();
Expand Down

0 comments on commit 0a15fe7

Please sign in to comment.