The Carousel component is flickering on our Careers page in this code. It happens because the rect.width
is flickering from the correct value to a larger incorrect value when the temporary DOM nodes are added during drag.
import React from 'react';
import { ThemedLink } from '@thumbtack/tp-ui-react-link';
import { NavigationCaretLeftMedium, NavigationCaretRightMedium } from '@thumbtack/thumbprint-icons';
import ThumbprintCarousel from '@thumbtack/tp-ui-react-carousel';
import classNames from 'classnames';
import './styles/carousel.scss';
/**
* Compute modulo in JavaScript. This is needed because `%` doesn't handle negative numbers.
* https://dev.to/maurobringolf/a-neat-trick-to-compute-modulo-of-negative-numbers-111e
*/
const mod = (x, n) => (x % n + n) % n;
export default class Carousel extends React.Component {
constructor(props) {
super(props);
this.state = {
selectedIndex: 0,
};
this.goToSlide = this.goToSlide.bind(this);
}
goToSlide(newIndex) {
this.setState({
selectedIndex: Math.round(newIndex),
});
}
render() {
const { selectedIndex } = this.state;
// TODODODO: This number is needed for the dots to work. Change it before merging.
const numItems = 3;
return (
<div className="carousel ph4 s_ph6 m_ph7 bg-black">
<ThumbprintCarousel
selectedIndex={selectedIndex}
onSelectedIndexChange={this.goToSlide}
>
<div className="carousel-pane">
<div className="mw8">
<div className="b white mb3">Whatโs special about working here?</div>
<div className="carousel-quote tp-title-1 white mb4">
I think itโs amazing that I just said, โI want to try mobileโ and
people were willing to make that happen.
</div>
<div className="b white mb4">
Heidy Hernandez Breton, Mobile Engineer
</div>
<ThemedLink
theme="primary"
size="small"
to="https://medium.com/life-thumbtack/get-to-know-heidy-hernandez-breton-mobile-engineer-at-thumbtack-71f909b5cb61"
>
Meet Heidy
</ThemedLink>
</div>
</div>
<div className="carousel-pane">
<div className="mw8">
<div className="b white mb3">Whatโs special about working here?</div>
<div className="carousel-quote tp-title-1 white mb4">
I think itโs amazing that I just said, โI want to try mobileโ and
people were willing to make that happen.
</div>
<div className="b white mb4">
Heidy Hernandez Breton, Mobile Engineer
</div>
<ThemedLink
theme="primary"
size="small"
to="https://medium.com/life-thumbtack/get-to-know-heidy-hernandez-breton-mobile-engineer-at-thumbtack-71f909b5cb61"
>
Meet Heidy
</ThemedLink>
</div>
</div>
<div className="carousel-pane">
<div className="mw8">
<div className="b white mb3">Whatโs special about working here?</div>
<div className="carousel-quote tp-title-1 white mb4">
I think itโs amazing that I just said, โI want to try mobileโ and
people were willing to make that happen.
</div>
<div className="b white mb4">
Heidy Hernandez Breton, Mobile Engineer
</div>
<ThemedLink
theme="primary"
size="small"
to="https://medium.com/life-thumbtack/get-to-know-heidy-hernandez-breton-mobile-engineer-at-thumbtack-71f909b5cb61"
>
Meet Heidy
</ThemedLink>
</div>
</div>
</ThumbprintCarousel>
<div className="carousel-nav">
<button
aria-label="Previous slide"
className="carousel-button carousel-nav carousel-nav-left"
onClick={() => {
this.goToSlide(selectedIndex - 1);
}}
>
<NavigationCaretLeftMedium className="white db" />
</button>
<button
aria-label="Next slide"
className="carousel-button carousel-nav carousel-nav-right"
onClick={() => {
this.goToSlide(selectedIndex + 1);
}}
>
<NavigationCaretRightMedium className="white db" />
</button>
</div>
<div className="carousel-dot-wrap">
<button
aria-label="Go to first slide"
className={classNames({
'carousel-button carousel-dot': true,
'is-active': mod(selectedIndex, numItems) === 0,
})}
onClick={() => {
this.goToSlide(0);
}}
/>
<button
aria-label="Go to second slide"
className={classNames({
'carousel-button carousel-dot': true,
'is-active': mod(selectedIndex, numItems) === 1,
})}
onClick={() => {
this.goToSlide(1);
}}
/>
<button
aria-label="Go to third slide"
className={classNames({
'carousel-button carousel-dot': true,
'is-active': mod(selectedIndex, numItems) === 2,
})}
onClick={() => {
this.goToSlide(2);
}}
/>
</div>
</div>
);
}
}