akiran / react-slick

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

Keyboard control for navigation slider #1893

Open mathiasha opened 4 years ago

mathiasha commented 4 years ago

When running 2 sliders on the same page, where one of the sliders is in "asNavFor"-mode there is no keyboard access to the navigation slider. I can't tab to the bottom slider and activate it via the keyboard. As far as I can tell all the items in the "navigation slider" has tabindex="-1" making them unreachable via keyboard.

Here is an example: https://codesandbox.io/s/react-slick-playground-forked-mc4c1

akiran commented 4 years ago

Keyboard navigation in the codesandbox you provided is working for me.

You have to click once to bring slider to focus. After that keyboard navigation works

mathiasha commented 4 years ago

Yes, exactly, that's the point. I have to click on it. But I am trying to make my site accessible in accordance to the WCAG 2.1 guidlines, so I need the slider to controllable by keyboard alone.

akiran commented 4 years ago

Can you create a PR with fix?

mathiasha commented 4 years ago

After looking a bit further into it i think maybe the issue is related to Slick itself, and not just your implementation of the slider.

odididi commented 4 years ago

Maybe not super relevant, but here's how i managed to set focus to the slider on mount. Maybe it can get you somewhere @mathiasha.

const Slider = ({children}) => {
  const sliderRef = React.useRef(null);
  React.useEffect(() => {
    const track = sliderRef.current.innerSlider.list.querySelector('.slick-track');
    const focusSlider = setTimeout(() => {
      const slide = track.querySelector('.slick-slide');
      slide.focus();
    }, 0);
    return () => clearTimeout(focusSlider);
  }, []);
  const handleNextClick = () => sliderRef.current.slickNext();
  const handlePrevClick = () => sliderRef.current.slickPrev();
  return (
    <Container>
      <NextArrow onClick={handleNextClick} />
      <PrevArrow onClick={handlePrevClick} />
      <SlickSlider
        arrows={false}
        infinite
        slidesToShow={1}
        ref={sliderRef}
      >
        {children}
      </SlickSlider>
    </Container>
  );
};