Swiper React Mouse-wheel Scrolling and Keyboard Control Not Working - reactjs

Using the mouse-wheel or keyboard to control the sliding in SwiperJs for React doesn't work. I can't seem to find anything on it and following Swiper API docs doesn't help either.
Using
react: 17.0.1
swiper: 6.4.11
There's a sandbox setup of it here
const App = () => {
const slides = [1, 2, 3, 4];
return (
<Swiper
slidesPerView={2}
keyboard={{ enabled: true }}
direction="vertical"
mousewheel
>
{slides.map((slide) => (
<SwiperSlide key={slide}>
<h1>Slide</h1>
</SwiperSlide>
))}
</Swiper>
);
};

Please get SwiperCore module to do below:
import SwiperCore, { Keyboard } from 'swiper';
and add following line of code:
SwiperCore.use([Keyboard]);
This should have the keyboard working.

This works for me perfectly.
import SwiperCore, { Keyboard, Mousewheel } from "swiper/core";
SwiperCore.use([Keyboard, Mousewheel]);
const App = () => {
const slides = [1, 2, 3, 4];
return (
<Swiper
slidesPerView={2}
keyboard={true}
direction="vertical"
mousewheel={true}
>
{slides.map((slide) => (
<SwiperSlide key={slide}>
<h1>Slide</h1>
</SwiperSlide>
))}
</Swiper>
);
};

Not a proper solution but for anyone interested I have come up with a work around.
I was unable to get the mouse-wheel or keyboard controls to work for Swiper using React components or with pure javascript. Official Swiper examples didn't work when replicated so I tried some previous versions. Went all the way back to 5.4.5 to get it work.
Unfortunately 5.4.5 doesn't support React but Swiper can still be incorporated into a React setup.
// import Swiper JS
import Swiper from "swiper/js/swiper";
// import Swiper styles
import "swiper/css/swiper.css";
const SimpleSwiper = () => {
useEffect(() => {
const swiper = new Swiper(".swiper-container", {
direction: "vertical",
mousewheel: true,
keyboard: { enabled: true },
slidesPerView: 1,
});
}, []);
const slides = [1, 2, 3];
return (
<div className="swiper-container">
<div className="swiper-wrapper">
{slides.map((slide) => (
<div
className="swiper-slide"
key={slide}
>{`slide ${slide}`}</div>
))}
</div>
</div>
);
};
You can view the code sandbox here. The keyboard control doesn't seem to work here but it does work locally.

Related

Issue using eventHandlers with react-leaflet and next.js

I'm trying to use eventHandlers with react-leaflet in a next.js application, but the events are never being fired.
Here is an example of the code I'm using in my Map component:
import { MapContainer, Rectangle } from "react-leaflet";
const Map = () => {
return (
<MapContainer center={[25, 25]} zoom={1} style={{ height: 600, width: 600 }}>
<Rectangle
bounds={[
[0, 0],
[50, 50],
]}
eventHandlers={{
click: () => console.log("clicked.."),
}}
/>
</MapContainer>
);
};
export default Map;
I've tried using this code outside of a next.js application (plane react app) and it worked as expected, but when I use it in a next.js application, the event is never fired.
Here is an example of how I'm rendering the Map component in my index.js file:
import dynamic from "next/dynamic";
const Map = dynamic(() => import("../components/Map"), {
ssr: false,
});
export default function Home() {
return (
<>
<Map />
</>
);
}
I also tried using this code in a codesandbox, but I couldn't get the sandbox to work (it crashed). Also tested it on the live editor on https://react-leaflet.js.org/docs/example-popup-marker/ and replacing the marker with the rectangle component, the event is triggered on click.
Has anyone else experienced this issue and found a solution?
Thanks in advance for any help!

How to separate two swiper instance hooks on the same page?

I have two React Swipers on the same page.
I'm using useSwiper to create my own navigation buttons.
It works great for one swiper. But now that I have two instances on the same page, when I click the next on one instance, both of them go to the next item.
In other words, their navigations are tied together.
These swiper instances are inside two separate components.
const Home = () => {
return <div>
<FirstSection /> // This has a `useSwiper` in it
<SecondSection /> // This also has a `useSwiper` in it
</div>
}
How can I make these instances separate from each other?
I have searched the docs and I can't find what to do.
you need to add a controller for each one take a look to the docs https://swiperjs.com/react#controller and check the example below
import React, { useState } from 'react';
import { Controller } from 'swiper';
import { Swiper, SwiperSlide } from 'swiper/react';
const App = () => {
// store swiper instances
const [firstSwiper, setFirstSwiper] = useState(null);
const [secondSwiper, setSecondSwiper] = useState(null);
return (
<main>
<Swiper
modules={[Controller]}
onSwiper={setFirstSwiper}
controller={{ control: secondSwiper }}
>
{/* ... */}
</Swiper>
<Swiper
modules={[Controller]}
onSwiper={setSecondSwiper}
controller={{ control: firstSwiper }}
>
{/* ... */}
</Swiper>
</main>
);
};

