glide icon indicating copy to clipboard operation
glide copied to clipboard

How could we use glidejs with React ?

Open bryanthuan opened this issue 5 years ago • 8 comments

Deal all,

I have been struggled with using glide with React, could any of you give an example on how we could use with React ? Thanks.

bryanthuan avatar May 27 '19 05:05 bryanthuan

I agree with this, it would be nice if this is possible

ledikari avatar Jun 07 '19 12:06 ledikari

this is a simple implementation using hooks. I don't need handling events, but consider that slider is a reference to a Glide object, from which you can handle events easily.

import Glide from '@glidejs/glide'
import { useState, useEffect } from 'react'

const Carousel = ({element = 'glide', options, children}) => {
    const [slider] = useState(new Glide(`.${element}`, options))
    useEffect(() => {
       slider.mount()

      // subscribe to an event 
      slider.on('run.before', (event) => {
          // ... do something cool here
        })

      // cleanup when unmounting component
      return () => slider.destroy()
    }, [])

   return (
       <div className={element}>
           <div className="glide__track" data-glide-el="track">
                  <ul className="glide__slides">
                    {children.map((slide, index) => {
                            return React.cloneElement(slide, {
                                key: index,
                                className: `${slide.props.className} glide__slide`
                            })
                        })
                    }
                </ul>
           </div>
      </div>
  )
}

and then in component

import Carousel from 'path-to-carousel'

<Carousel element="carousel-class-to-inject" options={{ perView: 3, ... }}

arienzIT avatar Jun 07 '19 13:06 arienzIT

this is a simple implementation using hooks. I don't need handling events, but consider that slider is a reference to a Glide object, from which you can handle events easily.

is this the only way? it felt like hacky.

ledikari avatar Jun 10 '19 09:06 ledikari

I expanded solution of the @lucari94. Now, you can set slide position from external Component, when you updated the startAt props.

I am using this solution:


import React, { Component } from 'react'
import Glide from '@glidejs/glide'

export default class SliderGlide extends Component {
  state = { id: null }

  componentDidMount = () => {
    // Generated random id 
    this.setState({ id: `glide-${Math.ceil(Math.random() * 100)}` }, this.initializeGlider)
  }

  initializeGlider = () => {
    this.slider = new Glide(`#${this.state.id}`, this.props.options)
    this.slider.mount()
  }

  componentWillReceiveProps = newProps => {
    if (this.props.options.startAt !== newProps.options.startAt) {
      this.slider.go(`=${newProps.options.startAt}`)
    }
  }

  render = () => (
    <div id={this.state.id} style={{ overflowX: 'hidden', userSelect: 'none', maxWidth: '100vw' }}>
      <div className="glide__track" data-glide-el="track">
        <div className="glide__slides" style={{ display: 'flex' }}>
          {this.props.children.map((slide, index) => {
            return React.cloneElement(slide, {
              key: index,
              className: `${slide.props.className} glide__slide`,
            })
          })}
        </div>
      </div>
    </div>
  )
}

SliderGlide.defaultProps = {
  options: {},
}

RicardoFredes avatar Jul 12 '19 14:07 RicardoFredes

This works if you have only one slider per page. Not per component, per page. I have two sliders with different classes within two different components. Once I add the second component (with the second slider) it runs infinitely and crashes the browser. Here part of my code.

MainSlider.js

import React, { useEffect } from "react";
import Glide from "@glidejs/glide";
import "@glidejs/glide/dist/css/glide.core.min.css";

const Mainslider = ()=>{
  const mainGlide = new Glide(".main__glide"); // default options

 useEffect(() => {
    mainGlide.mount();
    return () => mainGlide.destroy();
  }, [mainGlide]);

return (
  <div className="main__glide">
    <div className="glide__track" data-glide-el="track">
        <ul className="glide__slides">
          <li className="glide__slide">
             {/* content 1 */}
         </li>
         <li className="glide__slide">
             {/* content 1 */}
         </li>
         <li className="glide__slide">
             {/* content 2 */}
         </li>
         <li className="glide__slide">
             {/* content 3 */}
         </li>
      </ul>
  </div>
</div>
)
}

