@anker-in/headless-ui 1.1.88 → 1.1.90
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/ImageTextOverlay/index.js +2 -2
- package/dist/cjs/biz-components/ImageTextOverlay/index.js.map +3 -3
- package/dist/cjs/biz-components/ProductNav/ProductNav.js +1 -1
- package/dist/cjs/biz-components/ProductNav/ProductNav.js.map +3 -3
- package/dist/cjs/biz-components/Tabs/Tabs.js +1 -1
- package/dist/cjs/biz-components/Tabs/Tabs.js.map +3 -3
- package/dist/cjs/biz-components/Tabs/types.d.ts +3 -0
- package/dist/cjs/biz-components/Tabs/types.js +1 -1
- package/dist/cjs/biz-components/Tabs/types.js.map +1 -1
- package/dist/cjs/shared/trackUrlRef.js +1 -1
- package/dist/cjs/shared/trackUrlRef.js.map +2 -2
- package/dist/esm/biz-components/ImageTextOverlay/index.js +2 -2
- package/dist/esm/biz-components/ImageTextOverlay/index.js.map +3 -3
- package/dist/esm/biz-components/ProductNav/ProductNav.js +1 -1
- package/dist/esm/biz-components/ProductNav/ProductNav.js.map +3 -3
- package/dist/esm/biz-components/Tabs/Tabs.js +1 -1
- package/dist/esm/biz-components/Tabs/Tabs.js.map +3 -3
- package/dist/esm/biz-components/Tabs/types.d.ts +3 -0
- package/dist/esm/shared/trackUrlRef.js +1 -1
- package/dist/esm/shared/trackUrlRef.js.map +2 -2
- package/package.json +1 -1
- package/style.css +18 -9
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";"use client";var j=Object.create;var
|
|
1
|
+
"use strict";"use client";var j=Object.create;var v=Object.defineProperty;var V=Object.getOwnPropertyDescriptor;var F=Object.getOwnPropertyNames;var G=Object.getPrototypeOf,Q=Object.prototype.hasOwnProperty;var q=(e,t)=>{for(var l in t)v(e,l,{get:t[l],enumerable:!0})},S=(e,t,l,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of F(t))!Q.call(e,o)&&o!==l&&v(e,o,{get:()=>t[o],enumerable:!(s=V(t,o))||s.enumerable});return e};var N=(e,t,l)=>(l=e!=null?j(G(e)):{},S(t||!e||!e.__esModule?v(l,"default",{value:e,enumerable:!0}):l,e)),K=e=>S(v({},"__esModule",{value:!0}),e);var ae={};q(ae,{default:()=>te});module.exports=K(ae);var a=require("react/jsx-runtime"),T=N(require("react")),n=require("react"),r=require("../../helpers/utils.js"),P=require("../../components/heading.js"),D=require("../../components/text.js"),_=N(require("../../components/picture.js")),w=require("../../hooks/useExposure.js"),A=require("../../shared/Styles.js"),z=require("../../shared/trackUrlRef.js"),L=require("../../helpers/utils.js"),B=require("../AiuiProvider/index.js"),E=require("react-responsive"),b=require("swiper/react"),H=require("swiper/modules"),re=require("swiper/css"),oe=require("swiper/css/pagination");const U="content",x="image_text_overlay",I="image",$="image-text-overlay-mobile-pagination",y={default:767,tablet:1024,laptop:1439,desktop:1919,lgDesktop:9999},W=e=>{if(!e)return"";const t=[];return e.lgDesktop?.url&&t.push(`${e.lgDesktop.url}`),e.desktop?.url&&t.push(`${e.desktop.url} ${y.desktop}`),e.laptop?.url&&t.push(`${e.laptop.url} ${y.laptop}`),e.tablet?.url&&t.push(`${e.tablet.url} ${y.tablet}`),e.default?.url&&t.push(`${e.default.url} ${y.default}`),t.join(", ")},J=e=>e&&(e.default?.alt||e.tablet?.alt||e.laptop?.alt||e.desktop?.alt||e.lgDesktop?.alt)||"",X=(e,t)=>{const l=[];for(let s=0;s<e.length;s+=t)l.push(e.slice(s,s+t));return l},Y=e=>{switch(e){case 2:return"grid-cols-1 tablet:grid-cols-2";case 3:return"grid-cols-1 tablet:grid-cols-2 laptop:grid-cols-3";case 4:return"grid-cols-1 tablet:grid-cols-2";case 5:return"grid-cols-1 tablet:grid-cols-2 laptop:grid-cols-6";case 6:return"grid-cols-1 tablet:grid-cols-2 desktop:grid-cols-3";default:return e<=1?"grid-cols-1":"grid-cols-1 laptop:grid-cols-3"}},Z=(e,t)=>t===5?e<2?"laptop:col-span-3":"laptop:col-span-2":"",ee=(e,t)=>{switch(e){case 2:case 4:return"aspect-[358/240] tablet:aspect-[346/240] laptop:aspect-[440/192] desktop:aspect-[648/256] lg-desktop:aspect-[824/320]";case 3:return"aspect-[358/240] tablet:aspect-[346/240] laptop:aspect-[288/192] desktop:aspect-[427/256] lg-desktop:aspect-[544/320]";case 5:return t<2?"aspect-[358/240] tablet:aspect-[346/240] laptop:aspect-[440/192] desktop:aspect-[648/256] lg-desktop:aspect-[824/320]":"aspect-[358/240] tablet:aspect-[346/240] laptop:aspect-[288/192] desktop:aspect-[427/256] lg-desktop:aspect-[544/320]";case 6:return"aspect-[358/240] tablet:aspect-[346/240] laptop:aspect-[440/192] desktop:aspect-[427/256] lg-desktop:aspect-[544/320]";default:return e<=1?"aspect-[358/240]":"aspect-[358/240] tablet:aspect-[346/240] laptop:aspect-[440/192] desktop:aspect-[648/256] lg-desktop:aspect-[824/320]"}},R=({item:e,index:t,count:l,classNames:s})=>{const o=W(e.backgroundImage),d=J(e.backgroundImage),p=Z(t,l),m=T.useRef(null),{locale:k="us",pageHandle:g}=(0,B.useAiuiContext)();(0,w.useExposure)(m,{componentType:I,componentName:x,position:t+1,componentTitle:e.title,componentDescription:e.subtitle});const i=e.link?(0,L.getLocalizedPath)(e.link,k):void 0,f=i?(0,z.trackUrlRef)(i,`${g??""}_${I}_${x}`):void 0,h=`${e.title}#${e.subtitle||""}#${e.title}`,u=ee(l,t);return(0,a.jsxs)("div",{ref:m,className:(0,r.cn)("image-text-overlay-card rounded-card",{"aiui-dark":e.theme==="dark"},"desktop:p-6 lg-desktop:p-8 group relative flex flex-col items-start justify-end overflow-hidden p-4",u,p,s?.card),children:[f&&(0,a.jsx)("a",{href:f,className:"absolute inset-0 z-20","aria-label":e.title,"data-headless-type-name":`${I}#${x}`,"data-headless-title-desc-button":h}),e.backgroundImage?.isShowVideo?(0,a.jsxs)(a.Fragment,{children:[e.backgroundImage?.mobileVideo&&(0,a.jsx)("video",{className:(0,r.cn)("image-text-overlay-card-image","laptop:hidden absolute inset-0 size-full object-cover",s?.cardImage),src:e.backgroundImage.mobileVideo.url,autoPlay:!0,muted:!0,loop:!0,playsInline:!0}),e.backgroundImage?.desktopVideo&&(0,a.jsx)("video",{className:(0,r.cn)("image-text-overlay-card-image","laptop:block absolute inset-0 hidden size-full object-cover",s?.cardImage),src:e.backgroundImage.desktopVideo.url,autoPlay:!0,muted:!0,loop:!0,playsInline:!0})]}):o&&(0,a.jsx)(_.default,{source:o,alt:d||e.title,className:(0,r.cn)("image-text-overlay-card-image","absolute inset-0 size-full",s?.cardImage),imgClassName:"size-full object-cover cursor-pointer transition-all duration-300 group-hover:scale-105"}),(0,a.jsxs)("div",{className:(0,r.cn)("image-text-overlay-card-content","relative z-10 flex w-full flex-col gap-1",s?.cardContent),children:[(0,a.jsx)(P.Heading,{as:"h4",size:2,weight:"bold",className:(0,r.cn)("image-text-overlay-card-title text-info-primary line-clamp-1","w-full leading-[1.2] tracking-[-0.04em]","desktop:text-xl lg-desktop:text-2xl text-lg",s?.cardTitle),children:e.title}),e.subtitle&&(0,a.jsx)(D.Text,{as:"p",size:"none",weight:"bold",className:(0,r.cn)("image-text-overlay-card-subtitle text-info-primary line-clamp-1","w-full truncate leading-[1.4] tracking-[-0.02em]","lg-desktop:text-base text-sm",l<=3&&"lg-desktop:text-lg",s?.cardSubtitle),children:e.subtitle})]})]})},C=(0,n.forwardRef)(({data:e,className:t,classNames:l={},...s},o)=>{const d=T.useRef(null),{items:p=[]}=e,[m,k]=(0,n.useState)(!1),g=(0,E.useMediaQuery)({query:"(max-width: 767px)"});if((0,n.useEffect)(()=>{k(g)},[g]),(0,w.useExposure)(d,{componentType:U,componentName:x}),T.useImperativeHandle(o,()=>d.current),!p.length)return null;const i=p.length,f=i>3&&m,h=X(p,3);return(0,a.jsx)("div",{ref:d,className:(0,r.cn)("image-text-overlay-root",t,l.root),"data-ui-component-id":"ImageTextOverlay",...s,children:f?(0,a.jsxs)("div",{className:"image-text-overlay-mobile-swiper relative pb-8",children:[(0,a.jsx)(b.Swiper,{className:"w-full [&_.swiper-slide]:!h-auto [&_.swiper-wrapper]:items-stretch",modules:[H.Pagination],slidesPerView:1,pagination:{clickable:!0,el:`.${$}`,bulletClass:"image-text-overlay-bullet",bulletActiveClass:"image-text-overlay-bullet-active"},spaceBetween:16,children:h.map((u,c)=>(0,a.jsx)(b.SwiperSlide,{className:"!h-auto",children:(0,a.jsx)("div",{className:"flex flex-col gap-4",children:u.map((M,O)=>(0,a.jsx)(R,{item:M,index:c*3+O,count:i,classNames:l},c*3+O))})},c))}),(0,a.jsx)("div",{className:"absolute inset-x-0 bottom-0 z-10 flex justify-center",children:(0,a.jsx)("div",{className:(0,r.cn)($,"flex items-center justify-center gap-2 text-center","[&_.swiper-pagination-bullet]:m-0","[&_.swiper-pagination-bullet]:shrink-0","[&_.swiper-pagination-bullet]:opacity-100")})}),(0,a.jsx)("style",{children:`
|
|
2
2
|
.image-text-overlay-bullet {
|
|
3
3
|
display: inline-block;
|
|
4
4
|
width: 8px;
|
|
@@ -14,5 +14,5 @@
|
|
|
14
14
|
border-radius: 9999px;
|
|
15
15
|
background: #080A0F;
|
|
16
16
|
}
|
|
17
|
-
`})]}):(0,a.jsx)("div",{className:(0,
|
|
17
|
+
`})]}):(0,a.jsx)("div",{className:(0,r.cn)("image-text-overlay-grid","grid gap-4",Y(i),l.grid),children:p.map((u,c)=>(0,a.jsx)(R,{item:u,index:c,count:i,classNames:l},c))})})});C.displayName="ImageTextOverlay";var te=(0,A.withLayout)(C);
|
|
18
18
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/biz-components/ImageTextOverlay/index.tsx"],
|
|
4
|
-
"sourcesContent": ["'use client'\nimport * as React from 'react'\nimport { forwardRef, useEffect, useRef, useState } from 'react'\nimport { cn } from '../../helpers/utils.js'\nimport { Heading } from '../../components/heading.js'\nimport { Text } from '../../components/text.js'\nimport Picture from '../../components/picture.js'\nimport { useExposure } from '../../hooks/useExposure.js'\nimport { withLayout } from '../../shared/Styles.js'\nimport { trackUrlRef } from '../../shared/trackUrlRef.js'\nimport type {\n ImageTextOverlayProps,\n ImageTextOverlayItem,\n ImageTextOverlaySemanticName,\n ImageTextOverlayData,\n ImageTextOverlayBackgroundImage,\n} from './types.js'\nimport { getLocalizedPath } from '../../helpers/utils.js'\nimport { useAiuiContext } from '../AiuiProvider/index.js'\nimport { useMediaQuery } from 'react-responsive'\nimport { Swiper, SwiperSlide } from 'swiper/react'\nimport { Pagination } from 'swiper/modules'\nimport 'swiper/css'\nimport 'swiper/css/pagination'\n\nexport type {\n ImageTextOverlayProps,\n ImageTextOverlayItem,\n ImageTextOverlaySemanticName,\n ImageTextOverlayData,\n ImageTextOverlayBackgroundImage,\n}\n\nconst componentType = 'content'\nconst componentName = 'image_text_overlay'\nconst imageComponentType = 'image'\nconst MOBILE_SWIPER_PAGINATION_CLASS = 'image-text-overlay-mobile-pagination'\n\n/**\n * \u65AD\u70B9\u914D\u7F6E\uFF08\u4E0E Tailwind \u65AD\u70B9\u5BF9\u5E94\uFF09\n * Picture \u7EC4\u4EF6\u4F7F\u7528 max-width \u5A92\u4F53\u67E5\u8BE2\uFF0C\u6240\u4EE5\u9700\u8981\u6309\u4ECE\u5927\u5230\u5C0F\u7684\u987A\u5E8F\u6392\u5217\n */\nconst BREAKPOINTS = {\n default: 767, // <768px (\u79FB\u52A8\u7AEF)\n tablet: 1024, // 768px - 1024px\n laptop: 1439, // 1025px - 1439px\n desktop: 1919, // 1440px - 1919px\n lgDesktop: 9999, // \u22651920px\n} as const\n\n/**\n * \u5C06\u54CD\u5E94\u5F0F\u80CC\u666F\u56FE\u7247\u5BF9\u8C61\u8F6C\u6362\u4E3A Picture \u7EC4\u4EF6\u7684 source \u5B57\u7B26\u4E32\n * \u683C\u5F0F: \"lgDesktopUrl, desktopUrl 1919, laptopUrl 1439, tabletUrl 1024, defaultUrl 767\"\n */\nconst buildResponsiveSource = (backgroundImage?: ImageTextOverlayBackgroundImage): string => {\n if (!backgroundImage) return ''\n\n const sources: string[] = []\n\n // lgDesktop \u4F5C\u4E3A\u9ED8\u8BA4\u56FE\u7247\uFF08\u65E0\u65AD\u70B9\u503C\uFF09\n if (backgroundImage.lgDesktop?.url) {\n sources.push(`${backgroundImage.lgDesktop.url}`)\n }\n if (backgroundImage.desktop?.url) {\n sources.push(`${backgroundImage.desktop.url} ${BREAKPOINTS.desktop}`)\n }\n if (backgroundImage.laptop?.url) {\n sources.push(`${backgroundImage.laptop.url} ${BREAKPOINTS.laptop}`)\n }\n if (backgroundImage.tablet?.url) {\n sources.push(`${backgroundImage.tablet.url} ${BREAKPOINTS.tablet}`)\n }\n if (backgroundImage.default?.url) {\n sources.push(`${backgroundImage.default.url} ${BREAKPOINTS.default}`)\n }\n\n return sources.join(', ')\n}\n\n/**\n * \u83B7\u53D6\u54CD\u5E94\u5F0F\u80CC\u666F\u56FE\u7247\u7684\u9ED8\u8BA4 alt \u6587\u672C\n */\nconst getBackgroundAlt = (backgroundImage?: ImageTextOverlayBackgroundImage): string => {\n if (!backgroundImage) return ''\n return (\n backgroundImage.default?.alt ||\n backgroundImage.tablet?.alt ||\n backgroundImage.laptop?.alt ||\n backgroundImage.desktop?.alt ||\n backgroundImage.lgDesktop?.alt ||\n ''\n )\n}\n\n// ============================================================================\n// \u54CD\u5E94\u5F0F\u5E03\u5C40\u7C7B\u540D \u2014\u2014 \u6839\u636E items \u6570\u91CF\u52A8\u6001\u51B3\u5B9A\u7F51\u683C\u5217\u6570\n//\n// Figma \u8BBE\u8BA1\u89C4\u8303\u603B\u7ED3:\n//\n// | Count | <768 (mobile) | 768-1024 (tablet) | 1025-1440 (laptop) | 1441-1920 (desktop) | \u22651921 (lg-desktop) |\n// |-------|---------------|--------------------|--------------------|---------------------|--------------------|\n// | 2 | 1col | 2col | 2col | 2col | 2col |\n// | 3 | 1col | 2col (2+1) | 3col | 3col | 3col |\n// | 4 | 2col (2 rows) | 2col (2 rows) | 2col (2 rows) | 2col (2 rows) | 2col (2 rows) |\n// | 5 | 2col (3 rows) | 2col (3 rows) | 2+3 (5col flex) | 2+3 (5col flex) | 2+3 (5col flex) |\n// | 6 | 2col (3 rows) | 2col (3 rows) | 3col (2 rows) | 3col (2 rows) | 3col (2 rows) |\n//\n// ============================================================================\n\n/**\n * \u5C06\u6570\u7EC4\u6309\u6307\u5B9A\u5927\u5C0F\u5206\u7EC4\n */\nconst chunkArray = <T,>(arr: T[], size: number): T[][] => {\n const chunks: T[][] = []\n for (let i = 0; i < arr.length; i += size) {\n chunks.push(arr.slice(i, i + size))\n }\n return chunks\n}\n\n/**\n * \u83B7\u53D6\u5BB9\u5668\u7F51\u683C\u7C7B\u540D\uFF08\u6839\u636E items \u6570\u91CF\uFF09\n */\n\n/**\n * \u83B7\u53D6\u5BB9\u5668\u7F51\u683C\u7C7B\u540D\uFF08\u6839\u636E items \u6570\u91CF\uFF09\n */\nconst getGridClasses = (count: number): string => {\n switch (count) {\n case 2:\n // mobile: 1col, tablet+: 2col\n return 'grid-cols-1 tablet:grid-cols-2'\n case 3:\n // mobile: 1col, tablet: 2col, laptop+: 3col\n return 'grid-cols-1 tablet:grid-cols-2 laptop:grid-cols-3'\n case 4:\n // mobile: 2col, tablet+: 2col (uniform)\n return 'grid-cols-1 tablet:grid-cols-2'\n case 5:\n // mobile/tablet: 2col grid, laptop+: use flex layout instead (2+3 pattern)\n // We handle laptop+ separately via flex, grid for mobile/tablet only\n return 'grid-cols-1 tablet:grid-cols-2 laptop:grid-cols-6'\n case 6:\n // mobile/tablet: 2col, laptop+: 3col\n return 'grid-cols-1 tablet:grid-cols-2 desktop:grid-cols-3'\n default:\n if (count <= 1) return 'grid-cols-1'\n // fallback: 2col mobile, 3col laptop+\n return 'grid-cols-1 laptop:grid-cols-3'\n }\n}\n\n/**\n * \u83B7\u53D6\u5355\u4E2A item \u7684 span \u7C7B\u540D (\u4EC5\u7528\u4E8E count=3 tablet \u548C count=5 laptop+)\n */\nconst getItemSpanClasses = (index: number, count: number): string => {\n if (count === 5) {\n // laptop+: \u7B2C1\u884C 2 items \u5404 span 3, \u7B2C2\u884C 3 items \u5404 span 2\n if (index < 2) return 'laptop:col-span-3'\n return 'laptop:col-span-2'\n }\n return ''\n}\n\n/**\n * \u83B7\u53D6\u5361\u7247\u9AD8\u5EA6\u7C7B\u540D\n * Figma: mobile 240px, tablet 240px, laptop 192px, desktop 256px, lg-desktop 320px\n */\nconst cardHeightClasses = 'h-[240px] tablet:h-[240px] laptop:h-[192px] desktop:h-[256px] lg-desktop:h-[320px]'\n\n/**\n * ImageTextOverlayCard - \u5355\u4E2A\u56FE\u6587\u53E0\u52A0\u5361\u7247\n */\nconst ImageTextOverlayCard: React.FC<{\n item: ImageTextOverlayItem\n index: number\n count: number\n classNames?: Partial<Record<ImageTextOverlaySemanticName, string>>\n}> = ({ item, index, count, classNames }) => {\n const responsiveSource = buildResponsiveSource(item.backgroundImage)\n const defaultAlt = getBackgroundAlt(item.backgroundImage)\n const spanClasses = getItemSpanClasses(index, count)\n const imageRef = React.useRef<HTMLDivElement>(null)\n const { locale = 'us', pageHandle } = useAiuiContext()\n\n useExposure(imageRef, {\n componentType: imageComponentType,\n componentName,\n position: index + 1,\n componentTitle: item.title,\n componentDescription: item.subtitle,\n })\n\n const localizedLink = item.link ? getLocalizedPath(item.link, locale) : undefined\n const trackedLink = localizedLink\n ? trackUrlRef(localizedLink, `${pageHandle ?? ''}_${imageComponentType}_${componentName}`)\n : undefined\n const titleDescButton = `${item.title}#${item.subtitle || ''}#${item.title}`\n\n return (\n <div\n ref={imageRef}\n className={cn(\n 'image-text-overlay-card rounded-card',\n { 'aiui-dark': item.theme === 'dark' },\n 'desktop:p-6 lg-desktop:p-8 group relative flex flex-col items-start justify-end overflow-hidden p-4',\n cardHeightClasses,\n spanClasses,\n classNames?.card\n )}\n >\n {/* \u6574\u5361\u94FE\u63A5 */}\n {trackedLink && (\n <a\n href={trackedLink}\n className=\"absolute inset-0 z-20\"\n aria-label={item.title}\n data-headless-type-name={`${imageComponentType}#${componentName}`}\n data-headless-title-desc-button={titleDescButton}\n />\n )}\n\n {/* \u80CC\u666F\u5A92\u4F53\uFF1A\u89C6\u9891\u6216\u56FE\u7247 */}\n {item.backgroundImage?.isShowVideo ? (\n <>\n {/* \u79FB\u52A8\u7AEF\u89C6\u9891 (<1025px) */}\n {item.backgroundImage?.mobileVideo && (\n <video\n className={cn(\n 'image-text-overlay-card-image',\n 'laptop:hidden absolute inset-0 size-full object-cover',\n classNames?.cardImage\n )}\n src={item.backgroundImage.mobileVideo.url}\n autoPlay\n muted\n loop\n playsInline\n />\n )}\n {/* \u684C\u9762\u7AEF\u89C6\u9891 (>=1025px) */}\n {item.backgroundImage?.desktopVideo && (\n <video\n className={cn(\n 'image-text-overlay-card-image',\n 'laptop:block absolute inset-0 hidden size-full object-cover',\n classNames?.cardImage\n )}\n src={item.backgroundImage.desktopVideo.url}\n autoPlay\n muted\n loop\n playsInline\n />\n )}\n </>\n ) : (\n responsiveSource && (\n <Picture\n source={responsiveSource}\n alt={defaultAlt || item.title}\n className={cn('image-text-overlay-card-image', 'absolute inset-0 size-full', classNames?.cardImage)}\n imgClassName=\"size-full object-cover cursor-pointer transition-all duration-300 group-hover:scale-105\"\n />\n )\n )}\n\n {/* \u6587\u5B57\u5185\u5BB9 */}\n <div\n className={cn(\n 'image-text-overlay-card-content',\n 'relative z-10 flex w-full flex-col gap-1',\n classNames?.cardContent\n )}\n >\n <Heading\n as=\"h4\"\n size={2}\n weight=\"bold\"\n className={cn(\n 'image-text-overlay-card-title text-info-primary line-clamp-1',\n 'w-full leading-[1.2] tracking-[-0.04em]',\n // \u5B57\u53F7: mobile/tablet/laptop 18px, desktop 20px, lg-desktop 24px\n 'desktop:text-xl lg-desktop:text-2xl text-lg',\n classNames?.cardTitle\n )}\n >\n {item.title}\n </Heading>\n\n {item.subtitle && (\n <Text\n as=\"p\"\n size=\"none\"\n weight=\"bold\"\n className={cn(\n 'image-text-overlay-card-subtitle text-info-primary line-clamp-1',\n 'w-full truncate leading-[1.4] tracking-[-0.02em]',\n // \u5B57\u53F7: mobile/tablet/laptop 14px, desktop 14px, lg-desktop 18px (count<=3) or 16px (count>3)\n 'lg-desktop:text-base text-sm',\n count <= 3 && 'lg-desktop:text-lg',\n classNames?.cardSubtitle\n )}\n >\n {item.subtitle}\n </Text>\n )}\n </div>\n </div>\n )\n}\n\n/**\n * ImageTextOverlay - \u56FE\u6587\u53E0\u52A0\u7EC4\u4EF6\n *\n * @description \u4EE5\u80CC\u666F\u56FE\u4E3A\u4E3B\u7684\u5361\u7247\u5E03\u5C40\u7EC4\u4EF6\uFF0C\u6807\u9898\u548C\u526F\u6807\u9898\u53E0\u52A0\u663E\u793A\u5728\u56FE\u7247\u5E95\u90E8\u3002\n * \u652F\u6301 2-6 \u4E2A items \u7684\u81EA\u52A8\u54CD\u5E94\u5F0F\u7F51\u683C\u5E03\u5C40\uFF0C\u6BCF\u4E2A item \u7684 backgroundImage\n * \u652F\u6301 5 \u4E2A\u65AD\u70B9 (default/tablet/laptop/desktop/lgDesktop)\u3002\n *\n * @example\n * ```tsx\n * <ImageTextOverlay\n * data={{\n * items: [\n * {\n * backgroundImage: {\n * default: { url: '/bg-mobile.jpg', alt: 'feature' },\n * tablet: { url: '/bg-tablet.jpg', alt: 'feature' },\n * laptop: { url: '/bg-laptop.jpg', alt: 'feature' },\n * desktop: { url: '/bg-desktop.jpg', alt: 'feature' },\n * lgDesktop: { url: '/bg-xl.jpg', alt: 'feature' },\n * },\n * title: '300+ AI brainwave audios',\n * subtitle: 'Charge in a Flash, Share in a Dash',\n * },\n * {\n * backgroundImage: { default: { url: '/bg2.jpg', alt: '' } },\n * title: '20+ white noise sounds',\n * subtitle: 'Power to Drive Your Prime',\n * },\n * ],\n * theme: 'dark',\n * }}\n * />\n * ```\n */\nconst ImageTextOverlay = forwardRef<HTMLDivElement, ImageTextOverlayProps>(\n ({ data, className, classNames = {}, ...props }, ref) => {\n const boxRef = React.useRef<HTMLDivElement>(null)\n const { items = [] } = data\n const [isMobile, setIsMobile] = useState(false)\n const mediaQuery = useMediaQuery({ query: '(max-width: 767px)' })\n\n useEffect(() => {\n setIsMobile(mediaQuery)\n }, [mediaQuery])\n\n useExposure(boxRef, {\n componentType,\n componentName,\n })\n\n React.useImperativeHandle(ref, () => boxRef.current as HTMLDivElement)\n\n if (!items.length) return null\n\n const count = items.length\n const useSwiper = count > 3 && isMobile\n const chunkedItems = chunkArray(items, 3)\n\n return (\n <div\n ref={boxRef}\n className={cn('image-text-overlay-root', className, classNames.root)}\n data-ui-component-id=\"ImageTextOverlay\"\n {...props}\n >\n {useSwiper ? (\n <div className=\"image-text-overlay-mobile-swiper relative pb-8\">\n <Swiper\n className=\"w-full [&_.swiper-slide]:!h-auto [&_.swiper-wrapper]:items-stretch\"\n modules={[Pagination]}\n slidesPerView={1}\n pagination={{\n clickable: true,\n el: `.${MOBILE_SWIPER_PAGINATION_CLASS}`,\n bulletClass: 'image-text-overlay-bullet',\n bulletActiveClass: 'image-text-overlay-bullet-active',\n }}\n spaceBetween={16}\n >\n {chunkedItems.map((group, gIndex) => (\n <SwiperSlide key={gIndex} className=\"!h-auto\">\n <div className=\"flex flex-col gap-4\">\n {group.map((item, index) => (\n <ImageTextOverlayCard\n key={gIndex * 3 + index}\n item={item}\n index={gIndex * 3 + index}\n count={count}\n classNames={classNames}\n />\n ))}\n </div>\n </SwiperSlide>\n ))}\n </Swiper>\n <div className=\"absolute inset-x-0 bottom-0 z-10 flex justify-center\">\n <div\n className={cn(\n MOBILE_SWIPER_PAGINATION_CLASS,\n 'flex items-center justify-center gap-2 text-center',\n '[&_.swiper-pagination-bullet]:m-0',\n '[&_.swiper-pagination-bullet]:shrink-0',\n '[&_.swiper-pagination-bullet]:opacity-100'\n )}\n />\n </div>\n <style>{`\n .image-text-overlay-bullet {\n display: inline-block;\n width: 8px;\n height: 8px;\n border-radius: 9999px;\n background: #767880;\n transition: all 0.3s ease;\n }\n\n .image-text-overlay-bullet-active {\n width: 32px;\n height: 8px;\n border-radius: 9999px;\n background: #080A0F;\n }\n `}</style>\n </div>\n ) : (\n <div className={cn('image-text-overlay-grid', 'grid gap-4', getGridClasses(count), classNames.grid)}>\n {items.map((item, index) => (\n <ImageTextOverlayCard key={index} item={item} index={index} count={count} classNames={classNames} />\n ))}\n </div>\n )}\n </div>\n )\n }\n)\n\nImageTextOverlay.displayName = 'ImageTextOverlay'\n\nexport default withLayout(ImageTextOverlay)\n"],
|
|
5
|
-
"mappings": "ukBAAA,IAAAA,GAAA,GAAAC,EAAAD,GAAA,aAAAE,KAAA,eAAAC,EAAAH,
|
|
6
|
-
"names": ["ImageTextOverlay_exports", "__export", "ImageTextOverlay_default", "__toCommonJS", "import_jsx_runtime", "React", "import_react", "import_utils", "import_heading", "import_text", "import_picture", "import_useExposure", "import_Styles", "import_trackUrlRef", "import_AiuiProvider", "import_react_responsive", "import_modules", "import_css", "import_pagination", "componentType", "componentName", "imageComponentType", "MOBILE_SWIPER_PAGINATION_CLASS", "BREAKPOINTS", "buildResponsiveSource", "backgroundImage", "sources", "getBackgroundAlt", "chunkArray", "arr", "size", "chunks", "i", "getGridClasses", "count", "getItemSpanClasses", "index", "
|
|
4
|
+
"sourcesContent": ["'use client'\nimport * as React from 'react'\nimport { forwardRef, useEffect, useRef, useState } from 'react'\nimport { cn } from '../../helpers/utils.js'\nimport { Heading } from '../../components/heading.js'\nimport { Text } from '../../components/text.js'\nimport Picture from '../../components/picture.js'\nimport { useExposure } from '../../hooks/useExposure.js'\nimport { withLayout } from '../../shared/Styles.js'\nimport { trackUrlRef } from '../../shared/trackUrlRef.js'\nimport type {\n ImageTextOverlayProps,\n ImageTextOverlayItem,\n ImageTextOverlaySemanticName,\n ImageTextOverlayData,\n ImageTextOverlayBackgroundImage,\n} from './types.js'\nimport { getLocalizedPath } from '../../helpers/utils.js'\nimport { useAiuiContext } from '../AiuiProvider/index.js'\nimport { useMediaQuery } from 'react-responsive'\nimport { Swiper, SwiperSlide } from 'swiper/react'\nimport { Pagination } from 'swiper/modules'\nimport 'swiper/css'\nimport 'swiper/css/pagination'\n\nexport type {\n ImageTextOverlayProps,\n ImageTextOverlayItem,\n ImageTextOverlaySemanticName,\n ImageTextOverlayData,\n ImageTextOverlayBackgroundImage,\n}\n\nconst componentType = 'content'\nconst componentName = 'image_text_overlay'\nconst imageComponentType = 'image'\nconst MOBILE_SWIPER_PAGINATION_CLASS = 'image-text-overlay-mobile-pagination'\n\n/**\n * \u65AD\u70B9\u914D\u7F6E\uFF08\u4E0E Tailwind \u65AD\u70B9\u5BF9\u5E94\uFF09\n * Picture \u7EC4\u4EF6\u4F7F\u7528 max-width \u5A92\u4F53\u67E5\u8BE2\uFF0C\u6240\u4EE5\u9700\u8981\u6309\u4ECE\u5927\u5230\u5C0F\u7684\u987A\u5E8F\u6392\u5217\n */\nconst BREAKPOINTS = {\n default: 767, // <768px (\u79FB\u52A8\u7AEF)\n tablet: 1024, // 768px - 1024px\n laptop: 1439, // 1025px - 1439px\n desktop: 1919, // 1440px - 1919px\n lgDesktop: 9999, // \u22651920px\n} as const\n\n/**\n * \u5C06\u54CD\u5E94\u5F0F\u80CC\u666F\u56FE\u7247\u5BF9\u8C61\u8F6C\u6362\u4E3A Picture \u7EC4\u4EF6\u7684 source \u5B57\u7B26\u4E32\n * \u683C\u5F0F: \"lgDesktopUrl, desktopUrl 1919, laptopUrl 1439, tabletUrl 1024, defaultUrl 767\"\n */\nconst buildResponsiveSource = (backgroundImage?: ImageTextOverlayBackgroundImage): string => {\n if (!backgroundImage) return ''\n\n const sources: string[] = []\n\n // lgDesktop \u4F5C\u4E3A\u9ED8\u8BA4\u56FE\u7247\uFF08\u65E0\u65AD\u70B9\u503C\uFF09\n if (backgroundImage.lgDesktop?.url) {\n sources.push(`${backgroundImage.lgDesktop.url}`)\n }\n if (backgroundImage.desktop?.url) {\n sources.push(`${backgroundImage.desktop.url} ${BREAKPOINTS.desktop}`)\n }\n if (backgroundImage.laptop?.url) {\n sources.push(`${backgroundImage.laptop.url} ${BREAKPOINTS.laptop}`)\n }\n if (backgroundImage.tablet?.url) {\n sources.push(`${backgroundImage.tablet.url} ${BREAKPOINTS.tablet}`)\n }\n if (backgroundImage.default?.url) {\n sources.push(`${backgroundImage.default.url} ${BREAKPOINTS.default}`)\n }\n\n return sources.join(', ')\n}\n\n/**\n * \u83B7\u53D6\u54CD\u5E94\u5F0F\u80CC\u666F\u56FE\u7247\u7684\u9ED8\u8BA4 alt \u6587\u672C\n */\nconst getBackgroundAlt = (backgroundImage?: ImageTextOverlayBackgroundImage): string => {\n if (!backgroundImage) return ''\n return (\n backgroundImage.default?.alt ||\n backgroundImage.tablet?.alt ||\n backgroundImage.laptop?.alt ||\n backgroundImage.desktop?.alt ||\n backgroundImage.lgDesktop?.alt ||\n ''\n )\n}\n\n// ============================================================================\n// \u54CD\u5E94\u5F0F\u5E03\u5C40\u7C7B\u540D \u2014\u2014 \u6839\u636E items \u6570\u91CF\u52A8\u6001\u51B3\u5B9A\u7F51\u683C\u5217\u6570\n//\n// Figma \u8BBE\u8BA1\u89C4\u8303\u603B\u7ED3:\n//\n// | Count | <768 (mobile) | 768-1024 (tablet) | 1025-1440 (laptop) | 1441-1920 (desktop) | \u22651921 (lg-desktop) |\n// |-------|---------------|--------------------|--------------------|---------------------|--------------------|\n// | 2 | 1col | 2col | 2col | 2col | 2col |\n// | 3 | 1col | 2col (2+1) | 3col | 3col | 3col |\n// | 4 | 2col (2 rows) | 2col (2 rows) | 2col (2 rows) | 2col (2 rows) | 2col (2 rows) |\n// | 5 | 2col (3 rows) | 2col (3 rows) | 2+3 (5col flex) | 2+3 (5col flex) | 2+3 (5col flex) |\n// | 6 | 2col (3 rows) | 2col (3 rows) | 3col (2 rows) | 3col (2 rows) | 3col (2 rows) |\n//\n// ============================================================================\n\n/**\n * \u5C06\u6570\u7EC4\u6309\u6307\u5B9A\u5927\u5C0F\u5206\u7EC4\n */\nconst chunkArray = <T,>(arr: T[], size: number): T[][] => {\n const chunks: T[][] = []\n for (let i = 0; i < arr.length; i += size) {\n chunks.push(arr.slice(i, i + size))\n }\n return chunks\n}\n\n/**\n * \u83B7\u53D6\u5BB9\u5668\u7F51\u683C\u7C7B\u540D\uFF08\u6839\u636E items \u6570\u91CF\uFF09\n */\nconst getGridClasses = (count: number): string => {\n switch (count) {\n case 2:\n // mobile: 1col, tablet+: 2col\n return 'grid-cols-1 tablet:grid-cols-2'\n case 3:\n // mobile: 1col, tablet: 2col, laptop+: 3col\n return 'grid-cols-1 tablet:grid-cols-2 laptop:grid-cols-3'\n case 4:\n // mobile: 2col, tablet+: 2col (uniform)\n return 'grid-cols-1 tablet:grid-cols-2'\n case 5:\n // mobile/tablet: 2col grid, laptop+: use flex layout instead (2+3 pattern)\n // We handle laptop+ separately via flex, grid for mobile/tablet only\n return 'grid-cols-1 tablet:grid-cols-2 laptop:grid-cols-6'\n case 6:\n // mobile/tablet: 2col, laptop+: 3col\n return 'grid-cols-1 tablet:grid-cols-2 desktop:grid-cols-3'\n default:\n if (count <= 1) return 'grid-cols-1'\n // fallback: 2col mobile, 3col laptop+\n return 'grid-cols-1 laptop:grid-cols-3'\n }\n}\n\n/**\n * \u83B7\u53D6\u5355\u4E2A item \u7684 span \u7C7B\u540D (\u4EC5\u7528\u4E8E count=3 tablet \u548C count=5 laptop+)\n */\nconst getItemSpanClasses = (index: number, count: number): string => {\n if (count === 5) {\n // laptop+: \u7B2C1\u884C 2 items \u5404 span 3, \u7B2C2\u884C 3 items \u5404 span 2\n if (index < 2) return 'laptop:col-span-3'\n return 'laptop:col-span-2'\n }\n return ''\n}\n\n/**\n * \u83B7\u53D6\u5361\u7247\u5BBD\u9AD8\u6BD4\u7C7B\u540D\n * \u6839\u636E items \u6570\u91CF\u548C\u65AD\u70B9\u52A8\u6001\u8BA1\u7B97\uFF0C\u786E\u4FDD\u56FE\u7247\u4E0D\u88AB\u622A\u65AD\n */\nconst getAspectRatioClasses = (count: number, index: number): string => {\n switch (count) {\n case 2:\n case 4:\n // \u59CB\u7EC8 2 \u5217\n return 'aspect-[358/240] tablet:aspect-[346/240] laptop:aspect-[440/192] desktop:aspect-[648/256] lg-desktop:aspect-[824/320]'\n case 3:\n // tablet 2 \u5217, laptop+ 3 \u5217\n return 'aspect-[358/240] tablet:aspect-[346/240] laptop:aspect-[288/192] desktop:aspect-[427/256] lg-desktop:aspect-[544/320]'\n case 5:\n // tablet 2 \u5217, laptop+ \u7279\u6B8A flex (\u9996\u884C 2 \u4E2A\u5404\u5360 50%, \u6B21\u884C 3 \u4E2A\u5404\u5360 33%)\n // \u7B2C\u4E00\u884C\uFF08index 0-1\uFF09\u7528 2 \u5217\u5BBD\u9AD8\u6BD4\uFF0C\u7B2C\u4E8C\u884C\uFF08index 2-4\uFF09\u7528 3 \u5217\u5BBD\u9AD8\u6BD4\uFF0C\u786E\u4FDD\u9AD8\u5EA6\u4E00\u81F4\n if (index < 2) {\n return 'aspect-[358/240] tablet:aspect-[346/240] laptop:aspect-[440/192] desktop:aspect-[648/256] lg-desktop:aspect-[824/320]'\n }\n return 'aspect-[358/240] tablet:aspect-[346/240] laptop:aspect-[288/192] desktop:aspect-[427/256] lg-desktop:aspect-[544/320]'\n case 6:\n // tablet/laptop 2 \u5217, desktop+ 3 \u5217\n return 'aspect-[358/240] tablet:aspect-[346/240] laptop:aspect-[440/192] desktop:aspect-[427/256] lg-desktop:aspect-[544/320]'\n default:\n if (count <= 1) return 'aspect-[358/240]'\n return 'aspect-[358/240] tablet:aspect-[346/240] laptop:aspect-[440/192] desktop:aspect-[648/256] lg-desktop:aspect-[824/320]'\n }\n}\n\n/**\n * ImageTextOverlayCard - \u5355\u4E2A\u56FE\u6587\u53E0\u52A0\u5361\u7247\n */\nconst ImageTextOverlayCard: React.FC<{\n item: ImageTextOverlayItem\n index: number\n count: number\n classNames?: Partial<Record<ImageTextOverlaySemanticName, string>>\n}> = ({ item, index, count, classNames }) => {\n const responsiveSource = buildResponsiveSource(item.backgroundImage)\n const defaultAlt = getBackgroundAlt(item.backgroundImage)\n const spanClasses = getItemSpanClasses(index, count)\n const imageRef = React.useRef<HTMLDivElement>(null)\n const { locale = 'us', pageHandle } = useAiuiContext()\n\n useExposure(imageRef, {\n componentType: imageComponentType,\n componentName,\n position: index + 1,\n componentTitle: item.title,\n componentDescription: item.subtitle,\n })\n\n const localizedLink = item.link ? getLocalizedPath(item.link, locale) : undefined\n const trackedLink = localizedLink\n ? trackUrlRef(localizedLink, `${pageHandle ?? ''}_${imageComponentType}_${componentName}`)\n : undefined\n const titleDescButton = `${item.title}#${item.subtitle || ''}#${item.title}`\n\n const aspectRatioClasses = getAspectRatioClasses(count, index)\n\n return (\n <div\n ref={imageRef}\n className={cn(\n 'image-text-overlay-card rounded-card',\n { 'aiui-dark': item.theme === 'dark' },\n 'desktop:p-6 lg-desktop:p-8 group relative flex flex-col items-start justify-end overflow-hidden p-4',\n aspectRatioClasses,\n spanClasses,\n classNames?.card\n )}\n >\n {/* \u6574\u5361\u94FE\u63A5 */}\n {trackedLink && (\n <a\n href={trackedLink}\n className=\"absolute inset-0 z-20\"\n aria-label={item.title}\n data-headless-type-name={`${imageComponentType}#${componentName}`}\n data-headless-title-desc-button={titleDescButton}\n />\n )}\n\n {/* \u80CC\u666F\u5A92\u4F53\uFF1A\u89C6\u9891\u6216\u56FE\u7247 */}\n {item.backgroundImage?.isShowVideo ? (\n <>\n {/* \u79FB\u52A8\u7AEF\u89C6\u9891 (<1025px) */}\n {item.backgroundImage?.mobileVideo && (\n <video\n className={cn(\n 'image-text-overlay-card-image',\n 'laptop:hidden absolute inset-0 size-full object-cover',\n classNames?.cardImage\n )}\n src={item.backgroundImage.mobileVideo.url}\n autoPlay\n muted\n loop\n playsInline\n />\n )}\n {/* \u684C\u9762\u7AEF\u89C6\u9891 (>=1025px) */}\n {item.backgroundImage?.desktopVideo && (\n <video\n className={cn(\n 'image-text-overlay-card-image',\n 'laptop:block absolute inset-0 hidden size-full object-cover',\n classNames?.cardImage\n )}\n src={item.backgroundImage.desktopVideo.url}\n autoPlay\n muted\n loop\n playsInline\n />\n )}\n </>\n ) : (\n responsiveSource && (\n <Picture\n source={responsiveSource}\n alt={defaultAlt || item.title}\n className={cn('image-text-overlay-card-image', 'absolute inset-0 size-full', classNames?.cardImage)}\n imgClassName=\"size-full object-cover cursor-pointer transition-all duration-300 group-hover:scale-105\"\n />\n )\n )}\n\n {/* \u6587\u5B57\u5185\u5BB9 */}\n <div\n className={cn(\n 'image-text-overlay-card-content',\n 'relative z-10 flex w-full flex-col gap-1',\n classNames?.cardContent\n )}\n >\n <Heading\n as=\"h4\"\n size={2}\n weight=\"bold\"\n className={cn(\n 'image-text-overlay-card-title text-info-primary line-clamp-1',\n 'w-full leading-[1.2] tracking-[-0.04em]',\n // \u5B57\u53F7: mobile/tablet/laptop 18px, desktop 20px, lg-desktop 24px\n 'desktop:text-xl lg-desktop:text-2xl text-lg',\n classNames?.cardTitle\n )}\n >\n {item.title}\n </Heading>\n\n {item.subtitle && (\n <Text\n as=\"p\"\n size=\"none\"\n weight=\"bold\"\n className={cn(\n 'image-text-overlay-card-subtitle text-info-primary line-clamp-1',\n 'w-full truncate leading-[1.4] tracking-[-0.02em]',\n // \u5B57\u53F7: mobile/tablet/laptop 14px, desktop 14px, lg-desktop 18px (count<=3) or 16px (count>3)\n 'lg-desktop:text-base text-sm',\n count <= 3 && 'lg-desktop:text-lg',\n classNames?.cardSubtitle\n )}\n >\n {item.subtitle}\n </Text>\n )}\n </div>\n </div>\n )\n}\n\n/**\n * ImageTextOverlay - \u56FE\u6587\u53E0\u52A0\u7EC4\u4EF6\n *\n * @description \u4EE5\u80CC\u666F\u56FE\u4E3A\u4E3B\u7684\u5361\u7247\u5E03\u5C40\u7EC4\u4EF6\uFF0C\u6807\u9898\u548C\u526F\u6807\u9898\u53E0\u52A0\u663E\u793A\u5728\u56FE\u7247\u5E95\u90E8\u3002\n * \u652F\u6301 2-6 \u4E2A items \u7684\u81EA\u52A8\u54CD\u5E94\u5F0F\u7F51\u683C\u5E03\u5C40\uFF0C\u6BCF\u4E2A item \u7684 backgroundImage\n * \u652F\u6301 5 \u4E2A\u65AD\u70B9 (default/tablet/laptop/desktop/lgDesktop)\u3002\n *\n * @example\n * ```tsx\n * <ImageTextOverlay\n * data={{\n * items: [\n * {\n * backgroundImage: {\n * default: { url: '/bg-mobile.jpg', alt: 'feature' },\n * tablet: { url: '/bg-tablet.jpg', alt: 'feature' },\n * laptop: { url: '/bg-laptop.jpg', alt: 'feature' },\n * desktop: { url: '/bg-desktop.jpg', alt: 'feature' },\n * lgDesktop: { url: '/bg-xl.jpg', alt: 'feature' },\n * },\n * title: '300+ AI brainwave audios',\n * subtitle: 'Charge in a Flash, Share in a Dash',\n * },\n * {\n * backgroundImage: { default: { url: '/bg2.jpg', alt: '' } },\n * title: '20+ white noise sounds',\n * subtitle: 'Power to Drive Your Prime',\n * },\n * ],\n * theme: 'dark',\n * }}\n * />\n * ```\n */\nconst ImageTextOverlay = forwardRef<HTMLDivElement, ImageTextOverlayProps>(\n ({ data, className, classNames = {}, ...props }, ref) => {\n const boxRef = React.useRef<HTMLDivElement>(null)\n const { items = [] } = data\n const [isMobile, setIsMobile] = useState(false)\n const mediaQuery = useMediaQuery({ query: '(max-width: 767px)' })\n\n useEffect(() => {\n setIsMobile(mediaQuery)\n }, [mediaQuery])\n\n useExposure(boxRef, {\n componentType,\n componentName,\n })\n\n React.useImperativeHandle(ref, () => boxRef.current as HTMLDivElement)\n\n if (!items.length) return null\n\n const count = items.length\n const useSwiper = count > 3 && isMobile\n const chunkedItems = chunkArray(items, 3)\n\n return (\n <div\n ref={boxRef}\n className={cn('image-text-overlay-root', className, classNames.root)}\n data-ui-component-id=\"ImageTextOverlay\"\n {...props}\n >\n {useSwiper ? (\n <div className=\"image-text-overlay-mobile-swiper relative pb-8\">\n <Swiper\n className=\"w-full [&_.swiper-slide]:!h-auto [&_.swiper-wrapper]:items-stretch\"\n modules={[Pagination]}\n slidesPerView={1}\n pagination={{\n clickable: true,\n el: `.${MOBILE_SWIPER_PAGINATION_CLASS}`,\n bulletClass: 'image-text-overlay-bullet',\n bulletActiveClass: 'image-text-overlay-bullet-active',\n }}\n spaceBetween={16}\n >\n {chunkedItems.map((group, gIndex) => (\n <SwiperSlide key={gIndex} className=\"!h-auto\">\n <div className=\"flex flex-col gap-4\">\n {group.map((item, index) => (\n <ImageTextOverlayCard\n key={gIndex * 3 + index}\n item={item}\n index={gIndex * 3 + index}\n count={count}\n classNames={classNames}\n />\n ))}\n </div>\n </SwiperSlide>\n ))}\n </Swiper>\n <div className=\"absolute inset-x-0 bottom-0 z-10 flex justify-center\">\n <div\n className={cn(\n MOBILE_SWIPER_PAGINATION_CLASS,\n 'flex items-center justify-center gap-2 text-center',\n '[&_.swiper-pagination-bullet]:m-0',\n '[&_.swiper-pagination-bullet]:shrink-0',\n '[&_.swiper-pagination-bullet]:opacity-100'\n )}\n />\n </div>\n <style>{`\n .image-text-overlay-bullet {\n display: inline-block;\n width: 8px;\n height: 8px;\n border-radius: 9999px;\n background: #767880;\n transition: all 0.3s ease;\n }\n\n .image-text-overlay-bullet-active {\n width: 32px;\n height: 8px;\n border-radius: 9999px;\n background: #080A0F;\n }\n `}</style>\n </div>\n ) : (\n <div className={cn('image-text-overlay-grid', 'grid gap-4', getGridClasses(count), classNames.grid)}>\n {items.map((item, index) => (\n <ImageTextOverlayCard key={index} item={item} index={index} count={count} classNames={classNames} />\n ))}\n </div>\n )}\n </div>\n )\n }\n)\n\nImageTextOverlay.displayName = 'ImageTextOverlay'\n\nexport default withLayout(ImageTextOverlay)\n"],
|
|
5
|
+
"mappings": "ukBAAA,IAAAA,GAAA,GAAAC,EAAAD,GAAA,aAAAE,KAAA,eAAAC,EAAAH,IA0OQ,IAAAI,EAAA,6BAzORC,EAAuB,oBACvBC,EAAwD,iBACxDC,EAAmB,kCACnBC,EAAwB,uCACxBC,EAAqB,oCACrBC,EAAoB,0CACpBC,EAA4B,sCAC5BC,EAA2B,kCAC3BC,EAA4B,uCAQ5BN,EAAiC,kCACjCO,EAA+B,oCAC/BC,EAA8B,4BAC9BT,EAAoC,wBACpCU,EAA2B,0BAC3BC,GAAO,sBACPC,GAAO,iCAUP,MAAMC,EAAgB,UAChBC,EAAgB,qBAChBC,EAAqB,QACrBC,EAAiC,uCAMjCC,EAAc,CAClB,QAAS,IACT,OAAQ,KACR,OAAQ,KACR,QAAS,KACT,UAAW,IACb,EAMMC,EAAyBC,GAA8D,CAC3F,GAAI,CAACA,EAAiB,MAAO,GAE7B,MAAMC,EAAoB,CAAC,EAG3B,OAAID,EAAgB,WAAW,KAC7BC,EAAQ,KAAK,GAAGD,EAAgB,UAAU,GAAG,EAAE,EAE7CA,EAAgB,SAAS,KAC3BC,EAAQ,KAAK,GAAGD,EAAgB,QAAQ,GAAG,IAAIF,EAAY,OAAO,EAAE,EAElEE,EAAgB,QAAQ,KAC1BC,EAAQ,KAAK,GAAGD,EAAgB,OAAO,GAAG,IAAIF,EAAY,MAAM,EAAE,EAEhEE,EAAgB,QAAQ,KAC1BC,EAAQ,KAAK,GAAGD,EAAgB,OAAO,GAAG,IAAIF,EAAY,MAAM,EAAE,EAEhEE,EAAgB,SAAS,KAC3BC,EAAQ,KAAK,GAAGD,EAAgB,QAAQ,GAAG,IAAIF,EAAY,OAAO,EAAE,EAG/DG,EAAQ,KAAK,IAAI,CAC1B,EAKMC,EAAoBF,GACnBA,IAEHA,EAAgB,SAAS,KACzBA,EAAgB,QAAQ,KACxBA,EAAgB,QAAQ,KACxBA,EAAgB,SAAS,KACzBA,EAAgB,WAAW,MAC3B,GAsBEG,EAAa,CAAKC,EAAUC,IAAwB,CACxD,MAAMC,EAAgB,CAAC,EACvB,QAASC,EAAI,EAAGA,EAAIH,EAAI,OAAQG,GAAKF,EACnCC,EAAO,KAAKF,EAAI,MAAMG,EAAGA,EAAIF,CAAI,CAAC,EAEpC,OAAOC,CACT,EAKME,EAAkBC,GAA0B,CAChD,OAAQA,EAAO,CACb,IAAK,GAEH,MAAO,iCACT,IAAK,GAEH,MAAO,oDACT,IAAK,GAEH,MAAO,iCACT,IAAK,GAGH,MAAO,oDACT,IAAK,GAEH,MAAO,qDACT,QACE,OAAIA,GAAS,EAAU,cAEhB,gCACX,CACF,EAKMC,EAAqB,CAACC,EAAeF,IACrCA,IAAU,EAERE,EAAQ,EAAU,oBACf,oBAEF,GAOHC,GAAwB,CAACH,EAAeE,IAA0B,CACtE,OAAQF,EAAO,CACb,IAAK,GACL,IAAK,GAEH,MAAO,wHACT,IAAK,GAEH,MAAO,wHACT,IAAK,GAGH,OAAIE,EAAQ,EACH,wHAEF,wHACT,IAAK,GAEH,MAAO,wHACT,QACE,OAAIF,GAAS,EAAU,mBAChB,uHACX,CACF,EAKMI,EAKD,CAAC,CAAE,KAAAC,EAAM,MAAAH,EAAO,MAAAF,EAAO,WAAAM,CAAW,IAAM,CAC3C,MAAMC,EAAmBjB,EAAsBe,EAAK,eAAe,EAC7DG,EAAaf,EAAiBY,EAAK,eAAe,EAClDI,EAAcR,EAAmBC,EAAOF,CAAK,EAC7CU,EAAWvC,EAAM,OAAuB,IAAI,EAC5C,CAAE,OAAAwC,EAAS,KAAM,WAAAC,CAAW,KAAI,kBAAe,KAErD,eAAYF,EAAU,CACpB,cAAevB,EACf,cAAAD,EACA,SAAUgB,EAAQ,EAClB,eAAgBG,EAAK,MACrB,qBAAsBA,EAAK,QAC7B,CAAC,EAED,MAAMQ,EAAgBR,EAAK,QAAO,oBAAiBA,EAAK,KAAMM,CAAM,EAAI,OAClEG,EAAcD,KAChB,eAAYA,EAAe,GAAGD,GAAc,EAAE,IAAIzB,CAAkB,IAAID,CAAa,EAAE,EACvF,OACE6B,EAAkB,GAAGV,EAAK,KAAK,IAAIA,EAAK,UAAY,EAAE,IAAIA,EAAK,KAAK,GAEpEW,EAAqBb,GAAsBH,EAAOE,CAAK,EAE7D,SACE,QAAC,OACC,IAAKQ,EACL,aAAW,MACT,uCACA,CAAE,YAAaL,EAAK,QAAU,MAAO,EACrC,sGACAW,EACAP,EACAH,GAAY,IACd,EAGC,UAAAQ,MACC,OAAC,KACC,KAAMA,EACN,UAAU,wBACV,aAAYT,EAAK,MACjB,0BAAyB,GAAGlB,CAAkB,IAAID,CAAa,GAC/D,kCAAiC6B,EACnC,EAIDV,EAAK,iBAAiB,eACrB,oBAEG,UAAAA,EAAK,iBAAiB,gBACrB,OAAC,SACC,aAAW,MACT,gCACA,wDACAC,GAAY,SACd,EACA,IAAKD,EAAK,gBAAgB,YAAY,IACtC,SAAQ,GACR,MAAK,GACL,KAAI,GACJ,YAAW,GACb,EAGDA,EAAK,iBAAiB,iBACrB,OAAC,SACC,aAAW,MACT,gCACA,8DACAC,GAAY,SACd,EACA,IAAKD,EAAK,gBAAgB,aAAa,IACvC,SAAQ,GACR,MAAK,GACL,KAAI,GACJ,YAAW,GACb,GAEJ,EAEAE,MACE,OAAC,EAAAU,QAAA,CACC,OAAQV,EACR,IAAKC,GAAcH,EAAK,MACxB,aAAW,MAAG,gCAAiC,6BAA8BC,GAAY,SAAS,EAClG,aAAa,0FACf,KAKJ,QAAC,OACC,aAAW,MACT,kCACA,2CACAA,GAAY,WACd,EAEA,oBAAC,WACC,GAAG,KACH,KAAM,EACN,OAAO,OACP,aAAW,MACT,+DACA,0CAEA,8CACAA,GAAY,SACd,EAEC,SAAAD,EAAK,MACR,EAECA,EAAK,aACJ,OAAC,QACC,GAAG,IACH,KAAK,OACL,OAAO,OACP,aAAW,MACT,kEACA,mDAEA,+BACAL,GAAS,GAAK,qBACdM,GAAY,YACd,EAEC,SAAAD,EAAK,SACR,GAEJ,GACF,CAEJ,EAoCMa,KAAmB,cACvB,CAAC,CAAE,KAAAC,EAAM,UAAAC,EAAW,WAAAd,EAAa,CAAC,EAAG,GAAGe,CAAM,EAAGC,IAAQ,CACvD,MAAMC,EAASpD,EAAM,OAAuB,IAAI,EAC1C,CAAE,MAAAqD,EAAQ,CAAC,CAAE,EAAIL,EACjB,CAACM,EAAUC,CAAW,KAAI,YAAS,EAAK,EACxCC,KAAa,iBAAc,CAAE,MAAO,oBAAqB,CAAC,EAahE,MAXA,aAAU,IAAM,CACdD,EAAYC,CAAU,CACxB,EAAG,CAACA,CAAU,CAAC,KAEf,eAAYJ,EAAQ,CAClB,cAAAtC,EACA,cAAAC,CACF,CAAC,EAEDf,EAAM,oBAAoBmD,EAAK,IAAMC,EAAO,OAAyB,EAEjE,CAACC,EAAM,OAAQ,OAAO,KAE1B,MAAMxB,EAAQwB,EAAM,OACdI,EAAY5B,EAAQ,GAAKyB,EACzBI,EAAenC,EAAW8B,EAAO,CAAC,EAExC,SACE,OAAC,OACC,IAAKD,EACL,aAAW,MAAG,0BAA2BH,EAAWd,EAAW,IAAI,EACnE,uBAAqB,mBACpB,GAAGe,EAEH,SAAAO,KACC,QAAC,OAAI,UAAU,iDACb,oBAAC,UACC,UAAU,qEACV,QAAS,CAAC,YAAU,EACpB,cAAe,EACf,WAAY,CACV,UAAW,GACX,GAAI,IAAIxC,CAA8B,GACtC,YAAa,4BACb,kBAAmB,kCACrB,EACA,aAAc,GAEb,SAAAyC,EAAa,IAAI,CAACC,EAAOC,OACxB,OAAC,eAAyB,UAAU,UAClC,mBAAC,OAAI,UAAU,sBACZ,SAAAD,EAAM,IAAI,CAACzB,EAAMH,OAChB,OAACE,EAAA,CAEC,KAAMC,EACN,MAAO0B,EAAS,EAAI7B,EACpB,MAAOF,EACP,WAAYM,GAJPyB,EAAS,EAAI7B,CAKpB,CACD,EACH,GAXgB6B,CAYlB,CACD,EACH,KACA,OAAC,OAAI,UAAU,uDACb,mBAAC,OACC,aAAW,MACT3C,EACA,qDACA,oCACA,yCACA,2CACF,EACF,EACF,KACA,OAAC,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,cAgBN,GACJ,KAEA,OAAC,OAAI,aAAW,MAAG,0BAA2B,aAAcW,EAAeC,CAAK,EAAGM,EAAW,IAAI,EAC/F,SAAAkB,EAAM,IAAI,CAACnB,EAAMH,OAChB,OAACE,EAAA,CAAiC,KAAMC,EAAM,MAAOH,EAAO,MAAOF,EAAO,WAAYM,GAA3DJ,CAAuE,CACnG,EACH,EAEJ,CAEJ,CACF,EAEAgB,EAAiB,YAAc,mBAE/B,IAAOlD,MAAQ,cAAWkD,CAAgB",
|
|
6
|
+
"names": ["ImageTextOverlay_exports", "__export", "ImageTextOverlay_default", "__toCommonJS", "import_jsx_runtime", "React", "import_react", "import_utils", "import_heading", "import_text", "import_picture", "import_useExposure", "import_Styles", "import_trackUrlRef", "import_AiuiProvider", "import_react_responsive", "import_modules", "import_css", "import_pagination", "componentType", "componentName", "imageComponentType", "MOBILE_SWIPER_PAGINATION_CLASS", "BREAKPOINTS", "buildResponsiveSource", "backgroundImage", "sources", "getBackgroundAlt", "chunkArray", "arr", "size", "chunks", "i", "getGridClasses", "count", "getItemSpanClasses", "index", "getAspectRatioClasses", "ImageTextOverlayCard", "item", "classNames", "responsiveSource", "defaultAlt", "spanClasses", "imageRef", "locale", "pageHandle", "localizedLink", "trackedLink", "titleDescButton", "aspectRatioClasses", "Picture", "ImageTextOverlay", "data", "className", "props", "ref", "boxRef", "items", "isMobile", "setIsMobile", "mediaQuery", "useSwiper", "chunkedItems", "group", "gIndex"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";"use client";var
|
|
1
|
+
"use strict";"use client";var F=Object.create;var N=Object.defineProperty;var G=Object.getOwnPropertyDescriptor;var I=Object.getOwnPropertyNames;var V=Object.getPrototypeOf,_=Object.prototype.hasOwnProperty;var $=(r,l)=>{for(var p in l)N(r,p,{get:l[p],enumerable:!0})},M=(r,l,p,x)=>{if(l&&typeof l=="object"||typeof l=="function")for(let c of I(l))!_.call(r,c)&&c!==p&&N(r,c,{get:()=>l[c],enumerable:!(x=G(l,c))||x.enumerable});return r};var q=(r,l,p)=>(p=r!=null?F(V(r)):{},M(l||!r||!r.__esModule?N(p,"default",{value:r,enumerable:!0}):p,r)),O=r=>M(N({},"__esModule",{value:!0}),r);var U={};$(U,{default:()=>Q});module.exports=O(U);var t=require("react/jsx-runtime"),n=require("react"),E=require("../../helpers/utils.js"),H=require("../../shared/Styles.js"),m=require("../../components/index.js"),A=require("../../hooks/useExposure.js"),S=q(require("@radix-ui/react-popover"));const W="navigation",J="product_nav",K=r=>(0,t.jsx)("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"none",xmlns:"http://www.w3.org/2000/svg",...r,children:(0,t.jsx)("path",{d:"M5 7.5L10 12.5L15 7.5",stroke:"currentColor",strokeWidth:"1.66667",strokeLinecap:"round",strokeLinejoin:"round"})}),D=(0,n.forwardRef)(({className:r="",data:l,id:p,onAnchorClick:x,scrollOffsetExtra:c=0},B)=>{const{tabLinks:k=[],anchorList:i=[],textLink:d,buyBtn:f,theme:z="light"}=l||{},[j,b]=(0,n.useState)(""),g=(0,n.useRef)(null),y=(0,n.useRef)(!1),h=(0,n.useRef)(""),w=(0,n.useRef)(null),P=(0,n.useRef)(new Map);(0,n.useImperativeHandle)(B,()=>g.current),(0,A.useExposure)(g,{componentType:W,componentName:J});const T=(0,n.useCallback)(()=>{if(i.length===0)return;const e=window.scrollY;window.scrollTo({top:0,behavior:"instant"}),requestAnimationFrame(()=>{const o=new Map;i.forEach(a=>{const s=document.getElementById(a.id);if(s){const u=s.getBoundingClientRect();o.set(a.id,u.top+window.scrollY)}}),P.current=o,window.scrollTo({top:e,behavior:"instant"})})},[i]);(0,n.useEffect)(()=>{if(i.length===0)return;const e=setTimeout(T,100);return()=>clearTimeout(e)},[i,T]),(0,n.useEffect)(()=>{if(i.length===0)return;let e=null;const o=new ResizeObserver(()=>{e&&clearTimeout(e),e=setTimeout(T,150)});return o.observe(document.body),()=>{o.disconnect(),e&&clearTimeout(e)}},[i,T]),(0,n.useEffect)(()=>{if(i.length===0)return;const e=()=>{if(y.current){w.current&&clearTimeout(w.current),w.current=setTimeout(()=>{y.current=!1,h.current&&(b(h.current),h.current="")},100);return}const a=g.current?.offsetHeight||0,s=window.scrollY+a+c+10;let u="";const R=P.current;for(let v=i.length-1;v>=0;v--){const C=i[v],L=R.get(C.id);if(L!==void 0&&s>=L){u=C.id;break}}if(!u&&i.length>0){const v=R.get(i[0].id);v!==void 0&&s<v&&(u="")}b(u)},o=setTimeout(()=>{e()},200);return window.addEventListener("scroll",e,{passive:!0}),()=>{clearTimeout(o),window.removeEventListener("scroll",e),w.current&&clearTimeout(w.current)}},[i,c]),(0,n.useEffect)(()=>{const e=document.querySelectorAll(".header"),o=[];return e.forEach(a=>{const s=a;o.push({element:s,originalPosition:s.style.position||getComputedStyle(s).position}),s.style.position="relative"}),()=>{o.forEach(({element:a,originalPosition:s})=>{a.style.position=s==="static"?"":s})}},[]);const Y=(e,o)=>{e.preventDefault();const a=P.current.get(o);if(a===void 0){console.warn(`Cached position for "${o}" not found`);return}b(o),h.current=o,y.current=!0;const s=g.current?.offsetHeight||0,u=a-s-c;window.scrollTo({top:u,behavior:"smooth"}),window.history.pushState(null,"",`#${o}`)};return(0,t.jsxs)("div",{id:p,ref:g,className:(0,E.cn)("product-nav text-info-primary bg-container-primary tablet:px-8 laptop:px-16 desktop:px-16 lg-desktop:px-[calc(50%-832px)] !sticky top-0 !z-[51] flex w-full justify-between overflow-hidden px-4 py-0",{"aiui-dark":z==="dark"},r),children:[(0,t.jsxs)("div",{className:"product-nav-main desktop:flex-row desktop:gap-[48px] flex w-full flex-col justify-start",children:[(0,t.jsxs)("div",{className:"product-nav-header laptop:w-full desktop:w-fit desktop:gap-[24px] desktop:py-0 flex w-full flex-row items-center justify-between gap-[16px] pt-[14px]",children:[(0,t.jsxs)("div",{className:"product-nav-tabs flex flex-row items-center gap-[8px]",children:[k.map((e,o)=>(0,t.jsxs)("div",{className:"product-nav-tab-item flex items-center gap-[8px]",children:[(0,t.jsx)("a",{href:e.link,className:(0,E.cn)("product-nav-tab-link hover:text-brand-color text-nowrap text-[14px] font-bold tracking-[-0.04em]",{"text-[#6D6D6F]":o!==0,"hidden desktop:block":o===1}),children:(0,t.jsx)("span",{children:e.label})}),o!==k.length-1&&(0,t.jsx)("div",{className:"product-nav-tab-divider desktop:inline-block hidden h-[14px] w-px bg-[#E4E5E6]"})]},e.link||o)),k.length>1&&(0,t.jsxs)(S.Root,{children:[(0,t.jsx)(S.Trigger,{asChild:!0,children:(0,t.jsx)("button",{className:"product-nav-dropdown-trigger desktop:hidden -ml-1 inline-block","aria-label":"More products",children:(0,t.jsx)(K,{className:"text-[#1D1D1F]"})})}),(0,t.jsx)(S.Content,{className:"product-nav-dropdown-content rounded-[6px] border border-[#E4E5E6] bg-white p-[6px] px-[8px] py-[4px]",style:{boxShadow:"0px 4px 8px 0px rgba(0,0,0,0.12)"},side:"bottom",align:"end",alignOffset:10,sideOffset:10,children:k.slice(1).map(e=>(0,t.jsx)("a",{href:e.link,className:"product-nav-dropdown-link hover:text-brand-color text-nowrap",children:(0,t.jsx)("span",{children:e.label})},e.link))})]})]}),(0,t.jsxs)("div",{className:"product-nav-mobile-actions desktop:hidden desktop:gap-[24px] flex items-center gap-[16px]",children:[d?.link&&(0,t.jsx)("a",{href:d.link,target:d.target||"_self",className:"product-nav-text-link hover:text-brand-color cursor-pointer",children:(0,t.jsx)(m.Text,{size:2,className:"text-nowrap",children:d.text})}),f?.link&&(0,t.jsx)(m.Button,{as:"a",href:f.link,size:"sm",className:"product-nav-buy-button text-nowrap",children:f.text})]})]}),(0,t.jsx)("div",{className:"product-nav-anchors laptop:w-fit desktop:gap-[24px] desktop:py-[8px] flex w-full items-center gap-[16px] overflow-x-scroll py-[12px] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",children:i.map((e,o)=>(0,t.jsxs)("a",{href:`#${e.id}`,className:"product-nav-anchor-link",onClick:a=>{x?(a.preventDefault(),b(e.id),h.current=e.id,y.current=!0,x(e,o)):Y(a,e.id)},children:[(0,t.jsx)(m.Text,{size:2,className:"product-nav-anchor-text text-nowrap",children:e.label}),(0,t.jsx)("div",{className:(0,E.cn)("product-nav-anchor-indicator laptop:top-[12px] desktop:top-[10px] relative top-[12px] h-[4px] w-full bg-transparent",{"!bg-brand-0":j===e.id})})]},e.id))})]}),(0,t.jsxs)("div",{className:"product-nav-desktop-actions desktop:flex desktop:gap-[24px] desktop:py-[8px] hidden items-center gap-[16px]",children:[d?.link&&(0,t.jsx)("a",{href:d.link,target:d.target||"_self",className:"product-nav-text-link hover:text-brand-color cursor-pointer text-black",children:(0,t.jsx)(m.Text,{size:2,className:"text-nowrap",children:d.text})}),f?.link&&(0,t.jsx)(m.Button,{as:"a",href:f.link,size:"sm",className:"product-nav-buy-button text-nowrap",children:f.text})]})]})});D.displayName="ProductNav";var Q=(0,H.withLayout)(D);
|
|
2
2
|
//# sourceMappingURL=ProductNav.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/biz-components/ProductNav/ProductNav.tsx"],
|
|
4
|
-
"sourcesContent": ["'use client'\nimport { useState, useEffect, forwardRef, useImperativeHandle, useRef } from 'react'\nimport { cn } from '../../helpers/utils.js'\nimport { withLayout } from '../../shared/Styles.js'\nimport { Button, Text } from '../../components/index.js'\nimport { useExposure } from '../../hooks/useExposure.js'\nimport type { ProductNavProps } from './types.js'\nimport * as Popover from '@radix-ui/react-popover'\n\nconst componentType = 'navigation'\nconst componentName = 'product_nav'\n\nconst ChevronDownIcon = (props: React.SVGProps<SVGSVGElement>) => {\n return (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" {...props}>\n <path\n d=\"M5 7.5L10 12.5L15 7.5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.66667\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n )\n}\n\nconst ProductNav = forwardRef<HTMLDivElement, ProductNavProps>(\n ({ className = '', data, id, onAnchorClick, scrollOffsetExtra = 0 }, ref) => {\n const { tabLinks = [], anchorList = [], textLink, buyBtn, theme = 'light' } = data || {}\n const [activeAnchorId, setActiveAnchorId] = useState('')\n const innerRef = useRef<HTMLDivElement>(null)\n const isScrollingRef = useRef(false) // \u6807\u8BB0\u662F\u5426\u6B63\u5728\u7A0B\u5E8F\u5316\u6EDA\u52A8\u4E2D\n const targetAnchorIdRef = useRef<string>('') // \u8BB0\u5F55\u70B9\u51FB\u76EE\u6807\u951A\u70B9\n const scrollEndTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null) // \u6EDA\u52A8\u7ED3\u675F\u68C0\u6D4B\u5B9A\u65F6\u5668\n const anchorPositionsRef = useRef<Map<string, number>>(new Map()) // \u7F13\u5B58\u951A\u70B9\u539F\u59CB\u4F4D\u7F6E\n\n useImperativeHandle(ref, () => innerRef.current as HTMLDivElement)\n\n useExposure(innerRef, {\n componentType,\n componentName,\n })\n\n // \u521D\u59CB\u5316\u65F6\u7F13\u5B58\u6240\u6709\u951A\u70B9\u7684\u539F\u59CB\u4F4D\u7F6E\uFF08\u5728\u6EDA\u52A8\u524D\u8BA1\u7B97\uFF0C\u907F\u514D sticky \u5F71\u54CD\uFF09\n useEffect(() => {\n if (anchorList.length === 0) return\n\n // \u9875\u9762\u52A0\u8F7D\u540E\u5EF6\u8FDF\u8BA1\u7B97\uFF0C\u786E\u4FDD\u5E03\u5C40\u5B8C\u6210\n const timer = setTimeout(() => {\n // \u5148\u6EDA\u52A8\u5230\u9876\u90E8\u8BA1\u7B97\u771F\u5B9E\u4F4D\u7F6E\n const originalScrollY = window.scrollY\n window.scrollTo({ top: 0, behavior: 'instant' as ScrollBehavior })\n\n // \u7B49\u5F85\u4E00\u5E27\u8BA9\u5E03\u5C40\u7A33\u5B9A\n requestAnimationFrame(() => {\n const positions = new Map<string, number>()\n anchorList.forEach(anchor => {\n const element = document.getElementById(anchor.id)\n if (element) {\n const rect = element.getBoundingClientRect()\n positions.set(anchor.id, rect.top + window.scrollY)\n }\n })\n anchorPositionsRef.current = positions\n\n // \u6062\u590D\u539F\u6765\u7684\u6EDA\u52A8\u4F4D\u7F6E\n window.scrollTo({ top: originalScrollY, behavior: 'instant' as ScrollBehavior })\n })\n }, 100)\n\n return () => clearTimeout(timer)\n }, [anchorList])\n\n // \u6EDA\u52A8\u76D1\u542C\uFF1A\u68C0\u6D4B\u5F53\u524D\u6EDA\u52A8\u4F4D\u7F6E\u5BF9\u5E94\u7684\u951A\u70B9\n useEffect(() => {\n if (anchorList.length === 0) return\n\n const handleScroll = () => {\n // \u5982\u679C\u6B63\u5728\u7A0B\u5E8F\u5316\u6EDA\u52A8\u4E2D\uFF0C\u4F7F\u7528 debounce \u68C0\u6D4B\u6EDA\u52A8\u7ED3\u675F\n if (isScrollingRef.current) {\n // \u6E05\u9664\u4E4B\u524D\u7684\u5B9A\u65F6\u5668\n if (scrollEndTimerRef.current) {\n clearTimeout(scrollEndTimerRef.current)\n }\n // \u8BBE\u7F6E\u65B0\u7684\u5B9A\u65F6\u5668\uFF0C100ms \u6CA1\u6709\u65B0\u6EDA\u52A8\u4E8B\u4EF6\u5219\u8BA4\u4E3A\u6EDA\u52A8\u7ED3\u675F\n scrollEndTimerRef.current = setTimeout(() => {\n isScrollingRef.current = false\n // \u6EDA\u52A8\u7ED3\u675F\u540E\uFF0C\u786E\u4FDD\u9AD8\u4EAE\u505C\u7559\u5728\u76EE\u6807\u951A\u70B9\n if (targetAnchorIdRef.current) {\n setActiveAnchorId(targetAnchorIdRef.current)\n targetAnchorIdRef.current = ''\n }\n }, 100)\n return\n }\n\n const navHeight = innerRef.current?.offsetHeight || 0\n const scrollPosition = window.scrollY + navHeight + scrollOffsetExtra + 10 // 10px \u7F13\u51B2\n\n let currentAnchorId = ''\n\n // \u4F7F\u7528\u7F13\u5B58\u7684\u951A\u70B9\u4F4D\u7F6E\n const positions = anchorPositionsRef.current\n\n // \u904D\u5386\u6240\u6709\u951A\u70B9\uFF0C\u627E\u5230\u5F53\u524D\u6EDA\u52A8\u4F4D\u7F6E\u5BF9\u5E94\u7684\u951A\u70B9\n for (let i = anchorList.length - 1; i >= 0; i--) {\n const anchor = anchorList[i]\n const elementTop = positions.get(anchor.id)\n if (elementTop !== undefined && scrollPosition >= elementTop) {\n currentAnchorId = anchor.id\n break\n }\n }\n\n // \u5982\u679C\u6CA1\u6709\u627E\u5230\u4E14\u7F13\u5B58\u4E2D\u6709\u7B2C\u4E00\u4E2A\u951A\u70B9\u7684\u4F4D\u7F6E\n if (!currentAnchorId && anchorList.length > 0) {\n const firstElementTop = positions.get(anchorList[0].id)\n if (firstElementTop !== undefined && scrollPosition < firstElementTop) {\n currentAnchorId = ''\n }\n }\n\n setActiveAnchorId(currentAnchorId)\n }\n\n // \u5EF6\u8FDF\u521D\u59CB\u5316\uFF0C\u7B49\u5F85\u4F4D\u7F6E\u7F13\u5B58\u5B8C\u6210\n const timer = setTimeout(() => {\n handleScroll()\n }, 200)\n\n window.addEventListener('scroll', handleScroll, { passive: true })\n return () => {\n clearTimeout(timer)\n window.removeEventListener('scroll', handleScroll)\n // \u6E05\u7406\u5B9A\u65F6\u5668\n if (scrollEndTimerRef.current) {\n clearTimeout(scrollEndTimerRef.current)\n }\n }\n }, [anchorList, scrollOffsetExtra])\n\n // \u8BBE\u7F6E\u9875\u9762\u4E2Dheader\u5143\u7D20\u7684position\u4E3Arelative\n useEffect(() => {\n const headerElements = document.querySelectorAll('.header')\n const originalStyles: { element: HTMLElement; originalPosition: string }[] = []\n\n headerElements.forEach(element => {\n const htmlElement = element as HTMLElement\n // \u4FDD\u5B58\u539F\u59CB\u6837\u5F0F\n originalStyles.push({\n element: htmlElement,\n originalPosition: htmlElement.style.position || getComputedStyle(htmlElement).position,\n })\n // \u8BBE\u7F6E\u4E3Arelative\n htmlElement.style.position = 'relative'\n })\n\n // \u6E05\u7406\u51FD\u6570\uFF1A\u6062\u590D\u539F\u59CB\u6837\u5F0F\n return () => {\n originalStyles.forEach(({ element, originalPosition }) => {\n element.style.position = originalPosition === 'static' ? '' : originalPosition\n })\n }\n }, [])\n\n // \u5904\u7406\u951A\u70B9\u70B9\u51FB\u6EDA\u52A8\n const handleAnchorClick = (e: React.MouseEvent, anchorId: string) => {\n e.preventDefault()\n\n // \u4F7F\u7528\u7F13\u5B58\u7684\u4F4D\u7F6E\n const elementAbsoluteTop = anchorPositionsRef.current.get(anchorId)\n if (elementAbsoluteTop === undefined) {\n console.warn(`Cached position for \"${anchorId}\" not found`)\n return\n }\n\n // \u7ACB\u5373\u66F4\u65B0\u9AD8\u4EAE\u72B6\u6001\uFF0C\u907F\u514D\u6EDA\u52A8\u8FC7\u7A0B\u4E2D\u95EA\u70C1\n setActiveAnchorId(anchorId)\n\n // \u8BB0\u5F55\u76EE\u6807\u951A\u70B9\uFF0C\u7528\u4E8E\u6EDA\u52A8\u7ED3\u675F\u540E\u786E\u4FDD\u9AD8\u4EAE\u6B63\u786E\n targetAnchorIdRef.current = anchorId\n\n // \u6807\u8BB0\u6B63\u5728\u7A0B\u5E8F\u5316\u6EDA\u52A8\uFF0C\u6682\u505C\u6EDA\u52A8\u76D1\u542C\n isScrollingRef.current = true\n\n // \u83B7\u53D6\u5BFC\u822A\u680F\u9AD8\u5EA6\n const navHeight = innerRef.current?.offsetHeight || 0\n\n // \u76EE\u6807\u6EDA\u52A8\u4F4D\u7F6E = \u7F13\u5B58\u7684\u5143\u7D20\u7EDD\u5BF9\u4F4D\u7F6E - \u5BFC\u822A\u680F\u9AD8\u5EA6 - \u989D\u5916\u504F\u79FB\n const targetPosition = elementAbsoluteTop - navHeight - scrollOffsetExtra\n\n // \u5E73\u6ED1\u6EDA\u52A8\u5230\u76EE\u6807\u4F4D\u7F6E\n window.scrollTo({\n top: targetPosition,\n behavior: 'smooth',\n })\n\n // \u66F4\u65B0 URL hash\uFF08\u4E0D\u89E6\u53D1\u9875\u9762\u8DF3\u8F6C\uFF09\n window.history.pushState(null, '', `#${anchorId}`)\n\n // \u6CE8\u610F\uFF1A\u6EDA\u52A8\u7ED3\u675F\u68C0\u6D4B\u7531 handleScroll \u4E2D\u7684 debounce \u903B\u8F91\u5904\u7406\n // \u4E0D\u518D\u4F7F\u7528\u56FA\u5B9A 800ms \u8D85\u65F6\uFF0C\u800C\u662F\u68C0\u6D4B\u5B9E\u9645\u6EDA\u52A8\u7ED3\u675F\n }\n\n return (\n <div\n id={id}\n ref={innerRef}\n className={cn(\n 'product-nav text-info-primary bg-container-primary tablet:px-8 laptop:px-16 desktop:px-16 lg-desktop:px-[calc(50%-832px)] !sticky top-0 !z-[51] flex w-full justify-between overflow-hidden px-4 py-0',\n {\n 'aiui-dark': theme === 'dark',\n },\n className\n )}\n >\n <div className=\"product-nav-main desktop:flex-row desktop:gap-[48px] flex w-full flex-col justify-start\">\n {/* Tab Links Section */}\n <div className=\"product-nav-header laptop:w-full desktop:w-fit desktop:gap-[24px] desktop:py-0 flex w-full flex-row items-center justify-between gap-[16px] pt-[14px]\">\n <div className=\"product-nav-tabs flex flex-row items-center gap-[8px]\">\n {tabLinks.map((tabLink, index) => {\n return (\n <div key={tabLink.link || index} className=\"product-nav-tab-item flex items-center gap-[8px]\">\n <a\n href={tabLink.link}\n className={cn(\n 'product-nav-tab-link hover:text-brand-color text-nowrap text-[14px] font-bold tracking-[-0.04em]',\n {\n 'text-[#6D6D6F]': index !== 0,\n 'hidden desktop:block': index === 1,\n }\n )}\n // onClick={() => onShowSpecs?.(false)}\n >\n <span>{tabLink.label}</span>\n </a>\n {index !== tabLinks.length - 1 && (\n <div className=\"product-nav-tab-divider desktop:inline-block hidden h-[14px] w-px bg-[#E4E5E6]\" />\n )}\n </div>\n )\n })}\n\n {/* Mobile Dropdown */}\n {tabLinks.length > 1 && (\n <Popover.Root>\n <Popover.Trigger asChild>\n <button\n className=\"product-nav-dropdown-trigger desktop:hidden -ml-1 inline-block\"\n aria-label=\"More products\"\n >\n <ChevronDownIcon className=\"text-[#1D1D1F]\" />\n </button>\n </Popover.Trigger>\n <Popover.Content\n className=\"product-nav-dropdown-content rounded-[6px] border border-[#E4E5E6] bg-white p-[6px] px-[8px] py-[4px]\"\n style={{\n boxShadow: '0px 4px 8px 0px rgba(0,0,0,0.12)',\n }}\n side=\"bottom\"\n align=\"end\"\n alignOffset={10}\n sideOffset={10}\n >\n {tabLinks.slice(1).map(tabLink => (\n <a\n key={tabLink.link}\n href={tabLink.link}\n className=\"product-nav-dropdown-link hover:text-brand-color text-nowrap\"\n >\n <span>{tabLink.label}</span>\n </a>\n ))}\n </Popover.Content>\n </Popover.Root>\n )}\n </div>\n\n {/* Mobile Actions */}\n <div className=\"product-nav-mobile-actions desktop:hidden desktop:gap-[24px] flex items-center gap-[16px]\">\n {/* {specs?.text && (\n <Text\n size={2}\n onClick={handleSpecsClick}\n className=\"product-nav-specs-button cursor-pointer hover:text-brand-color\"\n >\n {specs.text}\n </Text>\n )} */}\n {textLink?.link && (\n <a\n href={textLink.link}\n target={textLink.target || '_self'}\n className=\"product-nav-text-link hover:text-brand-color cursor-pointer\"\n >\n <Text size={2} className=\"text-nowrap\">\n {textLink.text}\n </Text>\n </a>\n )}\n {buyBtn?.link && (\n <Button as=\"a\" href={buyBtn.link} size=\"sm\" className=\"product-nav-buy-button text-nowrap\">\n {buyBtn.text}\n </Button>\n )}\n </div>\n </div>\n\n {/* Anchor Navigation */}\n <div className=\"product-nav-anchors laptop:w-fit desktop:gap-[24px] desktop:py-[8px] flex w-full items-center gap-[16px] overflow-x-scroll py-[12px] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden\">\n {anchorList.map((anchor, index) => (\n <a\n key={anchor.id}\n href={`#${anchor.id}`}\n className=\"product-nav-anchor-link\"\n onClick={e => {\n // \u5982\u679C\u63D0\u4F9B\u4E86\u81EA\u5B9A\u4E49\u70B9\u51FB\u4E8B\u4EF6,\u4F7F\u7528\u81EA\u5B9A\u4E49\u4E8B\u4EF6\u5E76\u963B\u6B62\u9ED8\u8BA4\u884C\u4E3A\n if (onAnchorClick) {\n e.preventDefault()\n // \u6807\u8BB0\u7A0B\u5E8F\u5316\u6EDA\u52A8\uFF0C\u907F\u514D\u6EDA\u52A8\u8FC7\u7A0B\u4E2D\u9AD8\u4EAE\u95EA\u70C1\n setActiveAnchorId(anchor.id)\n targetAnchorIdRef.current = anchor.id\n isScrollingRef.current = true\n onAnchorClick(anchor, index)\n } else {\n // \u4F7F\u7528\u9ED8\u8BA4\u7684\u951A\u70B9\u6EDA\u52A8\u884C\u4E3A\uFF0C\u5E26\u504F\u79FB\u91CF\n handleAnchorClick(e, anchor.id)\n }\n }}\n >\n <Text size={2} className=\"product-nav-anchor-text text-nowrap\">\n {anchor.label}\n </Text>\n <div\n className={cn(\n 'product-nav-anchor-indicator laptop:top-[12px] desktop:top-[10px] relative top-[12px] h-[4px] w-full bg-transparent',\n {\n '!bg-brand-0': activeAnchorId === anchor.id,\n }\n )}\n />\n </a>\n ))}\n </div>\n </div>\n\n {/* Desktop Actions */}\n <div className=\"product-nav-desktop-actions desktop:flex desktop:gap-[24px] desktop:py-[8px] hidden items-center gap-[16px]\">\n {/* {specs?.text && (\n <Text\n size={2}\n onClick={handleSpecsClick}\n className=\"product-nav-specs-button cursor-pointer text-black hover:text-brand-color\"\n >\n {specs.text}\n </Text>\n )} */}\n {textLink?.link && (\n <a\n href={textLink.link}\n target={textLink.target || '_self'}\n className=\"product-nav-text-link hover:text-brand-color cursor-pointer text-black\"\n >\n <Text size={2} className=\"text-nowrap\">\n {textLink.text}\n </Text>\n </a>\n )}\n {buyBtn?.link && (\n <Button as=\"a\" href={buyBtn.link} size=\"sm\" className=\"product-nav-buy-button text-nowrap\">\n {buyBtn.text}\n </Button>\n )}\n </div>\n </div>\n )\n }\n)\n\nProductNav.displayName = 'ProductNav'\n\nexport default withLayout(ProductNav)\n"],
|
|
5
|
-
"mappings": "ukBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,aAAAE,IAAA,eAAAC,EAAAH,GAeM,IAAAI,EAAA,6BAdNC,
|
|
6
|
-
"names": ["ProductNav_exports", "__export", "ProductNav_default", "__toCommonJS", "import_jsx_runtime", "import_react", "import_utils", "import_Styles", "import_components", "import_useExposure", "Popover", "componentType", "componentName", "ChevronDownIcon", "props", "ProductNav", "className", "data", "id", "onAnchorClick", "scrollOffsetExtra", "ref", "tabLinks", "anchorList", "textLink", "buyBtn", "theme", "activeAnchorId", "setActiveAnchorId", "innerRef", "isScrollingRef", "targetAnchorIdRef", "scrollEndTimerRef", "anchorPositionsRef", "
|
|
4
|
+
"sourcesContent": ["'use client'\nimport { useState, useEffect, useCallback, forwardRef, useImperativeHandle, useRef } from 'react'\nimport { cn } from '../../helpers/utils.js'\nimport { withLayout } from '../../shared/Styles.js'\nimport { Button, Text } from '../../components/index.js'\nimport { useExposure } from '../../hooks/useExposure.js'\nimport type { ProductNavProps } from './types.js'\nimport * as Popover from '@radix-ui/react-popover'\n\nconst componentType = 'navigation'\nconst componentName = 'product_nav'\n\nconst ChevronDownIcon = (props: React.SVGProps<SVGSVGElement>) => {\n return (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" {...props}>\n <path\n d=\"M5 7.5L10 12.5L15 7.5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.66667\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n )\n}\n\nconst ProductNav = forwardRef<HTMLDivElement, ProductNavProps>(\n ({ className = '', data, id, onAnchorClick, scrollOffsetExtra = 0 }, ref) => {\n const { tabLinks = [], anchorList = [], textLink, buyBtn, theme = 'light' } = data || {}\n const [activeAnchorId, setActiveAnchorId] = useState('')\n const innerRef = useRef<HTMLDivElement>(null)\n const isScrollingRef = useRef(false) // \u6807\u8BB0\u662F\u5426\u6B63\u5728\u7A0B\u5E8F\u5316\u6EDA\u52A8\u4E2D\n const targetAnchorIdRef = useRef<string>('') // \u8BB0\u5F55\u70B9\u51FB\u76EE\u6807\u951A\u70B9\n const scrollEndTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null) // \u6EDA\u52A8\u7ED3\u675F\u68C0\u6D4B\u5B9A\u65F6\u5668\n const anchorPositionsRef = useRef<Map<string, number>>(new Map()) // \u7F13\u5B58\u951A\u70B9\u539F\u59CB\u4F4D\u7F6E\n\n useImperativeHandle(ref, () => innerRef.current as HTMLDivElement)\n\n useExposure(innerRef, {\n componentType,\n componentName,\n })\n\n // \u7F13\u5B58\u6240\u6709\u951A\u70B9\u7684\u7EDD\u5BF9\u4F4D\u7F6E\uFF08\u6EDA\u52A8\u5230\u9876\u90E8\u540E\u8BA1\u7B97\uFF0C\u907F\u514D sticky \u5F71\u54CD\uFF09\n const updateAnchorPositions = useCallback(() => {\n if (anchorList.length === 0) return\n\n const originalScrollY = window.scrollY\n window.scrollTo({ top: 0, behavior: 'instant' as ScrollBehavior })\n\n requestAnimationFrame(() => {\n const positions = new Map<string, number>()\n anchorList.forEach(anchor => {\n const element = document.getElementById(anchor.id)\n if (element) {\n const rect = element.getBoundingClientRect()\n positions.set(anchor.id, rect.top + window.scrollY)\n }\n })\n anchorPositionsRef.current = positions\n\n window.scrollTo({ top: originalScrollY, behavior: 'instant' as ScrollBehavior })\n })\n }, [anchorList])\n\n // \u521D\u59CB\u5316\u65F6\u7F13\u5B58\u6240\u6709\u951A\u70B9\u7684\u539F\u59CB\u4F4D\u7F6E\n useEffect(() => {\n if (anchorList.length === 0) return\n\n // \u9875\u9762\u52A0\u8F7D\u540E\u5EF6\u8FDF\u8BA1\u7B97\uFF0C\u786E\u4FDD\u5E03\u5C40\u5B8C\u6210\n const timer = setTimeout(updateAnchorPositions, 100)\n\n return () => clearTimeout(timer)\n }, [anchorList, updateAnchorPositions])\n\n // \u76D1\u542C body \u9AD8\u5EA6\u53D8\u5316\uFF0C\u9AD8\u5EA6\u6539\u53D8\u65F6\u91CD\u65B0\u8BA1\u7B97\u951A\u70B9\u4F4D\u7F6E\n useEffect(() => {\n if (anchorList.length === 0) return\n\n let resizeTimer: ReturnType<typeof setTimeout> | null = null\n\n const observer = new ResizeObserver(() => {\n // debounce\uFF0C\u907F\u514D\u9AD8\u9891\u89E6\u53D1\n if (resizeTimer) clearTimeout(resizeTimer)\n resizeTimer = setTimeout(updateAnchorPositions, 150)\n })\n\n observer.observe(document.body)\n\n return () => {\n observer.disconnect()\n if (resizeTimer) clearTimeout(resizeTimer)\n }\n }, [anchorList, updateAnchorPositions])\n\n // \u6EDA\u52A8\u76D1\u542C\uFF1A\u68C0\u6D4B\u5F53\u524D\u6EDA\u52A8\u4F4D\u7F6E\u5BF9\u5E94\u7684\u951A\u70B9\n useEffect(() => {\n if (anchorList.length === 0) return\n\n const handleScroll = () => {\n // \u5982\u679C\u6B63\u5728\u7A0B\u5E8F\u5316\u6EDA\u52A8\u4E2D\uFF0C\u4F7F\u7528 debounce \u68C0\u6D4B\u6EDA\u52A8\u7ED3\u675F\n if (isScrollingRef.current) {\n // \u6E05\u9664\u4E4B\u524D\u7684\u5B9A\u65F6\u5668\n if (scrollEndTimerRef.current) {\n clearTimeout(scrollEndTimerRef.current)\n }\n // \u8BBE\u7F6E\u65B0\u7684\u5B9A\u65F6\u5668\uFF0C100ms \u6CA1\u6709\u65B0\u6EDA\u52A8\u4E8B\u4EF6\u5219\u8BA4\u4E3A\u6EDA\u52A8\u7ED3\u675F\n scrollEndTimerRef.current = setTimeout(() => {\n isScrollingRef.current = false\n // \u6EDA\u52A8\u7ED3\u675F\u540E\uFF0C\u786E\u4FDD\u9AD8\u4EAE\u505C\u7559\u5728\u76EE\u6807\u951A\u70B9\n if (targetAnchorIdRef.current) {\n setActiveAnchorId(targetAnchorIdRef.current)\n targetAnchorIdRef.current = ''\n }\n }, 100)\n return\n }\n\n const navHeight = innerRef.current?.offsetHeight || 0\n const scrollPosition = window.scrollY + navHeight + scrollOffsetExtra + 10 // 10px \u7F13\u51B2\n\n let currentAnchorId = ''\n\n // \u4F7F\u7528\u7F13\u5B58\u7684\u951A\u70B9\u4F4D\u7F6E\n const positions = anchorPositionsRef.current\n\n // \u904D\u5386\u6240\u6709\u951A\u70B9\uFF0C\u627E\u5230\u5F53\u524D\u6EDA\u52A8\u4F4D\u7F6E\u5BF9\u5E94\u7684\u951A\u70B9\n for (let i = anchorList.length - 1; i >= 0; i--) {\n const anchor = anchorList[i]\n const elementTop = positions.get(anchor.id)\n if (elementTop !== undefined && scrollPosition >= elementTop) {\n currentAnchorId = anchor.id\n break\n }\n }\n\n // \u5982\u679C\u6CA1\u6709\u627E\u5230\u4E14\u7F13\u5B58\u4E2D\u6709\u7B2C\u4E00\u4E2A\u951A\u70B9\u7684\u4F4D\u7F6E\n if (!currentAnchorId && anchorList.length > 0) {\n const firstElementTop = positions.get(anchorList[0].id)\n if (firstElementTop !== undefined && scrollPosition < firstElementTop) {\n currentAnchorId = ''\n }\n }\n\n setActiveAnchorId(currentAnchorId)\n }\n\n // \u5EF6\u8FDF\u521D\u59CB\u5316\uFF0C\u7B49\u5F85\u4F4D\u7F6E\u7F13\u5B58\u5B8C\u6210\n const timer = setTimeout(() => {\n handleScroll()\n }, 200)\n\n window.addEventListener('scroll', handleScroll, { passive: true })\n return () => {\n clearTimeout(timer)\n window.removeEventListener('scroll', handleScroll)\n // \u6E05\u7406\u5B9A\u65F6\u5668\n if (scrollEndTimerRef.current) {\n clearTimeout(scrollEndTimerRef.current)\n }\n }\n }, [anchorList, scrollOffsetExtra])\n\n // \u8BBE\u7F6E\u9875\u9762\u4E2Dheader\u5143\u7D20\u7684position\u4E3Arelative\n useEffect(() => {\n const headerElements = document.querySelectorAll('.header')\n const originalStyles: { element: HTMLElement; originalPosition: string }[] = []\n\n headerElements.forEach(element => {\n const htmlElement = element as HTMLElement\n // \u4FDD\u5B58\u539F\u59CB\u6837\u5F0F\n originalStyles.push({\n element: htmlElement,\n originalPosition: htmlElement.style.position || getComputedStyle(htmlElement).position,\n })\n // \u8BBE\u7F6E\u4E3Arelative\n htmlElement.style.position = 'relative'\n })\n\n // \u6E05\u7406\u51FD\u6570\uFF1A\u6062\u590D\u539F\u59CB\u6837\u5F0F\n return () => {\n originalStyles.forEach(({ element, originalPosition }) => {\n element.style.position = originalPosition === 'static' ? '' : originalPosition\n })\n }\n }, [])\n\n // \u5904\u7406\u951A\u70B9\u70B9\u51FB\u6EDA\u52A8\n const handleAnchorClick = (e: React.MouseEvent, anchorId: string) => {\n e.preventDefault()\n\n // \u4F7F\u7528\u7F13\u5B58\u7684\u4F4D\u7F6E\n const elementAbsoluteTop = anchorPositionsRef.current.get(anchorId)\n if (elementAbsoluteTop === undefined) {\n console.warn(`Cached position for \"${anchorId}\" not found`)\n return\n }\n\n // \u7ACB\u5373\u66F4\u65B0\u9AD8\u4EAE\u72B6\u6001\uFF0C\u907F\u514D\u6EDA\u52A8\u8FC7\u7A0B\u4E2D\u95EA\u70C1\n setActiveAnchorId(anchorId)\n\n // \u8BB0\u5F55\u76EE\u6807\u951A\u70B9\uFF0C\u7528\u4E8E\u6EDA\u52A8\u7ED3\u675F\u540E\u786E\u4FDD\u9AD8\u4EAE\u6B63\u786E\n targetAnchorIdRef.current = anchorId\n\n // \u6807\u8BB0\u6B63\u5728\u7A0B\u5E8F\u5316\u6EDA\u52A8\uFF0C\u6682\u505C\u6EDA\u52A8\u76D1\u542C\n isScrollingRef.current = true\n\n // \u83B7\u53D6\u5BFC\u822A\u680F\u9AD8\u5EA6\n const navHeight = innerRef.current?.offsetHeight || 0\n\n // \u76EE\u6807\u6EDA\u52A8\u4F4D\u7F6E = \u7F13\u5B58\u7684\u5143\u7D20\u7EDD\u5BF9\u4F4D\u7F6E - \u5BFC\u822A\u680F\u9AD8\u5EA6 - \u989D\u5916\u504F\u79FB\n const targetPosition = elementAbsoluteTop - navHeight - scrollOffsetExtra\n\n // \u5E73\u6ED1\u6EDA\u52A8\u5230\u76EE\u6807\u4F4D\u7F6E\n window.scrollTo({\n top: targetPosition,\n behavior: 'smooth',\n })\n\n // \u66F4\u65B0 URL hash\uFF08\u4E0D\u89E6\u53D1\u9875\u9762\u8DF3\u8F6C\uFF09\n window.history.pushState(null, '', `#${anchorId}`)\n\n // \u6CE8\u610F\uFF1A\u6EDA\u52A8\u7ED3\u675F\u68C0\u6D4B\u7531 handleScroll \u4E2D\u7684 debounce \u903B\u8F91\u5904\u7406\n // \u4E0D\u518D\u4F7F\u7528\u56FA\u5B9A 800ms \u8D85\u65F6\uFF0C\u800C\u662F\u68C0\u6D4B\u5B9E\u9645\u6EDA\u52A8\u7ED3\u675F\n }\n\n return (\n <div\n id={id}\n ref={innerRef}\n className={cn(\n 'product-nav text-info-primary bg-container-primary tablet:px-8 laptop:px-16 desktop:px-16 lg-desktop:px-[calc(50%-832px)] !sticky top-0 !z-[51] flex w-full justify-between overflow-hidden px-4 py-0',\n {\n 'aiui-dark': theme === 'dark',\n },\n className\n )}\n >\n <div className=\"product-nav-main desktop:flex-row desktop:gap-[48px] flex w-full flex-col justify-start\">\n {/* Tab Links Section */}\n <div className=\"product-nav-header laptop:w-full desktop:w-fit desktop:gap-[24px] desktop:py-0 flex w-full flex-row items-center justify-between gap-[16px] pt-[14px]\">\n <div className=\"product-nav-tabs flex flex-row items-center gap-[8px]\">\n {tabLinks.map((tabLink, index) => {\n return (\n <div key={tabLink.link || index} className=\"product-nav-tab-item flex items-center gap-[8px]\">\n <a\n href={tabLink.link}\n className={cn(\n 'product-nav-tab-link hover:text-brand-color text-nowrap text-[14px] font-bold tracking-[-0.04em]',\n {\n 'text-[#6D6D6F]': index !== 0,\n 'hidden desktop:block': index === 1,\n }\n )}\n // onClick={() => onShowSpecs?.(false)}\n >\n <span>{tabLink.label}</span>\n </a>\n {index !== tabLinks.length - 1 && (\n <div className=\"product-nav-tab-divider desktop:inline-block hidden h-[14px] w-px bg-[#E4E5E6]\" />\n )}\n </div>\n )\n })}\n\n {/* Mobile Dropdown */}\n {tabLinks.length > 1 && (\n <Popover.Root>\n <Popover.Trigger asChild>\n <button\n className=\"product-nav-dropdown-trigger desktop:hidden -ml-1 inline-block\"\n aria-label=\"More products\"\n >\n <ChevronDownIcon className=\"text-[#1D1D1F]\" />\n </button>\n </Popover.Trigger>\n <Popover.Content\n className=\"product-nav-dropdown-content rounded-[6px] border border-[#E4E5E6] bg-white p-[6px] px-[8px] py-[4px]\"\n style={{\n boxShadow: '0px 4px 8px 0px rgba(0,0,0,0.12)',\n }}\n side=\"bottom\"\n align=\"end\"\n alignOffset={10}\n sideOffset={10}\n >\n {tabLinks.slice(1).map(tabLink => (\n <a\n key={tabLink.link}\n href={tabLink.link}\n className=\"product-nav-dropdown-link hover:text-brand-color text-nowrap\"\n >\n <span>{tabLink.label}</span>\n </a>\n ))}\n </Popover.Content>\n </Popover.Root>\n )}\n </div>\n\n {/* Mobile Actions */}\n <div className=\"product-nav-mobile-actions desktop:hidden desktop:gap-[24px] flex items-center gap-[16px]\">\n {/* {specs?.text && (\n <Text\n size={2}\n onClick={handleSpecsClick}\n className=\"product-nav-specs-button cursor-pointer hover:text-brand-color\"\n >\n {specs.text}\n </Text>\n )} */}\n {textLink?.link && (\n <a\n href={textLink.link}\n target={textLink.target || '_self'}\n className=\"product-nav-text-link hover:text-brand-color cursor-pointer\"\n >\n <Text size={2} className=\"text-nowrap\">\n {textLink.text}\n </Text>\n </a>\n )}\n {buyBtn?.link && (\n <Button as=\"a\" href={buyBtn.link} size=\"sm\" className=\"product-nav-buy-button text-nowrap\">\n {buyBtn.text}\n </Button>\n )}\n </div>\n </div>\n\n {/* Anchor Navigation */}\n <div className=\"product-nav-anchors laptop:w-fit desktop:gap-[24px] desktop:py-[8px] flex w-full items-center gap-[16px] overflow-x-scroll py-[12px] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden\">\n {anchorList.map((anchor, index) => (\n <a\n key={anchor.id}\n href={`#${anchor.id}`}\n className=\"product-nav-anchor-link\"\n onClick={e => {\n // \u5982\u679C\u63D0\u4F9B\u4E86\u81EA\u5B9A\u4E49\u70B9\u51FB\u4E8B\u4EF6,\u4F7F\u7528\u81EA\u5B9A\u4E49\u4E8B\u4EF6\u5E76\u963B\u6B62\u9ED8\u8BA4\u884C\u4E3A\n if (onAnchorClick) {\n e.preventDefault()\n // \u6807\u8BB0\u7A0B\u5E8F\u5316\u6EDA\u52A8\uFF0C\u907F\u514D\u6EDA\u52A8\u8FC7\u7A0B\u4E2D\u9AD8\u4EAE\u95EA\u70C1\n setActiveAnchorId(anchor.id)\n targetAnchorIdRef.current = anchor.id\n isScrollingRef.current = true\n onAnchorClick(anchor, index)\n } else {\n // \u4F7F\u7528\u9ED8\u8BA4\u7684\u951A\u70B9\u6EDA\u52A8\u884C\u4E3A\uFF0C\u5E26\u504F\u79FB\u91CF\n handleAnchorClick(e, anchor.id)\n }\n }}\n >\n <Text size={2} className=\"product-nav-anchor-text text-nowrap\">\n {anchor.label}\n </Text>\n <div\n className={cn(\n 'product-nav-anchor-indicator laptop:top-[12px] desktop:top-[10px] relative top-[12px] h-[4px] w-full bg-transparent',\n {\n '!bg-brand-0': activeAnchorId === anchor.id,\n }\n )}\n />\n </a>\n ))}\n </div>\n </div>\n\n {/* Desktop Actions */}\n <div className=\"product-nav-desktop-actions desktop:flex desktop:gap-[24px] desktop:py-[8px] hidden items-center gap-[16px]\">\n {/* {specs?.text && (\n <Text\n size={2}\n onClick={handleSpecsClick}\n className=\"product-nav-specs-button cursor-pointer text-black hover:text-brand-color\"\n >\n {specs.text}\n </Text>\n )} */}\n {textLink?.link && (\n <a\n href={textLink.link}\n target={textLink.target || '_self'}\n className=\"product-nav-text-link hover:text-brand-color cursor-pointer text-black\"\n >\n <Text size={2} className=\"text-nowrap\">\n {textLink.text}\n </Text>\n </a>\n )}\n {buyBtn?.link && (\n <Button as=\"a\" href={buyBtn.link} size=\"sm\" className=\"product-nav-buy-button text-nowrap\">\n {buyBtn.text}\n </Button>\n )}\n </div>\n </div>\n )\n }\n)\n\nProductNav.displayName = 'ProductNav'\n\nexport default withLayout(ProductNav)\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["ProductNav_exports", "__export", "ProductNav_default", "__toCommonJS", "import_jsx_runtime", "import_react", "import_utils", "import_Styles", "import_components", "import_useExposure", "Popover", "componentType", "componentName", "ChevronDownIcon", "props", "ProductNav", "className", "data", "id", "onAnchorClick", "scrollOffsetExtra", "ref", "tabLinks", "anchorList", "textLink", "buyBtn", "theme", "activeAnchorId", "setActiveAnchorId", "innerRef", "isScrollingRef", "targetAnchorIdRef", "scrollEndTimerRef", "anchorPositionsRef", "updateAnchorPositions", "originalScrollY", "positions", "anchor", "element", "rect", "timer", "resizeTimer", "observer", "handleScroll", "navHeight", "scrollPosition", "currentAnchorId", "i", "elementTop", "firstElementTop", "headerElements", "originalStyles", "htmlElement", "originalPosition", "handleAnchorClick", "anchorId", "elementAbsoluteTop", "targetPosition", "tabLink", "index", "e"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";"use client";var w=Object.create;var c=Object.defineProperty;var E=Object.getOwnPropertyDescriptor;var G=Object.getOwnPropertyNames;var
|
|
1
|
+
"use strict";"use client";var w=Object.create;var c=Object.defineProperty;var E=Object.getOwnPropertyDescriptor;var G=Object.getOwnPropertyNames;var W=Object.getPrototypeOf,D=Object.prototype.hasOwnProperty;var I=(r,a)=>{for(var l in a)c(r,l,{get:a[l],enumerable:!0})},u=(r,a,l,p)=>{if(a&&typeof a=="object"||typeof a=="function")for(let m of G(a))!D.call(r,m)&&m!==l&&c(r,m,{get:()=>a[m],enumerable:!(p=E(a,m))||p.enumerable});return r};var s=(r,a,l)=>(l=r!=null?w(W(r)):{},u(a||!r||!r.__esModule?c(l,"default",{value:r,enumerable:!0}):l,r)),M=r=>u(c({},"__esModule",{value:!0}),r);var F={};I(F,{default:()=>R});module.exports=M(F);var e=require("react/jsx-runtime"),n=require("../../shared/Styles.js"),d=s(require("../../components/tabs.js")),o=require("../../helpers/index.js"),b=s(require("react")),h=s(require("../ShelfDisplay/index.js")),k=s(require("../AccordionCards/index.js")),g=s(require("../Faq/index.js")),N=s(require("../MultiLayoutGraphicBlock/MultiLayoutGraphicBlock.js")),T=s(require("../Title/index.js")),v=s(require("../Graphic/index.js")),L=s(require("../WhyChoose/index.js")),P=s(require("../BrandEquity/index.js")),A=s(require("../BrandCardLink/index.js")),q=s(require("../ImageWithText/index.js"));const y=b.default.forwardRef(({data:r,className:a},l)=>{const{theme:p,shape:m,align:x,tabs:t=[],sectionTitle:f}=r,B=i=>i?.blockType==="ipc-shelfdisplay"?(0,e.jsx)(h.default,{data:i}):i?.blockType==="ipc-multiLayoutGraphicBlock"?(0,e.jsx)(N.default,{data:i}):i?.blockType==="ipc-accordioncards"?(0,e.jsx)(k.default,{data:i}):i?.blockType==="ipc-faq"?(0,e.jsx)(g.default,{data:i}):i?.blockType==="ipc-graphic"?(0,e.jsx)(v.default,{data:i}):i?.blockType==="ipc-whychoose"?(0,e.jsx)(L.default,{data:i}):i?.blockType==="ipc-brand-equity"?(0,e.jsx)(P.default,{data:i}):i?.blockType==="ipc-brand-card-link"?(0,e.jsx)(A.default,{data:i}):i?.blockType==="ImageWithText"?(0,e.jsx)(q.default,{data:i}):null;return(0,e.jsxs)("section",{ref:l,className:(0,o.cn)(p==="dark"?"aiui-dark":"",a),children:[f&&(0,e.jsx)(T.default,{className:"section-title",data:{title:f}}),(0,e.jsxs)(d.Tabs,{shape:m,align:x,defaultValue:t?.[0]?.id||t?.[0]?.tabName,children:[Array.isArray(t)&&t.length>1&&(0,e.jsx)(d.TabsList,{className:"tabs-list",children:t.map(i=>(0,e.jsx)(d.TabsTrigger,{value:i.id||i.tabName,className:"tabs-trigger",children:i.tabName},i.id||i.tabName))}),(Array.isArray(t)?t:[])?.map(i=>(0,e.jsxs)(d.TabsContent,{value:i.id||i.tabName,className:`tabs-content ${t?.length>1?"mt-[24px]":""}`,children:[!(0,o.isLexicalEmpty)(i.caption)||!(0,o.isLexicalEmpty)(i?.subtitle)?(0,e.jsx)(T.default,{className:"tabs-title",data:{caption:i?.caption,subtitle:i?.subtitle}}):null,i.tabContent?.[0]?B(i.tabContent?.[0]):null]},i.id||i.tabName))]})]})});y.displayName="Tabs";var R=(0,n.withLayout)(y);
|
|
2
2
|
//# sourceMappingURL=Tabs.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/biz-components/Tabs/Tabs.tsx"],
|
|
4
|
-
"sourcesContent": ["'use client'\nimport { withLayout } from '../../shared/Styles.js'\nimport * as TabsPrimitive from '../../components/tabs.js'\nimport { cn, isLexicalEmpty } from '../../helpers/index.js'\nimport type { TabsProps } from './types.js'\nimport React from 'react'\nimport ShelfDisplay from '../ShelfDisplay/index.js'\nimport AccordionCards from '../AccordionCards/index.js'\nimport Faq from '../Faq/index.js'\nimport MultiLayoutGraphicBlock from '../MultiLayoutGraphicBlock/MultiLayoutGraphicBlock.js'\nimport Title from '../Title/index.js'\nimport Graphic from '../Graphic/index.js'\nimport WhyChoose from '../WhyChoose/index.js'\nimport BrandEquity from '../BrandEquity/index.js'\nimport BrandCardLink from '../BrandCardLink/index.js'\n\nconst Tabs = React.forwardRef<HTMLDivElement, TabsProps>(({ data, className }, forwardedRef) => {\n const { theme, shape, align, tabs = [], sectionTitle } = data\n\n const renderTabContent = (tabContent: TabsProps['data']['tabs'][number]['tabContent'][number]) => {\n if (tabContent?.blockType === 'ipc-shelfdisplay') {\n return <ShelfDisplay data={tabContent} />\n } else if (tabContent?.blockType === 'ipc-multiLayoutGraphicBlock') {\n return <MultiLayoutGraphicBlock data={tabContent} />\n } else if (tabContent?.blockType === 'ipc-accordioncards') {\n return <AccordionCards data={tabContent} />\n } else if (tabContent?.blockType === 'ipc-faq') {\n return <Faq data={tabContent} />\n } else if (tabContent?.blockType === 'ipc-graphic') {\n return <Graphic data={tabContent} />\n } else if (tabContent?.blockType === 'ipc-whychoose') {\n return <WhyChoose data={tabContent} />\n } else if (tabContent?.blockType === 'ipc-brand-equity') {\n return <BrandEquity data={tabContent} />\n } else if (tabContent?.blockType === 'ipc-brand-card-link') {\n return <BrandCardLink data={tabContent} />\n } else {\n return null\n }\n }\n\n return (\n <section ref={forwardedRef} className={cn(theme === 'dark' ? 'aiui-dark' : '', className)}>\n {sectionTitle && <Title className=\"section-title\" data={{ title: sectionTitle }} />}\n <TabsPrimitive.Tabs shape={shape} align={align} defaultValue={tabs?.[0]?.id || tabs?.[0]?.tabName}>\n {/* <TabsPrimitive.TabsList className=\"tabs-list\">\n {(Array.isArray(tabs) ? tabs : [])?.map(tab => (\n <TabsPrimitive.TabsTrigger\n key={tab.id || tab.tabName}\n value={tab.id || tab.tabName}\n className=\"tabs-trigger\"\n >\n {tab.tabName}\n </TabsPrimitive.TabsTrigger>\n ))}\n </TabsPrimitive.TabsList> */}\n {/* Tab\u4E3A1\u65F6\uFF0C\u4E0D\u5C55\u793Atab\u6309\u94AE */}\n {Array.isArray(tabs) && tabs.length > 1 && (\n <TabsPrimitive.TabsList className=\"tabs-list\">\n {tabs.map(tab => (\n <TabsPrimitive.TabsTrigger\n key={tab.id || tab.tabName}\n value={tab.id || tab.tabName}\n className=\"tabs-trigger\"\n >\n {tab.tabName}\n </TabsPrimitive.TabsTrigger>\n ))}\n </TabsPrimitive.TabsList>\n )}\n {(Array.isArray(tabs) ? tabs : [])?.map((tab: any) => (\n <TabsPrimitive.TabsContent\n key={tab.id || tab.tabName}\n value={tab.id || tab.tabName}\n className={`tabs-content ${tabs?.length > 1 ? 'mt-[24px]' : ''}`}\n >\n {!isLexicalEmpty(tab.caption) || !isLexicalEmpty(tab?.subtitle) ? (\n <Title className=\"tabs-title\" data={{ caption: tab?.caption, subtitle: tab?.subtitle }} />\n ) : null}\n {tab.tabContent?.[0] ? renderTabContent(tab.tabContent?.[0]) : null}\n </TabsPrimitive.TabsContent>\n ))}\n </TabsPrimitive.Tabs>\n </section>\n )\n})\nTabs.displayName = 'Tabs'\nexport default withLayout(Tabs)\n"],
|
|
5
|
-
"mappings": "ukBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,aAAAE,IAAA,eAAAC,EAAAH,
|
|
6
|
-
"names": ["Tabs_exports", "__export", "Tabs_default", "__toCommonJS", "import_jsx_runtime", "import_Styles", "TabsPrimitive", "import_helpers", "import_react", "import_ShelfDisplay", "import_AccordionCards", "import_Faq", "import_MultiLayoutGraphicBlock", "import_Title", "import_Graphic", "import_WhyChoose", "import_BrandEquity", "import_BrandCardLink", "Tabs", "React", "data", "className", "forwardedRef", "theme", "shape", "align", "tabs", "sectionTitle", "renderTabContent", "tabContent", "ShelfDisplay", "MultiLayoutGraphicBlock", "AccordionCards", "Faq", "Graphic", "WhyChoose", "BrandEquity", "BrandCardLink", "Title", "tab"]
|
|
4
|
+
"sourcesContent": ["'use client'\nimport { withLayout } from '../../shared/Styles.js'\nimport * as TabsPrimitive from '../../components/tabs.js'\nimport { cn, isLexicalEmpty } from '../../helpers/index.js'\nimport type { TabsProps } from './types.js'\nimport React from 'react'\nimport ShelfDisplay from '../ShelfDisplay/index.js'\nimport AccordionCards from '../AccordionCards/index.js'\nimport Faq from '../Faq/index.js'\nimport MultiLayoutGraphicBlock from '../MultiLayoutGraphicBlock/MultiLayoutGraphicBlock.js'\nimport Title from '../Title/index.js'\nimport Graphic from '../Graphic/index.js'\nimport WhyChoose from '../WhyChoose/index.js'\nimport BrandEquity from '../BrandEquity/index.js'\nimport BrandCardLink from '../BrandCardLink/index.js'\nimport ImageWithText from '../ImageWithText/index.js'\n\nconst Tabs = React.forwardRef<HTMLDivElement, TabsProps>(({ data, className }, forwardedRef) => {\n const { theme, shape, align, tabs = [], sectionTitle } = data\n\n const renderTabContent = (tabContent: TabsProps['data']['tabs'][number]['tabContent'][number]) => {\n if (tabContent?.blockType === 'ipc-shelfdisplay') {\n return <ShelfDisplay data={tabContent} />\n } else if (tabContent?.blockType === 'ipc-multiLayoutGraphicBlock') {\n return <MultiLayoutGraphicBlock data={tabContent} />\n } else if (tabContent?.blockType === 'ipc-accordioncards') {\n return <AccordionCards data={tabContent} />\n } else if (tabContent?.blockType === 'ipc-faq') {\n return <Faq data={tabContent} />\n } else if (tabContent?.blockType === 'ipc-graphic') {\n return <Graphic data={tabContent} />\n } else if (tabContent?.blockType === 'ipc-whychoose') {\n return <WhyChoose data={tabContent} />\n } else if (tabContent?.blockType === 'ipc-brand-equity') {\n return <BrandEquity data={tabContent} />\n } else if (tabContent?.blockType === 'ipc-brand-card-link') {\n return <BrandCardLink data={tabContent} />\n } else if (tabContent?.blockType === 'ImageWithText') {\n return <ImageWithText data={tabContent} />\n } else {\n return null\n }\n }\n\n return (\n <section ref={forwardedRef} className={cn(theme === 'dark' ? 'aiui-dark' : '', className)}>\n {sectionTitle && <Title className=\"section-title\" data={{ title: sectionTitle }} />}\n <TabsPrimitive.Tabs shape={shape} align={align} defaultValue={tabs?.[0]?.id || tabs?.[0]?.tabName}>\n {/* <TabsPrimitive.TabsList className=\"tabs-list\">\n {(Array.isArray(tabs) ? tabs : [])?.map(tab => (\n <TabsPrimitive.TabsTrigger\n key={tab.id || tab.tabName}\n value={tab.id || tab.tabName}\n className=\"tabs-trigger\"\n >\n {tab.tabName}\n </TabsPrimitive.TabsTrigger>\n ))}\n </TabsPrimitive.TabsList> */}\n {/* Tab\u4E3A1\u65F6\uFF0C\u4E0D\u5C55\u793Atab\u6309\u94AE */}\n {Array.isArray(tabs) && tabs.length > 1 && (\n <TabsPrimitive.TabsList className=\"tabs-list\">\n {tabs.map(tab => (\n <TabsPrimitive.TabsTrigger\n key={tab.id || tab.tabName}\n value={tab.id || tab.tabName}\n className=\"tabs-trigger\"\n >\n {tab.tabName}\n </TabsPrimitive.TabsTrigger>\n ))}\n </TabsPrimitive.TabsList>\n )}\n {(Array.isArray(tabs) ? tabs : [])?.map((tab: any) => (\n <TabsPrimitive.TabsContent\n key={tab.id || tab.tabName}\n value={tab.id || tab.tabName}\n className={`tabs-content ${tabs?.length > 1 ? 'mt-[24px]' : ''}`}\n >\n {!isLexicalEmpty(tab.caption) || !isLexicalEmpty(tab?.subtitle) ? (\n <Title className=\"tabs-title\" data={{ caption: tab?.caption, subtitle: tab?.subtitle }} />\n ) : null}\n {tab.tabContent?.[0] ? renderTabContent(tab.tabContent?.[0]) : null}\n </TabsPrimitive.TabsContent>\n ))}\n </TabsPrimitive.Tabs>\n </section>\n )\n})\nTabs.displayName = 'Tabs'\nexport default withLayout(Tabs)\n"],
|
|
5
|
+
"mappings": "ukBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,aAAAE,IAAA,eAAAC,EAAAH,GAsBa,IAAAI,EAAA,6BArBbC,EAA2B,kCAC3BC,EAA+B,uCAC/BC,EAAmC,kCAEnCC,EAAkB,oBAClBC,EAAyB,uCACzBC,EAA2B,yCAC3BC,EAAgB,8BAChBC,EAAoC,oEACpCC,EAAkB,gCAClBC,EAAoB,kCACpBC,EAAsB,oCACtBC,EAAwB,sCACxBC,EAA0B,wCAC1BC,EAA0B,wCAE1B,MAAMC,EAAO,EAAAC,QAAM,WAAsC,CAAC,CAAE,KAAAC,EAAM,UAAAC,CAAU,EAAGC,IAAiB,CAC9F,KAAM,CAAE,MAAAC,EAAO,MAAAC,EAAO,MAAAC,EAAO,KAAAC,EAAO,CAAC,EAAG,aAAAC,CAAa,EAAIP,EAEnDQ,EAAoBC,GACpBA,GAAY,YAAc,sBACrB,OAAC,EAAAC,QAAA,CAAa,KAAMD,EAAY,EAC9BA,GAAY,YAAc,iCAC5B,OAAC,EAAAE,QAAA,CAAwB,KAAMF,EAAY,EACzCA,GAAY,YAAc,wBAC5B,OAAC,EAAAG,QAAA,CAAe,KAAMH,EAAY,EAChCA,GAAY,YAAc,aAC5B,OAAC,EAAAI,QAAA,CAAI,KAAMJ,EAAY,EACrBA,GAAY,YAAc,iBAC5B,OAAC,EAAAK,QAAA,CAAQ,KAAML,EAAY,EACzBA,GAAY,YAAc,mBAC5B,OAAC,EAAAM,QAAA,CAAU,KAAMN,EAAY,EAC3BA,GAAY,YAAc,sBAC5B,OAAC,EAAAO,QAAA,CAAY,KAAMP,EAAY,EAC7BA,GAAY,YAAc,yBAC5B,OAAC,EAAAQ,QAAA,CAAc,KAAMR,EAAY,EAC/BA,GAAY,YAAc,mBAC5B,OAAC,EAAAS,QAAA,CAAc,KAAMT,EAAY,EAEjC,KAIX,SACE,QAAC,WAAQ,IAAKP,EAAc,aAAW,MAAGC,IAAU,OAAS,YAAc,GAAIF,CAAS,EACrF,UAAAM,MAAgB,OAAC,EAAAY,QAAA,CAAM,UAAU,gBAAgB,KAAM,CAAE,MAAOZ,CAAa,EAAG,KACjF,QAACtB,EAAc,KAAd,CAAmB,MAAOmB,EAAO,MAAOC,EAAO,aAAcC,IAAO,CAAC,GAAG,IAAMA,IAAO,CAAC,GAAG,QAavF,gBAAM,QAAQA,CAAI,GAAKA,EAAK,OAAS,MACpC,OAACrB,EAAc,SAAd,CAAuB,UAAU,YAC/B,SAAAqB,EAAK,IAAIc,MACR,OAACnC,EAAc,YAAd,CAEC,MAAOmC,EAAI,IAAMA,EAAI,QACrB,UAAU,eAET,SAAAA,EAAI,SAJAA,EAAI,IAAMA,EAAI,OAKrB,CACD,EACH,GAEA,MAAM,QAAQd,CAAI,EAAIA,EAAO,CAAC,IAAI,IAAKc,MACvC,QAACnC,EAAc,YAAd,CAEC,MAAOmC,EAAI,IAAMA,EAAI,QACrB,UAAW,gBAAgBd,GAAM,OAAS,EAAI,YAAc,EAAE,GAE7D,cAAC,kBAAec,EAAI,OAAO,GAAK,IAAC,kBAAeA,GAAK,QAAQ,KAC5D,OAAC,EAAAD,QAAA,CAAM,UAAU,aAAa,KAAM,CAAE,QAASC,GAAK,QAAS,SAAUA,GAAK,QAAS,EAAG,EACtF,KACHA,EAAI,aAAa,CAAC,EAAIZ,EAAiBY,EAAI,aAAa,CAAC,CAAC,EAAI,OAP1DA,EAAI,IAAMA,EAAI,OAQrB,CACD,GACH,GACF,CAEJ,CAAC,EACDtB,EAAK,YAAc,OACnB,IAAOjB,KAAQ,cAAWiB,CAAI",
|
|
6
|
+
"names": ["Tabs_exports", "__export", "Tabs_default", "__toCommonJS", "import_jsx_runtime", "import_Styles", "TabsPrimitive", "import_helpers", "import_react", "import_ShelfDisplay", "import_AccordionCards", "import_Faq", "import_MultiLayoutGraphicBlock", "import_Title", "import_Graphic", "import_WhyChoose", "import_BrandEquity", "import_BrandCardLink", "import_ImageWithText", "Tabs", "React", "data", "className", "forwardedRef", "theme", "shape", "align", "tabs", "sectionTitle", "renderTabContent", "tabContent", "ShelfDisplay", "MultiLayoutGraphicBlock", "AccordionCards", "Faq", "Graphic", "WhyChoose", "BrandEquity", "BrandCardLink", "ImageWithText", "Title", "tab"]
|
|
7
7
|
}
|
|
@@ -7,6 +7,7 @@ import type { GraphicProps } from '../Graphic/index.js';
|
|
|
7
7
|
import type { WhyChooseProps } from '../WhyChoose/types.js';
|
|
8
8
|
import type { BrandEquityProps } from '../BrandEquity/types.js';
|
|
9
9
|
import type { BrandCardLinkProps } from '../BrandCardLink/types.js';
|
|
10
|
+
import type { ImageWithTextProps } from '../ImageWithText/types.js';
|
|
10
11
|
export type TabsProps = {
|
|
11
12
|
data: {
|
|
12
13
|
sectionTitle?: string;
|
|
@@ -32,6 +33,8 @@ export type TabsProps = {
|
|
|
32
33
|
blockType: 'ipc-brand-equity';
|
|
33
34
|
})[] | (BrandCardLinkProps['data'] & {
|
|
34
35
|
blockType: 'ipc-brand-card-link';
|
|
36
|
+
})[] | (ImageWithTextProps['data'] & {
|
|
37
|
+
blockType: 'ImageWithText';
|
|
35
38
|
})[];
|
|
36
39
|
}[];
|
|
37
40
|
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var t=Object.defineProperty;var
|
|
1
|
+
"use strict";var t=Object.defineProperty;var i=Object.getOwnPropertyDescriptor;var s=Object.getOwnPropertyNames;var y=Object.prototype.hasOwnProperty;var c=(o,p,e,r)=>{if(p&&typeof p=="object"||typeof p=="function")for(let a of s(p))!y.call(o,a)&&a!==e&&t(o,a,{get:()=>p[a],enumerable:!(r=i(p,a))||r.enumerable});return o};var d=o=>c(t({},"__esModule",{value:!0}),o);var l={};module.exports=d(l);
|
|
2
2
|
//# sourceMappingURL=types.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/biz-components/Tabs/types.ts"],
|
|
4
|
-
"sourcesContent": ["import type { Align, Shape, Theme } from '../../types/props.js'\nimport type { MultiLayoutGraphicBlockProps } from '../MultiLayoutGraphicBlock/types.js'\nimport type { ShelfDisplayProps } from '../ShelfDisplay/shelfDisplay.js'\nimport type { AccordionCardsType } from '../AccordionCards/index.js'\nimport type { FaqProps } from '../Faq/types.js'\nimport type { GraphicProps } from '../Graphic/index.js'\nimport type { WhyChooseProps } from '../WhyChoose/types.js'\nimport type { BrandEquityProps } from '../BrandEquity/types.js'\nimport type { BrandCardLinkProps } from '../BrandCardLink/types.js'\n\nexport type TabsProps = {\n data: {\n sectionTitle?: string\n theme: Theme\n shape: Shape\n align: Align\n tabs: {\n id: string\n tabName: string\n tabContent:\n | (ShelfDisplayProps['data'] & { blockType: 'ipc-shelfdisplay' })[]\n | (MultiLayoutGraphicBlockProps['data'] & { blockType: 'ipc-multiLayoutGraphicBlock' })[]\n | (AccordionCardsType['data'] & { blockType: 'ipc-accordioncards' })[]\n | (FaqProps['data'] & { blockType: 'ipc-faq' })[]\n | (GraphicProps['data'] & { blockType: 'ipc-graphic' })[]\n | (WhyChooseProps['data'] & { blockType: 'ipc-whychoose' })[]\n | (BrandEquityProps['data'] & { blockType: 'ipc-brand-equity' })[]\n | (BrandCardLinkProps['data'] & { blockType: 'ipc-brand-card-link' })[]\n }[]\n }\n className?: string\n}\n"],
|
|
4
|
+
"sourcesContent": ["import type { Align, Shape, Theme } from '../../types/props.js'\nimport type { MultiLayoutGraphicBlockProps } from '../MultiLayoutGraphicBlock/types.js'\nimport type { ShelfDisplayProps } from '../ShelfDisplay/shelfDisplay.js'\nimport type { AccordionCardsType } from '../AccordionCards/index.js'\nimport type { FaqProps } from '../Faq/types.js'\nimport type { GraphicProps } from '../Graphic/index.js'\nimport type { WhyChooseProps } from '../WhyChoose/types.js'\nimport type { BrandEquityProps } from '../BrandEquity/types.js'\nimport type { BrandCardLinkProps } from '../BrandCardLink/types.js'\nimport type { ImageWithTextProps } from '../ImageWithText/types.js'\n\nexport type TabsProps = {\n data: {\n sectionTitle?: string\n theme: Theme\n shape: Shape\n align: Align\n tabs: {\n id: string\n tabName: string\n tabContent:\n | (ShelfDisplayProps['data'] & { blockType: 'ipc-shelfdisplay' })[]\n | (MultiLayoutGraphicBlockProps['data'] & { blockType: 'ipc-multiLayoutGraphicBlock' })[]\n | (AccordionCardsType['data'] & { blockType: 'ipc-accordioncards' })[]\n | (FaqProps['data'] & { blockType: 'ipc-faq' })[]\n | (GraphicProps['data'] & { blockType: 'ipc-graphic' })[]\n | (WhyChooseProps['data'] & { blockType: 'ipc-whychoose' })[]\n | (BrandEquityProps['data'] & { blockType: 'ipc-brand-equity' })[]\n | (BrandCardLinkProps['data'] & { blockType: 'ipc-brand-card-link' })[]\n | (ImageWithTextProps['data'] & { blockType: 'ImageWithText' })[]\n }[]\n }\n className?: string\n}\n"],
|
|
5
5
|
"mappings": "+WAAA,IAAAA,EAAA,kBAAAC,EAAAD",
|
|
6
6
|
"names": ["types_exports", "__toCommonJS"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var c=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var $=Object.prototype.hasOwnProperty;var m=(t,n)=>{for(var r in n)c(t,r,{get:n[r],enumerable:!0})},R=(t,n,r,s)=>{if(n&&typeof n=="object"||typeof n=="function")for(let e of f(n))!$.call(t,e)&&e!==r&&c(t,e,{get:()=>n[e],enumerable:!(s=p(n,e))||s.enumerable});return t};var S=t=>R(c({},"__esModule",{value:!0}),t);var d={};m(d,{buildTrackingRef:()=>U,trackUrlRef:()=>y});module.exports=S(d);const y=(t="",n="")=>{try{if(n=n.replace(/Activity Page_/g,""),/^https?:\/\//.test(t)){const s=new URL(t);return s.searchParams.has("ref")?t:(s.searchParams.set("ref",n),s.toString())}else{const[s,e=""]=t.split("#"),[o
|
|
1
|
+
"use strict";var c=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var $=Object.prototype.hasOwnProperty;var m=(t,n)=>{for(var r in n)c(t,r,{get:n[r],enumerable:!0})},R=(t,n,r,s)=>{if(n&&typeof n=="object"||typeof n=="function")for(let e of f(n))!$.call(t,e)&&e!==r&&c(t,e,{get:()=>n[e],enumerable:!(s=p(n,e))||s.enumerable});return t};var S=t=>R(c({},"__esModule",{value:!0}),t);var d={};m(d,{buildTrackingRef:()=>U,trackUrlRef:()=>y});module.exports=S(d);const y=(t="",n="")=>{try{if(t?.startsWith("#"))return t;if(n=n.replace(/Activity Page_/g,""),/^https?:\/\//.test(t)){const s=new URL(t);return s.searchParams.has("ref")?t:(s.searchParams.set("ref",n),s.toString())}else{const[s,e=""]=t.split("#"),[a,o=""]=s.split("?"),i=new URLSearchParams(o);if(i.has("ref"))return t;i.set("ref",n);const g=i.toString()?`?${i.toString()}`:"",h=e?`#${e}`:"";return`${a}${g}${h}`}}catch{return/[?&]ref=/.test(t)?t:t?.includes("?")?t+"&ref="+encodeURIComponent(n):t+"?ref="+encodeURIComponent(n)}},U=(t,n,r)=>`${t}_${n}_${r}`;
|
|
2
2
|
//# sourceMappingURL=trackUrlRef.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/shared/trackUrlRef.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * \u7ED9 url \u6216 path \u6DFB\u52A0 ref \u53C2\u6570\n * @param url \u539F\u59CB url \u6216 path\n * @param refValue ref \u53C2\u6570\u7684\u503C\n * @returns \u6DFB\u52A0\u4E86 ref \u53C2\u6570\u7684\u65B0 url\n */\nexport const trackUrlRef = (url: string = '', refValue: string = ''): string => {\n try {\n // \u5386\u53F2\u57CB\u70B9\u95EE\u9898\u5904\u7406\uFF0C\u53BB\u6389pageHandle \u7684\u524D\u7F00\n refValue = refValue.replace(/Activity Page_/g, '')\n // \u5224\u65AD\u662F\u5426\u4E3A\u7EDD\u5BF9 URL\n const hasOrigin = /^https?:\\/\\//.test(url)\n if (hasOrigin) {\n const u = new URL(url)\n // \u5982\u679C\u5DF2\u6709 ref \u53C2\u6570\uFF0C\u8DF3\u8FC7\u8986\u76D6\n if (u.searchParams.has('ref')) {\n return url\n }\n u.searchParams.set('ref', refValue)\n return u.toString()\n } else {\n const [pathWithQuery, hash = ''] = url.split('#')\n const [path, query = ''] = pathWithQuery.split('?')\n const params = new URLSearchParams(query)\n // \u5982\u679C\u5DF2\u6709 ref \u53C2\u6570\uFF0C\u8DF3\u8FC7\u8986\u76D6\n if (params.has('ref')) {\n return url\n }\n params.set('ref', refValue)\n const queryString = params.toString() ? `?${params.toString()}` : ''\n const hashString = hash ? `#${hash}` : ''\n return `${path}${queryString}${hashString}`\n }\n } catch (e) {\n // \u5982\u679C\u5DF2\u6709 ref \u53C2\u6570\uFF0C\u8DF3\u8FC7\u8986\u76D6\n if (/[?&]ref=/.test(url)) {\n return url\n }\n if (url?.includes('?')) {\n return url + '&ref=' + encodeURIComponent(refValue)\n }\n return url + '?ref=' + encodeURIComponent(refValue)\n }\n}\n\n/**\n * \u6784\u9020\u6807\u51C6\u5316 ref \u8FFD\u8E2A\u5B57\u7B26\u4E32\n * \u683C\u5F0F: `${pageHandle}_${componentType}_${componentName}`\n * @param pageHandle \u9875\u9762\u6807\u8BC6\uFF0C\u5982 'soundcore-lottery'\n * @param componentType \u7EC4\u4EF6\u7C7B\u578B\uFF0C\u5982 'copy'\n * @param componentName \u7EC4\u4EF6\u540D\u79F0\uFF0C\u5982 'lottery_banner'\n * @returns \u62FC\u63A5\u540E\u7684 ref \u5B57\u7B26\u4E32\uFF0C\u5982 'soundcore-lottery_copy_lottery_banner'\n */\nexport const buildTrackingRef = (pageHandle: string, componentType: string, componentName: string): string => {\n return `${pageHandle}_${componentType}_${componentName}`\n}\n"],
|
|
5
|
-
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,sBAAAE,EAAA,gBAAAC,IAAA,eAAAC,EAAAJ,GAMO,MAAMG,EAAc,CAACE,EAAc,GAAIC,EAAmB,KAAe,CAC9E,GAAI,
|
|
4
|
+
"sourcesContent": ["/**\n * \u7ED9 url \u6216 path \u6DFB\u52A0 ref \u53C2\u6570\n * @param url \u539F\u59CB url \u6216 path\n * @param refValue ref \u53C2\u6570\u7684\u503C\n * @returns \u6DFB\u52A0\u4E86 ref \u53C2\u6570\u7684\u65B0 url\n */\nexport const trackUrlRef = (url: string = '', refValue: string = ''): string => {\n try {\n // \u5904\u7406\u951A\u70B9\n if (url?.startsWith('#')) return url\n // \u5386\u53F2\u57CB\u70B9\u95EE\u9898\u5904\u7406\uFF0C\u53BB\u6389pageHandle \u7684\u524D\u7F00\n refValue = refValue.replace(/Activity Page_/g, '')\n // \u5224\u65AD\u662F\u5426\u4E3A\u7EDD\u5BF9 URL\n const hasOrigin = /^https?:\\/\\//.test(url)\n if (hasOrigin) {\n const u = new URL(url)\n // \u5982\u679C\u5DF2\u6709 ref \u53C2\u6570\uFF0C\u8DF3\u8FC7\u8986\u76D6\n if (u.searchParams.has('ref')) {\n return url\n }\n u.searchParams.set('ref', refValue)\n return u.toString()\n } else {\n const [pathWithQuery, hash = ''] = url.split('#')\n const [path, query = ''] = pathWithQuery.split('?')\n const params = new URLSearchParams(query)\n // \u5982\u679C\u5DF2\u6709 ref \u53C2\u6570\uFF0C\u8DF3\u8FC7\u8986\u76D6\n if (params.has('ref')) {\n return url\n }\n params.set('ref', refValue)\n const queryString = params.toString() ? `?${params.toString()}` : ''\n const hashString = hash ? `#${hash}` : ''\n return `${path}${queryString}${hashString}`\n }\n } catch (e) {\n // \u5982\u679C\u5DF2\u6709 ref \u53C2\u6570\uFF0C\u8DF3\u8FC7\u8986\u76D6\n if (/[?&]ref=/.test(url)) {\n return url\n }\n if (url?.includes('?')) {\n return url + '&ref=' + encodeURIComponent(refValue)\n }\n return url + '?ref=' + encodeURIComponent(refValue)\n }\n}\n\n/**\n * \u6784\u9020\u6807\u51C6\u5316 ref \u8FFD\u8E2A\u5B57\u7B26\u4E32\n * \u683C\u5F0F: `${pageHandle}_${componentType}_${componentName}`\n * @param pageHandle \u9875\u9762\u6807\u8BC6\uFF0C\u5982 'soundcore-lottery'\n * @param componentType \u7EC4\u4EF6\u7C7B\u578B\uFF0C\u5982 'copy'\n * @param componentName \u7EC4\u4EF6\u540D\u79F0\uFF0C\u5982 'lottery_banner'\n * @returns \u62FC\u63A5\u540E\u7684 ref \u5B57\u7B26\u4E32\uFF0C\u5982 'soundcore-lottery_copy_lottery_banner'\n */\nexport const buildTrackingRef = (pageHandle: string, componentType: string, componentName: string): string => {\n return `${pageHandle}_${componentType}_${componentName}`\n}\n"],
|
|
5
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,sBAAAE,EAAA,gBAAAC,IAAA,eAAAC,EAAAJ,GAMO,MAAMG,EAAc,CAACE,EAAc,GAAIC,EAAmB,KAAe,CAC9E,GAAI,CAEF,GAAID,GAAK,WAAW,GAAG,EAAG,OAAOA,EAKjC,GAHAC,EAAWA,EAAS,QAAQ,kBAAmB,EAAE,EAE/B,eAAe,KAAKD,CAAG,EAC1B,CACb,MAAME,EAAI,IAAI,IAAIF,CAAG,EAErB,OAAIE,EAAE,aAAa,IAAI,KAAK,EACnBF,GAETE,EAAE,aAAa,IAAI,MAAOD,CAAQ,EAC3BC,EAAE,SAAS,EACpB,KAAO,CACL,KAAM,CAACC,EAAeC,EAAO,EAAE,EAAIJ,EAAI,MAAM,GAAG,EAC1C,CAACK,EAAMC,EAAQ,EAAE,EAAIH,EAAc,MAAM,GAAG,EAC5CI,EAAS,IAAI,gBAAgBD,CAAK,EAExC,GAAIC,EAAO,IAAI,KAAK,EAClB,OAAOP,EAETO,EAAO,IAAI,MAAON,CAAQ,EAC1B,MAAMO,EAAcD,EAAO,SAAS,EAAI,IAAIA,EAAO,SAAS,CAAC,GAAK,GAC5DE,EAAaL,EAAO,IAAIA,CAAI,GAAK,GACvC,MAAO,GAAGC,CAAI,GAAGG,CAAW,GAAGC,CAAU,EAC3C,CACF,MAAY,CAEV,MAAI,WAAW,KAAKT,CAAG,EACdA,EAELA,GAAK,SAAS,GAAG,EACZA,EAAM,QAAU,mBAAmBC,CAAQ,EAE7CD,EAAM,QAAU,mBAAmBC,CAAQ,CACpD,CACF,EAUaJ,EAAmB,CAACa,EAAoBC,EAAuBC,IACnE,GAAGF,CAAU,IAAIC,CAAa,IAAIC,CAAa",
|
|
6
6
|
"names": ["trackUrlRef_exports", "__export", "buildTrackingRef", "trackUrlRef", "__toCommonJS", "url", "refValue", "u", "pathWithQuery", "hash", "path", "query", "params", "queryString", "hashString", "pageHandle", "componentType", "componentName"]
|
|
7
7
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use client";import{Fragment as W,jsx as a,jsxs as x}from"react/jsx-runtime";import*as
|
|
1
|
+
"use client";import{Fragment as W,jsx as a,jsxs as x}from"react/jsx-runtime";import*as k from"react";import{forwardRef as $,useEffect as R,useState as C}from"react";import{cn as r}from"../../helpers/utils.js";import{Heading as P}from"../../components/heading.js";import{Text as D}from"../../components/text.js";import _ from"../../components/picture.js";import{useExposure as I}from"../../hooks/useExposure.js";import{withLayout as A}from"../../shared/Styles.js";import{trackUrlRef as z}from"../../shared/trackUrlRef.js";import{getLocalizedPath as L}from"../../helpers/utils.js";import{useAiuiContext as B}from"../AiuiProvider/index.js";import{useMediaQuery as E}from"react-responsive";import{Swiper as H,SwiperSlide as M}from"swiper/react";import{Pagination as j}from"swiper/modules";import"swiper/css";import"swiper/css/pagination";const V="content",f="image_text_overlay",h="image",w="image-text-overlay-mobile-pagination",v={default:767,tablet:1024,laptop:1439,desktop:1919,lgDesktop:9999},F=e=>{if(!e)return"";const t=[];return e.lgDesktop?.url&&t.push(`${e.lgDesktop.url}`),e.desktop?.url&&t.push(`${e.desktop.url} ${v.desktop}`),e.laptop?.url&&t.push(`${e.laptop.url} ${v.laptop}`),e.tablet?.url&&t.push(`${e.tablet.url} ${v.tablet}`),e.default?.url&&t.push(`${e.default.url} ${v.default}`),t.join(", ")},G=e=>e&&(e.default?.alt||e.tablet?.alt||e.laptop?.alt||e.desktop?.alt||e.lgDesktop?.alt)||"",Q=(e,t)=>{const s=[];for(let l=0;l<e.length;l+=t)s.push(e.slice(l,l+t));return s},q=e=>{switch(e){case 2:return"grid-cols-1 tablet:grid-cols-2";case 3:return"grid-cols-1 tablet:grid-cols-2 laptop:grid-cols-3";case 4:return"grid-cols-1 tablet:grid-cols-2";case 5:return"grid-cols-1 tablet:grid-cols-2 laptop:grid-cols-6";case 6:return"grid-cols-1 tablet:grid-cols-2 desktop:grid-cols-3";default:return e<=1?"grid-cols-1":"grid-cols-1 laptop:grid-cols-3"}},K=(e,t)=>t===5?e<2?"laptop:col-span-3":"laptop:col-span-2":"",U=(e,t)=>{switch(e){case 2:case 4:return"aspect-[358/240] tablet:aspect-[346/240] laptop:aspect-[440/192] desktop:aspect-[648/256] lg-desktop:aspect-[824/320]";case 3:return"aspect-[358/240] tablet:aspect-[346/240] laptop:aspect-[288/192] desktop:aspect-[427/256] lg-desktop:aspect-[544/320]";case 5:return t<2?"aspect-[358/240] tablet:aspect-[346/240] laptop:aspect-[440/192] desktop:aspect-[648/256] lg-desktop:aspect-[824/320]":"aspect-[358/240] tablet:aspect-[346/240] laptop:aspect-[288/192] desktop:aspect-[427/256] lg-desktop:aspect-[544/320]";case 6:return"aspect-[358/240] tablet:aspect-[346/240] laptop:aspect-[440/192] desktop:aspect-[427/256] lg-desktop:aspect-[544/320]";default:return e<=1?"aspect-[358/240]":"aspect-[358/240] tablet:aspect-[346/240] laptop:aspect-[440/192] desktop:aspect-[648/256] lg-desktop:aspect-[824/320]"}},O=({item:e,index:t,count:s,classNames:l})=>{const d=F(e.backgroundImage),c=G(e.backgroundImage),i=K(t,s),u=k.useRef(null),{locale:y="us",pageHandle:m}=B();I(u,{componentType:h,componentName:f,position:t+1,componentTitle:e.title,componentDescription:e.subtitle});const o=e.link?L(e.link,y):void 0,g=o?z(o,`${m??""}_${h}_${f}`):void 0,b=`${e.title}#${e.subtitle||""}#${e.title}`,n=U(s,t);return x("div",{ref:u,className:r("image-text-overlay-card rounded-card",{"aiui-dark":e.theme==="dark"},"desktop:p-6 lg-desktop:p-8 group relative flex flex-col items-start justify-end overflow-hidden p-4",n,i,l?.card),children:[g&&a("a",{href:g,className:"absolute inset-0 z-20","aria-label":e.title,"data-headless-type-name":`${h}#${f}`,"data-headless-title-desc-button":b}),e.backgroundImage?.isShowVideo?x(W,{children:[e.backgroundImage?.mobileVideo&&a("video",{className:r("image-text-overlay-card-image","laptop:hidden absolute inset-0 size-full object-cover",l?.cardImage),src:e.backgroundImage.mobileVideo.url,autoPlay:!0,muted:!0,loop:!0,playsInline:!0}),e.backgroundImage?.desktopVideo&&a("video",{className:r("image-text-overlay-card-image","laptop:block absolute inset-0 hidden size-full object-cover",l?.cardImage),src:e.backgroundImage.desktopVideo.url,autoPlay:!0,muted:!0,loop:!0,playsInline:!0})]}):d&&a(_,{source:d,alt:c||e.title,className:r("image-text-overlay-card-image","absolute inset-0 size-full",l?.cardImage),imgClassName:"size-full object-cover cursor-pointer transition-all duration-300 group-hover:scale-105"}),x("div",{className:r("image-text-overlay-card-content","relative z-10 flex w-full flex-col gap-1",l?.cardContent),children:[a(P,{as:"h4",size:2,weight:"bold",className:r("image-text-overlay-card-title text-info-primary line-clamp-1","w-full leading-[1.2] tracking-[-0.04em]","desktop:text-xl lg-desktop:text-2xl text-lg",l?.cardTitle),children:e.title}),e.subtitle&&a(D,{as:"p",size:"none",weight:"bold",className:r("image-text-overlay-card-subtitle text-info-primary line-clamp-1","w-full truncate leading-[1.4] tracking-[-0.02em]","lg-desktop:text-base text-sm",s<=3&&"lg-desktop:text-lg",l?.cardSubtitle),children:e.subtitle})]})]})},S=$(({data:e,className:t,classNames:s={},...l},d)=>{const c=k.useRef(null),{items:i=[]}=e,[u,y]=C(!1),m=E({query:"(max-width: 767px)"});if(R(()=>{y(m)},[m]),I(c,{componentType:V,componentName:f}),k.useImperativeHandle(d,()=>c.current),!i.length)return null;const o=i.length,g=o>3&&u,b=Q(i,3);return a("div",{ref:c,className:r("image-text-overlay-root",t,s.root),"data-ui-component-id":"ImageTextOverlay",...l,children:g?x("div",{className:"image-text-overlay-mobile-swiper relative pb-8",children:[a(H,{className:"w-full [&_.swiper-slide]:!h-auto [&_.swiper-wrapper]:items-stretch",modules:[j],slidesPerView:1,pagination:{clickable:!0,el:`.${w}`,bulletClass:"image-text-overlay-bullet",bulletActiveClass:"image-text-overlay-bullet-active"},spaceBetween:16,children:b.map((n,p)=>a(M,{className:"!h-auto",children:a("div",{className:"flex flex-col gap-4",children:n.map((N,T)=>a(O,{item:N,index:p*3+T,count:o,classNames:s},p*3+T))})},p))}),a("div",{className:"absolute inset-x-0 bottom-0 z-10 flex justify-center",children:a("div",{className:r(w,"flex items-center justify-center gap-2 text-center","[&_.swiper-pagination-bullet]:m-0","[&_.swiper-pagination-bullet]:shrink-0","[&_.swiper-pagination-bullet]:opacity-100")})}),a("style",{children:`
|
|
2
2
|
.image-text-overlay-bullet {
|
|
3
3
|
display: inline-block;
|
|
4
4
|
width: 8px;
|
|
@@ -14,5 +14,5 @@
|
|
|
14
14
|
border-radius: 9999px;
|
|
15
15
|
background: #080A0F;
|
|
16
16
|
}
|
|
17
|
-
`})]}):a("div",{className:
|
|
17
|
+
`})]}):a("div",{className:r("image-text-overlay-grid","grid gap-4",q(o),s.grid),children:i.map((n,p)=>a(O,{item:n,index:p,count:o,classNames:s},p))})})});S.displayName="ImageTextOverlay";var ue=A(S);export{ue as default};
|
|
18
18
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/biz-components/ImageTextOverlay/index.tsx"],
|
|
4
|
-
"sourcesContent": ["'use client'\nimport * as React from 'react'\nimport { forwardRef, useEffect, useRef, useState } from 'react'\nimport { cn } from '../../helpers/utils.js'\nimport { Heading } from '../../components/heading.js'\nimport { Text } from '../../components/text.js'\nimport Picture from '../../components/picture.js'\nimport { useExposure } from '../../hooks/useExposure.js'\nimport { withLayout } from '../../shared/Styles.js'\nimport { trackUrlRef } from '../../shared/trackUrlRef.js'\nimport type {\n ImageTextOverlayProps,\n ImageTextOverlayItem,\n ImageTextOverlaySemanticName,\n ImageTextOverlayData,\n ImageTextOverlayBackgroundImage,\n} from './types.js'\nimport { getLocalizedPath } from '../../helpers/utils.js'\nimport { useAiuiContext } from '../AiuiProvider/index.js'\nimport { useMediaQuery } from 'react-responsive'\nimport { Swiper, SwiperSlide } from 'swiper/react'\nimport { Pagination } from 'swiper/modules'\nimport 'swiper/css'\nimport 'swiper/css/pagination'\n\nexport type {\n ImageTextOverlayProps,\n ImageTextOverlayItem,\n ImageTextOverlaySemanticName,\n ImageTextOverlayData,\n ImageTextOverlayBackgroundImage,\n}\n\nconst componentType = 'content'\nconst componentName = 'image_text_overlay'\nconst imageComponentType = 'image'\nconst MOBILE_SWIPER_PAGINATION_CLASS = 'image-text-overlay-mobile-pagination'\n\n/**\n * \u65AD\u70B9\u914D\u7F6E\uFF08\u4E0E Tailwind \u65AD\u70B9\u5BF9\u5E94\uFF09\n * Picture \u7EC4\u4EF6\u4F7F\u7528 max-width \u5A92\u4F53\u67E5\u8BE2\uFF0C\u6240\u4EE5\u9700\u8981\u6309\u4ECE\u5927\u5230\u5C0F\u7684\u987A\u5E8F\u6392\u5217\n */\nconst BREAKPOINTS = {\n default: 767, // <768px (\u79FB\u52A8\u7AEF)\n tablet: 1024, // 768px - 1024px\n laptop: 1439, // 1025px - 1439px\n desktop: 1919, // 1440px - 1919px\n lgDesktop: 9999, // \u22651920px\n} as const\n\n/**\n * \u5C06\u54CD\u5E94\u5F0F\u80CC\u666F\u56FE\u7247\u5BF9\u8C61\u8F6C\u6362\u4E3A Picture \u7EC4\u4EF6\u7684 source \u5B57\u7B26\u4E32\n * \u683C\u5F0F: \"lgDesktopUrl, desktopUrl 1919, laptopUrl 1439, tabletUrl 1024, defaultUrl 767\"\n */\nconst buildResponsiveSource = (backgroundImage?: ImageTextOverlayBackgroundImage): string => {\n if (!backgroundImage) return ''\n\n const sources: string[] = []\n\n // lgDesktop \u4F5C\u4E3A\u9ED8\u8BA4\u56FE\u7247\uFF08\u65E0\u65AD\u70B9\u503C\uFF09\n if (backgroundImage.lgDesktop?.url) {\n sources.push(`${backgroundImage.lgDesktop.url}`)\n }\n if (backgroundImage.desktop?.url) {\n sources.push(`${backgroundImage.desktop.url} ${BREAKPOINTS.desktop}`)\n }\n if (backgroundImage.laptop?.url) {\n sources.push(`${backgroundImage.laptop.url} ${BREAKPOINTS.laptop}`)\n }\n if (backgroundImage.tablet?.url) {\n sources.push(`${backgroundImage.tablet.url} ${BREAKPOINTS.tablet}`)\n }\n if (backgroundImage.default?.url) {\n sources.push(`${backgroundImage.default.url} ${BREAKPOINTS.default}`)\n }\n\n return sources.join(', ')\n}\n\n/**\n * \u83B7\u53D6\u54CD\u5E94\u5F0F\u80CC\u666F\u56FE\u7247\u7684\u9ED8\u8BA4 alt \u6587\u672C\n */\nconst getBackgroundAlt = (backgroundImage?: ImageTextOverlayBackgroundImage): string => {\n if (!backgroundImage) return ''\n return (\n backgroundImage.default?.alt ||\n backgroundImage.tablet?.alt ||\n backgroundImage.laptop?.alt ||\n backgroundImage.desktop?.alt ||\n backgroundImage.lgDesktop?.alt ||\n ''\n )\n}\n\n// ============================================================================\n// \u54CD\u5E94\u5F0F\u5E03\u5C40\u7C7B\u540D \u2014\u2014 \u6839\u636E items \u6570\u91CF\u52A8\u6001\u51B3\u5B9A\u7F51\u683C\u5217\u6570\n//\n// Figma \u8BBE\u8BA1\u89C4\u8303\u603B\u7ED3:\n//\n// | Count | <768 (mobile) | 768-1024 (tablet) | 1025-1440 (laptop) | 1441-1920 (desktop) | \u22651921 (lg-desktop) |\n// |-------|---------------|--------------------|--------------------|---------------------|--------------------|\n// | 2 | 1col | 2col | 2col | 2col | 2col |\n// | 3 | 1col | 2col (2+1) | 3col | 3col | 3col |\n// | 4 | 2col (2 rows) | 2col (2 rows) | 2col (2 rows) | 2col (2 rows) | 2col (2 rows) |\n// | 5 | 2col (3 rows) | 2col (3 rows) | 2+3 (5col flex) | 2+3 (5col flex) | 2+3 (5col flex) |\n// | 6 | 2col (3 rows) | 2col (3 rows) | 3col (2 rows) | 3col (2 rows) | 3col (2 rows) |\n//\n// ============================================================================\n\n/**\n * \u5C06\u6570\u7EC4\u6309\u6307\u5B9A\u5927\u5C0F\u5206\u7EC4\n */\nconst chunkArray = <T,>(arr: T[], size: number): T[][] => {\n const chunks: T[][] = []\n for (let i = 0; i < arr.length; i += size) {\n chunks.push(arr.slice(i, i + size))\n }\n return chunks\n}\n\n/**\n * \u83B7\u53D6\u5BB9\u5668\u7F51\u683C\u7C7B\u540D\uFF08\u6839\u636E items \u6570\u91CF\uFF09\n */\n\n/**\n * \u83B7\u53D6\u5BB9\u5668\u7F51\u683C\u7C7B\u540D\uFF08\u6839\u636E items \u6570\u91CF\uFF09\n */\nconst getGridClasses = (count: number): string => {\n switch (count) {\n case 2:\n // mobile: 1col, tablet+: 2col\n return 'grid-cols-1 tablet:grid-cols-2'\n case 3:\n // mobile: 1col, tablet: 2col, laptop+: 3col\n return 'grid-cols-1 tablet:grid-cols-2 laptop:grid-cols-3'\n case 4:\n // mobile: 2col, tablet+: 2col (uniform)\n return 'grid-cols-1 tablet:grid-cols-2'\n case 5:\n // mobile/tablet: 2col grid, laptop+: use flex layout instead (2+3 pattern)\n // We handle laptop+ separately via flex, grid for mobile/tablet only\n return 'grid-cols-1 tablet:grid-cols-2 laptop:grid-cols-6'\n case 6:\n // mobile/tablet: 2col, laptop+: 3col\n return 'grid-cols-1 tablet:grid-cols-2 desktop:grid-cols-3'\n default:\n if (count <= 1) return 'grid-cols-1'\n // fallback: 2col mobile, 3col laptop+\n return 'grid-cols-1 laptop:grid-cols-3'\n }\n}\n\n/**\n * \u83B7\u53D6\u5355\u4E2A item \u7684 span \u7C7B\u540D (\u4EC5\u7528\u4E8E count=3 tablet \u548C count=5 laptop+)\n */\nconst getItemSpanClasses = (index: number, count: number): string => {\n if (count === 5) {\n // laptop+: \u7B2C1\u884C 2 items \u5404 span 3, \u7B2C2\u884C 3 items \u5404 span 2\n if (index < 2) return 'laptop:col-span-3'\n return 'laptop:col-span-2'\n }\n return ''\n}\n\n/**\n * \u83B7\u53D6\u5361\u7247\u9AD8\u5EA6\u7C7B\u540D\n * Figma: mobile 240px, tablet 240px, laptop 192px, desktop 256px, lg-desktop 320px\n */\nconst cardHeightClasses = 'h-[240px] tablet:h-[240px] laptop:h-[192px] desktop:h-[256px] lg-desktop:h-[320px]'\n\n/**\n * ImageTextOverlayCard - \u5355\u4E2A\u56FE\u6587\u53E0\u52A0\u5361\u7247\n */\nconst ImageTextOverlayCard: React.FC<{\n item: ImageTextOverlayItem\n index: number\n count: number\n classNames?: Partial<Record<ImageTextOverlaySemanticName, string>>\n}> = ({ item, index, count, classNames }) => {\n const responsiveSource = buildResponsiveSource(item.backgroundImage)\n const defaultAlt = getBackgroundAlt(item.backgroundImage)\n const spanClasses = getItemSpanClasses(index, count)\n const imageRef = React.useRef<HTMLDivElement>(null)\n const { locale = 'us', pageHandle } = useAiuiContext()\n\n useExposure(imageRef, {\n componentType: imageComponentType,\n componentName,\n position: index + 1,\n componentTitle: item.title,\n componentDescription: item.subtitle,\n })\n\n const localizedLink = item.link ? getLocalizedPath(item.link, locale) : undefined\n const trackedLink = localizedLink\n ? trackUrlRef(localizedLink, `${pageHandle ?? ''}_${imageComponentType}_${componentName}`)\n : undefined\n const titleDescButton = `${item.title}#${item.subtitle || ''}#${item.title}`\n\n return (\n <div\n ref={imageRef}\n className={cn(\n 'image-text-overlay-card rounded-card',\n { 'aiui-dark': item.theme === 'dark' },\n 'desktop:p-6 lg-desktop:p-8 group relative flex flex-col items-start justify-end overflow-hidden p-4',\n cardHeightClasses,\n spanClasses,\n classNames?.card\n )}\n >\n {/* \u6574\u5361\u94FE\u63A5 */}\n {trackedLink && (\n <a\n href={trackedLink}\n className=\"absolute inset-0 z-20\"\n aria-label={item.title}\n data-headless-type-name={`${imageComponentType}#${componentName}`}\n data-headless-title-desc-button={titleDescButton}\n />\n )}\n\n {/* \u80CC\u666F\u5A92\u4F53\uFF1A\u89C6\u9891\u6216\u56FE\u7247 */}\n {item.backgroundImage?.isShowVideo ? (\n <>\n {/* \u79FB\u52A8\u7AEF\u89C6\u9891 (<1025px) */}\n {item.backgroundImage?.mobileVideo && (\n <video\n className={cn(\n 'image-text-overlay-card-image',\n 'laptop:hidden absolute inset-0 size-full object-cover',\n classNames?.cardImage\n )}\n src={item.backgroundImage.mobileVideo.url}\n autoPlay\n muted\n loop\n playsInline\n />\n )}\n {/* \u684C\u9762\u7AEF\u89C6\u9891 (>=1025px) */}\n {item.backgroundImage?.desktopVideo && (\n <video\n className={cn(\n 'image-text-overlay-card-image',\n 'laptop:block absolute inset-0 hidden size-full object-cover',\n classNames?.cardImage\n )}\n src={item.backgroundImage.desktopVideo.url}\n autoPlay\n muted\n loop\n playsInline\n />\n )}\n </>\n ) : (\n responsiveSource && (\n <Picture\n source={responsiveSource}\n alt={defaultAlt || item.title}\n className={cn('image-text-overlay-card-image', 'absolute inset-0 size-full', classNames?.cardImage)}\n imgClassName=\"size-full object-cover cursor-pointer transition-all duration-300 group-hover:scale-105\"\n />\n )\n )}\n\n {/* \u6587\u5B57\u5185\u5BB9 */}\n <div\n className={cn(\n 'image-text-overlay-card-content',\n 'relative z-10 flex w-full flex-col gap-1',\n classNames?.cardContent\n )}\n >\n <Heading\n as=\"h4\"\n size={2}\n weight=\"bold\"\n className={cn(\n 'image-text-overlay-card-title text-info-primary line-clamp-1',\n 'w-full leading-[1.2] tracking-[-0.04em]',\n // \u5B57\u53F7: mobile/tablet/laptop 18px, desktop 20px, lg-desktop 24px\n 'desktop:text-xl lg-desktop:text-2xl text-lg',\n classNames?.cardTitle\n )}\n >\n {item.title}\n </Heading>\n\n {item.subtitle && (\n <Text\n as=\"p\"\n size=\"none\"\n weight=\"bold\"\n className={cn(\n 'image-text-overlay-card-subtitle text-info-primary line-clamp-1',\n 'w-full truncate leading-[1.4] tracking-[-0.02em]',\n // \u5B57\u53F7: mobile/tablet/laptop 14px, desktop 14px, lg-desktop 18px (count<=3) or 16px (count>3)\n 'lg-desktop:text-base text-sm',\n count <= 3 && 'lg-desktop:text-lg',\n classNames?.cardSubtitle\n )}\n >\n {item.subtitle}\n </Text>\n )}\n </div>\n </div>\n )\n}\n\n/**\n * ImageTextOverlay - \u56FE\u6587\u53E0\u52A0\u7EC4\u4EF6\n *\n * @description \u4EE5\u80CC\u666F\u56FE\u4E3A\u4E3B\u7684\u5361\u7247\u5E03\u5C40\u7EC4\u4EF6\uFF0C\u6807\u9898\u548C\u526F\u6807\u9898\u53E0\u52A0\u663E\u793A\u5728\u56FE\u7247\u5E95\u90E8\u3002\n * \u652F\u6301 2-6 \u4E2A items \u7684\u81EA\u52A8\u54CD\u5E94\u5F0F\u7F51\u683C\u5E03\u5C40\uFF0C\u6BCF\u4E2A item \u7684 backgroundImage\n * \u652F\u6301 5 \u4E2A\u65AD\u70B9 (default/tablet/laptop/desktop/lgDesktop)\u3002\n *\n * @example\n * ```tsx\n * <ImageTextOverlay\n * data={{\n * items: [\n * {\n * backgroundImage: {\n * default: { url: '/bg-mobile.jpg', alt: 'feature' },\n * tablet: { url: '/bg-tablet.jpg', alt: 'feature' },\n * laptop: { url: '/bg-laptop.jpg', alt: 'feature' },\n * desktop: { url: '/bg-desktop.jpg', alt: 'feature' },\n * lgDesktop: { url: '/bg-xl.jpg', alt: 'feature' },\n * },\n * title: '300+ AI brainwave audios',\n * subtitle: 'Charge in a Flash, Share in a Dash',\n * },\n * {\n * backgroundImage: { default: { url: '/bg2.jpg', alt: '' } },\n * title: '20+ white noise sounds',\n * subtitle: 'Power to Drive Your Prime',\n * },\n * ],\n * theme: 'dark',\n * }}\n * />\n * ```\n */\nconst ImageTextOverlay = forwardRef<HTMLDivElement, ImageTextOverlayProps>(\n ({ data, className, classNames = {}, ...props }, ref) => {\n const boxRef = React.useRef<HTMLDivElement>(null)\n const { items = [] } = data\n const [isMobile, setIsMobile] = useState(false)\n const mediaQuery = useMediaQuery({ query: '(max-width: 767px)' })\n\n useEffect(() => {\n setIsMobile(mediaQuery)\n }, [mediaQuery])\n\n useExposure(boxRef, {\n componentType,\n componentName,\n })\n\n React.useImperativeHandle(ref, () => boxRef.current as HTMLDivElement)\n\n if (!items.length) return null\n\n const count = items.length\n const useSwiper = count > 3 && isMobile\n const chunkedItems = chunkArray(items, 3)\n\n return (\n <div\n ref={boxRef}\n className={cn('image-text-overlay-root', className, classNames.root)}\n data-ui-component-id=\"ImageTextOverlay\"\n {...props}\n >\n {useSwiper ? (\n <div className=\"image-text-overlay-mobile-swiper relative pb-8\">\n <Swiper\n className=\"w-full [&_.swiper-slide]:!h-auto [&_.swiper-wrapper]:items-stretch\"\n modules={[Pagination]}\n slidesPerView={1}\n pagination={{\n clickable: true,\n el: `.${MOBILE_SWIPER_PAGINATION_CLASS}`,\n bulletClass: 'image-text-overlay-bullet',\n bulletActiveClass: 'image-text-overlay-bullet-active',\n }}\n spaceBetween={16}\n >\n {chunkedItems.map((group, gIndex) => (\n <SwiperSlide key={gIndex} className=\"!h-auto\">\n <div className=\"flex flex-col gap-4\">\n {group.map((item, index) => (\n <ImageTextOverlayCard\n key={gIndex * 3 + index}\n item={item}\n index={gIndex * 3 + index}\n count={count}\n classNames={classNames}\n />\n ))}\n </div>\n </SwiperSlide>\n ))}\n </Swiper>\n <div className=\"absolute inset-x-0 bottom-0 z-10 flex justify-center\">\n <div\n className={cn(\n MOBILE_SWIPER_PAGINATION_CLASS,\n 'flex items-center justify-center gap-2 text-center',\n '[&_.swiper-pagination-bullet]:m-0',\n '[&_.swiper-pagination-bullet]:shrink-0',\n '[&_.swiper-pagination-bullet]:opacity-100'\n )}\n />\n </div>\n <style>{`\n .image-text-overlay-bullet {\n display: inline-block;\n width: 8px;\n height: 8px;\n border-radius: 9999px;\n background: #767880;\n transition: all 0.3s ease;\n }\n\n .image-text-overlay-bullet-active {\n width: 32px;\n height: 8px;\n border-radius: 9999px;\n background: #080A0F;\n }\n `}</style>\n </div>\n ) : (\n <div className={cn('image-text-overlay-grid', 'grid gap-4', getGridClasses(count), classNames.grid)}>\n {items.map((item, index) => (\n <ImageTextOverlayCard key={index} item={item} index={index} count={count} classNames={classNames} />\n ))}\n </div>\n )}\n </div>\n )\n }\n)\n\nImageTextOverlay.displayName = 'ImageTextOverlay'\n\nexport default withLayout(ImageTextOverlay)\n"],
|
|
5
|
-
"mappings": "
|
|
6
|
-
"names": ["Fragment", "jsx", "jsxs", "React", "forwardRef", "useEffect", "useState", "cn", "Heading", "Text", "Picture", "useExposure", "withLayout", "trackUrlRef", "getLocalizedPath", "useAiuiContext", "useMediaQuery", "Swiper", "SwiperSlide", "Pagination", "componentType", "componentName", "imageComponentType", "MOBILE_SWIPER_PAGINATION_CLASS", "BREAKPOINTS", "buildResponsiveSource", "backgroundImage", "sources", "getBackgroundAlt", "chunkArray", "arr", "size", "chunks", "i", "getGridClasses", "count", "getItemSpanClasses", "index", "
|
|
4
|
+
"sourcesContent": ["'use client'\nimport * as React from 'react'\nimport { forwardRef, useEffect, useRef, useState } from 'react'\nimport { cn } from '../../helpers/utils.js'\nimport { Heading } from '../../components/heading.js'\nimport { Text } from '../../components/text.js'\nimport Picture from '../../components/picture.js'\nimport { useExposure } from '../../hooks/useExposure.js'\nimport { withLayout } from '../../shared/Styles.js'\nimport { trackUrlRef } from '../../shared/trackUrlRef.js'\nimport type {\n ImageTextOverlayProps,\n ImageTextOverlayItem,\n ImageTextOverlaySemanticName,\n ImageTextOverlayData,\n ImageTextOverlayBackgroundImage,\n} from './types.js'\nimport { getLocalizedPath } from '../../helpers/utils.js'\nimport { useAiuiContext } from '../AiuiProvider/index.js'\nimport { useMediaQuery } from 'react-responsive'\nimport { Swiper, SwiperSlide } from 'swiper/react'\nimport { Pagination } from 'swiper/modules'\nimport 'swiper/css'\nimport 'swiper/css/pagination'\n\nexport type {\n ImageTextOverlayProps,\n ImageTextOverlayItem,\n ImageTextOverlaySemanticName,\n ImageTextOverlayData,\n ImageTextOverlayBackgroundImage,\n}\n\nconst componentType = 'content'\nconst componentName = 'image_text_overlay'\nconst imageComponentType = 'image'\nconst MOBILE_SWIPER_PAGINATION_CLASS = 'image-text-overlay-mobile-pagination'\n\n/**\n * \u65AD\u70B9\u914D\u7F6E\uFF08\u4E0E Tailwind \u65AD\u70B9\u5BF9\u5E94\uFF09\n * Picture \u7EC4\u4EF6\u4F7F\u7528 max-width \u5A92\u4F53\u67E5\u8BE2\uFF0C\u6240\u4EE5\u9700\u8981\u6309\u4ECE\u5927\u5230\u5C0F\u7684\u987A\u5E8F\u6392\u5217\n */\nconst BREAKPOINTS = {\n default: 767, // <768px (\u79FB\u52A8\u7AEF)\n tablet: 1024, // 768px - 1024px\n laptop: 1439, // 1025px - 1439px\n desktop: 1919, // 1440px - 1919px\n lgDesktop: 9999, // \u22651920px\n} as const\n\n/**\n * \u5C06\u54CD\u5E94\u5F0F\u80CC\u666F\u56FE\u7247\u5BF9\u8C61\u8F6C\u6362\u4E3A Picture \u7EC4\u4EF6\u7684 source \u5B57\u7B26\u4E32\n * \u683C\u5F0F: \"lgDesktopUrl, desktopUrl 1919, laptopUrl 1439, tabletUrl 1024, defaultUrl 767\"\n */\nconst buildResponsiveSource = (backgroundImage?: ImageTextOverlayBackgroundImage): string => {\n if (!backgroundImage) return ''\n\n const sources: string[] = []\n\n // lgDesktop \u4F5C\u4E3A\u9ED8\u8BA4\u56FE\u7247\uFF08\u65E0\u65AD\u70B9\u503C\uFF09\n if (backgroundImage.lgDesktop?.url) {\n sources.push(`${backgroundImage.lgDesktop.url}`)\n }\n if (backgroundImage.desktop?.url) {\n sources.push(`${backgroundImage.desktop.url} ${BREAKPOINTS.desktop}`)\n }\n if (backgroundImage.laptop?.url) {\n sources.push(`${backgroundImage.laptop.url} ${BREAKPOINTS.laptop}`)\n }\n if (backgroundImage.tablet?.url) {\n sources.push(`${backgroundImage.tablet.url} ${BREAKPOINTS.tablet}`)\n }\n if (backgroundImage.default?.url) {\n sources.push(`${backgroundImage.default.url} ${BREAKPOINTS.default}`)\n }\n\n return sources.join(', ')\n}\n\n/**\n * \u83B7\u53D6\u54CD\u5E94\u5F0F\u80CC\u666F\u56FE\u7247\u7684\u9ED8\u8BA4 alt \u6587\u672C\n */\nconst getBackgroundAlt = (backgroundImage?: ImageTextOverlayBackgroundImage): string => {\n if (!backgroundImage) return ''\n return (\n backgroundImage.default?.alt ||\n backgroundImage.tablet?.alt ||\n backgroundImage.laptop?.alt ||\n backgroundImage.desktop?.alt ||\n backgroundImage.lgDesktop?.alt ||\n ''\n )\n}\n\n// ============================================================================\n// \u54CD\u5E94\u5F0F\u5E03\u5C40\u7C7B\u540D \u2014\u2014 \u6839\u636E items \u6570\u91CF\u52A8\u6001\u51B3\u5B9A\u7F51\u683C\u5217\u6570\n//\n// Figma \u8BBE\u8BA1\u89C4\u8303\u603B\u7ED3:\n//\n// | Count | <768 (mobile) | 768-1024 (tablet) | 1025-1440 (laptop) | 1441-1920 (desktop) | \u22651921 (lg-desktop) |\n// |-------|---------------|--------------------|--------------------|---------------------|--------------------|\n// | 2 | 1col | 2col | 2col | 2col | 2col |\n// | 3 | 1col | 2col (2+1) | 3col | 3col | 3col |\n// | 4 | 2col (2 rows) | 2col (2 rows) | 2col (2 rows) | 2col (2 rows) | 2col (2 rows) |\n// | 5 | 2col (3 rows) | 2col (3 rows) | 2+3 (5col flex) | 2+3 (5col flex) | 2+3 (5col flex) |\n// | 6 | 2col (3 rows) | 2col (3 rows) | 3col (2 rows) | 3col (2 rows) | 3col (2 rows) |\n//\n// ============================================================================\n\n/**\n * \u5C06\u6570\u7EC4\u6309\u6307\u5B9A\u5927\u5C0F\u5206\u7EC4\n */\nconst chunkArray = <T,>(arr: T[], size: number): T[][] => {\n const chunks: T[][] = []\n for (let i = 0; i < arr.length; i += size) {\n chunks.push(arr.slice(i, i + size))\n }\n return chunks\n}\n\n/**\n * \u83B7\u53D6\u5BB9\u5668\u7F51\u683C\u7C7B\u540D\uFF08\u6839\u636E items \u6570\u91CF\uFF09\n */\nconst getGridClasses = (count: number): string => {\n switch (count) {\n case 2:\n // mobile: 1col, tablet+: 2col\n return 'grid-cols-1 tablet:grid-cols-2'\n case 3:\n // mobile: 1col, tablet: 2col, laptop+: 3col\n return 'grid-cols-1 tablet:grid-cols-2 laptop:grid-cols-3'\n case 4:\n // mobile: 2col, tablet+: 2col (uniform)\n return 'grid-cols-1 tablet:grid-cols-2'\n case 5:\n // mobile/tablet: 2col grid, laptop+: use flex layout instead (2+3 pattern)\n // We handle laptop+ separately via flex, grid for mobile/tablet only\n return 'grid-cols-1 tablet:grid-cols-2 laptop:grid-cols-6'\n case 6:\n // mobile/tablet: 2col, laptop+: 3col\n return 'grid-cols-1 tablet:grid-cols-2 desktop:grid-cols-3'\n default:\n if (count <= 1) return 'grid-cols-1'\n // fallback: 2col mobile, 3col laptop+\n return 'grid-cols-1 laptop:grid-cols-3'\n }\n}\n\n/**\n * \u83B7\u53D6\u5355\u4E2A item \u7684 span \u7C7B\u540D (\u4EC5\u7528\u4E8E count=3 tablet \u548C count=5 laptop+)\n */\nconst getItemSpanClasses = (index: number, count: number): string => {\n if (count === 5) {\n // laptop+: \u7B2C1\u884C 2 items \u5404 span 3, \u7B2C2\u884C 3 items \u5404 span 2\n if (index < 2) return 'laptop:col-span-3'\n return 'laptop:col-span-2'\n }\n return ''\n}\n\n/**\n * \u83B7\u53D6\u5361\u7247\u5BBD\u9AD8\u6BD4\u7C7B\u540D\n * \u6839\u636E items \u6570\u91CF\u548C\u65AD\u70B9\u52A8\u6001\u8BA1\u7B97\uFF0C\u786E\u4FDD\u56FE\u7247\u4E0D\u88AB\u622A\u65AD\n */\nconst getAspectRatioClasses = (count: number, index: number): string => {\n switch (count) {\n case 2:\n case 4:\n // \u59CB\u7EC8 2 \u5217\n return 'aspect-[358/240] tablet:aspect-[346/240] laptop:aspect-[440/192] desktop:aspect-[648/256] lg-desktop:aspect-[824/320]'\n case 3:\n // tablet 2 \u5217, laptop+ 3 \u5217\n return 'aspect-[358/240] tablet:aspect-[346/240] laptop:aspect-[288/192] desktop:aspect-[427/256] lg-desktop:aspect-[544/320]'\n case 5:\n // tablet 2 \u5217, laptop+ \u7279\u6B8A flex (\u9996\u884C 2 \u4E2A\u5404\u5360 50%, \u6B21\u884C 3 \u4E2A\u5404\u5360 33%)\n // \u7B2C\u4E00\u884C\uFF08index 0-1\uFF09\u7528 2 \u5217\u5BBD\u9AD8\u6BD4\uFF0C\u7B2C\u4E8C\u884C\uFF08index 2-4\uFF09\u7528 3 \u5217\u5BBD\u9AD8\u6BD4\uFF0C\u786E\u4FDD\u9AD8\u5EA6\u4E00\u81F4\n if (index < 2) {\n return 'aspect-[358/240] tablet:aspect-[346/240] laptop:aspect-[440/192] desktop:aspect-[648/256] lg-desktop:aspect-[824/320]'\n }\n return 'aspect-[358/240] tablet:aspect-[346/240] laptop:aspect-[288/192] desktop:aspect-[427/256] lg-desktop:aspect-[544/320]'\n case 6:\n // tablet/laptop 2 \u5217, desktop+ 3 \u5217\n return 'aspect-[358/240] tablet:aspect-[346/240] laptop:aspect-[440/192] desktop:aspect-[427/256] lg-desktop:aspect-[544/320]'\n default:\n if (count <= 1) return 'aspect-[358/240]'\n return 'aspect-[358/240] tablet:aspect-[346/240] laptop:aspect-[440/192] desktop:aspect-[648/256] lg-desktop:aspect-[824/320]'\n }\n}\n\n/**\n * ImageTextOverlayCard - \u5355\u4E2A\u56FE\u6587\u53E0\u52A0\u5361\u7247\n */\nconst ImageTextOverlayCard: React.FC<{\n item: ImageTextOverlayItem\n index: number\n count: number\n classNames?: Partial<Record<ImageTextOverlaySemanticName, string>>\n}> = ({ item, index, count, classNames }) => {\n const responsiveSource = buildResponsiveSource(item.backgroundImage)\n const defaultAlt = getBackgroundAlt(item.backgroundImage)\n const spanClasses = getItemSpanClasses(index, count)\n const imageRef = React.useRef<HTMLDivElement>(null)\n const { locale = 'us', pageHandle } = useAiuiContext()\n\n useExposure(imageRef, {\n componentType: imageComponentType,\n componentName,\n position: index + 1,\n componentTitle: item.title,\n componentDescription: item.subtitle,\n })\n\n const localizedLink = item.link ? getLocalizedPath(item.link, locale) : undefined\n const trackedLink = localizedLink\n ? trackUrlRef(localizedLink, `${pageHandle ?? ''}_${imageComponentType}_${componentName}`)\n : undefined\n const titleDescButton = `${item.title}#${item.subtitle || ''}#${item.title}`\n\n const aspectRatioClasses = getAspectRatioClasses(count, index)\n\n return (\n <div\n ref={imageRef}\n className={cn(\n 'image-text-overlay-card rounded-card',\n { 'aiui-dark': item.theme === 'dark' },\n 'desktop:p-6 lg-desktop:p-8 group relative flex flex-col items-start justify-end overflow-hidden p-4',\n aspectRatioClasses,\n spanClasses,\n classNames?.card\n )}\n >\n {/* \u6574\u5361\u94FE\u63A5 */}\n {trackedLink && (\n <a\n href={trackedLink}\n className=\"absolute inset-0 z-20\"\n aria-label={item.title}\n data-headless-type-name={`${imageComponentType}#${componentName}`}\n data-headless-title-desc-button={titleDescButton}\n />\n )}\n\n {/* \u80CC\u666F\u5A92\u4F53\uFF1A\u89C6\u9891\u6216\u56FE\u7247 */}\n {item.backgroundImage?.isShowVideo ? (\n <>\n {/* \u79FB\u52A8\u7AEF\u89C6\u9891 (<1025px) */}\n {item.backgroundImage?.mobileVideo && (\n <video\n className={cn(\n 'image-text-overlay-card-image',\n 'laptop:hidden absolute inset-0 size-full object-cover',\n classNames?.cardImage\n )}\n src={item.backgroundImage.mobileVideo.url}\n autoPlay\n muted\n loop\n playsInline\n />\n )}\n {/* \u684C\u9762\u7AEF\u89C6\u9891 (>=1025px) */}\n {item.backgroundImage?.desktopVideo && (\n <video\n className={cn(\n 'image-text-overlay-card-image',\n 'laptop:block absolute inset-0 hidden size-full object-cover',\n classNames?.cardImage\n )}\n src={item.backgroundImage.desktopVideo.url}\n autoPlay\n muted\n loop\n playsInline\n />\n )}\n </>\n ) : (\n responsiveSource && (\n <Picture\n source={responsiveSource}\n alt={defaultAlt || item.title}\n className={cn('image-text-overlay-card-image', 'absolute inset-0 size-full', classNames?.cardImage)}\n imgClassName=\"size-full object-cover cursor-pointer transition-all duration-300 group-hover:scale-105\"\n />\n )\n )}\n\n {/* \u6587\u5B57\u5185\u5BB9 */}\n <div\n className={cn(\n 'image-text-overlay-card-content',\n 'relative z-10 flex w-full flex-col gap-1',\n classNames?.cardContent\n )}\n >\n <Heading\n as=\"h4\"\n size={2}\n weight=\"bold\"\n className={cn(\n 'image-text-overlay-card-title text-info-primary line-clamp-1',\n 'w-full leading-[1.2] tracking-[-0.04em]',\n // \u5B57\u53F7: mobile/tablet/laptop 18px, desktop 20px, lg-desktop 24px\n 'desktop:text-xl lg-desktop:text-2xl text-lg',\n classNames?.cardTitle\n )}\n >\n {item.title}\n </Heading>\n\n {item.subtitle && (\n <Text\n as=\"p\"\n size=\"none\"\n weight=\"bold\"\n className={cn(\n 'image-text-overlay-card-subtitle text-info-primary line-clamp-1',\n 'w-full truncate leading-[1.4] tracking-[-0.02em]',\n // \u5B57\u53F7: mobile/tablet/laptop 14px, desktop 14px, lg-desktop 18px (count<=3) or 16px (count>3)\n 'lg-desktop:text-base text-sm',\n count <= 3 && 'lg-desktop:text-lg',\n classNames?.cardSubtitle\n )}\n >\n {item.subtitle}\n </Text>\n )}\n </div>\n </div>\n )\n}\n\n/**\n * ImageTextOverlay - \u56FE\u6587\u53E0\u52A0\u7EC4\u4EF6\n *\n * @description \u4EE5\u80CC\u666F\u56FE\u4E3A\u4E3B\u7684\u5361\u7247\u5E03\u5C40\u7EC4\u4EF6\uFF0C\u6807\u9898\u548C\u526F\u6807\u9898\u53E0\u52A0\u663E\u793A\u5728\u56FE\u7247\u5E95\u90E8\u3002\n * \u652F\u6301 2-6 \u4E2A items \u7684\u81EA\u52A8\u54CD\u5E94\u5F0F\u7F51\u683C\u5E03\u5C40\uFF0C\u6BCF\u4E2A item \u7684 backgroundImage\n * \u652F\u6301 5 \u4E2A\u65AD\u70B9 (default/tablet/laptop/desktop/lgDesktop)\u3002\n *\n * @example\n * ```tsx\n * <ImageTextOverlay\n * data={{\n * items: [\n * {\n * backgroundImage: {\n * default: { url: '/bg-mobile.jpg', alt: 'feature' },\n * tablet: { url: '/bg-tablet.jpg', alt: 'feature' },\n * laptop: { url: '/bg-laptop.jpg', alt: 'feature' },\n * desktop: { url: '/bg-desktop.jpg', alt: 'feature' },\n * lgDesktop: { url: '/bg-xl.jpg', alt: 'feature' },\n * },\n * title: '300+ AI brainwave audios',\n * subtitle: 'Charge in a Flash, Share in a Dash',\n * },\n * {\n * backgroundImage: { default: { url: '/bg2.jpg', alt: '' } },\n * title: '20+ white noise sounds',\n * subtitle: 'Power to Drive Your Prime',\n * },\n * ],\n * theme: 'dark',\n * }}\n * />\n * ```\n */\nconst ImageTextOverlay = forwardRef<HTMLDivElement, ImageTextOverlayProps>(\n ({ data, className, classNames = {}, ...props }, ref) => {\n const boxRef = React.useRef<HTMLDivElement>(null)\n const { items = [] } = data\n const [isMobile, setIsMobile] = useState(false)\n const mediaQuery = useMediaQuery({ query: '(max-width: 767px)' })\n\n useEffect(() => {\n setIsMobile(mediaQuery)\n }, [mediaQuery])\n\n useExposure(boxRef, {\n componentType,\n componentName,\n })\n\n React.useImperativeHandle(ref, () => boxRef.current as HTMLDivElement)\n\n if (!items.length) return null\n\n const count = items.length\n const useSwiper = count > 3 && isMobile\n const chunkedItems = chunkArray(items, 3)\n\n return (\n <div\n ref={boxRef}\n className={cn('image-text-overlay-root', className, classNames.root)}\n data-ui-component-id=\"ImageTextOverlay\"\n {...props}\n >\n {useSwiper ? (\n <div className=\"image-text-overlay-mobile-swiper relative pb-8\">\n <Swiper\n className=\"w-full [&_.swiper-slide]:!h-auto [&_.swiper-wrapper]:items-stretch\"\n modules={[Pagination]}\n slidesPerView={1}\n pagination={{\n clickable: true,\n el: `.${MOBILE_SWIPER_PAGINATION_CLASS}`,\n bulletClass: 'image-text-overlay-bullet',\n bulletActiveClass: 'image-text-overlay-bullet-active',\n }}\n spaceBetween={16}\n >\n {chunkedItems.map((group, gIndex) => (\n <SwiperSlide key={gIndex} className=\"!h-auto\">\n <div className=\"flex flex-col gap-4\">\n {group.map((item, index) => (\n <ImageTextOverlayCard\n key={gIndex * 3 + index}\n item={item}\n index={gIndex * 3 + index}\n count={count}\n classNames={classNames}\n />\n ))}\n </div>\n </SwiperSlide>\n ))}\n </Swiper>\n <div className=\"absolute inset-x-0 bottom-0 z-10 flex justify-center\">\n <div\n className={cn(\n MOBILE_SWIPER_PAGINATION_CLASS,\n 'flex items-center justify-center gap-2 text-center',\n '[&_.swiper-pagination-bullet]:m-0',\n '[&_.swiper-pagination-bullet]:shrink-0',\n '[&_.swiper-pagination-bullet]:opacity-100'\n )}\n />\n </div>\n <style>{`\n .image-text-overlay-bullet {\n display: inline-block;\n width: 8px;\n height: 8px;\n border-radius: 9999px;\n background: #767880;\n transition: all 0.3s ease;\n }\n\n .image-text-overlay-bullet-active {\n width: 32px;\n height: 8px;\n border-radius: 9999px;\n background: #080A0F;\n }\n `}</style>\n </div>\n ) : (\n <div className={cn('image-text-overlay-grid', 'grid gap-4', getGridClasses(count), classNames.grid)}>\n {items.map((item, index) => (\n <ImageTextOverlayCard key={index} item={item} index={index} count={count} classNames={classNames} />\n ))}\n </div>\n )}\n </div>\n )\n }\n)\n\nImageTextOverlay.displayName = 'ImageTextOverlay'\n\nexport default withLayout(ImageTextOverlay)\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["Fragment", "jsx", "jsxs", "React", "forwardRef", "useEffect", "useState", "cn", "Heading", "Text", "Picture", "useExposure", "withLayout", "trackUrlRef", "getLocalizedPath", "useAiuiContext", "useMediaQuery", "Swiper", "SwiperSlide", "Pagination", "componentType", "componentName", "imageComponentType", "MOBILE_SWIPER_PAGINATION_CLASS", "BREAKPOINTS", "buildResponsiveSource", "backgroundImage", "sources", "getBackgroundAlt", "chunkArray", "arr", "size", "chunks", "i", "getGridClasses", "count", "getItemSpanClasses", "index", "getAspectRatioClasses", "ImageTextOverlayCard", "item", "classNames", "responsiveSource", "defaultAlt", "spanClasses", "imageRef", "locale", "pageHandle", "localizedLink", "trackedLink", "titleDescButton", "aspectRatioClasses", "ImageTextOverlay", "data", "className", "props", "ref", "boxRef", "items", "isMobile", "setIsMobile", "mediaQuery", "useSwiper", "chunkedItems", "group", "gIndex", "ImageTextOverlay_default"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import{jsx as
|
|
1
|
+
"use client";import{jsx as o,jsxs as i}from"react/jsx-runtime";import{useState as Y,useEffect as w,useCallback as F,forwardRef as G,useImperativeHandle as I,useRef as f}from"react";import{cn as T}from"../../helpers/utils.js";import{withLayout as V}from"../../shared/Styles.js";import{Button as L,Text as N}from"../../components/index.js";import{useExposure as _}from"../../hooks/useExposure.js";import*as E from"@radix-ui/react-popover";const $="navigation",q="product_nav",O=k=>o("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"none",xmlns:"http://www.w3.org/2000/svg",...k,children:o("path",{d:"M5 7.5L10 12.5L15 7.5",stroke:"currentColor",strokeWidth:"1.66667",strokeLinecap:"round",strokeLinejoin:"round"})}),M=G(({className:k="",data:D,id:H,onAnchorClick:P,scrollOffsetExtra:b=0},A)=>{const{tabLinks:v=[],anchorList:r=[],textLink:a,buyBtn:p,theme:B="light"}=D||{},[z,x]=Y(""),d=f(null),g=f(!1),u=f(""),m=f(null),y=f(new Map);I(A,()=>d.current),_(d,{componentType:$,componentName:q});const h=F(()=>{if(r.length===0)return;const e=window.scrollY;window.scrollTo({top:0,behavior:"instant"}),requestAnimationFrame(()=>{const t=new Map;r.forEach(s=>{const n=document.getElementById(s.id);if(n){const l=n.getBoundingClientRect();t.set(s.id,l.top+window.scrollY)}}),y.current=t,window.scrollTo({top:e,behavior:"instant"})})},[r]);w(()=>{if(r.length===0)return;const e=setTimeout(h,100);return()=>clearTimeout(e)},[r,h]),w(()=>{if(r.length===0)return;let e=null;const t=new ResizeObserver(()=>{e&&clearTimeout(e),e=setTimeout(h,150)});return t.observe(document.body),()=>{t.disconnect(),e&&clearTimeout(e)}},[r,h]),w(()=>{if(r.length===0)return;const e=()=>{if(g.current){m.current&&clearTimeout(m.current),m.current=setTimeout(()=>{g.current=!1,u.current&&(x(u.current),u.current="")},100);return}const s=d.current?.offsetHeight||0,n=window.scrollY+s+b+10;let l="";const S=y.current;for(let c=r.length-1;c>=0;c--){const R=r[c],C=S.get(R.id);if(C!==void 0&&n>=C){l=R.id;break}}if(!l&&r.length>0){const c=S.get(r[0].id);c!==void 0&&n<c&&(l="")}x(l)},t=setTimeout(()=>{e()},200);return window.addEventListener("scroll",e,{passive:!0}),()=>{clearTimeout(t),window.removeEventListener("scroll",e),m.current&&clearTimeout(m.current)}},[r,b]),w(()=>{const e=document.querySelectorAll(".header"),t=[];return e.forEach(s=>{const n=s;t.push({element:n,originalPosition:n.style.position||getComputedStyle(n).position}),n.style.position="relative"}),()=>{t.forEach(({element:s,originalPosition:n})=>{s.style.position=n==="static"?"":n})}},[]);const j=(e,t)=>{e.preventDefault();const s=y.current.get(t);if(s===void 0){console.warn(`Cached position for "${t}" not found`);return}x(t),u.current=t,g.current=!0;const n=d.current?.offsetHeight||0,l=s-n-b;window.scrollTo({top:l,behavior:"smooth"}),window.history.pushState(null,"",`#${t}`)};return i("div",{id:H,ref:d,className:T("product-nav text-info-primary bg-container-primary tablet:px-8 laptop:px-16 desktop:px-16 lg-desktop:px-[calc(50%-832px)] !sticky top-0 !z-[51] flex w-full justify-between overflow-hidden px-4 py-0",{"aiui-dark":B==="dark"},k),children:[i("div",{className:"product-nav-main desktop:flex-row desktop:gap-[48px] flex w-full flex-col justify-start",children:[i("div",{className:"product-nav-header laptop:w-full desktop:w-fit desktop:gap-[24px] desktop:py-0 flex w-full flex-row items-center justify-between gap-[16px] pt-[14px]",children:[i("div",{className:"product-nav-tabs flex flex-row items-center gap-[8px]",children:[v.map((e,t)=>i("div",{className:"product-nav-tab-item flex items-center gap-[8px]",children:[o("a",{href:e.link,className:T("product-nav-tab-link hover:text-brand-color text-nowrap text-[14px] font-bold tracking-[-0.04em]",{"text-[#6D6D6F]":t!==0,"hidden desktop:block":t===1}),children:o("span",{children:e.label})}),t!==v.length-1&&o("div",{className:"product-nav-tab-divider desktop:inline-block hidden h-[14px] w-px bg-[#E4E5E6]"})]},e.link||t)),v.length>1&&i(E.Root,{children:[o(E.Trigger,{asChild:!0,children:o("button",{className:"product-nav-dropdown-trigger desktop:hidden -ml-1 inline-block","aria-label":"More products",children:o(O,{className:"text-[#1D1D1F]"})})}),o(E.Content,{className:"product-nav-dropdown-content rounded-[6px] border border-[#E4E5E6] bg-white p-[6px] px-[8px] py-[4px]",style:{boxShadow:"0px 4px 8px 0px rgba(0,0,0,0.12)"},side:"bottom",align:"end",alignOffset:10,sideOffset:10,children:v.slice(1).map(e=>o("a",{href:e.link,className:"product-nav-dropdown-link hover:text-brand-color text-nowrap",children:o("span",{children:e.label})},e.link))})]})]}),i("div",{className:"product-nav-mobile-actions desktop:hidden desktop:gap-[24px] flex items-center gap-[16px]",children:[a?.link&&o("a",{href:a.link,target:a.target||"_self",className:"product-nav-text-link hover:text-brand-color cursor-pointer",children:o(N,{size:2,className:"text-nowrap",children:a.text})}),p?.link&&o(L,{as:"a",href:p.link,size:"sm",className:"product-nav-buy-button text-nowrap",children:p.text})]})]}),o("div",{className:"product-nav-anchors laptop:w-fit desktop:gap-[24px] desktop:py-[8px] flex w-full items-center gap-[16px] overflow-x-scroll py-[12px] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",children:r.map((e,t)=>i("a",{href:`#${e.id}`,className:"product-nav-anchor-link",onClick:s=>{P?(s.preventDefault(),x(e.id),u.current=e.id,g.current=!0,P(e,t)):j(s,e.id)},children:[o(N,{size:2,className:"product-nav-anchor-text text-nowrap",children:e.label}),o("div",{className:T("product-nav-anchor-indicator laptop:top-[12px] desktop:top-[10px] relative top-[12px] h-[4px] w-full bg-transparent",{"!bg-brand-0":z===e.id})})]},e.id))})]}),i("div",{className:"product-nav-desktop-actions desktop:flex desktop:gap-[24px] desktop:py-[8px] hidden items-center gap-[16px]",children:[a?.link&&o("a",{href:a.link,target:a.target||"_self",className:"product-nav-text-link hover:text-brand-color cursor-pointer text-black",children:o(N,{size:2,className:"text-nowrap",children:a.text})}),p?.link&&o(L,{as:"a",href:p.link,size:"sm",className:"product-nav-buy-button text-nowrap",children:p.text})]})]})});M.displayName="ProductNav";var X=V(M);export{X as default};
|
|
2
2
|
//# sourceMappingURL=ProductNav.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/biz-components/ProductNav/ProductNav.tsx"],
|
|
4
|
-
"sourcesContent": ["'use client'\nimport { useState, useEffect, forwardRef, useImperativeHandle, useRef } from 'react'\nimport { cn } from '../../helpers/utils.js'\nimport { withLayout } from '../../shared/Styles.js'\nimport { Button, Text } from '../../components/index.js'\nimport { useExposure } from '../../hooks/useExposure.js'\nimport type { ProductNavProps } from './types.js'\nimport * as Popover from '@radix-ui/react-popover'\n\nconst componentType = 'navigation'\nconst componentName = 'product_nav'\n\nconst ChevronDownIcon = (props: React.SVGProps<SVGSVGElement>) => {\n return (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" {...props}>\n <path\n d=\"M5 7.5L10 12.5L15 7.5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.66667\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n )\n}\n\nconst ProductNav = forwardRef<HTMLDivElement, ProductNavProps>(\n ({ className = '', data, id, onAnchorClick, scrollOffsetExtra = 0 }, ref) => {\n const { tabLinks = [], anchorList = [], textLink, buyBtn, theme = 'light' } = data || {}\n const [activeAnchorId, setActiveAnchorId] = useState('')\n const innerRef = useRef<HTMLDivElement>(null)\n const isScrollingRef = useRef(false) // \u6807\u8BB0\u662F\u5426\u6B63\u5728\u7A0B\u5E8F\u5316\u6EDA\u52A8\u4E2D\n const targetAnchorIdRef = useRef<string>('') // \u8BB0\u5F55\u70B9\u51FB\u76EE\u6807\u951A\u70B9\n const scrollEndTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null) // \u6EDA\u52A8\u7ED3\u675F\u68C0\u6D4B\u5B9A\u65F6\u5668\n const anchorPositionsRef = useRef<Map<string, number>>(new Map()) // \u7F13\u5B58\u951A\u70B9\u539F\u59CB\u4F4D\u7F6E\n\n useImperativeHandle(ref, () => innerRef.current as HTMLDivElement)\n\n useExposure(innerRef, {\n componentType,\n componentName,\n })\n\n // \u521D\u59CB\u5316\u65F6\u7F13\u5B58\u6240\u6709\u951A\u70B9\u7684\u539F\u59CB\u4F4D\u7F6E\uFF08\u5728\u6EDA\u52A8\u524D\u8BA1\u7B97\uFF0C\u907F\u514D sticky \u5F71\u54CD\uFF09\n useEffect(() => {\n if (anchorList.length === 0) return\n\n // \u9875\u9762\u52A0\u8F7D\u540E\u5EF6\u8FDF\u8BA1\u7B97\uFF0C\u786E\u4FDD\u5E03\u5C40\u5B8C\u6210\n const timer = setTimeout(() => {\n // \u5148\u6EDA\u52A8\u5230\u9876\u90E8\u8BA1\u7B97\u771F\u5B9E\u4F4D\u7F6E\n const originalScrollY = window.scrollY\n window.scrollTo({ top: 0, behavior: 'instant' as ScrollBehavior })\n\n // \u7B49\u5F85\u4E00\u5E27\u8BA9\u5E03\u5C40\u7A33\u5B9A\n requestAnimationFrame(() => {\n const positions = new Map<string, number>()\n anchorList.forEach(anchor => {\n const element = document.getElementById(anchor.id)\n if (element) {\n const rect = element.getBoundingClientRect()\n positions.set(anchor.id, rect.top + window.scrollY)\n }\n })\n anchorPositionsRef.current = positions\n\n // \u6062\u590D\u539F\u6765\u7684\u6EDA\u52A8\u4F4D\u7F6E\n window.scrollTo({ top: originalScrollY, behavior: 'instant' as ScrollBehavior })\n })\n }, 100)\n\n return () => clearTimeout(timer)\n }, [anchorList])\n\n // \u6EDA\u52A8\u76D1\u542C\uFF1A\u68C0\u6D4B\u5F53\u524D\u6EDA\u52A8\u4F4D\u7F6E\u5BF9\u5E94\u7684\u951A\u70B9\n useEffect(() => {\n if (anchorList.length === 0) return\n\n const handleScroll = () => {\n // \u5982\u679C\u6B63\u5728\u7A0B\u5E8F\u5316\u6EDA\u52A8\u4E2D\uFF0C\u4F7F\u7528 debounce \u68C0\u6D4B\u6EDA\u52A8\u7ED3\u675F\n if (isScrollingRef.current) {\n // \u6E05\u9664\u4E4B\u524D\u7684\u5B9A\u65F6\u5668\n if (scrollEndTimerRef.current) {\n clearTimeout(scrollEndTimerRef.current)\n }\n // \u8BBE\u7F6E\u65B0\u7684\u5B9A\u65F6\u5668\uFF0C100ms \u6CA1\u6709\u65B0\u6EDA\u52A8\u4E8B\u4EF6\u5219\u8BA4\u4E3A\u6EDA\u52A8\u7ED3\u675F\n scrollEndTimerRef.current = setTimeout(() => {\n isScrollingRef.current = false\n // \u6EDA\u52A8\u7ED3\u675F\u540E\uFF0C\u786E\u4FDD\u9AD8\u4EAE\u505C\u7559\u5728\u76EE\u6807\u951A\u70B9\n if (targetAnchorIdRef.current) {\n setActiveAnchorId(targetAnchorIdRef.current)\n targetAnchorIdRef.current = ''\n }\n }, 100)\n return\n }\n\n const navHeight = innerRef.current?.offsetHeight || 0\n const scrollPosition = window.scrollY + navHeight + scrollOffsetExtra + 10 // 10px \u7F13\u51B2\n\n let currentAnchorId = ''\n\n // \u4F7F\u7528\u7F13\u5B58\u7684\u951A\u70B9\u4F4D\u7F6E\n const positions = anchorPositionsRef.current\n\n // \u904D\u5386\u6240\u6709\u951A\u70B9\uFF0C\u627E\u5230\u5F53\u524D\u6EDA\u52A8\u4F4D\u7F6E\u5BF9\u5E94\u7684\u951A\u70B9\n for (let i = anchorList.length - 1; i >= 0; i--) {\n const anchor = anchorList[i]\n const elementTop = positions.get(anchor.id)\n if (elementTop !== undefined && scrollPosition >= elementTop) {\n currentAnchorId = anchor.id\n break\n }\n }\n\n // \u5982\u679C\u6CA1\u6709\u627E\u5230\u4E14\u7F13\u5B58\u4E2D\u6709\u7B2C\u4E00\u4E2A\u951A\u70B9\u7684\u4F4D\u7F6E\n if (!currentAnchorId && anchorList.length > 0) {\n const firstElementTop = positions.get(anchorList[0].id)\n if (firstElementTop !== undefined && scrollPosition < firstElementTop) {\n currentAnchorId = ''\n }\n }\n\n setActiveAnchorId(currentAnchorId)\n }\n\n // \u5EF6\u8FDF\u521D\u59CB\u5316\uFF0C\u7B49\u5F85\u4F4D\u7F6E\u7F13\u5B58\u5B8C\u6210\n const timer = setTimeout(() => {\n handleScroll()\n }, 200)\n\n window.addEventListener('scroll', handleScroll, { passive: true })\n return () => {\n clearTimeout(timer)\n window.removeEventListener('scroll', handleScroll)\n // \u6E05\u7406\u5B9A\u65F6\u5668\n if (scrollEndTimerRef.current) {\n clearTimeout(scrollEndTimerRef.current)\n }\n }\n }, [anchorList, scrollOffsetExtra])\n\n // \u8BBE\u7F6E\u9875\u9762\u4E2Dheader\u5143\u7D20\u7684position\u4E3Arelative\n useEffect(() => {\n const headerElements = document.querySelectorAll('.header')\n const originalStyles: { element: HTMLElement; originalPosition: string }[] = []\n\n headerElements.forEach(element => {\n const htmlElement = element as HTMLElement\n // \u4FDD\u5B58\u539F\u59CB\u6837\u5F0F\n originalStyles.push({\n element: htmlElement,\n originalPosition: htmlElement.style.position || getComputedStyle(htmlElement).position,\n })\n // \u8BBE\u7F6E\u4E3Arelative\n htmlElement.style.position = 'relative'\n })\n\n // \u6E05\u7406\u51FD\u6570\uFF1A\u6062\u590D\u539F\u59CB\u6837\u5F0F\n return () => {\n originalStyles.forEach(({ element, originalPosition }) => {\n element.style.position = originalPosition === 'static' ? '' : originalPosition\n })\n }\n }, [])\n\n // \u5904\u7406\u951A\u70B9\u70B9\u51FB\u6EDA\u52A8\n const handleAnchorClick = (e: React.MouseEvent, anchorId: string) => {\n e.preventDefault()\n\n // \u4F7F\u7528\u7F13\u5B58\u7684\u4F4D\u7F6E\n const elementAbsoluteTop = anchorPositionsRef.current.get(anchorId)\n if (elementAbsoluteTop === undefined) {\n console.warn(`Cached position for \"${anchorId}\" not found`)\n return\n }\n\n // \u7ACB\u5373\u66F4\u65B0\u9AD8\u4EAE\u72B6\u6001\uFF0C\u907F\u514D\u6EDA\u52A8\u8FC7\u7A0B\u4E2D\u95EA\u70C1\n setActiveAnchorId(anchorId)\n\n // \u8BB0\u5F55\u76EE\u6807\u951A\u70B9\uFF0C\u7528\u4E8E\u6EDA\u52A8\u7ED3\u675F\u540E\u786E\u4FDD\u9AD8\u4EAE\u6B63\u786E\n targetAnchorIdRef.current = anchorId\n\n // \u6807\u8BB0\u6B63\u5728\u7A0B\u5E8F\u5316\u6EDA\u52A8\uFF0C\u6682\u505C\u6EDA\u52A8\u76D1\u542C\n isScrollingRef.current = true\n\n // \u83B7\u53D6\u5BFC\u822A\u680F\u9AD8\u5EA6\n const navHeight = innerRef.current?.offsetHeight || 0\n\n // \u76EE\u6807\u6EDA\u52A8\u4F4D\u7F6E = \u7F13\u5B58\u7684\u5143\u7D20\u7EDD\u5BF9\u4F4D\u7F6E - \u5BFC\u822A\u680F\u9AD8\u5EA6 - \u989D\u5916\u504F\u79FB\n const targetPosition = elementAbsoluteTop - navHeight - scrollOffsetExtra\n\n // \u5E73\u6ED1\u6EDA\u52A8\u5230\u76EE\u6807\u4F4D\u7F6E\n window.scrollTo({\n top: targetPosition,\n behavior: 'smooth',\n })\n\n // \u66F4\u65B0 URL hash\uFF08\u4E0D\u89E6\u53D1\u9875\u9762\u8DF3\u8F6C\uFF09\n window.history.pushState(null, '', `#${anchorId}`)\n\n // \u6CE8\u610F\uFF1A\u6EDA\u52A8\u7ED3\u675F\u68C0\u6D4B\u7531 handleScroll \u4E2D\u7684 debounce \u903B\u8F91\u5904\u7406\n // \u4E0D\u518D\u4F7F\u7528\u56FA\u5B9A 800ms \u8D85\u65F6\uFF0C\u800C\u662F\u68C0\u6D4B\u5B9E\u9645\u6EDA\u52A8\u7ED3\u675F\n }\n\n return (\n <div\n id={id}\n ref={innerRef}\n className={cn(\n 'product-nav text-info-primary bg-container-primary tablet:px-8 laptop:px-16 desktop:px-16 lg-desktop:px-[calc(50%-832px)] !sticky top-0 !z-[51] flex w-full justify-between overflow-hidden px-4 py-0',\n {\n 'aiui-dark': theme === 'dark',\n },\n className\n )}\n >\n <div className=\"product-nav-main desktop:flex-row desktop:gap-[48px] flex w-full flex-col justify-start\">\n {/* Tab Links Section */}\n <div className=\"product-nav-header laptop:w-full desktop:w-fit desktop:gap-[24px] desktop:py-0 flex w-full flex-row items-center justify-between gap-[16px] pt-[14px]\">\n <div className=\"product-nav-tabs flex flex-row items-center gap-[8px]\">\n {tabLinks.map((tabLink, index) => {\n return (\n <div key={tabLink.link || index} className=\"product-nav-tab-item flex items-center gap-[8px]\">\n <a\n href={tabLink.link}\n className={cn(\n 'product-nav-tab-link hover:text-brand-color text-nowrap text-[14px] font-bold tracking-[-0.04em]',\n {\n 'text-[#6D6D6F]': index !== 0,\n 'hidden desktop:block': index === 1,\n }\n )}\n // onClick={() => onShowSpecs?.(false)}\n >\n <span>{tabLink.label}</span>\n </a>\n {index !== tabLinks.length - 1 && (\n <div className=\"product-nav-tab-divider desktop:inline-block hidden h-[14px] w-px bg-[#E4E5E6]\" />\n )}\n </div>\n )\n })}\n\n {/* Mobile Dropdown */}\n {tabLinks.length > 1 && (\n <Popover.Root>\n <Popover.Trigger asChild>\n <button\n className=\"product-nav-dropdown-trigger desktop:hidden -ml-1 inline-block\"\n aria-label=\"More products\"\n >\n <ChevronDownIcon className=\"text-[#1D1D1F]\" />\n </button>\n </Popover.Trigger>\n <Popover.Content\n className=\"product-nav-dropdown-content rounded-[6px] border border-[#E4E5E6] bg-white p-[6px] px-[8px] py-[4px]\"\n style={{\n boxShadow: '0px 4px 8px 0px rgba(0,0,0,0.12)',\n }}\n side=\"bottom\"\n align=\"end\"\n alignOffset={10}\n sideOffset={10}\n >\n {tabLinks.slice(1).map(tabLink => (\n <a\n key={tabLink.link}\n href={tabLink.link}\n className=\"product-nav-dropdown-link hover:text-brand-color text-nowrap\"\n >\n <span>{tabLink.label}</span>\n </a>\n ))}\n </Popover.Content>\n </Popover.Root>\n )}\n </div>\n\n {/* Mobile Actions */}\n <div className=\"product-nav-mobile-actions desktop:hidden desktop:gap-[24px] flex items-center gap-[16px]\">\n {/* {specs?.text && (\n <Text\n size={2}\n onClick={handleSpecsClick}\n className=\"product-nav-specs-button cursor-pointer hover:text-brand-color\"\n >\n {specs.text}\n </Text>\n )} */}\n {textLink?.link && (\n <a\n href={textLink.link}\n target={textLink.target || '_self'}\n className=\"product-nav-text-link hover:text-brand-color cursor-pointer\"\n >\n <Text size={2} className=\"text-nowrap\">\n {textLink.text}\n </Text>\n </a>\n )}\n {buyBtn?.link && (\n <Button as=\"a\" href={buyBtn.link} size=\"sm\" className=\"product-nav-buy-button text-nowrap\">\n {buyBtn.text}\n </Button>\n )}\n </div>\n </div>\n\n {/* Anchor Navigation */}\n <div className=\"product-nav-anchors laptop:w-fit desktop:gap-[24px] desktop:py-[8px] flex w-full items-center gap-[16px] overflow-x-scroll py-[12px] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden\">\n {anchorList.map((anchor, index) => (\n <a\n key={anchor.id}\n href={`#${anchor.id}`}\n className=\"product-nav-anchor-link\"\n onClick={e => {\n // \u5982\u679C\u63D0\u4F9B\u4E86\u81EA\u5B9A\u4E49\u70B9\u51FB\u4E8B\u4EF6,\u4F7F\u7528\u81EA\u5B9A\u4E49\u4E8B\u4EF6\u5E76\u963B\u6B62\u9ED8\u8BA4\u884C\u4E3A\n if (onAnchorClick) {\n e.preventDefault()\n // \u6807\u8BB0\u7A0B\u5E8F\u5316\u6EDA\u52A8\uFF0C\u907F\u514D\u6EDA\u52A8\u8FC7\u7A0B\u4E2D\u9AD8\u4EAE\u95EA\u70C1\n setActiveAnchorId(anchor.id)\n targetAnchorIdRef.current = anchor.id\n isScrollingRef.current = true\n onAnchorClick(anchor, index)\n } else {\n // \u4F7F\u7528\u9ED8\u8BA4\u7684\u951A\u70B9\u6EDA\u52A8\u884C\u4E3A\uFF0C\u5E26\u504F\u79FB\u91CF\n handleAnchorClick(e, anchor.id)\n }\n }}\n >\n <Text size={2} className=\"product-nav-anchor-text text-nowrap\">\n {anchor.label}\n </Text>\n <div\n className={cn(\n 'product-nav-anchor-indicator laptop:top-[12px] desktop:top-[10px] relative top-[12px] h-[4px] w-full bg-transparent',\n {\n '!bg-brand-0': activeAnchorId === anchor.id,\n }\n )}\n />\n </a>\n ))}\n </div>\n </div>\n\n {/* Desktop Actions */}\n <div className=\"product-nav-desktop-actions desktop:flex desktop:gap-[24px] desktop:py-[8px] hidden items-center gap-[16px]\">\n {/* {specs?.text && (\n <Text\n size={2}\n onClick={handleSpecsClick}\n className=\"product-nav-specs-button cursor-pointer text-black hover:text-brand-color\"\n >\n {specs.text}\n </Text>\n )} */}\n {textLink?.link && (\n <a\n href={textLink.link}\n target={textLink.target || '_self'}\n className=\"product-nav-text-link hover:text-brand-color cursor-pointer text-black\"\n >\n <Text size={2} className=\"text-nowrap\">\n {textLink.text}\n </Text>\n </a>\n )}\n {buyBtn?.link && (\n <Button as=\"a\" href={buyBtn.link} size=\"sm\" className=\"product-nav-buy-button text-nowrap\">\n {buyBtn.text}\n </Button>\n )}\n </div>\n </div>\n )\n }\n)\n\nProductNav.displayName = 'ProductNav'\n\nexport default withLayout(ProductNav)\n"],
|
|
5
|
-
"mappings": "aAeM,cAAAA,
|
|
6
|
-
"names": ["jsx", "jsxs", "useState", "useEffect", "forwardRef", "useImperativeHandle", "useRef", "cn", "withLayout", "Button", "Text", "useExposure", "Popover", "componentType", "componentName", "ChevronDownIcon", "props", "ProductNav", "className", "data", "id", "onAnchorClick", "scrollOffsetExtra", "ref", "tabLinks", "anchorList", "textLink", "buyBtn", "theme", "activeAnchorId", "setActiveAnchorId", "innerRef", "isScrollingRef", "targetAnchorIdRef", "scrollEndTimerRef", "anchorPositionsRef", "
|
|
4
|
+
"sourcesContent": ["'use client'\nimport { useState, useEffect, useCallback, forwardRef, useImperativeHandle, useRef } from 'react'\nimport { cn } from '../../helpers/utils.js'\nimport { withLayout } from '../../shared/Styles.js'\nimport { Button, Text } from '../../components/index.js'\nimport { useExposure } from '../../hooks/useExposure.js'\nimport type { ProductNavProps } from './types.js'\nimport * as Popover from '@radix-ui/react-popover'\n\nconst componentType = 'navigation'\nconst componentName = 'product_nav'\n\nconst ChevronDownIcon = (props: React.SVGProps<SVGSVGElement>) => {\n return (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" {...props}>\n <path\n d=\"M5 7.5L10 12.5L15 7.5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.66667\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n )\n}\n\nconst ProductNav = forwardRef<HTMLDivElement, ProductNavProps>(\n ({ className = '', data, id, onAnchorClick, scrollOffsetExtra = 0 }, ref) => {\n const { tabLinks = [], anchorList = [], textLink, buyBtn, theme = 'light' } = data || {}\n const [activeAnchorId, setActiveAnchorId] = useState('')\n const innerRef = useRef<HTMLDivElement>(null)\n const isScrollingRef = useRef(false) // \u6807\u8BB0\u662F\u5426\u6B63\u5728\u7A0B\u5E8F\u5316\u6EDA\u52A8\u4E2D\n const targetAnchorIdRef = useRef<string>('') // \u8BB0\u5F55\u70B9\u51FB\u76EE\u6807\u951A\u70B9\n const scrollEndTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null) // \u6EDA\u52A8\u7ED3\u675F\u68C0\u6D4B\u5B9A\u65F6\u5668\n const anchorPositionsRef = useRef<Map<string, number>>(new Map()) // \u7F13\u5B58\u951A\u70B9\u539F\u59CB\u4F4D\u7F6E\n\n useImperativeHandle(ref, () => innerRef.current as HTMLDivElement)\n\n useExposure(innerRef, {\n componentType,\n componentName,\n })\n\n // \u7F13\u5B58\u6240\u6709\u951A\u70B9\u7684\u7EDD\u5BF9\u4F4D\u7F6E\uFF08\u6EDA\u52A8\u5230\u9876\u90E8\u540E\u8BA1\u7B97\uFF0C\u907F\u514D sticky \u5F71\u54CD\uFF09\n const updateAnchorPositions = useCallback(() => {\n if (anchorList.length === 0) return\n\n const originalScrollY = window.scrollY\n window.scrollTo({ top: 0, behavior: 'instant' as ScrollBehavior })\n\n requestAnimationFrame(() => {\n const positions = new Map<string, number>()\n anchorList.forEach(anchor => {\n const element = document.getElementById(anchor.id)\n if (element) {\n const rect = element.getBoundingClientRect()\n positions.set(anchor.id, rect.top + window.scrollY)\n }\n })\n anchorPositionsRef.current = positions\n\n window.scrollTo({ top: originalScrollY, behavior: 'instant' as ScrollBehavior })\n })\n }, [anchorList])\n\n // \u521D\u59CB\u5316\u65F6\u7F13\u5B58\u6240\u6709\u951A\u70B9\u7684\u539F\u59CB\u4F4D\u7F6E\n useEffect(() => {\n if (anchorList.length === 0) return\n\n // \u9875\u9762\u52A0\u8F7D\u540E\u5EF6\u8FDF\u8BA1\u7B97\uFF0C\u786E\u4FDD\u5E03\u5C40\u5B8C\u6210\n const timer = setTimeout(updateAnchorPositions, 100)\n\n return () => clearTimeout(timer)\n }, [anchorList, updateAnchorPositions])\n\n // \u76D1\u542C body \u9AD8\u5EA6\u53D8\u5316\uFF0C\u9AD8\u5EA6\u6539\u53D8\u65F6\u91CD\u65B0\u8BA1\u7B97\u951A\u70B9\u4F4D\u7F6E\n useEffect(() => {\n if (anchorList.length === 0) return\n\n let resizeTimer: ReturnType<typeof setTimeout> | null = null\n\n const observer = new ResizeObserver(() => {\n // debounce\uFF0C\u907F\u514D\u9AD8\u9891\u89E6\u53D1\n if (resizeTimer) clearTimeout(resizeTimer)\n resizeTimer = setTimeout(updateAnchorPositions, 150)\n })\n\n observer.observe(document.body)\n\n return () => {\n observer.disconnect()\n if (resizeTimer) clearTimeout(resizeTimer)\n }\n }, [anchorList, updateAnchorPositions])\n\n // \u6EDA\u52A8\u76D1\u542C\uFF1A\u68C0\u6D4B\u5F53\u524D\u6EDA\u52A8\u4F4D\u7F6E\u5BF9\u5E94\u7684\u951A\u70B9\n useEffect(() => {\n if (anchorList.length === 0) return\n\n const handleScroll = () => {\n // \u5982\u679C\u6B63\u5728\u7A0B\u5E8F\u5316\u6EDA\u52A8\u4E2D\uFF0C\u4F7F\u7528 debounce \u68C0\u6D4B\u6EDA\u52A8\u7ED3\u675F\n if (isScrollingRef.current) {\n // \u6E05\u9664\u4E4B\u524D\u7684\u5B9A\u65F6\u5668\n if (scrollEndTimerRef.current) {\n clearTimeout(scrollEndTimerRef.current)\n }\n // \u8BBE\u7F6E\u65B0\u7684\u5B9A\u65F6\u5668\uFF0C100ms \u6CA1\u6709\u65B0\u6EDA\u52A8\u4E8B\u4EF6\u5219\u8BA4\u4E3A\u6EDA\u52A8\u7ED3\u675F\n scrollEndTimerRef.current = setTimeout(() => {\n isScrollingRef.current = false\n // \u6EDA\u52A8\u7ED3\u675F\u540E\uFF0C\u786E\u4FDD\u9AD8\u4EAE\u505C\u7559\u5728\u76EE\u6807\u951A\u70B9\n if (targetAnchorIdRef.current) {\n setActiveAnchorId(targetAnchorIdRef.current)\n targetAnchorIdRef.current = ''\n }\n }, 100)\n return\n }\n\n const navHeight = innerRef.current?.offsetHeight || 0\n const scrollPosition = window.scrollY + navHeight + scrollOffsetExtra + 10 // 10px \u7F13\u51B2\n\n let currentAnchorId = ''\n\n // \u4F7F\u7528\u7F13\u5B58\u7684\u951A\u70B9\u4F4D\u7F6E\n const positions = anchorPositionsRef.current\n\n // \u904D\u5386\u6240\u6709\u951A\u70B9\uFF0C\u627E\u5230\u5F53\u524D\u6EDA\u52A8\u4F4D\u7F6E\u5BF9\u5E94\u7684\u951A\u70B9\n for (let i = anchorList.length - 1; i >= 0; i--) {\n const anchor = anchorList[i]\n const elementTop = positions.get(anchor.id)\n if (elementTop !== undefined && scrollPosition >= elementTop) {\n currentAnchorId = anchor.id\n break\n }\n }\n\n // \u5982\u679C\u6CA1\u6709\u627E\u5230\u4E14\u7F13\u5B58\u4E2D\u6709\u7B2C\u4E00\u4E2A\u951A\u70B9\u7684\u4F4D\u7F6E\n if (!currentAnchorId && anchorList.length > 0) {\n const firstElementTop = positions.get(anchorList[0].id)\n if (firstElementTop !== undefined && scrollPosition < firstElementTop) {\n currentAnchorId = ''\n }\n }\n\n setActiveAnchorId(currentAnchorId)\n }\n\n // \u5EF6\u8FDF\u521D\u59CB\u5316\uFF0C\u7B49\u5F85\u4F4D\u7F6E\u7F13\u5B58\u5B8C\u6210\n const timer = setTimeout(() => {\n handleScroll()\n }, 200)\n\n window.addEventListener('scroll', handleScroll, { passive: true })\n return () => {\n clearTimeout(timer)\n window.removeEventListener('scroll', handleScroll)\n // \u6E05\u7406\u5B9A\u65F6\u5668\n if (scrollEndTimerRef.current) {\n clearTimeout(scrollEndTimerRef.current)\n }\n }\n }, [anchorList, scrollOffsetExtra])\n\n // \u8BBE\u7F6E\u9875\u9762\u4E2Dheader\u5143\u7D20\u7684position\u4E3Arelative\n useEffect(() => {\n const headerElements = document.querySelectorAll('.header')\n const originalStyles: { element: HTMLElement; originalPosition: string }[] = []\n\n headerElements.forEach(element => {\n const htmlElement = element as HTMLElement\n // \u4FDD\u5B58\u539F\u59CB\u6837\u5F0F\n originalStyles.push({\n element: htmlElement,\n originalPosition: htmlElement.style.position || getComputedStyle(htmlElement).position,\n })\n // \u8BBE\u7F6E\u4E3Arelative\n htmlElement.style.position = 'relative'\n })\n\n // \u6E05\u7406\u51FD\u6570\uFF1A\u6062\u590D\u539F\u59CB\u6837\u5F0F\n return () => {\n originalStyles.forEach(({ element, originalPosition }) => {\n element.style.position = originalPosition === 'static' ? '' : originalPosition\n })\n }\n }, [])\n\n // \u5904\u7406\u951A\u70B9\u70B9\u51FB\u6EDA\u52A8\n const handleAnchorClick = (e: React.MouseEvent, anchorId: string) => {\n e.preventDefault()\n\n // \u4F7F\u7528\u7F13\u5B58\u7684\u4F4D\u7F6E\n const elementAbsoluteTop = anchorPositionsRef.current.get(anchorId)\n if (elementAbsoluteTop === undefined) {\n console.warn(`Cached position for \"${anchorId}\" not found`)\n return\n }\n\n // \u7ACB\u5373\u66F4\u65B0\u9AD8\u4EAE\u72B6\u6001\uFF0C\u907F\u514D\u6EDA\u52A8\u8FC7\u7A0B\u4E2D\u95EA\u70C1\n setActiveAnchorId(anchorId)\n\n // \u8BB0\u5F55\u76EE\u6807\u951A\u70B9\uFF0C\u7528\u4E8E\u6EDA\u52A8\u7ED3\u675F\u540E\u786E\u4FDD\u9AD8\u4EAE\u6B63\u786E\n targetAnchorIdRef.current = anchorId\n\n // \u6807\u8BB0\u6B63\u5728\u7A0B\u5E8F\u5316\u6EDA\u52A8\uFF0C\u6682\u505C\u6EDA\u52A8\u76D1\u542C\n isScrollingRef.current = true\n\n // \u83B7\u53D6\u5BFC\u822A\u680F\u9AD8\u5EA6\n const navHeight = innerRef.current?.offsetHeight || 0\n\n // \u76EE\u6807\u6EDA\u52A8\u4F4D\u7F6E = \u7F13\u5B58\u7684\u5143\u7D20\u7EDD\u5BF9\u4F4D\u7F6E - \u5BFC\u822A\u680F\u9AD8\u5EA6 - \u989D\u5916\u504F\u79FB\n const targetPosition = elementAbsoluteTop - navHeight - scrollOffsetExtra\n\n // \u5E73\u6ED1\u6EDA\u52A8\u5230\u76EE\u6807\u4F4D\u7F6E\n window.scrollTo({\n top: targetPosition,\n behavior: 'smooth',\n })\n\n // \u66F4\u65B0 URL hash\uFF08\u4E0D\u89E6\u53D1\u9875\u9762\u8DF3\u8F6C\uFF09\n window.history.pushState(null, '', `#${anchorId}`)\n\n // \u6CE8\u610F\uFF1A\u6EDA\u52A8\u7ED3\u675F\u68C0\u6D4B\u7531 handleScroll \u4E2D\u7684 debounce \u903B\u8F91\u5904\u7406\n // \u4E0D\u518D\u4F7F\u7528\u56FA\u5B9A 800ms \u8D85\u65F6\uFF0C\u800C\u662F\u68C0\u6D4B\u5B9E\u9645\u6EDA\u52A8\u7ED3\u675F\n }\n\n return (\n <div\n id={id}\n ref={innerRef}\n className={cn(\n 'product-nav text-info-primary bg-container-primary tablet:px-8 laptop:px-16 desktop:px-16 lg-desktop:px-[calc(50%-832px)] !sticky top-0 !z-[51] flex w-full justify-between overflow-hidden px-4 py-0',\n {\n 'aiui-dark': theme === 'dark',\n },\n className\n )}\n >\n <div className=\"product-nav-main desktop:flex-row desktop:gap-[48px] flex w-full flex-col justify-start\">\n {/* Tab Links Section */}\n <div className=\"product-nav-header laptop:w-full desktop:w-fit desktop:gap-[24px] desktop:py-0 flex w-full flex-row items-center justify-between gap-[16px] pt-[14px]\">\n <div className=\"product-nav-tabs flex flex-row items-center gap-[8px]\">\n {tabLinks.map((tabLink, index) => {\n return (\n <div key={tabLink.link || index} className=\"product-nav-tab-item flex items-center gap-[8px]\">\n <a\n href={tabLink.link}\n className={cn(\n 'product-nav-tab-link hover:text-brand-color text-nowrap text-[14px] font-bold tracking-[-0.04em]',\n {\n 'text-[#6D6D6F]': index !== 0,\n 'hidden desktop:block': index === 1,\n }\n )}\n // onClick={() => onShowSpecs?.(false)}\n >\n <span>{tabLink.label}</span>\n </a>\n {index !== tabLinks.length - 1 && (\n <div className=\"product-nav-tab-divider desktop:inline-block hidden h-[14px] w-px bg-[#E4E5E6]\" />\n )}\n </div>\n )\n })}\n\n {/* Mobile Dropdown */}\n {tabLinks.length > 1 && (\n <Popover.Root>\n <Popover.Trigger asChild>\n <button\n className=\"product-nav-dropdown-trigger desktop:hidden -ml-1 inline-block\"\n aria-label=\"More products\"\n >\n <ChevronDownIcon className=\"text-[#1D1D1F]\" />\n </button>\n </Popover.Trigger>\n <Popover.Content\n className=\"product-nav-dropdown-content rounded-[6px] border border-[#E4E5E6] bg-white p-[6px] px-[8px] py-[4px]\"\n style={{\n boxShadow: '0px 4px 8px 0px rgba(0,0,0,0.12)',\n }}\n side=\"bottom\"\n align=\"end\"\n alignOffset={10}\n sideOffset={10}\n >\n {tabLinks.slice(1).map(tabLink => (\n <a\n key={tabLink.link}\n href={tabLink.link}\n className=\"product-nav-dropdown-link hover:text-brand-color text-nowrap\"\n >\n <span>{tabLink.label}</span>\n </a>\n ))}\n </Popover.Content>\n </Popover.Root>\n )}\n </div>\n\n {/* Mobile Actions */}\n <div className=\"product-nav-mobile-actions desktop:hidden desktop:gap-[24px] flex items-center gap-[16px]\">\n {/* {specs?.text && (\n <Text\n size={2}\n onClick={handleSpecsClick}\n className=\"product-nav-specs-button cursor-pointer hover:text-brand-color\"\n >\n {specs.text}\n </Text>\n )} */}\n {textLink?.link && (\n <a\n href={textLink.link}\n target={textLink.target || '_self'}\n className=\"product-nav-text-link hover:text-brand-color cursor-pointer\"\n >\n <Text size={2} className=\"text-nowrap\">\n {textLink.text}\n </Text>\n </a>\n )}\n {buyBtn?.link && (\n <Button as=\"a\" href={buyBtn.link} size=\"sm\" className=\"product-nav-buy-button text-nowrap\">\n {buyBtn.text}\n </Button>\n )}\n </div>\n </div>\n\n {/* Anchor Navigation */}\n <div className=\"product-nav-anchors laptop:w-fit desktop:gap-[24px] desktop:py-[8px] flex w-full items-center gap-[16px] overflow-x-scroll py-[12px] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden\">\n {anchorList.map((anchor, index) => (\n <a\n key={anchor.id}\n href={`#${anchor.id}`}\n className=\"product-nav-anchor-link\"\n onClick={e => {\n // \u5982\u679C\u63D0\u4F9B\u4E86\u81EA\u5B9A\u4E49\u70B9\u51FB\u4E8B\u4EF6,\u4F7F\u7528\u81EA\u5B9A\u4E49\u4E8B\u4EF6\u5E76\u963B\u6B62\u9ED8\u8BA4\u884C\u4E3A\n if (onAnchorClick) {\n e.preventDefault()\n // \u6807\u8BB0\u7A0B\u5E8F\u5316\u6EDA\u52A8\uFF0C\u907F\u514D\u6EDA\u52A8\u8FC7\u7A0B\u4E2D\u9AD8\u4EAE\u95EA\u70C1\n setActiveAnchorId(anchor.id)\n targetAnchorIdRef.current = anchor.id\n isScrollingRef.current = true\n onAnchorClick(anchor, index)\n } else {\n // \u4F7F\u7528\u9ED8\u8BA4\u7684\u951A\u70B9\u6EDA\u52A8\u884C\u4E3A\uFF0C\u5E26\u504F\u79FB\u91CF\n handleAnchorClick(e, anchor.id)\n }\n }}\n >\n <Text size={2} className=\"product-nav-anchor-text text-nowrap\">\n {anchor.label}\n </Text>\n <div\n className={cn(\n 'product-nav-anchor-indicator laptop:top-[12px] desktop:top-[10px] relative top-[12px] h-[4px] w-full bg-transparent',\n {\n '!bg-brand-0': activeAnchorId === anchor.id,\n }\n )}\n />\n </a>\n ))}\n </div>\n </div>\n\n {/* Desktop Actions */}\n <div className=\"product-nav-desktop-actions desktop:flex desktop:gap-[24px] desktop:py-[8px] hidden items-center gap-[16px]\">\n {/* {specs?.text && (\n <Text\n size={2}\n onClick={handleSpecsClick}\n className=\"product-nav-specs-button cursor-pointer text-black hover:text-brand-color\"\n >\n {specs.text}\n </Text>\n )} */}\n {textLink?.link && (\n <a\n href={textLink.link}\n target={textLink.target || '_self'}\n className=\"product-nav-text-link hover:text-brand-color cursor-pointer text-black\"\n >\n <Text size={2} className=\"text-nowrap\">\n {textLink.text}\n </Text>\n </a>\n )}\n {buyBtn?.link && (\n <Button as=\"a\" href={buyBtn.link} size=\"sm\" className=\"product-nav-buy-button text-nowrap\">\n {buyBtn.text}\n </Button>\n )}\n </div>\n </div>\n )\n }\n)\n\nProductNav.displayName = 'ProductNav'\n\nexport default withLayout(ProductNav)\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["jsx", "jsxs", "useState", "useEffect", "useCallback", "forwardRef", "useImperativeHandle", "useRef", "cn", "withLayout", "Button", "Text", "useExposure", "Popover", "componentType", "componentName", "ChevronDownIcon", "props", "ProductNav", "className", "data", "id", "onAnchorClick", "scrollOffsetExtra", "ref", "tabLinks", "anchorList", "textLink", "buyBtn", "theme", "activeAnchorId", "setActiveAnchorId", "innerRef", "isScrollingRef", "targetAnchorIdRef", "scrollEndTimerRef", "anchorPositionsRef", "updateAnchorPositions", "originalScrollY", "positions", "anchor", "element", "rect", "timer", "resizeTimer", "observer", "handleScroll", "navHeight", "scrollPosition", "currentAnchorId", "i", "elementTop", "firstElementTop", "headerElements", "originalStyles", "htmlElement", "originalPosition", "handleAnchorClick", "anchorId", "elementAbsoluteTop", "targetPosition", "tabLink", "index", "e", "ProductNav_default"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import{jsx as
|
|
1
|
+
"use client";import{jsx as e,jsxs as s}from"react/jsx-runtime";import{withLayout as n}from"../../shared/Styles.js";import*as a from"../../components/tabs.js";import{cn as b,isLexicalEmpty as t}from"../../helpers/index.js";import h from"react";import k from"../ShelfDisplay/index.js";import g from"../AccordionCards/index.js";import N from"../Faq/index.js";import v from"../MultiLayoutGraphicBlock/MultiLayoutGraphicBlock.js";import m from"../Title/index.js";import L from"../Graphic/index.js";import P from"../WhyChoose/index.js";import A from"../BrandEquity/index.js";import q from"../BrandCardLink/index.js";import x from"../ImageWithText/index.js";const o=h.forwardRef(({data:p,className:c},d)=>{const{theme:T,shape:f,align:u,tabs:r=[],sectionTitle:l}=p,y=i=>i?.blockType==="ipc-shelfdisplay"?e(k,{data:i}):i?.blockType==="ipc-multiLayoutGraphicBlock"?e(v,{data:i}):i?.blockType==="ipc-accordioncards"?e(g,{data:i}):i?.blockType==="ipc-faq"?e(N,{data:i}):i?.blockType==="ipc-graphic"?e(L,{data:i}):i?.blockType==="ipc-whychoose"?e(P,{data:i}):i?.blockType==="ipc-brand-equity"?e(A,{data:i}):i?.blockType==="ipc-brand-card-link"?e(q,{data:i}):i?.blockType==="ImageWithText"?e(x,{data:i}):null;return s("section",{ref:d,className:b(T==="dark"?"aiui-dark":"",c),children:[l&&e(m,{className:"section-title",data:{title:l}}),s(a.Tabs,{shape:f,align:u,defaultValue:r?.[0]?.id||r?.[0]?.tabName,children:[Array.isArray(r)&&r.length>1&&e(a.TabsList,{className:"tabs-list",children:r.map(i=>e(a.TabsTrigger,{value:i.id||i.tabName,className:"tabs-trigger",children:i.tabName},i.id||i.tabName))}),(Array.isArray(r)?r:[])?.map(i=>s(a.TabsContent,{value:i.id||i.tabName,className:`tabs-content ${r?.length>1?"mt-[24px]":""}`,children:[!t(i.caption)||!t(i?.subtitle)?e(m,{className:"tabs-title",data:{caption:i?.caption,subtitle:i?.subtitle}}):null,i.tabContent?.[0]?y(i.tabContent?.[0]):null]},i.id||i.tabName))]})]})});o.displayName="Tabs";var $=n(o);export{$ as default};
|
|
2
2
|
//# sourceMappingURL=Tabs.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/biz-components/Tabs/Tabs.tsx"],
|
|
4
|
-
"sourcesContent": ["'use client'\nimport { withLayout } from '../../shared/Styles.js'\nimport * as TabsPrimitive from '../../components/tabs.js'\nimport { cn, isLexicalEmpty } from '../../helpers/index.js'\nimport type { TabsProps } from './types.js'\nimport React from 'react'\nimport ShelfDisplay from '../ShelfDisplay/index.js'\nimport AccordionCards from '../AccordionCards/index.js'\nimport Faq from '../Faq/index.js'\nimport MultiLayoutGraphicBlock from '../MultiLayoutGraphicBlock/MultiLayoutGraphicBlock.js'\nimport Title from '../Title/index.js'\nimport Graphic from '../Graphic/index.js'\nimport WhyChoose from '../WhyChoose/index.js'\nimport BrandEquity from '../BrandEquity/index.js'\nimport BrandCardLink from '../BrandCardLink/index.js'\n\nconst Tabs = React.forwardRef<HTMLDivElement, TabsProps>(({ data, className }, forwardedRef) => {\n const { theme, shape, align, tabs = [], sectionTitle } = data\n\n const renderTabContent = (tabContent: TabsProps['data']['tabs'][number]['tabContent'][number]) => {\n if (tabContent?.blockType === 'ipc-shelfdisplay') {\n return <ShelfDisplay data={tabContent} />\n } else if (tabContent?.blockType === 'ipc-multiLayoutGraphicBlock') {\n return <MultiLayoutGraphicBlock data={tabContent} />\n } else if (tabContent?.blockType === 'ipc-accordioncards') {\n return <AccordionCards data={tabContent} />\n } else if (tabContent?.blockType === 'ipc-faq') {\n return <Faq data={tabContent} />\n } else if (tabContent?.blockType === 'ipc-graphic') {\n return <Graphic data={tabContent} />\n } else if (tabContent?.blockType === 'ipc-whychoose') {\n return <WhyChoose data={tabContent} />\n } else if (tabContent?.blockType === 'ipc-brand-equity') {\n return <BrandEquity data={tabContent} />\n } else if (tabContent?.blockType === 'ipc-brand-card-link') {\n return <BrandCardLink data={tabContent} />\n } else {\n return null\n }\n }\n\n return (\n <section ref={forwardedRef} className={cn(theme === 'dark' ? 'aiui-dark' : '', className)}>\n {sectionTitle && <Title className=\"section-title\" data={{ title: sectionTitle }} />}\n <TabsPrimitive.Tabs shape={shape} align={align} defaultValue={tabs?.[0]?.id || tabs?.[0]?.tabName}>\n {/* <TabsPrimitive.TabsList className=\"tabs-list\">\n {(Array.isArray(tabs) ? tabs : [])?.map(tab => (\n <TabsPrimitive.TabsTrigger\n key={tab.id || tab.tabName}\n value={tab.id || tab.tabName}\n className=\"tabs-trigger\"\n >\n {tab.tabName}\n </TabsPrimitive.TabsTrigger>\n ))}\n </TabsPrimitive.TabsList> */}\n {/* Tab\u4E3A1\u65F6\uFF0C\u4E0D\u5C55\u793Atab\u6309\u94AE */}\n {Array.isArray(tabs) && tabs.length > 1 && (\n <TabsPrimitive.TabsList className=\"tabs-list\">\n {tabs.map(tab => (\n <TabsPrimitive.TabsTrigger\n key={tab.id || tab.tabName}\n value={tab.id || tab.tabName}\n className=\"tabs-trigger\"\n >\n {tab.tabName}\n </TabsPrimitive.TabsTrigger>\n ))}\n </TabsPrimitive.TabsList>\n )}\n {(Array.isArray(tabs) ? tabs : [])?.map((tab: any) => (\n <TabsPrimitive.TabsContent\n key={tab.id || tab.tabName}\n value={tab.id || tab.tabName}\n className={`tabs-content ${tabs?.length > 1 ? 'mt-[24px]' : ''}`}\n >\n {!isLexicalEmpty(tab.caption) || !isLexicalEmpty(tab?.subtitle) ? (\n <Title className=\"tabs-title\" data={{ caption: tab?.caption, subtitle: tab?.subtitle }} />\n ) : null}\n {tab.tabContent?.[0] ? renderTabContent(tab.tabContent?.[0]) : null}\n </TabsPrimitive.TabsContent>\n ))}\n </TabsPrimitive.Tabs>\n </section>\n )\n})\nTabs.displayName = 'Tabs'\nexport default withLayout(Tabs)\n"],
|
|
5
|
-
"mappings": "
|
|
6
|
-
"names": ["jsx", "jsxs", "withLayout", "TabsPrimitive", "cn", "isLexicalEmpty", "React", "ShelfDisplay", "AccordionCards", "Faq", "MultiLayoutGraphicBlock", "Title", "Graphic", "WhyChoose", "BrandEquity", "BrandCardLink", "Tabs", "data", "className", "forwardedRef", "theme", "shape", "align", "tabs", "sectionTitle", "renderTabContent", "tabContent", "tab", "Tabs_default"]
|
|
4
|
+
"sourcesContent": ["'use client'\nimport { withLayout } from '../../shared/Styles.js'\nimport * as TabsPrimitive from '../../components/tabs.js'\nimport { cn, isLexicalEmpty } from '../../helpers/index.js'\nimport type { TabsProps } from './types.js'\nimport React from 'react'\nimport ShelfDisplay from '../ShelfDisplay/index.js'\nimport AccordionCards from '../AccordionCards/index.js'\nimport Faq from '../Faq/index.js'\nimport MultiLayoutGraphicBlock from '../MultiLayoutGraphicBlock/MultiLayoutGraphicBlock.js'\nimport Title from '../Title/index.js'\nimport Graphic from '../Graphic/index.js'\nimport WhyChoose from '../WhyChoose/index.js'\nimport BrandEquity from '../BrandEquity/index.js'\nimport BrandCardLink from '../BrandCardLink/index.js'\nimport ImageWithText from '../ImageWithText/index.js'\n\nconst Tabs = React.forwardRef<HTMLDivElement, TabsProps>(({ data, className }, forwardedRef) => {\n const { theme, shape, align, tabs = [], sectionTitle } = data\n\n const renderTabContent = (tabContent: TabsProps['data']['tabs'][number]['tabContent'][number]) => {\n if (tabContent?.blockType === 'ipc-shelfdisplay') {\n return <ShelfDisplay data={tabContent} />\n } else if (tabContent?.blockType === 'ipc-multiLayoutGraphicBlock') {\n return <MultiLayoutGraphicBlock data={tabContent} />\n } else if (tabContent?.blockType === 'ipc-accordioncards') {\n return <AccordionCards data={tabContent} />\n } else if (tabContent?.blockType === 'ipc-faq') {\n return <Faq data={tabContent} />\n } else if (tabContent?.blockType === 'ipc-graphic') {\n return <Graphic data={tabContent} />\n } else if (tabContent?.blockType === 'ipc-whychoose') {\n return <WhyChoose data={tabContent} />\n } else if (tabContent?.blockType === 'ipc-brand-equity') {\n return <BrandEquity data={tabContent} />\n } else if (tabContent?.blockType === 'ipc-brand-card-link') {\n return <BrandCardLink data={tabContent} />\n } else if (tabContent?.blockType === 'ImageWithText') {\n return <ImageWithText data={tabContent} />\n } else {\n return null\n }\n }\n\n return (\n <section ref={forwardedRef} className={cn(theme === 'dark' ? 'aiui-dark' : '', className)}>\n {sectionTitle && <Title className=\"section-title\" data={{ title: sectionTitle }} />}\n <TabsPrimitive.Tabs shape={shape} align={align} defaultValue={tabs?.[0]?.id || tabs?.[0]?.tabName}>\n {/* <TabsPrimitive.TabsList className=\"tabs-list\">\n {(Array.isArray(tabs) ? tabs : [])?.map(tab => (\n <TabsPrimitive.TabsTrigger\n key={tab.id || tab.tabName}\n value={tab.id || tab.tabName}\n className=\"tabs-trigger\"\n >\n {tab.tabName}\n </TabsPrimitive.TabsTrigger>\n ))}\n </TabsPrimitive.TabsList> */}\n {/* Tab\u4E3A1\u65F6\uFF0C\u4E0D\u5C55\u793Atab\u6309\u94AE */}\n {Array.isArray(tabs) && tabs.length > 1 && (\n <TabsPrimitive.TabsList className=\"tabs-list\">\n {tabs.map(tab => (\n <TabsPrimitive.TabsTrigger\n key={tab.id || tab.tabName}\n value={tab.id || tab.tabName}\n className=\"tabs-trigger\"\n >\n {tab.tabName}\n </TabsPrimitive.TabsTrigger>\n ))}\n </TabsPrimitive.TabsList>\n )}\n {(Array.isArray(tabs) ? tabs : [])?.map((tab: any) => (\n <TabsPrimitive.TabsContent\n key={tab.id || tab.tabName}\n value={tab.id || tab.tabName}\n className={`tabs-content ${tabs?.length > 1 ? 'mt-[24px]' : ''}`}\n >\n {!isLexicalEmpty(tab.caption) || !isLexicalEmpty(tab?.subtitle) ? (\n <Title className=\"tabs-title\" data={{ caption: tab?.caption, subtitle: tab?.subtitle }} />\n ) : null}\n {tab.tabContent?.[0] ? renderTabContent(tab.tabContent?.[0]) : null}\n </TabsPrimitive.TabsContent>\n ))}\n </TabsPrimitive.Tabs>\n </section>\n )\n})\nTabs.displayName = 'Tabs'\nexport default withLayout(Tabs)\n"],
|
|
5
|
+
"mappings": "aAsBa,cAAAA,EAoDH,QAAAC,MApDG,oBArBb,OAAS,cAAAC,MAAkB,yBAC3B,UAAYC,MAAmB,2BAC/B,OAAS,MAAAC,EAAI,kBAAAC,MAAsB,yBAEnC,OAAOC,MAAW,QAClB,OAAOC,MAAkB,2BACzB,OAAOC,MAAoB,6BAC3B,OAAOC,MAAS,kBAChB,OAAOC,MAA6B,wDACpC,OAAOC,MAAW,oBAClB,OAAOC,MAAa,sBACpB,OAAOC,MAAe,wBACtB,OAAOC,MAAiB,0BACxB,OAAOC,MAAmB,4BAC1B,OAAOC,MAAmB,4BAE1B,MAAMC,EAAOX,EAAM,WAAsC,CAAC,CAAE,KAAAY,EAAM,UAAAC,CAAU,EAAGC,IAAiB,CAC9F,KAAM,CAAE,MAAAC,EAAO,MAAAC,EAAO,MAAAC,EAAO,KAAAC,EAAO,CAAC,EAAG,aAAAC,CAAa,EAAIP,EAEnDQ,EAAoBC,GACpBA,GAAY,YAAc,mBACrB3B,EAACO,EAAA,CAAa,KAAMoB,EAAY,EAC9BA,GAAY,YAAc,8BAC5B3B,EAACU,EAAA,CAAwB,KAAMiB,EAAY,EACzCA,GAAY,YAAc,qBAC5B3B,EAACQ,EAAA,CAAe,KAAMmB,EAAY,EAChCA,GAAY,YAAc,UAC5B3B,EAACS,EAAA,CAAI,KAAMkB,EAAY,EACrBA,GAAY,YAAc,cAC5B3B,EAACY,EAAA,CAAQ,KAAMe,EAAY,EACzBA,GAAY,YAAc,gBAC5B3B,EAACa,EAAA,CAAU,KAAMc,EAAY,EAC3BA,GAAY,YAAc,mBAC5B3B,EAACc,EAAA,CAAY,KAAMa,EAAY,EAC7BA,GAAY,YAAc,sBAC5B3B,EAACe,EAAA,CAAc,KAAMY,EAAY,EAC/BA,GAAY,YAAc,gBAC5B3B,EAACgB,EAAA,CAAc,KAAMW,EAAY,EAEjC,KAIX,OACE1B,EAAC,WAAQ,IAAKmB,EAAc,UAAWhB,EAAGiB,IAAU,OAAS,YAAc,GAAIF,CAAS,EACrF,UAAAM,GAAgBzB,EAACW,EAAA,CAAM,UAAU,gBAAgB,KAAM,CAAE,MAAOc,CAAa,EAAG,EACjFxB,EAACE,EAAc,KAAd,CAAmB,MAAOmB,EAAO,MAAOC,EAAO,aAAcC,IAAO,CAAC,GAAG,IAAMA,IAAO,CAAC,GAAG,QAavF,gBAAM,QAAQA,CAAI,GAAKA,EAAK,OAAS,GACpCxB,EAACG,EAAc,SAAd,CAAuB,UAAU,YAC/B,SAAAqB,EAAK,IAAII,GACR5B,EAACG,EAAc,YAAd,CAEC,MAAOyB,EAAI,IAAMA,EAAI,QACrB,UAAU,eAET,SAAAA,EAAI,SAJAA,EAAI,IAAMA,EAAI,OAKrB,CACD,EACH,GAEA,MAAM,QAAQJ,CAAI,EAAIA,EAAO,CAAC,IAAI,IAAKI,GACvC3B,EAACE,EAAc,YAAd,CAEC,MAAOyB,EAAI,IAAMA,EAAI,QACrB,UAAW,gBAAgBJ,GAAM,OAAS,EAAI,YAAc,EAAE,GAE7D,WAACnB,EAAeuB,EAAI,OAAO,GAAK,CAACvB,EAAeuB,GAAK,QAAQ,EAC5D5B,EAACW,EAAA,CAAM,UAAU,aAAa,KAAM,CAAE,QAASiB,GAAK,QAAS,SAAUA,GAAK,QAAS,EAAG,EACtF,KACHA,EAAI,aAAa,CAAC,EAAIF,EAAiBE,EAAI,aAAa,CAAC,CAAC,EAAI,OAP1DA,EAAI,IAAMA,EAAI,OAQrB,CACD,GACH,GACF,CAEJ,CAAC,EACDX,EAAK,YAAc,OACnB,IAAOY,EAAQ3B,EAAWe,CAAI",
|
|
6
|
+
"names": ["jsx", "jsxs", "withLayout", "TabsPrimitive", "cn", "isLexicalEmpty", "React", "ShelfDisplay", "AccordionCards", "Faq", "MultiLayoutGraphicBlock", "Title", "Graphic", "WhyChoose", "BrandEquity", "BrandCardLink", "ImageWithText", "Tabs", "data", "className", "forwardedRef", "theme", "shape", "align", "tabs", "sectionTitle", "renderTabContent", "tabContent", "tab", "Tabs_default"]
|
|
7
7
|
}
|
|
@@ -7,6 +7,7 @@ import type { GraphicProps } from '../Graphic/index.js';
|
|
|
7
7
|
import type { WhyChooseProps } from '../WhyChoose/types.js';
|
|
8
8
|
import type { BrandEquityProps } from '../BrandEquity/types.js';
|
|
9
9
|
import type { BrandCardLinkProps } from '../BrandCardLink/types.js';
|
|
10
|
+
import type { ImageWithTextProps } from '../ImageWithText/types.js';
|
|
10
11
|
export type TabsProps = {
|
|
11
12
|
data: {
|
|
12
13
|
sectionTitle?: string;
|
|
@@ -32,6 +33,8 @@ export type TabsProps = {
|
|
|
32
33
|
blockType: 'ipc-brand-equity';
|
|
33
34
|
})[] | (BrandCardLinkProps['data'] & {
|
|
34
35
|
blockType: 'ipc-brand-card-link';
|
|
36
|
+
})[] | (ImageWithTextProps['data'] & {
|
|
37
|
+
blockType: 'ImageWithText';
|
|
35
38
|
})[];
|
|
36
39
|
}[];
|
|
37
40
|
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const h=(t="",n="")=>{try{if(n=n.replace(/Activity Page_/g,""),/^https?:\/\//.test(t)){const r=new URL(t);return r.searchParams.has("ref")?t:(r.searchParams.set("ref",n),r.toString())}else{const[r,i=""]=t.split("#"),[c,
|
|
1
|
+
const h=(t="",n="")=>{try{if(t?.startsWith("#"))return t;if(n=n.replace(/Activity Page_/g,""),/^https?:\/\//.test(t)){const r=new URL(t);return r.searchParams.has("ref")?t:(r.searchParams.set("ref",n),r.toString())}else{const[r,i=""]=t.split("#"),[c,a=""]=r.split("?"),s=new URLSearchParams(a);if(s.has("ref"))return t;s.set("ref",n);const o=s.toString()?`?${s.toString()}`:"",g=i?`#${i}`:"";return`${c}${o}${g}`}}catch{return/[?&]ref=/.test(t)?t:t?.includes("?")?t+"&ref="+encodeURIComponent(n):t+"?ref="+encodeURIComponent(n)}},p=(t,n,e)=>`${t}_${n}_${e}`;export{p as buildTrackingRef,h as trackUrlRef};
|
|
2
2
|
//# sourceMappingURL=trackUrlRef.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/shared/trackUrlRef.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * \u7ED9 url \u6216 path \u6DFB\u52A0 ref \u53C2\u6570\n * @param url \u539F\u59CB url \u6216 path\n * @param refValue ref \u53C2\u6570\u7684\u503C\n * @returns \u6DFB\u52A0\u4E86 ref \u53C2\u6570\u7684\u65B0 url\n */\nexport const trackUrlRef = (url: string = '', refValue: string = ''): string => {\n try {\n // \u5386\u53F2\u57CB\u70B9\u95EE\u9898\u5904\u7406\uFF0C\u53BB\u6389pageHandle \u7684\u524D\u7F00\n refValue = refValue.replace(/Activity Page_/g, '')\n // \u5224\u65AD\u662F\u5426\u4E3A\u7EDD\u5BF9 URL\n const hasOrigin = /^https?:\\/\\//.test(url)\n if (hasOrigin) {\n const u = new URL(url)\n // \u5982\u679C\u5DF2\u6709 ref \u53C2\u6570\uFF0C\u8DF3\u8FC7\u8986\u76D6\n if (u.searchParams.has('ref')) {\n return url\n }\n u.searchParams.set('ref', refValue)\n return u.toString()\n } else {\n const [pathWithQuery, hash = ''] = url.split('#')\n const [path, query = ''] = pathWithQuery.split('?')\n const params = new URLSearchParams(query)\n // \u5982\u679C\u5DF2\u6709 ref \u53C2\u6570\uFF0C\u8DF3\u8FC7\u8986\u76D6\n if (params.has('ref')) {\n return url\n }\n params.set('ref', refValue)\n const queryString = params.toString() ? `?${params.toString()}` : ''\n const hashString = hash ? `#${hash}` : ''\n return `${path}${queryString}${hashString}`\n }\n } catch (e) {\n // \u5982\u679C\u5DF2\u6709 ref \u53C2\u6570\uFF0C\u8DF3\u8FC7\u8986\u76D6\n if (/[?&]ref=/.test(url)) {\n return url\n }\n if (url?.includes('?')) {\n return url + '&ref=' + encodeURIComponent(refValue)\n }\n return url + '?ref=' + encodeURIComponent(refValue)\n }\n}\n\n/**\n * \u6784\u9020\u6807\u51C6\u5316 ref \u8FFD\u8E2A\u5B57\u7B26\u4E32\n * \u683C\u5F0F: `${pageHandle}_${componentType}_${componentName}`\n * @param pageHandle \u9875\u9762\u6807\u8BC6\uFF0C\u5982 'soundcore-lottery'\n * @param componentType \u7EC4\u4EF6\u7C7B\u578B\uFF0C\u5982 'copy'\n * @param componentName \u7EC4\u4EF6\u540D\u79F0\uFF0C\u5982 'lottery_banner'\n * @returns \u62FC\u63A5\u540E\u7684 ref \u5B57\u7B26\u4E32\uFF0C\u5982 'soundcore-lottery_copy_lottery_banner'\n */\nexport const buildTrackingRef = (pageHandle: string, componentType: string, componentName: string): string => {\n return `${pageHandle}_${componentType}_${componentName}`\n}\n"],
|
|
5
|
-
"mappings": "AAMO,MAAMA,EAAc,CAACC,EAAc,GAAIC,EAAmB,KAAe,CAC9E,GAAI,
|
|
4
|
+
"sourcesContent": ["/**\n * \u7ED9 url \u6216 path \u6DFB\u52A0 ref \u53C2\u6570\n * @param url \u539F\u59CB url \u6216 path\n * @param refValue ref \u53C2\u6570\u7684\u503C\n * @returns \u6DFB\u52A0\u4E86 ref \u53C2\u6570\u7684\u65B0 url\n */\nexport const trackUrlRef = (url: string = '', refValue: string = ''): string => {\n try {\n // \u5904\u7406\u951A\u70B9\n if (url?.startsWith('#')) return url\n // \u5386\u53F2\u57CB\u70B9\u95EE\u9898\u5904\u7406\uFF0C\u53BB\u6389pageHandle \u7684\u524D\u7F00\n refValue = refValue.replace(/Activity Page_/g, '')\n // \u5224\u65AD\u662F\u5426\u4E3A\u7EDD\u5BF9 URL\n const hasOrigin = /^https?:\\/\\//.test(url)\n if (hasOrigin) {\n const u = new URL(url)\n // \u5982\u679C\u5DF2\u6709 ref \u53C2\u6570\uFF0C\u8DF3\u8FC7\u8986\u76D6\n if (u.searchParams.has('ref')) {\n return url\n }\n u.searchParams.set('ref', refValue)\n return u.toString()\n } else {\n const [pathWithQuery, hash = ''] = url.split('#')\n const [path, query = ''] = pathWithQuery.split('?')\n const params = new URLSearchParams(query)\n // \u5982\u679C\u5DF2\u6709 ref \u53C2\u6570\uFF0C\u8DF3\u8FC7\u8986\u76D6\n if (params.has('ref')) {\n return url\n }\n params.set('ref', refValue)\n const queryString = params.toString() ? `?${params.toString()}` : ''\n const hashString = hash ? `#${hash}` : ''\n return `${path}${queryString}${hashString}`\n }\n } catch (e) {\n // \u5982\u679C\u5DF2\u6709 ref \u53C2\u6570\uFF0C\u8DF3\u8FC7\u8986\u76D6\n if (/[?&]ref=/.test(url)) {\n return url\n }\n if (url?.includes('?')) {\n return url + '&ref=' + encodeURIComponent(refValue)\n }\n return url + '?ref=' + encodeURIComponent(refValue)\n }\n}\n\n/**\n * \u6784\u9020\u6807\u51C6\u5316 ref \u8FFD\u8E2A\u5B57\u7B26\u4E32\n * \u683C\u5F0F: `${pageHandle}_${componentType}_${componentName}`\n * @param pageHandle \u9875\u9762\u6807\u8BC6\uFF0C\u5982 'soundcore-lottery'\n * @param componentType \u7EC4\u4EF6\u7C7B\u578B\uFF0C\u5982 'copy'\n * @param componentName \u7EC4\u4EF6\u540D\u79F0\uFF0C\u5982 'lottery_banner'\n * @returns \u62FC\u63A5\u540E\u7684 ref \u5B57\u7B26\u4E32\uFF0C\u5982 'soundcore-lottery_copy_lottery_banner'\n */\nexport const buildTrackingRef = (pageHandle: string, componentType: string, componentName: string): string => {\n return `${pageHandle}_${componentType}_${componentName}`\n}\n"],
|
|
5
|
+
"mappings": "AAMO,MAAMA,EAAc,CAACC,EAAc,GAAIC,EAAmB,KAAe,CAC9E,GAAI,CAEF,GAAID,GAAK,WAAW,GAAG,EAAG,OAAOA,EAKjC,GAHAC,EAAWA,EAAS,QAAQ,kBAAmB,EAAE,EAE/B,eAAe,KAAKD,CAAG,EAC1B,CACb,MAAME,EAAI,IAAI,IAAIF,CAAG,EAErB,OAAIE,EAAE,aAAa,IAAI,KAAK,EACnBF,GAETE,EAAE,aAAa,IAAI,MAAOD,CAAQ,EAC3BC,EAAE,SAAS,EACpB,KAAO,CACL,KAAM,CAACC,EAAeC,EAAO,EAAE,EAAIJ,EAAI,MAAM,GAAG,EAC1C,CAACK,EAAMC,EAAQ,EAAE,EAAIH,EAAc,MAAM,GAAG,EAC5CI,EAAS,IAAI,gBAAgBD,CAAK,EAExC,GAAIC,EAAO,IAAI,KAAK,EAClB,OAAOP,EAETO,EAAO,IAAI,MAAON,CAAQ,EAC1B,MAAMO,EAAcD,EAAO,SAAS,EAAI,IAAIA,EAAO,SAAS,CAAC,GAAK,GAC5DE,EAAaL,EAAO,IAAIA,CAAI,GAAK,GACvC,MAAO,GAAGC,CAAI,GAAGG,CAAW,GAAGC,CAAU,EAC3C,CACF,MAAY,CAEV,MAAI,WAAW,KAAKT,CAAG,EACdA,EAELA,GAAK,SAAS,GAAG,EACZA,EAAM,QAAU,mBAAmBC,CAAQ,EAE7CD,EAAM,QAAU,mBAAmBC,CAAQ,CACpD,CACF,EAUaS,EAAmB,CAACC,EAAoBC,EAAuBC,IACnE,GAAGF,CAAU,IAAIC,CAAa,IAAIC,CAAa",
|
|
6
6
|
"names": ["trackUrlRef", "url", "refValue", "u", "pathWithQuery", "hash", "path", "query", "params", "queryString", "hashString", "buildTrackingRef", "pageHandle", "componentType", "componentName"]
|
|
7
7
|
}
|
package/package.json
CHANGED
package/style.css
CHANGED
|
@@ -4963,9 +4963,6 @@ video {
|
|
|
4963
4963
|
.tablet\:h-\[18\.22vw\] {
|
|
4964
4964
|
height: 18.22vw;
|
|
4965
4965
|
}
|
|
4966
|
-
.tablet\:h-\[240px\] {
|
|
4967
|
-
height: 240px;
|
|
4968
|
-
}
|
|
4969
4966
|
.tablet\:h-\[24px\] {
|
|
4970
4967
|
height: 24px;
|
|
4971
4968
|
}
|
|
@@ -5504,9 +5501,15 @@ video {
|
|
|
5504
5501
|
.laptop\:aspect-\[1024\/520\] {
|
|
5505
5502
|
aspect-ratio: 1024/520;
|
|
5506
5503
|
}
|
|
5504
|
+
.laptop\:aspect-\[288\/192\] {
|
|
5505
|
+
aspect-ratio: 288/192;
|
|
5506
|
+
}
|
|
5507
5507
|
.laptop\:aspect-\[332\/190\] {
|
|
5508
5508
|
aspect-ratio: 332/190;
|
|
5509
5509
|
}
|
|
5510
|
+
.laptop\:aspect-\[440\/192\] {
|
|
5511
|
+
aspect-ratio: 440/192;
|
|
5512
|
+
}
|
|
5510
5513
|
.laptop\:aspect-\[440\/280\] {
|
|
5511
5514
|
aspect-ratio: 440/280;
|
|
5512
5515
|
}
|
|
@@ -6512,6 +6515,12 @@ video {
|
|
|
6512
6515
|
.desktop\:aspect-\[1440\/700\] {
|
|
6513
6516
|
aspect-ratio: 1440/700;
|
|
6514
6517
|
}
|
|
6518
|
+
.desktop\:aspect-\[427\/256\] {
|
|
6519
|
+
aspect-ratio: 427/256;
|
|
6520
|
+
}
|
|
6521
|
+
.desktop\:aspect-\[648\/256\] {
|
|
6522
|
+
aspect-ratio: 648/256;
|
|
6523
|
+
}
|
|
6515
6524
|
.desktop\:aspect-\[648\/448\] {
|
|
6516
6525
|
aspect-ratio: 648/448;
|
|
6517
6526
|
}
|
|
@@ -6586,9 +6595,6 @@ video {
|
|
|
6586
6595
|
.desktop\:h-\[24px\] {
|
|
6587
6596
|
height: 24px;
|
|
6588
6597
|
}
|
|
6589
|
-
.desktop\:h-\[256px\] {
|
|
6590
|
-
height: 256px;
|
|
6591
|
-
}
|
|
6592
6598
|
.desktop\:h-\[280px\] {
|
|
6593
6599
|
height: 280px;
|
|
6594
6600
|
}
|
|
@@ -7146,9 +7152,15 @@ video {
|
|
|
7146
7152
|
.lg-desktop\:aspect-\[543\/320\] {
|
|
7147
7153
|
aspect-ratio: 543/320;
|
|
7148
7154
|
}
|
|
7155
|
+
.lg-desktop\:aspect-\[544\/320\] {
|
|
7156
|
+
aspect-ratio: 544/320;
|
|
7157
|
+
}
|
|
7149
7158
|
.lg-desktop\:aspect-\[644\/320\] {
|
|
7150
7159
|
aspect-ratio: 644/320;
|
|
7151
7160
|
}
|
|
7161
|
+
.lg-desktop\:aspect-\[824\/320\] {
|
|
7162
|
+
aspect-ratio: 824/320;
|
|
7163
|
+
}
|
|
7152
7164
|
.lg-desktop\:size-12 {
|
|
7153
7165
|
width: 3rem;
|
|
7154
7166
|
height: 3rem;
|
|
@@ -7243,9 +7255,6 @@ video {
|
|
|
7243
7255
|
.lg-desktop\:h-\[28px\] {
|
|
7244
7256
|
height: 28px;
|
|
7245
7257
|
}
|
|
7246
|
-
.lg-desktop\:h-\[320px\] {
|
|
7247
|
-
height: 320px;
|
|
7248
|
-
}
|
|
7249
7258
|
.lg-desktop\:h-\[362px\] {
|
|
7250
7259
|
height: 362px;
|
|
7251
7260
|
}
|