Swiper Component not working in React and throwing Erros

So I am following along with a course by Traversy Media called "React Front To Back 2022", at the 16th section of the course in the 5th and 6th videos, he was using the Swiper component. I was following along step-by-step but at the end, it threw an error, so after a bit of thinking and googling I decided to see the solution of the GitHub repository posted by him of the project, I compared the code, seemed the same, I copied it, still, it threw the errors and didn't render the page.
I couldn't find a fix anywhere(google, documentation, youtube, etc), so hopefully someone can help me here. Thank you in advance for the help.
The Errors:
init-swiper.js:25 Uncaught TypeError: Cannot read properties of undefined (reading 'pagination')
at mountSwiper (init-swiper.js:25:1)
at swiper.js:136:1
at commitHookEffectListMount (react-dom.development.js:23049:1)
at invokeLayoutEffectMountInDEV (react-dom.development.js:25010:1)
at invokeEffectsInDev (react-dom.development.js:27304:1)
at commitDoubleInvokeEffectsInDEV (react-dom.development.js:27280:1)
at flushPassiveEffectsImpl (react-dom.development.js:27007:1)
at flushPassiveEffects (react-dom.development.js:26935:1)
at performSyncWorkOnRoot (react-dom.development.js:26032:1)
at flushSyncCallbacks (react-dom.development.js:12009:1)
react_devtools_backend.js:4026 The above error occurred in the <Swiper> component:
at http://localhost:3000/static/js/bundle.js:131862:66
at Slider (http://localhost:3000/static/js/bundle.js:1549:66)
at main
at div
at Explore
at Routes (http://localhost:3000/static/js/bundle.js:120121:24)
at Router (http://localhost:3000/static/js/bundle.js:120046:30)
at BrowserRouter (http://localhost:3000/static/js/bundle.js:118774:23)
at App
Uncaught TypeError: Cannot read properties of undefined (reading 'pagination')
at mountSwiper (init-swiper.js:25:1)
at swiper.js:136:1
at commitHookEffectListMount (react-dom.development.js:23049:1)
at invokeLayoutEffectMountInDEV (react-dom.development.js:25010:1)
at invokeEffectsInDev (react-dom.development.js:27304:1)
at commitDoubleInvokeEffectsInDEV (react-dom.development.js:27280:1)
at flushPassiveEffectsImpl (react-dom.development.js:27007:1)
at flushPassiveEffects (react-dom.development.js:26935:1)
at performSyncWorkOnRoot (react-dom.development.js:26032:1)
at flushSyncCallbacks (react-dom.development.js:12009:1)
The Code:
import { useState, useEffect } from 'react'
import { useNavigate } from 'react-router-dom'
import { collection, getDocs, query, orderBy, limit } from 'firebase/firestore'
import { db } from '../firebase.config'
import SwiperCore, { Navigation, Pagination, Scrollbar, A11y } from 'swiper'
import { Swiper, SwiperSlide } from 'swiper/react'
import 'swiper/swiper-bundle.css'
import Spinner from './Spinner'
SwiperCore.use([Navigation, Pagination, Scrollbar, A11y])
function Slider() {
const [loading, setLoading] = useState(true)
const [listings, setListings] = useState(null)
const navigate = useNavigate()
useEffect(() => {
const fetchListings = async () => {
const listingsRef = collection(db, 'listings')
const q = query(listingsRef, orderBy('timestamp', 'desc'), limit(5))
const querySnap = await getDocs(q)
let listings = []
querySnap.forEach((doc) => {
return listings.push({
id: doc.id,
data: doc.data(),
})
})
setListings(listings)
setLoading(false)
}
fetchListings()
}, [])
if (loading) {
return <Spinner />
}
if (listings.length === 0) {
return <></>
}
return (
listings && (
<>
<p className='exploreHeading'>Recommended</p>
<Swiper slidesPerView={1} pagination={{ clickable: true }}>
{listings.map(({ data, id }) => (
<SwiperSlide
key={id}
onClick={() => navigate(`/category/${data.type}/${id}`)}
>
<div
style={{
background: `url(${data.imgUrls[0]}) center no-repeat`,
backgroundSize: 'cover',
}}
className='swiperSlideDiv'
>
<p className='swiperSlideText'>{data.name}</p>
<p className='swiperSlidePrice'>
${data.discountedPrice ?? data.regularPrice}{' '}
{data.type === 'rent' && '/ month'}
</p>
</div>
</SwiperSlide>
))}
</Swiper>
</>
)
)
}
export default Slider
GitHub link to the repo
I'm currently facing same issue while following the course On udemy can't seem to find any difference in my code. The fix was, I updated Swiper to the latest version using npm i swiper#latest then changed my imports to import {Navigation, Pagination, Scrollbar, A11y } from 'swiper'
import { Swiper, SwiperSlide } from 'swiper/react'
import 'swiper/css'
and finally updated my swiper components to <Swiper
slidesPerView={1}
pagination={{ clickable: true }}
modules={[Navigation, Pagination, Scrollbar, A11y]}
navigation
scrollbar={{ draggable: true }}
>
{listing.imgUrls.map((url, index) => (
<SwiperSlide key={index}>
<div
style={{
background: `url(${listing.imgUrls[index]}) center no-repeat`,
backgroundSize: 'cover',
minHeight: '26rem',
}}
className='swiperSlideDiv'
></div>
</SwiperSlide>
))}
</Swiper>
Try switching versions for switcher package.
Checkout the package.json of traversary's repo: https://github.com/bradtraversy/house-marketplace/blob/main/package.json
Its coming due to <react.strictmode> remove it from index.js and it works but I don't know why strict mode causes this error

Gatsby/React - fade out section on scroll?

I've been trying to use gatsby-plugin-scroll-reveal which uses Sal.js to animate a hero section on my site. I'm trying to make it so that the text in the hero fades in then fades out as you scroll down the page. Right now, I can only get it to fade in. How can I make that happen with Sal.js or another way?
I also tried a different way by creating a component that uses IntersectionObserver DOM API but I couldn't get that to work really.
Here's the component:
import React from 'react';
import ReactDOM from 'react-dom';
function FadeInSection(props) {
const [isVisible, setVisible] = React.useState(true);
const domRef = React.useRef();
React.useEffect(() => {
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => setVisible(entry.isIntersecting));
});
observer.observe(domRef.current);
return () => observer.unobserve(domRef.current);
}, []);
return (
<div
className={`fade-in-section ${isVisible ? 'is-visible' : ''}`}
ref={domRef}
>
{props.children}
</div>
);
}
export default FadeInSection
I figured out a solution from this article:
https://markoskon.com/scroll-reveal-animations-with-react-spring/
So, I'm using the react-spring to create reveal animations on scroll and react-visibility-sensor to see if the I want animated element is visible.
// App.js
import React from "react";
import { Spring } from "react-spring/renderprops";
import VisibilitySensor from "react-visibility-sensor";
<VisibilitySensor once>
{({ isVisible }) => (
<Spring delay={100} to={{ opacity: isVisible ? 1 : 0 }}>
{({ opacity }) => <h1 style={{opacity}}>Title</h1>}
</Spring>
)}
</VisibilitySensor>

React-use-gesture not working with Storybook

I have my component and the storybook stories file, it renders with no errors but it is not draggable. I am basing my studies into this example from the react-use-gesture Github. I noticed that if I start a new project with create-react-app and paste this code there it works fine, but using storybook it doesn't work. I also notice that in my code the element looks like <div style="x: 0px; y: 0px;"></div> instead of <div style="transform: none;"></div> (code from the example that works), I've been researching and I couldn't find a solution so I came to ask the help of this awesome community.
Goal: To have a draggable card component story on react storybook, using react-spring and react-use-gesture.
Expected results: To be able to drag the component around.
Actual results: Component is not draggable
Error Messages: none.
Component's code:
import React from 'react'
import { useSpring, animated } from 'react-spring'
import { useDrag } from 'react-use-gesture'
export function Card() {
const [props,
set] = useSpring(() => ({ x: 0, y: 0, scale: 1 }))
const bind = useDrag(({ down, movement: [x, y] }) => {
set({ x: down ? x : 0, y: down ? y : 0, scale: down ? 1.2 : 1 })
})
return <animated.div {...bind()} style={props} />
}
export default Card;
Stories code:
import React from 'react'
import { storiesOf } from '#storybook/react'
import Card from './Card'
import './card.css'
const Body = ({ children }: any) => (
<div className="wrapper">
<style
dangerouslySetInnerHTML={{ __html: `body { margin: 0; }` }}
/>
{children}
</div>
)
storiesOf('UI Components | Card', module)
.add("Simple Card", () => (
<Body>
<Card />
</Body>
))
You can check my github repo for this and run npm install and npm run storybook
Here is the folder that contains the code above ^ if you want to check the code only.
I found the solution, the codesandbox is using the latest beta of useSpring.
The versions I had were:
"react-spring": "^8.0.27",
"react-use-gesture": "^6.0.14",
and the solution
"react-spring": "9.0.0-beta.34",
"react-use-gesture": "latest"
Maybe this will be of help for someone else as well.

Resources