1
0
Fork 0
mirror of https://github.com/muerwre/vault-frontend.git synced 2025-04-25 04:46:40 +07:00

made new hero component

This commit is contained in:
Fedor Katurov 2021-10-07 12:33:17 +07:00
parent 3b7997b442
commit 330e233869
10 changed files with 321 additions and 15 deletions

View file

@ -0,0 +1,131 @@
import React, { FC, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { Swiper, SwiperSlide } from 'swiper/react';
import 'swiper/swiper.scss';
import 'swiper/components/effect-fade/effect-fade.scss';
import 'swiper/components/lazy/lazy.scss';
import styles from './styles.module.scss';
import SwiperCore, { EffectFade, Navigation, Lazy, Autoplay } from 'swiper';
import { Icon } from '~/components/input/Icon';
import { IFlowState } from '~/redux/flow/reducer';
import { getURLFromString } from '~/utils/dom';
import { PRESETS, URLS } from '~/constants/urls';
import SwiperClass from 'swiper/types/swiper-class';
import { LoaderCircle } from '~/components/input/LoaderCircle';
import { useHistory } from 'react-router';
SwiperCore.use([EffectFade, Lazy, Autoplay, Navigation]);
interface Props {
heroes: IFlowState['heroes'];
}
export const FlowSwiperHero: FC<Props> = ({ heroes }) => {
const [controlledSwiper, setControlledSwiper] = useState<SwiperClass | undefined>(undefined);
const [currentIndex, setCurrentIndex] = useState(heroes.length);
const preset = useMemo(() => (window.innerWidth <= 768 ? PRESETS.cover : PRESETS.small_hero), []);
const history = useHistory();
const onNext = useCallback(() => {
controlledSwiper?.slideNext(1);
}, [controlledSwiper]);
const onPrev = useCallback(() => {
controlledSwiper?.slidePrev(1);
}, [controlledSwiper]);
const onIndexChange = useCallback((swiper: SwiperClass) => {
let activeIndex = swiper.activeIndex;
let slidesLen = swiper.slides.length;
if (slidesLen === 0) {
return 0;
}
if (swiper.params.loop) {
switch (swiper.activeIndex) {
case 0:
activeIndex = slidesLen - 3;
break;
case slidesLen - 1:
activeIndex = 0;
break;
default:
--activeIndex;
}
}
setCurrentIndex(activeIndex);
}, []);
const onClick = useCallback(
(sw: SwiperClass) => {
history.push(URLS.NODE_URL(heroes[sw.realIndex]?.id));
},
[history, heroes]
);
if (!heroes.length) {
return (
<div className={styles.loader}>
<LoaderCircle size={100} fill="currentColor" />
</div>
);
}
const title = heroes[currentIndex]?.title;
return (
<div className={styles.wrap}>
<div className={styles.slide}>
<div className={styles.info}>
<div className={styles.title}>{title}</div>
<div className={styles.buttons}>
<button className={styles.button} onClick={onPrev} type="button">
<Icon icon="left" />
</button>
<button className={styles.button} onClick={onNext} type="button">
<Icon icon="right" />
</button>
</div>
</div>
</div>
<Swiper
spaceBetween={300}
effect="fade"
speed={3000}
className={styles.swiper}
lazy
loop
slidesPerView={1}
autoplay={{
delay: 3000,
pauseOnMouseEnter: false,
stopOnLastSlide: false,
disableOnInteraction: false,
}}
runCallbacksOnInit
onSwiper={setControlledSwiper}
onSlidesLengthChange={onIndexChange}
onRealIndexChange={onIndexChange}
onAfterInit={onIndexChange}
onClick={onClick}
>
{heroes
.filter(node => node.thumbnail)
.map(node => (
<SwiperSlide key={node.id}>
<img
src={getURLFromString(node.thumbnail!, preset)}
alt=""
className={styles.preview}
/>
</SwiperSlide>
))}
</Swiper>
</div>
);
};