Keen Slider

Easily create sliders, carousels and much more

Default
swiper 1
swiper 2
swiper 3
swiper 4
swiper 5

// ** MUI Imports
import Box from '@mui/material/Box'
import { Direction } from '@mui/material'

// ** Third Party Components
import { useKeenSlider } from 'keen-slider/react'

const SwiperDefault = ({ direction }: { direction: Direction }) => {
  // ** Hook
  const [ref] = useKeenSlider<HTMLDivElement>({
    rtl: direction === 'rtl'
  })

  return (
    <Box ref={ref} className='keen-slider'>
      <Box className='keen-slider__slide'>
        <img src='/images/banners/banner-1.jpg' alt='swiper 1' />
      </Box>
      <Box className='keen-slider__slide'>
        <img src='/images/banners/banner-2.jpg' alt='swiper 2' />
      </Box>
      <Box className='keen-slider__slide'>
        <img src='/images/banners/banner-3.jpg' alt='swiper 3' />
      </Box>
      <Box className='keen-slider__slide'>
        <img src='/images/banners/banner-4.jpg' alt='swiper 4' />
      </Box>
      <Box className='keen-slider__slide'>
        <img src='/images/banners/banner-5.jpg' alt='swiper 5' />
      </Box>
    </Box>
  )
}

export default SwiperDefault
Loop
swiper 7
swiper 8
swiper 9
swiper 10

// ** MUI Imports
import Box from '@mui/material/Box'
import { Direction } from '@mui/material'

// ** Third Party Components
import { useKeenSlider } from 'keen-slider/react'

const SwiperLoop = ({ direction }: { direction: Direction }) => {
  // ** Hook
  const [ref] = useKeenSlider<HTMLDivElement>({
    loop: true,
    rtl: direction === 'rtl'
  })

  return (
    <Box ref={ref} className='keen-slider'>
      <Box className='keen-slider__slide'>
        <img src='/images/banners/banner-7.jpg' alt='swiper 7' />
      </Box>
      <Box className='keen-slider__slide'>
        <img src='/images/banners/banner-8.jpg' alt='swiper 8' />
      </Box>
      <Box className='keen-slider__slide'>
        <img src='/images/banners/banner-9.jpg' alt='swiper 9' />
      </Box>
      <Box className='keen-slider__slide'>
        <img src='/images/banners/banner-10.jpg' alt='swiper 10' />
      </Box>
    </Box>
  )
}

export default SwiperLoop
Multiple Slides
swiper 11
swiper 12
swiper 13
swiper 14
swiper 15

// ** MUI Imports
import Box from '@mui/material/Box'
import { Direction } from '@mui/material'

// ** Third Party Components
import { useKeenSlider } from 'keen-slider/react'

const SwiperMultipleSlides = ({ direction }: { direction: Direction }) => {
  // ** Hook
  const [ref] = useKeenSlider<HTMLDivElement>({
    rtl: direction === 'rtl',
    slides: {
      perView: 2
    }
  })

  return (
    <Box ref={ref} className='keen-slider'>
      <Box className='keen-slider__slide'>
        <img src='/images/banners/banner-11.jpg' alt='swiper 11' />
      </Box>
      <Box className='keen-slider__slide'>
        <img src='/images/banners/banner-12.jpg' alt='swiper 12' />
      </Box>
      <Box className='keen-slider__slide'>
        <img src='/images/banners/banner-13.jpg' alt='swiper 13' />
      </Box>
      <Box className='keen-slider__slide'>
        <img src='/images/banners/banner-14.jpg' alt='swiper 14' />
      </Box>
      <Box className='keen-slider__slide'>
        <img src='/images/banners/banner-15.jpg' alt='swiper 15' />
      </Box>
    </Box>
  )
}

export default SwiperMultipleSlides
Spacing
swiper 16
swiper 17
swiper 18
swiper 19
swiper 20

// ** MUI Imports
import Box from '@mui/material/Box'
import { Direction } from '@mui/material'

// ** Third Party Components
import { useKeenSlider } from 'keen-slider/react'

const SwiperSpacing = ({ direction }: { direction: Direction }) => {
  // ** Hook
  const [ref] = useKeenSlider<HTMLDivElement>({
    rtl: direction === 'rtl',
    slides: {
      perView: 2,
      spacing: 16
    }
  })

  return (
    <Box ref={ref} className='keen-slider'>
      <Box className='keen-slider__slide'>
        <img src='/images/banners/banner-16.jpg' alt='swiper 16' />
      </Box>
      <Box className='keen-slider__slide'>
        <img src='/images/banners/banner-17.jpg' alt='swiper 17' />
      </Box>
      <Box className='keen-slider__slide'>
        <img src='/images/banners/banner-18.jpg' alt='swiper 18' />
      </Box>
      <Box className='keen-slider__slide'>
        <img src='/images/banners/banner-19.jpg' alt='swiper 19' />
      </Box>
      <Box className='keen-slider__slide'>
        <img src='/images/banners/banner-20.jpg' alt='swiper 20' />
      </Box>
    </Box>
  )
}

