Skip to content

Commit

Permalink
feat(carousel): add Bootstrap5 updates
Browse files Browse the repository at this point in the history
- Use renamed RTL class names

- Updates indicator markup and selectors for correct styling

- Add support for carousel-fade
  • Loading branch information
bestguy authored and phwebi committed Oct 27, 2021
1 parent 02b3b71 commit a698814
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 28 deletions.
14 changes: 8 additions & 6 deletions src/Carousel.js
Expand Up @@ -19,7 +19,7 @@ class Carousel extends React.Component {
this.touchStartY = 0;
this.state = {
activeIndex: this.props.activeIndex,
direction: 'right',
direction: 'end',
indicatorClicked: false,
};
}
Expand All @@ -45,13 +45,13 @@ class Carousel extends React.Component {
if (nextProps.activeIndex !== activeIndex) {
// Calculate the direction to turn
if (nextProps.activeIndex === activeIndex + 1) {
direction = 'right';
direction = 'end';
} else if (nextProps.activeIndex === activeIndex -1) {
direction = 'left';
direction = 'start';
} else if (nextProps.activeIndex < activeIndex) {
direction = indicatorClicked ? 'left' : 'right';
direction = indicatorClicked ? 'start' : 'end';
} else if (nextProps.activeIndex !== activeIndex) {
direction = indicatorClicked ? 'right' : 'left';
direction = indicatorClicked ? 'end' : 'start';
}

newState = {
Expand Down Expand Up @@ -166,10 +166,11 @@ class Carousel extends React.Component {
}

render() {
const { cssModule, slide, className, dark } = this.props;
const { cssModule, slide, className, dark, fade } = this.props;
const outerClasses = mapToCssModules(classNames(
className,
'carousel',
'carousel-fade' && fade,
slide && 'slide',
dark && 'carousel-dark'
), cssModule);
Expand Down Expand Up @@ -274,6 +275,7 @@ Carousel.defaultProps = {
keyboard: true,
slide: true,
enableTouch: true,
fade: false,
};

Carousel.childContextTypes = {
Expand Down
12 changes: 8 additions & 4 deletions src/CarouselIndicators.js
Expand Up @@ -12,20 +12,24 @@ const CarouselIndicators = (props) => {
{ active: activeIndex === idx }
), cssModule);
return (
<li
<button
aria-label={item.caption}
data-bs-target
key={`${item.key || Object.values(item).join('')}`}
onClick={(e) => {
e.preventDefault();
onClickHandler(idx);
}}
className={indicatorClasses}
/>);
>
{item.caption}
</button>);
});

return (
<ol className={listClasses}>
<div className={listClasses}>
{indicators}
</ol>
</div>
);
};

