Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add slick-active class in Slider dots in React Slick

I used react-slick and made a carousel using Slider component. The code is bellow,

const carousel = (props) => {
    return (
        <div style={{ height: '50%', marginTop: '20px' }}>
            <Slider {...settings}>
                <div className={text__bar}>
                    <div >
                        <font>Lorum Ipsum 1</font>
                    </div>
                    <div className={slide1} />
                </div>
                <div className={text__bar}>
                    <div>
                        <font>Lorum Ipsum 2</font>
                    </div>
                    <div className={slide1} />
                </div>
                <div className={text__bar}>
                    <div>
                        <font>Lorum Ipsum 3</font>
                    </div>
                    <div className={slide1} />
                </div>
            </Slider>
            <div className={purple__bar}></div>
        </div>
    );
};

And the settings object,

const settings = {
    dots: true,
    infinite: true,
    speed: 500,
    slidesToShow: 1,
    slidesToScroll: 1,
    autoplay: true,
    autoplaySpeed: 5000,
    className: SlickMain,
    dotsClass: button__bar,
    arrows: false,
};

I have added some extra CSS to style my carousel dots (buttons) to look like bellow,

dotbar

When examined by the developer tools the button related to the currently shown slide gets a CSS class injected named 'slick-active'

injected-class

What I need to do is change the background color of the button corresponding to the slide, to black relapsing the current color purple.

What I did was,

.button__bar li.slick-active button {
    opacity: .75;
    color: #000
}

But it won't work. What am I missing?

.button__bar is the dotsClass I have given to dots in settings object.

like image 987
sajithneyo Avatar asked Dec 13 '22 12:12

sajithneyo


2 Answers

This is happening because I'm using CSS-Modules to load my CSS file. In the following code example, you can clearly see what's happening.

https://codesandbox.io/s/1z2lnox5rq?fontsize=14

So as a solution what I did was adding bellow methods to settings object.

const settings = {
  dots: true,
  infinite: true,
  speed: 1000,
  slidesToShow: 1,
  slidesToScroll: 1,
  autoplay: true,
  autoplaySpeed: 3000,
  className: slickMain,
  dotsClass: button__bar,
  arrows: false,
  beforeChange: (prev, next) => {
    this.setState({ currentSlide: next });
  },
  // afterChange: (index) => this.setState({ currentSlide: index }),
  appendDots: dots => {
    return (
      <div>
        <ul>
          {dots.map((item, index) => {
            return (
              <li key={index}>{item.props.children}</li>
            );
          })}
        </ul>
      </div>
    )
  },
  customPaging: index => {
    return (
      <button style={index === this.state.currentSlide ? testSettings : null}>
        {index + 1}
      </button>
    )
  }
};

To solve my problem, I used beforeChange to acquire the next slide index and saved it in the state. Then using appendDots a div with a ul, li is injected to the dot-bar section which. Inside the li, a button passed as a child prop using customPaging method. When the current slide equals the index of the customPaging, which is in the state, then a class is injected with a background color.

const testSettings = {
    backgroundColor: 'rgba(255, 255, 255, 0.8)',
    outline: '0'
}
like image 96
sajithneyo Avatar answered Dec 17 '22 22:12

sajithneyo


In case someone is using material ui here is how it could work

const settings: Settings = {
  dots: true,
  infinite: true,
  speed: 500,
  slidesToShow: 1,
  slidesToScroll: 1,
  dotsClass: `slick-dots ${classes.dots}`,
};
// your classes created with material ui
makeStyles((theme: Theme) => ({
// may not be the best way but it works
  dots: {
    bottom: 0,
    "& li.slick-active button::before": {
      color: theme.palette.primary.main,
    },
    "& li": {
      "& button::before": {
      fontSize: theme.typography.pxToRem(14),
      color: "#fff",
      opacity: 0.5,
    },
  }
}))

Here is a codesandbox link https://codesandbox.io/s/bold-snow-h9rwq?file=/src/App.tsx

Please note, that I haven't checked it with importing slick css i.e.

// Import css files
import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";

but used cdn instead

like image 45
Alexander Tarasenko Avatar answered Dec 18 '22 00:12

Alexander Tarasenko