export default SwiperSpacing
FreeMode
swiper 21
swiper 22
swiper 23
swiper 24
swiper 25

// ** MUI Imports
import Box from '@mui/material/Box'
import { Direction } from '@mui/material'

// ** Third Party Components
import { useKeenSlider } from 'keen-slider/react'

const SwiperFreeMode = ({ direction }: { direction: Direction }) => {
  // ** Hook
  const [ref] = useKeenSlider<HTMLDivElement>({
    loop: true,
    mode: 'free',
    rtl: direction === 'rtl',
    slides: {
      perView: 2,
      spacing: 16
    }
  })

  return (
    <Box ref={ref} className='keen-slider'>
      <Box className='keen-slider__slide'>
        <img src='/images/banners/banner-21.jpg' alt='swiper 21' />
      </Box>
      <Box className='keen-slider__slide'>
        <img src='/images/banners/banner-22.jpg' alt='swiper 22' />
      </Box>
      <Box className='keen-slider__slide'>
        <img src='/images/banners/banner-23.jpg' alt='swiper 23' />
      </Box>
      <Box className='keen-slider__slide'>
        <img src='/images/banners/banner-24.jpg' alt='swiper 24' />
      </Box>
      <Box className='keen-slider__slide'>
        <img src='/images/banners/banner-25.jpg' alt='swiper 25' />
      </Box>
    </Box>
  )
}

export default SwiperFreeMode
Centered
swiper 26
swiper 27
swiper 28
swiper 29
swiper 30

// ** MUI Imports
import Box from '@mui/material/Box'
import { Direction } from '@mui/material'

// ** Third Party Components
import { useKeenSlider } from 'keen-slider/react'

const SwiperCentered = ({ direction }: { direction: Direction }) => {
  // ** Hook
  const [ref] = useKeenSlider<HTMLDivElement>({
    rtl: direction === 'rtl',
    slides: {
      perView: 2,
      spacing: 16,
      origin: 'center'
    }
  })

  return (
    <Box ref={ref} className='keen-slider'>
      <Box className='keen-slider__slide'>
        <img src='/images/banners/banner-26.jpg' alt='swiper 26' />
      </Box>
      <Box className='keen-slider__slide'>
        <img src='/images/banners/banner-27.jpg' alt='swiper 27' />
      </Box>
      <Box className='keen-slider__slide'>
        <img src='/images/banners/banner-28.jpg' alt='swiper 28' />
      </Box>
      <Box className='keen-slider__slide'>
        <img src='/images/banners/banner-29.jpg' alt='swiper 29' />
      </Box>
      <Box className='keen-slider__slide'>
        <img src='/images/banners/banner-30.jpg' alt='swiper 30' />
      </Box>
    </Box>
  )
}

export default SwiperCentered
Vertical
1
2
3
4
5
6
7
8
9
10

// ** MUI Imports
import Box from '@mui/material/Box'

// ** Third Party Components
import { useKeenSlider } from 'keen-slider/react'

const SwiperVertical = () => {
  // ** Hook
  const [ref] = useKeenSlider<HTMLDivElement>({
    vertical: true,
    slides: {
      perView: 2,
      spacing: 8
    }
  })

  return (
    <Box ref={ref} className='keen-slider vertical' sx={{ maxHeight: 300 }}>
      {[...Array(10).keys()].map((num: number) => (
        <Box key={num} className='keen-slider__slide default-slide'>
          {num + 1}
        </Box>
      ))}
    </Box>
  )
}

export default SwiperVertical
Controls

// ** React Imports
import { useState } from 'react'

// ** MUI Imports
import Box from '@mui/material/Box'
import Badge from '@mui/material/Badge'
import { Direction } from '@mui/material'

// ** Icon Imports
import Icon from 'src/@core/components/icon'

// ** Third Party Components
import clsx from 'clsx'
import { useKeenSlider } from 'keen-slider/react'

