Swiper: Swiper React custom navigation components

Created on 29 Aug 2020  路  5Comments  路  Source: nolimits4web/swiper

This is a:

  • [x] bug
  • [ ] enhancement
  • [ ] feature-discussion (RFC)
  • Swiper Version: [email protected].

  • Live Link or JSFiddle/Codepen or website with isssue: PREFERABLY _(IF YOU WANT YOUR ISSUE TO BE RESOLVED ASAP)_.

What you did

I set navigation property
<Swiper navigation={{ navigation: { nextEl: (<div className='next'></div>), prevEl: (<div className='next'></div>) }}> ... </Swiper>

Expected Behavior

I want to see my own navigation buttons

Actual Behavior

The navigation isn't there, nither the original. It's like "navigation: false".

Thanks in advance

Most helpful comment

@awt0523 If you check the Typescript interface from navigation, it can receives an object with nextEl and prevEl and both can receive a CSSSelector or HTMLElement and yeah, for some reason they aren't showing.

@MacGyver98 To get around this, I ended up creating a useRef in the swipe to access the slideNext and slidePrev methods, here's an example.

import React, { useCallback, useRef } from 'react';
import { Swiper, SwiperSlide } from 'swiper/react';
import SwiperCore, { Autoplay } from 'swiper';

function Swiper() {
  const swiperRef = useRef(null);
  SwiperCore.use([Autoplay]); // don't need navigation anymore

  const prevSlide = useCallback(() => {
    swiperRef.current?.swiper.slidePrev();
  }, [swiperRef]);

  const nextSlide = useCallback(() => {
    swiperRef.current?.swiper.slideNext();
  }, [swiperRef]);

  return (
    <>
      <div className="left-floating-el" onClick={prevSlide}>
        an floating element
      </div>
      <Swiper
        ref={swiperRef}
        spaceBetween={30}
        slidesPerView={5}
        autoplay={{ delay: 5000 }}
        loop
      >
        <SwiperSlide>slide 1</SwiperSlide>
        <SwiperSlide>slide 2</SwiperSlide>
      </Swiper>
      <div className="right-floating-el" onClick={nextSlide}>
        an floating element
      </div>
    </>
  );
}

All 5 comments

Navigation is possible with boolean, and the default value is true.

navigation>
Try

Just before
swiper.use([Navigation]) should be declared

you should document is recheck
https://swiperjs.com/react/

@awt0523 If you check the Typescript interface from navigation, it can receives an object with nextEl and prevEl and both can receive a CSSSelector or HTMLElement and yeah, for some reason they aren't showing.

@MacGyver98 To get around this, I ended up creating a useRef in the swipe to access the slideNext and slidePrev methods, here's an example.

import React, { useCallback, useRef } from 'react';
import { Swiper, SwiperSlide } from 'swiper/react';
import SwiperCore, { Autoplay } from 'swiper';

function Swiper() {
  const swiperRef = useRef(null);
  SwiperCore.use([Autoplay]); // don't need navigation anymore

  const prevSlide = useCallback(() => {
    swiperRef.current?.swiper.slidePrev();
  }, [swiperRef]);

  const nextSlide = useCallback(() => {
    swiperRef.current?.swiper.slideNext();
  }, [swiperRef]);

  return (
    <>
      <div className="left-floating-el" onClick={prevSlide}>
        an floating element
      </div>
      <Swiper
        ref={swiperRef}
        spaceBetween={30}
        slidesPerView={5}
        autoplay={{ delay: 5000 }}
        loop
      >
        <SwiperSlide>slide 1</SwiperSlide>
        <SwiperSlide>slide 2</SwiperSlide>
      </Swiper>
      <div className="right-floating-el" onClick={nextSlide}>
        an floating element
      </div>
    </>
  );
}

You could also use Swiper Slots to place your navigation buttons within the .swiper-container which is where Swiper places it's own navigation buttons.

<Swiper ref={swiperRef} {...other}>
  <span slot="container-start">
    <div className="left-floating-el" onClick={prevSlide}>
      an floating element
    </div>
    <div className="right-floating-el" onClick={nextSlide}>
      an floating element
    </div>
  </span>

  <SwiperSlide>slide 1</SwiperSlide>
  <SwiperSlide>slide 2</SwiperSlide>
</Swiper>

The issue here is that you lose functionality for getting the .swiper-button-disabled className and the A11y module not setting the aria-disabled or tabindex attributes. Therefore I am also in need of being able to pass custom navigation elements. Ideally I would want to do something like below.

import React from 'react'
import SwiperCore, { A11y, Navigation } from 'swiper'
import { Swiper, SwiperSlide } from 'swiper/react'
import ArrowBackwardIosIcon from '@material-ui/icons/ArrowBackwardIos'
import ArrowForwardIosIcon from '@material-ui/icons/ArrowForwardIos'
import IconButton from '@material-ui/core/IconButton'

SwiperCore.use([A11y, Navigation])

const Swiper = () => (
  <Swiper
    navigation={{
      prevEl: <IconButton><ArrowBackwardIosIcon /></IconButton>,
      nextEl: <IconButton><ArrowForwardIosIcon /></IconButton>,
    }}
  >
    <SwiperSlide>slide 1</SwiperSlide>
    <SwiperSlide>slide 2</SwiperSlide>
  </Swiper>
)

As to documentation nextEl and prevEl receive HTMLElement or string with CSS selector, so it should be:

  <Swiper
    navigation={{
      prevEl: '.prev',
      nextEl: '.next',
    }}
  >
    <SwiperSlide>slide 1</SwiperSlide>
    <SwiperSlide>slide 2</SwiperSlide>
    <div className="prev" />
    <div className="next" />
  </Swiper>

Oh I see! Works like a charm, thanks 馃憤

Was this page helpful?
0 / 5 - 0 ratings