Expand Down
4 changes: 2 additions & 2 deletions src/CarouselItem.js
Expand Up @@ -68,9 +68,9 @@ class CarouselItem extends React.Component {
const isActive = (status === TransitionStatuses.ENTERED) || (status === TransitionStatuses.EXITING);
const directionClassName = (status === TransitionStatuses.ENTERING || status === TransitionStatuses.EXITING) &&
this.state.startAnimation &&
(direction === 'right' ? 'carousel-item-left' : 'carousel-item-right');
(direction === 'end' ? 'carousel-item-start' : 'carousel-item-end');
const orderClassName = (status === TransitionStatuses.ENTERING) &&
(direction === 'right' ? 'carousel-item-next' : 'carousel-item-prev');
(direction === 'end' ? 'carousel-item-next' : 'carousel-item-prev');
const itemClasses = mapToCssModules(classNames(
className,
'carousel-item',
Expand Down
32 changes: 16 additions & 16 deletions src/__tests__/Carousel.spec.js
Expand Up @@ -55,27 +55,27 @@ describe('Carousel', () => {

describe('transitions', () => {
it('should add the appropriate classes when entering right', () => {
const wrapper = mount(<CarouselItem in={false} />, { context: { direction: 'right' } });
const wrapper = mount(<CarouselItem in={false} />, { context: { direction: 'end' } });

wrapper.setProps({ in: true });
expect(wrapper.update().find('div').prop('className')).toEqual('carousel-item carousel-item-left carousel-item-next');
expect(wrapper.update().find('div').prop('className')).toEqual('carousel-item carousel-item-start carousel-item-next');
jest.runTimersToTime(600);
expect(wrapper.update().find('div').prop('className')).toEqual('carousel-item active');
wrapper.setProps({ in: false });
expect(wrapper.update().find('div').prop('className')).toEqual('carousel-item active carousel-item-left');
expect(wrapper.update().find('div').prop('className')).toEqual('carousel-item active carousel-item-start');
jest.runTimersToTime(600);
expect(wrapper.update().find('div').prop('className')).toEqual('carousel-item');
});

it('should add the appropriate classes when entering left', () => {
const wrapper = mount(<CarouselItem in={false} />, { context: { direction: 'left' } });
const wrapper = mount(<CarouselItem in={false} />, { context: { direction: 'start' } });

wrapper.setProps({ in: true });
expect(wrapper.update().find('div').prop('className')).toEqual('carousel-item carousel-item-right carousel-item-prev');
expect(wrapper.update().find('div').prop('className')).toEqual('carousel-item carousel-item-end carousel-item-prev');
jest.runTimersToTime(600);
expect(wrapper.update().find('div').prop('className')).toEqual('carousel-item active');
wrapper.setProps({ in: false });
expect(wrapper.update().find('div').prop('className')).toEqual('carousel-item active carousel-item-right');
expect(wrapper.update().find('div').prop('className')).toEqual('carousel-item active carousel-item-end');
jest.runTimersToTime(600);
expect(wrapper.update().find('div').prop('className')).toEqual('carousel-item');
});
Expand Down Expand Up @@ -114,8 +114,8 @@ describe('Carousel', () => {
describe('indicators', () => {
it('should render a list with the right number of items', () => {
const wrapper = mount(<CarouselIndicators items={items} activeIndex={0} onClickHandler={() => { }} />);
expect(wrapper.find('ol').length).toEqual(1);
expect(wrapper.find('li').length).toEqual(3);
expect(wrapper.find('div').length).toEqual(1);
expect(wrapper.find('button').length).toEqual(3);
});

it('should append the correct active class', () => {
Expand All @@ -126,7 +126,7 @@ describe('Carousel', () => {
it('should call the click hanlder', () => {
const onClick = jest.fn();
const wrapper = mount(<CarouselIndicators items={items} activeIndex={0} onClickHandler={onClick} />);
wrapper.find('li').first().simulate('click');
wrapper.find('button').first().simulate('click');
expect(onClick).toHaveBeenCalled();
});
});
Expand Down Expand Up @@ -314,7 +314,7 @@ describe('Carousel', () => {
</Carousel>
);

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

Expand All @@ -336,7 +336,7 @@ describe('Carousel', () => {
);

wrapper.setProps({ activeIndex: 1 });
expect(wrapper.state().direction).toEqual('right');
expect(wrapper.state().direction).toEqual('end');
});

it('should go left when the index decreases', () => {
Expand All @@ -357,7 +357,7 @@ describe('Carousel', () => {
);

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

it('should go right if transitioning from the last to first slide by non-indicator', () => {
Expand All @@ -378,7 +378,7 @@ describe('Carousel', () => {
);

wrapper.setProps({ activeIndex: 0 });
expect(wrapper.state().direction).toEqual('right');
expect(wrapper.state().direction).toEqual('end');
});

it('should go left if transitioning from the last to first slide by indicator', () => {
Expand All @@ -403,7 +403,7 @@ describe('Carousel', () => {

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

it('should go left if transitioning from the first to last slide by non-indicator', () => {
Expand All @@ -424,7 +424,7 @@ describe('Carousel', () => {
);

wrapper.setProps({ activeIndex: 2 });
expect(wrapper.state().direction).toEqual('left');
expect(wrapper.state().direction).toEqual('start');
});
});

Expand All @@ -450,7 +450,7 @@ describe('Carousel', () => {

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

describe('interval', () => {
Expand Down
1 change: 1 addition & 0 deletions types/lib/Carousel.d.ts
Expand Up @@ -12,6 +12,7 @@ interface CommonCarouselProps extends React.HTMLAttributes<HTMLElement> {
mouseExit?: () => void;
slide?: boolean;
dark?: boolean;
fade?: boolean;
cssModule?: CSSModule;
enableTouch?: boolean;
}
Expand Down

0 comments on commit a698814

Please sign in to comment.