const SwiperControls = ({ direction }: { direction: Direction }) => {
  // ** States
  const [loaded, setLoaded] = useState<boolean>(false)
  const [currentSlide, setCurrentSlide] = useState<number>(0)

  // ** Hook
  const [sliderRef, instanceRef] = useKeenSlider<HTMLDivElement>({
    rtl: direction === 'rtl',
    slideChanged(slider) {
      setCurrentSlide(slider.track.details.rel)
    },
    created() {
      setLoaded(true)
    }
  })

  return (
    <>
      <Box className='navigation-wrapper'>
        <Box ref={sliderRef} className='keen-slider'>
          <Box className='keen-slider__slide'>
            <img src='/images/banners/banner-1.jpg' alt='swiper 1' />
          </Box>
          <Box className='keen-slider__slide'>
            <img src='/images/banners/banner-2.jpg' alt='swiper 2' />
          </Box>
          <Box className='keen-slider__slide'>
            <img src='/images/banners/banner-3.jpg' alt='swiper 3' />
          </Box>
          <Box className='keen-slider__slide'>
            <img src='/images/banners/banner-4.jpg' alt='swiper 4' />
          </Box>
          <Box className='keen-slider__slide'>
            <img src='/images/banners/banner-5.jpg' alt='swiper 5' />
          </Box>
        </Box>
        {loaded && instanceRef.current && (
          <>
            <Icon
              icon='tabler:chevron-left'
              className={clsx('arrow arrow-left', {
                'arrow-disabled': currentSlide === 0
              })}
              onClick={(e: any) => e.stopPropagation() || instanceRef.current?.prev()}
            />

            <Icon
              icon='tabler:chevron-right'
              className={clsx('arrow arrow-right', {
                'arrow-disabled': currentSlide === instanceRef.current.track.details.slides.length - 1
              })}
              onClick={(e: any) => e.stopPropagation() || instanceRef.current?.next()}
            />
          </>
        )}
      </Box>
      {loaded && instanceRef.current && (
        <Box className='swiper-dots'>
          {[...Array(instanceRef.current.track.details.slides.length).keys()].map(idx => {
            return (
              <Badge
                key={idx}
                variant='dot'
                component='div'
                className={clsx({
                  active: currentSlide === idx
                })}
                onClick={() => {
                  instanceRef.current?.moveToIdx(idx)
                }}
              ></Badge>
            )
          })}
        </Box>
      )}
    </>
  )
}

export default SwiperControls
Thumbnails
swiper 1
swiper 2
swiper 3
swiper 4
swiper 5
swiper 1
swiper 2
swiper 3
swiper 4
swiper 5

// ** React Imports
import { MutableRefObject } from 'react'

// ** MUI Imports
import Box from '@mui/material/Box'
import { Direction } from '@mui/material'
import { useTheme } from '@mui/material/styles'

// ** Third Party Components
import { useKeenSlider, KeenSliderPlugin, KeenSliderInstance } from 'keen-slider/react'

const ThumbnailPlugin = (mainRef: MutableRefObject<KeenSliderInstance | null>): KeenSliderPlugin => {
  return slider => {
    function removeActive() {
      slider.slides.forEach(slide => {
        slide.classList.remove('active')
      })
    }
    function addActive(idx: number) {
      slider.slides[idx].classList.add('active')
    }

    function addClickEvents() {
      slider.slides.forEach((slide, idx) => {
        slide.addEventListener('click', () => {
          if (mainRef.current) mainRef.current.moveToIdx(idx)
        })
      })
    }

    slider.on('created', () => {
      if (!mainRef.current) return
      addActive(slider.track.details.rel)
      addClickEvents()
      mainRef.current.on('animationStarted', main => {
        removeActive()
        const next = main.animator.targetIdx || 0
        addActive(main.track.absToRel(next))
        slider.moveToIdx(next)
      })
    })
  }
}

