How to make the Swiper.js and React Player carousel responsive - reactjs

I have been looking for a way to make my Swiper.js carousel responsive when it's nesting the Youtube React Player. I finally found a workaround and hope this helps somebody. This also works if the slidesPerView is more than 2 or even float number like slidesPerView={1.3}.

Remove the default css mySwiper class, and apply player-wrapper and react-player css as below.
The point is that the player-wrapper div is self close and does not wrap the <ReactPlayer> component. Also have the width and height props to be 100% in the <ReactPlayer> component.
<Swiper
slidesPerView={1.3}
grabCursor={false}
loop={false}
watchSlidesProgress={true}
centeredSlides={true}
modules={[Pagination, Navigation]}
// className='mySwiper' <=remove
>
<SwiperSlide>
<div className='player-wrapper' /> //<= self close div
<ReactPlayer
url='youtube.com/1234'
controls={true}
width='100%'
height='100%'
playing={isPlaying === data.id}
config={{
youtube: {
playerVars: { showinfo: 1 },
},
}}
className='react-player'
/>
</SwiperSlide>
CSS
.player-wrapper {
position: relative;
padding-top: 56.25%
}
.react-player {
position: absolute;
top: 0;
left: 0;
}

Related

React Inline BackgroundImage with Media Queries

I am working on a react app that is responsive. When the viewport shrinks or increases the 'backgroundImage' should change. I used an inline style because I was unable to use a relative path to the image which is in the public folder.
I have created a media queries within a variable in react with the widths that they should change.
I have placed the style within the .hearder-flex dive element.
Header.js
const Header = () => {
const media = {
'#media (max-width: 650px)':{
backgroundImage: 'url("starter-code/assets/mobile/bg-pattern-header.svg")' ,
},
'#media (min-width: 750px)':{
backgroundImage: 'url("starter-code/assets/tablet/bg-pattern-header.svg")' ,
}
}
return (
<div className="header-wrapper">
<main className="header-flex" style={media}>
<img src="starter-code/assets/desktop/logo.svg" alt="logo" className="logo-img"/>
<div class="space-around">
<img src="starter-code/assets/desktop/icon-sun.svg" alt="icon-sun" className="sun-img"/>
<label className="switch">
<input type="checkbox" />
<span className="slider"/>
</label>
<img src="starter-code/assets/desktop/icon-moon.svg" alt="icon-moon" className="moon-img"/>
</div>
</main>
<div className="input-search">
<img src="starter-code/assets/desktop/icon-search.svg" alt="icon-search" className="icon-search"/>
<input type="text" placeholder="Enter desired job..." className="enter-job"/>
</div>
</div>
);
}
export default Header;
well, Media Queries cannot be used as the inline style.
However you can use this approach to assign the background images:
First create the css style as below and save it in a variable called css:
const css = `#media (max-width: 650px) {
.backimage {
background-image: url("https://picsum.photos/200/300")
}
}
#media (min-width: 750px) {
.backimage {
background-image: url("https://picsum.photos/200");
}
}`;
Then, use it in the component in the style tag above the main tag:
<style scoped>{css}</style>
<main style={{ height: 300 }} className="backimage">
Please also check this sandbox link

Make a React-video Cover the Parent Container? (react-player)

I'm trying to get my video to fit/cover the entire screen and respond to resize just like if you use objectFit: cover or backgroundSize: cover. Right now when the video is too large you can see the left and right side of the video, and when the window is too small, you are able to see the top and bottom.
import React from "react";
import ReactPlayer from "react-player/lazy";
const Header = (props) => {
return (
<ReactPlayer
muted={true}
volume={0}
playing={true}
loop={true}
width="100vw"
height="100vh"
style={{
position: "absolute",
objectFit: "cover",
backgroundSize: "cover",
}}
url={props.videos[1]}
/>
);
};
export default Header;
Here you can see the black background:
Too tall:
Too wide:
The container's size is 100vw, 100vh, and the ratio of the video is 4096x2160.
Here an example that I'm trying to not do since the video shrinks with the page:
https://jsfiddle.net/e6w3rtj1/131/
I found my solution, for some reason the react-video package doesn't work with object-fit or background-size, so I had to try something else.
I found that you can just use the html5 video and source tags for the video.
Here the code:
<video
autoPlay
muted
loop
style={{ height: "100%", width: "100%", objectFit: "cover" }} //object-fit:cover
>
<source src={props.videos[1]} type="video/mp4" />
</video>

How can I implement css hover effect in react inline-styling?

I am trying to implement a hover effect in the react component using react inline-styling.
const InfoWindow: React.FC<IInfoWindowProps> = ({ room }) => {
const info_window_image = {
width: "100%",
height: "168px",
background: `url(${room.pictures[0].image.large}) no-repeat`,
backgroundSize: "contain",
cursor: 'pointer'
};
return (
<div className="info_window_container">
<div style={info_window_image} />
</div>
)
};
div tag under info_window_container gets style object info_window_image .
I can successfully receive an image from API but I want to give zoom-in animation when the user hovers the image in the component.
I gave className to the div and styled in CSS file however it does not work. Styles I declared in CSS file do not render.
How can I make hover or focus effect in react-inline-styling?

Unable to set Nuka Carousel slide content height