The second component is called GallerySlider.js and has similar if not the same code. But none of the two slider mount.

oscarcontrerasnavas avatar May 12 '21 21:05 oscarcontrerasnavas

Glide is a vanilla js library and was not created with the focus on use with React, but its quite easy to get it working. This is the way how I would go with a React carousel component that is based on Glide.js.

import Glide from "@glidejs/glide";
import { useImperativeHandle, useEffect, useRef, forwardRef } from "react";

import "@glidejs/glide/dist/css/glide.core.css";

export const Carousel = forwardRef(({ options, children }, ref) => {
  const sliderRef = useRef();

  useImperativeHandle(ref, () => sliderRef.current);

  useEffect(() => {
    const slider = new Glide(sliderRef.current, options);

    slider.mount();

    return () => slider.destroy();
  }, [options]);

  return (
    <div className="glide" ref={sliderRef}>
      <div className="glide__track" data-glide-el="track">
        <ul className="glide__slides">{children}</ul>
      </div>
    </div>
  );
});

export const Slide = forwardRef(({ children }, ref) => {
  return (
    <li className="glide__slide" ref={ref}>
      {children}
    </li>
  );
});

Here a complete example on Codesandbox

jedrzejchalubek avatar May 19 '21 14:05 jedrzejchalubek

It's very simple.

import { useRef, useEffect } from "react";
import Glide from "@glidejs/glide";
import "./App.css";
import "./styles.scss";

const sliderConfiguration = {
  autoplay: 4000,
};

function App() {
  const ref = useRef();

  useEffect(() => {
    const slider = new Glide(ref.current, sliderConfiguration);
    slider.mount();
  }, [ref]);

  return (
      <>
        {" "}
        <div ref={ref} className="glide">
          <div className="glide__track" data-glide-el="track">
            <ul className="glide__slides">
              <li className="glide__slide">
                <div
                  className="container"
                  style={{ backgroundColor: "#0033FF" }}
                >
                  text one
                </div>
              </li>
              <li className="glide__slide">
                <div
                  className="container"
                  style={{ backgroundColor: "#660000" }}
                >
                  text two
                </div>
              </li>
              <li className="glide__slide">
                <div
                  className="container"
                  style={{ backgroundColor: "#9933CC" }}
                >
                  text three
                </div>
              </li>
            </ul>
          </div>

          <div className="glide__arrows" data-glide-el="controls">
            <button
              className="glide__arrow glide__arrow--left"
              data-glide-dir="<"
            >
              prev
            </button>
            <button
              className="glide__arrow glide__arrow--right"
              data-glide-dir=">"
            >
              next
            </button>
          </div>

          <div className="glide__bullets" data-glide-el="controls[nav]">
            <button className="glide__bullet" data-glide-dir="=0"></button>
            <button className="glide__bullet" data-glide-dir="=1"></button>
            <button className="glide__bullet" data-glide-dir="=2"></button>
          </div>
        </div>
      </>
  );
}

export default App;

For example.

cmirnow avatar Oct 14 '22 10:10 cmirnow

For anyone looking for the typescript version of @jedrzejchalubek solution:

import Glide, { Options } from "@glidejs/glide";
import { forwardRef, useEffect, useImperativeHandle, useRef } from "react";

export const sliderConfiguration: Partial<Options> = {
  type: "carousel",
  gap: 20,
  perView: 3
};

type CarouselType = {
  children: React.ReactNode;
};

export const Carousel = forwardRef(({ children }: CarouselType, ref) => {
  const sliderRef = useRef<HTMLDivElement>(null);

  useImperativeHandle(ref, () => sliderRef.current);

  useEffect(() => {
    const slider = new Glide(
      sliderRef.current as HTMLElement,
      sliderConfiguration,
    );
    slider.mount();

    return () => {
      slider.destroy();
    };
  }, []);

  return (
    <div className="glide relative md:px-0" ref={sliderRef}>
      <div className="glide__track" data-glide-el="track">
        <ul className="glide__slides">
          { children }
        </ul>
      </div>
    </div>
  );
});

Carousel.displayName = "Carousel";

renzodamgo avatar Feb 22 '23 03:02 renzodamgo