@anker-in/headless-ui 1.3.17 → 1.3.18
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/GiftShelf/index.js +1 -1
- package/dist/cjs/biz-components/GiftShelf/index.js.map +3 -3
- package/dist/cjs/biz-components/ImageWithText/ImageWithText.js +1 -1
- package/dist/cjs/biz-components/ImageWithText/ImageWithText.js.map +2 -2
- package/dist/cjs/biz-components/MediaTextOverlay/MediaTextOverlay.js +1 -1
- package/dist/cjs/biz-components/MediaTextOverlay/MediaTextOverlay.js.map +2 -2
- package/dist/cjs/biz-components/ProductCompare/index.js +1 -1
- package/dist/cjs/biz-components/ProductCompare/index.js.map +2 -2
- package/dist/cjs/biz-components/Title/index.js +1 -1
- package/dist/cjs/biz-components/Title/index.js.map +3 -3
- package/dist/esm/biz-components/GiftShelf/index.js +1 -1
- package/dist/esm/biz-components/GiftShelf/index.js.map +3 -3
- package/dist/esm/biz-components/ImageWithText/ImageWithText.js +1 -1
- package/dist/esm/biz-components/ImageWithText/ImageWithText.js.map +2 -2
- package/dist/esm/biz-components/MediaTextOverlay/MediaTextOverlay.js +1 -1
- package/dist/esm/biz-components/MediaTextOverlay/MediaTextOverlay.js.map +2 -2
- package/dist/esm/biz-components/ProductCompare/index.js +1 -1
- package/dist/esm/biz-components/ProductCompare/index.js.map +2 -2
- package/dist/esm/biz-components/Title/index.js +1 -1
- package/dist/esm/biz-components/Title/index.js.map +3 -3
- package/dist/tokens/base.css +1 -0
- package/package.json +1 -1
- package/style.css +15 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/biz-components/GiftShelf/index.tsx"],
|
|
4
|
-
"sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { cn } from '../../helpers/index.js'\nimport { Text, Picture, Button, Container, Heading } from '../../components/index.js'\nimport { cva } from 'class-variance-authority'\nimport type { GiftShelfProps, GiftShelfItem, CountdownConfig, ResponsiveBackgroundImage } from './types.js'\nimport { Swiper, SwiperSlide } from 'swiper/react'\nimport { withLayout } from '../../shared/Styles.js'\nimport type { Product, ProductVariant } from '../Listing/types/product.js'\nimport { formatVariantPrice } from '../Listing/utils/index.js'\nimport { useAiuiContext } from '../AiuiProvider/index.js'\nimport { replaceTemplate } from '../Listing/utils/textFormat.js'\nimport type { GiftShelfProduct } from './types.js'\nimport type { Media } from '../../types/props.js'\n\n/**\n * Card style variants for gift shelf\n */\nconst giftCardVariants = cva('desktop:px-6 rounded-card relative min-w-0 overflow-hidden p-4', {\n variants: {\n state: {\n light: 'bg-[#EAEAEC]',\n dark: 'bg-[#1E2024]',\n },\n },\n defaultVariants: {\n state: 'light',\n },\n})\n\n/**\n * Content layout variants - \u63A7\u5236 Background image \u548C Bottom info area \u7684\u5E03\u5C40\n * horizontal \u5E03\u5C40\u4EC5\u5728 desktop (\u22651440px) \u65AD\u70B9\u751F\u6548\n */\nconst contentLayoutVariants = cva('', {\n variants: {\n layout: {\n vertical: '',\n horizontal: 'desktop:flex desktop:flex-row desktop:items-stretch desktop:gap-10',\n },\n },\n defaultVariants: {\n layout: 'vertical',\n },\n})\n\n/**\n * Image area variants\n * horizontal \u5E03\u5C40\u4EC5\u5728 desktop (\u22651440px) \u65AD\u70B9\u751F\u6548\n */\nconst imageAreaVariants = cva(\n 'desktop:max-w-[268px] lg-desktop:max-w-[356px] lg-desktop:h-[171px] relative mx-auto h-[118px] max-w-[256px] ',\n {\n variants: {\n layout: {\n vertical: '',\n horizontal: 'desktop:flex-1 desktop:h-[122px] lg-desktop:h-[161px]',\n },\n },\n defaultVariants: {\n layout: 'vertical',\n },\n }\n)\n\n/**\n * Info area variants\n * horizontal \u5E03\u5C40\u4EC5\u5728 desktop (\u22651440px) \u65AD\u70B9\u751F\u6548\n */\nconst infoAreaVariants = cva('mt-3', {\n variants: {\n layout: {\n vertical: '',\n horizontal: 'desktop:mt-0 desktop:flex-1 desktop:flex desktop:flex-col desktop:justify-center',\n },\n },\n defaultVariants: {\n layout: 'vertical',\n },\n})\n\n/**\n * Button style variants\n */\nconst buttonVariants = cva('mt-4 self-start', {\n variants: {\n state: {\n light: 'bg-[#080A0F] text-white',\n dark: 'bg-white text-[#080A0F]',\n },\n },\n defaultVariants: {\n state: 'light',\n },\n})\n\n/**\n * Text style variants\n */\nconst textVariants = cva('', {\n variants: {\n state: {\n light: 'text-[#080A0F]',\n dark: 'text-white',\n },\n },\n defaultVariants: {\n state: 'light',\n },\n})\n\n/**\n * Convert ResponsiveBackgroundImage to Picture source string\n * Format: \"url1 1920, url2 1439, url3 1024, url4 767, url5\"\n */\nconst getResponsiveSource = (bgImage?: ResponsiveBackgroundImage): string | undefined => {\n if (!bgImage) return undefined\n\n const sources: string[] = []\n\n // lg-desktop: \u22651920px\n if (bgImage.lgDesktop?.url) {\n sources.push(`${bgImage.lgDesktop.url} 1920`)\n }\n // desktop: \u22651440px\n if (bgImage.desktop?.url) {\n sources.push(`${bgImage.desktop.url} 1439`)\n }\n // laptop: \u22651025px\n if (bgImage.laptop?.url) {\n sources.push(`${bgImage.laptop.url} 1024`)\n }\n // tablet: \u2265768px\n if (bgImage.tablet?.url) {\n sources.push(`${bgImage.tablet.url} 767`)\n }\n // default (mobile): <768px\n if (bgImage.default?.url) {\n sources.push(bgImage.default.url)\n }\n\n return sources.length > 0 ? sources.join(', ') : undefined\n}\n\n/**\n * Get alt text from ResponsiveBackgroundImage\n */\nconst getBackgroundAlt = (bgImage?: ResponsiveBackgroundImage): string => {\n if (!bgImage) return ''\n return (\n bgImage.default?.alt ||\n bgImage.tablet?.alt ||\n bgImage.laptop?.alt ||\n bgImage.desktop?.alt ||\n bgImage.lgDesktop?.alt ||\n ''\n )\n}\n\n/**\n * Format countdown time\n */\nconst formatTime = (seconds: number) => {\n const hours = Math.floor(seconds / 3600)\n const minutes = Math.floor((seconds % 3600) / 60)\n const secs = seconds % 60\n return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`\n}\n\n/**\n * \u89E3\u6790\u5F00\u59CB\u65F6\u95F4\uFF0C\u652F\u6301 ISO 8601 \u5B57\u7B26\u4E32\u6216\u65F6\u95F4\u6233\n */\nconst parseStartTime = (startTime: string | number): number => {\n if (typeof startTime === 'number') {\n return startTime\n }\n // \u89E3\u6790 ISO 8601 \u5B57\u7B26\u4E32\n const parsed = new Date(startTime).getTime()\n return isNaN(parsed) ? 0 : parsed\n}\n\n/**\n * \u8BA1\u7B97\u5F53\u524D\u662F\u5426\u5904\u4E8E\u8F6E\u6B21\u5207\u6362\u671F\uFF08\u4E0B\u4E00\u8F6E\u5F00\u59CB\u524D5\u5206\u949F\uFF09\n * @param countdown \u5012\u8BA1\u65F6\u914D\u7F6E\n * @returns \u662F\u5426\u5904\u4E8E\u5207\u6362\u671F\n */\nconst isInTransitionPeriod = (countdown?: CountdownConfig): boolean => {\n if (!countdown) return false\n const startTimeMs = parseStartTime(countdown.startTime)\n const durationMs = (countdown.durationDays ?? 1) * 24 * 3600 * 1000\n const rounds = countdown.rounds ?? 1\n const now = Date.now()\n\n // \u672A\u5230\u5F00\u59CB\u65F6\u95F4\n if (now < startTimeMs) return false\n\n // \u8BA1\u7B97\u5F53\u524D\u8F6E\u6B21\n const elapsed = now - startTimeMs\n const currentRound = Math.floor(elapsed / durationMs) + 1\n\n // \u6240\u6709\u8F6E\u6B21\u5DF2\u7ED3\u675F\n if (currentRound > rounds) return false\n\n // \u8BA1\u7B97\u5F53\u524D\u8F6E\u6B21\u7684\u7ED3\u675F\u65F6\u95F4\n const currentRoundEndTime = startTimeMs + currentRound * durationMs\n\n // \u8DDD\u79BB\u5F53\u524D\u8F6E\u6B21\u7ED3\u675F\u7684\u65F6\u95F4\n const timeUntilRoundEnd = currentRoundEndTime - now\n\n // \u5982\u679C\u8DDD\u79BB\u7ED3\u675F\u4E0D\u52305\u5206\u949F\uFF0C\u5904\u4E8E\u5207\u6362\u671F\n const TRANSITION_PERIOD_MS = 5 * 60 * 1000 // 5\u5206\u949F\n return timeUntilRoundEnd <= TRANSITION_PERIOD_MS && timeUntilRoundEnd > 0\n}\n\n/**\n * \u6839\u636E\u5012\u8BA1\u65F6\u914D\u7F6E\u8BA1\u7B97\u5F53\u524D\u8F6E\u6B21\u7684 Code\n * @param codePrefix Code \u524D\u7F00\n * @param countdown \u5012\u8BA1\u65F6\u914D\u7F6E\n * @returns \u5B8C\u6574\u7684 Code\uFF08\u524D\u7F00 + MMDD \u540E\u7F00\uFF09\n * @description \u7EDF\u4E00\u4F7F\u7528 UTC \u65F6\u95F4\u8BA1\u7B97\uFF0C\u786E\u4FDD\u5168\u7403\u4EFB\u4F55\u65F6\u533A\u5F97\u5230\u76F8\u540C\u7684 code\n */\nconst getCodeWithSuffix = (codePrefix?: string, countdown?: CountdownConfig): string => {\n if (!codePrefix || !countdown) return codePrefix || ''\n\n const startTimeMs = parseStartTime(countdown.startTime)\n const durationMs = (countdown.durationDays ?? 1) * 24 * 3600 * 1000\n const rounds = countdown.rounds ?? 1\n const now = Date.now()\n\n // \u672A\u5230\u5F00\u59CB\u65F6\u95F4\uFF0C\u4F7F\u7528\u7B2C\u4E00\u8F6E\u7684\u65E5\u671F\uFF08UTC \u65F6\u95F4\uFF09\n if (now < startTimeMs) {\n const date = new Date(startTimeMs)\n const suffix = `${(date.getUTCMonth() + 1).toString().padStart(2, '0')}${date.getUTCDate().toString().padStart(2, '0')}`\n return `${codePrefix}${suffix}`\n }\n\n // \u8BA1\u7B97\u5F53\u524D\u5904\u4E8E\u7B2C\u51E0\u8F6E\uFF08\u4ECE 1 \u5F00\u59CB\uFF09\n const elapsed = now - startTimeMs\n const currentRound = Math.min(Math.floor(elapsed / durationMs) + 1, rounds)\n\n // \u8BA1\u7B97\u5F53\u524D\u8F6E\u6B21\u7684\u5F00\u59CB\u65E5\u671F\n const currentRoundStartMs = startTimeMs + (currentRound - 1) * durationMs\n const date = new Date(currentRoundStartMs)\n\n // \u683C\u5F0F\u5316\u4E3A MMDD\uFF08\u4F7F\u7528 UTC \u65F6\u95F4\uFF09\n const suffix = `${(date.getUTCMonth() + 1).toString().padStart(2, '0')}${date.getUTCDate().toString().padStart(2, '0')}`\n\n return `${codePrefix}${suffix}`\n}\n\n/**\n * \u5012\u8BA1\u65F6\u72B6\u6001\u7C7B\u578B\n */\ntype CountdownState = 'beforeStart' | 'running' | 'lastRound' | 'finished'\n\n/**\n * Countdown Component\n * \u652F\u6301\u591A\u8F6E\u5012\u8BA1\u65F6\uFF0C\u663E\u793A\u4E0D\u540C\u72B6\u6001\u7684\u6807\u7B7E\n */\nconst Countdown = React.memo(\n ({\n config,\n theme = 'light',\n className,\n countdownText = 'Next round start time',\n lastRoundText = 'Last round',\n beforeStartText = 'Start time',\n countdownIcon,\n onStateChange,\n }: {\n config: CountdownConfig\n theme?: 'light' | 'dark'\n className?: string\n countdownText?: string\n lastRoundText?: string\n beforeStartText?: string\n countdownIcon?: Media\n onStateChange?: (state: CountdownState) => void\n }) => {\n const [timeLeft, setTimeLeft] = React.useState(0)\n const [countdownState, setCountdownState] = React.useState<CountdownState>('beforeStart')\n\n // \u89E3\u6790\u5F00\u59CB\u65F6\u95F4\u4E3A\u65F6\u95F4\u6233\n const startTimeMs = React.useMemo(() => parseStartTime(config.startTime), [config.startTime])\n\n const rounds = config.rounds ?? 1\n // \u9ED8\u8BA4 1 \u5929\uFF0C\u8F6C\u6362\u4E3A\u6BEB\u79D2 (1\u5929 = 24\u5C0F\u65F6 = 86400\u79D2 = 86400000\u6BEB\u79D2)\n const durationMs = (config.durationDays ?? 1) * 24 * 3600 * 1000\n\n React.useEffect(() => {\n const calculateCountdown = () => {\n const now = Date.now()\n\n // \u672A\u5230\u5F00\u59CB\u65F6\u95F4\uFF0C\u663E\u793A\u5F00\u59CB\u524D\u5012\u8BA1\u65F6\n if (now < startTimeMs) {\n const diff = Math.max(0, Math.floor((startTimeMs - now) / 1000))\n setTimeLeft(diff)\n setCountdownState('beforeStart')\n return\n }\n\n // \u8BA1\u7B97\u5DF2\u7ECF\u8FC7\u53BB\u7684\u65F6\u95F4\n const elapsed = now - startTimeMs\n // \u8BA1\u7B97\u5F53\u524D\u5904\u4E8E\u7B2C\u51E0\u8F6E\uFF08\u4ECE 1 \u5F00\u59CB\uFF09\n const currentRound = Math.floor(elapsed / durationMs) + 1\n\n // \u6240\u6709\u8F6E\u6B21\u5DF2\u7ED3\u675F\n if (currentRound > rounds) {\n setCountdownState('finished')\n return\n }\n\n // \u8BA1\u7B97\u5F53\u524D\u8F6E\u6B21\u7684\u76EE\u6807\u65F6\u95F4\n const currentRoundTargetTime = startTimeMs + currentRound * durationMs\n // \u8BA1\u7B97\u5269\u4F59\u79D2\u6570\n const diff = Math.max(0, Math.floor((currentRoundTargetTime - now) / 1000))\n\n setTimeLeft(diff)\n // \u5224\u65AD\u662F\u5426\u662F\u6700\u540E\u4E00\u8F6E\n setCountdownState(currentRound === rounds ? 'lastRound' : 'running')\n }\n\n calculateCountdown()\n const timer = setInterval(calculateCountdown, 1000)\n\n return () => clearInterval(timer)\n }, [startTimeMs, durationMs, rounds])\n\n // \u901A\u77E5\u7236\u7EC4\u4EF6\u72B6\u6001\u53D8\u5316\n React.useEffect(() => {\n onStateChange?.(countdownState)\n }, [countdownState, onStateChange])\n\n // \u6839\u636E\u72B6\u6001\u83B7\u53D6\u663E\u793A\u7684\u6807\u7B7E\u6587\u672C\n const labelText = React.useMemo(() => {\n switch (countdownState) {\n case 'beforeStart':\n return beforeStartText\n case 'lastRound':\n return lastRoundText\n default:\n return countdownText\n }\n }, [countdownState, beforeStartText, lastRoundText, countdownText])\n\n // \u6240\u6709\u8F6E\u6B21\u5DF2\u7ED3\u675F\uFF0C\u4E0D\u6E32\u67D3\n if (countdownState === 'finished') {\n return null\n }\n\n return (\n <div\n className={cn(\n 'desktop:gap-2 laptop:text-base flex items-center gap-1 text-sm',\n theme === 'dark' ? 'text-white' : 'text-[#080A0F]',\n className\n )}\n >\n {countdownIcon && (\n <Picture\n source={countdownIcon.url}\n alt={countdownIcon.alt}\n className=\"laptop:size-5 size-4 shrink-0\"\n imgClassName=\"size-full object-contain\"\n />\n )}\n <Text html={labelText} className=\"whitespace-nowrap font-bold\" />\n <span className=\"font-bold\">|</span>\n <Text className=\"font-bold\" html={formatTime(timeLeft)} />\n </div>\n )\n }\n)\n\nCountdown.displayName = 'Countdown'\n\n/**\n * Progress Bar Component\n */\nconst ProgressBar = React.memo(\n ({ progress, theme = 'light', className }: { progress: number; theme?: 'light' | 'dark'; className?: string }) => {\n // Clamp progress between 0 and 100\n const clampedProgress = Math.min(100, Math.max(0, progress))\n\n return (\n <div\n className={cn(\n 'flex h-2 w-full items-stretch overflow-hidden rounded-full',\n theme === 'dark' ? 'bg-white/20' : 'bg-black/20',\n className\n )}\n role=\"progressbar\"\n aria-valuenow={clampedProgress}\n aria-valuemin={0}\n aria-valuemax={100}\n >\n <div\n className={cn(\n 'h-full rounded-full transition-all duration-300',\n theme === 'dark' ? 'bg-white' : 'bg-[#080A0F]'\n )}\n style={{ width: `${clampedProgress}%` }}\n />\n </div>\n )\n }\n)\n\nProgressBar.displayName = 'ProgressBar'\n\n/**\n * Gift Shelf Card Component\n */\nconst GiftShelfCard = React.memo(\n ({\n item,\n theme = 'light',\n layout = 'vertical',\n className,\n buttonClassName,\n countdownClassName,\n onButtonClick,\n onProductImageClick,\n buildData,\n buttonText,\n remainText,\n lowStockText,\n soldOutButtonText,\n discountText = 'Only {price}',\n countdownText,\n countdownIcon,\n lastRoundText,\n beforeStartText,\n comingSoonButtonText,\n loading,\n }: {\n item: GiftShelfItem\n theme?: 'light' | 'dark'\n layout?: 'vertical' | 'horizontal'\n className?: string\n buttonClassName?: string\n countdownClassName?: string\n onButtonClick?: ({ product, code }: { product: GiftShelfProduct; code: string }) => void\n onProductImageClick?: (product: GiftShelfProduct) => void\n buildData?: {\n products: Product[]\n }\n buttonText: string\n remainText?: string\n lowStockText?: string\n soldOutButtonText?: string\n discountText?: string\n countdownText?: string\n countdownIcon?: Media\n lastRoundText?: string\n beforeStartText?: string\n comingSoonButtonText?: string\n loading?: boolean\n }) => {\n const { locale = 'us' } = useAiuiContext()\n // \u83B7\u53D6\u7B2C\u4E00\u4E2A\u4EA7\u54C1\u7684\u7B80\u5316\u6570\u636E\n const firstProduct = item.products?.[0]\n\n // \u68C0\u6D4B\u662F\u5426\u5904\u4E8E\u8F6E\u6B21\u5207\u6362\u671F + \u5F53\u524D\u8F6E\u6B21 code\uFF08\u6BCF\u79D2\u66F4\u65B0\uFF09\n const [isTransitioning, setIsTransitioning] = React.useState(() => isInTransitionPeriod(item.countdown))\n const [currentCode, setCurrentCode] = React.useState(() => getCodeWithSuffix(item.codePrefix, item.countdown))\n // \u5012\u8BA1\u65F6\u72B6\u6001\n const [countdownState, setCountdownState] = React.useState<CountdownState>('beforeStart')\n\n React.useEffect(() => {\n const checkAndUpdate = () => {\n // \u66F4\u65B0\u8F6E\u6B21\u5207\u6362\u72B6\u6001\n setIsTransitioning(isInTransitionPeriod(item.countdown))\n // \u66F4\u65B0\u5F53\u524D\u8F6E\u6B21 code\uFF08\u4EC5\u5728\u503C\u53D8\u5316\u65F6\u66F4\u65B0\uFF09\n const newCode = getCodeWithSuffix(item.codePrefix, item.countdown)\n setCurrentCode(prev => (prev !== newCode ? newCode : prev))\n }\n\n // \u521D\u59CB\u68C0\u67E5\n checkAndUpdate()\n // \u6BCF\u79D2\u68C0\u67E5\u4E00\u6B21\n const timer = setInterval(checkAndUpdate, 1000)\n\n return () => clearInterval(timer)\n }, [item.codePrefix, item.countdown])\n\n // \u5012\u8BA1\u65F6\u72B6\u6001\u53D8\u5316\u56DE\u8C03\n const handleCountdownStateChange = React.useCallback((state: CountdownState) => {\n setCountdownState(state)\n }, [])\n\n // \u901A\u8FC7 handle \u5339\u914D buildData \u4E2D\u7684\u5B8C\u6574\u4EA7\u54C1\u6570\u636E\n const fullProduct = React.useMemo(() => {\n if (!firstProduct?.handle || !buildData?.products?.length) return null\n return buildData.products.find(p => p.handle === firstProduct.handle) || null\n }, [firstProduct?.handle, buildData?.products])\n\n const fullProductVariant = React.useMemo(\n () => fullProduct?.variants?.find(variant => variant?.sku === firstProduct?.sku) || ({} as ProductVariant),\n [firstProduct?.sku, fullProduct?.variants]\n )\n\n // \u7EC4\u5408\u5C55\u793A\u6570\u636E\uFF08\u4F18\u5148\u4F7F\u7528\u8BE6\u7EC6\u6570\u636E\uFF0C\u56DE\u9000\u5230\u7B80\u5316\u6570\u636E\uFF09\n const displayData = React.useMemo(() => {\n const { price, basePrice } = formatVariantPrice({\n locale: locale || 'us',\n baseAmount: fullProductVariant?.price?.amount,\n amount: firstProduct?.custom_price ?? fullProductVariant?.price?.amount,\n currencyCode: fullProduct?.price?.currencyCode || 'USD',\n })\n\n return {\n // \u4E3B\u4EF7\u683C/\u4EF7\u503C\u5C55\u793A\uFF1A\u6709\u8BE6\u7EC6\u6570\u636E\u65F6\u663E\u793A\u4EF7\u683C\uFF0C\u5426\u5219\u663E\u793A\u4EA7\u54C1\u540D\n value: basePrice,\n // \u4EA7\u54C1\u63CF\u8FF0/\u6807\u9898\uFF1A\u6709\u8BE6\u7EC6\u6570\u636E\u65F6\u663E\u793A\u6807\u9898\uFF0C\u5426\u5219\u4E3A\u7A7A\uFF08\u907F\u514D\u91CD\u590D\u663E\u793A\uFF09\n description: firstProduct?.custom_description,\n // \u4F18\u60E0\u4EF7\u683C\n salePrice: replaceTemplate(discountText || '', {\n price,\n }),\n }\n }, [\n fullProduct,\n fullProductVariant,\n locale,\n discountText,\n firstProduct?.custom_price,\n firstProduct?.custom_description,\n ])\n\n const handleClick = React.useCallback(() => {\n onButtonClick?.({ product: firstProduct, code: currentCode })\n }, [onButtonClick, currentCode, firstProduct])\n\n return (\n <div className={cn(giftCardVariants({ state: theme }), className)} data-ui-component-id=\"GiftShelfCard\">\n {/* Countdown section - above the card content (only in vertical layout) */}\n {item.countdown && (\n <div className=\"laptop:h-[24px] mb-4 h-[20px]\">\n <Countdown\n config={item.countdown}\n theme={theme}\n className={countdownClassName}\n countdownText={countdownText}\n lastRoundText={lastRoundText}\n beforeStartText={beforeStartText}\n countdownIcon={countdownIcon}\n onStateChange={handleCountdownStateChange}\n />\n </div>\n )}\n\n {/* Content layout wrapper - \u63A7\u5236 Background image \u548C Bottom info area \u7684\u5E03\u5C40 */}\n <div className={contentLayoutVariants({ layout })}>\n {/* Background image - responsive across 5 breakpoints */}\n <div className={imageAreaVariants({ layout })}>\n {item.backgroundImage &&\n (onProductImageClick ? (\n <a onClick={() => firstProduct && onProductImageClick(firstProduct)} className=\"cursor-pointer\">\n <Picture\n source={getResponsiveSource(item.backgroundImage)}\n alt={getBackgroundAlt(item.backgroundImage)}\n className=\"rounded-card size-full overflow-hidden object-cover\"\n imgClassName=\"h-full w-full object-cover\"\n />\n </a>\n ) : (\n <Picture\n source={getResponsiveSource(item.backgroundImage)}\n alt={getBackgroundAlt(item.backgroundImage)}\n className=\"rounded-card size-full overflow-hidden object-cover\"\n imgClassName=\"h-full w-full object-cover\"\n />\n ))}\n {/* Card content area */}\n <div className=\"absolute top-1/2 z-10 w-full -translate-y-1/2 px-6\">\n {/* Value and description */}\n <div className=\"flex flex-col gap-1\">\n {/* Main value display */}\n {displayData.value && (\n <Heading\n html={displayData.value}\n size={4}\n className={cn('font-bold leading-none', textVariants({ state: theme }))}\n />\n )}\n\n {/* Description */}\n {displayData.description && (\n <Text\n html={displayData.description}\n className={cn('text-base font-bold opacity-60', textVariants({ state: theme }))}\n />\n )}\n </div>\n </div>\n </div>\n\n {/* Bottom/Right info area */}\n <div className={infoAreaVariants({ layout })}>\n {/* Sale price */}\n {displayData.salePrice && (\n <Text\n as=\"p\"\n html={displayData.salePrice}\n className={cn('lg-desktop:text-2xl text-xl font-bold', textVariants({ state: theme }))}\n />\n )}\n\n {/* Progress bar - \u8D85\u5356\u65F6\u9690\u85CF\uFF08availableForSale=true \u4E14 quantityAvailable<=0\uFF09 */}\n <ProgressBar\n progress={\n firstProduct?.custom_inventory\n ? ((fullProductVariant?.quantityAvailable || 0) / firstProduct.custom_inventory) * 100\n : 0\n }\n theme={theme}\n className={cn(\n 'mb-1 mt-2',\n fullProductVariant?.availableForSale && (fullProductVariant?.quantityAvailable ?? 0) <= 0 && 'invisible'\n )}\n />\n\n {/* Remain text - \u6B63\u5E38\u5E93\u5B58\u63D0\u793A */}\n {remainText && (fullProductVariant?.quantityAvailable ?? 0) >= 0 && (\n <Text\n html={replaceTemplate(remainText, {\n inventory: firstProduct?.custom_inventory?.toString() || '',\n quantity: fullProductVariant?.quantityAvailable?.toString() || '0',\n })}\n as=\"p\"\n className={cn('laptop:text-base text-sm font-bold', textVariants({ state: theme }))}\n />\n )}\n\n {/* Low stock text - \u652F\u6301\u8D85\u5356\u65F6\u663E\u793A\uFF08availableForSale=true \u4F46 quantityAvailable<=0\uFF09 */}\n {lowStockText &&\n fullProductVariant?.availableForSale &&\n (fullProductVariant?.quantityAvailable ?? 0) < 0 && (\n <Text\n html={lowStockText}\n as=\"p\"\n className={cn('laptop:text-base text-sm font-bold text-red-500', textVariants({ state: theme }))}\n />\n )}\n\n {/* Action button */}\n <Button\n size=\"lg\"\n className={cn(buttonVariants({ state: theme }), buttonClassName)}\n onClick={handleClick}\n disabled={\n !fullProductVariant?.availableForSale ||\n loading ||\n isTransitioning ||\n countdownState === 'beforeStart' ||\n countdownState === 'finished'\n }\n loading={loading && fullProductVariant?.availableForSale}\n >\n {countdownState === 'beforeStart'\n ? comingSoonButtonText || buttonText\n : fullProductVariant?.availableForSale\n ? buttonText\n : soldOutButtonText || buttonText}\n </Button>\n </div>\n </div>\n </div>\n )\n }\n)\n\nGiftShelfCard.displayName = 'GiftShelfCard'\n\n/**\n * GiftShelf - Gift/Promotion Shelf Component\n *\n * @description Display gift cards with countdown, pricing, and purchase buttons\n */\nconst GiftShelf = React.forwardRef<HTMLDivElement, GiftShelfProps>(\n ({ classNames = {}, data, onButtonClick, onProductImageClick, buildData, loading, ...rest }, ref) => {\n const theme = data.theme || 'light'\n\n const itemsPerRow = React.useMemo(() => {\n return data?.items?.length || 4\n }, [data?.items])\n\n // \u5F53\u5361\u7247\u6570\u91CF\u4E3A 2 \u65F6\u4F7F\u7528\u6C34\u5E73\u5E03\u5C40\uFF0C\u5426\u5219\u4F7F\u7528\u5782\u76F4\u5E03\u5C40\n const cardLayout = itemsPerRow === 2 ? 'horizontal' : 'vertical'\n\n const swiperBreakpoints = React.useMemo(() => {\n const getBreakpointConfig = (breakpoint: 'mobile' | 'tablet' | 'laptop' | 'desktop') => {\n switch (breakpoint) {\n case 'mobile':\n return { slidesPerView: 1.2, spaceBetween: 12 }\n case 'tablet':\n if (itemsPerRow <= 2) return { slidesPerView: 2, spaceBetween: 12 }\n return { slidesPerView: 2.5, spaceBetween: 12 }\n case 'laptop':\n if (itemsPerRow <= 3) return { slidesPerView: itemsPerRow, spaceBetween: 16 }\n return { slidesPerView: 3.01, spaceBetween: 16 }\n case 'desktop':\n return { slidesPerView: Math.min(itemsPerRow, 4), spaceBetween: 20 }\n }\n }\n\n return {\n 0: getBreakpointConfig('mobile'),\n 768: getBreakpointConfig('tablet'),\n 1025: getBreakpointConfig('laptop'),\n 1440: getBreakpointConfig('desktop'),\n }\n }, [itemsPerRow])\n\n return (\n <Container\n ref={ref}\n className={cn(classNames?.root)}\n childClassName=\"overflow-hidden\"\n data-ui-component-id=\"GiftShelf\"\n {...rest}\n >\n {/* Cards swiper */}\n <Swiper breakpoints={swiperBreakpoints} className=\"w-full !overflow-visible\">\n {data.items.map((item, index) => (\n <SwiperSlide key={'giftShelfCardItem' + index}>\n <GiftShelfCard\n item={item}\n theme={theme}\n layout={cardLayout}\n className={classNames?.card}\n buttonClassName={classNames?.button}\n countdownClassName={classNames?.countdown}\n onButtonClick={onButtonClick}\n onProductImageClick={onProductImageClick}\n buildData={buildData}\n buttonText={data.buttonText}\n discountText={data.discountText}\n remainText={data.remainText}\n lowStockText={data.lowStockText}\n soldOutButtonText={data.soldOutButtonText}\n countdownText={data.countdownText}\n lastRoundText={data.lastRoundText}\n countdownIcon={data?.countdownIcon}\n beforeStartText={data.beforeStartText}\n comingSoonButtonText={data.comingSoonButtonText}\n loading={loading}\n />\n </SwiperSlide>\n ))}\n </Swiper>\n </Container>\n )\n }\n)\n\nGiftShelf.displayName = 'GiftShelf'\n\nexport default withLayout(GiftShelf)\nexport type {\n GiftShelfProps,\n GiftShelfData,\n GiftShelfItem,\n GiftShelfProduct,\n CountdownConfig,\n ResponsiveBackgroundImage,\n} from './types.js'\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["jsx", "jsxs", "React", "cn", "Text", "Picture", "Button", "Container", "Heading", "cva", "Swiper", "SwiperSlide", "withLayout", "formatVariantPrice", "useAiuiContext", "replaceTemplate", "giftCardVariants", "contentLayoutVariants", "imageAreaVariants", "infoAreaVariants", "buttonVariants", "textVariants", "getResponsiveSource", "bgImage", "sources", "getBackgroundAlt", "formatTime", "seconds", "hours", "minutes", "secs", "parseStartTime", "startTime", "parsed", "isInTransitionPeriod", "countdown", "startTimeMs", "durationMs", "rounds", "now", "elapsed", "currentRound", "timeUntilRoundEnd", "TRANSITION_PERIOD_MS", "getCodeWithSuffix", "codePrefix", "date", "suffix", "currentRoundStartMs", "Countdown", "config", "theme", "className", "countdownText", "lastRoundText", "beforeStartText", "countdownIcon", "onStateChange", "timeLeft", "setTimeLeft", "countdownState", "setCountdownState", "calculateCountdown", "diff", "currentRoundTargetTime", "timer", "labelText", "ProgressBar", "progress", "clampedProgress", "GiftShelfCard", "item", "layout", "buttonClassName", "countdownClassName", "onButtonClick", "onProductImageClick", "buildData", "buttonText", "remainText", "lowStockText", "soldOutButtonText", "discountText", "comingSoonButtonText", "loading", "locale", "firstProduct", "isTransitioning", "setIsTransitioning", "currentCode", "setCurrentCode", "checkAndUpdate", "newCode", "prev", "handleCountdownStateChange", "state", "fullProduct", "p", "fullProductVariant", "variant", "displayData", "price", "basePrice", "handleClick", "GiftShelf", "classNames", "data", "rest", "ref", "itemsPerRow", "cardLayout", "swiperBreakpoints", "getBreakpointConfig", "breakpoint", "index", "GiftShelf_default"]
|
|
4
|
+
"sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { cn } from '../../helpers/index.js'\nimport { Text, Picture, Button, Container, Heading } from '../../components/index.js'\nimport { cva } from 'class-variance-authority'\nimport type { GiftShelfProps, GiftShelfItem, CountdownConfig, ResponsiveBackgroundImage } from './types.js'\nimport { Swiper, SwiperSlide } from 'swiper/react'\nimport { withLayout } from '../../shared/Styles.js'\nimport type { Product, ProductVariant } from '../Listing/types/product.js'\nimport { formatVariantPrice } from '../Listing/utils/index.js'\nimport { useAiuiContext } from '../AiuiProvider/index.js'\nimport { replaceTemplate } from '../Listing/utils/textFormat.js'\nimport type { GiftShelfProduct } from './types.js'\nimport type { Media } from '../../types/props.js'\n\n/**\n * Card style variants for gift shelf\n */\nconst giftCardVariants = cva('desktop:px-6 rounded-card relative min-w-0 overflow-hidden p-4', {\n variants: {\n state: {\n light: 'bg-[#EAEAEC]',\n dark: 'bg-[#1E2024]',\n },\n },\n defaultVariants: {\n state: 'light',\n },\n})\n\n/**\n * Content layout variants - \u63A7\u5236 Background image \u548C Bottom info area \u7684\u5E03\u5C40\n * horizontal \u5E03\u5C40\u4EC5\u5728 desktop (\u22651440px) \u65AD\u70B9\u751F\u6548\n */\nconst contentLayoutVariants = cva('', {\n variants: {\n layout: {\n vertical: '',\n horizontal: 'desktop:flex desktop:flex-row desktop:items-stretch desktop:gap-10',\n },\n },\n defaultVariants: {\n layout: 'vertical',\n },\n})\n\n/**\n * Image area variants\n * horizontal \u5E03\u5C40\u4EC5\u5728 desktop (\u22651440px) \u65AD\u70B9\u751F\u6548\n */\nconst imageAreaVariants = cva(\n 'desktop:max-w-[268px] lg-desktop:max-w-[356px] lg-desktop:h-[171px] relative mx-auto h-[118px] max-w-[256px] ',\n {\n variants: {\n layout: {\n vertical: '',\n horizontal: 'desktop:flex-1 desktop:h-[122px] lg-desktop:h-[161px]',\n },\n },\n defaultVariants: {\n layout: 'vertical',\n },\n }\n)\n\n/**\n * Info area variants\n * horizontal \u5E03\u5C40\u4EC5\u5728 desktop (\u22651440px) \u65AD\u70B9\u751F\u6548\n */\nconst infoAreaVariants = cva('mt-3', {\n variants: {\n layout: {\n vertical: '',\n horizontal: 'desktop:mt-0 desktop:flex-1 desktop:flex desktop:flex-col desktop:justify-center',\n },\n },\n defaultVariants: {\n layout: 'vertical',\n },\n})\n\n/**\n * Button style variants\n */\nconst buttonVariants = cva('mt-4 self-start', {\n variants: {\n state: {\n light: 'bg-[#080A0F] text-white',\n dark: 'bg-white text-[#080A0F]',\n },\n },\n defaultVariants: {\n state: 'light',\n },\n})\n\n/**\n * Text style variants\n */\nconst textVariants = cva('', {\n variants: {\n state: {\n light: 'text-[#080A0F]',\n dark: 'text-white',\n },\n },\n defaultVariants: {\n state: 'light',\n },\n})\n\n/**\n * Convert ResponsiveBackgroundImage to Picture source string\n * Format: \"url1 1920, url2 1439, url3 1024, url4 767, url5\"\n */\nconst getResponsiveSource = (bgImage?: ResponsiveBackgroundImage): string | undefined => {\n if (!bgImage) return undefined\n\n const sources: string[] = []\n\n // lg-desktop: \u22651920px\n if (bgImage.lgDesktop?.url) {\n sources.push(`${bgImage.lgDesktop.url} 1920`)\n }\n // desktop: \u22651440px\n if (bgImage.desktop?.url) {\n sources.push(`${bgImage.desktop.url} 1439`)\n }\n // laptop: \u22651025px\n if (bgImage.laptop?.url) {\n sources.push(`${bgImage.laptop.url} 1024`)\n }\n // tablet: \u2265768px\n if (bgImage.tablet?.url) {\n sources.push(`${bgImage.tablet.url} 767`)\n }\n // default (mobile): <768px\n if (bgImage.default?.url) {\n sources.push(bgImage.default.url)\n }\n\n return sources.length > 0 ? sources.join(', ') : undefined\n}\n\n/**\n * Get alt text from ResponsiveBackgroundImage\n */\nconst getBackgroundAlt = (bgImage?: ResponsiveBackgroundImage): string => {\n if (!bgImage) return ''\n return (\n bgImage.default?.alt ||\n bgImage.tablet?.alt ||\n bgImage.laptop?.alt ||\n bgImage.desktop?.alt ||\n bgImage.lgDesktop?.alt ||\n ''\n )\n}\n\n/**\n * Format countdown time\n */\nconst formatTime = (seconds: number) => {\n const hours = Math.floor(seconds / 3600)\n const minutes = Math.floor((seconds % 3600) / 60)\n const secs = seconds % 60\n return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`\n}\n\n/**\n * \u89E3\u6790\u5F00\u59CB\u65F6\u95F4\uFF0C\u652F\u6301 ISO 8601 \u5B57\u7B26\u4E32\u6216\u65F6\u95F4\u6233\n */\nconst parseStartTime = (startTime: string | number): number => {\n if (typeof startTime === 'number') {\n return startTime\n }\n // \u89E3\u6790 ISO 8601 \u5B57\u7B26\u4E32\n const parsed = new Date(startTime).getTime()\n return isNaN(parsed) ? 0 : parsed\n}\n\n/**\n * \u8BA1\u7B97\u5F53\u524D\u662F\u5426\u5904\u4E8E\u8F6E\u6B21\u5207\u6362\u671F\uFF08\u4E0B\u4E00\u8F6E\u5F00\u59CB\u524D5\u5206\u949F\uFF09\n * @param countdown \u5012\u8BA1\u65F6\u914D\u7F6E\n * @returns \u662F\u5426\u5904\u4E8E\u5207\u6362\u671F\n */\nconst isInTransitionPeriod = (countdown?: CountdownConfig): boolean => {\n if (!countdown) return false\n const startTimeMs = parseStartTime(countdown.startTime)\n const durationMs = (countdown.durationDays ?? 1) * 24 * 3600 * 1000\n const rounds = countdown.rounds ?? 1\n const now = Date.now()\n\n // \u672A\u5230\u5F00\u59CB\u65F6\u95F4\n if (now < startTimeMs) return false\n\n // \u8BA1\u7B97\u5F53\u524D\u8F6E\u6B21\n const elapsed = now - startTimeMs\n const currentRound = Math.floor(elapsed / durationMs) + 1\n\n // \u6240\u6709\u8F6E\u6B21\u5DF2\u7ED3\u675F\n if (currentRound > rounds) return false\n\n // \u8BA1\u7B97\u5F53\u524D\u8F6E\u6B21\u7684\u7ED3\u675F\u65F6\u95F4\n const currentRoundEndTime = startTimeMs + currentRound * durationMs\n\n // \u8DDD\u79BB\u5F53\u524D\u8F6E\u6B21\u7ED3\u675F\u7684\u65F6\u95F4\n const timeUntilRoundEnd = currentRoundEndTime - now\n\n // \u5982\u679C\u8DDD\u79BB\u7ED3\u675F\u4E0D\u52305\u5206\u949F\uFF0C\u5904\u4E8E\u5207\u6362\u671F\n const TRANSITION_PERIOD_MS = 5 * 60 * 1000 // 5\u5206\u949F\n return timeUntilRoundEnd <= TRANSITION_PERIOD_MS && timeUntilRoundEnd > 0\n}\n\n/**\n * \u6839\u636E\u5012\u8BA1\u65F6\u914D\u7F6E\u8BA1\u7B97\u5F53\u524D\u8F6E\u6B21\u7684 Code\n * @param codePrefix Code \u524D\u7F00\n * @param countdown \u5012\u8BA1\u65F6\u914D\u7F6E\n * @returns \u5B8C\u6574\u7684 Code\uFF08\u524D\u7F00 + MMDD \u540E\u7F00\uFF09\n * @description \u7EDF\u4E00\u4F7F\u7528 UTC \u65F6\u95F4\u8BA1\u7B97\uFF0C\u786E\u4FDD\u5168\u7403\u4EFB\u4F55\u65F6\u533A\u5F97\u5230\u76F8\u540C\u7684 code\n */\nconst getCodeWithSuffix = (codePrefix?: string, countdown?: CountdownConfig): string => {\n if (!codePrefix || !countdown) return codePrefix || ''\n\n const startTimeMs = parseStartTime(countdown.startTime)\n const durationMs = (countdown.durationDays ?? 1) * 24 * 3600 * 1000\n const rounds = countdown.rounds ?? 1\n const now = Date.now()\n\n // \u672A\u5230\u5F00\u59CB\u65F6\u95F4\uFF0C\u4F7F\u7528\u7B2C\u4E00\u8F6E\u7684\u65E5\u671F\uFF08UTC \u65F6\u95F4\uFF09\n if (now < startTimeMs) {\n const date = new Date(startTimeMs)\n const suffix = `${(date.getUTCMonth() + 1).toString().padStart(2, '0')}${date.getUTCDate().toString().padStart(2, '0')}`\n return `${codePrefix}${suffix}`\n }\n\n // \u8BA1\u7B97\u5F53\u524D\u5904\u4E8E\u7B2C\u51E0\u8F6E\uFF08\u4ECE 1 \u5F00\u59CB\uFF09\n const elapsed = now - startTimeMs\n const currentRound = Math.min(Math.floor(elapsed / durationMs) + 1, rounds)\n\n // \u8BA1\u7B97\u5F53\u524D\u8F6E\u6B21\u7684\u5F00\u59CB\u65E5\u671F\n const currentRoundStartMs = startTimeMs + (currentRound - 1) * durationMs\n const date = new Date(currentRoundStartMs)\n\n // \u683C\u5F0F\u5316\u4E3A MMDD\uFF08\u4F7F\u7528 UTC \u65F6\u95F4\uFF09\n const suffix = `${(date.getUTCMonth() + 1).toString().padStart(2, '0')}${date.getUTCDate().toString().padStart(2, '0')}`\n\n return `${codePrefix}${suffix}`\n}\n\n/**\n * \u5012\u8BA1\u65F6\u72B6\u6001\u7C7B\u578B\n */\ntype CountdownState = 'beforeStart' | 'running' | 'lastRound' | 'finished'\n\n/**\n * Countdown Component\n * \u652F\u6301\u591A\u8F6E\u5012\u8BA1\u65F6\uFF0C\u663E\u793A\u4E0D\u540C\u72B6\u6001\u7684\u6807\u7B7E\n */\nconst Countdown = React.memo(\n ({\n config,\n theme = 'light',\n className,\n countdownText = 'Next round start time',\n lastRoundText = 'Last round',\n beforeStartText = 'Start time',\n countdownIcon,\n onStateChange,\n }: {\n config: CountdownConfig\n theme?: 'light' | 'dark'\n className?: string\n countdownText?: string\n lastRoundText?: string\n beforeStartText?: string\n countdownIcon?: Media\n onStateChange?: (state: CountdownState) => void\n }) => {\n const [timeLeft, setTimeLeft] = React.useState(0)\n const [countdownState, setCountdownState] = React.useState<CountdownState>('beforeStart')\n\n // \u89E3\u6790\u5F00\u59CB\u65F6\u95F4\u4E3A\u65F6\u95F4\u6233\n const startTimeMs = React.useMemo(() => parseStartTime(config.startTime), [config.startTime])\n\n const rounds = config.rounds ?? 1\n // \u9ED8\u8BA4 1 \u5929\uFF0C\u8F6C\u6362\u4E3A\u6BEB\u79D2 (1\u5929 = 24\u5C0F\u65F6 = 86400\u79D2 = 86400000\u6BEB\u79D2)\n const durationMs = (config.durationDays ?? 1) * 24 * 3600 * 1000\n\n React.useEffect(() => {\n const calculateCountdown = () => {\n const now = Date.now()\n\n // \u672A\u5230\u5F00\u59CB\u65F6\u95F4\uFF0C\u663E\u793A\u5F00\u59CB\u524D\u5012\u8BA1\u65F6\n if (now < startTimeMs) {\n const diff = Math.max(0, Math.floor((startTimeMs - now) / 1000))\n setTimeLeft(diff)\n setCountdownState('beforeStart')\n return\n }\n\n // \u8BA1\u7B97\u5DF2\u7ECF\u8FC7\u53BB\u7684\u65F6\u95F4\n const elapsed = now - startTimeMs\n // \u8BA1\u7B97\u5F53\u524D\u5904\u4E8E\u7B2C\u51E0\u8F6E\uFF08\u4ECE 1 \u5F00\u59CB\uFF09\n const currentRound = Math.floor(elapsed / durationMs) + 1\n\n // \u6240\u6709\u8F6E\u6B21\u5DF2\u7ED3\u675F\n if (currentRound > rounds) {\n setCountdownState('finished')\n return\n }\n\n // \u8BA1\u7B97\u5F53\u524D\u8F6E\u6B21\u7684\u76EE\u6807\u65F6\u95F4\n const currentRoundTargetTime = startTimeMs + currentRound * durationMs\n // \u8BA1\u7B97\u5269\u4F59\u79D2\u6570\n const diff = Math.max(0, Math.floor((currentRoundTargetTime - now) / 1000))\n\n setTimeLeft(diff)\n // \u5224\u65AD\u662F\u5426\u662F\u6700\u540E\u4E00\u8F6E\n setCountdownState(currentRound === rounds ? 'lastRound' : 'running')\n }\n\n calculateCountdown()\n const timer = setInterval(calculateCountdown, 1000)\n\n return () => clearInterval(timer)\n }, [startTimeMs, durationMs, rounds])\n\n // \u901A\u77E5\u7236\u7EC4\u4EF6\u72B6\u6001\u53D8\u5316\n React.useEffect(() => {\n onStateChange?.(countdownState)\n }, [countdownState, onStateChange])\n\n // \u6839\u636E\u72B6\u6001\u83B7\u53D6\u663E\u793A\u7684\u6807\u7B7E\u6587\u672C\n const labelText = React.useMemo(() => {\n switch (countdownState) {\n case 'beforeStart':\n return beforeStartText\n case 'lastRound':\n return lastRoundText\n default:\n return countdownText\n }\n }, [countdownState, beforeStartText, lastRoundText, countdownText])\n\n // \u6240\u6709\u8F6E\u6B21\u5DF2\u7ED3\u675F\uFF0C\u4E0D\u6E32\u67D3\n if (countdownState === 'finished') {\n return null\n }\n\n return (\n <div\n className={cn(\n 'desktop:gap-2 laptop:text-base flex items-center gap-1 text-sm',\n theme === 'dark' ? 'text-white' : 'text-[#080A0F]',\n className\n )}\n >\n {countdownIcon && (\n <Picture\n source={countdownIcon.url}\n alt={countdownIcon.alt}\n className=\"laptop:size-5 size-4 shrink-0\"\n imgClassName=\"size-full object-contain\"\n />\n )}\n <Text html={labelText} className=\"whitespace-nowrap font-bold\" />\n <span className=\"font-bold\">|</span>\n <Text className=\"font-bold\" html={formatTime(timeLeft)} />\n </div>\n )\n }\n)\n\nCountdown.displayName = 'Countdown'\n\n/**\n * Progress Bar Component\n */\nconst ProgressBar = React.memo(\n ({ progress, theme = 'light', className }: { progress: number; theme?: 'light' | 'dark'; className?: string }) => {\n // Clamp progress between 0 and 100\n const clampedProgress = Math.min(100, Math.max(0, progress))\n\n return (\n <div\n className={cn(\n 'flex h-2 w-full items-stretch overflow-hidden rounded-full',\n theme === 'dark' ? 'bg-white/20' : 'bg-black/20',\n className\n )}\n role=\"progressbar\"\n aria-valuenow={clampedProgress}\n aria-valuemin={0}\n aria-valuemax={100}\n >\n <div\n className={cn(\n 'h-full rounded-full transition-all duration-300',\n theme === 'dark' ? 'bg-white' : 'bg-[#080A0F]'\n )}\n style={{ width: `${clampedProgress}%` }}\n />\n </div>\n )\n }\n)\n\nProgressBar.displayName = 'ProgressBar'\n\n/**\n * Gift Shelf Card Component\n */\nconst GiftShelfCard = React.memo(\n ({\n item,\n theme = 'light',\n layout = 'vertical',\n className,\n buttonClassName,\n countdownClassName,\n onButtonClick,\n onProductImageClick,\n buildData,\n buttonText,\n remainText,\n lowStockText,\n soldOutButtonText,\n discountText = 'Only {price}',\n countdownText,\n countdownIcon,\n lastRoundText,\n beforeStartText,\n comingSoonButtonText,\n loading,\n }: {\n item: GiftShelfItem\n theme?: 'light' | 'dark'\n layout?: 'vertical' | 'horizontal'\n className?: string\n buttonClassName?: string\n countdownClassName?: string\n onButtonClick?: ({ product, code }: { product: GiftShelfProduct; code: string }) => void\n onProductImageClick?: (product: GiftShelfProduct) => void\n buildData?: {\n products: Product[]\n }\n buttonText: string\n remainText?: string\n lowStockText?: string\n soldOutButtonText?: string\n discountText?: string\n countdownText?: string\n countdownIcon?: Media\n lastRoundText?: string\n beforeStartText?: string\n comingSoonButtonText?: string\n loading?: boolean\n }) => {\n const { locale = 'us', currencyCode } = useAiuiContext()\n // \u83B7\u53D6\u7B2C\u4E00\u4E2A\u4EA7\u54C1\u7684\u7B80\u5316\u6570\u636E\n const firstProduct = item.products?.[0]\n\n // \u68C0\u6D4B\u662F\u5426\u5904\u4E8E\u8F6E\u6B21\u5207\u6362\u671F + \u5F53\u524D\u8F6E\u6B21 code\uFF08\u6BCF\u79D2\u66F4\u65B0\uFF09\n const [isTransitioning, setIsTransitioning] = React.useState(() => isInTransitionPeriod(item.countdown))\n const [currentCode, setCurrentCode] = React.useState(() => getCodeWithSuffix(item.codePrefix, item.countdown))\n // \u5012\u8BA1\u65F6\u72B6\u6001\n const [countdownState, setCountdownState] = React.useState<CountdownState>('beforeStart')\n\n React.useEffect(() => {\n const checkAndUpdate = () => {\n // \u66F4\u65B0\u8F6E\u6B21\u5207\u6362\u72B6\u6001\n setIsTransitioning(isInTransitionPeriod(item.countdown))\n // \u66F4\u65B0\u5F53\u524D\u8F6E\u6B21 code\uFF08\u4EC5\u5728\u503C\u53D8\u5316\u65F6\u66F4\u65B0\uFF09\n const newCode = getCodeWithSuffix(item.codePrefix, item.countdown)\n setCurrentCode(prev => (prev !== newCode ? newCode : prev))\n }\n\n // \u521D\u59CB\u68C0\u67E5\n checkAndUpdate()\n // \u6BCF\u79D2\u68C0\u67E5\u4E00\u6B21\n const timer = setInterval(checkAndUpdate, 1000)\n\n return () => clearInterval(timer)\n }, [item.codePrefix, item.countdown])\n\n // \u5012\u8BA1\u65F6\u72B6\u6001\u53D8\u5316\u56DE\u8C03\n const handleCountdownStateChange = React.useCallback((state: CountdownState) => {\n setCountdownState(state)\n }, [])\n\n // \u901A\u8FC7 handle \u5339\u914D buildData \u4E2D\u7684\u5B8C\u6574\u4EA7\u54C1\u6570\u636E\n const fullProduct = React.useMemo(() => {\n if (!firstProduct?.handle || !buildData?.products?.length) return null\n return buildData.products.find(p => p.handle === firstProduct.handle) || null\n }, [firstProduct?.handle, buildData?.products])\n\n const fullProductVariant = React.useMemo(\n () => fullProduct?.variants?.find(variant => variant?.sku === firstProduct?.sku) || ({} as ProductVariant),\n [firstProduct?.sku, fullProduct?.variants]\n )\n\n // \u7EC4\u5408\u5C55\u793A\u6570\u636E\uFF08\u4F18\u5148\u4F7F\u7528\u8BE6\u7EC6\u6570\u636E\uFF0C\u56DE\u9000\u5230\u7B80\u5316\u6570\u636E\uFF09\n const displayData = React.useMemo(() => {\n const { price, basePrice } = formatVariantPrice({\n locale: currencyCode === 'CAD' ? 'us' : locale || 'us',\n baseAmount: fullProductVariant?.price?.amount,\n amount: firstProduct?.custom_price ?? fullProductVariant?.price?.amount,\n currencyCode: fullProduct?.price?.currencyCode || 'USD',\n })\n\n return {\n // \u4E3B\u4EF7\u683C/\u4EF7\u503C\u5C55\u793A\uFF1A\u6709\u8BE6\u7EC6\u6570\u636E\u65F6\u663E\u793A\u4EF7\u683C\uFF0C\u5426\u5219\u663E\u793A\u4EA7\u54C1\u540D\n value: basePrice,\n // \u4EA7\u54C1\u63CF\u8FF0/\u6807\u9898\uFF1A\u6709\u8BE6\u7EC6\u6570\u636E\u65F6\u663E\u793A\u6807\u9898\uFF0C\u5426\u5219\u4E3A\u7A7A\uFF08\u907F\u514D\u91CD\u590D\u663E\u793A\uFF09\n description: firstProduct?.custom_description,\n // \u4F18\u60E0\u4EF7\u683C\n salePrice: replaceTemplate(discountText || '', {\n price,\n }),\n }\n }, [\n fullProduct,\n fullProductVariant,\n locale,\n discountText,\n firstProduct?.custom_price,\n firstProduct?.custom_description,\n ])\n\n const handleClick = React.useCallback(() => {\n onButtonClick?.({ product: firstProduct, code: currentCode })\n }, [onButtonClick, currentCode, firstProduct])\n\n return (\n <div className={cn(giftCardVariants({ state: theme }), className)} data-ui-component-id=\"GiftShelfCard\">\n {/* Countdown section - above the card content (only in vertical layout) */}\n {item.countdown && (\n <div className=\"laptop:h-[24px] mb-4 h-[20px]\">\n <Countdown\n config={item.countdown}\n theme={theme}\n className={countdownClassName}\n countdownText={countdownText}\n lastRoundText={lastRoundText}\n beforeStartText={beforeStartText}\n countdownIcon={countdownIcon}\n onStateChange={handleCountdownStateChange}\n />\n </div>\n )}\n\n {/* Content layout wrapper - \u63A7\u5236 Background image \u548C Bottom info area \u7684\u5E03\u5C40 */}\n <div className={contentLayoutVariants({ layout })}>\n {/* Background image - responsive across 5 breakpoints */}\n <div className={imageAreaVariants({ layout })}>\n {item.backgroundImage &&\n (onProductImageClick ? (\n <a onClick={() => firstProduct && onProductImageClick(firstProduct)} className=\"cursor-pointer\">\n <Picture\n source={getResponsiveSource(item.backgroundImage)}\n alt={getBackgroundAlt(item.backgroundImage)}\n className=\"rounded-card size-full overflow-hidden object-cover\"\n imgClassName=\"h-full w-full object-cover\"\n />\n </a>\n ) : (\n <Picture\n source={getResponsiveSource(item.backgroundImage)}\n alt={getBackgroundAlt(item.backgroundImage)}\n className=\"rounded-card size-full overflow-hidden object-cover\"\n imgClassName=\"h-full w-full object-cover\"\n />\n ))}\n {/* Card content area */}\n <div className=\"absolute top-1/2 z-10 w-full -translate-y-1/2 px-6\">\n {/* Value and description */}\n <div className=\"flex flex-col gap-1\">\n {/* Main value display */}\n {displayData.value && (\n <Heading\n html={displayData.value}\n size={4}\n className={cn('font-bold leading-none', textVariants({ state: theme }))}\n />\n )}\n\n {/* Description */}\n {displayData.description && (\n <Text\n html={displayData.description}\n className={cn('text-base font-bold opacity-60', textVariants({ state: theme }))}\n />\n )}\n </div>\n </div>\n </div>\n\n {/* Bottom/Right info area */}\n <div className={infoAreaVariants({ layout })}>\n {/* Sale price */}\n {displayData.salePrice && (\n <Text\n as=\"p\"\n html={displayData.salePrice}\n className={cn('lg-desktop:text-2xl text-xl font-bold', textVariants({ state: theme }))}\n />\n )}\n\n {/* Progress bar - \u8D85\u5356\u65F6\u9690\u85CF\uFF08availableForSale=true \u4E14 quantityAvailable<=0\uFF09 */}\n <ProgressBar\n progress={\n firstProduct?.custom_inventory\n ? ((fullProductVariant?.quantityAvailable || 0) / firstProduct.custom_inventory) * 100\n : 0\n }\n theme={theme}\n className={cn(\n 'mb-1 mt-2',\n fullProductVariant?.availableForSale && (fullProductVariant?.quantityAvailable ?? 0) <= 0 && 'invisible'\n )}\n />\n\n {/* Remain text - \u6B63\u5E38\u5E93\u5B58\u63D0\u793A */}\n {remainText && (fullProductVariant?.quantityAvailable ?? 0) >= 0 && (\n <Text\n html={replaceTemplate(remainText, {\n inventory: firstProduct?.custom_inventory?.toString() || '',\n quantity: fullProductVariant?.quantityAvailable?.toString() || '0',\n })}\n as=\"p\"\n className={cn('laptop:text-base text-sm font-bold', textVariants({ state: theme }))}\n />\n )}\n\n {/* Low stock text - \u652F\u6301\u8D85\u5356\u65F6\u663E\u793A\uFF08availableForSale=true \u4F46 quantityAvailable<=0\uFF09 */}\n {lowStockText &&\n fullProductVariant?.availableForSale &&\n (fullProductVariant?.quantityAvailable ?? 0) < 0 && (\n <Text\n html={lowStockText}\n as=\"p\"\n className={cn('laptop:text-base text-sm font-bold text-red-500', textVariants({ state: theme }))}\n />\n )}\n\n {/* Action button */}\n <Button\n size=\"lg\"\n className={cn(buttonVariants({ state: theme }), buttonClassName)}\n onClick={handleClick}\n disabled={\n !fullProductVariant?.availableForSale ||\n loading ||\n isTransitioning ||\n countdownState === 'beforeStart' ||\n countdownState === 'finished'\n }\n loading={loading && fullProductVariant?.availableForSale}\n >\n {countdownState === 'beforeStart'\n ? comingSoonButtonText || buttonText\n : fullProductVariant?.availableForSale\n ? buttonText\n : soldOutButtonText || buttonText}\n </Button>\n </div>\n </div>\n </div>\n )\n }\n)\n\nGiftShelfCard.displayName = 'GiftShelfCard'\n\n/**\n * GiftShelf - Gift/Promotion Shelf Component\n *\n * @description Display gift cards with countdown, pricing, and purchase buttons\n */\nconst GiftShelf = React.forwardRef<HTMLDivElement, GiftShelfProps>(\n ({ classNames = {}, data, onButtonClick, onProductImageClick, buildData, loading, ...rest }, ref) => {\n const theme = data.theme || 'light'\n\n const itemsPerRow = React.useMemo(() => {\n return data?.items?.length || 4\n }, [data?.items])\n\n // \u5F53\u5361\u7247\u6570\u91CF\u4E3A 2 \u65F6\u4F7F\u7528\u6C34\u5E73\u5E03\u5C40\uFF0C\u5426\u5219\u4F7F\u7528\u5782\u76F4\u5E03\u5C40\n const cardLayout = itemsPerRow === 2 ? 'horizontal' : 'vertical'\n\n const swiperBreakpoints = React.useMemo(() => {\n const getBreakpointConfig = (breakpoint: 'mobile' | 'tablet' | 'laptop' | 'desktop') => {\n switch (breakpoint) {\n case 'mobile':\n return { slidesPerView: 1.2, spaceBetween: 12 }\n case 'tablet':\n if (itemsPerRow <= 2) return { slidesPerView: 2, spaceBetween: 12 }\n return { slidesPerView: 2.5, spaceBetween: 12 }\n case 'laptop':\n if (itemsPerRow <= 3) return { slidesPerView: itemsPerRow, spaceBetween: 16 }\n return { slidesPerView: 3.01, spaceBetween: 16 }\n case 'desktop':\n return { slidesPerView: Math.min(itemsPerRow, 4), spaceBetween: 20 }\n }\n }\n\n return {\n 0: getBreakpointConfig('mobile'),\n 768: getBreakpointConfig('tablet'),\n 1025: getBreakpointConfig('laptop'),\n 1440: getBreakpointConfig('desktop'),\n }\n }, [itemsPerRow])\n\n return (\n <Container\n ref={ref}\n className={cn(classNames?.root)}\n childClassName=\"overflow-hidden\"\n data-ui-component-id=\"GiftShelf\"\n {...rest}\n >\n {/* Cards swiper */}\n <Swiper breakpoints={swiperBreakpoints} className=\"w-full !overflow-visible\">\n {data.items.map((item, index) => (\n <SwiperSlide key={'giftShelfCardItem' + index}>\n <GiftShelfCard\n item={item}\n theme={theme}\n layout={cardLayout}\n className={classNames?.card}\n buttonClassName={classNames?.button}\n countdownClassName={classNames?.countdown}\n onButtonClick={onButtonClick}\n onProductImageClick={onProductImageClick}\n buildData={buildData}\n buttonText={data.buttonText}\n discountText={data.discountText}\n remainText={data.remainText}\n lowStockText={data.lowStockText}\n soldOutButtonText={data.soldOutButtonText}\n countdownText={data.countdownText}\n lastRoundText={data.lastRoundText}\n countdownIcon={data?.countdownIcon}\n beforeStartText={data.beforeStartText}\n comingSoonButtonText={data.comingSoonButtonText}\n loading={loading}\n />\n </SwiperSlide>\n ))}\n </Swiper>\n </Container>\n )\n }\n)\n\nGiftShelf.displayName = 'GiftShelf'\n\nexport default withLayout(GiftShelf)\nexport type {\n GiftShelfProps,\n GiftShelfData,\n GiftShelfItem,\n GiftShelfProduct,\n CountdownConfig,\n ResponsiveBackgroundImage,\n} from './types.js'\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["jsx", "jsxs", "React", "cn", "Text", "Picture", "Button", "Container", "Heading", "cva", "Swiper", "SwiperSlide", "withLayout", "formatVariantPrice", "useAiuiContext", "replaceTemplate", "giftCardVariants", "contentLayoutVariants", "imageAreaVariants", "infoAreaVariants", "buttonVariants", "textVariants", "getResponsiveSource", "bgImage", "sources", "getBackgroundAlt", "formatTime", "seconds", "hours", "minutes", "secs", "parseStartTime", "startTime", "parsed", "isInTransitionPeriod", "countdown", "startTimeMs", "durationMs", "rounds", "now", "elapsed", "currentRound", "timeUntilRoundEnd", "TRANSITION_PERIOD_MS", "getCodeWithSuffix", "codePrefix", "date", "suffix", "currentRoundStartMs", "Countdown", "config", "theme", "className", "countdownText", "lastRoundText", "beforeStartText", "countdownIcon", "onStateChange", "timeLeft", "setTimeLeft", "countdownState", "setCountdownState", "calculateCountdown", "diff", "currentRoundTargetTime", "timer", "labelText", "ProgressBar", "progress", "clampedProgress", "GiftShelfCard", "item", "layout", "buttonClassName", "countdownClassName", "onButtonClick", "onProductImageClick", "buildData", "buttonText", "remainText", "lowStockText", "soldOutButtonText", "discountText", "comingSoonButtonText", "loading", "locale", "currencyCode", "firstProduct", "isTransitioning", "setIsTransitioning", "currentCode", "setCurrentCode", "checkAndUpdate", "newCode", "prev", "handleCountdownStateChange", "state", "fullProduct", "p", "fullProductVariant", "variant", "displayData", "price", "basePrice", "handleClick", "GiftShelf", "classNames", "data", "rest", "ref", "itemsPerRow", "cardLayout", "swiperBreakpoints", "getBreakpointConfig", "breakpoint", "index", "GiftShelf_default"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import{jsx as e,jsxs as m}from"react/jsx-runtime";import he,{useImperativeHandle as ge,useRef as g,useState as v,useEffect as Q}from"react";import{Heading as y,Picture as S,Text as M,Link as U}from"../../components/index.js";import{cn as r,getLocalizedPath as X}from"../../helpers/utils.js";import{withLayout as ve}from"../../shared/Styles.js";import{useExposure as be}from"../../hooks/useExposure.js";import{useIntersectionObserverDelay as we}from"../../hooks/useIntersectionObserver.js";import{useAiuiContext as _e}from"../AiuiProvider/index.js";import{motion as Y,AnimatePresence as ee}from"framer-motion";const ye="image",ke="image_with_text",te=e("svg",{xmlns:"http://www.w3.org/2000/svg",width:"20",height:"20",viewBox:"0 0 20 20",fill:"none",children:e("path",{d:"M6.91009 4.41058C7.23553 4.08514 7.76304 4.08514 8.08848 4.41058L13.0885 9.41058C13.4139 9.73602 13.4139 10.2635 13.0885 10.589L8.08848 15.589C7.76304 15.9144 7.23553 15.9144 6.91009 15.589C6.58466 15.2635 6.58466 14.736 6.91009 14.4106L11.3209 9.99977L6.91009 5.58897C6.58466 5.26353 6.58466 4.73602 6.91009 4.41058Z",fill:"currentColor"})}),ie=he.forwardRef(({data:ae,className:oe},le)=>{const{title:b,subtitle:k,desc:f,descIcon:P,image:w,padImage:D,mobileImage:z,theme:se="dark",items:E=[],layout:re="left",mediaType:ne="image",datalist:s=[],video:H,padVideo:j,mobVideo:R,button:u,textAlign:l="left"}=ae,i=re,{locale:W="us"}=_e(),V=g(null),N=g(null),T=g(null),I=g(null),C=g(null),[p,me]=v(0),A=g([]),[q,de]=v({left:0,width:0}),[h,$]=v(""),[B,F]=v(""),[O,Z]=v(""),n=s.length>0,_=ne==="video";be(V,{componentType:ye,componentName:ke,componentTitle:b,componentDescription:k}),ge(le,()=>V.current),Q(()=>{if(s.length>0){const t=A.current[p];if(t){const{offsetLeft:o,offsetWidth:a}=t;de({left:o,width:a})}}},[p,s.length]);const[G,pe]=v(!1);we(C,{once:!0,threshold:.01,callback:()=>{pe(!0)}}),Q(()=>{if(!G||!_)return;let t="",o="",a="";if(n&&s[p]){const c=s[p];t=c.video?.url||"",o=c.padVideo?.url||t,a=c.mobVideo?.url||t}else t=H?.url||"",o=j?.url||t,a=R?.url||t;t&&$(t),o&&F(o),a&&Z(a),setTimeout(()=>{[N.current?.querySelector("video"),T.current?.querySelector("video"),I.current?.querySelector("video")].forEach(x=>{x&&(x.load(),x.play().catch(()=>{}))})},200)},[G,_,n,p,s,H?.url,j?.url,R?.url]);const ce=(t,o)=>{if(me(t),o.target.scrollIntoView({behavior:"smooth",inline:"center",block:"nearest"}),_&&n&&s[t]){const a=s[t];a.video?.url&&$(a.video.url),a.padVideo?.url&&F(a.padVideo.url),a.mobVideo?.url&&Z(a.mobVideo.url),setTimeout(()=>{[N.current?.querySelector("video"),T.current?.querySelector("video"),I.current?.querySelector("video")].forEach(x=>{x&&(x.load(),x.play().catch(()=>{}))})},300)}},xe=()=>!L||!u?.text||i==="top"||i==="bottom"?null:e("div",{className:r("image-with-text__button-wrapper laptop:mt-[32px] mt-[24px]",{"flex justify-center":l==="center","flex justify-start":l==="left"}),children:e(U,{href:X(u.link||"",W),className:"image-with-text__button whitespace-nowrap no-underline",suffixIcon:te,children:u.text})}),d=E.length>0,L=!!u,J=()=>{if(n&&s[p]){const t=s[p];return`${t.image?.url} ,${t.imgPad?.url||t.image?.url} 1440, ${t.imageMob?.url||t.image?.url} 767`}return w?`${w?.url},${D?.url||w?.url} 1024, ${z?.url||w?.url} 768`:""},K=()=>{if(n){const c=s[p],x=c.image?.url,ue=c.imgPad?.url||x,fe=c.imageMob?.url||x;return e(ee,{mode:"wait",children:e(Y.div,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:{duration:.3},className:"image-with-text__video-motion absolute left-0 top-0 w-full",children:m("div",{className:"image-with-text__video-wrapper rounded-box overflow-hidden",children:[e("div",{ref:N,className:"image-with-text__desktop-video-container",children:e("video",{playsInline:!0,autoPlay:!0,muted:!0,poster:x,src:h,loop:!0,className:"image-with-text__video image-with-text__video--desktop lg-desktop:block hidden size-full object-cover"})}),e("div",{ref:T,className:"image-with-text__tablet-video-container",children:e("video",{playsInline:!0,autoPlay:!0,muted:!0,poster:ue,src:B||h,loop:!0,className:"image-with-text__video image-with-text__video--tablet tablet:block lg-desktop:hidden hidden"})}),e("div",{ref:I,className:"image-with-text__mobile-video-container",children:e("video",{playsInline:!0,autoPlay:!0,muted:!0,poster:fe,src:O||h,loop:!0,className:"image-with-text__video image-with-text__video--mobile tablet:hidden block"})})]})},c.video?.url||c.image?.url)})}const t=w?.url,o=D?.url||t,a=z?.url||t;return m("div",{className:"image-with-text__video-wrapper rounded-box laptop:rounded-box overflow-hidden",children:[e("div",{ref:N,className:"image-with-text__desktop-video-container",children:e("video",{playsInline:!0,autoPlay:!0,muted:!0,poster:t,src:h,loop:!0,className:"image-with-text__video image-with-text__video--desktop lg-desktop:block hidden size-full object-cover"})}),e("div",{ref:T,className:"image-with-text__tablet-video-container",children:e("video",{playsInline:!0,autoPlay:!0,muted:!0,poster:o,src:B||h,loop:!0,className:"image-with-text__video image-with-text__video--tablet tablet:block lg-desktop:hidden hidden"})}),e("div",{ref:I,className:"image-with-text__mobile-video-container",children:e("video",{playsInline:!0,autoPlay:!0,muted:!0,poster:a,src:O||h,loop:!0,className:"image-with-text__video image-with-text__video--mobile tablet:hidden block"})})]})};return m("section",{ref:V,"data-ui-component-id":"ImageWithText",className:r("image-with-text text-info-primary",{"flex gap-[24px] laptop:gap-[48px] lg-desktop:gap-[64px]":!n,"flex-col":!n&&(i==="top"||i==="bottom"),"items-center":i==="left"||i==="right","flex-col laptop:flex-row":!n&&(i==="left"||i==="right"),"flex l:gap-[24px] xl:flex-col min-md:justify-between min-l:gap-[20px]":n,"aiui-dark":se==="dark"},oe),children:[n&&(b||f||s.length>0)&&m("div",{className:r("image-with-text__tab-content min-md:gap-[24px] laptop:basis-[36%] inline-flex flex-col justify-center",{"text-left":l==="left","text-center":l==="center"}),children:[m("div",{className:"image-with-text__header",children:[e(y,{as:"h3",size:4,html:b,className:"image-with-text__title"}),e(M,{as:"p",size:1,html:f,className:"image-with-text__description tablet:text-[14px] laptop:text-[14px] desktop:text-[16px] lg-desktop:text-[18px] mt-[4px] text-[14px]"})]}),e("div",{className:r("image-with-text__tabs-wrapper md:scrollbar-hidden relative md:overflow-hidden md:overflow-x-scroll",{"flex justify-center":l==="center"}),children:m("div",{className:"image-with-text__tabs rounded-btn relative inline-flex bg-[#1D1D1F] px-[4px] md:my-[24px]",children:[e("div",{className:"image-with-text__slider rounded-btn absolute inset-y-0 bg-white transition-all duration-300 ease-in-out",style:{left:q.left,width:q.width}}),s.map((t,o)=>e("div",{ref:a=>{A.current[o]=a},onClick:a=>ce(o,a),className:r("image-with-text__tab rounded-btn min-xxl:px-[28px] min-xxl:py-[15px] relative z-10 cursor-pointer px-[20px] py-[10px] text-center text-[12px] font-medium transition-colors duration-300 md:px-[20px] md:py-[10px]",p===o?"image-with-text__tab--active text-black":"text-white"),children:e(y,{as:"h1",size:1,html:t?.title,className:"image-with-text__tab-title text-balance-normal !whitespace-nowrap md:text-[14px]"})},o))]})})]}),!n&&(b||k||f)&&m("div",{className:r("image-with-text__content flex flex-col",{"justify-center":!L,"justify-between":L,"w-full laptop:w-fit":d,"items-start":l==="left","items-center":l==="center","text-left":l==="left","text-center":l==="center","laptop:order-1":i==="left"}),children:[m("div",{className:r("image-with-text__main-content",{"flex flex-col":L}),children:[m("div",{className:r("image-with-text__header",{"laptop:flex laptop:items-end laptop:justify-between laptop:gap-16":(i==="top"||i==="bottom")&&u?.text}),children:[m("div",{className:"image-with-text__title-wrapper flex min-w-0 flex-1 flex-col",children:[e(y,{as:"h2",size:4,html:b,className:r("image-with-text__title",{"text-left":d&&l==="left","text-center":d&&l==="center"})}),k&&e(M,{as:"p",size:d?4:3,html:k,className:r("image-with-text__subtitle tablet:text-[14px] laptop:text-[14px] desktop:text-[16px] lg-desktop:text-[18px] mt-[4px] text-[14px]",{"laptop:mt-[16px]":!d,"min-xxl:mt-[8px] laptop:text-[16px] lg-desktop:text-[18px]":d,"text-left":d&&l==="left","text-center":d&&l==="center"})})]}),(i==="top"||i==="bottom")&&u?.text&&e(U,{href:X(u.link||"",W),className:"laptop:flex hidden whitespace-nowrap no-underline",suffixIcon:te,children:u.text})]}),!d&&(f||P)&&m("div",{className:"image-with-text__description flex flex-row gap-[8px]",children:[P&&e("img",{src:P,alt:"icon",className:"image-with-text__description-icon desktop:size-[48px] size-[36px]"}),f&&e(y,{as:"h4",size:5,html:f,className:"image-with-text__description-text min-md:text-[40px] min-l:text-[40px] min-xl:text-[56px] min-xxl:text-[64px] text-[#3AD1FF] md:text-[40px]"})]}),d&&e("div",{className:r("image-with-text__items laptop:mt-[32px] desktop:mt-[48px] mt-[24px] grid w-full gap-6",{"!mt-6":i==="top"||i==="bottom","grid-cols-2 tablet:grid-cols-4":i==="top"||i==="bottom","grid-cols-2 tablet:grid-cols-4 laptop:grid-cols-2":i==="left"||i==="right"}),children:E.map((t,o)=>m("div",{className:r("image-with-text__item",{"text-center":l==="center"}),children:[m("div",{className:r("image-with-text__item-header flex flex-row items-center gap-[8px]",{"justify-center":l==="center","justify-start":l==="left"}),children:[e(S,{source:t.icon?.url,alt:t.icon?.alt,className:"image-with-text__item-icon min-md:text-[40px] min-l:text-[40px] min-xl:text-[56px] min-xxl:text-[64px] desktop:h-[44px] lg-desktop:h-[52px] h-[28px] translate-y-[-12%] md:text-[40px]",imgClassName:"h-full !w-full"}),e(y,{size:4,as:"h6",className:"image-with-text__item-text bg-gradient-to-r from-[#3ad1ff] to-[#008cd6] bg-clip-text text-transparent",children:t.text})]}),e(M,{size:4,as:"p",html:t.desc,className:"image-with-text__item-desc tablet:text-[14px] laptop:text-[14px] desktop:text-[16px] lg-desktop:text-[18px] mt-[-2px] text-[14px]"})]},o))})]}),xe()]}),e("div",{ref:C,className:r("image-with-text__media-wrapper",{"laptop:w-[60%] w-full shrink-0":i==="left"||i==="right","aspect-[716/720] max-h-[560px] max-w-[824px] tablet:aspect-[704/360] laptop:aspect-[824/560] shrink-0":d,"laptop:basis-[63%] desktop:basis-[57%]":d&&i==="left","relative w-full shrink md:aspect-[358/360] min-xxl:aspect-[824/560] min-xxl:max-w-[824px] tablet:aspect-[704/360] laptop:aspect-[744/336] laptop:basis-[64%] desktop:aspect-[648/448]":n,"!max-w-none !max-h-none aspect-auto":i==="top"||i==="bottom"}),children:n?_?K():e(ee,{mode:"wait",children:e(Y.div,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:{duration:.3},className:"image-with-text__image-motion absolute left-0 top-0 w-full",children:e(S,{source:J(),alt:s[p].image?.alt,className:"image-with-text__image rounded-box min-xxl:aspect-[824/560] min-xxl:max-w-[824px] tablet:aspect-[704/360] laptop:aspect-[744/336] desktop:aspect-[648/448] md:aspect-[358/360]"})},s[p].image?.url)}):_?K():e(S,{source:J(),className:r("image-with-text__image rounded-box laptop:rounded-box")})})]})});ie.displayName="ImageWithText";var De=ve(ie);export{De as default};
|
|
1
|
+
"use client";import{jsx as e,jsxs as d}from"react/jsx-runtime";import he,{useImperativeHandle as ge,useRef as g,useState as v,useEffect as Q}from"react";import{Heading as y,Picture as S,Text as M,Link as U}from"../../components/index.js";import{cn as r,getLocalizedPath as X}from"../../helpers/utils.js";import{withLayout as ve}from"../../shared/Styles.js";import{useExposure as be}from"../../hooks/useExposure.js";import{useIntersectionObserverDelay as we}from"../../hooks/useIntersectionObserver.js";import{useAiuiContext as _e}from"../AiuiProvider/index.js";import{motion as Y,AnimatePresence as ee}from"framer-motion";const ye="image",ke="image_with_text",te=e("svg",{xmlns:"http://www.w3.org/2000/svg",width:"20",height:"20",viewBox:"0 0 20 20",fill:"none",children:e("path",{d:"M6.91009 4.41058C7.23553 4.08514 7.76304 4.08514 8.08848 4.41058L13.0885 9.41058C13.4139 9.73602 13.4139 10.2635 13.0885 10.589L8.08848 15.589C7.76304 15.9144 7.23553 15.9144 6.91009 15.589C6.58466 15.2635 6.58466 14.736 6.91009 14.4106L11.3209 9.99977L6.91009 5.58897C6.58466 5.26353 6.58466 4.73602 6.91009 4.41058Z",fill:"currentColor"})}),ie=he.forwardRef(({data:ae,className:oe},le)=>{const{title:b,subtitle:k,desc:f,descIcon:P,image:w,padImage:D,mobileImage:z,theme:se="dark",items:E=[],layout:re="left",mediaType:ne="image",datalist:s=[],video:H,padVideo:j,mobVideo:R,button:u,textAlign:l="left"}=ae,i=re,{locale:W="us"}=_e(),V=g(null),N=g(null),T=g(null),I=g(null),C=g(null),[p,me]=v(0),A=g([]),[q,de]=v({left:0,width:0}),[h,$]=v(""),[B,F]=v(""),[O,Z]=v(""),n=s.length>0,_=ne==="video";be(V,{componentType:ye,componentName:ke,componentTitle:b,componentDescription:k}),ge(le,()=>V.current),Q(()=>{if(s.length>0){const t=A.current[p];if(t){const{offsetLeft:o,offsetWidth:a}=t;de({left:o,width:a})}}},[p,s.length]);const[G,pe]=v(!1);we(C,{once:!0,threshold:.01,callback:()=>{pe(!0)}}),Q(()=>{if(!G||!_)return;let t="",o="",a="";if(n&&s[p]){const c=s[p];t=c.video?.url||"",o=c.padVideo?.url||t,a=c.mobVideo?.url||t}else t=H?.url||"",o=j?.url||t,a=R?.url||t;t&&$(t),o&&F(o),a&&Z(a),setTimeout(()=>{[N.current?.querySelector("video"),T.current?.querySelector("video"),I.current?.querySelector("video")].forEach(x=>{x&&(x.load(),x.play().catch(()=>{}))})},200)},[G,_,n,p,s,H?.url,j?.url,R?.url]);const ce=(t,o)=>{if(me(t),o.target.scrollIntoView({behavior:"smooth",inline:"center",block:"nearest"}),_&&n&&s[t]){const a=s[t];a.video?.url&&$(a.video.url),a.padVideo?.url&&F(a.padVideo.url),a.mobVideo?.url&&Z(a.mobVideo.url),setTimeout(()=>{[N.current?.querySelector("video"),T.current?.querySelector("video"),I.current?.querySelector("video")].forEach(x=>{x&&(x.load(),x.play().catch(()=>{}))})},300)}},xe=()=>!L||!u?.text||i==="top"||i==="bottom"?null:e("div",{className:r("image-with-text__button-wrapper laptop:mt-[32px] mt-[24px]",{"flex justify-center":l==="center","flex justify-start":l==="left"}),children:e(U,{href:X(u.link||"",W),className:"image-with-text__button whitespace-nowrap no-underline",suffixIcon:te,children:u.text})}),m=E.length>0,L=!!u,J=()=>{if(n&&s[p]){const t=s[p];return`${t.image?.url} ,${t.imgPad?.url||t.image?.url} 1440, ${t.imageMob?.url||t.image?.url} 767`}return w?`${w?.url},${D?.url||w?.url} 1024, ${z?.url||w?.url} 768`:""},K=()=>{if(n){const c=s[p],x=c.image?.url,ue=c.imgPad?.url||x,fe=c.imageMob?.url||x;return e(ee,{mode:"wait",children:e(Y.div,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:{duration:.3},className:"image-with-text__video-motion absolute left-0 top-0 w-full",children:d("div",{className:"image-with-text__video-wrapper rounded-box overflow-hidden",children:[e("div",{ref:N,className:"image-with-text__desktop-video-container",children:e("video",{playsInline:!0,autoPlay:!0,muted:!0,poster:x,src:h,loop:!0,className:"image-with-text__video image-with-text__video--desktop lg-desktop:block hidden size-full object-cover"})}),e("div",{ref:T,className:"image-with-text__tablet-video-container",children:e("video",{playsInline:!0,autoPlay:!0,muted:!0,poster:ue,src:B||h,loop:!0,className:"image-with-text__video image-with-text__video--tablet tablet:block lg-desktop:hidden hidden"})}),e("div",{ref:I,className:"image-with-text__mobile-video-container",children:e("video",{playsInline:!0,autoPlay:!0,muted:!0,poster:fe,src:O||h,loop:!0,className:"image-with-text__video image-with-text__video--mobile tablet:hidden block"})})]})},c.video?.url||c.image?.url)})}const t=w?.url,o=D?.url||t,a=z?.url||t;return d("div",{className:"image-with-text__video-wrapper rounded-box laptop:rounded-box overflow-hidden",children:[e("div",{ref:N,className:"image-with-text__desktop-video-container",children:e("video",{playsInline:!0,autoPlay:!0,muted:!0,poster:t,src:h,loop:!0,className:"image-with-text__video image-with-text__video--desktop lg-desktop:block hidden size-full object-cover"})}),e("div",{ref:T,className:"image-with-text__tablet-video-container",children:e("video",{playsInline:!0,autoPlay:!0,muted:!0,poster:o,src:B||h,loop:!0,className:"image-with-text__video image-with-text__video--tablet tablet:block lg-desktop:hidden hidden"})}),e("div",{ref:I,className:"image-with-text__mobile-video-container",children:e("video",{playsInline:!0,autoPlay:!0,muted:!0,poster:a,src:O||h,loop:!0,className:"image-with-text__video image-with-text__video--mobile tablet:hidden block"})})]})};return d("section",{ref:V,"data-ui-component-id":"ImageWithText",className:r("image-with-text text-info-primary",{"flex gap-[24px] laptop:gap-[48px] lg-desktop:gap-[64px]":!n,"flex-col":!n&&(i==="top"||i==="bottom"),"items-center":i==="left"||i==="right","flex-col laptop:flex-row":!n&&(i==="left"||i==="right"),"flex l:gap-[24px] xl:flex-col min-md:justify-between min-l:gap-[20px]":n,"aiui-dark":se==="dark"},oe),children:[n&&(b||f||s.length>0)&&d("div",{className:r("image-with-text__tab-content min-md:gap-[24px] laptop:basis-[36%] inline-flex flex-col justify-center",{"text-left":l==="left","text-center":l==="center"}),children:[d("div",{className:"image-with-text__header",children:[e(y,{as:"h3",size:4,html:b,className:"image-with-text__title"}),e(M,{as:"p",size:1,html:f,className:"image-with-text__description tablet:text-[14px] laptop:text-[14px] desktop:text-[16px] lg-desktop:text-[18px] mt-[4px] text-[14px]"})]}),e("div",{className:r("image-with-text__tabs-wrapper md:scrollbar-hidden relative md:overflow-hidden md:overflow-x-scroll",{"flex justify-center":l==="center"}),children:d("div",{className:"image-with-text__tabs rounded-btn relative inline-flex bg-[#1D1D1F] px-[4px] md:my-[24px]",children:[e("div",{className:"image-with-text__slider rounded-btn absolute inset-y-0 bg-white transition-all duration-300 ease-in-out",style:{left:q.left,width:q.width}}),s.map((t,o)=>e("div",{ref:a=>{A.current[o]=a},onClick:a=>ce(o,a),className:r("image-with-text__tab rounded-btn min-xxl:px-[28px] min-xxl:py-[15px] relative z-10 cursor-pointer px-[20px] py-[10px] text-center text-[12px] font-medium transition-colors duration-300 md:px-[20px] md:py-[10px]",p===o?"image-with-text__tab--active text-black":"text-white"),children:e(y,{as:"h1",size:1,html:t?.title,className:"image-with-text__tab-title text-balance-normal !whitespace-nowrap md:text-[14px]"})},o))]})})]}),!n&&(b||k||f)&&d("div",{className:r("image-with-text__content flex w-full flex-col",{"justify-center":!L,"justify-between":L,"items-start":l==="left"&&m,"items-center":l==="center"&&m,"text-left":l==="left","text-center":l==="center","laptop:order-1":i==="left"}),children:[d("div",{className:r("image-with-text__main-content",{"flex flex-col":L}),children:[d("div",{className:r("image-with-text__header",{"laptop:flex laptop:items-end laptop:justify-between laptop:gap-16":(i==="top"||i==="bottom")&&u?.text}),children:[d("div",{className:"image-with-text__title-wrapper flex min-w-0 flex-1 flex-col",children:[e(y,{as:"h2",size:4,html:b,className:r("image-with-text__title",{"text-left":m&&l==="left","text-center":m&&l==="center"})}),k&&e(M,{as:"p",size:m?4:3,html:k,className:r("image-with-text__subtitle tablet:text-[14px] laptop:text-[14px] desktop:text-[16px] lg-desktop:text-[18px] mt-[4px] text-[14px]",{"laptop:mt-[16px]":!m,"min-xxl:mt-[8px] laptop:text-[16px] lg-desktop:text-[18px]":m,"text-left":m&&l==="left","text-center":m&&l==="center"})})]}),(i==="top"||i==="bottom")&&u?.text&&e(U,{href:X(u.link||"",W),className:"laptop:flex hidden whitespace-nowrap no-underline",suffixIcon:te,children:u.text})]}),!m&&(f||P)&&d("div",{className:"image-with-text__description flex flex-row gap-[8px]",children:[P&&e("img",{src:P,alt:"icon",className:"image-with-text__description-icon desktop:size-[48px] size-[36px]"}),f&&e(y,{as:"h4",size:5,html:f,className:"image-with-text__description-text min-md:text-[40px] min-l:text-[40px] min-xl:text-[56px] min-xxl:text-[64px] text-[#3AD1FF] md:text-[40px]"})]}),m&&e("div",{className:r("image-with-text__items laptop:mt-[32px] desktop:mt-[48px] mt-[24px] grid w-full gap-6",{"!mt-6":i==="top"||i==="bottom","grid-cols-2 tablet:grid-cols-4":i==="top"||i==="bottom","grid-cols-2 tablet:grid-cols-4 laptop:grid-cols-2":i==="left"||i==="right"}),children:E.map((t,o)=>d("div",{className:r("image-with-text__item",{"text-center":l==="center"}),children:[d("div",{className:r("image-with-text__item-header flex flex-row items-center gap-[8px]",{"justify-center":l==="center","justify-start":l==="left"}),children:[e(S,{source:t.icon?.url,alt:t.icon?.alt,className:"image-with-text__item-icon min-md:text-[40px] min-l:text-[40px] min-xl:text-[56px] min-xxl:text-[64px] desktop:h-[44px] lg-desktop:h-[52px] h-[28px] translate-y-[-12%] md:text-[40px]",imgClassName:"h-full !w-full"}),e(y,{size:4,as:"h6",className:"image-with-text__item-text bg-gradient-to-r from-[#3ad1ff] to-[#008cd6] bg-clip-text text-transparent",children:t.text})]}),e(M,{size:4,as:"p",html:t.desc,className:"image-with-text__item-desc tablet:text-[14px] laptop:text-[14px] desktop:text-[16px] lg-desktop:text-[18px] mt-[-2px] text-[14px]"})]},o))})]}),xe()]}),e("div",{ref:C,className:r("image-with-text__media-wrapper",{"laptop:w-[60%] w-full shrink-0":i==="left"||i==="right","aspect-[716/720] max-h-[560px] max-w-[824px] tablet:aspect-[704/360] laptop:aspect-[824/560] shrink-0":m,"laptop:basis-[63%] desktop:basis-[57%]":m&&i==="left","relative w-full shrink md:aspect-[358/360] min-xxl:aspect-[824/560] min-xxl:max-w-[824px] tablet:aspect-[704/360] laptop:aspect-[744/336] laptop:basis-[64%] desktop:aspect-[648/448]":n,"!max-w-none !max-h-none aspect-auto":i==="top"||i==="bottom"}),children:n?_?K():e(ee,{mode:"wait",children:e(Y.div,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:{duration:.3},className:"image-with-text__image-motion absolute left-0 top-0 w-full",children:e(S,{source:J(),alt:s[p].image?.alt,className:"image-with-text__image rounded-box min-xxl:aspect-[824/560] min-xxl:max-w-[824px] tablet:aspect-[704/360] laptop:aspect-[744/336] desktop:aspect-[648/448] md:aspect-[358/360]"})},s[p].image?.url)}):_?K():e(S,{source:J(),className:r("image-with-text__image rounded-box laptop:rounded-box")})})]})});ie.displayName="ImageWithText";var De=ve(ie);export{De as default};
|
|
2
2
|
//# sourceMappingURL=ImageWithText.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/biz-components/ImageWithText/ImageWithText.tsx"],
|
|
4
|
-
"sourcesContent": ["'use client'\nimport React, { useImperativeHandle, useRef, useState, useEffect } from 'react'\nimport { Heading, Picture, Text, Link } from '../../components/index.js'\nimport { cn, getLocalizedPath } from '../../helpers/utils.js'\nimport { withLayout } from '../../shared/Styles.js'\nimport { useExposure } from '../../hooks/useExposure.js'\nimport { useIntersectionObserverDelay } from '../../hooks/useIntersectionObserver.js'\nimport { useAiuiContext } from '../AiuiProvider/index.js'\nimport { motion, AnimatePresence } from 'framer-motion'\nimport type { ImageWithTextProps, ImageWithTextItem, ImageWithTextTabItem } from './types.js'\n\nconst componentType = 'image'\nconst componentName = 'image_with_text'\n\nconst ArrowRight = (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\n <path\n d=\"M6.91009 4.41058C7.23553 4.08514 7.76304 4.08514 8.08848 4.41058L13.0885 9.41058C13.4139 9.73602 13.4139 10.2635 13.0885 10.589L8.08848 15.589C7.76304 15.9144 7.23553 15.9144 6.91009 15.589C6.58466 15.2635 6.58466 14.736 6.91009 14.4106L11.3209 9.99977L6.91009 5.58897C6.58466 5.26353 6.58466 4.73602 6.91009 4.41058Z\"\n fill=\"currentColor\"\n />\n </svg>\n)\n\nconst ImageWithText = React.forwardRef<HTMLDivElement, ImageWithTextProps>(({ data, className }, ref) => {\n const {\n title,\n subtitle,\n desc,\n descIcon,\n image,\n padImage,\n mobileImage,\n theme = 'dark',\n items = [],\n layout = 'left',\n mediaType = 'image',\n datalist = [],\n video,\n padVideo,\n mobVideo,\n button,\n textAlign = 'left',\n } = data\n\n const effectiveLayout = layout\n\n const { locale = 'us' } = useAiuiContext()\n const boxRef = useRef<HTMLDivElement>(null)\n const desktopVideoRef = useRef<HTMLDivElement>(null)\n const tabletVideoRef = useRef<HTMLDivElement>(null)\n const mobileVideoRef = useRef<HTMLDivElement>(null)\n const mediaWrapperRef = useRef<HTMLDivElement>(null)\n\n // Tab\u72B6\u6001\u7BA1\u7406\n const [activeIndex, setActiveIndex] = useState(0)\n const tabRefs = useRef<Array<HTMLDivElement | null>>([])\n const [sliderStyle, setSliderStyle] = useState({ left: 0, width: 0 })\n\n // \u89C6\u9891\u61D2\u52A0\u8F7D\u72B6\u6001\n const [loadedDesktopVideoSrc, setLoadedDesktopVideoSrc] = useState('')\n const [loadedTabletVideoSrc, setLoadedTabletVideoSrc] = useState('')\n const [loadedMobileVideoSrc, setLoadedMobileVideoSrc] = useState('')\n\n // \u5224\u65AD\u662F\u5426\u4E3ATabWithImage\u6A21\u5F0F\uFF08\u4F18\u5148\u7EA7\u6700\u9AD8\uFF09\n const isTabMode = datalist.length > 0\n\n // \u5224\u65AD\u5F53\u524D\u662F\u5426\u4E3A\u89C6\u9891\u6A21\u5F0F\n const isVideo = mediaType === 'video'\n\n useExposure(boxRef, {\n componentType,\n componentName,\n componentTitle: title,\n componentDescription: subtitle,\n })\n\n useImperativeHandle(ref, () => boxRef.current as HTMLDivElement)\n\n // Tab\u6ED1\u5757\u4F4D\u7F6E\u8BA1\u7B97\n useEffect(() => {\n if (datalist.length > 0) {\n const current = tabRefs.current[activeIndex]\n if (current) {\n const { offsetLeft, offsetWidth } = current\n setSliderStyle({ left: offsetLeft, width: offsetWidth })\n }\n }\n }, [activeIndex, datalist.length])\n\n // \u89C6\u9891\u61D2\u52A0\u8F7D\u903B\u8F91\uFF08\u4F7F\u7528 useEffect \u907F\u514D\u95ED\u5305\u95EE\u9898\uFF09\n const [videoIntersected, setVideoIntersected] = useState(false)\n\n // \u4F7F\u7528 IntersectionObserver \u68C0\u6D4B\u5A92\u4F53\u533A\u57DF\u662F\u5426\u53EF\u89C1\uFF08\u76D1\u542C\u7236\u5BB9\u5668\u907F\u514D\u54CD\u5E94\u5F0F\u9690\u85CF\u95EE\u9898\uFF09\n useIntersectionObserverDelay(mediaWrapperRef, {\n once: true,\n threshold: 0.01,\n callback: () => {\n setVideoIntersected(true)\n },\n })\n\n // \u5F53\u89C6\u9891\u533A\u57DF\u53EF\u89C1\u65F6\uFF0C\u52A0\u8F7D\u5BF9\u5E94\u7684\u89C6\u9891\u6E90\n useEffect(() => {\n if (!videoIntersected || !isVideo) return\n\n // \u786E\u5B9A\u89C6\u9891\u6E90\n let desktopSrc = ''\n let tabletSrc = ''\n let mobileSrc = ''\n\n if (isTabMode && datalist[activeIndex]) {\n const activeTab = datalist[activeIndex]\n desktopSrc = activeTab.video?.url || ''\n tabletSrc = activeTab.padVideo?.url || desktopSrc\n mobileSrc = activeTab.mobVideo?.url || desktopSrc\n } else {\n desktopSrc = video?.url || ''\n tabletSrc = padVideo?.url || desktopSrc\n mobileSrc = mobVideo?.url || desktopSrc\n }\n\n // \u8BBE\u7F6E\u89C6\u9891\u6E90\n if (desktopSrc) setLoadedDesktopVideoSrc(desktopSrc)\n if (tabletSrc) setLoadedTabletVideoSrc(tabletSrc)\n if (mobileSrc) setLoadedMobileVideoSrc(mobileSrc)\n\n // \u5EF6\u8FDF\u89E6\u53D1\u64AD\u653E\n setTimeout(() => {\n const videos = [\n desktopVideoRef.current?.querySelector('video'),\n tabletVideoRef.current?.querySelector('video'),\n mobileVideoRef.current?.querySelector('video'),\n ]\n\n videos.forEach(videoElement => {\n if (videoElement) {\n videoElement.load()\n videoElement.play().catch(() => {\n // \u9759\u9ED8\u5904\u7406\u81EA\u52A8\u64AD\u653E\u5931\u8D25\u7684\u60C5\u51B5\n })\n }\n })\n }, 200)\n }, [videoIntersected, isVideo, isTabMode, activeIndex, datalist, video?.url, padVideo?.url, mobVideo?.url])\n\n const handleTabClick = (index: number, e: React.MouseEvent<HTMLDivElement>) => {\n setActiveIndex(index)\n ;(e.target as HTMLElement).scrollIntoView({\n behavior: 'smooth',\n inline: 'center',\n block: 'nearest',\n })\n\n // \u5982\u679C\u662F\u89C6\u9891\u6A21\u5F0F\u5E76\u4E14\u5207\u6362\u4E86Tab\uFF0C\u9700\u8981\u91CD\u65B0\u52A0\u8F7D\u548C\u64AD\u653E\u89C6\u9891\n if (isVideo && isTabMode && datalist[index]) {\n const activeTab = datalist[index]\n\n // \u66F4\u65B0\u89C6\u9891\u6E90\n if (activeTab.video?.url) {\n setLoadedDesktopVideoSrc(activeTab.video.url)\n }\n if (activeTab.padVideo?.url) {\n setLoadedTabletVideoSrc(activeTab.padVideo.url)\n }\n if (activeTab.mobVideo?.url) {\n setLoadedMobileVideoSrc(activeTab.mobVideo.url)\n }\n\n // \u5EF6\u8FDF\u89E6\u53D1\u64AD\u653E\uFF0C\u786E\u4FDDDOM\u66F4\u65B0\u5B8C\u6210\n setTimeout(() => {\n const videos = [\n desktopVideoRef.current?.querySelector('video'),\n tabletVideoRef.current?.querySelector('video'),\n mobileVideoRef.current?.querySelector('video'),\n ]\n\n videos.forEach(video => {\n if (video) {\n video.load()\n video.play().catch(() => {\n // \u9759\u9ED8\u5904\u7406\u81EA\u52A8\u64AD\u653E\u5931\u8D25\u7684\u60C5\u51B5\n })\n }\n })\n }, 300) // \u7A0D\u5FAE\u5EF6\u957F\u65F6\u95F4\u4EE5\u786E\u4FDDframer-motion\u52A8\u753B\u5B8C\u6210\n }\n }\n\n // \u6E32\u67D3\u6309\u94AE\n const renderButton = () => {\n if (!hasButton || !button?.text) return null\n if (effectiveLayout === 'top' || effectiveLayout === 'bottom') return null\n\n return (\n <div\n className={cn('image-with-text__button-wrapper laptop:mt-[32px] mt-[24px]', {\n 'flex justify-center': textAlign === 'center',\n 'flex justify-start': textAlign === 'left',\n })}\n >\n <Link\n href={getLocalizedPath(button.link || '', locale)}\n className=\"image-with-text__button whitespace-nowrap no-underline\"\n suffixIcon={ArrowRight}\n >\n {button.text}\n </Link>\n </div>\n )\n }\n\n // \u5224\u65AD\u662F\u5426\u6709\u529F\u80FD\u5217\u8868\n const hasItems = items.length > 0\n\n // \u5224\u65AD\u662F\u5426\u6709\u6309\u94AE\uFF08\u5F71\u54CD\u6587\u672C\u533A\u57DF\u7684\u5BF9\u9F50\u65B9\u5F0F\uFF09\n const hasButton = Boolean(button)\n\n // \u83B7\u53D6\u56FE\u7247\u6E90\n const getImageSource = () => {\n if (isTabMode && datalist[activeIndex]) {\n const activeTab = datalist[activeIndex]\n return `${activeTab.image?.url} ,${activeTab.imgPad?.url || activeTab.image?.url} 1440, ${activeTab.imageMob?.url || activeTab.image?.url} 767`\n }\n if (image) {\n return `${image?.url},${padImage?.url || image?.url} 1024, ${mobileImage?.url || image?.url} 768`\n }\n return ''\n }\n\n // \u6E32\u67D3\u89C6\u9891\u5185\u5BB9\uFF08\u652F\u6301\u4E09\u7AEF\uFF09\n const renderVideo = () => {\n if (isTabMode) {\n const activeTab = datalist[activeIndex]\n // Tab\u6A21\u5F0F\u4E0B\u7684\u89C6\u9891\uFF0C\u4F7F\u7528 image/imgPad/imageMob \u4F5C\u4E3A\u5C01\u9762\n const desktopPoster = activeTab.image?.url\n const tabletPoster = activeTab.imgPad?.url || desktopPoster\n const mobilePoster = activeTab.imageMob?.url || desktopPoster\n\n return (\n <AnimatePresence mode=\"wait\">\n <motion.div\n key={activeTab.video?.url || activeTab.image?.url}\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.3 }}\n className=\"image-with-text__video-motion absolute left-0 top-0 w-full\"\n >\n <div className=\"image-with-text__video-wrapper rounded-box overflow-hidden\">\n {/* \u684C\u9762\u7AEF\u89C6\u9891 */}\n <div ref={desktopVideoRef} className=\"image-with-text__desktop-video-container\">\n <video\n playsInline\n autoPlay\n muted\n poster={desktopPoster}\n src={loadedDesktopVideoSrc}\n loop\n className=\"image-with-text__video image-with-text__video--desktop lg-desktop:block hidden size-full object-cover\"\n ></video>\n </div>\n {/* \u5E73\u677F\u7AEF\u89C6\u9891 */}\n <div ref={tabletVideoRef} className=\"image-with-text__tablet-video-container\">\n <video\n playsInline\n autoPlay\n muted\n poster={tabletPoster}\n src={loadedTabletVideoSrc || loadedDesktopVideoSrc}\n loop\n className=\"image-with-text__video image-with-text__video--tablet tablet:block lg-desktop:hidden hidden\"\n ></video>\n </div>\n {/* \u79FB\u52A8\u7AEF\u89C6\u9891 */}\n <div ref={mobileVideoRef} className=\"image-with-text__mobile-video-container\">\n <video\n playsInline\n autoPlay\n muted\n poster={mobilePoster}\n src={loadedMobileVideoSrc || loadedDesktopVideoSrc}\n loop\n className=\"image-with-text__video image-with-text__video--mobile tablet:hidden block\"\n ></video>\n </div>\n </div>\n </motion.div>\n </AnimatePresence>\n )\n }\n\n // \u57FA\u7840\u6A21\u5F0F\u4E0B\u7684\u89C6\u9891\uFF08\u652F\u6301\u4E09\u7AEF\uFF09\uFF0C\u4F7F\u7528 image/padImage/mobileImage \u4F5C\u4E3A\u5C01\u9762\n const desktopPoster = image?.url\n const tabletPoster = padImage?.url || desktopPoster\n const mobilePoster = mobileImage?.url || desktopPoster\n\n return (\n <div className=\"image-with-text__video-wrapper rounded-box laptop:rounded-box overflow-hidden\">\n {/* \u684C\u9762\u7AEF\u89C6\u9891 */}\n <div ref={desktopVideoRef} className=\"image-with-text__desktop-video-container\">\n <video\n playsInline\n autoPlay\n muted\n poster={desktopPoster}\n src={loadedDesktopVideoSrc}\n loop\n className=\"image-with-text__video image-with-text__video--desktop lg-desktop:block hidden size-full object-cover\"\n ></video>\n </div>\n {/* \u5E73\u677F\u7AEF\u89C6\u9891 */}\n <div ref={tabletVideoRef} className=\"image-with-text__tablet-video-container\">\n <video\n playsInline\n autoPlay\n muted\n poster={tabletPoster}\n src={loadedTabletVideoSrc || loadedDesktopVideoSrc}\n loop\n className=\"image-with-text__video image-with-text__video--tablet tablet:block lg-desktop:hidden hidden\"\n ></video>\n </div>\n {/* \u79FB\u52A8\u7AEF\u89C6\u9891 */}\n <div ref={mobileVideoRef} className=\"image-with-text__mobile-video-container\">\n <video\n playsInline\n autoPlay\n muted\n poster={mobilePoster}\n src={loadedMobileVideoSrc || loadedDesktopVideoSrc}\n loop\n className=\"image-with-text__video image-with-text__video--mobile tablet:hidden block\"\n ></video>\n </div>\n </div>\n )\n }\n\n return (\n <section\n ref={boxRef}\n data-ui-component-id=\"ImageWithText\"\n className={cn(\n 'image-with-text text-info-primary',\n {\n // \u57FA\u7840\u6A21\u5F0F\u6837\u5F0F - \u652F\u6301\u4E0A\u4E0B\u5DE6\u53F3\u5E03\u5C40\n 'flex gap-[24px] laptop:gap-[48px] lg-desktop:gap-[64px]': !isTabMode,\n 'flex-col': !isTabMode && (effectiveLayout === 'top' || effectiveLayout === 'bottom'),\n 'items-center': effectiveLayout === 'left' || effectiveLayout === 'right',\n 'flex-col laptop:flex-row': !isTabMode && (effectiveLayout === 'left' || effectiveLayout === 'right'),\n // TabWithImage\u6A21\u5F0F\u6837\u5F0F\n 'flex l:gap-[24px] xl:flex-col min-md:justify-between min-l:gap-[20px]': isTabMode,\n // \u4E3B\u9898\u6837\u5F0F\n 'aiui-dark': theme === 'dark',\n },\n className\n )}\n >\n {/* TabWithImage\u6A21\u5F0F\u7684\u5185\u5BB9\u548CTab\u63A7\u5236 */}\n {isTabMode && (title || desc || datalist.length > 0) && (\n <div\n className={cn(\n 'image-with-text__tab-content min-md:gap-[24px] laptop:basis-[36%] inline-flex flex-col justify-center',\n {\n 'text-left': textAlign === 'left',\n 'text-center': textAlign === 'center',\n }\n )}\n >\n <div className=\"image-with-text__header\">\n <Heading as={'h3'} size={4} html={title} className=\"image-with-text__title\" />\n <Text\n as={'p'}\n size={1}\n html={desc}\n className=\"image-with-text__description tablet:text-[14px] laptop:text-[14px] desktop:text-[16px] lg-desktop:text-[18px] mt-[4px] text-[14px]\"\n />\n </div>\n\n <div\n className={cn(\n 'image-with-text__tabs-wrapper md:scrollbar-hidden relative md:overflow-hidden md:overflow-x-scroll',\n {\n 'flex justify-center': textAlign === 'center',\n }\n )}\n >\n <div className=\"image-with-text__tabs rounded-btn relative inline-flex bg-[#1D1D1F] px-[4px] md:my-[24px]\">\n {/* \u6ED1\u52A8\u80CC\u666F */}\n <div\n className=\"image-with-text__slider rounded-btn absolute inset-y-0 bg-white transition-all duration-300 ease-in-out\"\n style={{\n left: sliderStyle.left,\n width: sliderStyle.width,\n }}\n />\n\n {/* Tab Items */}\n {datalist.map((item: ImageWithTextTabItem, index: number) => (\n <div\n key={index}\n ref={el => {\n tabRefs.current[index] = el\n }}\n onClick={e => handleTabClick(index, e)}\n className={cn(\n 'image-with-text__tab rounded-btn min-xxl:px-[28px] min-xxl:py-[15px] relative z-10 cursor-pointer px-[20px] py-[10px] text-center text-[12px] font-medium transition-colors duration-300 md:px-[20px] md:py-[10px]',\n activeIndex === index ? 'image-with-text__tab--active text-black' : 'text-white'\n )}\n >\n <Heading\n as=\"h1\"\n size={1}\n html={item?.title}\n className=\"image-with-text__tab-title text-balance-normal !whitespace-nowrap md:text-[14px]\"\n />\n </div>\n ))}\n </div>\n </div>\n </div>\n )}\n\n {/* \u57FA\u7840\u6A21\u5F0F\u7684\u5185\u5BB9\u533A\u57DF */}\n {!isTabMode && (title || subtitle || desc) && (\n <div\n className={cn('image-with-text__content flex flex-col', {\n // \u5782\u76F4\u5BF9\u9F50\uFF1A\u5982\u679C\u6709\u6309\u94AE\u5219\u4F7F\u7528 justify-between\uFF0C\u5426\u5219\u5C45\u4E2D\u5BF9\u9F50\n 'justify-center': !hasButton,\n 'justify-between': hasButton,\n // \u4F7F\u7528items\u65F6\u7684\u7279\u6B8A\u6837\u5F0F\uFF08\u7C7B\u4F3C\u539FFeature\u6A21\u5F0F\uFF09\n 'w-full laptop:w-fit': hasItems,\n // \u6C34\u5E73\u5BF9\u9F50\u63A7\u5236\uFF1A\u5F53\u6709\u529F\u80FD\u5217\u8868\u65F6\uFF0C\u6839\u636EtextAlign\u51B3\u5B9A\u5BF9\u9F50\u65B9\u5F0F\n 'items-start': textAlign === 'left',\n 'items-center': textAlign === 'center',\n // \u6587\u672C\u5BF9\u9F50\u63A7\u5236\n 'text-left': textAlign === 'left',\n 'text-center': textAlign === 'center',\n // order\u63A7\u5236\n 'laptop:order-1': effectiveLayout === 'left',\n })}\n >\n {/* \u4E3B\u8981\u5185\u5BB9\u533A\u57DF\uFF08\u5F53\u6709\u6309\u94AE\u65F6\uFF0C\u8FD9\u4E2Adiv\u5305\u542B\u9664\u6309\u94AE\u5916\u7684\u6240\u6709\u5185\u5BB9\uFF09 */}\n <div className={cn('image-with-text__main-content', { 'flex flex-col': hasButton })}>\n <div\n className={cn('image-with-text__header', {\n 'laptop:flex laptop:items-end laptop:justify-between laptop:gap-16':\n (effectiveLayout === 'top' || effectiveLayout === 'bottom') && button?.text,\n })}\n >\n <div className=\"image-with-text__title-wrapper flex min-w-0 flex-1 flex-col\">\n <Heading\n as={'h2'}\n size={4}\n html={title}\n className={cn('image-with-text__title', {\n 'text-left': hasItems && textAlign === 'left',\n 'text-center': hasItems && textAlign === 'center',\n })}\n />\n {subtitle && (\n <Text\n as={'p'}\n size={hasItems ? 4 : 3}\n html={subtitle}\n className={cn(\n 'image-with-text__subtitle tablet:text-[14px] laptop:text-[14px] desktop:text-[16px] lg-desktop:text-[18px] mt-[4px] text-[14px]',\n {\n 'laptop:mt-[16px]': !hasItems,\n 'min-xxl:mt-[8px] laptop:text-[16px] lg-desktop:text-[18px]': hasItems,\n 'text-left': hasItems && textAlign === 'left',\n 'text-center': hasItems && textAlign === 'center',\n }\n )}\n />\n )}\n </div>\n {(effectiveLayout === 'top' || effectiveLayout === 'bottom') && button?.text && (\n <Link\n href={getLocalizedPath(button.link || '', locale)}\n className=\"laptop:flex hidden whitespace-nowrap no-underline\"\n suffixIcon={ArrowRight}\n >\n {button.text}\n </Link>\n )}\n </div>\n\n {/* \u57FA\u7840\u6A21\u5F0F\u7684\u63CF\u8FF0\uFF08\u4E0D\u4F7F\u7528items\u65F6\uFF09 */}\n {!hasItems && (desc || descIcon) && (\n <div className=\"image-with-text__description flex flex-row gap-[8px]\">\n {descIcon && (\n <img\n src={descIcon}\n alt=\"icon\"\n className=\"image-with-text__description-icon desktop:size-[48px] size-[36px]\"\n />\n )}\n {desc && (\n <Heading\n as={'h4'}\n size={5}\n html={desc}\n className=\"image-with-text__description-text min-md:text-[40px] min-l:text-[40px] min-xl:text-[56px] min-xxl:text-[64px] text-[#3AD1FF] md:text-[40px]\"\n />\n )}\n </div>\n )}\n\n {/* \u529F\u80FD\u5217\u8868\uFF08\u5F53\u6709items\u65F6\u663E\u793A\uFF09 */}\n {hasItems && (\n <div\n className={cn('image-with-text__items laptop:mt-[32px] desktop:mt-[48px] mt-[24px] grid w-full gap-6', {\n '!mt-6': effectiveLayout === 'top' || effectiveLayout === 'bottom',\n // \u5F53 effectiveLayout \u662F top \u6216 bottom \u65F6\uFF1A\u9ED8\u8BA4 cols \u662F 2\uFF0Ctablet \u6216\u4EE5\u4E0A\u5C3A\u5BF8\u662F 4\n 'grid-cols-2 tablet:grid-cols-4': effectiveLayout === 'top' || effectiveLayout === 'bottom',\n // \u5F53 effectiveLayout \u662F left \u6216 right \u65F6\uFF1Acols \u9ED8\u8BA4\u662F 2\uFF0Ctablet \u662F 4\uFF0Claptop \u6216\u4EE5\u4E0A\u5C3A\u5BF8\u662F 2\n 'grid-cols-2 tablet:grid-cols-4 laptop:grid-cols-2':\n effectiveLayout === 'left' || effectiveLayout === 'right',\n })}\n >\n {items.map((item: ImageWithTextItem, index: number) => (\n <div\n key={index}\n className={cn('image-with-text__item', {\n 'text-center': textAlign === 'center',\n })}\n >\n <div\n className={cn('image-with-text__item-header flex flex-row items-center gap-[8px]', {\n 'justify-center': textAlign === 'center',\n 'justify-start': textAlign === 'left',\n })}\n >\n <Picture\n source={item.icon?.url}\n alt={item.icon?.alt}\n className=\"image-with-text__item-icon min-md:text-[40px] min-l:text-[40px] min-xl:text-[56px] min-xxl:text-[64px] desktop:h-[44px] lg-desktop:h-[52px] h-[28px] translate-y-[-12%] md:text-[40px]\"\n imgClassName=\"h-full !w-full\"\n />\n <Heading\n size={4}\n as=\"h6\"\n className=\"image-with-text__item-text bg-gradient-to-r from-[#3ad1ff] to-[#008cd6] bg-clip-text text-transparent\"\n >\n {item.text}\n </Heading>\n </div>\n <Text\n size={4}\n as=\"p\"\n html={item.desc}\n className=\"image-with-text__item-desc tablet:text-[14px] laptop:text-[14px] desktop:text-[16px] lg-desktop:text-[18px] mt-[-2px] text-[14px]\"\n />\n </div>\n ))}\n </div>\n )}\n </div>\n\n {/* \u6309\u94AE\uFF08\u653E\u5728\u4E3B\u8981\u5185\u5BB9\u533A\u57DF\u5916\uFF09 */}\n {renderButton()}\n </div>\n )}\n\n {/* \u56FE\u7247/\u89C6\u9891\u533A\u57DF */}\n <div\n ref={mediaWrapperRef}\n className={cn('image-with-text__media-wrapper', {\n 'laptop:w-[60%] w-full shrink-0': effectiveLayout === 'left' || effectiveLayout === 'right',\n // \u4F7F\u7528items\u65F6\u7684\u7279\u6B8A\u6837\u5F0F\uFF08\u7C7B\u4F3C\u539FFeature\u6A21\u5F0F\uFF09\n 'aspect-[716/720] max-h-[560px] max-w-[824px] tablet:aspect-[704/360] laptop:aspect-[824/560] shrink-0':\n hasItems,\n 'laptop:basis-[63%] desktop:basis-[57%]': hasItems && effectiveLayout === 'left',\n // TabWithImage\u6A21\u5F0F\n 'relative w-full shrink md:aspect-[358/360] min-xxl:aspect-[824/560] min-xxl:max-w-[824px] tablet:aspect-[704/360] laptop:aspect-[744/336] laptop:basis-[64%] desktop:aspect-[648/448]':\n isTabMode,\n '!max-w-none !max-h-none aspect-auto': effectiveLayout === 'top' || effectiveLayout === 'bottom',\n })}\n >\n {isTabMode ? (\n // TabWithImage\u6A21\u5F0F - \u652F\u6301\u56FE\u7247\u548C\u89C6\u9891\n isVideo ? (\n renderVideo()\n ) : (\n <AnimatePresence mode=\"wait\">\n <motion.div\n key={datalist[activeIndex].image?.url}\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.3 }}\n className=\"image-with-text__image-motion absolute left-0 top-0 w-full\"\n >\n <Picture\n source={getImageSource()}\n alt={datalist[activeIndex].image?.alt}\n className=\"image-with-text__image rounded-box min-xxl:aspect-[824/560] min-xxl:max-w-[824px] tablet:aspect-[704/360] laptop:aspect-[744/336] desktop:aspect-[648/448] md:aspect-[358/360]\"\n />\n </motion.div>\n </AnimatePresence>\n )\n ) : isVideo ? (\n // \u57FA\u7840\u6A21\u5F0F - \u89C6\u9891\n renderVideo()\n ) : (\n // \u57FA\u7840\u6A21\u5F0F - \u56FE\u7247\n <Picture source={getImageSource()} className={cn('image-with-text__image rounded-box laptop:rounded-box')} />\n )}\n </div>\n </section>\n )\n})\n\nImageWithText.displayName = 'ImageWithText'\n\nexport default withLayout(ImageWithText)\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["'use client'\nimport React, { useImperativeHandle, useRef, useState, useEffect } from 'react'\nimport { Heading, Picture, Text, Link } from '../../components/index.js'\nimport { cn, getLocalizedPath } from '../../helpers/utils.js'\nimport { withLayout } from '../../shared/Styles.js'\nimport { useExposure } from '../../hooks/useExposure.js'\nimport { useIntersectionObserverDelay } from '../../hooks/useIntersectionObserver.js'\nimport { useAiuiContext } from '../AiuiProvider/index.js'\nimport { motion, AnimatePresence } from 'framer-motion'\nimport type { ImageWithTextProps, ImageWithTextItem, ImageWithTextTabItem } from './types.js'\n\nconst componentType = 'image'\nconst componentName = 'image_with_text'\n\nconst ArrowRight = (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\n <path\n d=\"M6.91009 4.41058C7.23553 4.08514 7.76304 4.08514 8.08848 4.41058L13.0885 9.41058C13.4139 9.73602 13.4139 10.2635 13.0885 10.589L8.08848 15.589C7.76304 15.9144 7.23553 15.9144 6.91009 15.589C6.58466 15.2635 6.58466 14.736 6.91009 14.4106L11.3209 9.99977L6.91009 5.58897C6.58466 5.26353 6.58466 4.73602 6.91009 4.41058Z\"\n fill=\"currentColor\"\n />\n </svg>\n)\n\nconst ImageWithText = React.forwardRef<HTMLDivElement, ImageWithTextProps>(({ data, className }, ref) => {\n const {\n title,\n subtitle,\n desc,\n descIcon,\n image,\n padImage,\n mobileImage,\n theme = 'dark',\n items = [],\n layout = 'left',\n mediaType = 'image',\n datalist = [],\n video,\n padVideo,\n mobVideo,\n button,\n textAlign = 'left',\n } = data\n\n const effectiveLayout = layout\n\n const { locale = 'us' } = useAiuiContext()\n const boxRef = useRef<HTMLDivElement>(null)\n const desktopVideoRef = useRef<HTMLDivElement>(null)\n const tabletVideoRef = useRef<HTMLDivElement>(null)\n const mobileVideoRef = useRef<HTMLDivElement>(null)\n const mediaWrapperRef = useRef<HTMLDivElement>(null)\n\n // Tab\u72B6\u6001\u7BA1\u7406\n const [activeIndex, setActiveIndex] = useState(0)\n const tabRefs = useRef<Array<HTMLDivElement | null>>([])\n const [sliderStyle, setSliderStyle] = useState({ left: 0, width: 0 })\n\n // \u89C6\u9891\u61D2\u52A0\u8F7D\u72B6\u6001\n const [loadedDesktopVideoSrc, setLoadedDesktopVideoSrc] = useState('')\n const [loadedTabletVideoSrc, setLoadedTabletVideoSrc] = useState('')\n const [loadedMobileVideoSrc, setLoadedMobileVideoSrc] = useState('')\n\n // \u5224\u65AD\u662F\u5426\u4E3ATabWithImage\u6A21\u5F0F\uFF08\u4F18\u5148\u7EA7\u6700\u9AD8\uFF09\n const isTabMode = datalist.length > 0\n\n // \u5224\u65AD\u5F53\u524D\u662F\u5426\u4E3A\u89C6\u9891\u6A21\u5F0F\n const isVideo = mediaType === 'video'\n\n useExposure(boxRef, {\n componentType,\n componentName,\n componentTitle: title,\n componentDescription: subtitle,\n })\n\n useImperativeHandle(ref, () => boxRef.current as HTMLDivElement)\n\n // Tab\u6ED1\u5757\u4F4D\u7F6E\u8BA1\u7B97\n useEffect(() => {\n if (datalist.length > 0) {\n const current = tabRefs.current[activeIndex]\n if (current) {\n const { offsetLeft, offsetWidth } = current\n setSliderStyle({ left: offsetLeft, width: offsetWidth })\n }\n }\n }, [activeIndex, datalist.length])\n\n // \u89C6\u9891\u61D2\u52A0\u8F7D\u903B\u8F91\uFF08\u4F7F\u7528 useEffect \u907F\u514D\u95ED\u5305\u95EE\u9898\uFF09\n const [videoIntersected, setVideoIntersected] = useState(false)\n\n // \u4F7F\u7528 IntersectionObserver \u68C0\u6D4B\u5A92\u4F53\u533A\u57DF\u662F\u5426\u53EF\u89C1\uFF08\u76D1\u542C\u7236\u5BB9\u5668\u907F\u514D\u54CD\u5E94\u5F0F\u9690\u85CF\u95EE\u9898\uFF09\n useIntersectionObserverDelay(mediaWrapperRef, {\n once: true,\n threshold: 0.01,\n callback: () => {\n setVideoIntersected(true)\n },\n })\n\n // \u5F53\u89C6\u9891\u533A\u57DF\u53EF\u89C1\u65F6\uFF0C\u52A0\u8F7D\u5BF9\u5E94\u7684\u89C6\u9891\u6E90\n useEffect(() => {\n if (!videoIntersected || !isVideo) return\n\n // \u786E\u5B9A\u89C6\u9891\u6E90\n let desktopSrc = ''\n let tabletSrc = ''\n let mobileSrc = ''\n\n if (isTabMode && datalist[activeIndex]) {\n const activeTab = datalist[activeIndex]\n desktopSrc = activeTab.video?.url || ''\n tabletSrc = activeTab.padVideo?.url || desktopSrc\n mobileSrc = activeTab.mobVideo?.url || desktopSrc\n } else {\n desktopSrc = video?.url || ''\n tabletSrc = padVideo?.url || desktopSrc\n mobileSrc = mobVideo?.url || desktopSrc\n }\n\n // \u8BBE\u7F6E\u89C6\u9891\u6E90\n if (desktopSrc) setLoadedDesktopVideoSrc(desktopSrc)\n if (tabletSrc) setLoadedTabletVideoSrc(tabletSrc)\n if (mobileSrc) setLoadedMobileVideoSrc(mobileSrc)\n\n // \u5EF6\u8FDF\u89E6\u53D1\u64AD\u653E\n setTimeout(() => {\n const videos = [\n desktopVideoRef.current?.querySelector('video'),\n tabletVideoRef.current?.querySelector('video'),\n mobileVideoRef.current?.querySelector('video'),\n ]\n\n videos.forEach(videoElement => {\n if (videoElement) {\n videoElement.load()\n videoElement.play().catch(() => {\n // \u9759\u9ED8\u5904\u7406\u81EA\u52A8\u64AD\u653E\u5931\u8D25\u7684\u60C5\u51B5\n })\n }\n })\n }, 200)\n }, [videoIntersected, isVideo, isTabMode, activeIndex, datalist, video?.url, padVideo?.url, mobVideo?.url])\n\n const handleTabClick = (index: number, e: React.MouseEvent<HTMLDivElement>) => {\n setActiveIndex(index)\n ;(e.target as HTMLElement).scrollIntoView({\n behavior: 'smooth',\n inline: 'center',\n block: 'nearest',\n })\n\n // \u5982\u679C\u662F\u89C6\u9891\u6A21\u5F0F\u5E76\u4E14\u5207\u6362\u4E86Tab\uFF0C\u9700\u8981\u91CD\u65B0\u52A0\u8F7D\u548C\u64AD\u653E\u89C6\u9891\n if (isVideo && isTabMode && datalist[index]) {\n const activeTab = datalist[index]\n\n // \u66F4\u65B0\u89C6\u9891\u6E90\n if (activeTab.video?.url) {\n setLoadedDesktopVideoSrc(activeTab.video.url)\n }\n if (activeTab.padVideo?.url) {\n setLoadedTabletVideoSrc(activeTab.padVideo.url)\n }\n if (activeTab.mobVideo?.url) {\n setLoadedMobileVideoSrc(activeTab.mobVideo.url)\n }\n\n // \u5EF6\u8FDF\u89E6\u53D1\u64AD\u653E\uFF0C\u786E\u4FDDDOM\u66F4\u65B0\u5B8C\u6210\n setTimeout(() => {\n const videos = [\n desktopVideoRef.current?.querySelector('video'),\n tabletVideoRef.current?.querySelector('video'),\n mobileVideoRef.current?.querySelector('video'),\n ]\n\n videos.forEach(video => {\n if (video) {\n video.load()\n video.play().catch(() => {\n // \u9759\u9ED8\u5904\u7406\u81EA\u52A8\u64AD\u653E\u5931\u8D25\u7684\u60C5\u51B5\n })\n }\n })\n }, 300) // \u7A0D\u5FAE\u5EF6\u957F\u65F6\u95F4\u4EE5\u786E\u4FDDframer-motion\u52A8\u753B\u5B8C\u6210\n }\n }\n\n // \u6E32\u67D3\u6309\u94AE\n const renderButton = () => {\n if (!hasButton || !button?.text) return null\n if (effectiveLayout === 'top' || effectiveLayout === 'bottom') return null\n\n return (\n <div\n className={cn('image-with-text__button-wrapper laptop:mt-[32px] mt-[24px]', {\n 'flex justify-center': textAlign === 'center',\n 'flex justify-start': textAlign === 'left',\n })}\n >\n <Link\n href={getLocalizedPath(button.link || '', locale)}\n className=\"image-with-text__button whitespace-nowrap no-underline\"\n suffixIcon={ArrowRight}\n >\n {button.text}\n </Link>\n </div>\n )\n }\n\n // \u5224\u65AD\u662F\u5426\u6709\u529F\u80FD\u5217\u8868\n const hasItems = items.length > 0\n\n // \u5224\u65AD\u662F\u5426\u6709\u6309\u94AE\uFF08\u5F71\u54CD\u6587\u672C\u533A\u57DF\u7684\u5BF9\u9F50\u65B9\u5F0F\uFF09\n const hasButton = Boolean(button)\n\n // \u83B7\u53D6\u56FE\u7247\u6E90\n const getImageSource = () => {\n if (isTabMode && datalist[activeIndex]) {\n const activeTab = datalist[activeIndex]\n return `${activeTab.image?.url} ,${activeTab.imgPad?.url || activeTab.image?.url} 1440, ${activeTab.imageMob?.url || activeTab.image?.url} 767`\n }\n if (image) {\n return `${image?.url},${padImage?.url || image?.url} 1024, ${mobileImage?.url || image?.url} 768`\n }\n return ''\n }\n\n // \u6E32\u67D3\u89C6\u9891\u5185\u5BB9\uFF08\u652F\u6301\u4E09\u7AEF\uFF09\n const renderVideo = () => {\n if (isTabMode) {\n const activeTab = datalist[activeIndex]\n // Tab\u6A21\u5F0F\u4E0B\u7684\u89C6\u9891\uFF0C\u4F7F\u7528 image/imgPad/imageMob \u4F5C\u4E3A\u5C01\u9762\n const desktopPoster = activeTab.image?.url\n const tabletPoster = activeTab.imgPad?.url || desktopPoster\n const mobilePoster = activeTab.imageMob?.url || desktopPoster\n\n return (\n <AnimatePresence mode=\"wait\">\n <motion.div\n key={activeTab.video?.url || activeTab.image?.url}\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.3 }}\n className=\"image-with-text__video-motion absolute left-0 top-0 w-full\"\n >\n <div className=\"image-with-text__video-wrapper rounded-box overflow-hidden\">\n {/* \u684C\u9762\u7AEF\u89C6\u9891 */}\n <div ref={desktopVideoRef} className=\"image-with-text__desktop-video-container\">\n <video\n playsInline\n autoPlay\n muted\n poster={desktopPoster}\n src={loadedDesktopVideoSrc}\n loop\n className=\"image-with-text__video image-with-text__video--desktop lg-desktop:block hidden size-full object-cover\"\n ></video>\n </div>\n {/* \u5E73\u677F\u7AEF\u89C6\u9891 */}\n <div ref={tabletVideoRef} className=\"image-with-text__tablet-video-container\">\n <video\n playsInline\n autoPlay\n muted\n poster={tabletPoster}\n src={loadedTabletVideoSrc || loadedDesktopVideoSrc}\n loop\n className=\"image-with-text__video image-with-text__video--tablet tablet:block lg-desktop:hidden hidden\"\n ></video>\n </div>\n {/* \u79FB\u52A8\u7AEF\u89C6\u9891 */}\n <div ref={mobileVideoRef} className=\"image-with-text__mobile-video-container\">\n <video\n playsInline\n autoPlay\n muted\n poster={mobilePoster}\n src={loadedMobileVideoSrc || loadedDesktopVideoSrc}\n loop\n className=\"image-with-text__video image-with-text__video--mobile tablet:hidden block\"\n ></video>\n </div>\n </div>\n </motion.div>\n </AnimatePresence>\n )\n }\n\n // \u57FA\u7840\u6A21\u5F0F\u4E0B\u7684\u89C6\u9891\uFF08\u652F\u6301\u4E09\u7AEF\uFF09\uFF0C\u4F7F\u7528 image/padImage/mobileImage \u4F5C\u4E3A\u5C01\u9762\n const desktopPoster = image?.url\n const tabletPoster = padImage?.url || desktopPoster\n const mobilePoster = mobileImage?.url || desktopPoster\n\n return (\n <div className=\"image-with-text__video-wrapper rounded-box laptop:rounded-box overflow-hidden\">\n {/* \u684C\u9762\u7AEF\u89C6\u9891 */}\n <div ref={desktopVideoRef} className=\"image-with-text__desktop-video-container\">\n <video\n playsInline\n autoPlay\n muted\n poster={desktopPoster}\n src={loadedDesktopVideoSrc}\n loop\n className=\"image-with-text__video image-with-text__video--desktop lg-desktop:block hidden size-full object-cover\"\n ></video>\n </div>\n {/* \u5E73\u677F\u7AEF\u89C6\u9891 */}\n <div ref={tabletVideoRef} className=\"image-with-text__tablet-video-container\">\n <video\n playsInline\n autoPlay\n muted\n poster={tabletPoster}\n src={loadedTabletVideoSrc || loadedDesktopVideoSrc}\n loop\n className=\"image-with-text__video image-with-text__video--tablet tablet:block lg-desktop:hidden hidden\"\n ></video>\n </div>\n {/* \u79FB\u52A8\u7AEF\u89C6\u9891 */}\n <div ref={mobileVideoRef} className=\"image-with-text__mobile-video-container\">\n <video\n playsInline\n autoPlay\n muted\n poster={mobilePoster}\n src={loadedMobileVideoSrc || loadedDesktopVideoSrc}\n loop\n className=\"image-with-text__video image-with-text__video--mobile tablet:hidden block\"\n ></video>\n </div>\n </div>\n )\n }\n\n return (\n <section\n ref={boxRef}\n data-ui-component-id=\"ImageWithText\"\n className={cn(\n 'image-with-text text-info-primary',\n {\n // \u57FA\u7840\u6A21\u5F0F\u6837\u5F0F - \u652F\u6301\u4E0A\u4E0B\u5DE6\u53F3\u5E03\u5C40\n 'flex gap-[24px] laptop:gap-[48px] lg-desktop:gap-[64px]': !isTabMode,\n 'flex-col': !isTabMode && (effectiveLayout === 'top' || effectiveLayout === 'bottom'),\n 'items-center': effectiveLayout === 'left' || effectiveLayout === 'right',\n 'flex-col laptop:flex-row': !isTabMode && (effectiveLayout === 'left' || effectiveLayout === 'right'),\n // TabWithImage\u6A21\u5F0F\u6837\u5F0F\n 'flex l:gap-[24px] xl:flex-col min-md:justify-between min-l:gap-[20px]': isTabMode,\n // \u4E3B\u9898\u6837\u5F0F\n 'aiui-dark': theme === 'dark',\n },\n className\n )}\n >\n {/* TabWithImage\u6A21\u5F0F\u7684\u5185\u5BB9\u548CTab\u63A7\u5236 */}\n {isTabMode && (title || desc || datalist.length > 0) && (\n <div\n className={cn(\n 'image-with-text__tab-content min-md:gap-[24px] laptop:basis-[36%] inline-flex flex-col justify-center',\n {\n 'text-left': textAlign === 'left',\n 'text-center': textAlign === 'center',\n }\n )}\n >\n <div className=\"image-with-text__header\">\n <Heading as={'h3'} size={4} html={title} className=\"image-with-text__title\" />\n <Text\n as={'p'}\n size={1}\n html={desc}\n className=\"image-with-text__description tablet:text-[14px] laptop:text-[14px] desktop:text-[16px] lg-desktop:text-[18px] mt-[4px] text-[14px]\"\n />\n </div>\n\n <div\n className={cn(\n 'image-with-text__tabs-wrapper md:scrollbar-hidden relative md:overflow-hidden md:overflow-x-scroll',\n {\n 'flex justify-center': textAlign === 'center',\n }\n )}\n >\n <div className=\"image-with-text__tabs rounded-btn relative inline-flex bg-[#1D1D1F] px-[4px] md:my-[24px]\">\n {/* \u6ED1\u52A8\u80CC\u666F */}\n <div\n className=\"image-with-text__slider rounded-btn absolute inset-y-0 bg-white transition-all duration-300 ease-in-out\"\n style={{\n left: sliderStyle.left,\n width: sliderStyle.width,\n }}\n />\n\n {/* Tab Items */}\n {datalist.map((item: ImageWithTextTabItem, index: number) => (\n <div\n key={index}\n ref={el => {\n tabRefs.current[index] = el\n }}\n onClick={e => handleTabClick(index, e)}\n className={cn(\n 'image-with-text__tab rounded-btn min-xxl:px-[28px] min-xxl:py-[15px] relative z-10 cursor-pointer px-[20px] py-[10px] text-center text-[12px] font-medium transition-colors duration-300 md:px-[20px] md:py-[10px]',\n activeIndex === index ? 'image-with-text__tab--active text-black' : 'text-white'\n )}\n >\n <Heading\n as=\"h1\"\n size={1}\n html={item?.title}\n className=\"image-with-text__tab-title text-balance-normal !whitespace-nowrap md:text-[14px]\"\n />\n </div>\n ))}\n </div>\n </div>\n </div>\n )}\n\n {/* \u57FA\u7840\u6A21\u5F0F\u7684\u5185\u5BB9\u533A\u57DF */}\n {!isTabMode && (title || subtitle || desc) && (\n <div\n className={cn('image-with-text__content flex w-full flex-col', {\n // \u5782\u76F4\u5BF9\u9F50\uFF1A\u5982\u679C\u6709\u6309\u94AE\u5219\u4F7F\u7528 justify-between\uFF0C\u5426\u5219\u5C45\u4E2D\u5BF9\u9F50\n 'justify-center': !hasButton,\n 'justify-between': hasButton,\n // \u6C34\u5E73\u5BF9\u9F50\u63A7\u5236\uFF1A\u5F53\u6709\u529F\u80FD\u5217\u8868\u65F6\uFF0C\u6839\u636EtextAlign\u51B3\u5B9A\u5BF9\u9F50\u65B9\u5F0F\n 'items-start': textAlign === 'left' && hasItems,\n 'items-center': textAlign === 'center' && hasItems,\n // \u6587\u672C\u5BF9\u9F50\u63A7\u5236\n 'text-left': textAlign === 'left',\n 'text-center': textAlign === 'center',\n // order\u63A7\u5236\n 'laptop:order-1': effectiveLayout === 'left',\n })}\n >\n {/* \u4E3B\u8981\u5185\u5BB9\u533A\u57DF\uFF08\u5F53\u6709\u6309\u94AE\u65F6\uFF0C\u8FD9\u4E2Adiv\u5305\u542B\u9664\u6309\u94AE\u5916\u7684\u6240\u6709\u5185\u5BB9\uFF09 */}\n <div className={cn('image-with-text__main-content', { 'flex flex-col': hasButton })}>\n <div\n className={cn('image-with-text__header', {\n 'laptop:flex laptop:items-end laptop:justify-between laptop:gap-16':\n (effectiveLayout === 'top' || effectiveLayout === 'bottom') && button?.text,\n })}\n >\n <div className=\"image-with-text__title-wrapper flex min-w-0 flex-1 flex-col\">\n <Heading\n as={'h2'}\n size={4}\n html={title}\n className={cn('image-with-text__title', {\n 'text-left': hasItems && textAlign === 'left',\n 'text-center': hasItems && textAlign === 'center',\n })}\n />\n {subtitle && (\n <Text\n as={'p'}\n size={hasItems ? 4 : 3}\n html={subtitle}\n className={cn(\n 'image-with-text__subtitle tablet:text-[14px] laptop:text-[14px] desktop:text-[16px] lg-desktop:text-[18px] mt-[4px] text-[14px]',\n {\n 'laptop:mt-[16px]': !hasItems,\n 'min-xxl:mt-[8px] laptop:text-[16px] lg-desktop:text-[18px]': hasItems,\n 'text-left': hasItems && textAlign === 'left',\n 'text-center': hasItems && textAlign === 'center',\n }\n )}\n />\n )}\n </div>\n {(effectiveLayout === 'top' || effectiveLayout === 'bottom') && button?.text && (\n <Link\n href={getLocalizedPath(button.link || '', locale)}\n className=\"laptop:flex hidden whitespace-nowrap no-underline\"\n suffixIcon={ArrowRight}\n >\n {button.text}\n </Link>\n )}\n </div>\n\n {/* \u57FA\u7840\u6A21\u5F0F\u7684\u63CF\u8FF0\uFF08\u4E0D\u4F7F\u7528items\u65F6\uFF09 */}\n {!hasItems && (desc || descIcon) && (\n <div className=\"image-with-text__description flex flex-row gap-[8px]\">\n {descIcon && (\n <img\n src={descIcon}\n alt=\"icon\"\n className=\"image-with-text__description-icon desktop:size-[48px] size-[36px]\"\n />\n )}\n {desc && (\n <Heading\n as={'h4'}\n size={5}\n html={desc}\n className=\"image-with-text__description-text min-md:text-[40px] min-l:text-[40px] min-xl:text-[56px] min-xxl:text-[64px] text-[#3AD1FF] md:text-[40px]\"\n />\n )}\n </div>\n )}\n\n {/* \u529F\u80FD\u5217\u8868\uFF08\u5F53\u6709items\u65F6\u663E\u793A\uFF09 */}\n {hasItems && (\n <div\n className={cn('image-with-text__items laptop:mt-[32px] desktop:mt-[48px] mt-[24px] grid w-full gap-6', {\n '!mt-6': effectiveLayout === 'top' || effectiveLayout === 'bottom',\n // \u5F53 effectiveLayout \u662F top \u6216 bottom \u65F6\uFF1A\u9ED8\u8BA4 cols \u662F 2\uFF0Ctablet \u6216\u4EE5\u4E0A\u5C3A\u5BF8\u662F 4\n 'grid-cols-2 tablet:grid-cols-4': effectiveLayout === 'top' || effectiveLayout === 'bottom',\n // \u5F53 effectiveLayout \u662F left \u6216 right \u65F6\uFF1Acols \u9ED8\u8BA4\u662F 2\uFF0Ctablet \u662F 4\uFF0Claptop \u6216\u4EE5\u4E0A\u5C3A\u5BF8\u662F 2\n 'grid-cols-2 tablet:grid-cols-4 laptop:grid-cols-2':\n effectiveLayout === 'left' || effectiveLayout === 'right',\n })}\n >\n {items.map((item: ImageWithTextItem, index: number) => (\n <div\n key={index}\n className={cn('image-with-text__item', {\n 'text-center': textAlign === 'center',\n })}\n >\n <div\n className={cn('image-with-text__item-header flex flex-row items-center gap-[8px]', {\n 'justify-center': textAlign === 'center',\n 'justify-start': textAlign === 'left',\n })}\n >\n <Picture\n source={item.icon?.url}\n alt={item.icon?.alt}\n className=\"image-with-text__item-icon min-md:text-[40px] min-l:text-[40px] min-xl:text-[56px] min-xxl:text-[64px] desktop:h-[44px] lg-desktop:h-[52px] h-[28px] translate-y-[-12%] md:text-[40px]\"\n imgClassName=\"h-full !w-full\"\n />\n <Heading\n size={4}\n as=\"h6\"\n className=\"image-with-text__item-text bg-gradient-to-r from-[#3ad1ff] to-[#008cd6] bg-clip-text text-transparent\"\n >\n {item.text}\n </Heading>\n </div>\n <Text\n size={4}\n as=\"p\"\n html={item.desc}\n className=\"image-with-text__item-desc tablet:text-[14px] laptop:text-[14px] desktop:text-[16px] lg-desktop:text-[18px] mt-[-2px] text-[14px]\"\n />\n </div>\n ))}\n </div>\n )}\n </div>\n\n {/* \u6309\u94AE\uFF08\u653E\u5728\u4E3B\u8981\u5185\u5BB9\u533A\u57DF\u5916\uFF09 */}\n {renderButton()}\n </div>\n )}\n\n {/* \u56FE\u7247/\u89C6\u9891\u533A\u57DF */}\n <div\n ref={mediaWrapperRef}\n className={cn('image-with-text__media-wrapper', {\n 'laptop:w-[60%] w-full shrink-0': effectiveLayout === 'left' || effectiveLayout === 'right',\n // \u4F7F\u7528items\u65F6\u7684\u7279\u6B8A\u6837\u5F0F\uFF08\u7C7B\u4F3C\u539FFeature\u6A21\u5F0F\uFF09\n 'aspect-[716/720] max-h-[560px] max-w-[824px] tablet:aspect-[704/360] laptop:aspect-[824/560] shrink-0':\n hasItems,\n 'laptop:basis-[63%] desktop:basis-[57%]': hasItems && effectiveLayout === 'left',\n // TabWithImage\u6A21\u5F0F\n 'relative w-full shrink md:aspect-[358/360] min-xxl:aspect-[824/560] min-xxl:max-w-[824px] tablet:aspect-[704/360] laptop:aspect-[744/336] laptop:basis-[64%] desktop:aspect-[648/448]':\n isTabMode,\n '!max-w-none !max-h-none aspect-auto': effectiveLayout === 'top' || effectiveLayout === 'bottom',\n })}\n >\n {isTabMode ? (\n // TabWithImage\u6A21\u5F0F - \u652F\u6301\u56FE\u7247\u548C\u89C6\u9891\n isVideo ? (\n renderVideo()\n ) : (\n <AnimatePresence mode=\"wait\">\n <motion.div\n key={datalist[activeIndex].image?.url}\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.3 }}\n className=\"image-with-text__image-motion absolute left-0 top-0 w-full\"\n >\n <Picture\n source={getImageSource()}\n alt={datalist[activeIndex].image?.alt}\n className=\"image-with-text__image rounded-box min-xxl:aspect-[824/560] min-xxl:max-w-[824px] tablet:aspect-[704/360] laptop:aspect-[744/336] desktop:aspect-[648/448] md:aspect-[358/360]\"\n />\n </motion.div>\n </AnimatePresence>\n )\n ) : isVideo ? (\n // \u57FA\u7840\u6A21\u5F0F - \u89C6\u9891\n renderVideo()\n ) : (\n // \u57FA\u7840\u6A21\u5F0F - \u56FE\u7247\n <Picture source={getImageSource()} className={cn('image-with-text__image rounded-box laptop:rounded-box')} />\n )}\n </div>\n </section>\n )\n})\n\nImageWithText.displayName = 'ImageWithText'\n\nexport default withLayout(ImageWithText)\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["jsx", "jsxs", "React", "useImperativeHandle", "useRef", "useState", "useEffect", "Heading", "Picture", "Text", "Link", "cn", "getLocalizedPath", "withLayout", "useExposure", "useIntersectionObserverDelay", "useAiuiContext", "motion", "AnimatePresence", "componentType", "componentName", "ArrowRight", "ImageWithText", "data", "className", "ref", "title", "subtitle", "desc", "descIcon", "image", "padImage", "mobileImage", "theme", "items", "layout", "mediaType", "datalist", "video", "padVideo", "mobVideo", "button", "textAlign", "effectiveLayout", "locale", "boxRef", "desktopVideoRef", "tabletVideoRef", "mobileVideoRef", "mediaWrapperRef", "activeIndex", "setActiveIndex", "tabRefs", "sliderStyle", "setSliderStyle", "loadedDesktopVideoSrc", "setLoadedDesktopVideoSrc", "loadedTabletVideoSrc", "setLoadedTabletVideoSrc", "loadedMobileVideoSrc", "setLoadedMobileVideoSrc", "isTabMode", "isVideo", "current", "offsetLeft", "offsetWidth", "videoIntersected", "setVideoIntersected", "desktopSrc", "tabletSrc", "mobileSrc", "activeTab", "videoElement", "handleTabClick", "index", "e", "renderButton", "hasButton", "hasItems", "getImageSource", "renderVideo", "desktopPoster", "tabletPoster", "mobilePoster", "item", "el", "ImageWithText_default"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import{Fragment as G,jsx as e,jsxs as p}from"react/jsx-runtime";import N,{useRef as B,useMemo as C,useState as M,useEffect as E,useCallback as T}from"react";import{withLayout as O}from"../../shared/Styles.js";import{cn as
|
|
1
|
+
"use client";import{Fragment as G,jsx as e,jsxs as p}from"react/jsx-runtime";import N,{useRef as B,useMemo as C,useState as M,useEffect as E,useCallback as T}from"react";import{withLayout as O}from"../../shared/Styles.js";import{cn as v}from"../../helpers/utils.js";import{useExposure as S}from"../../hooks/useExposure.js";import{useAiuiContext as L}from"../AiuiProvider/index.js";import V from"../Media/index.js";import"swiper/css";import"swiper/css/navigation";import{Heading as $}from"../../components/index.js";import{Swiper as R,SwiperSlide as j}from"swiper/react";import{Navigation as A}from"swiper/modules";const D=({disabled:l})=>p("svg",{width:"40",height:"40",viewBox:"0 0 56 56",fill:"none",xmlns:"http://www.w3.org/2000/svg",className:"text-info-primary lg-desktop:size-[56px] size-[40px]",children:[e("path",{d:"M0 28C0 43.464 12.536 56 28 56C43.464 56 56 43.464 56 28C56 12.536 43.464 0 28 0C12.536 0 0 12.536 0 28Z",fill:"currentColor",fillOpacity:l?"0.2":"0.6"}),e("path",{d:"M31 22L25 28L31 34",stroke:"white",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})]}),H=({disabled:l})=>p("svg",{width:"40",height:"40",viewBox:"0 0 56 56",fill:"none",xmlns:"http://www.w3.org/2000/svg",className:"text-info-primary lg-desktop:size-[56px] size-[40px]",children:[e("path",{d:"M0 28C0 12.536 12.536 0 28 0C43.464 0 56 12.536 56 28C56 43.464 43.464 56 28 56C12.536 56 0 43.464 0 28Z",fill:"currentColor",fillOpacity:l?"0.2":"0.6"}),e("path",{d:"M25 22L31 28L25 34",stroke:"white",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})]}),W="video",Z="media_text_overlay",_=()=>e("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:e("path",{d:"M8 5.14v13.72L19 12 8 5.14z",fill:"white"})}),F=()=>p("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[e("rect",{x:"6",y:"5",width:"4",height:"14",rx:"1",fill:"white"}),e("rect",{x:"14",y:"5",width:"4",height:"14",rx:"1",fill:"white"})]}),q=({data:l,configuration:r,jIndex:w,classNames:d={}})=>{const h=B(null),c=B(null),{content:i,media:s}=l,x=r?.theme||"light",b=r?.size||"lg",k=r?.onlyOne||!1,m=r?.isAutoPlay??!0,[f,a]=M(!1);S(h,{componentType:W,componentName:Z,position:w,componentTitle:i,navigation:r?.activeTab});const n=C(()=>[s.lgDesktop,s.desktop,s.laptop,s.pad,s.mobile].some(o=>o?.mimeType==="video/mp4"),[s]),P=T(()=>{const o=c.current;o&&(o.paused?(o.play(),a(!0)):(o.pause(),a(!1)))},[]);return E(()=>{const o=c.current;if(!o||!n||!m)return;const u=new IntersectionObserver(t=>{t.forEach(g=>{g.isIntersecting?o.play().catch(I=>{console.warn("Video autoplay failed:",I)}):o.pause()})},{threshold:.5});return u.observe(o),()=>{u.disconnect()}},[n,m]),p("div",{className:v("item-wrapper rounded-box group relative box-border w-full overflow-hidden",k?{lg:"aspect-[390/400] tablet:aspect-[768/400] laptop:aspect-[1024/384] desktop:aspect-[1440/512] lg-desktop:aspect-[1920/640]",sm:"h-[240px] laptop:h-[288px] desktop:h-[384px] lg-desktop:h-[480px]"}[b]:"tablet:aspect-[768/400] laptop:aspect-[1024/384] desktop:aspect-[1440/512] lg-desktop:aspect-[1920/640] aspect-[390/400]",{"aiui-dark":x==="dark"}),ref:h,children:[e("div",{className:"absolute inset-0",children:e(V,{pcImage:s.lgDesktop||s.desktop,desktopImage:s.desktop,laptopImage:s.laptop,padImage:s.pad,mobileImage:s.mobile,videoClassName:"absolute inset-0 size-full object-cover",imgClassName:"absolute inset-0 size-full object-cover",videoRef:c,muted:!0,loop:!0,playsInline:!0,autoPlay:m,onVideoPlay:()=>a(!0),onVideoPause:()=>a(!1),onVideoEnded:()=>a(!1)})}),n&&e("div",{className:"desktop:p-8 absolute bottom-0 right-0 z-30 p-6",children:e("button",{type:"button","aria-label":f?"Pause video":"Play video",onClick:P,className:v("flex size-14 shrink-0 items-center justify-center rounded-full bg-white/20 transition-opacity hover:opacity-80",d.playButton),children:f?e(F,{}):e(_,{})})}),e("div",{className:v("text-info-primary laptop:px-6 laptop:pb-6 laptop:pr-24 desktop:px-8 desktop:pb-8 desktop:pr-28 absolute inset-x-0 bottom-0 z-20 flex flex-col gap-4 px-4 pb-4 pr-20",d.overlay),children:e("div",{className:v("flex items-end justify-between gap-4",d.content),children:e($,{size:2,html:i,className:"line-clamp-3"})})})]})},z=N.forwardRef((l,r)=>{const{data:w,className:d,classNames:h={},...c}=l,{items:i=[],theme:s="dark",size:x="sm",isShowPagination:b=!0,isAutoPlay:k=!0}=w,{locale:m="us"}=L(),f=B(null),[a,n]=M({isBeginning:!0,isEnd:!1}),P=C(()=>{const t=i?.length||0;return{0:{spaceBetween:12,slidesPerView:t>1?1.2:1},768:{spaceBetween:12,slidesPerView:t>2?2.3:t>1?2:1},1024:{spaceBetween:16,slidesPerView:Math.min(t,3)},1440:{spaceBetween:16,slidesPerView:Math.min(t,4)},1920:{spaceBetween:16,slidesPerView:Math.min(t,4)}}},[i?.length]),y=N.useId().replace(/:/g,""),o=`${y}-custom-swiper-button-next`,u=`${y}-custom-swiper-button-prev`;return e("section",{"data-ui-component-id":"MediaTextOverlay",ref:r,...c,className:v("mediaTextOverlayBlock text-info-primary",d,h.root),children:i&&i.length>0?p("div",{className:"group relative",children:[e(R,{className:"!overflow-visible",modules:[A],navigation:{nextEl:`.${o}`,prevEl:`.${u}`},onSwiper:t=>{f.current=t,n({isBeginning:t.isBeginning,isEnd:t.isEnd})},onReachEnd:()=>{n(t=>({...t,isEnd:!0}))},onReachBeginning:()=>{n(t=>({...t,isBeginning:!0}))},onFromEdge:()=>{n({isBeginning:!1,isEnd:!1})},breakpoints:P,children:i.map((t,g)=>e(j,{className:"!flex !h-[unset]",children:e(q,{data:t,configuration:{theme:s,size:x,num:i.length,locale:m,onlyOne:i.length===1,index:g,isAutoPlay:k},jIndex:g})},`${y}-SwiperSlide-${g}`))}),b&&i.length>1&&p(G,{children:[e("button",{className:`${u} absolute left-4 top-1/2 z-10 -translate-y-1/2 transition-opacity ${a.isBeginning?"pointer-events-none opacity-0":"opacity-100 hover:opacity-80"}`,"aria-label":"Previous slide",children:e(D,{disabled:a.isBeginning})}),e("button",{className:`${o} absolute right-4 top-1/2 z-10 -translate-y-1/2 transition-opacity ${a.isEnd?"pointer-events-none opacity-0":"opacity-100 hover:opacity-80"}`,"aria-label":"Next slide",children:e(H,{disabled:a.isEnd})})]})]}):null})});z.displayName="MediaTextOverlay";var ae=O(z);export{ae as default};
|
|
2
2
|
//# sourceMappingURL=MediaTextOverlay.js.map
|