This commit is contained in:
parent
558c3c031d
commit
cecfe91391
|
|
@ -11,8 +11,8 @@ type Data = {
|
||||||
contentSubtitle?: string;
|
contentSubtitle?: string;
|
||||||
contentText?: string;
|
contentText?: string;
|
||||||
content?: string;
|
content?: string;
|
||||||
/** 以 mockData 为准,tabItems 可能使用 sideImage 或 backgroundImage */
|
/** 以 mockData 为准,tabItems 可能使用 sideImage 或 backgroundImage;string[] 时右侧为轮播 */
|
||||||
sideImage?: string;
|
sideImage?: string | string[];
|
||||||
path?: string;
|
path?: string;
|
||||||
}[],
|
}[],
|
||||||
backgroundImage?: string;
|
backgroundImage?: string;
|
||||||
|
|
|
||||||
|
|
@ -74,15 +74,15 @@
|
||||||
|
|
||||||
.topTabsBottomLine {
|
.topTabsBottomLine {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: -1px;
|
bottom: 0px;
|
||||||
height: .125rem;
|
height: 1px;
|
||||||
background: #14355C;
|
background: #14355C;
|
||||||
transition: left 0.25s ease, width 0.25s ease;
|
transition: left 0.25s ease, width 0.25s ease;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
.topTabsBottomLineWhite {
|
.topTabsBottomLineWhite {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: -1px;
|
bottom: 0px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: .125rem;
|
height: .125rem;
|
||||||
background: #D5D8DC;
|
background: #D5D8DC;
|
||||||
|
|
@ -177,9 +177,26 @@
|
||||||
img {
|
img {
|
||||||
width: 50rem;
|
width: 50rem;
|
||||||
height: 31.25rem;
|
height: 31.25rem;
|
||||||
|
object-fit: cover;
|
||||||
|
display: block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sideImageSwiper {
|
||||||
|
width: 50rem;
|
||||||
|
height: 31.25rem;
|
||||||
|
--swiper-pagination-color: #14355c;
|
||||||
|
--swiper-pagination-bullet-inactive-color: #d5d8dc;
|
||||||
|
--swiper-pagination-bullet-inactive-opacity: 1;
|
||||||
|
--swiper-pagination-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sideImageSwiper :global(.swiper-slide) img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
.topTabsContentItems {
|
.topTabsContentItems {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
display: grid;
|
display: grid;
|
||||||
|
|
@ -214,9 +231,18 @@
|
||||||
gap: 2.5rem;
|
gap: 2.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.topTabsContentRight img {
|
.topTabsContentRight img,
|
||||||
|
.sideImageSwiper {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: auto;
|
height: auto;
|
||||||
|
min-height: 12rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sideImageSwiper :global(.swiper-slide) img {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
max-height: 50vh;
|
||||||
|
object-fit: cover;
|
||||||
}
|
}
|
||||||
|
|
||||||
.topTabsContentItems {
|
.topTabsContentItems {
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,10 @@ import styles from './index.module.css';
|
||||||
import TopTabs from './TopTabs';
|
import TopTabs from './TopTabs';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router-dom';
|
||||||
import ScrollReveal from '@/components/ScrollReveal';
|
import ScrollReveal from '@/components/ScrollReveal';
|
||||||
|
import { Swiper, SwiperSlide } from 'swiper/react';
|
||||||
|
import { Autoplay, Pagination } from 'swiper/modules';
|
||||||
|
import 'swiper/css';
|
||||||
|
import 'swiper/css/pagination';
|
||||||
|
|
||||||
type Data = {
|
type Data = {
|
||||||
tabItems: {
|
tabItems: {
|
||||||
|
|
@ -13,15 +16,21 @@ type Data = {
|
||||||
contentSubtitle?: string;
|
contentSubtitle?: string;
|
||||||
contentText?: string;
|
contentText?: string;
|
||||||
content?: string;
|
content?: string;
|
||||||
/** 以 mockData 为准 */
|
/** 以 mockData 为准;传 string[] 时为右侧轮播 */
|
||||||
sideImage?: string;
|
sideImage?: string | string[];
|
||||||
path?: string;
|
path?: string;
|
||||||
items?: {label: string}[];
|
items?: { label: string }[];
|
||||||
}[]
|
}[]
|
||||||
backgroundImage?: string;
|
backgroundImage?: string;
|
||||||
titleDirection?: 'row' | 'column';
|
titleDirection?: 'row' | 'column';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sideImageToSlides(sideImage: string | string[] | undefined): string[] {
|
||||||
|
if (Array.isArray(sideImage)) return sideImage.filter(Boolean);
|
||||||
|
if (sideImage) return [sideImage];
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
export default function TopTabsSection({ data, className }: { data: Data, className?: string }) {
|
export default function TopTabsSection({ data, className }: { data: Data, className?: string }) {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const hash = location.hash;
|
const hash = location.hash;
|
||||||
|
|
@ -36,6 +45,9 @@ export default function TopTabsSection({ data, className }: { data: Data, classN
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [hashId, data.tabItems])
|
}, [hashId, data.tabItems])
|
||||||
|
|
||||||
|
const sideSlides = sideImageToSlides(data.tabItems[activeIndex]?.sideImage);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className={`${styles.topTabsSection} ${className}`} style={{ backgroundImage: `url(${data.backgroundImage})` }}>
|
<section className={`${styles.topTabsSection} ${className}`} style={{ backgroundImage: `url(${data.backgroundImage})` }}>
|
||||||
<div aria-hidden="true">
|
<div aria-hidden="true">
|
||||||
|
|
@ -49,7 +61,7 @@ export default function TopTabsSection({ data, className }: { data: Data, classN
|
||||||
data.tabItems[activeIndex]?.items && (data.tabItems[activeIndex]?.items as any).length > 0 ?
|
data.tabItems[activeIndex]?.items && (data.tabItems[activeIndex]?.items as any).length > 0 ?
|
||||||
<ul className={styles.topTabsContentItems}>
|
<ul className={styles.topTabsContentItems}>
|
||||||
{
|
{
|
||||||
(data.tabItems[activeIndex]?.items as any).map((item: {label: string}) => (
|
(data.tabItems[activeIndex]?.items as any).map((item: { label: string }) => (
|
||||||
<li key={item.label} className={styles.topTabsContentItem}>
|
<li key={item.label} className={styles.topTabsContentItem}>
|
||||||
<span>{item.label}</span>
|
<span>{item.label}</span>
|
||||||
</li>
|
</li>
|
||||||
|
|
@ -89,7 +101,29 @@ export default function TopTabsSection({ data, className }: { data: Data, classN
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.topTabsContentRight}>
|
<div className={styles.topTabsContentRight}>
|
||||||
<ScrollReveal preset="slideLeft" delay={0.5} >
|
<ScrollReveal preset="slideLeft" delay={0.5} >
|
||||||
<img src={data.tabItems[activeIndex].sideImage} alt="side-image" />
|
{sideSlides.length > 1 ? (
|
||||||
|
<Swiper
|
||||||
|
className={styles.sideImageSwiper}
|
||||||
|
modules={[Autoplay, Pagination]}
|
||||||
|
slidesPerView={1}
|
||||||
|
spaceBetween={0}
|
||||||
|
loop
|
||||||
|
allowTouchMove
|
||||||
|
autoplay={{
|
||||||
|
delay: 4500,
|
||||||
|
disableOnInteraction: false,
|
||||||
|
}}
|
||||||
|
pagination={{ clickable: true }}
|
||||||
|
>
|
||||||
|
{sideSlides.map((src, i) => (
|
||||||
|
<SwiperSlide key={`${src}-${i}`}>
|
||||||
|
<img src={src} alt="" />
|
||||||
|
</SwiperSlide>
|
||||||
|
))}
|
||||||
|
</Swiper>
|
||||||
|
) : (
|
||||||
|
<img src={sideSlides[0] || sideSlides as any} alt="" />
|
||||||
|
)}
|
||||||
</ScrollReveal>
|
</ScrollReveal>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue