@anker-in/headless-ui 1.1.69 → 1.1.70
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/biz-components/MediaSceneSwitcherV2/index.d.ts +7 -8
- package/dist/cjs/biz-components/MediaSceneSwitcherV2/index.js +1 -1
- package/dist/cjs/biz-components/MediaSceneSwitcherV2/index.js.map +3 -3
- package/dist/esm/biz-components/MediaSceneSwitcherV2/index.d.ts +7 -8
- package/dist/esm/biz-components/MediaSceneSwitcherV2/index.js +1 -1
- package/dist/esm/biz-components/MediaSceneSwitcherV2/index.js.map +3 -3
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import type { Media } from '../../types/props.js';
|
|
2
|
+
import type { Media, Theme } from '../../types/props.js';
|
|
3
3
|
export type MediaSceneSwitcherV2SemanticName = 'root' | 'header' | 'title' | 'subtitle' | 'container' | 'tabList' | 'tabItem' | 'tabTitle' | 'tabDescription' | 'mediaWrapper' | 'media' | 'swiper' | 'slide' | 'slideMedia' | 'slideContent';
|
|
4
4
|
/**
|
|
5
5
|
* 场景项数据接口
|
|
@@ -29,6 +29,8 @@ export type MediaSceneSwitcherV2Layout = 'left' | 'right' | 'top';
|
|
|
29
29
|
* MediaSceneSwitcherV2 业务组件数据接口
|
|
30
30
|
*/
|
|
31
31
|
export interface MediaSceneSwitcherV2Data {
|
|
32
|
+
/** 主题 */
|
|
33
|
+
theme?: Theme;
|
|
32
34
|
/** 主标题 */
|
|
33
35
|
title?: string;
|
|
34
36
|
/** 副标题 */
|
|
@@ -39,6 +41,10 @@ export interface MediaSceneSwitcherV2Data {
|
|
|
39
41
|
defaultActiveIndex?: number;
|
|
40
42
|
/** 布局模式,默认 text-left */
|
|
41
43
|
layout?: MediaSceneSwitcherV2Layout;
|
|
44
|
+
/** 是否开启自动轮播,默认 true */
|
|
45
|
+
autoplay?: boolean;
|
|
46
|
+
/** 自动轮播间隔时间(毫秒),默认 3000 */
|
|
47
|
+
autoplayDelay?: number;
|
|
42
48
|
}
|
|
43
49
|
export interface MediaSceneSwitcherV2Props extends React.HTMLAttributes<HTMLDivElement> {
|
|
44
50
|
/** 业务数据 */
|
|
@@ -48,12 +54,5 @@ export interface MediaSceneSwitcherV2Props extends React.HTMLAttributes<HTMLDivE
|
|
|
48
54
|
/** 场景切换回调 */
|
|
49
55
|
onSceneChange?: (index: number, scene: MediaSceneSwitcherV2Item) => void;
|
|
50
56
|
}
|
|
51
|
-
/**
|
|
52
|
-
* MediaSceneSwitcherV2 - 多场景切换组件
|
|
53
|
-
*
|
|
54
|
-
* @description 用于展示多个场景的切换组件,支持响应式布局:
|
|
55
|
-
* - mobile/tablet: 横向滑动卡片布局
|
|
56
|
-
* - laptop+: 左文右图 / 左图右文布局
|
|
57
|
-
*/
|
|
58
57
|
declare const MediaSceneSwitcherV2: React.ForwardRefExoticComponent<MediaSceneSwitcherV2Props & React.RefAttributes<HTMLDivElement>>;
|
|
59
58
|
export default MediaSceneSwitcherV2;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";"use client";var
|
|
1
|
+
"use strict";"use client";var j=Object.create;var I=Object.defineProperty;var E=Object.getOwnPropertyDescriptor;var B=Object.getOwnPropertyNames;var H=Object.getPrototypeOf,F=Object.prototype.hasOwnProperty;var O=(e,t)=>{for(var l in t)I(e,l,{get:t[l],enumerable:!0})},A=(e,t,l,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let d of B(t))!F.call(e,d)&&d!==l&&I(e,d,{get:()=>t[d],enumerable:!(n=E(t,d))||n.enumerable});return e};var C=(e,t,l)=>(l=e!=null?j(H(e)):{},A(t||!e||!e.__esModule?I(l,"default",{value:e,enumerable:!0}):l,e)),U=e=>A(I({},"__esModule",{value:!0}),e);var q={};O(q,{default:()=>Q});module.exports=U(q);var i=require("react/jsx-runtime"),m=C(require("react")),R=require("swiper/react"),v=require("swiper/modules"),k=require("react-responsive"),a=require("../../helpers/index.js"),z=C(require("../../components/picture.js")),c=require("../../components/index.js");const N=[{key:"lgDesktop",width:1920},{key:"desktop",width:1440},{key:"laptop",width:1024},{key:"tablet",width:768},{key:"mobile",width:390}],Y=(e,t)=>e[t]?.mimeType==="video/mp4",_=e=>N.filter(({key:l})=>e[l]?.url&&e[l]?.mimeType!=="video/mp4").map(({key:l,width:n})=>`${e[l].url} ${n}`).join(", "),$=(e,t)=>{for(const{key:l}of N)if(e[l]?.alt)return e[l].alt;return t},V=({media:e,alt:t,className:l})=>{const n=(0,k.useMediaQuery)({minWidth:1920}),d=(0,k.useMediaQuery)({minWidth:1440,maxWidth:1919}),g=(0,k.useMediaQuery)({minWidth:1025,maxWidth:1439}),u=(0,k.useMediaQuery)({minWidth:768,maxWidth:1024}),f=m.useMemo(()=>{if(n&&e.lgDesktop?.url)return"lgDesktop";if(d&&e.desktop?.url)return"desktop";if(g&&e.laptop?.url)return"laptop";if(u&&e.tablet?.url)return"tablet";if(e.mobile?.url)return"mobile";for(const{key:y}of N)if(e[y]?.url)return y;return"desktop"},[n,d,g,u,e]),s=e[f];if(!s?.url)return null;if(Y(e,f))return(0,i.jsx)("video",{src:s.url,className:l,autoPlay:!0,loop:!0,muted:!0,playsInline:!0});const S=_(e);return(0,i.jsx)(z.default,{source:S||s.url,alt:$(e,t),className:l,imgClassName:"size-full object-cover"})},K=3e3,W=m.forwardRef(({className:e,classNames:t={},data:l,onSceneChange:n,...d},g)=>{const{title:u,subtitle:f,items:s,defaultActiveIndex:S=0,layout:y="left",autoplay:h=!0,autoplayDelay:x=K}=l,[p,M]=m.useState(S),D=m.useRef(null),w=m.useRef(0);m.useEffect(()=>{if(!(!h||s.length<=1))return w.current=window.setInterval(()=>{M(r=>(r+1)%s.length)},x),()=>{w.current&&window.clearInterval(w.current)}},[h,x,s.length]);const T=m.useCallback(r=>{M(r),n?.(r,s[r]),D.current?.slideTo(r),h&&s.length>1&&(w.current&&window.clearInterval(w.current),w.current=window.setInterval(()=>{M(o=>(o+1)%s.length)},x))},[s,n,h,x]),P=m.useCallback(r=>{const o=r.realIndex;M(o),n?.(o,s[o])},[s,n]),b=s[p],L=y==="top";return(0,i.jsxs)("div",{ref:g,className:(0,a.cn)("scene-switcher-root","text-info-primary w-full",e,t.root,{"aiui-dark":l.theme==="dark"}),...d,children:[(u||f)&&(0,i.jsxs)("div",{className:(0,a.cn)("scene-switcher-header mb-6",t.header),children:[u&&(0,i.jsx)(c.Heading,{as:"h2",size:4,html:u,className:(0,a.cn)("scene-switcher-title",t.title)}),f&&(0,i.jsx)(c.Text,{as:"p",size:3,className:(0,a.cn)("",t?.subtitle),html:f})]}),(0,i.jsx)("div",{className:(0,a.cn)("scene-switcher-swiper","laptop:hidden !overflow-visible",t.swiper),children:(0,i.jsx)(R.Swiper,{modules:[v.FreeMode,v.Mousewheel,v.Autoplay],onSwiper:r=>{D.current=r},className:"!overflow-visible",onSlideChange:P,slidesPerView:"auto",spaceBetween:12,freeMode:!0,mousewheel:{forceToAxis:!0},initialSlide:S,loop:h&&s.length>1,autoplay:h&&s.length>1?{delay:x,disableOnInteraction:!1}:!1,breakpoints:{768:{spaceBetween:16}},children:s.map((r,o)=>(0,i.jsx)(R.SwiperSlide,{className:"h-[462px] !w-[296px]",children:(0,i.jsxs)("div",{className:(0,a.cn)("scene-switcher-slide","flex cursor-pointer flex-col",t.slide),onClick:()=>T(o),children:[(0,i.jsx)("div",{className:(0,a.cn)("scene-switcher-slide-media","relative aspect-[296/320] w-full overflow-hidden",t.slideMedia),children:(0,i.jsx)(V,{media:r.media,alt:r.title,className:"rounded-t-box size-full overflow-hidden object-cover"})}),(0,i.jsxs)("div",{className:(0,a.cn)("scene-switcher-slide-content"," border-t pt-4",p===o?"border-info-primary border-t-4":"border-lines-primary",t.slideContent),children:[(0,i.jsx)(c.Heading,{className:(0,a.cn)("scene-switcher-tab-title ",p===o?"text-info-primary":"text-info-tertiary",r.title),size:3,as:"h3",html:r.title}),r.description&&(0,i.jsx)(c.Text,{className:(0,a.cn)("desktop:text-[16px] lg-desktop:text-[18px] line-clamp-2 text-[14px]",p===o?"text-info-primary":"text-info-tertiary"),html:r.description})]})]})},o))})}),L&&(0,i.jsxs)("div",{className:(0,a.cn)("scene-switcher-container","laptop:flex laptop:flex-col hidden","laptop:h-[470px] desktop:h-[628px] lg-desktop:h-[746px] desktop:gap-[32px] gap-[16px]",t.container),children:[(0,i.jsx)("div",{className:(0,a.cn)("scene-switcher-media-wrapper","flex-1 overflow-hidden",t.mediaWrapper),children:b&&(0,i.jsx)(V,{media:b.media,alt:b.title,className:(0,a.cn)("scene-switcher-media","rounded-box size-full object-cover",t.media)})}),(0,i.jsx)("div",{className:(0,a.cn)("scene-switcher-tab-list","border-lines-primary laptop:gap-4 desktop:gap-4 lg-desktop:gap-4 flex border-t",t.tabList),children:s.map((r,o)=>(0,i.jsxs)("div",{className:(0,a.cn)("scene-switcher-tab-item","desktop:pt-6 -mt-px flex-1 cursor-pointer border-t-2 pt-4 transition-colors",p===o?"border-info-primary border-t-4":"hover:border-lines-primary border-transparent",t.tabItem),onClick:()=>T(o),role:"button","aria-selected":p===o,children:[(0,i.jsx)(c.Heading,{className:(0,a.cn)("scene-switcher-tab-title line-clamp-2",p===o?"text-info-primary":"text-info-tertiary",r.title),size:3,as:"h3",html:r.title}),r.description&&(0,i.jsx)(c.Text,{className:(0,a.cn)("desktop:text-[16px] lg-desktop:text-[18px] line-clamp-2 text-[14px]",p===o?"text-info-primary":"text-info-tertiary"),html:r.description})]},o))})]}),!L&&(0,i.jsxs)("div",{className:(0,a.cn)("scene-switcher-container","laptop:flex laptop:gap-6 desktop:gap-8 lg-desktop:gap-10 hidden","laptop:h-[336px] desktop:h-[448px] lg-desktop:h-[560px]",y==="right"&&"flex-row-reverse",t.container),children:[(0,i.jsx)("div",{className:(0,a.cn)("scene-switcher-tab-list","border-lines-primary laptop:w-[320px] desktop:w-[400px] lg-desktop:w-[544px] flex flex-col justify-center border-t",t.tabList),children:s.map((r,o)=>(0,i.jsxs)("div",{className:(0,a.cn)("scene-switcher-tab-item","relative cursor-pointer py-4","before:bg-lines before:absolute before:inset-y-4 before:w-1","pl-6 before:left-0",p===o?"before:bg-info-primary":"hover:before:bg-lines-primary before:bg-lines",t.tabItem),onClick:()=>T(o),role:"button","aria-selected":p===o,children:[(0,i.jsx)(c.Heading,{className:(0,a.cn)("scene-switcher-tab-title",p===o?"text-info-primary":"text-info-tertiary",r.title),size:3,as:"h3",html:r.title}),r.description&&(0,i.jsx)(c.Text,{className:(0,a.cn)("desktop:text-[16px] lg-desktop:text-[18px] line-clamp-2 text-[14px]",p===o?"text-info-primary":"text-info-tertiary hidden"),html:r.description})]},o))}),(0,i.jsx)("div",{className:(0,a.cn)("scene-switcher-media-wrapper","flex-1 overflow-hidden",t.mediaWrapper),children:b&&(0,i.jsx)(V,{media:b.media,alt:b.title,className:(0,a.cn)("scene-switcher-media","rounded-box size-full h-full overflow-visible object-cover",t.media)})})]})]})});W.displayName="MediaSceneSwitcherV2";var Q=W;
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/biz-components/MediaSceneSwitcherV2/index.tsx"],
|
|
4
|
-
"sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { Swiper, SwiperSlide } from 'swiper/react'\nimport { FreeMode, Mousewheel } from 'swiper/modules'\nimport type { Swiper as SwiperType } from 'swiper'\nimport { cn } from '../../helpers/index.js'\nimport Picture from '../../components/picture.js'\nimport type { Media } from '../../types/props.js'\nimport { Heading, Text } from '../../components/index.js'\n\nexport type MediaSceneSwitcherV2SemanticName =\n | 'root'\n | 'header'\n | 'title'\n | 'subtitle'\n | 'container'\n | 'tabList'\n | 'tabItem'\n | 'tabTitle'\n | 'tabDescription'\n | 'mediaWrapper'\n | 'media'\n | 'swiper'\n | 'slide'\n | 'slideMedia'\n | 'slideContent'\n\n/**\n * \u573A\u666F\u9879\u6570\u636E\u63A5\u53E3\n */\nexport interface MediaSceneSwitcherV2Item {\n /** \u573A\u666F\u6807\u9898 */\n title: string\n /** \u573A\u666F\u63CF\u8FF0 */\n description?: string\n /** \u573A\u666F\u5A92\u4F53\uFF08\u56FE\u7247/\u89C6\u9891\uFF09 */\n media: {\n mobile?: Media\n tablet?: Media\n laptop?: Media\n desktop?: Media\n lgDesktop?: Media\n }\n}\n\n/**\n * \u5E03\u5C40\u6A21\u5F0F\n * - left: \u5DE6\u6587\u53F3\u56FE\uFF08laptop+ \u9ED8\u8BA4\uFF09\n * - right: \u5DE6\u56FE\u53F3\u6587\n * - top: \u4E0A\u56FE\u4E0B\u6587\uFF08swiper \u5361\u7247\u6A21\u5F0F\uFF09\n */\nexport type MediaSceneSwitcherV2Layout = 'left' | 'right' | 'top'\n\n/**\n * MediaSceneSwitcherV2 \u4E1A\u52A1\u7EC4\u4EF6\u6570\u636E\u63A5\u53E3\n */\nexport interface MediaSceneSwitcherV2Data {\n /** \u4E3B\u6807\u9898 */\n title?: string\n /** \u526F\u6807\u9898 */\n subtitle?: string\n /** \u573A\u666F\u5217\u8868 */\n items: MediaSceneSwitcherV2Item[]\n /** \u9ED8\u8BA4\u9009\u4E2D\u7684\u573A\u666F\u7D22\u5F15 */\n defaultActiveIndex?: number\n /** \u5E03\u5C40\u6A21\u5F0F\uFF0C\u9ED8\u8BA4 text-left */\n layout?: MediaSceneSwitcherV2Layout\n}\n\nexport interface MediaSceneSwitcherV2Props extends React.HTMLAttributes<HTMLDivElement> {\n /** \u4E1A\u52A1\u6570\u636E */\n data: MediaSceneSwitcherV2Data\n /** \u8BED\u4E49\u5316\u7C7B\u540D\u8986\u76D6 */\n classNames?: Partial<Record<MediaSceneSwitcherV2SemanticName, string>>\n /** \u573A\u666F\u5207\u6362\u56DE\u8C03 */\n onSceneChange?: (index: number, scene: MediaSceneSwitcherV2Item) => void\n}\n\n/**\n * \u54CD\u5E94\u5F0F\u5A92\u4F53\u7C7B\u578B\n */\ntype ResponsiveMedia = MediaSceneSwitcherV2Item['media']\n\n/**\n * \u5C06\u54CD\u5E94\u5F0F\u5A92\u4F53\u5BF9\u8C61\u8F6C\u4E3A Picture source \u683C\u5F0F\u5B57\u7B26\u4E32\n */\nconst getMediaSource = (media: ResponsiveMedia): string => {\n const breakpoints: { key: keyof ResponsiveMedia; width: number }[] = [\n { key: 'lgDesktop', width: 1920 },\n { key: 'desktop', width: 1440 },\n { key: 'laptop', width: 1024 },\n { key: 'tablet', width: 768 },\n { key: 'mobile', width: 390 },\n ]\n\n const sources = breakpoints\n .filter(({ key }) => media[key]?.url)\n .map(({ key, width }) => `${media[key]!.url} ${width}`)\n\n if (sources.length > 0) {\n return sources.join(', ')\n }\n\n // fallback: \u8FD4\u56DE\u4EFB\u610F\u4E00\u4E2A\u6709\u6548\u7684 url\n for (const { key } of breakpoints) {\n if (media[key]?.url) return media[key]!.url\n }\n\n return ''\n}\n\n/**\n * \u4ECE\u54CD\u5E94\u5F0F\u5A92\u4F53\u5BF9\u8C61\u83B7\u53D6 alt \u6587\u672C\n */\nconst getMediaAlt = (media: ResponsiveMedia, fallback: string): string => {\n const keys: (keyof ResponsiveMedia)[] = ['desktop', 'laptop', 'tablet', 'mobile', 'lgDesktop']\n for (const key of keys) {\n if (media[key]?.alt) return media[key]!.alt\n }\n return fallback\n}\n\n/**\n * \u5224\u65AD\u5A92\u4F53\u662F\u5426\u4E3A\u89C6\u9891\n */\nconst isVideo = (media: ResponsiveMedia): boolean => {\n const keys: (keyof ResponsiveMedia)[] = ['desktop', 'laptop', 'tablet', 'mobile', 'lgDesktop']\n for (const key of keys) {\n if (media[key]?.mimeType === 'video/mp4') return true\n }\n return false\n}\n\n/**\n * \u83B7\u53D6\u89C6\u9891 URL\n */\nconst getVideoUrl = (media: ResponsiveMedia): string => {\n const keys: (keyof ResponsiveMedia)[] = ['desktop', 'laptop', 'tablet', 'mobile', 'lgDesktop']\n for (const key of keys) {\n if (media[key]?.url) return media[key]!.url\n }\n return ''\n}\n\n/**\n * \u5A92\u4F53\u6E32\u67D3\u7EC4\u4EF6 - \u652F\u6301\u56FE\u7247\u548C\u89C6\u9891\n */\nconst MediaRenderer: React.FC<{\n media: ResponsiveMedia\n alt: string\n className?: string\n}> = ({ media, alt, className }) => {\n if (isVideo(media)) {\n return <video src={getVideoUrl(media)} className={className} autoPlay loop muted playsInline />\n }\n\n return (\n <Picture\n source={getMediaSource(media)}\n alt={getMediaAlt(media, alt)}\n className={className}\n imgClassName=\"size-full\"\n />\n )\n}\n\n/**\n * MediaSceneSwitcherV2 - \u591A\u573A\u666F\u5207\u6362\u7EC4\u4EF6\n *\n * @description \u7528\u4E8E\u5C55\u793A\u591A\u4E2A\u573A\u666F\u7684\u5207\u6362\u7EC4\u4EF6\uFF0C\u652F\u6301\u54CD\u5E94\u5F0F\u5E03\u5C40\uFF1A\n * - mobile/tablet: \u6A2A\u5411\u6ED1\u52A8\u5361\u7247\u5E03\u5C40\n * - laptop+: \u5DE6\u6587\u53F3\u56FE / \u5DE6\u56FE\u53F3\u6587\u5E03\u5C40\n */\nconst MediaSceneSwitcherV2 = React.forwardRef<HTMLDivElement, MediaSceneSwitcherV2Props>(\n ({ className, classNames = {}, data, onSceneChange, ...props }, ref) => {\n const { title, subtitle, items: scenes, defaultActiveIndex = 0, layout = 'left' } = data\n const [activeIndex, setActiveIndex] = React.useState(defaultActiveIndex)\n const swiperRef = React.useRef<SwiperType | null>(null)\n\n const handleSceneClick = React.useCallback(\n (index: number) => {\n setActiveIndex(index)\n onSceneChange?.(index, scenes[index])\n // \u540C\u6B65 swiper \u4F4D\u7F6E\n swiperRef.current?.slideTo(index)\n },\n [scenes, onSceneChange]\n )\n\n const handleSlideChange = React.useCallback(\n (swiper: SwiperType) => {\n const index = swiper.activeIndex\n setActiveIndex(index)\n onSceneChange?.(index, scenes[index])\n },\n [scenes, onSceneChange]\n )\n\n const activeScene = scenes[activeIndex]\n\n const isMediaTop = layout === 'top'\n\n return (\n <div ref={ref} className={cn('scene-switcher-root', 'w-full', className, classNames.root)} {...props}>\n {/* \u6807\u9898\u533A\u57DF */}\n {(title || subtitle) && (\n <div className={cn('scene-switcher-header mb-6', classNames.header)}>\n {title && (\n <Heading as=\"h2\" size={4} html={title} className={cn('scene-switcher-title', classNames.title)} />\n )}\n {subtitle && <Text as=\"p\" size={3} className={cn('', classNames?.subtitle)} html={subtitle} />}\n </div>\n )}\n {/* Mobile/Tablet: \u6A2A\u5411\u6ED1\u52A8\u5361\u7247\u5E03\u5C40 */}\n <div className={cn('scene-switcher-swiper', 'laptop:hidden !overflow-visible', classNames.swiper)}>\n <Swiper\n modules={[FreeMode, Mousewheel]}\n onSwiper={swiper => {\n swiperRef.current = swiper\n }}\n className=\"!overflow-visible\"\n onSlideChange={handleSlideChange}\n slidesPerView=\"auto\"\n spaceBetween={12}\n freeMode={true}\n mousewheel={{ forceToAxis: true }}\n initialSlide={defaultActiveIndex}\n breakpoints={{\n 768: { spaceBetween: 16 },\n }}\n >\n {scenes.map((scene, index) => (\n <SwiperSlide key={index} className=\"tablet:!w-[296px] h-[462px] !w-[280px] \">\n <div\n className={cn('scene-switcher-slide', 'flex cursor-pointer flex-col', classNames.slide)}\n onClick={() => handleSceneClick(index)}\n >\n {/* \u5A92\u4F53 */}\n <div\n className={cn(\n 'scene-switcher-slide-media',\n 'relative aspect-[296/320] w-full overflow-hidden',\n classNames.slideMedia\n )}\n >\n <MediaRenderer\n media={scene.media}\n alt={scene.title}\n className=\"rounded-t-box size-full overflow-hidden object-cover\"\n />\n </div>\n {/* \u6587\u5B57\u5185\u5BB9 */}\n <div\n className={cn(\n 'scene-switcher-slide-content',\n ' border-t pt-4',\n activeIndex === index ? 'border-info-primary border-t-4' : 'border-lines-primary',\n classNames.slideContent\n )}\n >\n <Heading\n className={cn(\n 'scene-switcher-tab-title ',\n activeIndex === index ? 'text-info-primary' : 'text-info-tertiary',\n scene.title\n )}\n size={3}\n as={'h3'}\n html={scene.title}\n />\n {scene.description && (\n <Text\n className={cn(\n 'desktop:text-[16px] lg-desktop:text-[18px] line-clamp-2 text-[14px]',\n activeIndex === index ? 'text-info-primary' : 'text-info-tertiary'\n )}\n html={scene.description}\n />\n )}\n </div>\n </div>\n </SwiperSlide>\n ))}\n </Swiper>\n </div>\n\n {/* Laptop+: media-top \u5E03\u5C40 (\u4E0A\u56FE\u4E0B\u6587) */}\n {isMediaTop && (\n <div\n className={cn(\n 'scene-switcher-container',\n 'laptop:flex laptop:flex-col hidden',\n 'laptop:h-[470px] desktop:h-[628px] lg-desktop:h-[746px] desktop:gap-[32px] gap-[16px]',\n classNames.container\n )}\n >\n {/* \u5A92\u4F53\u533A\u57DF - \u663E\u793A\u5F53\u524D\u9009\u4E2D */}\n <div className={cn('scene-switcher-media-wrapper', 'flex-1 overflow-hidden', classNames.mediaWrapper)}>\n {activeScene && (\n <MediaRenderer\n media={activeScene.media}\n alt={activeScene.title}\n className={cn('scene-switcher-media', 'rounded-box size-full object-cover', classNames.media)}\n />\n )}\n </div>\n\n {/* Tab \u5217\u8868 - \u6A2A\u5411\u6392\u5217 */}\n <div\n className={cn(\n 'scene-switcher-tab-list',\n 'border-lines-primary laptop:gap-4 desktop:gap-4 lg-desktop:gap-4 flex border-t',\n classNames.tabList\n )}\n >\n {scenes.map((scene, index) => (\n <div\n key={index}\n className={cn(\n 'scene-switcher-tab-item',\n 'desktop:pt-6 -mt-px flex-1 cursor-pointer border-t-2 pt-4 transition-colors',\n activeIndex === index\n ? 'border-info-primary border-t-4'\n : 'hover:border-lines-primary border-transparent',\n classNames.tabItem\n )}\n onClick={() => handleSceneClick(index)}\n role=\"button\"\n aria-selected={activeIndex === index}\n >\n <Heading\n className={cn(\n 'scene-switcher-tab-title line-clamp-2',\n activeIndex === index ? 'text-info-primary' : 'text-info-tertiary',\n scene.title\n )}\n size={3}\n as={'h3'}\n html={scene.title}\n />\n {scene.description && (\n <Text\n className={cn(\n 'desktop:text-[16px] lg-desktop:text-[18px] line-clamp-2 text-[14px]',\n activeIndex === index ? 'text-info-primary' : 'text-info-tertiary'\n )}\n html={scene.description}\n />\n )}\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Laptop+: \u5DE6\u6587\u53F3\u56FE / \u5DE6\u56FE\u53F3\u6587\u5E03\u5C40 */}\n {!isMediaTop && (\n <div\n className={cn(\n 'scene-switcher-container',\n 'laptop:flex laptop:gap-6 desktop:gap-8 lg-desktop:gap-10 hidden',\n 'laptop:h-[336px] desktop:h-[448px] lg-desktop:h-[560px]',\n layout === 'right' && 'flex-row-reverse',\n classNames.container\n )}\n >\n {/* Tab \u5217\u8868 */}\n <div\n className={cn(\n 'scene-switcher-tab-list',\n 'border-lines-primary laptop:w-[320px] desktop:w-[400px] lg-desktop:w-[544px] flex flex-col justify-center border-t',\n classNames.tabList\n )}\n >\n {scenes.map((scene, index) => (\n <div\n key={index}\n className={cn(\n 'scene-switcher-tab-item',\n 'relative cursor-pointer py-4',\n 'before:absolute before:inset-y-4 before:w-1 before:transition-colors',\n layout === 'right' ? 'pr-6 before:right-0' : 'pl-6 before:left-0',\n activeIndex === index\n ? 'before:bg-info-primary'\n : 'hover:before:bg-lines-primary before:bg-transparent',\n classNames.tabItem\n )}\n onClick={() => handleSceneClick(index)}\n role=\"button\"\n aria-selected={activeIndex === index}\n >\n <Heading\n className={cn(\n 'scene-switcher-tab-title',\n activeIndex === index ? 'text-info-primary' : 'text-info-tertiary',\n scene.title\n )}\n size={3}\n as={'h3'}\n html={scene.title}\n />\n {scene.description && (\n <Text\n className={cn(\n 'desktop:text-[16px] lg-desktop:text-[18px] line-clamp-2 text-[14px]',\n activeIndex === index ? 'text-info-primary' : 'text-info-tertiary hidden'\n )}\n html={scene.description}\n />\n )}\n </div>\n ))}\n </div>\n\n {/* \u5A92\u4F53\u533A\u57DF */}\n <div className={cn('scene-switcher-media-wrapper', 'flex-1 overflow-hidden', classNames.mediaWrapper)}>\n {activeScene && (\n <MediaRenderer\n media={activeScene.media}\n alt={activeScene.title}\n className={cn(\n 'scene-switcher-media',\n 'rounded-box size-full h-full overflow-visible object-cover',\n classNames.media\n )}\n />\n )}\n </div>\n </div>\n )}\n </div>\n )\n }\n)\n\nMediaSceneSwitcherV2.displayName = 'MediaSceneSwitcherV2'\nexport default MediaSceneSwitcherV2\n"],
|
|
5
|
-
"mappings": "ukBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,aAAAE,IAAA,eAAAC,EAAAH,
|
|
6
|
-
"names": ["MediaSceneSwitcherV2_exports", "__export", "MediaSceneSwitcherV2_default", "__toCommonJS", "import_jsx_runtime", "React", "import_react", "import_modules", "import_helpers", "import_picture", "import_components", "
|
|
4
|
+
"sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { Swiper, SwiperSlide } from 'swiper/react'\nimport { FreeMode, Mousewheel, Autoplay } from 'swiper/modules'\nimport type { Swiper as SwiperType } from 'swiper'\nimport { useMediaQuery } from 'react-responsive'\nimport { cn } from '../../helpers/index.js'\nimport Picture from '../../components/picture.js'\nimport type { Media, Theme } from '../../types/props.js'\nimport { Heading, Text } from '../../components/index.js'\n\nexport type MediaSceneSwitcherV2SemanticName =\n | 'root'\n | 'header'\n | 'title'\n | 'subtitle'\n | 'container'\n | 'tabList'\n | 'tabItem'\n | 'tabTitle'\n | 'tabDescription'\n | 'mediaWrapper'\n | 'media'\n | 'swiper'\n | 'slide'\n | 'slideMedia'\n | 'slideContent'\n\n/**\n * \u573A\u666F\u9879\u6570\u636E\u63A5\u53E3\n */\nexport interface MediaSceneSwitcherV2Item {\n /** \u573A\u666F\u6807\u9898 */\n title: string\n /** \u573A\u666F\u63CF\u8FF0 */\n description?: string\n /** \u573A\u666F\u5A92\u4F53\uFF08\u56FE\u7247/\u89C6\u9891\uFF09 */\n media: {\n mobile?: Media\n tablet?: Media\n laptop?: Media\n desktop?: Media\n lgDesktop?: Media\n }\n}\n\n/**\n * \u5E03\u5C40\u6A21\u5F0F\n * - left: \u5DE6\u6587\u53F3\u56FE\uFF08laptop+ \u9ED8\u8BA4\uFF09\n * - right: \u5DE6\u56FE\u53F3\u6587\n * - top: \u4E0A\u56FE\u4E0B\u6587\uFF08swiper \u5361\u7247\u6A21\u5F0F\uFF09\n */\nexport type MediaSceneSwitcherV2Layout = 'left' | 'right' | 'top'\n\n/**\n * MediaSceneSwitcherV2 \u4E1A\u52A1\u7EC4\u4EF6\u6570\u636E\u63A5\u53E3\n */\nexport interface MediaSceneSwitcherV2Data {\n /** \u4E3B\u9898 */\n theme?: Theme\n /** \u4E3B\u6807\u9898 */\n title?: string\n /** \u526F\u6807\u9898 */\n subtitle?: string\n /** \u573A\u666F\u5217\u8868 */\n items: MediaSceneSwitcherV2Item[]\n /** \u9ED8\u8BA4\u9009\u4E2D\u7684\u573A\u666F\u7D22\u5F15 */\n defaultActiveIndex?: number\n /** \u5E03\u5C40\u6A21\u5F0F\uFF0C\u9ED8\u8BA4 text-left */\n layout?: MediaSceneSwitcherV2Layout\n /** \u662F\u5426\u5F00\u542F\u81EA\u52A8\u8F6E\u64AD\uFF0C\u9ED8\u8BA4 true */\n autoplay?: boolean\n /** \u81EA\u52A8\u8F6E\u64AD\u95F4\u9694\u65F6\u95F4\uFF08\u6BEB\u79D2\uFF09\uFF0C\u9ED8\u8BA4 3000 */\n autoplayDelay?: number\n}\n\nexport interface MediaSceneSwitcherV2Props extends React.HTMLAttributes<HTMLDivElement> {\n /** \u4E1A\u52A1\u6570\u636E */\n data: MediaSceneSwitcherV2Data\n /** \u8BED\u4E49\u5316\u7C7B\u540D\u8986\u76D6 */\n classNames?: Partial<Record<MediaSceneSwitcherV2SemanticName, string>>\n /** \u573A\u666F\u5207\u6362\u56DE\u8C03 */\n onSceneChange?: (index: number, scene: MediaSceneSwitcherV2Item) => void\n}\n\n/**\n * \u54CD\u5E94\u5F0F\u5A92\u4F53\u7C7B\u578B\n */\ntype ResponsiveMedia = MediaSceneSwitcherV2Item['media']\n\n/** \u65AD\u70B9\u914D\u7F6E */\nconst BREAKPOINTS: { key: keyof ResponsiveMedia; width: number }[] = [\n { key: 'lgDesktop', width: 1920 },\n { key: 'desktop', width: 1440 },\n { key: 'laptop', width: 1024 },\n { key: 'tablet', width: 768 },\n { key: 'mobile', width: 390 },\n]\n\n/**\n * \u68C0\u67E5\u5F53\u524D\u65AD\u70B9\u7684\u5A92\u4F53\u662F\u5426\u4E3A\u89C6\u9891\n */\nconst isCurrentMediaVideo = (media: ResponsiveMedia, currentBreakpoint: keyof ResponsiveMedia): boolean => {\n return media[currentBreakpoint]?.mimeType === 'video/mp4'\n}\n\n/**\n * \u5C06\u54CD\u5E94\u5F0F\u5A92\u4F53\u5BF9\u8C61\u8F6C\u4E3A Picture source \u683C\u5F0F\u5B57\u7B26\u4E32\n * \u683C\u5F0F: \"url1 1920, url2 1440, url3 1024\"\n */\nconst getImageSource = (media: ResponsiveMedia): string => {\n const sources = BREAKPOINTS.filter(({ key }) => media[key]?.url && media[key]?.mimeType !== 'video/mp4').map(\n ({ key, width }) => `${media[key]!.url} ${width}`\n )\n\n return sources.join(', ')\n}\n\n/**\n * \u83B7\u53D6 alt \u6587\u672C\n */\nconst getMediaAlt = (media: ResponsiveMedia, fallback: string): string => {\n for (const { key } of BREAKPOINTS) {\n if (media[key]?.alt) return media[key]!.alt\n }\n return fallback\n}\n\n/**\n * \u5A92\u4F53\u6E32\u67D3\u7EC4\u4EF6 - \u652F\u6301\u56FE\u7247\u548C\u89C6\u9891\uFF0C\u6839\u636E\u65AD\u70B9\u6E32\u67D3\u5BF9\u5E94\u8D44\u6E90\n */\nconst MediaRenderer: React.FC<{\n media: ResponsiveMedia\n alt: string\n className?: string\n}> = ({ media, alt, className }) => {\n const isLgDesktop = useMediaQuery({ minWidth: 1920 })\n const isDesktop = useMediaQuery({ minWidth: 1440, maxWidth: 1919 })\n const isLaptop = useMediaQuery({ minWidth: 1025, maxWidth: 1439 })\n const isTablet = useMediaQuery({ minWidth: 768, maxWidth: 1024 })\n\n // \u83B7\u53D6\u5F53\u524D\u65AD\u70B9 key\n const currentBreakpoint = React.useMemo((): keyof ResponsiveMedia => {\n if (isLgDesktop && media.lgDesktop?.url) return 'lgDesktop'\n if (isDesktop && media.desktop?.url) return 'desktop'\n if (isLaptop && media.laptop?.url) return 'laptop'\n if (isTablet && media.tablet?.url) return 'tablet'\n if (media.mobile?.url) return 'mobile'\n\n // fallback: \u8FD4\u56DE\u7B2C\u4E00\u4E2A\u6709\u6548\u7684\u65AD\u70B9\n for (const { key } of BREAKPOINTS) {\n if (media[key]?.url) return key\n }\n return 'desktop'\n }, [isLgDesktop, isDesktop, isLaptop, isTablet, media])\n\n const currentMedia = media[currentBreakpoint]\n\n if (!currentMedia?.url) return null\n\n // \u5F53\u524D\u65AD\u70B9\u662F\u89C6\u9891\u5219\u6E32\u67D3\u89C6\u9891\n if (isCurrentMediaVideo(media, currentBreakpoint)) {\n return <video src={currentMedia.url} className={className} autoPlay loop muted playsInline />\n }\n\n // \u56FE\u7247\uFF1A\u4F7F\u7528 Picture \u7EC4\u4EF6\u7684\u54CD\u5E94\u5F0F\u683C\u5F0F\n const imageSource = getImageSource(media)\n\n return (\n <Picture\n source={imageSource || currentMedia.url}\n alt={getMediaAlt(media, alt)}\n className={className}\n imgClassName=\"size-full object-cover\"\n />\n )\n}\n\n/**\n * MediaSceneSwitcherV2 - \u591A\u573A\u666F\u5207\u6362\u7EC4\u4EF6\n *\n * @description \u7528\u4E8E\u5C55\u793A\u591A\u4E2A\u573A\u666F\u7684\u5207\u6362\u7EC4\u4EF6\uFF0C\u652F\u6301\u54CD\u5E94\u5F0F\u5E03\u5C40\uFF1A\n * - mobile/tablet: \u6A2A\u5411\u6ED1\u52A8\u5361\u7247\u5E03\u5C40\n * - laptop+: \u5DE6\u6587\u53F3\u56FE / \u5DE6\u56FE\u53F3\u6587\u5E03\u5C40\n */\nconst DEFAULT_AUTOPLAY_DELAY = 3000\n\nconst MediaSceneSwitcherV2 = React.forwardRef<HTMLDivElement, MediaSceneSwitcherV2Props>(\n ({ className, classNames = {}, data, onSceneChange, ...props }, ref) => {\n const {\n title,\n subtitle,\n items: scenes,\n defaultActiveIndex = 0,\n layout = 'left',\n autoplay = true,\n autoplayDelay = DEFAULT_AUTOPLAY_DELAY,\n } = data\n const [activeIndex, setActiveIndex] = React.useState(defaultActiveIndex)\n const swiperRef = React.useRef<SwiperType | null>(null)\n const intervalRef = React.useRef<number>(0)\n\n // \u684C\u9762\u7AEF\u81EA\u52A8\u8F6E\u64AD\n React.useEffect(() => {\n if (!autoplay || scenes.length <= 1) return\n\n intervalRef.current = window.setInterval(() => {\n setActiveIndex(prev => (prev + 1) % scenes.length)\n }, autoplayDelay)\n\n return () => {\n if (intervalRef.current) {\n window.clearInterval(intervalRef.current)\n }\n }\n }, [autoplay, autoplayDelay, scenes.length])\n\n const handleSceneClick = React.useCallback(\n (index: number) => {\n setActiveIndex(index)\n onSceneChange?.(index, scenes[index])\n // \u540C\u6B65 swiper \u4F4D\u7F6E\n swiperRef.current?.slideTo(index)\n\n // \u91CD\u7F6E\u81EA\u52A8\u8F6E\u64AD\u8BA1\u65F6\u5668\n if (autoplay && scenes.length > 1) {\n if (intervalRef.current) {\n window.clearInterval(intervalRef.current)\n }\n intervalRef.current = window.setInterval(() => {\n setActiveIndex(prev => (prev + 1) % scenes.length)\n }, autoplayDelay)\n }\n },\n [scenes, onSceneChange, autoplay, autoplayDelay]\n )\n\n const handleSlideChange = React.useCallback(\n (swiper: SwiperType) => {\n // \u4F7F\u7528 realIndex \u4EE5\u6B63\u786E\u5904\u7406 loop \u6A21\u5F0F\n const index = swiper.realIndex\n setActiveIndex(index)\n onSceneChange?.(index, scenes[index])\n },\n [scenes, onSceneChange]\n )\n\n const activeScene = scenes[activeIndex]\n\n const isMediaTop = layout === 'top'\n\n return (\n <div\n ref={ref}\n className={cn('scene-switcher-root', 'text-info-primary w-full', className, classNames.root, {\n 'aiui-dark': data.theme === 'dark',\n })}\n {...props}\n >\n {/* \u6807\u9898\u533A\u57DF */}\n {(title || subtitle) && (\n <div className={cn('scene-switcher-header mb-6', classNames.header)}>\n {title && (\n <Heading as=\"h2\" size={4} html={title} className={cn('scene-switcher-title', classNames.title)} />\n )}\n {subtitle && <Text as=\"p\" size={3} className={cn('', classNames?.subtitle)} html={subtitle} />}\n </div>\n )}\n {/* Mobile/Tablet: \u6A2A\u5411\u6ED1\u52A8\u5361\u7247\u5E03\u5C40 */}\n <div className={cn('scene-switcher-swiper', 'laptop:hidden !overflow-visible', classNames.swiper)}>\n <Swiper\n modules={[FreeMode, Mousewheel, Autoplay]}\n onSwiper={swiper => {\n swiperRef.current = swiper\n }}\n className=\"!overflow-visible\"\n onSlideChange={handleSlideChange}\n slidesPerView=\"auto\"\n spaceBetween={12}\n freeMode={true}\n mousewheel={{ forceToAxis: true }}\n initialSlide={defaultActiveIndex}\n loop={autoplay && scenes.length > 1}\n autoplay={autoplay && scenes.length > 1 ? { delay: autoplayDelay, disableOnInteraction: false } : false}\n breakpoints={{\n 768: { spaceBetween: 16 },\n }}\n >\n {scenes.map((scene, index) => (\n <SwiperSlide key={index} className=\"h-[462px] !w-[296px]\">\n <div\n className={cn('scene-switcher-slide', 'flex cursor-pointer flex-col', classNames.slide)}\n onClick={() => handleSceneClick(index)}\n >\n {/* \u5A92\u4F53 */}\n <div\n className={cn(\n 'scene-switcher-slide-media',\n 'relative aspect-[296/320] w-full overflow-hidden',\n classNames.slideMedia\n )}\n >\n <MediaRenderer\n media={scene.media}\n alt={scene.title}\n className=\"rounded-t-box size-full overflow-hidden object-cover\"\n />\n </div>\n {/* \u6587\u5B57\u5185\u5BB9 */}\n <div\n className={cn(\n 'scene-switcher-slide-content',\n ' border-t pt-4',\n activeIndex === index ? 'border-info-primary border-t-4' : 'border-lines-primary',\n classNames.slideContent\n )}\n >\n <Heading\n className={cn(\n 'scene-switcher-tab-title ',\n activeIndex === index ? 'text-info-primary' : 'text-info-tertiary',\n scene.title\n )}\n size={3}\n as={'h3'}\n html={scene.title}\n />\n {scene.description && (\n <Text\n className={cn(\n 'desktop:text-[16px] lg-desktop:text-[18px] line-clamp-2 text-[14px]',\n activeIndex === index ? 'text-info-primary' : 'text-info-tertiary'\n )}\n html={scene.description}\n />\n )}\n </div>\n </div>\n </SwiperSlide>\n ))}\n </Swiper>\n </div>\n\n {/* Laptop+: media-top \u5E03\u5C40 (\u4E0A\u56FE\u4E0B\u6587) */}\n {isMediaTop && (\n <div\n className={cn(\n 'scene-switcher-container',\n 'laptop:flex laptop:flex-col hidden',\n 'laptop:h-[470px] desktop:h-[628px] lg-desktop:h-[746px] desktop:gap-[32px] gap-[16px]',\n classNames.container\n )}\n >\n {/* \u5A92\u4F53\u533A\u57DF - \u663E\u793A\u5F53\u524D\u9009\u4E2D */}\n <div className={cn('scene-switcher-media-wrapper', 'flex-1 overflow-hidden', classNames.mediaWrapper)}>\n {activeScene && (\n <MediaRenderer\n media={activeScene.media}\n alt={activeScene.title}\n className={cn('scene-switcher-media', 'rounded-box size-full object-cover', classNames.media)}\n />\n )}\n </div>\n\n {/* Tab \u5217\u8868 - \u6A2A\u5411\u6392\u5217 */}\n <div\n className={cn(\n 'scene-switcher-tab-list',\n 'border-lines-primary laptop:gap-4 desktop:gap-4 lg-desktop:gap-4 flex border-t',\n classNames.tabList\n )}\n >\n {scenes.map((scene, index) => (\n <div\n key={index}\n className={cn(\n 'scene-switcher-tab-item',\n 'desktop:pt-6 -mt-px flex-1 cursor-pointer border-t-2 pt-4 transition-colors',\n activeIndex === index\n ? 'border-info-primary border-t-4'\n : 'hover:border-lines-primary border-transparent',\n classNames.tabItem\n )}\n onClick={() => handleSceneClick(index)}\n role=\"button\"\n aria-selected={activeIndex === index}\n >\n <Heading\n className={cn(\n 'scene-switcher-tab-title line-clamp-2',\n activeIndex === index ? 'text-info-primary' : 'text-info-tertiary',\n scene.title\n )}\n size={3}\n as={'h3'}\n html={scene.title}\n />\n {scene.description && (\n <Text\n className={cn(\n 'desktop:text-[16px] lg-desktop:text-[18px] line-clamp-2 text-[14px]',\n activeIndex === index ? 'text-info-primary' : 'text-info-tertiary'\n )}\n html={scene.description}\n />\n )}\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Laptop+: \u5DE6\u6587\u53F3\u56FE / \u5DE6\u56FE\u53F3\u6587\u5E03\u5C40 */}\n {!isMediaTop && (\n <div\n className={cn(\n 'scene-switcher-container',\n 'laptop:flex laptop:gap-6 desktop:gap-8 lg-desktop:gap-10 hidden',\n 'laptop:h-[336px] desktop:h-[448px] lg-desktop:h-[560px]',\n layout === 'right' && 'flex-row-reverse',\n classNames.container\n )}\n >\n {/* Tab \u5217\u8868 */}\n <div\n className={cn(\n 'scene-switcher-tab-list',\n 'border-lines-primary laptop:w-[320px] desktop:w-[400px] lg-desktop:w-[544px] flex flex-col justify-center border-t',\n classNames.tabList\n )}\n >\n {scenes.map((scene, index) => (\n <div\n key={index}\n className={cn(\n 'scene-switcher-tab-item',\n 'relative cursor-pointer py-4',\n 'before:bg-lines before:absolute before:inset-y-4 before:w-1',\n 'pl-6 before:left-0',\n activeIndex === index ? 'before:bg-info-primary' : 'hover:before:bg-lines-primary before:bg-lines',\n classNames.tabItem\n )}\n onClick={() => handleSceneClick(index)}\n role=\"button\"\n aria-selected={activeIndex === index}\n >\n <Heading\n className={cn(\n 'scene-switcher-tab-title',\n activeIndex === index ? 'text-info-primary' : 'text-info-tertiary',\n scene.title\n )}\n size={3}\n as={'h3'}\n html={scene.title}\n />\n {scene.description && (\n <Text\n className={cn(\n 'desktop:text-[16px] lg-desktop:text-[18px] line-clamp-2 text-[14px]',\n activeIndex === index ? 'text-info-primary' : 'text-info-tertiary hidden'\n )}\n html={scene.description}\n />\n )}\n </div>\n ))}\n </div>\n\n {/* \u5A92\u4F53\u533A\u57DF */}\n <div className={cn('scene-switcher-media-wrapper', 'flex-1 overflow-hidden', classNames.mediaWrapper)}>\n {activeScene && (\n <MediaRenderer\n media={activeScene.media}\n alt={activeScene.title}\n className={cn(\n 'scene-switcher-media',\n 'rounded-box size-full h-full overflow-visible object-cover',\n classNames.media\n )}\n />\n )}\n </div>\n </div>\n )}\n </div>\n )\n }\n)\n\nMediaSceneSwitcherV2.displayName = 'MediaSceneSwitcherV2'\nexport default MediaSceneSwitcherV2\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["MediaSceneSwitcherV2_exports", "__export", "MediaSceneSwitcherV2_default", "__toCommonJS", "import_jsx_runtime", "React", "import_react", "import_modules", "import_react_responsive", "import_helpers", "import_picture", "import_components", "BREAKPOINTS", "isCurrentMediaVideo", "media", "currentBreakpoint", "getImageSource", "key", "width", "getMediaAlt", "fallback", "MediaRenderer", "alt", "className", "isLgDesktop", "isDesktop", "isLaptop", "isTablet", "currentMedia", "imageSource", "Picture", "DEFAULT_AUTOPLAY_DELAY", "MediaSceneSwitcherV2", "classNames", "data", "onSceneChange", "props", "ref", "title", "subtitle", "scenes", "defaultActiveIndex", "layout", "autoplay", "autoplayDelay", "activeIndex", "setActiveIndex", "swiperRef", "intervalRef", "prev", "handleSceneClick", "index", "handleSlideChange", "swiper", "activeScene", "isMediaTop", "scene"]
|
|
7
7
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import type { Media } from '../../types/props.js';
|
|
2
|
+
import type { Media, Theme } from '../../types/props.js';
|
|
3
3
|
export type MediaSceneSwitcherV2SemanticName = 'root' | 'header' | 'title' | 'subtitle' | 'container' | 'tabList' | 'tabItem' | 'tabTitle' | 'tabDescription' | 'mediaWrapper' | 'media' | 'swiper' | 'slide' | 'slideMedia' | 'slideContent';
|
|
4
4
|
/**
|
|
5
5
|
* 场景项数据接口
|
|
@@ -29,6 +29,8 @@ export type MediaSceneSwitcherV2Layout = 'left' | 'right' | 'top';
|
|
|
29
29
|
* MediaSceneSwitcherV2 业务组件数据接口
|
|
30
30
|
*/
|
|
31
31
|
export interface MediaSceneSwitcherV2Data {
|
|
32
|
+
/** 主题 */
|
|
33
|
+
theme?: Theme;
|
|
32
34
|
/** 主标题 */
|
|
33
35
|
title?: string;
|
|
34
36
|
/** 副标题 */
|
|
@@ -39,6 +41,10 @@ export interface MediaSceneSwitcherV2Data {
|
|
|
39
41
|
defaultActiveIndex?: number;
|
|
40
42
|
/** 布局模式,默认 text-left */
|
|
41
43
|
layout?: MediaSceneSwitcherV2Layout;
|
|
44
|
+
/** 是否开启自动轮播,默认 true */
|
|
45
|
+
autoplay?: boolean;
|
|
46
|
+
/** 自动轮播间隔时间(毫秒),默认 3000 */
|
|
47
|
+
autoplayDelay?: number;
|
|
42
48
|
}
|
|
43
49
|
export interface MediaSceneSwitcherV2Props extends React.HTMLAttributes<HTMLDivElement> {
|
|
44
50
|
/** 业务数据 */
|
|
@@ -48,12 +54,5 @@ export interface MediaSceneSwitcherV2Props extends React.HTMLAttributes<HTMLDivE
|
|
|
48
54
|
/** 场景切换回调 */
|
|
49
55
|
onSceneChange?: (index: number, scene: MediaSceneSwitcherV2Item) => void;
|
|
50
56
|
}
|
|
51
|
-
/**
|
|
52
|
-
* MediaSceneSwitcherV2 - 多场景切换组件
|
|
53
|
-
*
|
|
54
|
-
* @description 用于展示多个场景的切换组件,支持响应式布局:
|
|
55
|
-
* - mobile/tablet: 横向滑动卡片布局
|
|
56
|
-
* - laptop+: 左文右图 / 左图右文布局
|
|
57
|
-
*/
|
|
58
57
|
declare const MediaSceneSwitcherV2: React.ForwardRefExoticComponent<MediaSceneSwitcherV2Props & React.RefAttributes<HTMLDivElement>>;
|
|
59
58
|
export default MediaSceneSwitcherV2;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import{jsx as
|
|
1
|
+
"use client";import{jsx as a,jsxs as c}from"react/jsx-runtime";import*as d from"react";import{Swiper as C,SwiperSlide as W}from"swiper/react";import{FreeMode as z,Mousewheel as P,Autoplay as j}from"swiper/modules";import{useMediaQuery as S}from"react-responsive";import{cn as r}from"../../helpers/index.js";import E from"../../components/picture.js";import{Heading as M,Text as I}from"../../components/index.js";const T=[{key:"lgDesktop",width:1920},{key:"desktop",width:1440},{key:"laptop",width:1024},{key:"tablet",width:768},{key:"mobile",width:390}],B=(o,t)=>o[t]?.mimeType==="video/mp4",H=o=>T.filter(({key:s})=>o[s]?.url&&o[s]?.mimeType!=="video/mp4").map(({key:s,width:p})=>`${o[s].url} ${p}`).join(", "),F=(o,t)=>{for(const{key:s}of T)if(o[s]?.alt)return o[s].alt;return t},N=({media:o,alt:t,className:s})=>{const p=S({minWidth:1920}),y=S({minWidth:1440,maxWidth:1919}),x=S({minWidth:1025,maxWidth:1439}),m=S({minWidth:768,maxWidth:1024}),u=d.useMemo(()=>{if(p&&o.lgDesktop?.url)return"lgDesktop";if(y&&o.desktop?.url)return"desktop";if(x&&o.laptop?.url)return"laptop";if(m&&o.tablet?.url)return"tablet";if(o.mobile?.url)return"mobile";for(const{key:b}of T)if(o[b]?.url)return b;return"desktop"},[p,y,x,m,o]),l=o[u];if(!l?.url)return null;if(B(o,u))return a("video",{src:l.url,className:s,autoPlay:!0,loop:!0,muted:!0,playsInline:!0});const k=H(o);return a(E,{source:k||l.url,alt:F(o,t),className:s,imgClassName:"size-full object-cover"})},O=3e3,L=d.forwardRef(({className:o,classNames:t={},data:s,onSceneChange:p,...y},x)=>{const{title:m,subtitle:u,items:l,defaultActiveIndex:k=0,layout:b="left",autoplay:f=!0,autoplayDelay:v=O}=s,[n,g]=d.useState(k),V=d.useRef(null),h=d.useRef(0);d.useEffect(()=>{if(!(!f||l.length<=1))return h.current=window.setInterval(()=>{g(e=>(e+1)%l.length)},v),()=>{h.current&&window.clearInterval(h.current)}},[f,v,l.length]);const R=d.useCallback(e=>{g(e),p?.(e,l[e]),V.current?.slideTo(e),f&&l.length>1&&(h.current&&window.clearInterval(h.current),h.current=window.setInterval(()=>{g(i=>(i+1)%l.length)},v))},[l,p,f,v]),A=d.useCallback(e=>{const i=e.realIndex;g(i),p?.(i,l[i])},[l,p]),w=l[n],D=b==="top";return c("div",{ref:x,className:r("scene-switcher-root","text-info-primary w-full",o,t.root,{"aiui-dark":s.theme==="dark"}),...y,children:[(m||u)&&c("div",{className:r("scene-switcher-header mb-6",t.header),children:[m&&a(M,{as:"h2",size:4,html:m,className:r("scene-switcher-title",t.title)}),u&&a(I,{as:"p",size:3,className:r("",t?.subtitle),html:u})]}),a("div",{className:r("scene-switcher-swiper","laptop:hidden !overflow-visible",t.swiper),children:a(C,{modules:[z,P,j],onSwiper:e=>{V.current=e},className:"!overflow-visible",onSlideChange:A,slidesPerView:"auto",spaceBetween:12,freeMode:!0,mousewheel:{forceToAxis:!0},initialSlide:k,loop:f&&l.length>1,autoplay:f&&l.length>1?{delay:v,disableOnInteraction:!1}:!1,breakpoints:{768:{spaceBetween:16}},children:l.map((e,i)=>a(W,{className:"h-[462px] !w-[296px]",children:c("div",{className:r("scene-switcher-slide","flex cursor-pointer flex-col",t.slide),onClick:()=>R(i),children:[a("div",{className:r("scene-switcher-slide-media","relative aspect-[296/320] w-full overflow-hidden",t.slideMedia),children:a(N,{media:e.media,alt:e.title,className:"rounded-t-box size-full overflow-hidden object-cover"})}),c("div",{className:r("scene-switcher-slide-content"," border-t pt-4",n===i?"border-info-primary border-t-4":"border-lines-primary",t.slideContent),children:[a(M,{className:r("scene-switcher-tab-title ",n===i?"text-info-primary":"text-info-tertiary",e.title),size:3,as:"h3",html:e.title}),e.description&&a(I,{className:r("desktop:text-[16px] lg-desktop:text-[18px] line-clamp-2 text-[14px]",n===i?"text-info-primary":"text-info-tertiary"),html:e.description})]})]})},i))})}),D&&c("div",{className:r("scene-switcher-container","laptop:flex laptop:flex-col hidden","laptop:h-[470px] desktop:h-[628px] lg-desktop:h-[746px] desktop:gap-[32px] gap-[16px]",t.container),children:[a("div",{className:r("scene-switcher-media-wrapper","flex-1 overflow-hidden",t.mediaWrapper),children:w&&a(N,{media:w.media,alt:w.title,className:r("scene-switcher-media","rounded-box size-full object-cover",t.media)})}),a("div",{className:r("scene-switcher-tab-list","border-lines-primary laptop:gap-4 desktop:gap-4 lg-desktop:gap-4 flex border-t",t.tabList),children:l.map((e,i)=>c("div",{className:r("scene-switcher-tab-item","desktop:pt-6 -mt-px flex-1 cursor-pointer border-t-2 pt-4 transition-colors",n===i?"border-info-primary border-t-4":"hover:border-lines-primary border-transparent",t.tabItem),onClick:()=>R(i),role:"button","aria-selected":n===i,children:[a(M,{className:r("scene-switcher-tab-title line-clamp-2",n===i?"text-info-primary":"text-info-tertiary",e.title),size:3,as:"h3",html:e.title}),e.description&&a(I,{className:r("desktop:text-[16px] lg-desktop:text-[18px] line-clamp-2 text-[14px]",n===i?"text-info-primary":"text-info-tertiary"),html:e.description})]},i))})]}),!D&&c("div",{className:r("scene-switcher-container","laptop:flex laptop:gap-6 desktop:gap-8 lg-desktop:gap-10 hidden","laptop:h-[336px] desktop:h-[448px] lg-desktop:h-[560px]",b==="right"&&"flex-row-reverse",t.container),children:[a("div",{className:r("scene-switcher-tab-list","border-lines-primary laptop:w-[320px] desktop:w-[400px] lg-desktop:w-[544px] flex flex-col justify-center border-t",t.tabList),children:l.map((e,i)=>c("div",{className:r("scene-switcher-tab-item","relative cursor-pointer py-4","before:bg-lines before:absolute before:inset-y-4 before:w-1","pl-6 before:left-0",n===i?"before:bg-info-primary":"hover:before:bg-lines-primary before:bg-lines",t.tabItem),onClick:()=>R(i),role:"button","aria-selected":n===i,children:[a(M,{className:r("scene-switcher-tab-title",n===i?"text-info-primary":"text-info-tertiary",e.title),size:3,as:"h3",html:e.title}),e.description&&a(I,{className:r("desktop:text-[16px] lg-desktop:text-[18px] line-clamp-2 text-[14px]",n===i?"text-info-primary":"text-info-tertiary hidden"),html:e.description})]},i))}),a("div",{className:r("scene-switcher-media-wrapper","flex-1 overflow-hidden",t.mediaWrapper),children:w&&a(N,{media:w.media,alt:w.title,className:r("scene-switcher-media","rounded-box size-full h-full overflow-visible object-cover",t.media)})})]})]})});L.displayName="MediaSceneSwitcherV2";var q=L;export{q as default};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/biz-components/MediaSceneSwitcherV2/index.tsx"],
|
|
4
|
-
"sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { Swiper, SwiperSlide } from 'swiper/react'\nimport { FreeMode, Mousewheel } from 'swiper/modules'\nimport type { Swiper as SwiperType } from 'swiper'\nimport { cn } from '../../helpers/index.js'\nimport Picture from '../../components/picture.js'\nimport type { Media } from '../../types/props.js'\nimport { Heading, Text } from '../../components/index.js'\n\nexport type MediaSceneSwitcherV2SemanticName =\n | 'root'\n | 'header'\n | 'title'\n | 'subtitle'\n | 'container'\n | 'tabList'\n | 'tabItem'\n | 'tabTitle'\n | 'tabDescription'\n | 'mediaWrapper'\n | 'media'\n | 'swiper'\n | 'slide'\n | 'slideMedia'\n | 'slideContent'\n\n/**\n * \u573A\u666F\u9879\u6570\u636E\u63A5\u53E3\n */\nexport interface MediaSceneSwitcherV2Item {\n /** \u573A\u666F\u6807\u9898 */\n title: string\n /** \u573A\u666F\u63CF\u8FF0 */\n description?: string\n /** \u573A\u666F\u5A92\u4F53\uFF08\u56FE\u7247/\u89C6\u9891\uFF09 */\n media: {\n mobile?: Media\n tablet?: Media\n laptop?: Media\n desktop?: Media\n lgDesktop?: Media\n }\n}\n\n/**\n * \u5E03\u5C40\u6A21\u5F0F\n * - left: \u5DE6\u6587\u53F3\u56FE\uFF08laptop+ \u9ED8\u8BA4\uFF09\n * - right: \u5DE6\u56FE\u53F3\u6587\n * - top: \u4E0A\u56FE\u4E0B\u6587\uFF08swiper \u5361\u7247\u6A21\u5F0F\uFF09\n */\nexport type MediaSceneSwitcherV2Layout = 'left' | 'right' | 'top'\n\n/**\n * MediaSceneSwitcherV2 \u4E1A\u52A1\u7EC4\u4EF6\u6570\u636E\u63A5\u53E3\n */\nexport interface MediaSceneSwitcherV2Data {\n /** \u4E3B\u6807\u9898 */\n title?: string\n /** \u526F\u6807\u9898 */\n subtitle?: string\n /** \u573A\u666F\u5217\u8868 */\n items: MediaSceneSwitcherV2Item[]\n /** \u9ED8\u8BA4\u9009\u4E2D\u7684\u573A\u666F\u7D22\u5F15 */\n defaultActiveIndex?: number\n /** \u5E03\u5C40\u6A21\u5F0F\uFF0C\u9ED8\u8BA4 text-left */\n layout?: MediaSceneSwitcherV2Layout\n}\n\nexport interface MediaSceneSwitcherV2Props extends React.HTMLAttributes<HTMLDivElement> {\n /** \u4E1A\u52A1\u6570\u636E */\n data: MediaSceneSwitcherV2Data\n /** \u8BED\u4E49\u5316\u7C7B\u540D\u8986\u76D6 */\n classNames?: Partial<Record<MediaSceneSwitcherV2SemanticName, string>>\n /** \u573A\u666F\u5207\u6362\u56DE\u8C03 */\n onSceneChange?: (index: number, scene: MediaSceneSwitcherV2Item) => void\n}\n\n/**\n * \u54CD\u5E94\u5F0F\u5A92\u4F53\u7C7B\u578B\n */\ntype ResponsiveMedia = MediaSceneSwitcherV2Item['media']\n\n/**\n * \u5C06\u54CD\u5E94\u5F0F\u5A92\u4F53\u5BF9\u8C61\u8F6C\u4E3A Picture source \u683C\u5F0F\u5B57\u7B26\u4E32\n */\nconst getMediaSource = (media: ResponsiveMedia): string => {\n const breakpoints: { key: keyof ResponsiveMedia; width: number }[] = [\n { key: 'lgDesktop', width: 1920 },\n { key: 'desktop', width: 1440 },\n { key: 'laptop', width: 1024 },\n { key: 'tablet', width: 768 },\n { key: 'mobile', width: 390 },\n ]\n\n const sources = breakpoints\n .filter(({ key }) => media[key]?.url)\n .map(({ key, width }) => `${media[key]!.url} ${width}`)\n\n if (sources.length > 0) {\n return sources.join(', ')\n }\n\n // fallback: \u8FD4\u56DE\u4EFB\u610F\u4E00\u4E2A\u6709\u6548\u7684 url\n for (const { key } of breakpoints) {\n if (media[key]?.url) return media[key]!.url\n }\n\n return ''\n}\n\n/**\n * \u4ECE\u54CD\u5E94\u5F0F\u5A92\u4F53\u5BF9\u8C61\u83B7\u53D6 alt \u6587\u672C\n */\nconst getMediaAlt = (media: ResponsiveMedia, fallback: string): string => {\n const keys: (keyof ResponsiveMedia)[] = ['desktop', 'laptop', 'tablet', 'mobile', 'lgDesktop']\n for (const key of keys) {\n if (media[key]?.alt) return media[key]!.alt\n }\n return fallback\n}\n\n/**\n * \u5224\u65AD\u5A92\u4F53\u662F\u5426\u4E3A\u89C6\u9891\n */\nconst isVideo = (media: ResponsiveMedia): boolean => {\n const keys: (keyof ResponsiveMedia)[] = ['desktop', 'laptop', 'tablet', 'mobile', 'lgDesktop']\n for (const key of keys) {\n if (media[key]?.mimeType === 'video/mp4') return true\n }\n return false\n}\n\n/**\n * \u83B7\u53D6\u89C6\u9891 URL\n */\nconst getVideoUrl = (media: ResponsiveMedia): string => {\n const keys: (keyof ResponsiveMedia)[] = ['desktop', 'laptop', 'tablet', 'mobile', 'lgDesktop']\n for (const key of keys) {\n if (media[key]?.url) return media[key]!.url\n }\n return ''\n}\n\n/**\n * \u5A92\u4F53\u6E32\u67D3\u7EC4\u4EF6 - \u652F\u6301\u56FE\u7247\u548C\u89C6\u9891\n */\nconst MediaRenderer: React.FC<{\n media: ResponsiveMedia\n alt: string\n className?: string\n}> = ({ media, alt, className }) => {\n if (isVideo(media)) {\n return <video src={getVideoUrl(media)} className={className} autoPlay loop muted playsInline />\n }\n\n return (\n <Picture\n source={getMediaSource(media)}\n alt={getMediaAlt(media, alt)}\n className={className}\n imgClassName=\"size-full\"\n />\n )\n}\n\n/**\n * MediaSceneSwitcherV2 - \u591A\u573A\u666F\u5207\u6362\u7EC4\u4EF6\n *\n * @description \u7528\u4E8E\u5C55\u793A\u591A\u4E2A\u573A\u666F\u7684\u5207\u6362\u7EC4\u4EF6\uFF0C\u652F\u6301\u54CD\u5E94\u5F0F\u5E03\u5C40\uFF1A\n * - mobile/tablet: \u6A2A\u5411\u6ED1\u52A8\u5361\u7247\u5E03\u5C40\n * - laptop+: \u5DE6\u6587\u53F3\u56FE / \u5DE6\u56FE\u53F3\u6587\u5E03\u5C40\n */\nconst MediaSceneSwitcherV2 = React.forwardRef<HTMLDivElement, MediaSceneSwitcherV2Props>(\n ({ className, classNames = {}, data, onSceneChange, ...props }, ref) => {\n const { title, subtitle, items: scenes, defaultActiveIndex = 0, layout = 'left' } = data\n const [activeIndex, setActiveIndex] = React.useState(defaultActiveIndex)\n const swiperRef = React.useRef<SwiperType | null>(null)\n\n const handleSceneClick = React.useCallback(\n (index: number) => {\n setActiveIndex(index)\n onSceneChange?.(index, scenes[index])\n // \u540C\u6B65 swiper \u4F4D\u7F6E\n swiperRef.current?.slideTo(index)\n },\n [scenes, onSceneChange]\n )\n\n const handleSlideChange = React.useCallback(\n (swiper: SwiperType) => {\n const index = swiper.activeIndex\n setActiveIndex(index)\n onSceneChange?.(index, scenes[index])\n },\n [scenes, onSceneChange]\n )\n\n const activeScene = scenes[activeIndex]\n\n const isMediaTop = layout === 'top'\n\n return (\n <div ref={ref} className={cn('scene-switcher-root', 'w-full', className, classNames.root)} {...props}>\n {/* \u6807\u9898\u533A\u57DF */}\n {(title || subtitle) && (\n <div className={cn('scene-switcher-header mb-6', classNames.header)}>\n {title && (\n <Heading as=\"h2\" size={4} html={title} className={cn('scene-switcher-title', classNames.title)} />\n )}\n {subtitle && <Text as=\"p\" size={3} className={cn('', classNames?.subtitle)} html={subtitle} />}\n </div>\n )}\n {/* Mobile/Tablet: \u6A2A\u5411\u6ED1\u52A8\u5361\u7247\u5E03\u5C40 */}\n <div className={cn('scene-switcher-swiper', 'laptop:hidden !overflow-visible', classNames.swiper)}>\n <Swiper\n modules={[FreeMode, Mousewheel]}\n onSwiper={swiper => {\n swiperRef.current = swiper\n }}\n className=\"!overflow-visible\"\n onSlideChange={handleSlideChange}\n slidesPerView=\"auto\"\n spaceBetween={12}\n freeMode={true}\n mousewheel={{ forceToAxis: true }}\n initialSlide={defaultActiveIndex}\n breakpoints={{\n 768: { spaceBetween: 16 },\n }}\n >\n {scenes.map((scene, index) => (\n <SwiperSlide key={index} className=\"tablet:!w-[296px] h-[462px] !w-[280px] \">\n <div\n className={cn('scene-switcher-slide', 'flex cursor-pointer flex-col', classNames.slide)}\n onClick={() => handleSceneClick(index)}\n >\n {/* \u5A92\u4F53 */}\n <div\n className={cn(\n 'scene-switcher-slide-media',\n 'relative aspect-[296/320] w-full overflow-hidden',\n classNames.slideMedia\n )}\n >\n <MediaRenderer\n media={scene.media}\n alt={scene.title}\n className=\"rounded-t-box size-full overflow-hidden object-cover\"\n />\n </div>\n {/* \u6587\u5B57\u5185\u5BB9 */}\n <div\n className={cn(\n 'scene-switcher-slide-content',\n ' border-t pt-4',\n activeIndex === index ? 'border-info-primary border-t-4' : 'border-lines-primary',\n classNames.slideContent\n )}\n >\n <Heading\n className={cn(\n 'scene-switcher-tab-title ',\n activeIndex === index ? 'text-info-primary' : 'text-info-tertiary',\n scene.title\n )}\n size={3}\n as={'h3'}\n html={scene.title}\n />\n {scene.description && (\n <Text\n className={cn(\n 'desktop:text-[16px] lg-desktop:text-[18px] line-clamp-2 text-[14px]',\n activeIndex === index ? 'text-info-primary' : 'text-info-tertiary'\n )}\n html={scene.description}\n />\n )}\n </div>\n </div>\n </SwiperSlide>\n ))}\n </Swiper>\n </div>\n\n {/* Laptop+: media-top \u5E03\u5C40 (\u4E0A\u56FE\u4E0B\u6587) */}\n {isMediaTop && (\n <div\n className={cn(\n 'scene-switcher-container',\n 'laptop:flex laptop:flex-col hidden',\n 'laptop:h-[470px] desktop:h-[628px] lg-desktop:h-[746px] desktop:gap-[32px] gap-[16px]',\n classNames.container\n )}\n >\n {/* \u5A92\u4F53\u533A\u57DF - \u663E\u793A\u5F53\u524D\u9009\u4E2D */}\n <div className={cn('scene-switcher-media-wrapper', 'flex-1 overflow-hidden', classNames.mediaWrapper)}>\n {activeScene && (\n <MediaRenderer\n media={activeScene.media}\n alt={activeScene.title}\n className={cn('scene-switcher-media', 'rounded-box size-full object-cover', classNames.media)}\n />\n )}\n </div>\n\n {/* Tab \u5217\u8868 - \u6A2A\u5411\u6392\u5217 */}\n <div\n className={cn(\n 'scene-switcher-tab-list',\n 'border-lines-primary laptop:gap-4 desktop:gap-4 lg-desktop:gap-4 flex border-t',\n classNames.tabList\n )}\n >\n {scenes.map((scene, index) => (\n <div\n key={index}\n className={cn(\n 'scene-switcher-tab-item',\n 'desktop:pt-6 -mt-px flex-1 cursor-pointer border-t-2 pt-4 transition-colors',\n activeIndex === index\n ? 'border-info-primary border-t-4'\n : 'hover:border-lines-primary border-transparent',\n classNames.tabItem\n )}\n onClick={() => handleSceneClick(index)}\n role=\"button\"\n aria-selected={activeIndex === index}\n >\n <Heading\n className={cn(\n 'scene-switcher-tab-title line-clamp-2',\n activeIndex === index ? 'text-info-primary' : 'text-info-tertiary',\n scene.title\n )}\n size={3}\n as={'h3'}\n html={scene.title}\n />\n {scene.description && (\n <Text\n className={cn(\n 'desktop:text-[16px] lg-desktop:text-[18px] line-clamp-2 text-[14px]',\n activeIndex === index ? 'text-info-primary' : 'text-info-tertiary'\n )}\n html={scene.description}\n />\n )}\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Laptop+: \u5DE6\u6587\u53F3\u56FE / \u5DE6\u56FE\u53F3\u6587\u5E03\u5C40 */}\n {!isMediaTop && (\n <div\n className={cn(\n 'scene-switcher-container',\n 'laptop:flex laptop:gap-6 desktop:gap-8 lg-desktop:gap-10 hidden',\n 'laptop:h-[336px] desktop:h-[448px] lg-desktop:h-[560px]',\n layout === 'right' && 'flex-row-reverse',\n classNames.container\n )}\n >\n {/* Tab \u5217\u8868 */}\n <div\n className={cn(\n 'scene-switcher-tab-list',\n 'border-lines-primary laptop:w-[320px] desktop:w-[400px] lg-desktop:w-[544px] flex flex-col justify-center border-t',\n classNames.tabList\n )}\n >\n {scenes.map((scene, index) => (\n <div\n key={index}\n className={cn(\n 'scene-switcher-tab-item',\n 'relative cursor-pointer py-4',\n 'before:absolute before:inset-y-4 before:w-1 before:transition-colors',\n layout === 'right' ? 'pr-6 before:right-0' : 'pl-6 before:left-0',\n activeIndex === index\n ? 'before:bg-info-primary'\n : 'hover:before:bg-lines-primary before:bg-transparent',\n classNames.tabItem\n )}\n onClick={() => handleSceneClick(index)}\n role=\"button\"\n aria-selected={activeIndex === index}\n >\n <Heading\n className={cn(\n 'scene-switcher-tab-title',\n activeIndex === index ? 'text-info-primary' : 'text-info-tertiary',\n scene.title\n )}\n size={3}\n as={'h3'}\n html={scene.title}\n />\n {scene.description && (\n <Text\n className={cn(\n 'desktop:text-[16px] lg-desktop:text-[18px] line-clamp-2 text-[14px]',\n activeIndex === index ? 'text-info-primary' : 'text-info-tertiary hidden'\n )}\n html={scene.description}\n />\n )}\n </div>\n ))}\n </div>\n\n {/* \u5A92\u4F53\u533A\u57DF */}\n <div className={cn('scene-switcher-media-wrapper', 'flex-1 overflow-hidden', classNames.mediaWrapper)}>\n {activeScene && (\n <MediaRenderer\n media={activeScene.media}\n alt={activeScene.title}\n className={cn(\n 'scene-switcher-media',\n 'rounded-box size-full h-full overflow-visible object-cover',\n classNames.media\n )}\n />\n )}\n </div>\n </div>\n )}\n </div>\n )\n }\n)\n\nMediaSceneSwitcherV2.displayName = 'MediaSceneSwitcherV2'\nexport default MediaSceneSwitcherV2\n"],
|
|
5
|
-
"mappings": "
|
|
6
|
-
"names": ["jsx", "jsxs", "React", "Swiper", "SwiperSlide", "FreeMode", "Mousewheel", "cn", "Picture", "Heading", "Text", "
|
|
4
|
+
"sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { Swiper, SwiperSlide } from 'swiper/react'\nimport { FreeMode, Mousewheel, Autoplay } from 'swiper/modules'\nimport type { Swiper as SwiperType } from 'swiper'\nimport { useMediaQuery } from 'react-responsive'\nimport { cn } from '../../helpers/index.js'\nimport Picture from '../../components/picture.js'\nimport type { Media, Theme } from '../../types/props.js'\nimport { Heading, Text } from '../../components/index.js'\n\nexport type MediaSceneSwitcherV2SemanticName =\n | 'root'\n | 'header'\n | 'title'\n | 'subtitle'\n | 'container'\n | 'tabList'\n | 'tabItem'\n | 'tabTitle'\n | 'tabDescription'\n | 'mediaWrapper'\n | 'media'\n | 'swiper'\n | 'slide'\n | 'slideMedia'\n | 'slideContent'\n\n/**\n * \u573A\u666F\u9879\u6570\u636E\u63A5\u53E3\n */\nexport interface MediaSceneSwitcherV2Item {\n /** \u573A\u666F\u6807\u9898 */\n title: string\n /** \u573A\u666F\u63CF\u8FF0 */\n description?: string\n /** \u573A\u666F\u5A92\u4F53\uFF08\u56FE\u7247/\u89C6\u9891\uFF09 */\n media: {\n mobile?: Media\n tablet?: Media\n laptop?: Media\n desktop?: Media\n lgDesktop?: Media\n }\n}\n\n/**\n * \u5E03\u5C40\u6A21\u5F0F\n * - left: \u5DE6\u6587\u53F3\u56FE\uFF08laptop+ \u9ED8\u8BA4\uFF09\n * - right: \u5DE6\u56FE\u53F3\u6587\n * - top: \u4E0A\u56FE\u4E0B\u6587\uFF08swiper \u5361\u7247\u6A21\u5F0F\uFF09\n */\nexport type MediaSceneSwitcherV2Layout = 'left' | 'right' | 'top'\n\n/**\n * MediaSceneSwitcherV2 \u4E1A\u52A1\u7EC4\u4EF6\u6570\u636E\u63A5\u53E3\n */\nexport interface MediaSceneSwitcherV2Data {\n /** \u4E3B\u9898 */\n theme?: Theme\n /** \u4E3B\u6807\u9898 */\n title?: string\n /** \u526F\u6807\u9898 */\n subtitle?: string\n /** \u573A\u666F\u5217\u8868 */\n items: MediaSceneSwitcherV2Item[]\n /** \u9ED8\u8BA4\u9009\u4E2D\u7684\u573A\u666F\u7D22\u5F15 */\n defaultActiveIndex?: number\n /** \u5E03\u5C40\u6A21\u5F0F\uFF0C\u9ED8\u8BA4 text-left */\n layout?: MediaSceneSwitcherV2Layout\n /** \u662F\u5426\u5F00\u542F\u81EA\u52A8\u8F6E\u64AD\uFF0C\u9ED8\u8BA4 true */\n autoplay?: boolean\n /** \u81EA\u52A8\u8F6E\u64AD\u95F4\u9694\u65F6\u95F4\uFF08\u6BEB\u79D2\uFF09\uFF0C\u9ED8\u8BA4 3000 */\n autoplayDelay?: number\n}\n\nexport interface MediaSceneSwitcherV2Props extends React.HTMLAttributes<HTMLDivElement> {\n /** \u4E1A\u52A1\u6570\u636E */\n data: MediaSceneSwitcherV2Data\n /** \u8BED\u4E49\u5316\u7C7B\u540D\u8986\u76D6 */\n classNames?: Partial<Record<MediaSceneSwitcherV2SemanticName, string>>\n /** \u573A\u666F\u5207\u6362\u56DE\u8C03 */\n onSceneChange?: (index: number, scene: MediaSceneSwitcherV2Item) => void\n}\n\n/**\n * \u54CD\u5E94\u5F0F\u5A92\u4F53\u7C7B\u578B\n */\ntype ResponsiveMedia = MediaSceneSwitcherV2Item['media']\n\n/** \u65AD\u70B9\u914D\u7F6E */\nconst BREAKPOINTS: { key: keyof ResponsiveMedia; width: number }[] = [\n { key: 'lgDesktop', width: 1920 },\n { key: 'desktop', width: 1440 },\n { key: 'laptop', width: 1024 },\n { key: 'tablet', width: 768 },\n { key: 'mobile', width: 390 },\n]\n\n/**\n * \u68C0\u67E5\u5F53\u524D\u65AD\u70B9\u7684\u5A92\u4F53\u662F\u5426\u4E3A\u89C6\u9891\n */\nconst isCurrentMediaVideo = (media: ResponsiveMedia, currentBreakpoint: keyof ResponsiveMedia): boolean => {\n return media[currentBreakpoint]?.mimeType === 'video/mp4'\n}\n\n/**\n * \u5C06\u54CD\u5E94\u5F0F\u5A92\u4F53\u5BF9\u8C61\u8F6C\u4E3A Picture source \u683C\u5F0F\u5B57\u7B26\u4E32\n * \u683C\u5F0F: \"url1 1920, url2 1440, url3 1024\"\n */\nconst getImageSource = (media: ResponsiveMedia): string => {\n const sources = BREAKPOINTS.filter(({ key }) => media[key]?.url && media[key]?.mimeType !== 'video/mp4').map(\n ({ key, width }) => `${media[key]!.url} ${width}`\n )\n\n return sources.join(', ')\n}\n\n/**\n * \u83B7\u53D6 alt \u6587\u672C\n */\nconst getMediaAlt = (media: ResponsiveMedia, fallback: string): string => {\n for (const { key } of BREAKPOINTS) {\n if (media[key]?.alt) return media[key]!.alt\n }\n return fallback\n}\n\n/**\n * \u5A92\u4F53\u6E32\u67D3\u7EC4\u4EF6 - \u652F\u6301\u56FE\u7247\u548C\u89C6\u9891\uFF0C\u6839\u636E\u65AD\u70B9\u6E32\u67D3\u5BF9\u5E94\u8D44\u6E90\n */\nconst MediaRenderer: React.FC<{\n media: ResponsiveMedia\n alt: string\n className?: string\n}> = ({ media, alt, className }) => {\n const isLgDesktop = useMediaQuery({ minWidth: 1920 })\n const isDesktop = useMediaQuery({ minWidth: 1440, maxWidth: 1919 })\n const isLaptop = useMediaQuery({ minWidth: 1025, maxWidth: 1439 })\n const isTablet = useMediaQuery({ minWidth: 768, maxWidth: 1024 })\n\n // \u83B7\u53D6\u5F53\u524D\u65AD\u70B9 key\n const currentBreakpoint = React.useMemo((): keyof ResponsiveMedia => {\n if (isLgDesktop && media.lgDesktop?.url) return 'lgDesktop'\n if (isDesktop && media.desktop?.url) return 'desktop'\n if (isLaptop && media.laptop?.url) return 'laptop'\n if (isTablet && media.tablet?.url) return 'tablet'\n if (media.mobile?.url) return 'mobile'\n\n // fallback: \u8FD4\u56DE\u7B2C\u4E00\u4E2A\u6709\u6548\u7684\u65AD\u70B9\n for (const { key } of BREAKPOINTS) {\n if (media[key]?.url) return key\n }\n return 'desktop'\n }, [isLgDesktop, isDesktop, isLaptop, isTablet, media])\n\n const currentMedia = media[currentBreakpoint]\n\n if (!currentMedia?.url) return null\n\n // \u5F53\u524D\u65AD\u70B9\u662F\u89C6\u9891\u5219\u6E32\u67D3\u89C6\u9891\n if (isCurrentMediaVideo(media, currentBreakpoint)) {\n return <video src={currentMedia.url} className={className} autoPlay loop muted playsInline />\n }\n\n // \u56FE\u7247\uFF1A\u4F7F\u7528 Picture \u7EC4\u4EF6\u7684\u54CD\u5E94\u5F0F\u683C\u5F0F\n const imageSource = getImageSource(media)\n\n return (\n <Picture\n source={imageSource || currentMedia.url}\n alt={getMediaAlt(media, alt)}\n className={className}\n imgClassName=\"size-full object-cover\"\n />\n )\n}\n\n/**\n * MediaSceneSwitcherV2 - \u591A\u573A\u666F\u5207\u6362\u7EC4\u4EF6\n *\n * @description \u7528\u4E8E\u5C55\u793A\u591A\u4E2A\u573A\u666F\u7684\u5207\u6362\u7EC4\u4EF6\uFF0C\u652F\u6301\u54CD\u5E94\u5F0F\u5E03\u5C40\uFF1A\n * - mobile/tablet: \u6A2A\u5411\u6ED1\u52A8\u5361\u7247\u5E03\u5C40\n * - laptop+: \u5DE6\u6587\u53F3\u56FE / \u5DE6\u56FE\u53F3\u6587\u5E03\u5C40\n */\nconst DEFAULT_AUTOPLAY_DELAY = 3000\n\nconst MediaSceneSwitcherV2 = React.forwardRef<HTMLDivElement, MediaSceneSwitcherV2Props>(\n ({ className, classNames = {}, data, onSceneChange, ...props }, ref) => {\n const {\n title,\n subtitle,\n items: scenes,\n defaultActiveIndex = 0,\n layout = 'left',\n autoplay = true,\n autoplayDelay = DEFAULT_AUTOPLAY_DELAY,\n } = data\n const [activeIndex, setActiveIndex] = React.useState(defaultActiveIndex)\n const swiperRef = React.useRef<SwiperType | null>(null)\n const intervalRef = React.useRef<number>(0)\n\n // \u684C\u9762\u7AEF\u81EA\u52A8\u8F6E\u64AD\n React.useEffect(() => {\n if (!autoplay || scenes.length <= 1) return\n\n intervalRef.current = window.setInterval(() => {\n setActiveIndex(prev => (prev + 1) % scenes.length)\n }, autoplayDelay)\n\n return () => {\n if (intervalRef.current) {\n window.clearInterval(intervalRef.current)\n }\n }\n }, [autoplay, autoplayDelay, scenes.length])\n\n const handleSceneClick = React.useCallback(\n (index: number) => {\n setActiveIndex(index)\n onSceneChange?.(index, scenes[index])\n // \u540C\u6B65 swiper \u4F4D\u7F6E\n swiperRef.current?.slideTo(index)\n\n // \u91CD\u7F6E\u81EA\u52A8\u8F6E\u64AD\u8BA1\u65F6\u5668\n if (autoplay && scenes.length > 1) {\n if (intervalRef.current) {\n window.clearInterval(intervalRef.current)\n }\n intervalRef.current = window.setInterval(() => {\n setActiveIndex(prev => (prev + 1) % scenes.length)\n }, autoplayDelay)\n }\n },\n [scenes, onSceneChange, autoplay, autoplayDelay]\n )\n\n const handleSlideChange = React.useCallback(\n (swiper: SwiperType) => {\n // \u4F7F\u7528 realIndex \u4EE5\u6B63\u786E\u5904\u7406 loop \u6A21\u5F0F\n const index = swiper.realIndex\n setActiveIndex(index)\n onSceneChange?.(index, scenes[index])\n },\n [scenes, onSceneChange]\n )\n\n const activeScene = scenes[activeIndex]\n\n const isMediaTop = layout === 'top'\n\n return (\n <div\n ref={ref}\n className={cn('scene-switcher-root', 'text-info-primary w-full', className, classNames.root, {\n 'aiui-dark': data.theme === 'dark',\n })}\n {...props}\n >\n {/* \u6807\u9898\u533A\u57DF */}\n {(title || subtitle) && (\n <div className={cn('scene-switcher-header mb-6', classNames.header)}>\n {title && (\n <Heading as=\"h2\" size={4} html={title} className={cn('scene-switcher-title', classNames.title)} />\n )}\n {subtitle && <Text as=\"p\" size={3} className={cn('', classNames?.subtitle)} html={subtitle} />}\n </div>\n )}\n {/* Mobile/Tablet: \u6A2A\u5411\u6ED1\u52A8\u5361\u7247\u5E03\u5C40 */}\n <div className={cn('scene-switcher-swiper', 'laptop:hidden !overflow-visible', classNames.swiper)}>\n <Swiper\n modules={[FreeMode, Mousewheel, Autoplay]}\n onSwiper={swiper => {\n swiperRef.current = swiper\n }}\n className=\"!overflow-visible\"\n onSlideChange={handleSlideChange}\n slidesPerView=\"auto\"\n spaceBetween={12}\n freeMode={true}\n mousewheel={{ forceToAxis: true }}\n initialSlide={defaultActiveIndex}\n loop={autoplay && scenes.length > 1}\n autoplay={autoplay && scenes.length > 1 ? { delay: autoplayDelay, disableOnInteraction: false } : false}\n breakpoints={{\n 768: { spaceBetween: 16 },\n }}\n >\n {scenes.map((scene, index) => (\n <SwiperSlide key={index} className=\"h-[462px] !w-[296px]\">\n <div\n className={cn('scene-switcher-slide', 'flex cursor-pointer flex-col', classNames.slide)}\n onClick={() => handleSceneClick(index)}\n >\n {/* \u5A92\u4F53 */}\n <div\n className={cn(\n 'scene-switcher-slide-media',\n 'relative aspect-[296/320] w-full overflow-hidden',\n classNames.slideMedia\n )}\n >\n <MediaRenderer\n media={scene.media}\n alt={scene.title}\n className=\"rounded-t-box size-full overflow-hidden object-cover\"\n />\n </div>\n {/* \u6587\u5B57\u5185\u5BB9 */}\n <div\n className={cn(\n 'scene-switcher-slide-content',\n ' border-t pt-4',\n activeIndex === index ? 'border-info-primary border-t-4' : 'border-lines-primary',\n classNames.slideContent\n )}\n >\n <Heading\n className={cn(\n 'scene-switcher-tab-title ',\n activeIndex === index ? 'text-info-primary' : 'text-info-tertiary',\n scene.title\n )}\n size={3}\n as={'h3'}\n html={scene.title}\n />\n {scene.description && (\n <Text\n className={cn(\n 'desktop:text-[16px] lg-desktop:text-[18px] line-clamp-2 text-[14px]',\n activeIndex === index ? 'text-info-primary' : 'text-info-tertiary'\n )}\n html={scene.description}\n />\n )}\n </div>\n </div>\n </SwiperSlide>\n ))}\n </Swiper>\n </div>\n\n {/* Laptop+: media-top \u5E03\u5C40 (\u4E0A\u56FE\u4E0B\u6587) */}\n {isMediaTop && (\n <div\n className={cn(\n 'scene-switcher-container',\n 'laptop:flex laptop:flex-col hidden',\n 'laptop:h-[470px] desktop:h-[628px] lg-desktop:h-[746px] desktop:gap-[32px] gap-[16px]',\n classNames.container\n )}\n >\n {/* \u5A92\u4F53\u533A\u57DF - \u663E\u793A\u5F53\u524D\u9009\u4E2D */}\n <div className={cn('scene-switcher-media-wrapper', 'flex-1 overflow-hidden', classNames.mediaWrapper)}>\n {activeScene && (\n <MediaRenderer\n media={activeScene.media}\n alt={activeScene.title}\n className={cn('scene-switcher-media', 'rounded-box size-full object-cover', classNames.media)}\n />\n )}\n </div>\n\n {/* Tab \u5217\u8868 - \u6A2A\u5411\u6392\u5217 */}\n <div\n className={cn(\n 'scene-switcher-tab-list',\n 'border-lines-primary laptop:gap-4 desktop:gap-4 lg-desktop:gap-4 flex border-t',\n classNames.tabList\n )}\n >\n {scenes.map((scene, index) => (\n <div\n key={index}\n className={cn(\n 'scene-switcher-tab-item',\n 'desktop:pt-6 -mt-px flex-1 cursor-pointer border-t-2 pt-4 transition-colors',\n activeIndex === index\n ? 'border-info-primary border-t-4'\n : 'hover:border-lines-primary border-transparent',\n classNames.tabItem\n )}\n onClick={() => handleSceneClick(index)}\n role=\"button\"\n aria-selected={activeIndex === index}\n >\n <Heading\n className={cn(\n 'scene-switcher-tab-title line-clamp-2',\n activeIndex === index ? 'text-info-primary' : 'text-info-tertiary',\n scene.title\n )}\n size={3}\n as={'h3'}\n html={scene.title}\n />\n {scene.description && (\n <Text\n className={cn(\n 'desktop:text-[16px] lg-desktop:text-[18px] line-clamp-2 text-[14px]',\n activeIndex === index ? 'text-info-primary' : 'text-info-tertiary'\n )}\n html={scene.description}\n />\n )}\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Laptop+: \u5DE6\u6587\u53F3\u56FE / \u5DE6\u56FE\u53F3\u6587\u5E03\u5C40 */}\n {!isMediaTop && (\n <div\n className={cn(\n 'scene-switcher-container',\n 'laptop:flex laptop:gap-6 desktop:gap-8 lg-desktop:gap-10 hidden',\n 'laptop:h-[336px] desktop:h-[448px] lg-desktop:h-[560px]',\n layout === 'right' && 'flex-row-reverse',\n classNames.container\n )}\n >\n {/* Tab \u5217\u8868 */}\n <div\n className={cn(\n 'scene-switcher-tab-list',\n 'border-lines-primary laptop:w-[320px] desktop:w-[400px] lg-desktop:w-[544px] flex flex-col justify-center border-t',\n classNames.tabList\n )}\n >\n {scenes.map((scene, index) => (\n <div\n key={index}\n className={cn(\n 'scene-switcher-tab-item',\n 'relative cursor-pointer py-4',\n 'before:bg-lines before:absolute before:inset-y-4 before:w-1',\n 'pl-6 before:left-0',\n activeIndex === index ? 'before:bg-info-primary' : 'hover:before:bg-lines-primary before:bg-lines',\n classNames.tabItem\n )}\n onClick={() => handleSceneClick(index)}\n role=\"button\"\n aria-selected={activeIndex === index}\n >\n <Heading\n className={cn(\n 'scene-switcher-tab-title',\n activeIndex === index ? 'text-info-primary' : 'text-info-tertiary',\n scene.title\n )}\n size={3}\n as={'h3'}\n html={scene.title}\n />\n {scene.description && (\n <Text\n className={cn(\n 'desktop:text-[16px] lg-desktop:text-[18px] line-clamp-2 text-[14px]',\n activeIndex === index ? 'text-info-primary' : 'text-info-tertiary hidden'\n )}\n html={scene.description}\n />\n )}\n </div>\n ))}\n </div>\n\n {/* \u5A92\u4F53\u533A\u57DF */}\n <div className={cn('scene-switcher-media-wrapper', 'flex-1 overflow-hidden', classNames.mediaWrapper)}>\n {activeScene && (\n <MediaRenderer\n media={activeScene.media}\n alt={activeScene.title}\n className={cn(\n 'scene-switcher-media',\n 'rounded-box size-full h-full overflow-visible object-cover',\n classNames.media\n )}\n />\n )}\n </div>\n </div>\n )}\n </div>\n )\n }\n)\n\nMediaSceneSwitcherV2.displayName = 'MediaSceneSwitcherV2'\nexport default MediaSceneSwitcherV2\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["jsx", "jsxs", "React", "Swiper", "SwiperSlide", "FreeMode", "Mousewheel", "Autoplay", "useMediaQuery", "cn", "Picture", "Heading", "Text", "BREAKPOINTS", "isCurrentMediaVideo", "media", "currentBreakpoint", "getImageSource", "key", "width", "getMediaAlt", "fallback", "MediaRenderer", "alt", "className", "isLgDesktop", "isDesktop", "isLaptop", "isTablet", "currentMedia", "imageSource", "DEFAULT_AUTOPLAY_DELAY", "MediaSceneSwitcherV2", "classNames", "data", "onSceneChange", "props", "ref", "title", "subtitle", "scenes", "defaultActiveIndex", "layout", "autoplay", "autoplayDelay", "activeIndex", "setActiveIndex", "swiperRef", "intervalRef", "prev", "handleSceneClick", "index", "handleSlideChange", "swiper", "activeScene", "isMediaTop", "scene", "MediaSceneSwitcherV2_default"]
|
|
7
7
|
}
|