akiran / react-slick

React carousel component
http://react-slick.neostack.com/
MIT License
11.72k stars 2.1k forks source link

Custom arrows? #111

Closed abdelav closed 9 years ago

abdelav commented 9 years ago

What is the correct way to use custom arrows ?

thanks

vramana commented 9 years ago

I think that you need write your own css class .slick-arrow that will do the job I guess or your can pass your custom react components as prevArrow and nextArrow . I think it should work, I haven't tried it though. If you have face any problems, we will help you.

abdelav commented 9 years ago

passing a custom component as parameter change the style pretty well, but the next event handler doesn't work

vramana commented 9 years ago

Can you write an example so I have something to debug on?

brennanerbz commented 9 years ago

Any update on custom arrows?

vramana commented 9 years ago

@abdelav The next Event handler works just props of your Custom arrow component to the actual DOM element.

@brennanerbz Custom arrows works. Just need to declare it correctly.

chemoish commented 9 years ago

Do you have an example of this @vramana.

I haven't been able to configure it correctly. https://github.com/akiran/react-slick/pull/32 (Discussion)

vramana commented 9 years ago

@chemoish Let's say your custom arrow component is CustomPrevArrow then pass it as <Slider prevArrow={CustomPrevArrow} >. This should work.

chemoish commented 9 years ago

Did you have a chance to read the discussion of #32?

Unless I am missing something drastic, I don't believe it works.

The end goal is to add a simple slick-arrow class to the buttons.

vramana commented 9 years ago

@chemoish Have you tried this or you are believing that it doesn't work? If it doesn't work, I can tell a fix for this.

chemoish commented 9 years ago

I have tried a bunch of different implementations, including but not limited to…

var settings = {
  nextArrow: React.createClass({
    render: function () {
      return (
        <button {...this.props}></button>
      );
    }
  })
};

<Slider {...settings}></Slider>

var settings = {
  nextArrow: React.createClass({
    render: function () {
      return (
        <button class="slick-arrow" {...this.props}></button>
      );
    }
  })
};

<Slider nextArrow={...settings}></Slider>

var settings = {
  nextArrow: React.createClass({
    render: function () {
      return (
        <button class="slick-arrow"></button>
      );
    }
  })
};

<Slider {...settings}></Slider>

var nextArrow = React.createClass({
  render: function () {
    return (
      <button class="slick-arrow"></button>
    );
  }
});

<Slider nextArrow={nextArrow}></Slider>

var nextArrow = React.createClass({
  componentDidUpdate: function () {
    this.refs.next.getDOMNode().className += ' slick-arrow';
  },

  render: function () {
    return (
      <button ref="next" {...this.props}></button>
    );
  }
});

<Slider nextArrow={nextArrow}></Slider>

<Slider nextArrow={<button class="slick-arrow"></button>}></Slider>

No avail.


However, if you look at the code for...

https://github.com/akiran/react-slick/blob/master/src/inner-slider.jsx https://github.com/akiran/react-slick/blob/master/src/arrows.jsx

Unless I am missing something drastic, I don't believe it works.

vramana commented 9 years ago

