I made the following slider with swiper js
<Swiper
loop={true}
slidesPerView={1.25}
freeMode={true}
centeredSlides={true}
spaceBetween={30}
keyboard={true}
modules={[
Keyboard,
Navigation,
]}
navigation={{
nextEl: '.swiper-slide-next',
prevEl: '.swiper-slide-prev',
}}
breakpoints={{
1024: {
slidesPerView: 2.125,
},
768: {
slidesPerView: 1.5,
},
}}
onSlideChange={(swiper) => {
/********************************
THIS DOESN'T WORKS
********************************/
swiper.navigation.nextEl = document.querySelector('.swiper-slide-next') as HTMLElement
swiper.navigation.prevEl = document.querySelector('.swiper-slide-prev') as HTMLElement
}}
>
{slides.map(slide => (
<SwiperSlide key={slide.id}>
...
</SwiperSlide>
))}
</Swiper>
Now swiper automatically assigns and updates the .swiper-slide-next (red) and .swiper-slide-prev (green) classes to expected elements right away but swiper.navigation.nextEl and swiper.navigation.prevEl HTMLElements doesn't updates. I tried updating them by listening to the onSlideChange listener but that didn't work either.
What should I do? Any help would be greatly appreciated.
Related
Hi I am trying to create a snackbar using material ui.
React version = 0.14
Material-ui version =0.15.0
I couldn't find anything suitable for this version of React so I decided to use material-ui. It works but only opens at the bottom of the screen. How can I change this? For example how can I get the top right.
My Code :
import Snackbar from 'material-ui/Snackbar';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'
this.state = {
open: false,
};
handleTouchTap = () => {
this.setState({
open: true,
});
};
handleRequestClose = () => {
this.setState({
open: false,
});
};
<div>
<button
onClick={this.handleTouchTap}>
SHOW NOTIFICATION
<button>
<Snackbar
open={this.state.open}
message="Event added to your calendar"
autoHideDuration={4000}
onRequestClose={this.handleRequestClose}
/>
</div>
Image is here : [Notification image1
Just add anchorOrigin to update position:
<Snackbar
...
anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
/>
I have a swiper.js slider made in react. If I have 8 images in the swiper and then I navigate to the 8th thumbnail and click on the 7th thumb it will slider the thumbnail part up. Is there a way to prevent this behavior from happening?
What I want to do is for it to only auto slide if there are more slides up or down available. For example, if I have 5 thumbnails and slide [2, 3, 4, 5, 6] are visible, if I select slide 6 it would move over and show slide 7 available and if I select slide 2 it would slide over and show slide 1. That is the only movement I want it to do. Is that feature available in the docs?
<div className="mainSliderWrap">
<Swiper
pagination
onSlideChange={swiper => {
setImageSelectedIndex(swiper.activeIndex + 1)
return true
}}
thumbs={{ swiper: thumbsSwiper }}>
{products.images.map((product, index) => (
<SwiperSlide key={product.originalSrc}>
<img
className={classes.mainSliderImg}
ref={el => {
imagesRef.current[index] = el as HTMLImageElement
}}
src={product.originalSrc}
data-zoom={product.originalSrc}
alt={product.title}
height={360}
width={360}
/>
</SwiperSlide>
))}
</Swiper>
</div>
<div
className={[
"productSlider",
ProductSliderOrientation(width) === "horizontal" &&
"horizontalProductSlider"
].join(" ")}>
<div className="swiper-button-next mainProdNext" />
<div className="swiper-button-prev mainProdPrev" />
<Swiper
direction={ProductSliderOrientation(width)}
touchRatio={1}
threshold={10}
slidesPerView={slidesPerView}
spaceBetween={15}
navigation={{
nextEl: ".mainProdNext",
prevEl: ".mainProdPrev"
}}
onSwiper={setThumbsSwiper}
breakpoints={{
0: {
spaceBetween: 10,
slidesOffsetBefore: 20,
slidesOffsetAfter: 20
},
576: {
spaceBetween: 10,
slidesPerView: 5
},
768: {
touchRatio: 0,
slidesPerView: 5
},
992: {
touchRatio: 1,
slidesPerView: 5
},
1200: {
touchRatio: 0,
slidesPerView: 5
}
}}>
{products &&
products.images.map(product => (
<SwiperSlide key={product.originalSrc}>
<ProductImage
image={product}
alt={products.title}
moduleClass={classes.productImagePick}
gatsbyImageClass={classes.productImagePickGatsby}
/>
</SwiperSlide>
))}
</Swiper>
</div>
</div>
</div>
It looks like there is no way to implement thumbnails with this behavior without manipulating data. So idea is when you change a thumbnail you need to reorder data in order to show next/previous thumb.
export default function App() {
const [thumbsSwiper, setThumbsSwiper] = useState(null);
const [data, setData] = useState([
"https://swiperjs.com/demos/images/nature-1.jpg",
"https://swiperjs.com/demos/images/nature-2.jpg",
"https://swiperjs.com/demos/images/nature-3.jpg",
"https://swiperjs.com/demos/images/nature-4.jpg",
"https://swiperjs.com/demos/images/nature-5.jpg",
"https://swiperjs.com/demos/images/nature-6.jpg",
"https://swiperjs.com/demos/images/nature-7.jpg",
"https://swiperjs.com/demos/images/nature-8.jpg",
"https://swiperjs.com/demos/images/nature-9.jpg",
"https://swiperjs.com/demos/images/nature-10.jpg"
]);
return (
<>
<Swiper
style={{
"--swiper-navigation-color": "#fff",
"--swiper-pagination-color": "#fff"
}}
loop={false}
spaceBetween={10}
navigation={true}
thumbs={{ swiper: thumbsSwiper }}
className="mySwiper2"
onSlideChange={(e) => {
if (e.realIndex % 3 === 0) {
// move first element to the end
const newData = [...data];
newData.push(newData.shift());
setData(newData);
e.slideTo(e.realIndex - 1);
}
if (e.realIndex === 0) {
// move last element to the beginning
const newData = [...data];
newData.unshift(newData.pop());
setData(newData);
e.slideTo(e.realIndex + 1);
}
}}
>
{data.map((img) => (
<SwiperSlide key={img}>
<img src={img} />
</SwiperSlide>
))}
</Swiper>
<Swiper
onSwiper={setThumbsSwiper}
loop={false}
loopedSlides={1}
spaceBetween={10}
slidesPerView={4}
freeMode={false}
watchSlidesVisibility={true}
watchSlidesProgress={true}
className="mySwiper"
>
{data.map((img) => (
<SwiperSlide key={img}>
<img src={img} />
</SwiperSlide>
))}
</Swiper>
</>
);
}
Here is a codesandbox
This is a quick example only. I hope it will help you.
Here's a video showcasing all my visible current bottom-tab-items: Home, My Account, Cart and Menu. https://streamable.com/no6anz
I have other bottom-tab-items I want to render on the screen but not be visible in the bottom tab bar itself.(For example: SettingsView)
How do I achieve this using react native navigation v5?
just on the element (Tab.Screen) you don't want to show, render a null tabBarButton.
<Tab.Screen
name="SignIn"
component={SignInScreen}
options={{
tabBarButton: (props) => null, //like this
tabBarStyle: { display: 'none' }, //this is additional if you want to hide the whole bottom tab from the screen version 6.x
}}
/>
I've solved my own question:
<Tab.Navigator
tabBarOptions={{
activeTintColor: '#161718',
inactiveTintColor: '#ffffff',
style: {
backgroundColor: '#161718',
paddingTop: 10,
borderTopColor: '#161718',
},
labelStyle: {
textAlign: 'center',
top: 8,
},
}}
screenOptions={({route}) => ({
tabBarButton: ['Contact', 'Route2ToExclude'].includes(route.name)
? () => {
return null;
}
: undefined,
})}>
As you can see i'm using screenoptions to define which routes to exclude from the bottom tab bar. Note these routes do need to be an actual screen within the <tab.navigator> component.
React Navigation Bottom Tab Navigation github issue link
https://github.com/react-navigation/react-navigation/issues/5230#issuecomment-595846400
When i change orientation on tablet the slider breaks (shows 1 broken slide). Expected behavior ( 2 slides 50% width in portrait orientation). I try to fix with ref.current.swiper.update(), but it don't work
const ref = useRef()
const handleResize = () => {
ref?.current.swiper.update()
}
useEventListener('resize', handleResize)
<Swiper
loop
watchOverflow
ref={ref}
className="apartment-swiper"
breakpoints={{
768: {
slidesPerView: 'auto',
},
1280: {
slidesPerView: 1,
},
}}
>
{photo?.map((item, index) => (
<SwiperSlide className="swiper-slide" key={index}>
<img className="swiper-slide" src={item.url} alt="slide" />
</SwiperSlide>
))}
</Swiper>
try to add the parameters updateOnWindowResize or observer properties
<Swiper
loop
watchOverflow
observer={'true'}
className="apartment-swiper"
breakpoints={{
768: {
slidesPerView: 'auto',
},
1280: {
slidesPerView: 1,
},
}}
>
{photo?.map((item, index) => (
<SwiperSlide className="swiper-slide" key={index}>
<img className="swiper-slide" src={item.url} alt="slide" />
</SwiperSlide>
))}
</Swiper>
This problem - swiperRef1.current.swiper.autoplay.timeout = 366 by def!:)
To do:
console.log(swiperRef1.current.swiper)
swiperRef1.current.swiper.autoplay.timeout = 3;
console.log(swiperRef1.current.swiper.autoplay.timeout)
I was trying to use a context menu that shows up after selecting part of the text in a TextInput, but the native popup menu is covering it. I can not put the menu in the element above. And if I put it under current placement, the keyboard would cover it. I was trying to use marginBottom to move the menu higher, but it did not work. The only thing that lets me move the menu options above native popup is paddingBottom but it does not look good in the app.
<Menu ref={c => (this.styleMenu = c)} renderer={renderers.Popover} style={[{ opacity: 0 }, { marginBottom: '250%' }, { position: 'absolute' }, { top: 0 }, { right: 0 }, { float: 'top' }]}>
<MenuTrigger text='' />
<MenuOptions optionsContainerStyle={[/*{ paddingBottom: 100 }*/, { marginBottom: '1%' }, /*{height: 30}*/]}>
<MenuOption onSelect={() => this.doSomething('1')} text={I18n.t('1')} />
<MenuOption onSelect={() => this.doSomething('2')} text={I18n.t('2')} />
<MenuOption onSelect={() => this.doSomething('3')} text={I18n.t('3')} />
</MenuOptions>
</Menu>
Is it possible to obtain similar results without paddingBottom or at least make the extra part of the menu transparent?