This commit is contained in:
zhangjianjun 2026-03-28 16:56:02 +08:00
parent 558c3c031d
commit cecfe91391
3 changed files with 115 additions and 55 deletions

View File

@ -11,8 +11,8 @@ type Data = {
contentSubtitle?: string;
contentText?: string;
content?: string;
/** 以 mockData 为准tabItems 可能使用 sideImage 或 backgroundImage */
sideImage?: string;
/** 以 mockData 为准tabItems 可能使用 sideImage 或 backgroundImagestring[] 时右侧为轮播 */
sideImage?: string | string[];
path?: string;
}[],
backgroundImage?: string;

View File

@ -74,15 +74,15 @@
.topTabsBottomLine {
position: absolute;
bottom: -1px;
height: .125rem;
bottom: 0px;
height: 1px;
background: #14355C;
transition: left 0.25s ease, width 0.25s ease;
z-index: 1;
}
.topTabsBottomLineWhite {
position: absolute;
bottom: -1px;
bottom: 0px;
width: 100%;
height: .125rem;
background: #D5D8DC;
@ -177,9 +177,26 @@
img {
width: 50rem;
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 {
margin: 0 auto;
display: grid;
@ -214,9 +231,18 @@
gap: 2.5rem;
}
.topTabsContentRight img {
.topTabsContentRight img,
.sideImageSwiper {
width: 100%;
height: auto;
min-height: 12rem;
}
.sideImageSwiper :global(.swiper-slide) img {
width: 100%;
height: auto;
max-height: 50vh;
object-fit: cover;
}
.topTabsContentItems {

View File

@ -3,7 +3,10 @@ import styles from './index.module.css';
import TopTabs from './TopTabs';
import { useLocation } from 'react-router-dom';
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 = {
tabItems: {
@ -13,15 +16,21 @@ type Data = {
contentSubtitle?: string;
contentText?: string;
content?: string;
/** 以 mockData 为准 */
sideImage?: string;
/** 以 mockData 为准;传 string[] 时为右侧轮播 */
sideImage?: string | string[];
path?: string;
items?: {label: string}[];
items?: { label: string }[];
}[]
backgroundImage?: string;
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 }) {
const location = useLocation();
const hash = location.hash;
@ -36,6 +45,9 @@ export default function TopTabsSection({ data, className }: { data: Data, classN
}
}
}, [hashId, data.tabItems])
const sideSlides = sideImageToSlides(data.tabItems[activeIndex]?.sideImage);
return (
<section className={`${styles.topTabsSection} ${className}`} style={{ backgroundImage: `url(${data.backgroundImage})` }}>
<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 ?
<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}>
<span>{item.label}</span>
</li>
@ -89,7 +101,29 @@ export default function TopTabsSection({ data, className }: { data: Data, classN
</div>
<div className={styles.topTabsContentRight}>
<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>
</div>
</>