var nextArrow = React.createClass({

The name of the component has to start with a capital letter. React differentiates dom elements and React elements using this strategy. I have read about this somewhere. That may be the problem.

msalli commented 8 years ago

The click event wasn't working for me at first as well, but figured out that you need to pass this.props.onClick to your custom component. I think that's what @vramana was trying to say, but I didn't understand. (You can also pass {...this.props} and it works just the same.)

My code looks like this and the event is working!

var ProductSlider = React.createClass({

  propTypes: {
    items: React.PropTypes.array,
    slidesToShow: React.PropTypes.number,
    slidesToScroll: React.PropTypes.number,
  },

  render() {
    var settings = {
      dots: false,
      infinite: true,
      speed: 500,
      prevArrow: CustomPrevArrow,
      slidesToShow: this.props.slidesToShow,
      slidesToScroll: this.props.slidesToScroll,
      responsive: [{breakpoint: 768, settings: {slidesToShow: 1, slidesToScroll: 1}}, {breakpoint: 1024, settings: {slidesToShow: 3, slidesToScroll: 3}}]
    }

    return (
      <Slider { ...settings } >
        {this.props.items.map(i => <div>{i}</div>)}
      </Slider>
    )
  }

})

var CustomPrevArrow = React.createClass({
  render() {
    return (
      <button type="button" className="slick-prev" onClick={this.props.onClick}>What</button>
    )
  }
})
chemoish commented 8 years ago

Thats what this.props is doing. I was trying to override the className. Everything else is fine.

Pave91 commented 8 years ago

What if I want to add new functionality to onClick event of arrows? Does it exist any way how to keep functionality of arrow and at the same time add my own on the top of it?

blairanderson commented 8 years ago

@Pave91 the default button receives a clickHandler prop, so you can do something like this:

var CustomPrevArrow = React.createClass({

  newFunctionality(e) {
    this.doMoreStuff()
    this.props.onClick(e)
  }

  render() {
    return (
      <button type="button" className="slick-prev" onClick={this.newFunctionality}>What</button>
    )
  }
})

source code is here:

https://github.com/akiran/react-slick/blob/master/src/arrows.jsx#L8-L11

hafeez1042 commented 8 years ago

+1

Please add an example

bhuten commented 8 years ago

It worked for me finally and here is what I did: <Slider {...settings} prevArrow={PrevArrow}> </Slider>

Make sure to import your PrevArrow component. And in your PrevArrow component, return the following: <IconButton className="slickArrowPrev" onClick={this.props.onClick} iconClassName="fa fa-chevron-circle-left" />

Similarly you should have NextArrow component. Styling the arrows is little bit of work but it should be fairly easy.

Note: I am using font awesome for the next and prev icon. And IconButton is a material UI component. You can simply replace it with button tag if you are not familiar with material UI.

omenlog commented 8 years ago

I have tried diferent implementations without any results,here is my code

code.jsx.zip

The browser console return this error

Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined.

Any Ideas???

kasperkronborg commented 8 years ago

@tuxjs I'm getting the same thing, and I'm following the example given by the author in the README.

A clear working example would be great.

akiran commented 8 years ago

Check this https://github.com/akiran/react-slick/blob/master/docs/demos.jsx#L447-L485

miketrexler commented 7 years ago

I had to pass in the component as JSX, rather than the component name. That is what caused the "Element type is invalid" error for me.

See the example below:

const NextArrow = function(props) {
  return (
    <div {...this.props}>
      <img src="/images/arrow_next.png" />
    </div>
  );
};

const PrevArrow = function(props) {
  return (
    <div {...this.props}>
      <img src="/images/arrow_prev.png" />
    </div>
  );
};

And in the component which renders <Slider />:

const settings = {
  arrows: true,
  nextArrow: <NextArrow />,
  prevArrow: <PrevArrow />
};

<Slider
  className="Slider"
  {...settings}>
</Slider>

I did not need to add an onClick handler to the arrows, that was taken care of by {...props}.

Axelest commented 7 years ago

Dude Cannot read property 'props' of undefined why?

mnishiguchi commented 7 years ago
  1. Check the examples section in this repo https://github.com/akiran/react-slick/blob/master/examples/CustomArrows.js

  2. Edit slick-theme.css https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick-theme.css

function SampleNextArrow(props) {
  const {className, style, onClick} = props
  return (
    <div
      className={className}
      style={{...style, display: 'block', background: 'red'}}
      onClick={onClick}
    ></div>
  );
}

function SamplePrevArrow(props) {
  const {className, style, onClick} = props
  return (
    <div
      className={className}
      style={{...style, display: 'block', background: 'green'}}
      onClick={onClick}
    ></div>
  );
}
export default class CustomArrows extends Component {
  render() {
    const settings = {
      dots: true,
      infinite: true,
      slidesToShow: 3,
      slidesToScroll: 1,
      nextArrow: <SampleNextArrow />,
      prevArrow: <SamplePrevArrow />
    };
    return (
      <div>
        <h2>Custom Arrows</h2>
        <Slider {...settings}>
          <div><h3>1</h3></div>
          <div><h3>2</h3></div>
          <div><h3>3</h3></div>
          <div><h3>4</h3></div>
          <div><h3>5</h3></div>
          <div><h3>6</h3></div>
        </Slider>
      </div>
    );
  }
}
phtn commented 6 years ago

import React from 'react'
import Slider from 'react-slick'
import 'slick-carousel/slick/slick.css'
import 'slick-carousel/slick/slick-theme.css'

// import custom arrow
import Next from '../assets/chevronRight.svg'`

// declare component
const Right = props => (
  <div>
    <img src={Next} onClick={props.onClick}  className='slick-next' />
  </div>
)

// slider settings 
const settings = {
  arrows: true,
  nextArrow: <Right/>
}

// main component
export default props => (
  <div>
    <Slider {...settings}>
      <div>1</div>
      <div>2</div>
    </Slider>
  </div>
)
mustkem commented 6 years ago

Event handler is not working. Unfortunately It seems i am missing something.

My code looks like this

function SampleNextArrow(props) {
    const { className, style, onClick } = props;
    return (

      <div
        className={className}
        style={{ ...style, display: "block", background: "red" }}
        onClick={onClick}
      >whattt</div>
    );
  }

/* inside default class / //constructor

 this.settings = {
            customPaging: (i) => {
                return (
                  <div className="thumb">
                    <img alt="thumb" src={this.props.sliderData.slider[i].thumbnail.src} />
                  </div>
                );
            },
            dots: true,
            infinite: true,
            speed: 500,
            slidesToScroll: 1,
            slidesToShow: 1,
            nextArrow: <SampleNextArrow onClick={this.sliderHandler.bind(this)} />
        };

// and handler //

sliderHandler(dir) {
      console.log("slide moved")
    }

I am not getting in this sliderHandler.

Code seems all good. Am I missing something....

annjawn commented 5 years ago

It's 2019 and the Arrows still cannot accept React components.

blairanderson commented 5 years ago

@annjawn nobody owes you anything. read through this ticket and you'll figure it out.

annjawn commented 5 years ago

@blairanderson Never said that anyone owed me anything, just pointing out the fact that it still doesn’t accept React components and documentation isn’t that clear. But thanks for the nice reply. I can come down to your level and respond to your hostility, but then there’d be no difference between you and me. Have a nice day!

xNOVA2 commented 10 months ago

still not fucking working spend 6 hours on this shit library