const SwiperThumbnails = ({ direction }: { direction: Direction }) => {
  // ** Hooks
  const theme = useTheme()
  const [sliderRef, instanceRef] = useKeenSlider<HTMLDivElement>({
    rtl: direction === 'rtl'
  })
  const [thumbnailRef] = useKeenSlider<HTMLDivElement>(
    {
      rtl: direction === 'rtl',
      slides: {
        perView: 4,
        spacing: 16
      },
      breakpoints: {
        [(max-width: {theme.breakpoints.values.sm}px)]: {
          slides: {
            perView: 3,
            spacing: 8
          }
        }
      }
    },
    [ThumbnailPlugin(instanceRef)]
  )

  return (
    <>
      <Box ref={sliderRef} className='keen-slider'>
        <Box sx={{ display: 'flex' }} className='keen-slider__slide'>
          <img src='/images/banners/banner-1.jpg' alt='swiper 1' />
        </Box>
        <Box sx={{ display: 'flex' }} className='keen-slider__slide'>
          <img src='/images/banners/banner-2.jpg' alt='swiper 2' />
        </Box>
        <Box sx={{ display: 'flex' }} className='keen-slider__slide'>
          <img src='/images/banners/banner-3.jpg' alt='swiper 3' />
        </Box>
        <Box sx={{ display: 'flex' }} className='keen-slider__slide'>
          <img src='/images/banners/banner-4.jpg' alt='swiper 4' />
        </Box>
        <Box sx={{ display: 'flex' }} className='keen-slider__slide'>
          <img src='/images/banners/banner-5.jpg' alt='swiper 5' />
        </Box>
      </Box>

      <Box sx={{ mt: 4 }} ref={thumbnailRef} className='keen-slider thumbnail'>
        <Box className='keen-slider__slide' sx={{ display: 'flex', cursor: 'pointer' }}>
          <img src='/images/banners/banner-1.jpg' alt='swiper 1' />
        </Box>
        <Box className='keen-slider__slide' sx={{ display: 'flex', cursor: 'pointer' }}>
          <img src='/images/banners/banner-2.jpg' alt='swiper 2' />
        </Box>
        <Box className='keen-slider__slide' sx={{ display: 'flex', cursor: 'pointer' }}>
          <img src='/images/banners/banner-3.jpg' alt='swiper 3' />
        </Box>
        <Box className='keen-slider__slide' sx={{ display: 'flex', cursor: 'pointer' }}>
          <img src='/images/banners/banner-4.jpg' alt='swiper 4' />
        </Box>
        <Box className='keen-slider__slide' sx={{ display: 'flex', cursor: 'pointer' }}>
          <img src='/images/banners/banner-5.jpg' alt='swiper 5' />
        </Box>
      </Box>
    </>
  )
}

export default SwiperThumbnails
Fader
slider 0
slider 1
slider 2
slider 3
slider 4

// ** React Imports
import { useState } from 'react'

// ** MUI Imports
import Box from '@mui/material/Box'
import { Direction } from '@mui/material'

// ** Third Party Components
import { useKeenSlider } from 'keen-slider/react'

const images = [
  '/images/banners/banner-9.jpg',
  '/images/banners/banner-7.jpg',
  '/images/banners/banner-6.jpg',
  '/images/banners/banner-10.jpg',
  '/images/banners/banner-8.jpg'
]

const SwiperFader = ({ direction }: { direction: Direction }) => {
  const [opacities, setOpacities] = useState<number[]>([])

  // ** Hook
  const [sliderRef] = useKeenSlider<HTMLDivElement>({
    slides: images.length,
    rtl: direction === 'rtl',
    detailsChanged(s) {
      const new_opacities = s.track.details.slides.map(slide => slide.portion)
      setOpacities(new_opacities)
    }
  })

  return (
    <Box ref={sliderRef} className='fader' sx={{ height: [200, 250, 395] }}>
      {images.map((src, idx) => (
        <Box key={idx} className='fader__slide' sx={{ opacity: opacities[idx] }}>
          <img src={src} alt={slider {idx}} />
        </Box>
      ))}
    </Box>
  )
}

export default SwiperFader
Zoom
slider 0
slider 1
slider 2
slider 3
slider 4

// ** React Imports
import { useState } from 'react'

// ** MUI Imports
import Box from '@mui/material/Box'
import { Direction } from '@mui/material'

// ** Third Party Components
import { useKeenSlider, TrackDetails } from 'keen-slider/react'

const images = [
  '/images/banners/banner-6.jpg',
  '/images/banners/banner-7.jpg',
  '/images/banners/banner-8.jpg',
  '/images/banners/banner-9.jpg',
  '/images/banners/banner-10.jpg'
]

const SwiperZoom = ({ direction }: { direction: Direction }) => {
  // ** State
  const [details, setDetails] = useState<TrackDetails | null>(null)

  // ** Hook
  const [sliderRef] = useKeenSlider<HTMLDivElement>({
    initial: 2,
    rtl: direction === 'rtl',
    detailsChanged(s) {
      setDetails(s.track.details)
    }
  })

  const scaleStyle = (idx: number) => {
    if (!details) return {}
    const slide = details.slides[idx]
    const scale_size = 1
    const scale = 1 - (scale_size - scale_size * slide.portion)

    return {
      transform: scale({scale}),
      WebkitTransform: scale({scale})
    }
  }

  return (
    <Box ref={sliderRef} className='keen-slider zoom-out' sx={{ height: [200, 250, 395] }}>
      {images.map((src, idx) => (
        <Box key={idx} className='keen-slider__slide zoom-out__slide'>
          <Box className='slider-content-wrapper' sx={{ ...scaleStyle(idx) }}>
            <img src={src} alt={slider {idx}} />
          </Box>
        </Box>
      ))}
    </Box>
  )
}