I can't get the content of my nuka-carousel slides to be the same height. Setting heightMode="max" on the carousel sets the slide heights equal, but trying to expand the slide content isn't working right.
I've tried setting height on the slides to 100%, inherit, 100vh but no matter what, the slides expand to maybe 2-20x what they should be (depending on the div with the most content).
I've also tried using flexbox with flex:1 and I've tried with css-grid. Nothing seems to help
const Item = ({ children }) => (
<div
style={{
boxShadow: "rgb(153, 153, 153) 2px 2px 4px 2px"
// height: "100%"
// height: "100vh"
/// height: 'inherit'
}}
>
{children}
</div>
);
<Carousel
wrapAround
heightMode="max"
slidesToShow={1.25}
cellAlign="center">
{/* Item components with varying content */}
</Carousel>
Here's a codesandbox, If anyone has any suggestions I'd appreciate it.
https://codesandbox.io/s/brave-khorana-bowrz?file=/src/index.js

How to overlay content on react leaflet (z-index problem)

Really tried to not post this as I've seen similar questions but I'm not able to display anything over the react leaflet library after reading things online.
The following code snippets show the markup for the map and the overlay I'm trying to produce.
Many thanks, any help appreciated.
Looking at other questions online people refer to making the Map container position: absolute and setting the z-index to 400+ which doesn't seem to make a difference for me with the markup below.
Map markup
<Map
zoomControl={false}
doubleClickZoom= {false}
closePopupOnClick= {false}
dragging= {false}
zoomSnap= {false}
zoomDelta= {false}
trackResize= {false}
scrollWheelZoom= {false}
touchZoom={false}
className="map"
worldCopyJump={true}
center={position}
zoom={this.state.zoom}>
<TileLayer
attribution="&copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors and Chat location by Iconika from the Noun Project"
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
{this.state.pins.map(pin => (
<Marker
onClick={() => this.showPanel(pin)}
key={pin._id}
position={[pin.latitude, pin.longitude]}
icon={pinIcon}>
</Marker>
))}
</Map>
Overlay markup
<div ref={ref => this.el = ref}>
<button onClick={() => this.setState({ isPaneOpen: true })}>Click me to open right pane!</button>
<SlidingPane
className='some-custom-class'
overlayClassName='some-custom-overlay-class'
isOpen={ this.state.isPaneOpen }
title='Hey, it is optional pane title. I can be React component too.'
subtitle='Optional subtitle.'
onRequestClose={ () => {
// triggered on "<" on left top click or on outside click
this.setState({ isPaneOpen: false });
} }>
<div className="container-fluid padding">
</div>
</SlidingPane>
Update
I have now moved the overlay into a function, shown below
function MyOverLay(props) {
return <SlidingPane
className='some-custom-class'
overlayClassName='some-custom-overlay-class'
isOpen={ props.isPaneOpen }
title='Book here
</SlidingPane>
}
The change in the markup is shown below
New markup
<div>
<MyOverLay isPaneOpen={this.state.isPaneOpen} />
<div className="container-fluid padding">
<div className="row padding">
<div className="col-lg-8">
<Map zoomControl={false}
doubleClickZoom= {false}
closePopupOnClick= {false}
dragging= {false}
zoomSnap= {false}
zoomDelta= {false}
trackResize= {false}
scrollWheelZoom= {false}
touchZoom={false}
className="map"
worldCopyJump={true}
center={position}
zoom="13">
<TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" />
<Marker
position={[10, -10]}
icon={messageIcon}>
</Marker>
</Map>
</div>
this is the perfect answer
.leaflet-control { z-index: 0 !important}
.leaflet-pane { z-index: 0 !important}
.leaflet-top, .leaflet-bottom {z-index: 0 !important}
The solution I can only think is the use of React Portal. It's a feature of React that can append a component outside the "root" component inside the body element. Considering that element children in the lower part of the parent has higher stacking index than those in the higher part, it can "overlay" any component inside the root component. Try wrapping your component like this:
import React from 'react';
import ReactDOM from 'react-dom';
const OverlayComponent = () => {
return ReactDOM.createPortal(
<MyComponent />,
document.body
);
};
just had the same Problem. For anyone still looking for an answer - The highest z-index on leaftlet-react is for the zoom buttons and is
.leaflet-top, .leaflet-bottom
{
position: absolute;
z-index: 1000;
pointer-events: none;
}
so if you go above you can show the element in front of the map.
Cheers
Managed to get it working by controlling the z-index values within the CSS for all the panels the map renders on the page. The zIndex option available on the TileLayer doesn't seem to work for me but the following resolved the issue. Noticed - have tested this in Chrome only.
div.map.leaflet-container.leaflet-touch.leaflet-retina.leaflet-fade-anim {
/*border: 5px solid red;*/
z-index: 1;
}
div.slide-pane__content {
/*border: 5px solid black;*/
z-index: 100;
}
div.ReactModal__Content.ReactModal__Content--after-open.slide-pane.slide-pane_from_right.some-custom-class {
/*border: 5px solid orange;*/
z-index: 100;
}
div.slide-pane__header {
/*border: 5px solid orange;*/
z-index: 100;
}
div.ReactModal__Overlay.ReactModal__Overlay--after-open.slide-pane__overlay.some-custom-overlay-class {
/*border: 5px solid blue;*/
z-index: 100;
}

Resources