export default SwiperZoom
Auto Switch
swiper 1
swiper 2
swiper 3
swiper 4
swiper 5

// ** MUI Imports
import Box from '@mui/material/Box'
import { Direction } from '@mui/material'

// ** Third Party Components
import { useKeenSlider } from 'keen-slider/react'

const SwiperAutoSwitch = ({ direction }: { direction: Direction }) => {
  // ** Hook
  const [ref] = useKeenSlider<HTMLDivElement>(
    {
      loop: true,
      rtl: direction === 'rtl'
    },
    [
      slider => {
        let mouseOver = false
        let timeout: number | ReturnType<typeof setTimeout>
        const clearNextTimeout = () => {
          clearTimeout(timeout as number)
        }
        const nextTimeout = () => {
          clearTimeout(timeout as number)
          if (mouseOver) return
          timeout = setTimeout(() => {
            slider.next()
          }, 2000)
        }
        slider.on('created', () => {
          slider.container.addEventListener('mouseover', () => {
            mouseOver = true
            clearNextTimeout()
          })
          slider.container.addEventListener('mouseout', () => {
            mouseOver = false
            nextTimeout()
          })
          nextTimeout()
        })
        slider.on('dragStarted', clearNextTimeout)
        slider.on('animationEnded', nextTimeout)
        slider.on('updated', nextTimeout)
      }
    ]
  )

  return (
    <Box ref={ref} className='keen-slider'>
      <Box className='keen-slider__slide'>
        <img src='/images/banners/banner-1.jpg' alt='swiper 1' />
      </Box>
      <Box className='keen-slider__slide'>
        <img src='/images/banners/banner-2.jpg' alt='swiper 2' />
      </Box>
      <Box className='keen-slider__slide'>
        <img src='/images/banners/banner-3.jpg' alt='swiper 3' />
      </Box>
      <Box className='keen-slider__slide'>
        <img src='/images/banners/banner-4.jpg' alt='swiper 4' />
      </Box>
      <Box className='keen-slider__slide'>
        <img src='/images/banners/banner-5.jpg' alt='swiper 5' />
      </Box>
    </Box>
  )
}

export default SwiperAutoSwitch
Mutation Observer

1


// ** React Imports
import { useState } from 'react'

// ** MUI Imports
import Box from '@mui/material/Box'
import { Direction } from '@mui/material'
import Button from '@mui/material/Button'
import { useTheme } from '@mui/material/styles'
import Typography from '@mui/material/Typography'

// ** Third Party Components
import { useKeenSlider, KeenSliderPlugin } from 'keen-slider/react'

const MutationPlugin: KeenSliderPlugin = slider => {
  const observer = new MutationObserver(mutations => {
    mutations.forEach(() => {
      slider.update()
    })
  })
  const config = { childList: true }

  slider.on('created', () => {
    observer.observe(slider.container, config)
  })
  slider.on('destroyed', () => {
    observer.disconnect()
  })
}

const SwiperMutationObserver = ({ direction }: { direction: Direction }) => {
  // ** States
  const [slides, setSlides] = useState<number[]>([1])

  // ** Hooks
  const theme = useTheme()
  const [ref] = useKeenSlider<HTMLDivElement>(
    {
      rtl: direction === 'rtl',
      slides: {
        perView: 3,
        spacing: 16
      },
      breakpoints: {
        [(max-width: {theme.breakpoints.values.sm}px)]: {
          slides: { perView: 1, spacing: 16 }
        }
      }
    },
    [MutationPlugin]
  )

  return (
    <>
      <Box ref={ref} className='keen-slider'>
        {slides.map(slide => {
          return (
            <Box key={slide} className='keen-slider__slide default-slide'>
              <Typography variant='h1'>{slide}</Typography>
            </Box>
          )
        })}
      </Box>
      <Box sx={{ mt: 4 }} className='demo-space-x'>
        <Button variant='contained' onClick={() => setSlides([...slides, slides.length + 1])}>
          Add
        </Button>
        <Button variant='contained' color='error' onClick={() => setSlides(slides.slice(0, -1))}>
          Remove
        </Button>
      </Box>
    </>
  )
}

export default SwiperMutationObserver