@anker-in/headless-ui 1.1.65 → 1.1.66
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/HeroBanner/HeroBanner.js +1 -1
- package/dist/cjs/biz-components/HeroBanner/HeroBanner.js.map +3 -3
- package/dist/cjs/biz-components/HeroBanner/types.d.ts +2 -0
- package/dist/cjs/biz-components/HeroBanner/types.js.map +1 -1
- package/dist/cjs/biz-components/Title/index.js +1 -1
- package/dist/cjs/biz-components/Title/index.js.map +1 -1
- package/dist/cjs/components/Countdown.d.ts +1 -0
- package/dist/cjs/components/Countdown.js +1 -1
- package/dist/cjs/components/Countdown.js.map +3 -3
- package/dist/esm/biz-components/HeroBanner/HeroBanner.js +1 -1
- package/dist/esm/biz-components/HeroBanner/HeroBanner.js.map +3 -3
- package/dist/esm/biz-components/HeroBanner/types.d.ts +2 -0
- package/dist/esm/biz-components/Title/index.js +1 -1
- package/dist/esm/biz-components/Title/index.js.map +1 -1
- package/dist/esm/components/Countdown.d.ts +1 -0
- package/dist/esm/components/Countdown.js +1 -1
- package/dist/esm/components/Countdown.js.map +3 -3
- package/package.json +1 -1
- package/style.css +3 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";"use client";var
|
|
1
|
+
"use strict";"use client";var me=Object.create;var B=Object.defineProperty;var de=Object.getOwnPropertyDescriptor;var ge=Object.getOwnPropertyNames;var fe=Object.getPrototypeOf,be=Object.prototype.hasOwnProperty;var xe=(t,a)=>{for(var l in a)B(t,l,{get:a[l],enumerable:!0})},J=(t,a,l,N)=>{if(a&&typeof a=="object"||typeof a=="function")for(let g of ge(a))!be.call(t,g)&&g!==l&&B(t,g,{get:()=>a[g],enumerable:!(N=de(a,g))||N.enumerable});return t};var L=(t,a,l)=>(l=t!=null?me(fe(t)):{},J(a||!t||!t.__esModule?B(l,"default",{value:t,enumerable:!0}):l,t)),he=t=>J(B({},"__esModule",{value:!0}),t);var Be={};xe(Be,{default:()=>$e});module.exports=he(Be);var e=require("react/jsx-runtime"),r=L(require("react")),v=L(require("gsap")),w=require("gsap/dist/ScrollTrigger"),M=require("react-responsive"),O=require("react-intersection-observer"),W=L(require("../../helpers/ScrollLoadVideo.js")),o=require("../../components/index.js"),c=require("../../helpers/index.js"),k=require("class-variance-authority"),X=require("../../shared/Styles.js"),Y=require("../../hooks/useExposure.js"),V=require("../../shared/trackUrlRef.js"),ee=require("../../components/button.js"),te=require("../VideoModal/index.js");const m="image",d="hero_banner",ye=(0,k.cva)("hero-banner-content laptop:top-1/2 laptop:-translate-y-1/2 lg-desktop:gap-[32px] absolute top-24 z-10 flex w-full flex-col gap-[24px]",{variants:{align:{left:"tablet:px-[32px] laptop:px-[64px] lg-desktop:px-[calc(50%-832px)] left-0 px-[16px]",center:"left-1/2 -translate-x-1/2 items-center text-center"}},defaultVariants:{align:"left"}}),ve=(0,k.cva)("hero-banner-wrap-text lg-desktop:max-w-[824px] desktop:max-w-[648px] laptop:max-w-[440px] tablet:max-w-[704px] max-w-[358px]",{variants:{align:{left:"laptop:text-left",center:"text-center"}},defaultVariants:{align:"left"}}),we=(0,k.cva)("hero-banner-button-group lg-desktop:gap-3 flex items-center gap-2",{variants:{align:{left:"laptop:justify-start",center:"justify-center"}},defaultVariants:{align:"left"}}),ke=(0,k.cva)("hero-banner-icon-group flex items-center gap-2",{variants:{align:{left:"justify-start",center:"justify-center"}},defaultVariants:{align:"left"}}),Ne=({size:t="base"})=>{const{width:a,height:l}=ee.sizeMap[t];return(0,e.jsx)("svg",{width:a,height:l,viewBox:"0 0 20 20",fill:"currentcolor",xmlns:"http://www.w3.org/2000/svg",children:(0,e.jsx)("path",{d:"M13.9599 9.30662C14.4547 9.63647 14.4547 10.3635 13.9599 10.6934L6.29558 15.8029C5.74179 16.1721 5 15.7751 5 15.1096V4.89042C5 4.22484 5.74179 3.82785 6.29558 4.19705L13.9599 9.30662Z",fill:"currentcolor"})})},K=r.default.forwardRef(({data:t,className:a,classNames:l={},onSecondaryClick:N,onPrimaryClick:g},ae)=>{const{label:D,title:i,subtitle:p,endDate:E,endDate_tz:re,dateFormat:oe,pcImage:z,padImage:j,mobileImage:$,pcVideo:le,padVideo:se,mobileVideo:U,isShowVideo:ne,isVideoLoop:ie=!0,primaryButton:u,secondaryButton:s,theme:pe="light",size:H="default",titleSize:T,caption:I=[],blockLink:_,iconArray:ce,align:b="center"}=t,G=(0,M.useMediaQuery)({query:"(max-width: 768px)"}),F=(0,M.useMediaQuery)({query:"(max-width: 1024px)"}),[q,A]=(0,r.useState)(!1),{ref:ue,inView:Q}=(0,O.useInView)(),C=(0,r.useRef)(null),P=(0,r.useRef)(null),S=(0,r.useRef)(null),x=(0,r.useRef)(null),f=(0,r.useRef)(null);return(0,Y.useExposure)(f,{componentType:m,componentName:d,componentTitle:i,componentDescription:p}),(0,r.useImperativeHandle)(ae,()=>f.current),(0,r.useEffect)(()=>{v.default.registerPlugin(w.ScrollTrigger);function n(){if(!x.current)return;const R=f.current?.clientHeight||100;window.innerHeight<=R?C.current=w.ScrollTrigger.create({trigger:f.current,start:"top bottom",end:"bottom top",scrub:!0,onUpdate:h=>{const y=h.progress*40-20;v.default.set(x.current,{yPercent:y})}}):(S.current=w.ScrollTrigger.create({trigger:f.current,start:"top bottom",end:"bottom bottom",scrub:!0,onUpdate:h=>{const y=h.progress*20-20;v.default.set(x.current,{yPercent:y})}}),P.current=w.ScrollTrigger.create({trigger:f.current,start:"top top",end:"bottom top",scrub:!0,onUpdate:h=>{const y=h.progress*20;v.default.set(x.current,{yPercent:y})}}))}return Q&&n(),()=>{C.current&&C.current.kill(),S.current&&S.current.kill(),P.current&&P.current.kill()}},[Q]),(0,e.jsx)("div",{ref:ue,"data-ui-component-id":"HeroBanner",children:(0,e.jsxs)("div",{ref:f,className:(0,c.cn)(pe==="dark"?"aiui-dark":"","text-info-primary relative w-full overflow-hidden",{"lg-desktop:aspect-[1920/930] desktop:aspect-[1440/700] laptop:aspect-[1024/520] tablet:aspect-[768/660] aspect-[390/660]":H==="default","lg-desktop:aspect-[1920/800] desktop:aspect-[1440/640] laptop:aspect-[1024/480] tablet:aspect-[768/560] aspect-[390/560]":H==="sm"},a),children:[_&&(0,e.jsx)("a",{className:"absolute inset-0 z-10",href:(0,V.trackUrlRef)(_,`${m}_${d}`),"data-headless-type-name":`${m}#${d}`,"data-headless-title-desc-button":`${i}#${p}`,tabIndex:-1,"aria-hidden":"true","aria-label":i}),(0,e.jsx)("div",{ref:x,className:(0,c.cn)("absolute left-0 top-0 size-full"),children:ne?(0,e.jsx)(W.default,{poster:G?$?.url:F?j?.url||$?.url:z?.url,src:G?U?.url:F?se?.url||U?.url:le?.url,className:"laptop:w-full h-full",videoClassName:"h-full object-cover",muted:!0,loop:ie,playsInline:!0}):(0,e.jsx)(o.Picture,{className:"laptop:w-full h-full",imgClassName:"h-full object-cover",loading:"eager",fetchPriority:"high",alt:z?.alt||"",source:`${z?.url||""} , ${j?.url??($?.url||"")} 1024, ${$?.url||""} 767`})}),(0,e.jsxs)("div",{className:ye({align:b}),children:[(0,e.jsxs)("div",{className:ve({align:b}),children:[D&&(0,e.jsx)(o.Text,{size:2,as:"p",className:(0,c.cn)("hero-banner-label font-heading lg-desktop:text-[18px] desktop:text-base text-sm"),html:D}),i&&(0,e.jsx)(o.Heading,{as:T==="4"?"h1":"h2",html:i,className:(0,c.cn)("hero-banner-title",l.title),size:T?Number(T||"5"):H==="sm"?4:5}),p&&(0,e.jsx)(o.Text,{as:"p",size:2,className:(0,c.cn)("hero-banner-subtitle font-heading lg-desktop:text-[18px] desktop:text-base laptop:mt-2 lg-desktop:mt-4 mt-1 text-sm"),html:p}),E&&(0,e.jsx)("div",{className:"mt-3",children:(0,e.jsx)(o.Countdown,{endDate:E,endDate_tz:re,dateFormat:oe,variant:"spacious",align:b})})]}),(0,e.jsxs)("div",{className:we({align:b}),children:[s?.isShowPlayVideoButton&&s?.playVideoButtonText?(0,e.jsxs)(o.Button,{onClick:()=>A(!0),size:"lg",variant:"secondary",className:"hero-banner-play-video-button","data-headless-type-name":`${m}#${d}`,"data-headless-title-desc-button":`${i}#${p}#${s?.playVideoButtonText}`,children:[s?.playVideoButtonText," ",(0,e.jsx)(Ne,{size:"lg"})]}):s?.text?(0,e.jsxs)(o.Button,{"aria-label":i??p,size:"lg",variant:"secondary",className:"hero-banner-secondary-button",as:s?.isCustomSecondaryButton?"button":"a",href:(0,V.trackUrlRef)(s?.link,`${m}_${d}`),onClick:n=>s?.isCustomSecondaryButton&&N?.(t,n,s?.customSecondaryEventId),"data-headless-type-name":`${m}#${d}`,"data-headless-title-desc-button":`${i}#${p}#${s?.text}`,children:[s?.text,(0,e.jsx)("span",{className:"sr-only",children:i??p})]}):null,u&&u.text&&(0,e.jsx)(o.Button,{"aria-label":i??p,size:"lg",variant:"primary",className:"hero-banner-primary-button",as:u?.isCustomPrimaryButton?"button":"a",href:(0,V.trackUrlRef)(u.link,`${m}_${d}`),onClick:n=>u?.isCustomPrimaryButton&&g?.(t,n,u?.customPrimaryEventId),"data-headless-type-name":`${m}#${d}`,"data-headless-title-desc-button":`${i}#${p}#${u?.text}`,children:u.text})]}),(0,e.jsx)("div",{className:ke({align:b}),children:ce?.map(n=>(0,e.jsx)("div",{className:"h-12",children:(0,e.jsx)(o.Picture,{className:"laptop:w-full h-full",imgClassName:"h-full object-cover",loading:"eager",alt:n?.pcImage?.alt||"",source:n?.pcImage?.url})},n?.pcImage?.url||n?.pcImage?.alt))})]}),I.length>0&&(0,e.jsx)("div",{className:(0,c.cn)("hero-banner-caption-group laptop:gap-3 tablet:px-[32px] laptop:px-[64px] lg-desktop:px-[calc(50%-832px)] desktop:pb-[24px] absolute bottom-0 z-10 flex items-stretch gap-2 px-[16px] pb-[16px]",l.captionGroup),children:I.map((n,R)=>(0,e.jsxs)(r.default.Fragment,{children:[(0,e.jsx)(o.Text,{size:2,className:(0,c.cn)("hero-banner-product-text tablet:w-[108px] loptop:w-[150px] desktop:w-[156px] lg-desktop:w-[180px] laptop:text-[14px] flex-1 text-[12px]"),html:n.title}),R<I.length-1&&(0,e.jsx)("div",{className:(0,c.cn)("bg-info-primary w-px")})]},n.title))}),q&&(0,e.jsx)(te.VideoModal,{visible:q,videoUrl:s?.videoUrl?.url,youTubeId:s?.youtubeId,onCloseModal:()=>A(!1)})]})})});K.displayName="HeroBanner";var $e=(0,X.withLayout)(K);
|
|
2
2
|
//# sourceMappingURL=HeroBanner.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/biz-components/HeroBanner/HeroBanner.tsx"],
|
|
4
|
-
"sourcesContent": ["'use client'\nimport React, { useImperativeHandle, useRef, useState, useEffect } from 'react'\nimport gsap from 'gsap'\nimport { ScrollTrigger } from 'gsap/dist/ScrollTrigger'\nimport type { HeroBannerProps } from './types.js'\nimport { useMediaQuery } from 'react-responsive'\nimport { useInView } from 'react-intersection-observer'\nimport ScrollLoadVideo from '../../helpers/ScrollLoadVideo.js'\nimport { Button, Heading, Picture, Text, Countdown } from '../../components/index.js'\nimport { cn } from '../../helpers/index.js'\nimport { withLayout } from '../../shared/Styles.js'\nimport { useExposure } from '../../hooks/useExposure.js'\nimport { trackUrlRef } from '../../shared/trackUrlRef.js'\nimport { sizeMap } from '../../components/button.js'\nimport { VideoModal } from '../VideoModal/index.js'\n\nconst componentType = 'image'\nconst componentName = 'hero_banner'\n\nexport type HeroBannerSemanticName =\n | 'root'\n | 'title'\n | 'subtitle'\n | 'buttonGroup'\n | 'primaryButton'\n | 'secondaryButton'\n | 'captionGroup'\n\nconst PlayButtonAppendIcon = ({ size = 'base' }: { size: 'base' | 'lg' | 'sm' }) => {\n const { width, height } = sizeMap[size]\n return (\n <svg width={width} height={height} viewBox=\"0 0 20 20\" fill=\"currentcolor\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M13.9599 9.30662C14.4547 9.63647 14.4547 10.3635 13.9599 10.6934L6.29558 15.8029C5.74179 16.1721 5 15.7751 5 15.1096V4.89042C5 4.22484 5.74179 3.82785 6.29558 4.19705L13.9599 9.30662Z\"\n fill=\"currentcolor\"\n />\n </svg>\n )\n}\n\nconst HeroBanner = React.forwardRef<\n HTMLDivElement,\n HeroBannerProps & {\n classNames?: Partial<Record<HeroBannerSemanticName, string>>\n }\n>(({ data, className, classNames = {}, onSecondaryClick, onPrimaryClick }, ref) => {\n const {\n label,\n title,\n subtitle,\n endDate,\n endDate_tz,\n dateFormat,\n pcImage,\n padImage,\n mobileImage,\n pcVideo,\n padVideo,\n mobileVideo,\n isShowVideo,\n isVideoLoop = true,\n primaryButton,\n secondaryButton,\n theme = 'light',\n size = 'default',\n titleSize,\n caption = [],\n blockLink,\n iconArray,\n } = data\n\n const isMobile = useMediaQuery({ query: '(max-width: 768px)' })\n const isPad = useMediaQuery({ query: '(max-width: 1024px)' })\n const [visible, setVisible] = useState<boolean>(false)\n const { ref: inViewRef, inView } = useInView()\n const scrollTriggerRef = useRef<ScrollTrigger | null>(null)\n const bgTriggerRef = useRef<ScrollTrigger | null>(null)\n const boxTriggerRef = useRef<ScrollTrigger | null>(null)\n\n const bgRef = useRef<HTMLImageElement>(null)\n const boxRef = useRef<HTMLDivElement>(null)\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 useEffect(() => {\n gsap.registerPlugin(ScrollTrigger)\n function gsapResize() {\n if (!bgRef.current) return\n const clientHeight = boxRef.current?.clientHeight || 100\n const screenHeight = window.innerHeight\n\n if (screenHeight <= clientHeight) {\n scrollTriggerRef.current = ScrollTrigger.create({\n trigger: boxRef.current,\n start: 'top bottom',\n end: 'bottom top',\n scrub: true,\n onUpdate: (self: any) => {\n const base = 40\n const value = self.progress * base - base / 2\n gsap.set(bgRef.current, { yPercent: value })\n },\n })\n } else {\n boxTriggerRef.current = ScrollTrigger.create({\n trigger: boxRef.current,\n start: 'top bottom',\n end: 'bottom bottom',\n scrub: true,\n onUpdate: (self: any) => {\n const base = 20\n const value = self.progress * base - base\n gsap.set(bgRef.current, { yPercent: value })\n },\n })\n bgTriggerRef.current = ScrollTrigger.create({\n trigger: boxRef.current,\n start: 'top top',\n end: 'bottom top',\n scrub: true,\n onUpdate: (self: any) => {\n const base = 20\n const value = self.progress * base\n gsap.set(bgRef.current, { yPercent: value })\n },\n })\n }\n }\n if (inView) gsapResize()\n return () => {\n // ScrollTrigger.getAll().forEach((t: any) => t.kill())\n scrollTriggerRef.current && scrollTriggerRef.current.kill()\n boxTriggerRef.current && boxTriggerRef.current.kill()\n bgTriggerRef.current && bgTriggerRef.current.kill()\n }\n }, [inView])\n\n return (\n <div ref={inViewRef} data-ui-component-id=\"HeroBanner\">\n <div\n ref={boxRef}\n className={cn(\n theme === 'dark' ? 'aiui-dark' : '',\n 'text-info-primary relative w-full overflow-hidden',\n {\n 'lg-desktop:aspect-[1920/930] desktop:aspect-[1440/700] laptop:aspect-[1024/520] tablet:aspect-[768/660] aspect-[390/660]':\n size === 'default',\n 'lg-desktop:aspect-[1920/800] desktop:aspect-[1440/640] laptop:aspect-[1024/480] tablet:aspect-[768/560] aspect-[390/560]':\n size === 'sm',\n },\n className\n )}\n >\n {blockLink && (\n <a\n className=\"absolute inset-0 z-10\"\n href={trackUrlRef(blockLink, `${componentType}_${componentName}`)}\n data-headless-type-name={`${componentType}#${componentName}`}\n data-headless-title-desc-button={`${title}#${subtitle}`}\n tabIndex={-1}\n aria-hidden=\"true\"\n aria-label={title}\n ></a>\n )}\n <div ref={bgRef} className={cn('absolute left-0 top-0 size-full')}>\n {isShowVideo ? (\n <ScrollLoadVideo\n poster={isMobile ? mobileImage?.url : isPad ? padImage?.url || mobileImage?.url : pcImage?.url}\n src={\n isMobile\n ? (mobileVideo?.url as string)\n : isPad\n ? (padVideo?.url as string) || (mobileVideo?.url as string)\n : (pcVideo?.url as string)\n }\n className=\"laptop:w-full h-full\"\n videoClassName=\"h-full object-cover\"\n muted\n loop={isVideoLoop}\n playsInline\n />\n ) : (\n <Picture\n className=\"laptop:w-full h-full\"\n imgClassName=\"h-full object-cover\"\n loading=\"eager\"\n fetchPriority=\"high\"\n alt={pcImage?.alt || ''}\n source={`${pcImage?.url || ''} , ${padImage?.url ?? (mobileImage?.url || '')} 1024, ${mobileImage?.url || ''} 767`}\n />\n )}\n </div>\n\n {/* \u5185\u5BB9\u533A\u57DF */}\n <div className=\"hero-banner-content laptop:top-1/2 laptop:-translate-y-1/2 tablet:px-[32px] laptop:px-[64px] lg-desktop:px-[calc(50%-832px)] lg-desktop:gap-[32px] absolute top-24 z-10 flex flex-col gap-[24px] px-[16px]\">\n <div className=\"laptop:text-left hero-banner-wrap-text lg-desktop:max-w-[824px] desktop:max-w-[648px] laptop:max-w-[440px] tablet:max-w-[704px] max-w-[358px]\">\n {label && (\n <Text\n size={2}\n as=\"p\"\n className={cn('hero-banner-label font-heading lg-desktop:text-[18px] desktop:text-base text-sm')}\n html={label}\n />\n )}\n {title && (\n <Heading\n as={titleSize === '4' ? 'h1' : 'h2'}\n html={title}\n className={cn('hero-banner-title', classNames.title)}\n size={titleSize ? (Number(titleSize || '5') as any) : size === 'sm' ? 4 : 5}\n />\n )}\n {subtitle && (\n <Text\n as=\"p\"\n size={2}\n className={cn(\n 'hero-banner-subtitle font-heading lg-desktop:text-[18px] desktop:text-base laptop:mt-2 lg-desktop:mt-4 mt-1 text-sm'\n )}\n html={subtitle}\n />\n )}\n {endDate && (\n <div className=\"mt-3\">\n <Countdown endDate={endDate} endDate_tz={endDate_tz} dateFormat={dateFormat} variant=\"spacious\" />\n </div>\n )}\n </div>\n {/* \u6309\u94AE\u7EC4 */}\n <div className=\"hero-banner-button-group laptop:justify-start lg-desktop:gap-3 flex items-center gap-2\">\n {secondaryButton?.isShowPlayVideoButton && secondaryButton?.playVideoButtonText ? (\n <Button\n onClick={() => setVisible(true)}\n size=\"lg\"\n variant=\"secondary\"\n className=\"hero-banner-play-video-button\"\n data-headless-type-name={`${componentType}#${componentName}`}\n data-headless-title-desc-button={`${title}#${subtitle}#${secondaryButton?.playVideoButtonText}`}\n >\n {secondaryButton?.playVideoButtonText} <PlayButtonAppendIcon size=\"lg\" />\n </Button>\n ) : secondaryButton?.text ? (\n <Button\n aria-label={title ?? subtitle}\n size=\"lg\"\n variant=\"secondary\"\n className=\"hero-banner-secondary-button\"\n as={secondaryButton?.isCustomSecondaryButton ? 'button' : 'a'}\n href={trackUrlRef(secondaryButton?.link, `${componentType}_${componentName}`)}\n onClick={e =>\n secondaryButton?.isCustomSecondaryButton &&\n onSecondaryClick?.(data, e, secondaryButton?.customSecondaryEventId)\n }\n data-headless-type-name={`${componentType}#${componentName}`}\n data-headless-title-desc-button={`${title}#${subtitle}#${secondaryButton?.text}`}\n >\n {secondaryButton?.text}\n <span className=\"sr-only\">{title ?? subtitle}</span>\n </Button>\n ) : null}\n {primaryButton && primaryButton.text && (\n <Button\n aria-label={title ?? subtitle}\n size=\"lg\"\n variant=\"primary\"\n className=\"hero-banner-primary-button\"\n as={primaryButton?.isCustomPrimaryButton ? 'button' : 'a'}\n href={trackUrlRef(primaryButton.link, `${componentType}_${componentName}`)}\n onClick={e =>\n primaryButton?.isCustomPrimaryButton && onPrimaryClick?.(data, e, primaryButton?.customPrimaryEventId)\n }\n data-headless-type-name={`${componentType}#${componentName}`}\n data-headless-title-desc-button={`${title}#${subtitle}#${primaryButton?.text}`}\n >\n {primaryButton.text}\n </Button>\n )}\n </div>\n <div className=\"hero-banner-icon-group flex items-center gap-2\">\n {iconArray?.map(icon => (\n <div key={icon?.pcImage?.url || icon?.pcImage?.alt} className=\"h-12\">\n <Picture\n className=\"laptop:w-full h-full\"\n imgClassName=\"h-full object-cover\"\n loading=\"eager\"\n alt={icon?.pcImage?.alt || ''}\n source={icon?.pcImage?.url}\n />\n </div>\n ))}\n </div>\n </div>\n\n {/* \u5E95\u90E8\u4EA7\u54C1\u5217\u8868 */}\n {caption.length > 0 && (\n <div\n className={cn(\n 'hero-banner-caption-group laptop:gap-3 tablet:px-[32px] laptop:px-[64px] lg-desktop:px-[calc(50%-832px)] desktop:pb-[24px] absolute bottom-0 z-10 flex items-stretch gap-2 px-[16px] pb-[16px]',\n classNames.captionGroup\n )}\n >\n {caption.map((c, index) => (\n <React.Fragment key={c.title}>\n <Text\n size={2}\n className={cn(\n 'hero-banner-product-text tablet:w-[108px] loptop:w-[150px] desktop:w-[156px] lg-desktop:w-[180px] laptop:text-[14px] flex-1 text-[12px]'\n )}\n html={c.title}\n />\n {index < caption.length - 1 && <div className={cn('bg-info-primary w-px')} />}\n </React.Fragment>\n ))}\n </div>\n )}\n\n {/* \u89C6\u9891\u5F39\u7A97 */}\n {visible && (\n <VideoModal\n visible={visible}\n videoUrl={secondaryButton?.videoUrl?.url}\n youTubeId={secondaryButton?.youtubeId}\n onCloseModal={() => setVisible(false)}\n />\n )}\n </div>\n </div>\n )\n})\n\nHeroBanner.displayName = 'HeroBanner'\n\nexport default withLayout(HeroBanner)\n"],
|
|
5
|
-
"mappings": "mlBAAA,IAAAA,GAAA,GAAAC,GAAAD,GAAA,aAAAE,KAAA,eAAAC,GAAAH,
|
|
6
|
-
"names": ["HeroBanner_exports", "__export", "HeroBanner_default", "__toCommonJS", "import_jsx_runtime", "import_react", "import_gsap", "import_ScrollTrigger", "import_react_responsive", "import_react_intersection_observer", "import_ScrollLoadVideo", "import_components", "import_helpers", "import_Styles", "import_useExposure", "import_trackUrlRef", "import_button", "import_VideoModal", "componentType", "componentName", "PlayButtonAppendIcon", "size", "width", "height", "HeroBanner", "React", "data", "className", "classNames", "onSecondaryClick", "onPrimaryClick", "ref", "label", "title", "subtitle", "endDate", "endDate_tz", "dateFormat", "pcImage", "padImage", "mobileImage", "pcVideo", "padVideo", "mobileVideo", "isShowVideo", "isVideoLoop", "primaryButton", "secondaryButton", "theme", "titleSize", "caption", "blockLink", "iconArray", "isMobile", "isPad", "visible", "setVisible", "inViewRef", "inView", "scrollTriggerRef", "bgTriggerRef", "boxTriggerRef", "bgRef", "boxRef", "gsap", "gsapResize", "clientHeight", "self", "value", "ScrollLoadVideo", "e", "icon", "c", "index"]
|
|
4
|
+
"sourcesContent": ["'use client'\nimport React, { useImperativeHandle, useRef, useState, useEffect } from 'react'\nimport gsap from 'gsap'\nimport { ScrollTrigger } from 'gsap/dist/ScrollTrigger'\nimport type { HeroBannerProps } from './types.js'\nimport { useMediaQuery } from 'react-responsive'\nimport { useInView } from 'react-intersection-observer'\nimport ScrollLoadVideo from '../../helpers/ScrollLoadVideo.js'\nimport { Button, Heading, Picture, Text, Countdown } from '../../components/index.js'\nimport { cn } from '../../helpers/index.js'\nimport { cva } from 'class-variance-authority'\nimport { withLayout } from '../../shared/Styles.js'\nimport { useExposure } from '../../hooks/useExposure.js'\nimport { trackUrlRef } from '../../shared/trackUrlRef.js'\nimport { sizeMap } from '../../components/button.js'\nimport { VideoModal } from '../VideoModal/index.js'\n\nconst componentType = 'image'\nconst componentName = 'hero_banner'\n\n// CVA variants for align\nconst contentVariants = cva(\n 'hero-banner-content laptop:top-1/2 laptop:-translate-y-1/2 lg-desktop:gap-[32px] absolute top-24 z-10 flex w-full flex-col gap-[24px]',\n {\n variants: {\n align: {\n left: 'tablet:px-[32px] laptop:px-[64px] lg-desktop:px-[calc(50%-832px)] left-0 px-[16px]',\n center: 'left-1/2 -translate-x-1/2 items-center text-center',\n },\n },\n defaultVariants: {\n align: 'left',\n },\n }\n)\n\nconst textVariants = cva(\n 'hero-banner-wrap-text lg-desktop:max-w-[824px] desktop:max-w-[648px] laptop:max-w-[440px] tablet:max-w-[704px] max-w-[358px]',\n {\n variants: {\n align: {\n left: 'laptop:text-left',\n center: 'text-center',\n },\n },\n defaultVariants: {\n align: 'left',\n },\n }\n)\n\nconst buttonGroupVariants = cva('hero-banner-button-group lg-desktop:gap-3 flex items-center gap-2', {\n variants: {\n align: {\n left: 'laptop:justify-start',\n center: 'justify-center',\n },\n },\n defaultVariants: {\n align: 'left',\n },\n})\n\nconst iconGroupVariants = cva('hero-banner-icon-group flex items-center gap-2', {\n variants: {\n align: {\n left: 'justify-start',\n center: 'justify-center',\n },\n },\n defaultVariants: {\n align: 'left',\n },\n})\n\nexport type HeroBannerSemanticName =\n | 'root'\n | 'title'\n | 'subtitle'\n | 'buttonGroup'\n | 'primaryButton'\n | 'secondaryButton'\n | 'captionGroup'\n\nconst PlayButtonAppendIcon = ({ size = 'base' }: { size: 'base' | 'lg' | 'sm' }) => {\n const { width, height } = sizeMap[size]\n return (\n <svg width={width} height={height} viewBox=\"0 0 20 20\" fill=\"currentcolor\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M13.9599 9.30662C14.4547 9.63647 14.4547 10.3635 13.9599 10.6934L6.29558 15.8029C5.74179 16.1721 5 15.7751 5 15.1096V4.89042C5 4.22484 5.74179 3.82785 6.29558 4.19705L13.9599 9.30662Z\"\n fill=\"currentcolor\"\n />\n </svg>\n )\n}\n\nconst HeroBanner = React.forwardRef<\n HTMLDivElement,\n HeroBannerProps & {\n classNames?: Partial<Record<HeroBannerSemanticName, string>>\n }\n>(({ data, className, classNames = {}, onSecondaryClick, onPrimaryClick }, ref) => {\n const {\n label,\n title,\n subtitle,\n endDate,\n endDate_tz,\n dateFormat,\n pcImage,\n padImage,\n mobileImage,\n pcVideo,\n padVideo,\n mobileVideo,\n isShowVideo,\n isVideoLoop = true,\n primaryButton,\n secondaryButton,\n theme = 'light',\n size = 'default',\n titleSize,\n caption = [],\n blockLink,\n iconArray,\n align = 'center',\n } = data\n\n const isMobile = useMediaQuery({ query: '(max-width: 768px)' })\n const isPad = useMediaQuery({ query: '(max-width: 1024px)' })\n const [visible, setVisible] = useState<boolean>(false)\n const { ref: inViewRef, inView } = useInView()\n const scrollTriggerRef = useRef<ScrollTrigger | null>(null)\n const bgTriggerRef = useRef<ScrollTrigger | null>(null)\n const boxTriggerRef = useRef<ScrollTrigger | null>(null)\n\n const bgRef = useRef<HTMLImageElement>(null)\n const boxRef = useRef<HTMLDivElement>(null)\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 useEffect(() => {\n gsap.registerPlugin(ScrollTrigger)\n function gsapResize() {\n if (!bgRef.current) return\n const clientHeight = boxRef.current?.clientHeight || 100\n const screenHeight = window.innerHeight\n\n if (screenHeight <= clientHeight) {\n scrollTriggerRef.current = ScrollTrigger.create({\n trigger: boxRef.current,\n start: 'top bottom',\n end: 'bottom top',\n scrub: true,\n onUpdate: (self: any) => {\n const base = 40\n const value = self.progress * base - base / 2\n gsap.set(bgRef.current, { yPercent: value })\n },\n })\n } else {\n boxTriggerRef.current = ScrollTrigger.create({\n trigger: boxRef.current,\n start: 'top bottom',\n end: 'bottom bottom',\n scrub: true,\n onUpdate: (self: any) => {\n const base = 20\n const value = self.progress * base - base\n gsap.set(bgRef.current, { yPercent: value })\n },\n })\n bgTriggerRef.current = ScrollTrigger.create({\n trigger: boxRef.current,\n start: 'top top',\n end: 'bottom top',\n scrub: true,\n onUpdate: (self: any) => {\n const base = 20\n const value = self.progress * base\n gsap.set(bgRef.current, { yPercent: value })\n },\n })\n }\n }\n if (inView) gsapResize()\n return () => {\n // ScrollTrigger.getAll().forEach((t: any) => t.kill())\n scrollTriggerRef.current && scrollTriggerRef.current.kill()\n boxTriggerRef.current && boxTriggerRef.current.kill()\n bgTriggerRef.current && bgTriggerRef.current.kill()\n }\n }, [inView])\n\n return (\n <div ref={inViewRef} data-ui-component-id=\"HeroBanner\">\n <div\n ref={boxRef}\n className={cn(\n theme === 'dark' ? 'aiui-dark' : '',\n 'text-info-primary relative w-full overflow-hidden',\n {\n 'lg-desktop:aspect-[1920/930] desktop:aspect-[1440/700] laptop:aspect-[1024/520] tablet:aspect-[768/660] aspect-[390/660]':\n size === 'default',\n 'lg-desktop:aspect-[1920/800] desktop:aspect-[1440/640] laptop:aspect-[1024/480] tablet:aspect-[768/560] aspect-[390/560]':\n size === 'sm',\n },\n className\n )}\n >\n {blockLink && (\n <a\n className=\"absolute inset-0 z-10\"\n href={trackUrlRef(blockLink, `${componentType}_${componentName}`)}\n data-headless-type-name={`${componentType}#${componentName}`}\n data-headless-title-desc-button={`${title}#${subtitle}`}\n tabIndex={-1}\n aria-hidden=\"true\"\n aria-label={title}\n ></a>\n )}\n <div ref={bgRef} className={cn('absolute left-0 top-0 size-full')}>\n {isShowVideo ? (\n <ScrollLoadVideo\n poster={isMobile ? mobileImage?.url : isPad ? padImage?.url || mobileImage?.url : pcImage?.url}\n src={\n isMobile\n ? (mobileVideo?.url as string)\n : isPad\n ? (padVideo?.url as string) || (mobileVideo?.url as string)\n : (pcVideo?.url as string)\n }\n className=\"laptop:w-full h-full\"\n videoClassName=\"h-full object-cover\"\n muted\n loop={isVideoLoop}\n playsInline\n />\n ) : (\n <Picture\n className=\"laptop:w-full h-full\"\n imgClassName=\"h-full object-cover\"\n loading=\"eager\"\n fetchPriority=\"high\"\n alt={pcImage?.alt || ''}\n source={`${pcImage?.url || ''} , ${padImage?.url ?? (mobileImage?.url || '')} 1024, ${mobileImage?.url || ''} 767`}\n />\n )}\n </div>\n\n {/* \u5185\u5BB9\u533A\u57DF */}\n <div className={contentVariants({ align })}>\n <div className={textVariants({ align })}>\n {label && (\n <Text\n size={2}\n as=\"p\"\n className={cn('hero-banner-label font-heading lg-desktop:text-[18px] desktop:text-base text-sm')}\n html={label}\n />\n )}\n {title && (\n <Heading\n as={titleSize === '4' ? 'h1' : 'h2'}\n html={title}\n className={cn('hero-banner-title', classNames.title)}\n size={titleSize ? (Number(titleSize || '5') as any) : size === 'sm' ? 4 : 5}\n />\n )}\n {subtitle && (\n <Text\n as=\"p\"\n size={2}\n className={cn(\n 'hero-banner-subtitle font-heading lg-desktop:text-[18px] desktop:text-base laptop:mt-2 lg-desktop:mt-4 mt-1 text-sm'\n )}\n html={subtitle}\n />\n )}\n {endDate && (\n <div className=\"mt-3\">\n <Countdown\n endDate={endDate}\n endDate_tz={endDate_tz}\n dateFormat={dateFormat}\n variant=\"spacious\"\n align={align}\n />\n </div>\n )}\n </div>\n {/* \u6309\u94AE\u7EC4 */}\n <div className={buttonGroupVariants({ align })}>\n {secondaryButton?.isShowPlayVideoButton && secondaryButton?.playVideoButtonText ? (\n <Button\n onClick={() => setVisible(true)}\n size=\"lg\"\n variant=\"secondary\"\n className=\"hero-banner-play-video-button\"\n data-headless-type-name={`${componentType}#${componentName}`}\n data-headless-title-desc-button={`${title}#${subtitle}#${secondaryButton?.playVideoButtonText}`}\n >\n {secondaryButton?.playVideoButtonText} <PlayButtonAppendIcon size=\"lg\" />\n </Button>\n ) : secondaryButton?.text ? (\n <Button\n aria-label={title ?? subtitle}\n size=\"lg\"\n variant=\"secondary\"\n className=\"hero-banner-secondary-button\"\n as={secondaryButton?.isCustomSecondaryButton ? 'button' : 'a'}\n href={trackUrlRef(secondaryButton?.link, `${componentType}_${componentName}`)}\n onClick={e =>\n secondaryButton?.isCustomSecondaryButton &&\n onSecondaryClick?.(data, e, secondaryButton?.customSecondaryEventId)\n }\n data-headless-type-name={`${componentType}#${componentName}`}\n data-headless-title-desc-button={`${title}#${subtitle}#${secondaryButton?.text}`}\n >\n {secondaryButton?.text}\n <span className=\"sr-only\">{title ?? subtitle}</span>\n </Button>\n ) : null}\n {primaryButton && primaryButton.text && (\n <Button\n aria-label={title ?? subtitle}\n size=\"lg\"\n variant=\"primary\"\n className=\"hero-banner-primary-button\"\n as={primaryButton?.isCustomPrimaryButton ? 'button' : 'a'}\n href={trackUrlRef(primaryButton.link, `${componentType}_${componentName}`)}\n onClick={e =>\n primaryButton?.isCustomPrimaryButton && onPrimaryClick?.(data, e, primaryButton?.customPrimaryEventId)\n }\n data-headless-type-name={`${componentType}#${componentName}`}\n data-headless-title-desc-button={`${title}#${subtitle}#${primaryButton?.text}`}\n >\n {primaryButton.text}\n </Button>\n )}\n </div>\n <div className={iconGroupVariants({ align })}>\n {iconArray?.map(icon => (\n <div key={icon?.pcImage?.url || icon?.pcImage?.alt} className=\"h-12\">\n <Picture\n className=\"laptop:w-full h-full\"\n imgClassName=\"h-full object-cover\"\n loading=\"eager\"\n alt={icon?.pcImage?.alt || ''}\n source={icon?.pcImage?.url}\n />\n </div>\n ))}\n </div>\n </div>\n\n {/* \u5E95\u90E8\u4EA7\u54C1\u5217\u8868 */}\n {caption.length > 0 && (\n <div\n className={cn(\n 'hero-banner-caption-group laptop:gap-3 tablet:px-[32px] laptop:px-[64px] lg-desktop:px-[calc(50%-832px)] desktop:pb-[24px] absolute bottom-0 z-10 flex items-stretch gap-2 px-[16px] pb-[16px]',\n classNames.captionGroup\n )}\n >\n {caption.map((c, index) => (\n <React.Fragment key={c.title}>\n <Text\n size={2}\n className={cn(\n 'hero-banner-product-text tablet:w-[108px] loptop:w-[150px] desktop:w-[156px] lg-desktop:w-[180px] laptop:text-[14px] flex-1 text-[12px]'\n )}\n html={c.title}\n />\n {index < caption.length - 1 && <div className={cn('bg-info-primary w-px')} />}\n </React.Fragment>\n ))}\n </div>\n )}\n\n {/* \u89C6\u9891\u5F39\u7A97 */}\n {visible && (\n <VideoModal\n visible={visible}\n videoUrl={secondaryButton?.videoUrl?.url}\n youTubeId={secondaryButton?.youtubeId}\n onCloseModal={() => setVisible(false)}\n />\n )}\n </div>\n </div>\n )\n})\n\nHeroBanner.displayName = 'HeroBanner'\n\nexport default withLayout(HeroBanner)\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["HeroBanner_exports", "__export", "HeroBanner_default", "__toCommonJS", "import_jsx_runtime", "import_react", "import_gsap", "import_ScrollTrigger", "import_react_responsive", "import_react_intersection_observer", "import_ScrollLoadVideo", "import_components", "import_helpers", "import_class_variance_authority", "import_Styles", "import_useExposure", "import_trackUrlRef", "import_button", "import_VideoModal", "componentType", "componentName", "contentVariants", "textVariants", "buttonGroupVariants", "iconGroupVariants", "PlayButtonAppendIcon", "size", "width", "height", "HeroBanner", "React", "data", "className", "classNames", "onSecondaryClick", "onPrimaryClick", "ref", "label", "title", "subtitle", "endDate", "endDate_tz", "dateFormat", "pcImage", "padImage", "mobileImage", "pcVideo", "padVideo", "mobileVideo", "isShowVideo", "isVideoLoop", "primaryButton", "secondaryButton", "theme", "titleSize", "caption", "blockLink", "iconArray", "align", "isMobile", "isPad", "visible", "setVisible", "inViewRef", "inView", "scrollTriggerRef", "bgTriggerRef", "boxTriggerRef", "bgRef", "boxRef", "gsap", "gsapResize", "clientHeight", "self", "value", "ScrollLoadVideo", "e", "icon", "c", "index"]
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/biz-components/HeroBanner/types.ts"],
|
|
4
|
-
"sourcesContent": ["import type { ButtonProps } from '../../components/button.js'\nimport type { Media, Theme } from '../../types/props.js'\n\ntype TitleSizeType = '5' | '4' | '3' | '2' | '1'\nexport interface HeroBannerProps {\n data: {\n /** \u6807\u7B7E */\n label?: string\n /** \u4E3B\u6807\u9898 */\n title: string\n /** \u526F\u6807\u9898/\u63CF\u8FF0\u6587\u672C */\n subtitle: string\n /** \u7ED3\u675F\u65F6\u95F4\uFF08ISO \u5B57\u7B26\u4E32\uFF09 */\n endDate?: string\n /** \u7ED3\u675F\u65F6\u95F4\u65F6\u533A\uFF08\u5982: America/Los_Angeles\uFF09 */\n endDate_tz?: string\n dateFormat?: string\n /** \u56FE\u6807\u5217\u8868 */\n iconArray?: Array<any>\n pcImage: Media\n padImage?: Media\n mobileImage: Media\n pcVideo?: Media\n padVideo?: Media\n mobileVideo?: Media\n isShowVideo?: boolean\n /** \u89C6\u9891\u662F\u5426\u5FAA\u73AF\u64AD\u653E */\n isVideoLoop?: boolean\n blockLink?: string\n /** \u4E3B\u6309\u94AE\u6587\u672C\u548C\u914D\u7F6E */\n primaryButton?: {\n text: string\n link?: string\n isCustomPrimaryButton?: boolean\n /** \u81EA\u5B9A\u4E49\u4E8B\u4EF6ID\uFF0C\u4F20\u9012\u7ED9 onPrimaryClick */\n customPrimaryEventId?: string\n } & Omit<ButtonProps, 'children'>\n /** \u6B21\u8981\u6309\u94AE\u6587\u672C\u548C\u914D\u7F6E */\n secondaryButton?: {\n text: string\n link?: string\n isShowPlayVideoButton?: boolean\n playVideoButtonText?: string\n playIcon?: boolean\n videoUrl?: Media\n youtubeId?: string\n isCustomSecondaryButton?: boolean\n /** \u81EA\u5B9A\u4E49\u4E8B\u4EF6ID\uFF0C\u4F20\u9012\u7ED9 onSecondaryClick */\n customSecondaryEventId?: string\n } & Omit<ButtonProps, 'children'>\n /** \u4E3B\u9898 */\n theme?: Theme\n /** \u5927\u5C0F, \u9ED8\u8BA4default,\u5355banner, \u53EF\u9009sm, \u7528\u4E8E\u591Abanner\u573A\u666F */\n size?: 'default' | 'sm'\n titleSize?: TitleSizeType\n /** \u5E95\u90E8\u4EA7\u54C1\u5217\u8868 */\n caption?: Array<{\n title: string\n }>\n }\n /** \u81EA\u5B9A\u4E49\u7C7B\u540D */\n className?: string\n onSecondaryClick?: (data: any, e: any, customPrimaryEventId?: string) => void\n onPrimaryClick?: (data: any, e: any, customSecondaryEventId?: string) => void\n}\n"],
|
|
4
|
+
"sourcesContent": ["import type { ButtonProps } from '../../components/button.js'\nimport type { Media, Theme } from '../../types/props.js'\n\ntype TitleSizeType = '5' | '4' | '3' | '2' | '1'\nexport interface HeroBannerProps {\n data: {\n /** \u6807\u7B7E */\n label?: string\n /** \u4E3B\u6807\u9898 */\n title: string\n /** \u526F\u6807\u9898/\u63CF\u8FF0\u6587\u672C */\n subtitle: string\n /** \u7ED3\u675F\u65F6\u95F4\uFF08ISO \u5B57\u7B26\u4E32\uFF09 */\n endDate?: string\n /** \u7ED3\u675F\u65F6\u95F4\u65F6\u533A\uFF08\u5982: America/Los_Angeles\uFF09 */\n endDate_tz?: string\n dateFormat?: string\n /** \u56FE\u6807\u5217\u8868 */\n iconArray?: Array<any>\n pcImage: Media\n padImage?: Media\n mobileImage: Media\n pcVideo?: Media\n padVideo?: Media\n mobileVideo?: Media\n isShowVideo?: boolean\n /** \u89C6\u9891\u662F\u5426\u5FAA\u73AF\u64AD\u653E */\n isVideoLoop?: boolean\n blockLink?: string\n /** \u4E3B\u6309\u94AE\u6587\u672C\u548C\u914D\u7F6E */\n primaryButton?: {\n text: string\n link?: string\n isCustomPrimaryButton?: boolean\n /** \u81EA\u5B9A\u4E49\u4E8B\u4EF6ID\uFF0C\u4F20\u9012\u7ED9 onPrimaryClick */\n customPrimaryEventId?: string\n } & Omit<ButtonProps, 'children'>\n /** \u6B21\u8981\u6309\u94AE\u6587\u672C\u548C\u914D\u7F6E */\n secondaryButton?: {\n text: string\n link?: string\n isShowPlayVideoButton?: boolean\n playVideoButtonText?: string\n playIcon?: boolean\n videoUrl?: Media\n youtubeId?: string\n isCustomSecondaryButton?: boolean\n /** \u81EA\u5B9A\u4E49\u4E8B\u4EF6ID\uFF0C\u4F20\u9012\u7ED9 onSecondaryClick */\n customSecondaryEventId?: string\n } & Omit<ButtonProps, 'children'>\n /** \u4E3B\u9898 */\n theme?: Theme\n /** \u5927\u5C0F, \u9ED8\u8BA4default,\u5355banner, \u53EF\u9009sm, \u7528\u4E8E\u591Abanner\u573A\u666F */\n size?: 'default' | 'sm'\n titleSize?: TitleSizeType\n /** \u5185\u5BB9\u5BF9\u9F50\u65B9\u5F0F */\n align?: 'left' | 'center'\n /** \u5E95\u90E8\u4EA7\u54C1\u5217\u8868 */\n caption?: Array<{\n title: string\n }>\n }\n /** \u81EA\u5B9A\u4E49\u7C7B\u540D */\n className?: string\n onSecondaryClick?: (data: any, e: any, customPrimaryEventId?: string) => void\n onPrimaryClick?: (data: any, e: any, customSecondaryEventId?: string) => void\n}\n"],
|
|
5
5
|
"mappings": "+WAAA,IAAAA,EAAA,kBAAAC,EAAAD",
|
|
6
6
|
"names": ["types_exports", "__toCommonJS"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";"use client";var rt=Object.create;var g=Object.defineProperty;var it=Object.getOwnPropertyDescriptor;var st=Object.getOwnPropertyNames;var ot=Object.getPrototypeOf,at=Object.prototype.hasOwnProperty;var lt=(t,e)=>{for(var n in e)g(t,n,{get:e[n],enumerable:!0})},V=(t,e,n,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of st(e))!at.call(t,s)&&s!==n&&g(t,s,{get:()=>e[s],enumerable:!(o=it(e,s))||o.enumerable});return t};var M=(t,e,n)=>(n=t!=null?rt(ot(t)):{},V(e||!t||!t.__esModule?g(n,"default",{value:t,enumerable:!0}):n,t)),ct=t=>V(g({},"__esModule",{value:!0}),t);var
|
|
1
|
+
"use strict";"use client";var rt=Object.create;var g=Object.defineProperty;var it=Object.getOwnPropertyDescriptor;var st=Object.getOwnPropertyNames;var ot=Object.getPrototypeOf,at=Object.prototype.hasOwnProperty;var lt=(t,e)=>{for(var n in e)g(t,n,{get:e[n],enumerable:!0})},V=(t,e,n,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of st(e))!at.call(t,s)&&s!==n&&g(t,s,{get:()=>e[s],enumerable:!(o=it(e,s))||o.enumerable});return t};var M=(t,e,n)=>(n=t!=null?rt(ot(t)):{},V(e||!t||!t.__esModule?g(n,"default",{value:t,enumerable:!0}):n,t)),ct=t=>V(g({},"__esModule",{value:!0}),t);var pt={};lt(pt,{default:()=>ut});module.exports=ct(pt);var r=require("react/jsx-runtime"),i=M(require("react")),h=require("gsap"),b=require("gsap/dist/SplitText"),T=require("gsap/dist/ScrollTrigger"),l=require("../../helpers/utils.js"),F=require("class-variance-authority"),x=require("../../components/index.js"),j=require("../../shared/Styles.js"),A=require("../../shared/trackUrlRef.js"),I=require("react-intersection-observer"),B=M(require("./Countdown.js"));const $="link",z="title",dt=(0,F.cva)("",{variants:{theme:{light:"text-[#080A0F]",dark:"text-[#F5F6F7]"}},defaultVariants:{theme:"light"}}),mt=(0,F.cva)("desktop:text-base desktop:mt-2 lg-desktop:text-[18px] mt-1 text-[14px] font-bold leading-[1.4] tracking-[-0.36px]",{variants:{theme:{light:"text-[#080A0F]",dark:"text-[#F5F6F7]"}},defaultVariants:{theme:"light"}}),P=({data:t,className:e})=>{const{theme:n="light",extensions:o,title:s,caption:p,align:c}=t;return o?.textLink?(0,r.jsxs)("a",{className:(0,l.cn)({"aiui-dark":n==="dark"},"hover:text-brand-0 [&_svg_path]:hover:fill-brand-0 lg-desktop:text-base flex items-center overflow-hidden text-sm font-[700] leading-[1.4] transition-all duration-[0.4s]",{"text-[#080A0F]":n==="light"},{"text-[#F5F6F7]":n==="dark"},{"justify-center mt-4":c==="center"},{"mt-1 laptop:mt-0":c==="left"},e),href:(0,A.trackUrlRef)(o?.link,`${$}_${z}`),"data-headless-type-name":`${$}#${z}`,"data-headless-title-desc-button":`${s}#${p}`,children:[(0,r.jsx)("div",{className:"truncate whitespace-nowrap",children:o?.textLink}),(0,r.jsx)("div",{className:"lg-desktop:size-5 size-4",children:(0,r.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"100%",height:"100%",viewBox:"0 0 20 20",fill:"none",children:(0,r.jsx)("path",{d:"M6.91058 4.41083C7.23602 4.08539 7.76353 4.08539 8.08897 4.41083L13.089 9.41083C13.4144 9.73626 13.4144 10.2638 13.089 10.5892L8.08897 15.5892C7.76353 15.9146 7.23602 15.9146 6.91058 15.5892C6.58515 15.2638 6.58514 14.7363 6.91058 14.4108L11.3214 10L6.91058 5.58921C6.58514 5.26377 6.58514 4.73626 6.91058 4.41083Z",fill:n==="dark"?"#F5F6F7":"#080A0F",className:"transition-all duration-[0.4s]"})})})]}):null},S=i.default.forwardRef(({data:t,className:e,as:n="h2",weight:o="bold"},s)=>{const{title:p,caption:c,subtitle:y,countdown:N,showCountdown:D=!1,theme:f="light",extensions:_,align:d="left"}=t,C=(0,i.useRef)(null),m=(0,i.useRef)(null),a=(0,i.useRef)(null),u=(0,i.useRef)(null),[U,O]=(0,i.useState)(!0),{ref:Z,inView:L}=(0,I.useInView)();(0,i.useImperativeHandle)(s,()=>C.current);const q=()=>{O(!1)};return(0,i.useEffect)(()=>{h.gsap.registerPlugin(b.SplitText,T.ScrollTrigger);function G(){if(!m.current)return;const J=m.current?.clientHeight||80;a.current&&a.current.revert(),u.current&&u.current.kill(),a.current=new b.SplitText(m.current,{type:"words",wordsClass:"word"});const w=a.current.words;h.gsap.set(w,{opacity:0}),u.current=T.ScrollTrigger.create({trigger:m.current,start:"bottom bottom-=4%",end:`bottom+=${J*1.5+60}px bottom-=4%`,scrub:!0,invalidateOnRefresh:!0,onUpdate:K=>{const Q=K.progress,R=w.length||1,W=.5,v=1/R,E=v*(1-W),H=(R-1)*E+v,X=Math.min(1,H>0?Q/H:0);w.forEach((Y,tt)=>{const et=tt*E,nt=v;let k=(X-et)/nt;k=Math.max(0,Math.min(1,k)),h.gsap.set(Y,{opacity:k})})}})}return L&&G(),()=>{a.current&&a.current.revert(),u.current&&u.current.kill()}},[L]),(0,r.jsxs)("div",{id:_?.id,className:"titleBottom title-box flex items-end justify-between gap-2 pb-6",ref:C,children:[(0,r.jsxs)("div",{ref:Z,className:(0,l.cn)("flex-1",e,{"aiui-dark":f==="dark","text-center":d==="center","text-left":d==="left"}),children:[(c||p)&&(0,r.jsx)(x.Heading,{ref:m,as:n,size:4,html:c||p,weight:o,className:dt({theme:f})}),y&&(0,r.jsx)(x.Text,{html:y,as:"p",className:mt({theme:f})}),(0,r.jsx)(P,{data:t,className:(0,l.cn)({"laptop:hidden":d==="left"})}),D&&N&&U&&(0,r.jsx)(B.default,{className:(0,l.cn)("mt-4 justify-start",{"justify-center":d==="center"}),config:N,onCountdownEnd:q,theme:f})]}),(0,r.jsx)(P,{data:t,className:(0,l.cn)("hidden",{"laptop:flex":d==="left"})})]})});S.displayName="Title";var ut=(0,j.withLayout)(S);
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/biz-components/Title/index.tsx"],
|
|
4
|
-
"sourcesContent": ["'use client'\nimport React, { useEffect, useRef, useImperativeHandle, useState } from 'react'\nimport { gsap } from 'gsap'\nimport { SplitText } from 'gsap/dist/SplitText'\nimport { ScrollTrigger } from 'gsap/dist/ScrollTrigger'\nimport { cn } from '../../helpers/utils.js'\nimport { cva } from 'class-variance-authority'\nimport { Heading, Text } from '../../components/index.js'\nimport { withLayout } from '../../shared/Styles.js'\nimport type { TitleProps } from './types.js'\nimport { trackUrlRef } from '../../shared/trackUrlRef.js'\nimport { useInView } from 'react-intersection-observer'\nimport Countdown from './Countdown.js'\n\nconst componentType = 'link'\nconst componentName = 'title'\n\n/**\n * \u6807\u9898\u6837\u5F0F\u53D8\u4F53\n */\nconst titleHeadingVariants = cva('', {\n variants: {\n theme: {\n light: 'text-[#080A0F]',\n dark: 'text-[#F5F6F7]',\n },\n },\n defaultVariants: {\n theme: 'light',\n },\n})\n\n/**\n * \u526F\u6807\u9898\u6837\u5F0F\u53D8\u4F53\n */\nconst subtitleVariants = cva(\n 'desktop:text-base desktop:mt-2 lg-desktop:text-[18px] mt-1 text-[14px] font-bold leading-[1.4] tracking-[-0.36px]',\n {\n variants: {\n theme: {\n light: 'text-[#080A0F]',\n dark: 'text-[#F5F6F7]',\n },\n },\n defaultVariants: {\n theme: 'light',\n },\n }\n)\n\nconst TitleButton = ({ data, className }: { data: TitleProps['data']; className?: string }) => {\n const { theme = 'light', extensions, title, caption, align } = data\n if (!extensions?.textLink) return null\n return (\n <a\n className={cn(\n { 'aiui-dark': theme === 'dark' },\n 'hover:text-brand-0 [&_svg_path]:hover:fill-brand-0 lg-desktop:text-base flex items-center overflow-hidden text-sm font-[700] leading-[1.4] transition-all duration-[0.4s]',\n { 'text-[#080A0F]': theme === 'light' },\n { 'text-[#F5F6F7]': theme === 'dark' },\n { 'justify-center mt-4': align === 'center' },\n { 'mt-1 laptop:mt-0': align === 'left' },\n className\n )}\n href={trackUrlRef(extensions?.link, `${componentType}_${componentName}`)}\n data-headless-type-name={`${componentType}#${componentName}`}\n data-headless-title-desc-button={`${title}#${caption}`}\n >\n <div className=\"truncate whitespace-nowrap\">{extensions?.textLink}</div>\n <div className=\"lg-desktop:size-5 size-4\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"100%\" height=\"100%\" viewBox=\"0 0 20 20\" fill=\"none\">\n <path\n d=\"M6.91058 4.41083C7.23602 4.08539 7.76353 4.08539 8.08897 4.41083L13.089 9.41083C13.4144 9.73626 13.4144 10.2638 13.089 10.5892L8.08897 15.5892C7.76353 15.9146 7.23602 15.9146 6.91058 15.5892C6.58515 15.2638 6.58514 14.7363 6.91058 14.4108L11.3214 10L6.91058 5.58921C6.58514 5.26377 6.58514 4.73626 6.91058 4.41083Z\"\n fill={theme === 'dark' ? '#F5F6F7' : '#080A0F'}\n className=\"transition-all duration-[0.4s]\"\n />\n </svg>\n </div>\n </a>\n )\n}\n\nconst Title = React.forwardRef<HTMLDivElement, TitleProps>(({ data, className, as = 'h2', weight = 'bold' }, ref) => {\n const {\n title,\n caption,\n subtitle,\n countdown,\n showCountdown = false,\n theme = 'light',\n extensions,\n align = 'left',\n } = data\n const innerRef = useRef<HTMLDivElement>(null)\n const titleRef = useRef<HTMLHeadingElement>(null)\n const splitTextInstance = useRef<SplitText | null>(null)\n const scrollTriggerRef = useRef<ScrollTrigger | null>(null)\n\n // \u63A7\u5236\u5012\u8BA1\u65F6\u663E\u793A\u72B6\u6001\n const [isCountdownVisible, setIsCountdownVisible] = useState(true)\n\n const { ref: inViewRef, inView } = useInView()\n\n useImperativeHandle(ref, () => innerRef.current as HTMLDivElement)\n\n // \u5012\u8BA1\u65F6\u7ED3\u675F\u56DE\u8C03\n const handleCountdownEnd = () => {\n setIsCountdownVisible(false)\n }\n\n useEffect(() => {\n gsap.registerPlugin(SplitText, ScrollTrigger)\n function gsapResize() {\n if (!titleRef.current) return\n const height = titleRef.current?.clientHeight || 80\n if (splitTextInstance.current) {\n splitTextInstance.current.revert()\n }\n if (scrollTriggerRef.current) {\n scrollTriggerRef.current.kill()\n }\n splitTextInstance.current = new SplitText(titleRef.current, {\n type: 'words',\n wordsClass: 'word',\n })\n const words = splitTextInstance.current.words\n gsap.set(words, { opacity: 0 })\n scrollTriggerRef.current = ScrollTrigger.create({\n trigger: titleRef.current,\n start: 'bottom bottom-=4%',\n end: `bottom+=${height * 1.5 + 60}px bottom-=4%`,\n scrub: true,\n invalidateOnRefresh: true,\n onUpdate: (self: any) => {\n const progress = self.progress\n const total = words.length || 1\n const overlap = 0.5\n const interval = 1 / total\n const step = interval * (1 - overlap)\n const lastEnd = (total - 1) * step + interval\n const normalizedProgress = Math.min(1, lastEnd > 0 ? progress / lastEnd : 0)\n words.forEach((word: any, i: number) => {\n const start = i * step\n const width = interval\n let opacity = (normalizedProgress - start) / width\n opacity = Math.max(0, Math.min(1, opacity))\n gsap.set(word, { opacity })\n })\n },\n })\n }\n\n if (inView) {\n gsapResize()\n }\n\n return () => {\n splitTextInstance.current && splitTextInstance.current.revert()\n // ScrollTrigger.getAll().forEach((t: { kill: () => any }) => t.kill())\n scrollTriggerRef.current && scrollTriggerRef.current.kill()\n }\n }, [inView])\n\n return (\n <div id={extensions?.id} className=\"titleBottom title-box
|
|
4
|
+
"sourcesContent": ["'use client'\nimport React, { useEffect, useRef, useImperativeHandle, useState } from 'react'\nimport { gsap } from 'gsap'\nimport { SplitText } from 'gsap/dist/SplitText'\nimport { ScrollTrigger } from 'gsap/dist/ScrollTrigger'\nimport { cn } from '../../helpers/utils.js'\nimport { cva } from 'class-variance-authority'\nimport { Heading, Text } from '../../components/index.js'\nimport { withLayout } from '../../shared/Styles.js'\nimport type { TitleProps } from './types.js'\nimport { trackUrlRef } from '../../shared/trackUrlRef.js'\nimport { useInView } from 'react-intersection-observer'\nimport Countdown from './Countdown.js'\n\nconst componentType = 'link'\nconst componentName = 'title'\n\n/**\n * \u6807\u9898\u6837\u5F0F\u53D8\u4F53\n */\nconst titleHeadingVariants = cva('', {\n variants: {\n theme: {\n light: 'text-[#080A0F]',\n dark: 'text-[#F5F6F7]',\n },\n },\n defaultVariants: {\n theme: 'light',\n },\n})\n\n/**\n * \u526F\u6807\u9898\u6837\u5F0F\u53D8\u4F53\n */\nconst subtitleVariants = cva(\n 'desktop:text-base desktop:mt-2 lg-desktop:text-[18px] mt-1 text-[14px] font-bold leading-[1.4] tracking-[-0.36px]',\n {\n variants: {\n theme: {\n light: 'text-[#080A0F]',\n dark: 'text-[#F5F6F7]',\n },\n },\n defaultVariants: {\n theme: 'light',\n },\n }\n)\n\nconst TitleButton = ({ data, className }: { data: TitleProps['data']; className?: string }) => {\n const { theme = 'light', extensions, title, caption, align } = data\n if (!extensions?.textLink) return null\n return (\n <a\n className={cn(\n { 'aiui-dark': theme === 'dark' },\n 'hover:text-brand-0 [&_svg_path]:hover:fill-brand-0 lg-desktop:text-base flex items-center overflow-hidden text-sm font-[700] leading-[1.4] transition-all duration-[0.4s]',\n { 'text-[#080A0F]': theme === 'light' },\n { 'text-[#F5F6F7]': theme === 'dark' },\n { 'justify-center mt-4': align === 'center' },\n { 'mt-1 laptop:mt-0': align === 'left' },\n className\n )}\n href={trackUrlRef(extensions?.link, `${componentType}_${componentName}`)}\n data-headless-type-name={`${componentType}#${componentName}`}\n data-headless-title-desc-button={`${title}#${caption}`}\n >\n <div className=\"truncate whitespace-nowrap\">{extensions?.textLink}</div>\n <div className=\"lg-desktop:size-5 size-4\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"100%\" height=\"100%\" viewBox=\"0 0 20 20\" fill=\"none\">\n <path\n d=\"M6.91058 4.41083C7.23602 4.08539 7.76353 4.08539 8.08897 4.41083L13.089 9.41083C13.4144 9.73626 13.4144 10.2638 13.089 10.5892L8.08897 15.5892C7.76353 15.9146 7.23602 15.9146 6.91058 15.5892C6.58515 15.2638 6.58514 14.7363 6.91058 14.4108L11.3214 10L6.91058 5.58921C6.58514 5.26377 6.58514 4.73626 6.91058 4.41083Z\"\n fill={theme === 'dark' ? '#F5F6F7' : '#080A0F'}\n className=\"transition-all duration-[0.4s]\"\n />\n </svg>\n </div>\n </a>\n )\n}\n\nconst Title = React.forwardRef<HTMLDivElement, TitleProps>(({ data, className, as = 'h2', weight = 'bold' }, ref) => {\n const {\n title,\n caption,\n subtitle,\n countdown,\n showCountdown = false,\n theme = 'light',\n extensions,\n align = 'left',\n } = data\n const innerRef = useRef<HTMLDivElement>(null)\n const titleRef = useRef<HTMLHeadingElement>(null)\n const splitTextInstance = useRef<SplitText | null>(null)\n const scrollTriggerRef = useRef<ScrollTrigger | null>(null)\n\n // \u63A7\u5236\u5012\u8BA1\u65F6\u663E\u793A\u72B6\u6001\n const [isCountdownVisible, setIsCountdownVisible] = useState(true)\n\n const { ref: inViewRef, inView } = useInView()\n\n useImperativeHandle(ref, () => innerRef.current as HTMLDivElement)\n\n // \u5012\u8BA1\u65F6\u7ED3\u675F\u56DE\u8C03\n const handleCountdownEnd = () => {\n setIsCountdownVisible(false)\n }\n\n useEffect(() => {\n gsap.registerPlugin(SplitText, ScrollTrigger)\n function gsapResize() {\n if (!titleRef.current) return\n const height = titleRef.current?.clientHeight || 80\n if (splitTextInstance.current) {\n splitTextInstance.current.revert()\n }\n if (scrollTriggerRef.current) {\n scrollTriggerRef.current.kill()\n }\n splitTextInstance.current = new SplitText(titleRef.current, {\n type: 'words',\n wordsClass: 'word',\n })\n const words = splitTextInstance.current.words\n gsap.set(words, { opacity: 0 })\n scrollTriggerRef.current = ScrollTrigger.create({\n trigger: titleRef.current,\n start: 'bottom bottom-=4%',\n end: `bottom+=${height * 1.5 + 60}px bottom-=4%`,\n scrub: true,\n invalidateOnRefresh: true,\n onUpdate: (self: any) => {\n const progress = self.progress\n const total = words.length || 1\n const overlap = 0.5\n const interval = 1 / total\n const step = interval * (1 - overlap)\n const lastEnd = (total - 1) * step + interval\n const normalizedProgress = Math.min(1, lastEnd > 0 ? progress / lastEnd : 0)\n words.forEach((word: any, i: number) => {\n const start = i * step\n const width = interval\n let opacity = (normalizedProgress - start) / width\n opacity = Math.max(0, Math.min(1, opacity))\n gsap.set(word, { opacity })\n })\n },\n })\n }\n\n if (inView) {\n gsapResize()\n }\n\n return () => {\n splitTextInstance.current && splitTextInstance.current.revert()\n // ScrollTrigger.getAll().forEach((t: { kill: () => any }) => t.kill())\n scrollTriggerRef.current && scrollTriggerRef.current.kill()\n }\n }, [inView])\n\n return (\n <div id={extensions?.id} className=\"titleBottom title-box flex items-end justify-between gap-2 pb-6\" ref={innerRef}>\n <div\n ref={inViewRef}\n className={cn('flex-1', className, {\n 'aiui-dark': theme === 'dark',\n 'text-center': align === 'center',\n 'text-left': align === 'left',\n })}\n >\n {(caption || title) && (\n <Heading\n ref={titleRef}\n as={as}\n size={4}\n html={caption || title}\n weight={weight}\n className={titleHeadingVariants({ theme })}\n />\n )}\n {subtitle && <Text html={subtitle} as=\"p\" className={subtitleVariants({ theme })} />}\n <TitleButton data={data} className={cn({ 'laptop:hidden': align === 'left' })} />\n {showCountdown && countdown && isCountdownVisible && (\n <Countdown\n className={cn('mt-4 justify-start', {\n 'justify-center': align === 'center',\n })}\n config={countdown}\n onCountdownEnd={handleCountdownEnd}\n theme={theme}\n />\n )}\n </div>\n <TitleButton data={data} className={cn('hidden', { ['laptop:flex']: align === 'left' })} />\n </div>\n )\n})\n\nTitle.displayName = 'Title'\n\nexport default withLayout(Title)\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": ["Title_exports", "__export", "Title_default", "__toCommonJS", "import_jsx_runtime", "import_react", "import_gsap", "import_SplitText", "import_ScrollTrigger", "import_utils", "import_class_variance_authority", "import_components", "import_Styles", "import_trackUrlRef", "import_react_intersection_observer", "import_Countdown", "componentType", "componentName", "titleHeadingVariants", "subtitleVariants", "TitleButton", "data", "className", "theme", "extensions", "title", "caption", "align", "Title", "React", "as", "weight", "ref", "subtitle", "countdown", "showCountdown", "innerRef", "titleRef", "splitTextInstance", "scrollTriggerRef", "isCountdownVisible", "setIsCountdownVisible", "inViewRef", "inView", "handleCountdownEnd", "gsapResize", "height", "words", "self", "progress", "total", "overlap", "interval", "step", "lastEnd", "normalizedProgress", "word", "i", "start", "width", "opacity", "Countdown"]
|
|
7
7
|
}
|
|
@@ -2,6 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { type VariantProps } from 'class-variance-authority';
|
|
3
3
|
declare const countdownVariants: (props?: ({
|
|
4
4
|
variant?: "outline" | "spacious" | null | undefined;
|
|
5
|
+
align?: "left" | "center" | null | undefined;
|
|
5
6
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
6
7
|
/**
|
|
7
8
|
* 时间标签配置接口
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";"use client";var
|
|
1
|
+
"use strict";"use client";var J=Object.create;var p=Object.defineProperty;var $=Object.getOwnPropertyDescriptor;var q=Object.getOwnPropertyNames;var G=Object.getPrototypeOf,K=Object.prototype.hasOwnProperty;var Q=(e,t)=>{for(var a in t)p(e,a,{get:t[a],enumerable:!0})},R=(e,t,a,N)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of q(t))!K.call(e,i)&&i!==a&&p(e,i,{get:()=>t[i],enumerable:!(N=$(t,i))||N.enumerable});return e};var U=(e,t,a)=>(a=e!=null?J(G(e)):{},R(t||!e||!e.__esModule?p(a,"default",{value:e,enumerable:!0}):a,e)),X=e=>R(p({},"__esModule",{value:!0}),e);var tt={};Q(tt,{default:()=>F});module.exports=X(tt);var n=require("react/jsx-runtime"),r=U(require("react")),d=require("class-variance-authority"),l=require("../helpers/index.js");const Y=(0,d.cva)("countdown-container flex w-full items-center",{variants:{variant:{outline:"gap-1",spacious:"gap-1"},align:{left:"justify-start",center:"justify-center"}},defaultVariants:{variant:"outline",align:"left"}}),f=(0,d.cva)("time-block border-box rounded-box-small flex flex-col items-center justify-center overflow-hidden text-center text-xs",{variants:{variant:{outline:"border-info-primary text-info-primary desktop:size-12 desktop:p-1 size-10 border bg-transparent p-[2px]",spacious:"bg-info-white text-info-primary desktop:size-12 desktop:p-1 size-10 p-[2px]"}},defaultVariants:{variant:"outline"}}),x=(0,d.cva)("time-number lg-desktop:text-[24px] desktop:leading-[120%] translate-y-[2px] whitespace-nowrap text-center text-[20px] font-bold leading-none"),M=(0,d.cva)("separator desktop:text-2xl text-xl font-bold",{variants:{variant:{outline:"text-info-primary",spacious:"text-info-primary"}},defaultVariants:{variant:"outline"}}),v=(e,t=2)=>String(Math.abs(e)).padStart(t,"0"),b=()=>({day:"Day",hour:"Hours",minute:"Mins",second:"Secs"}),Z=e=>{try{let t=e?.trim?.();return!t?.startsWith?.("{")||!t?.endsWith?.("}")?b():(t=t?.replace?.(/(\w+)\s*:/g,'"$1":'),{...b(),...JSON.parse(t)})}catch{return b()}},z=r.default.forwardRef(({className:e,endDate:t,endDate_tz:a,locale:N,timeLabels:i,dateFormat:g,onExpire:D,separator:w=":",hideWhenExpired:C=!0,variant:o,align:H,...I},j)=>{const u=(0,r.useMemo)(()=>i||(g?Z(g):b()),[i,g]),c=(0,r.useRef)(Date.parse(t)),[P,k]=(0,r.useState)(()=>{const s=c.current;return isNaN(s)?0:Math.max(0,s-Date.now())}),[h,T]=(0,r.useState)(()=>{const s=c.current;return!isNaN(s)&&s<=Date.now()});(0,r.useEffect)(()=>{c.current=Date.parse(t);const s=c.current,m=isNaN(s)?0:Math.max(0,s-Date.now()),y=!isNaN(s)&&s<=Date.now();k(m),T(y)},[t]),(0,r.useEffect)(()=>{if(h||isNaN(c.current))return;let s=!1;const m=()=>{const B=Date.now(),S=Math.max(0,c.current-B);k(S),S<=0&&!s&&(s=!0,T(!0),D?.())};m();const y=window.setInterval(m,1e3);return()=>clearInterval(y)},[D,h,t]);const V=Math.floor(P/1e3),O=V%60,E=Math.floor(V/60),W=E%60,L=Math.floor(E/60),_=L%24,A=Math.floor(L/24);return h&&C?null:(0,n.jsxs)("div",{ref:j,className:(0,l.cn)(Y({variant:o,align:H}),e),role:"timer","aria-live":"polite","aria-label":"countdown timer",...I,children:[(0,n.jsxs)("div",{className:(0,l.cn)(f({variant:o}),"time-days-box"),children:[(0,n.jsx)("div",{className:x(),children:v(A,2)}),(0,n.jsx)("div",{className:"truncate text-center text-[12px] font-bold",children:u.day})]}),(0,n.jsx)("div",{className:M({variant:o}),children:w}),(0,n.jsxs)("div",{className:(0,l.cn)(f({variant:o}),"time-hours-box"),children:[(0,n.jsx)("div",{className:x(),children:v(_,2)}),(0,n.jsx)("div",{className:"truncate text-center text-[12px] font-bold",children:u.hour})]}),(0,n.jsx)("div",{className:M({variant:o}),children:w}),(0,n.jsxs)("div",{className:(0,l.cn)(f({variant:o}),"time-minutes-box"),children:[(0,n.jsx)("div",{className:x(),children:v(W,2)}),(0,n.jsx)("div",{className:"truncate text-center text-[12px] font-bold",children:u.minute})]}),(0,n.jsx)("div",{className:M({variant:o}),children:w}),(0,n.jsxs)("div",{className:(0,l.cn)(f({variant:o}),"time-seconds-box"),children:[(0,n.jsx)("div",{className:x(),children:v(O,2)}),(0,n.jsx)("div",{className:"truncate text-center text-[12px] font-bold",children:u.second})]})]})});z.displayName="Countdown";var F=z;
|
|
2
2
|
//# sourceMappingURL=Countdown.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/components/Countdown.tsx"],
|
|
4
|
-
"sourcesContent": ["'use client'\n\nimport React, { useEffect, useRef, useState, useMemo } from 'react'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { cn } from '../helpers/index.js'\n\n// \u5B9A\u4E49\u6837\u5F0F\u53D8\u4F53\nconst countdownVariants = cva(\n // \u57FA\u7840\u6837\u5F0F\uFF1A\u5012\u8BA1\u65F6\u5BB9\u5668\n 'countdown-container flex w-full items-center',\n {\n variants: {\n variant: {\n outline: 'gap-1',\n spacious: 'gap-1',\n },\n },\n defaultVariants: {\n variant: 'outline',\n },\n }\n)\n\nconst timeBlockVariants = cva(\n // \u57FA\u7840\u6837\u5F0F\uFF1A\u65F6\u95F4\u5757\n 'time-block border-box rounded-box-small flex flex-col items-center justify-center overflow-hidden text-center text-xs',\n {\n variants: {\n variant: {\n outline:\n 'border-info-primary text-info-primary desktop:size-12 desktop:p-1 size-10 border bg-transparent p-[2px]',\n spacious: 'bg-info-white text-info-primary desktop:size-12 desktop:p-1 size-10 p-[2px]',\n },\n },\n defaultVariants: {\n variant: 'outline',\n },\n }\n)\n\nconst timeNumberVariants = cva(\n 'time-number lg-desktop:text-[24px] desktop:leading-[120%] translate-y-[2px] whitespace-nowrap text-center text-[20px] font-bold leading-none'\n)\n\nconst separatorVariants = cva(\n // \u57FA\u7840\u6837\u5F0F\uFF1A\u5206\u9694\u7B26\n 'separator desktop:text-2xl text-xl font-bold',\n {\n variants: {\n variant: {\n outline: 'text-info-primary',\n spacious: 'text-info-primary',\n },\n },\n defaultVariants: {\n variant: 'outline',\n },\n }\n)\n\n/**\n * \u65F6\u95F4\u6807\u7B7E\u914D\u7F6E\u63A5\u53E3\n */\nexport interface TimeLabels {\n /** \u5929\u7684\u6807\u7B7E */\n day: string\n /** \u5C0F\u65F6\u7684\u6807\u7B7E */\n hour: string\n /** \u5206\u949F\u7684\u6807\u7B7E */\n minute: string\n /** \u79D2\u7684\u6807\u7B7E */\n second: string\n}\n\n/**\n * \u5012\u8BA1\u65F6\u7EC4\u4EF6Props\u63A5\u53E3\n */\nexport interface CountdownProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onExpire'>, VariantProps<typeof countdownVariants> {\n /** \u7ED3\u675F\u65F6\u95F4 - ISO\u683C\u5F0F\u5B57\u7B26\u4E32 */\n endDate: string\n /** \u7ED3\u675F\u65F6\u95F4\u65F6\u533A\uFF0C\u5982: America/Los_Angeles */\n endDate_tz?: string\n /** \u683C\u5F0F\u5316\u7528\u7684locale\uFF0C\u9ED8\u8BA4\u4F7F\u7528navigator.language */\n locale?: string\n /** \u65F6\u95F4\u6807\u7B7E\u914D\u7F6E\uFF0C\u7528\u4E8E\u56FD\u9645\u5316 */\n timeLabels?: TimeLabels\n /** JSON\u5B57\u7B26\u4E32\u683C\u5F0F\u7684\u65F6\u95F4\u6807\u7B7E\uFF08\u5411\u540E\u517C\u5BB9\uFF09 */\n dateFormat?: string\n /** \u5012\u8BA1\u65F6\u7ED3\u675F\u56DE\u8C03 */\n onExpire?: () => void\n /** \u5206\u9694\u7B26\u5B57\u7B26\uFF0C\u9ED8\u8BA4\u4E3A ':' */\n separator?: string\n /** \u9690\u85CF\u5DF2\u8FC7\u671F\u7684\u5012\u8BA1\u65F6\uFF0C\u9ED8\u8BA4\u4E3A true */\n hideWhenExpired?: boolean\n}\n\n/**\n * \u6570\u5B57\u8865\u96F6\u51FD\u6570\n */\nconst pad = (n: number, len = 2) => String(Math.abs(n)).padStart(len, '0')\n\n/**\n * \u9ED8\u8BA4\u65F6\u95F4\u6807\u7B7E\n */\nconst getDefaultTimeLabels = (): TimeLabels => ({\n day: 'Day',\n hour: 'Hours',\n minute: 'Mins',\n second: 'Secs',\n})\n\n/**\n * \u89E3\u6790dateFormat JSON\u5B57\u7B26\u4E32\uFF08\u5411\u540E\u517C\u5BB9\uFF09\n */\nconst safeStringToObject = (str: string): TimeLabels => {\n try {\n let jsonStr = str?.trim?.()\n if (!jsonStr?.startsWith?.('{') || !jsonStr?.endsWith?.('}')) {\n return getDefaultTimeLabels()\n }\n jsonStr = jsonStr?.replace?.(/(\\w+)\\s*:/g, '\"$1\":')\n return { ...getDefaultTimeLabels(), ...JSON.parse(jsonStr) }\n } catch (err) {\n return getDefaultTimeLabels()\n }\n}\n\n/**\n * Countdown - \u5012\u8BA1\u65F6\u539F\u5B50\u7EC4\u4EF6\n *\n * @description \u7528\u4E8E\u663E\u793A\u5012\u8BA1\u65F6\u7684\u7EC4\u4EF6\uFF0C\u652F\u6301\u5929\u3001\u65F6\u3001\u5206\u3001\u79D2\u663E\u793A\uFF0C\u652F\u6301\u591A\u79CD\u6837\u5F0F\u53D8\u4F53\u548C\u5C3A\u5BF8\n */\nconst Countdown = React.forwardRef<HTMLDivElement, CountdownProps>(\n (\n {\n className,\n endDate,\n endDate_tz,\n locale,\n timeLabels,\n dateFormat,\n onExpire,\n separator = ':',\n hideWhenExpired = true,\n variant,\n ...props\n },\n ref\n ) => {\n // \u786E\u5B9A\u6700\u7EC8\u4F7F\u7528\u7684\u65F6\u95F4\u6807\u7B7E\n const finalTimeLabels = useMemo(() => {\n if (timeLabels) return timeLabels\n if (dateFormat) return safeStringToObject(dateFormat)\n return getDefaultTimeLabels()\n }, [timeLabels, dateFormat])\n\n // \u89E3\u6790\u76EE\u6807\u65F6\u95F4\n const targetMsRef = useRef<number>(Date.parse(endDate))\n const [remainingMs, setRemainingMs] = useState<number>(() => {\n const t = targetMsRef.current\n return isNaN(t) ? 0 : Math.max(0, t - Date.now())\n })\n\n // \u5224\u65AD\u662F\u5426\u5DF2\u8FC7\u671F\n const [isExpired, setIsExpired] = useState<boolean>(() => {\n const t = targetMsRef.current\n return !isNaN(t) && t <= Date.now()\n })\n\n // \u5F53endDate\u6539\u53D8\u65F6\u66F4\u65B0\u76EE\u6807\u65F6\u95F4\n useEffect(() => {\n targetMsRef.current = Date.parse(endDate)\n const t = targetMsRef.current\n const newRemaining = isNaN(t) ? 0 : Math.max(0, t - Date.now())\n const newIsExpired = !isNaN(t) && t <= Date.now()\n\n setRemainingMs(newRemaining)\n setIsExpired(newIsExpired)\n }, [endDate])\n\n // \u542F\u52A8\u5012\u8BA1\u65F6\u5B9A\u65F6\u5668\n useEffect(() => {\n if (isExpired) return // \u5DF2\u8FC7\u671F\u5219\u4E0D\u542F\u52A8\n if (isNaN(targetMsRef.current)) return // \u65E0\u6548\u65E5\u671F\u4E0D\u542F\u52A8\n\n let expiredCalled = false\n const tick = () => {\n const now = Date.now()\n const remaining = Math.max(0, targetMsRef.current - now)\n setRemainingMs(remaining)\n\n if (remaining <= 0 && !expiredCalled) {\n expiredCalled = true\n setIsExpired(true)\n onExpire?.()\n }\n }\n\n tick() // \u7ACB\u5373\u6267\u884C\u4E00\u6B21\n const intervalId = window.setInterval(tick, 1000)\n\n return () => clearInterval(intervalId)\n }, [onExpire, isExpired, endDate])\n\n // \u8BA1\u7B97\u65F6\u95F4\u5355\u4F4D\n const totalSeconds = Math.floor(remainingMs / 1000)\n const seconds = totalSeconds % 60\n const totalMinutes = Math.floor(totalSeconds / 60)\n const minutes = totalMinutes % 60\n const totalHours = Math.floor(totalMinutes / 60)\n const hours = totalHours % 24\n const days = Math.floor(totalHours / 24)\n\n // \u5982\u679C\u5DF2\u8FC7\u671F\u4E14\u9700\u8981\u9690\u85CF\uFF0C\u5219\u8FD4\u56DEnull\n if (isExpired && hideWhenExpired) {\n return null\n }\n\n return (\n <div\n ref={ref}\n className={cn(countdownVariants({ variant }), className)}\n role=\"timer\"\n aria-live=\"polite\"\n aria-label=\"countdown timer\"\n {...props}\n >\n {/* \u5929 */}\n <div className={cn(timeBlockVariants({ variant }), 'time-days-box')}>\n <div className={timeNumberVariants()}>{pad(days, 2)}</div>\n <div className=\"truncate text-center text-[12px] font-bold\">{finalTimeLabels.day}</div>\n </div>\n\n <div className={separatorVariants({ variant })}>{separator}</div>\n\n {/* \u65F6 */}\n <div className={cn(timeBlockVariants({ variant }), 'time-hours-box')}>\n <div className={timeNumberVariants()}>{pad(hours, 2)}</div>\n <div className=\"truncate text-center text-[12px] font-bold\">{finalTimeLabels.hour}</div>\n </div>\n\n <div className={separatorVariants({ variant })}>{separator}</div>\n\n {/* \u5206 */}\n <div className={cn(timeBlockVariants({ variant }), 'time-minutes-box')}>\n <div className={timeNumberVariants()}>{pad(minutes, 2)}</div>\n <div className=\"truncate text-center text-[12px] font-bold\">{finalTimeLabels.minute}</div>\n </div>\n\n <div className={separatorVariants({ variant })}>{separator}</div>\n\n {/* \u79D2 */}\n <div className={cn(timeBlockVariants({ variant }), 'time-seconds-box')}>\n <div className={timeNumberVariants()}>{pad(seconds, 2)}</div>\n <div className=\"truncate text-center text-[12px] font-bold\">{finalTimeLabels.second}</div>\n </div>\n </div>\n )\n }\n)\n\nCountdown.displayName = 'Countdown'\n\nexport default Countdown\n"],
|
|
5
|
-
"mappings": "ukBAAA,IAAAA,
|
|
6
|
-
"names": ["Countdown_exports", "__export", "Countdown_default", "__toCommonJS", "import_jsx_runtime", "import_react", "import_class_variance_authority", "import_helpers", "countdownVariants", "timeBlockVariants", "timeNumberVariants", "separatorVariants", "pad", "n", "len", "getDefaultTimeLabels", "safeStringToObject", "str", "jsonStr", "Countdown", "React", "className", "endDate", "endDate_tz", "locale", "timeLabels", "dateFormat", "onExpire", "separator", "hideWhenExpired", "variant", "props", "ref", "finalTimeLabels", "targetMsRef", "remainingMs", "setRemainingMs", "t", "isExpired", "setIsExpired", "newRemaining", "newIsExpired", "expiredCalled", "tick", "now", "remaining", "intervalId", "totalSeconds", "seconds", "totalMinutes", "minutes", "totalHours", "hours", "days"]
|
|
4
|
+
"sourcesContent": ["'use client'\n\nimport React, { useEffect, useRef, useState, useMemo } from 'react'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { cn } from '../helpers/index.js'\n\n// \u5B9A\u4E49\u6837\u5F0F\u53D8\u4F53\nconst countdownVariants = cva(\n // \u57FA\u7840\u6837\u5F0F\uFF1A\u5012\u8BA1\u65F6\u5BB9\u5668\n 'countdown-container flex w-full items-center',\n {\n variants: {\n variant: {\n outline: 'gap-1',\n spacious: 'gap-1',\n },\n align: {\n left: 'justify-start',\n center: 'justify-center',\n },\n },\n defaultVariants: {\n variant: 'outline',\n align: 'left',\n },\n }\n)\n\nconst timeBlockVariants = cva(\n // \u57FA\u7840\u6837\u5F0F\uFF1A\u65F6\u95F4\u5757\n 'time-block border-box rounded-box-small flex flex-col items-center justify-center overflow-hidden text-center text-xs',\n {\n variants: {\n variant: {\n outline:\n 'border-info-primary text-info-primary desktop:size-12 desktop:p-1 size-10 border bg-transparent p-[2px]',\n spacious: 'bg-info-white text-info-primary desktop:size-12 desktop:p-1 size-10 p-[2px]',\n },\n },\n defaultVariants: {\n variant: 'outline',\n },\n }\n)\n\nconst timeNumberVariants = cva(\n 'time-number lg-desktop:text-[24px] desktop:leading-[120%] translate-y-[2px] whitespace-nowrap text-center text-[20px] font-bold leading-none'\n)\n\nconst separatorVariants = cva(\n // \u57FA\u7840\u6837\u5F0F\uFF1A\u5206\u9694\u7B26\n 'separator desktop:text-2xl text-xl font-bold',\n {\n variants: {\n variant: {\n outline: 'text-info-primary',\n spacious: 'text-info-primary',\n },\n },\n defaultVariants: {\n variant: 'outline',\n },\n }\n)\n\n/**\n * \u65F6\u95F4\u6807\u7B7E\u914D\u7F6E\u63A5\u53E3\n */\nexport interface TimeLabels {\n /** \u5929\u7684\u6807\u7B7E */\n day: string\n /** \u5C0F\u65F6\u7684\u6807\u7B7E */\n hour: string\n /** \u5206\u949F\u7684\u6807\u7B7E */\n minute: string\n /** \u79D2\u7684\u6807\u7B7E */\n second: string\n}\n\n/**\n * \u5012\u8BA1\u65F6\u7EC4\u4EF6Props\u63A5\u53E3\n */\nexport interface CountdownProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onExpire'>, VariantProps<typeof countdownVariants> {\n /** \u7ED3\u675F\u65F6\u95F4 - ISO\u683C\u5F0F\u5B57\u7B26\u4E32 */\n endDate: string\n /** \u7ED3\u675F\u65F6\u95F4\u65F6\u533A\uFF0C\u5982: America/Los_Angeles */\n endDate_tz?: string\n /** \u683C\u5F0F\u5316\u7528\u7684locale\uFF0C\u9ED8\u8BA4\u4F7F\u7528navigator.language */\n locale?: string\n /** \u65F6\u95F4\u6807\u7B7E\u914D\u7F6E\uFF0C\u7528\u4E8E\u56FD\u9645\u5316 */\n timeLabels?: TimeLabels\n /** JSON\u5B57\u7B26\u4E32\u683C\u5F0F\u7684\u65F6\u95F4\u6807\u7B7E\uFF08\u5411\u540E\u517C\u5BB9\uFF09 */\n dateFormat?: string\n /** \u5012\u8BA1\u65F6\u7ED3\u675F\u56DE\u8C03 */\n onExpire?: () => void\n /** \u5206\u9694\u7B26\u5B57\u7B26\uFF0C\u9ED8\u8BA4\u4E3A ':' */\n separator?: string\n /** \u9690\u85CF\u5DF2\u8FC7\u671F\u7684\u5012\u8BA1\u65F6\uFF0C\u9ED8\u8BA4\u4E3A true */\n hideWhenExpired?: boolean\n}\n\n/**\n * \u6570\u5B57\u8865\u96F6\u51FD\u6570\n */\nconst pad = (n: number, len = 2) => String(Math.abs(n)).padStart(len, '0')\n\n/**\n * \u9ED8\u8BA4\u65F6\u95F4\u6807\u7B7E\n */\nconst getDefaultTimeLabels = (): TimeLabels => ({\n day: 'Day',\n hour: 'Hours',\n minute: 'Mins',\n second: 'Secs',\n})\n\n/**\n * \u89E3\u6790dateFormat JSON\u5B57\u7B26\u4E32\uFF08\u5411\u540E\u517C\u5BB9\uFF09\n */\nconst safeStringToObject = (str: string): TimeLabels => {\n try {\n let jsonStr = str?.trim?.()\n if (!jsonStr?.startsWith?.('{') || !jsonStr?.endsWith?.('}')) {\n return getDefaultTimeLabels()\n }\n jsonStr = jsonStr?.replace?.(/(\\w+)\\s*:/g, '\"$1\":')\n return { ...getDefaultTimeLabels(), ...JSON.parse(jsonStr) }\n } catch (err) {\n return getDefaultTimeLabels()\n }\n}\n\n/**\n * Countdown - \u5012\u8BA1\u65F6\u539F\u5B50\u7EC4\u4EF6\n *\n * @description \u7528\u4E8E\u663E\u793A\u5012\u8BA1\u65F6\u7684\u7EC4\u4EF6\uFF0C\u652F\u6301\u5929\u3001\u65F6\u3001\u5206\u3001\u79D2\u663E\u793A\uFF0C\u652F\u6301\u591A\u79CD\u6837\u5F0F\u53D8\u4F53\u548C\u5C3A\u5BF8\n */\nconst Countdown = React.forwardRef<HTMLDivElement, CountdownProps>(\n (\n {\n className,\n endDate,\n endDate_tz,\n locale,\n timeLabels,\n dateFormat,\n onExpire,\n separator = ':',\n hideWhenExpired = true,\n variant,\n align,\n ...props\n },\n ref\n ) => {\n // \u786E\u5B9A\u6700\u7EC8\u4F7F\u7528\u7684\u65F6\u95F4\u6807\u7B7E\n const finalTimeLabels = useMemo(() => {\n if (timeLabels) return timeLabels\n if (dateFormat) return safeStringToObject(dateFormat)\n return getDefaultTimeLabels()\n }, [timeLabels, dateFormat])\n\n // \u89E3\u6790\u76EE\u6807\u65F6\u95F4\n const targetMsRef = useRef<number>(Date.parse(endDate))\n const [remainingMs, setRemainingMs] = useState<number>(() => {\n const t = targetMsRef.current\n return isNaN(t) ? 0 : Math.max(0, t - Date.now())\n })\n\n // \u5224\u65AD\u662F\u5426\u5DF2\u8FC7\u671F\n const [isExpired, setIsExpired] = useState<boolean>(() => {\n const t = targetMsRef.current\n return !isNaN(t) && t <= Date.now()\n })\n\n // \u5F53endDate\u6539\u53D8\u65F6\u66F4\u65B0\u76EE\u6807\u65F6\u95F4\n useEffect(() => {\n targetMsRef.current = Date.parse(endDate)\n const t = targetMsRef.current\n const newRemaining = isNaN(t) ? 0 : Math.max(0, t - Date.now())\n const newIsExpired = !isNaN(t) && t <= Date.now()\n\n setRemainingMs(newRemaining)\n setIsExpired(newIsExpired)\n }, [endDate])\n\n // \u542F\u52A8\u5012\u8BA1\u65F6\u5B9A\u65F6\u5668\n useEffect(() => {\n if (isExpired) return // \u5DF2\u8FC7\u671F\u5219\u4E0D\u542F\u52A8\n if (isNaN(targetMsRef.current)) return // \u65E0\u6548\u65E5\u671F\u4E0D\u542F\u52A8\n\n let expiredCalled = false\n const tick = () => {\n const now = Date.now()\n const remaining = Math.max(0, targetMsRef.current - now)\n setRemainingMs(remaining)\n\n if (remaining <= 0 && !expiredCalled) {\n expiredCalled = true\n setIsExpired(true)\n onExpire?.()\n }\n }\n\n tick() // \u7ACB\u5373\u6267\u884C\u4E00\u6B21\n const intervalId = window.setInterval(tick, 1000)\n\n return () => clearInterval(intervalId)\n }, [onExpire, isExpired, endDate])\n\n // \u8BA1\u7B97\u65F6\u95F4\u5355\u4F4D\n const totalSeconds = Math.floor(remainingMs / 1000)\n const seconds = totalSeconds % 60\n const totalMinutes = Math.floor(totalSeconds / 60)\n const minutes = totalMinutes % 60\n const totalHours = Math.floor(totalMinutes / 60)\n const hours = totalHours % 24\n const days = Math.floor(totalHours / 24)\n\n // \u5982\u679C\u5DF2\u8FC7\u671F\u4E14\u9700\u8981\u9690\u85CF\uFF0C\u5219\u8FD4\u56DEnull\n if (isExpired && hideWhenExpired) {\n return null\n }\n\n return (\n <div\n ref={ref}\n className={cn(countdownVariants({ variant, align }), className)}\n role=\"timer\"\n aria-live=\"polite\"\n aria-label=\"countdown timer\"\n {...props}\n >\n {/* \u5929 */}\n <div className={cn(timeBlockVariants({ variant }), 'time-days-box')}>\n <div className={timeNumberVariants()}>{pad(days, 2)}</div>\n <div className=\"truncate text-center text-[12px] font-bold\">{finalTimeLabels.day}</div>\n </div>\n\n <div className={separatorVariants({ variant })}>{separator}</div>\n\n {/* \u65F6 */}\n <div className={cn(timeBlockVariants({ variant }), 'time-hours-box')}>\n <div className={timeNumberVariants()}>{pad(hours, 2)}</div>\n <div className=\"truncate text-center text-[12px] font-bold\">{finalTimeLabels.hour}</div>\n </div>\n\n <div className={separatorVariants({ variant })}>{separator}</div>\n\n {/* \u5206 */}\n <div className={cn(timeBlockVariants({ variant }), 'time-minutes-box')}>\n <div className={timeNumberVariants()}>{pad(minutes, 2)}</div>\n <div className=\"truncate text-center text-[12px] font-bold\">{finalTimeLabels.minute}</div>\n </div>\n\n <div className={separatorVariants({ variant })}>{separator}</div>\n\n {/* \u79D2 */}\n <div className={cn(timeBlockVariants({ variant }), 'time-seconds-box')}>\n <div className={timeNumberVariants()}>{pad(seconds, 2)}</div>\n <div className=\"truncate text-center text-[12px] font-bold\">{finalTimeLabels.second}</div>\n </div>\n </div>\n )\n }\n)\n\nCountdown.displayName = 'Countdown'\n\nexport default Countdown\n"],
|
|
5
|
+
"mappings": "ukBAAA,IAAAA,GAAA,GAAAC,EAAAD,GAAA,aAAAE,IAAA,eAAAC,EAAAH,IA2OQ,IAAAI,EAAA,6BAzORC,EAA4D,oBAC5DC,EAAuC,oCACvCC,EAAmB,+BAGnB,MAAMC,KAAoB,OAExB,+CACA,CACE,SAAU,CACR,QAAS,CACP,QAAS,QACT,SAAU,OACZ,EACA,MAAO,CACL,KAAM,gBACN,OAAQ,gBACV,CACF,EACA,gBAAiB,CACf,QAAS,UACT,MAAO,MACT,CACF,CACF,EAEMC,KAAoB,OAExB,wHACA,CACE,SAAU,CACR,QAAS,CACP,QACE,0GACF,SAAU,6EACZ,CACF,EACA,gBAAiB,CACf,QAAS,SACX,CACF,CACF,EAEMC,KAAqB,OACzB,8IACF,EAEMC,KAAoB,OAExB,+CACA,CACE,SAAU,CACR,QAAS,CACP,QAAS,oBACT,SAAU,mBACZ,CACF,EACA,gBAAiB,CACf,QAAS,SACX,CACF,CACF,EA0CMC,EAAM,CAACC,EAAWC,EAAM,IAAM,OAAO,KAAK,IAAID,CAAC,CAAC,EAAE,SAASC,EAAK,GAAG,EAKnEC,EAAuB,KAAmB,CAC9C,IAAK,MACL,KAAM,QACN,OAAQ,OACR,OAAQ,MACV,GAKMC,EAAsBC,GAA4B,CACtD,GAAI,CACF,IAAIC,EAAUD,GAAK,OAAO,EAC1B,MAAI,CAACC,GAAS,aAAa,GAAG,GAAK,CAACA,GAAS,WAAW,GAAG,EAClDH,EAAqB,GAE9BG,EAAUA,GAAS,UAAU,aAAc,OAAO,EAC3C,CAAE,GAAGH,EAAqB,EAAG,GAAG,KAAK,MAAMG,CAAO,CAAE,EAC7D,MAAc,CACZ,OAAOH,EAAqB,CAC9B,CACF,EAOMI,EAAY,EAAAC,QAAM,WACtB,CACE,CACE,UAAAC,EACA,QAAAC,EACA,WAAAC,EACA,OAAAC,EACA,WAAAC,EACA,WAAAC,EACA,SAAAC,EACA,UAAAC,EAAY,IACZ,gBAAAC,EAAkB,GAClB,QAAAC,EACA,MAAAC,EACA,GAAGC,CACL,EACAC,IACG,CAEH,MAAMC,KAAkB,WAAQ,IAC1BT,IACAC,EAAmBV,EAAmBU,CAAU,EAC7CX,EAAqB,GAC3B,CAACU,EAAYC,CAAU,CAAC,EAGrBS,KAAc,UAAe,KAAK,MAAMb,CAAO,CAAC,EAChD,CAACc,EAAaC,CAAc,KAAI,YAAiB,IAAM,CAC3D,MAAMC,EAAIH,EAAY,QACtB,OAAO,MAAMG,CAAC,EAAI,EAAI,KAAK,IAAI,EAAGA,EAAI,KAAK,IAAI,CAAC,CAClD,CAAC,EAGK,CAACC,EAAWC,CAAY,KAAI,YAAkB,IAAM,CACxD,MAAMF,EAAIH,EAAY,QACtB,MAAO,CAAC,MAAMG,CAAC,GAAKA,GAAK,KAAK,IAAI,CACpC,CAAC,KAGD,aAAU,IAAM,CACdH,EAAY,QAAU,KAAK,MAAMb,CAAO,EACxC,MAAMgB,EAAIH,EAAY,QAChBM,EAAe,MAAMH,CAAC,EAAI,EAAI,KAAK,IAAI,EAAGA,EAAI,KAAK,IAAI,CAAC,EACxDI,EAAe,CAAC,MAAMJ,CAAC,GAAKA,GAAK,KAAK,IAAI,EAEhDD,EAAeI,CAAY,EAC3BD,EAAaE,CAAY,CAC3B,EAAG,CAACpB,CAAO,CAAC,KAGZ,aAAU,IAAM,CAEd,GADIiB,GACA,MAAMJ,EAAY,OAAO,EAAG,OAEhC,IAAIQ,EAAgB,GACpB,MAAMC,EAAO,IAAM,CACjB,MAAMC,EAAM,KAAK,IAAI,EACfC,EAAY,KAAK,IAAI,EAAGX,EAAY,QAAUU,CAAG,EACvDR,EAAeS,CAAS,EAEpBA,GAAa,GAAK,CAACH,IACrBA,EAAgB,GAChBH,EAAa,EAAI,EACjBb,IAAW,EAEf,EAEAiB,EAAK,EACL,MAAMG,EAAa,OAAO,YAAYH,EAAM,GAAI,EAEhD,MAAO,IAAM,cAAcG,CAAU,CACvC,EAAG,CAACpB,EAAUY,EAAWjB,CAAO,CAAC,EAGjC,MAAM0B,EAAe,KAAK,MAAMZ,EAAc,GAAI,EAC5Ca,EAAUD,EAAe,GACzBE,EAAe,KAAK,MAAMF,EAAe,EAAE,EAC3CG,EAAUD,EAAe,GACzBE,EAAa,KAAK,MAAMF,EAAe,EAAE,EACzCG,EAAQD,EAAa,GACrBE,EAAO,KAAK,MAAMF,EAAa,EAAE,EAGvC,OAAIb,GAAaV,EACR,QAIP,QAAC,OACC,IAAKI,EACL,aAAW,MAAGzB,EAAkB,CAAE,QAAAsB,EAAS,MAAAC,CAAM,CAAC,EAAGV,CAAS,EAC9D,KAAK,QACL,YAAU,SACV,aAAW,kBACV,GAAGW,EAGJ,qBAAC,OAAI,aAAW,MAAGvB,EAAkB,CAAE,QAAAqB,CAAQ,CAAC,EAAG,eAAe,EAChE,oBAAC,OAAI,UAAWpB,EAAmB,EAAI,SAAAE,EAAI0C,EAAM,CAAC,EAAE,KACpD,OAAC,OAAI,UAAU,6CAA8C,SAAApB,EAAgB,IAAI,GACnF,KAEA,OAAC,OAAI,UAAWvB,EAAkB,CAAE,QAAAmB,CAAQ,CAAC,EAAI,SAAAF,EAAU,KAG3D,QAAC,OAAI,aAAW,MAAGnB,EAAkB,CAAE,QAAAqB,CAAQ,CAAC,EAAG,gBAAgB,EACjE,oBAAC,OAAI,UAAWpB,EAAmB,EAAI,SAAAE,EAAIyC,EAAO,CAAC,EAAE,KACrD,OAAC,OAAI,UAAU,6CAA8C,SAAAnB,EAAgB,KAAK,GACpF,KAEA,OAAC,OAAI,UAAWvB,EAAkB,CAAE,QAAAmB,CAAQ,CAAC,EAAI,SAAAF,EAAU,KAG3D,QAAC,OAAI,aAAW,MAAGnB,EAAkB,CAAE,QAAAqB,CAAQ,CAAC,EAAG,kBAAkB,EACnE,oBAAC,OAAI,UAAWpB,EAAmB,EAAI,SAAAE,EAAIuC,EAAS,CAAC,EAAE,KACvD,OAAC,OAAI,UAAU,6CAA8C,SAAAjB,EAAgB,OAAO,GACtF,KAEA,OAAC,OAAI,UAAWvB,EAAkB,CAAE,QAAAmB,CAAQ,CAAC,EAAI,SAAAF,EAAU,KAG3D,QAAC,OAAI,aAAW,MAAGnB,EAAkB,CAAE,QAAAqB,CAAQ,CAAC,EAAG,kBAAkB,EACnE,oBAAC,OAAI,UAAWpB,EAAmB,EAAI,SAAAE,EAAIqC,EAAS,CAAC,EAAE,KACvD,OAAC,OAAI,UAAU,6CAA8C,SAAAf,EAAgB,OAAO,GACtF,GACF,CAEJ,CACF,EAEAf,EAAU,YAAc,YAExB,IAAOjB,EAAQiB",
|
|
6
|
+
"names": ["Countdown_exports", "__export", "Countdown_default", "__toCommonJS", "import_jsx_runtime", "import_react", "import_class_variance_authority", "import_helpers", "countdownVariants", "timeBlockVariants", "timeNumberVariants", "separatorVariants", "pad", "n", "len", "getDefaultTimeLabels", "safeStringToObject", "str", "jsonStr", "Countdown", "React", "className", "endDate", "endDate_tz", "locale", "timeLabels", "dateFormat", "onExpire", "separator", "hideWhenExpired", "variant", "align", "props", "ref", "finalTimeLabels", "targetMsRef", "remainingMs", "setRemainingMs", "t", "isExpired", "setIsExpired", "newRemaining", "newIsExpired", "expiredCalled", "tick", "now", "remaining", "intervalId", "totalSeconds", "seconds", "totalMinutes", "minutes", "totalHours", "hours", "days"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import{jsx as e,jsxs as c}from"react/jsx-runtime";import
|
|
1
|
+
"use client";import{jsx as e,jsxs as c}from"react/jsx-runtime";import A,{useImperativeHandle as ne,useRef as b,useState as ie,useEffect as pe}from"react";import y from"gsap";import{ScrollTrigger as v}from"gsap/dist/ScrollTrigger";import{useMediaQuery as Q}from"react-responsive";import{useInView as ce}from"react-intersection-observer";import ue from"../../helpers/ScrollLoadVideo.js";import{Button as C,Heading as me,Picture as Z,Text as P,Countdown as de}from"../../components/index.js";import{cn as s}from"../../helpers/index.js";import{cva as w}from"class-variance-authority";import{withLayout as ge}from"../../shared/Styles.js";import{useExposure as fe}from"../../hooks/useExposure.js";import{trackUrlRef as S}from"../../shared/trackUrlRef.js";import{sizeMap as be}from"../../components/button.js";import{VideoModal as xe}from"../VideoModal/index.js";const n="image",i="hero_banner",he=w("hero-banner-content laptop:top-1/2 laptop:-translate-y-1/2 lg-desktop:gap-[32px] absolute top-24 z-10 flex w-full flex-col gap-[24px]",{variants:{align:{left:"tablet:px-[32px] laptop:px-[64px] lg-desktop:px-[calc(50%-832px)] left-0 px-[16px]",center:"left-1/2 -translate-x-1/2 items-center text-center"}},defaultVariants:{align:"left"}}),ye=w("hero-banner-wrap-text lg-desktop:max-w-[824px] desktop:max-w-[648px] laptop:max-w-[440px] tablet:max-w-[704px] max-w-[358px]",{variants:{align:{left:"laptop:text-left",center:"text-center"}},defaultVariants:{align:"left"}}),ve=w("hero-banner-button-group lg-desktop:gap-3 flex items-center gap-2",{variants:{align:{left:"laptop:justify-start",center:"justify-center"}},defaultVariants:{align:"left"}}),we=w("hero-banner-icon-group flex items-center gap-2",{variants:{align:{left:"justify-start",center:"justify-center"}},defaultVariants:{align:"left"}}),ke=({size:u="base"})=>{const{width:k,height:x}=be[u];return e("svg",{width:k,height:x,viewBox:"0 0 20 20",fill:"currentcolor",xmlns:"http://www.w3.org/2000/svg",children:e("path",{d:"M13.9599 9.30662C14.4547 9.63647 14.4547 10.3635 13.9599 10.6934L6.29558 15.8029C5.74179 16.1721 5 15.7751 5 15.1096V4.89042C5 4.22484 5.74179 3.82785 6.29558 4.19705L13.9599 9.30662Z",fill:"currentcolor"})})},J=A.forwardRef(({data:u,className:k,classNames:x={},onSecondaryClick:K,onPrimaryClick:O},W)=>{const{label:R,title:r,subtitle:o,endDate:L,endDate_tz:X,dateFormat:Y,pcImage:N,padImage:M,mobileImage:h,pcVideo:ee,padVideo:te,mobileVideo:D,isShowVideo:ae,isVideoLoop:re=!0,primaryButton:l,secondaryButton:t,theme:oe="light",size:$="default",titleSize:B,caption:V=[],blockLink:E,iconArray:le,align:m="center"}=u,j=Q({query:"(max-width: 768px)"}),U=Q({query:"(max-width: 1024px)"}),[_,G]=ie(!1),{ref:se,inView:F}=ce(),z=b(null),H=b(null),T=b(null),d=b(null),p=b(null);return fe(p,{componentType:n,componentName:i,componentTitle:r,componentDescription:o}),ne(W,()=>p.current),pe(()=>{y.registerPlugin(v);function a(){if(!d.current)return;const I=p.current?.clientHeight||100;window.innerHeight<=I?z.current=v.create({trigger:p.current,start:"top bottom",end:"bottom top",scrub:!0,onUpdate:g=>{const f=g.progress*40-20;y.set(d.current,{yPercent:f})}}):(T.current=v.create({trigger:p.current,start:"top bottom",end:"bottom bottom",scrub:!0,onUpdate:g=>{const f=g.progress*20-20;y.set(d.current,{yPercent:f})}}),H.current=v.create({trigger:p.current,start:"top top",end:"bottom top",scrub:!0,onUpdate:g=>{const f=g.progress*20;y.set(d.current,{yPercent:f})}}))}return F&&a(),()=>{z.current&&z.current.kill(),T.current&&T.current.kill(),H.current&&H.current.kill()}},[F]),e("div",{ref:se,"data-ui-component-id":"HeroBanner",children:c("div",{ref:p,className:s(oe==="dark"?"aiui-dark":"","text-info-primary relative w-full overflow-hidden",{"lg-desktop:aspect-[1920/930] desktop:aspect-[1440/700] laptop:aspect-[1024/520] tablet:aspect-[768/660] aspect-[390/660]":$==="default","lg-desktop:aspect-[1920/800] desktop:aspect-[1440/640] laptop:aspect-[1024/480] tablet:aspect-[768/560] aspect-[390/560]":$==="sm"},k),children:[E&&e("a",{className:"absolute inset-0 z-10",href:S(E,`${n}_${i}`),"data-headless-type-name":`${n}#${i}`,"data-headless-title-desc-button":`${r}#${o}`,tabIndex:-1,"aria-hidden":"true","aria-label":r}),e("div",{ref:d,className:s("absolute left-0 top-0 size-full"),children:ae?e(ue,{poster:j?h?.url:U?M?.url||h?.url:N?.url,src:j?D?.url:U?te?.url||D?.url:ee?.url,className:"laptop:w-full h-full",videoClassName:"h-full object-cover",muted:!0,loop:re,playsInline:!0}):e(Z,{className:"laptop:w-full h-full",imgClassName:"h-full object-cover",loading:"eager",fetchPriority:"high",alt:N?.alt||"",source:`${N?.url||""} , ${M?.url??(h?.url||"")} 1024, ${h?.url||""} 767`})}),c("div",{className:he({align:m}),children:[c("div",{className:ye({align:m}),children:[R&&e(P,{size:2,as:"p",className:s("hero-banner-label font-heading lg-desktop:text-[18px] desktop:text-base text-sm"),html:R}),r&&e(me,{as:B==="4"?"h1":"h2",html:r,className:s("hero-banner-title",x.title),size:B?Number(B||"5"):$==="sm"?4:5}),o&&e(P,{as:"p",size:2,className:s("hero-banner-subtitle font-heading lg-desktop:text-[18px] desktop:text-base laptop:mt-2 lg-desktop:mt-4 mt-1 text-sm"),html:o}),L&&e("div",{className:"mt-3",children:e(de,{endDate:L,endDate_tz:X,dateFormat:Y,variant:"spacious",align:m})})]}),c("div",{className:ve({align:m}),children:[t?.isShowPlayVideoButton&&t?.playVideoButtonText?c(C,{onClick:()=>G(!0),size:"lg",variant:"secondary",className:"hero-banner-play-video-button","data-headless-type-name":`${n}#${i}`,"data-headless-title-desc-button":`${r}#${o}#${t?.playVideoButtonText}`,children:[t?.playVideoButtonText," ",e(ke,{size:"lg"})]}):t?.text?c(C,{"aria-label":r??o,size:"lg",variant:"secondary",className:"hero-banner-secondary-button",as:t?.isCustomSecondaryButton?"button":"a",href:S(t?.link,`${n}_${i}`),onClick:a=>t?.isCustomSecondaryButton&&K?.(u,a,t?.customSecondaryEventId),"data-headless-type-name":`${n}#${i}`,"data-headless-title-desc-button":`${r}#${o}#${t?.text}`,children:[t?.text,e("span",{className:"sr-only",children:r??o})]}):null,l&&l.text&&e(C,{"aria-label":r??o,size:"lg",variant:"primary",className:"hero-banner-primary-button",as:l?.isCustomPrimaryButton?"button":"a",href:S(l.link,`${n}_${i}`),onClick:a=>l?.isCustomPrimaryButton&&O?.(u,a,l?.customPrimaryEventId),"data-headless-type-name":`${n}#${i}`,"data-headless-title-desc-button":`${r}#${o}#${l?.text}`,children:l.text})]}),e("div",{className:we({align:m}),children:le?.map(a=>e("div",{className:"h-12",children:e(Z,{className:"laptop:w-full h-full",imgClassName:"h-full object-cover",loading:"eager",alt:a?.pcImage?.alt||"",source:a?.pcImage?.url})},a?.pcImage?.url||a?.pcImage?.alt))})]}),V.length>0&&e("div",{className:s("hero-banner-caption-group laptop:gap-3 tablet:px-[32px] laptop:px-[64px] lg-desktop:px-[calc(50%-832px)] desktop:pb-[24px] absolute bottom-0 z-10 flex items-stretch gap-2 px-[16px] pb-[16px]",x.captionGroup),children:V.map((a,I)=>c(A.Fragment,{children:[e(P,{size:2,className:s("hero-banner-product-text tablet:w-[108px] loptop:w-[150px] desktop:w-[156px] lg-desktop:w-[180px] laptop:text-[14px] flex-1 text-[12px]"),html:a.title}),I<V.length-1&&e("div",{className:s("bg-info-primary w-px")})]},a.title))}),_&&e(xe,{visible:_,videoUrl:t?.videoUrl?.url,youTubeId:t?.youtubeId,onCloseModal:()=>G(!1)})]})})});J.displayName="HeroBanner";var Ee=ge(J);export{Ee as default};
|
|
2
2
|
//# sourceMappingURL=HeroBanner.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/biz-components/HeroBanner/HeroBanner.tsx"],
|
|
4
|
-
"sourcesContent": ["'use client'\nimport React, { useImperativeHandle, useRef, useState, useEffect } from 'react'\nimport gsap from 'gsap'\nimport { ScrollTrigger } from 'gsap/dist/ScrollTrigger'\nimport type { HeroBannerProps } from './types.js'\nimport { useMediaQuery } from 'react-responsive'\nimport { useInView } from 'react-intersection-observer'\nimport ScrollLoadVideo from '../../helpers/ScrollLoadVideo.js'\nimport { Button, Heading, Picture, Text, Countdown } from '../../components/index.js'\nimport { cn } from '../../helpers/index.js'\nimport { withLayout } from '../../shared/Styles.js'\nimport { useExposure } from '../../hooks/useExposure.js'\nimport { trackUrlRef } from '../../shared/trackUrlRef.js'\nimport { sizeMap } from '../../components/button.js'\nimport { VideoModal } from '../VideoModal/index.js'\n\nconst componentType = 'image'\nconst componentName = 'hero_banner'\n\nexport type HeroBannerSemanticName =\n | 'root'\n | 'title'\n | 'subtitle'\n | 'buttonGroup'\n | 'primaryButton'\n | 'secondaryButton'\n | 'captionGroup'\n\nconst PlayButtonAppendIcon = ({ size = 'base' }: { size: 'base' | 'lg' | 'sm' }) => {\n const { width, height } = sizeMap[size]\n return (\n <svg width={width} height={height} viewBox=\"0 0 20 20\" fill=\"currentcolor\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M13.9599 9.30662C14.4547 9.63647 14.4547 10.3635 13.9599 10.6934L6.29558 15.8029C5.74179 16.1721 5 15.7751 5 15.1096V4.89042C5 4.22484 5.74179 3.82785 6.29558 4.19705L13.9599 9.30662Z\"\n fill=\"currentcolor\"\n />\n </svg>\n )\n}\n\nconst HeroBanner = React.forwardRef<\n HTMLDivElement,\n HeroBannerProps & {\n classNames?: Partial<Record<HeroBannerSemanticName, string>>\n }\n>(({ data, className, classNames = {}, onSecondaryClick, onPrimaryClick }, ref) => {\n const {\n label,\n title,\n subtitle,\n endDate,\n endDate_tz,\n dateFormat,\n pcImage,\n padImage,\n mobileImage,\n pcVideo,\n padVideo,\n mobileVideo,\n isShowVideo,\n isVideoLoop = true,\n primaryButton,\n secondaryButton,\n theme = 'light',\n size = 'default',\n titleSize,\n caption = [],\n blockLink,\n iconArray,\n } = data\n\n const isMobile = useMediaQuery({ query: '(max-width: 768px)' })\n const isPad = useMediaQuery({ query: '(max-width: 1024px)' })\n const [visible, setVisible] = useState<boolean>(false)\n const { ref: inViewRef, inView } = useInView()\n const scrollTriggerRef = useRef<ScrollTrigger | null>(null)\n const bgTriggerRef = useRef<ScrollTrigger | null>(null)\n const boxTriggerRef = useRef<ScrollTrigger | null>(null)\n\n const bgRef = useRef<HTMLImageElement>(null)\n const boxRef = useRef<HTMLDivElement>(null)\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 useEffect(() => {\n gsap.registerPlugin(ScrollTrigger)\n function gsapResize() {\n if (!bgRef.current) return\n const clientHeight = boxRef.current?.clientHeight || 100\n const screenHeight = window.innerHeight\n\n if (screenHeight <= clientHeight) {\n scrollTriggerRef.current = ScrollTrigger.create({\n trigger: boxRef.current,\n start: 'top bottom',\n end: 'bottom top',\n scrub: true,\n onUpdate: (self: any) => {\n const base = 40\n const value = self.progress * base - base / 2\n gsap.set(bgRef.current, { yPercent: value })\n },\n })\n } else {\n boxTriggerRef.current = ScrollTrigger.create({\n trigger: boxRef.current,\n start: 'top bottom',\n end: 'bottom bottom',\n scrub: true,\n onUpdate: (self: any) => {\n const base = 20\n const value = self.progress * base - base\n gsap.set(bgRef.current, { yPercent: value })\n },\n })\n bgTriggerRef.current = ScrollTrigger.create({\n trigger: boxRef.current,\n start: 'top top',\n end: 'bottom top',\n scrub: true,\n onUpdate: (self: any) => {\n const base = 20\n const value = self.progress * base\n gsap.set(bgRef.current, { yPercent: value })\n },\n })\n }\n }\n if (inView) gsapResize()\n return () => {\n // ScrollTrigger.getAll().forEach((t: any) => t.kill())\n scrollTriggerRef.current && scrollTriggerRef.current.kill()\n boxTriggerRef.current && boxTriggerRef.current.kill()\n bgTriggerRef.current && bgTriggerRef.current.kill()\n }\n }, [inView])\n\n return (\n <div ref={inViewRef} data-ui-component-id=\"HeroBanner\">\n <div\n ref={boxRef}\n className={cn(\n theme === 'dark' ? 'aiui-dark' : '',\n 'text-info-primary relative w-full overflow-hidden',\n {\n 'lg-desktop:aspect-[1920/930] desktop:aspect-[1440/700] laptop:aspect-[1024/520] tablet:aspect-[768/660] aspect-[390/660]':\n size === 'default',\n 'lg-desktop:aspect-[1920/800] desktop:aspect-[1440/640] laptop:aspect-[1024/480] tablet:aspect-[768/560] aspect-[390/560]':\n size === 'sm',\n },\n className\n )}\n >\n {blockLink && (\n <a\n className=\"absolute inset-0 z-10\"\n href={trackUrlRef(blockLink, `${componentType}_${componentName}`)}\n data-headless-type-name={`${componentType}#${componentName}`}\n data-headless-title-desc-button={`${title}#${subtitle}`}\n tabIndex={-1}\n aria-hidden=\"true\"\n aria-label={title}\n ></a>\n )}\n <div ref={bgRef} className={cn('absolute left-0 top-0 size-full')}>\n {isShowVideo ? (\n <ScrollLoadVideo\n poster={isMobile ? mobileImage?.url : isPad ? padImage?.url || mobileImage?.url : pcImage?.url}\n src={\n isMobile\n ? (mobileVideo?.url as string)\n : isPad\n ? (padVideo?.url as string) || (mobileVideo?.url as string)\n : (pcVideo?.url as string)\n }\n className=\"laptop:w-full h-full\"\n videoClassName=\"h-full object-cover\"\n muted\n loop={isVideoLoop}\n playsInline\n />\n ) : (\n <Picture\n className=\"laptop:w-full h-full\"\n imgClassName=\"h-full object-cover\"\n loading=\"eager\"\n fetchPriority=\"high\"\n alt={pcImage?.alt || ''}\n source={`${pcImage?.url || ''} , ${padImage?.url ?? (mobileImage?.url || '')} 1024, ${mobileImage?.url || ''} 767`}\n />\n )}\n </div>\n\n {/* \u5185\u5BB9\u533A\u57DF */}\n <div className=\"hero-banner-content laptop:top-1/2 laptop:-translate-y-1/2 tablet:px-[32px] laptop:px-[64px] lg-desktop:px-[calc(50%-832px)] lg-desktop:gap-[32px] absolute top-24 z-10 flex flex-col gap-[24px] px-[16px]\">\n <div className=\"laptop:text-left hero-banner-wrap-text lg-desktop:max-w-[824px] desktop:max-w-[648px] laptop:max-w-[440px] tablet:max-w-[704px] max-w-[358px]\">\n {label && (\n <Text\n size={2}\n as=\"p\"\n className={cn('hero-banner-label font-heading lg-desktop:text-[18px] desktop:text-base text-sm')}\n html={label}\n />\n )}\n {title && (\n <Heading\n as={titleSize === '4' ? 'h1' : 'h2'}\n html={title}\n className={cn('hero-banner-title', classNames.title)}\n size={titleSize ? (Number(titleSize || '5') as any) : size === 'sm' ? 4 : 5}\n />\n )}\n {subtitle && (\n <Text\n as=\"p\"\n size={2}\n className={cn(\n 'hero-banner-subtitle font-heading lg-desktop:text-[18px] desktop:text-base laptop:mt-2 lg-desktop:mt-4 mt-1 text-sm'\n )}\n html={subtitle}\n />\n )}\n {endDate && (\n <div className=\"mt-3\">\n <Countdown endDate={endDate} endDate_tz={endDate_tz} dateFormat={dateFormat} variant=\"spacious\" />\n </div>\n )}\n </div>\n {/* \u6309\u94AE\u7EC4 */}\n <div className=\"hero-banner-button-group laptop:justify-start lg-desktop:gap-3 flex items-center gap-2\">\n {secondaryButton?.isShowPlayVideoButton && secondaryButton?.playVideoButtonText ? (\n <Button\n onClick={() => setVisible(true)}\n size=\"lg\"\n variant=\"secondary\"\n className=\"hero-banner-play-video-button\"\n data-headless-type-name={`${componentType}#${componentName}`}\n data-headless-title-desc-button={`${title}#${subtitle}#${secondaryButton?.playVideoButtonText}`}\n >\n {secondaryButton?.playVideoButtonText} <PlayButtonAppendIcon size=\"lg\" />\n </Button>\n ) : secondaryButton?.text ? (\n <Button\n aria-label={title ?? subtitle}\n size=\"lg\"\n variant=\"secondary\"\n className=\"hero-banner-secondary-button\"\n as={secondaryButton?.isCustomSecondaryButton ? 'button' : 'a'}\n href={trackUrlRef(secondaryButton?.link, `${componentType}_${componentName}`)}\n onClick={e =>\n secondaryButton?.isCustomSecondaryButton &&\n onSecondaryClick?.(data, e, secondaryButton?.customSecondaryEventId)\n }\n data-headless-type-name={`${componentType}#${componentName}`}\n data-headless-title-desc-button={`${title}#${subtitle}#${secondaryButton?.text}`}\n >\n {secondaryButton?.text}\n <span className=\"sr-only\">{title ?? subtitle}</span>\n </Button>\n ) : null}\n {primaryButton && primaryButton.text && (\n <Button\n aria-label={title ?? subtitle}\n size=\"lg\"\n variant=\"primary\"\n className=\"hero-banner-primary-button\"\n as={primaryButton?.isCustomPrimaryButton ? 'button' : 'a'}\n href={trackUrlRef(primaryButton.link, `${componentType}_${componentName}`)}\n onClick={e =>\n primaryButton?.isCustomPrimaryButton && onPrimaryClick?.(data, e, primaryButton?.customPrimaryEventId)\n }\n data-headless-type-name={`${componentType}#${componentName}`}\n data-headless-title-desc-button={`${title}#${subtitle}#${primaryButton?.text}`}\n >\n {primaryButton.text}\n </Button>\n )}\n </div>\n <div className=\"hero-banner-icon-group flex items-center gap-2\">\n {iconArray?.map(icon => (\n <div key={icon?.pcImage?.url || icon?.pcImage?.alt} className=\"h-12\">\n <Picture\n className=\"laptop:w-full h-full\"\n imgClassName=\"h-full object-cover\"\n loading=\"eager\"\n alt={icon?.pcImage?.alt || ''}\n source={icon?.pcImage?.url}\n />\n </div>\n ))}\n </div>\n </div>\n\n {/* \u5E95\u90E8\u4EA7\u54C1\u5217\u8868 */}\n {caption.length > 0 && (\n <div\n className={cn(\n 'hero-banner-caption-group laptop:gap-3 tablet:px-[32px] laptop:px-[64px] lg-desktop:px-[calc(50%-832px)] desktop:pb-[24px] absolute bottom-0 z-10 flex items-stretch gap-2 px-[16px] pb-[16px]',\n classNames.captionGroup\n )}\n >\n {caption.map((c, index) => (\n <React.Fragment key={c.title}>\n <Text\n size={2}\n className={cn(\n 'hero-banner-product-text tablet:w-[108px] loptop:w-[150px] desktop:w-[156px] lg-desktop:w-[180px] laptop:text-[14px] flex-1 text-[12px]'\n )}\n html={c.title}\n />\n {index < caption.length - 1 && <div className={cn('bg-info-primary w-px')} />}\n </React.Fragment>\n ))}\n </div>\n )}\n\n {/* \u89C6\u9891\u5F39\u7A97 */}\n {visible && (\n <VideoModal\n visible={visible}\n videoUrl={secondaryButton?.videoUrl?.url}\n youTubeId={secondaryButton?.youtubeId}\n onCloseModal={() => setVisible(false)}\n />\n )}\n </div>\n </div>\n )\n})\n\nHeroBanner.displayName = 'HeroBanner'\n\nexport default withLayout(HeroBanner)\n"],
|
|
5
|
-
"mappings": "
|
|
6
|
-
"names": ["jsx", "jsxs", "React", "useImperativeHandle", "useRef", "useState", "useEffect", "gsap", "ScrollTrigger", "useMediaQuery", "useInView", "ScrollLoadVideo", "Button", "Heading", "Picture", "Text", "Countdown", "cn", "withLayout", "useExposure", "trackUrlRef", "sizeMap", "VideoModal", "componentType", "componentName", "PlayButtonAppendIcon", "size", "width", "height", "HeroBanner", "data", "className", "classNames", "onSecondaryClick", "onPrimaryClick", "ref", "label", "title", "subtitle", "endDate", "endDate_tz", "dateFormat", "pcImage", "padImage", "mobileImage", "pcVideo", "padVideo", "mobileVideo", "isShowVideo", "isVideoLoop", "primaryButton", "secondaryButton", "theme", "titleSize", "caption", "blockLink", "iconArray", "isMobile", "isPad", "visible", "setVisible", "inViewRef", "inView", "scrollTriggerRef", "bgTriggerRef", "boxTriggerRef", "bgRef", "boxRef", "gsapResize", "clientHeight", "self", "value", "e", "icon", "c", "index", "HeroBanner_default"]
|
|
4
|
+
"sourcesContent": ["'use client'\nimport React, { useImperativeHandle, useRef, useState, useEffect } from 'react'\nimport gsap from 'gsap'\nimport { ScrollTrigger } from 'gsap/dist/ScrollTrigger'\nimport type { HeroBannerProps } from './types.js'\nimport { useMediaQuery } from 'react-responsive'\nimport { useInView } from 'react-intersection-observer'\nimport ScrollLoadVideo from '../../helpers/ScrollLoadVideo.js'\nimport { Button, Heading, Picture, Text, Countdown } from '../../components/index.js'\nimport { cn } from '../../helpers/index.js'\nimport { cva } from 'class-variance-authority'\nimport { withLayout } from '../../shared/Styles.js'\nimport { useExposure } from '../../hooks/useExposure.js'\nimport { trackUrlRef } from '../../shared/trackUrlRef.js'\nimport { sizeMap } from '../../components/button.js'\nimport { VideoModal } from '../VideoModal/index.js'\n\nconst componentType = 'image'\nconst componentName = 'hero_banner'\n\n// CVA variants for align\nconst contentVariants = cva(\n 'hero-banner-content laptop:top-1/2 laptop:-translate-y-1/2 lg-desktop:gap-[32px] absolute top-24 z-10 flex w-full flex-col gap-[24px]',\n {\n variants: {\n align: {\n left: 'tablet:px-[32px] laptop:px-[64px] lg-desktop:px-[calc(50%-832px)] left-0 px-[16px]',\n center: 'left-1/2 -translate-x-1/2 items-center text-center',\n },\n },\n defaultVariants: {\n align: 'left',\n },\n }\n)\n\nconst textVariants = cva(\n 'hero-banner-wrap-text lg-desktop:max-w-[824px] desktop:max-w-[648px] laptop:max-w-[440px] tablet:max-w-[704px] max-w-[358px]',\n {\n variants: {\n align: {\n left: 'laptop:text-left',\n center: 'text-center',\n },\n },\n defaultVariants: {\n align: 'left',\n },\n }\n)\n\nconst buttonGroupVariants = cva('hero-banner-button-group lg-desktop:gap-3 flex items-center gap-2', {\n variants: {\n align: {\n left: 'laptop:justify-start',\n center: 'justify-center',\n },\n },\n defaultVariants: {\n align: 'left',\n },\n})\n\nconst iconGroupVariants = cva('hero-banner-icon-group flex items-center gap-2', {\n variants: {\n align: {\n left: 'justify-start',\n center: 'justify-center',\n },\n },\n defaultVariants: {\n align: 'left',\n },\n})\n\nexport type HeroBannerSemanticName =\n | 'root'\n | 'title'\n | 'subtitle'\n | 'buttonGroup'\n | 'primaryButton'\n | 'secondaryButton'\n | 'captionGroup'\n\nconst PlayButtonAppendIcon = ({ size = 'base' }: { size: 'base' | 'lg' | 'sm' }) => {\n const { width, height } = sizeMap[size]\n return (\n <svg width={width} height={height} viewBox=\"0 0 20 20\" fill=\"currentcolor\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M13.9599 9.30662C14.4547 9.63647 14.4547 10.3635 13.9599 10.6934L6.29558 15.8029C5.74179 16.1721 5 15.7751 5 15.1096V4.89042C5 4.22484 5.74179 3.82785 6.29558 4.19705L13.9599 9.30662Z\"\n fill=\"currentcolor\"\n />\n </svg>\n )\n}\n\nconst HeroBanner = React.forwardRef<\n HTMLDivElement,\n HeroBannerProps & {\n classNames?: Partial<Record<HeroBannerSemanticName, string>>\n }\n>(({ data, className, classNames = {}, onSecondaryClick, onPrimaryClick }, ref) => {\n const {\n label,\n title,\n subtitle,\n endDate,\n endDate_tz,\n dateFormat,\n pcImage,\n padImage,\n mobileImage,\n pcVideo,\n padVideo,\n mobileVideo,\n isShowVideo,\n isVideoLoop = true,\n primaryButton,\n secondaryButton,\n theme = 'light',\n size = 'default',\n titleSize,\n caption = [],\n blockLink,\n iconArray,\n align = 'center',\n } = data\n\n const isMobile = useMediaQuery({ query: '(max-width: 768px)' })\n const isPad = useMediaQuery({ query: '(max-width: 1024px)' })\n const [visible, setVisible] = useState<boolean>(false)\n const { ref: inViewRef, inView } = useInView()\n const scrollTriggerRef = useRef<ScrollTrigger | null>(null)\n const bgTriggerRef = useRef<ScrollTrigger | null>(null)\n const boxTriggerRef = useRef<ScrollTrigger | null>(null)\n\n const bgRef = useRef<HTMLImageElement>(null)\n const boxRef = useRef<HTMLDivElement>(null)\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 useEffect(() => {\n gsap.registerPlugin(ScrollTrigger)\n function gsapResize() {\n if (!bgRef.current) return\n const clientHeight = boxRef.current?.clientHeight || 100\n const screenHeight = window.innerHeight\n\n if (screenHeight <= clientHeight) {\n scrollTriggerRef.current = ScrollTrigger.create({\n trigger: boxRef.current,\n start: 'top bottom',\n end: 'bottom top',\n scrub: true,\n onUpdate: (self: any) => {\n const base = 40\n const value = self.progress * base - base / 2\n gsap.set(bgRef.current, { yPercent: value })\n },\n })\n } else {\n boxTriggerRef.current = ScrollTrigger.create({\n trigger: boxRef.current,\n start: 'top bottom',\n end: 'bottom bottom',\n scrub: true,\n onUpdate: (self: any) => {\n const base = 20\n const value = self.progress * base - base\n gsap.set(bgRef.current, { yPercent: value })\n },\n })\n bgTriggerRef.current = ScrollTrigger.create({\n trigger: boxRef.current,\n start: 'top top',\n end: 'bottom top',\n scrub: true,\n onUpdate: (self: any) => {\n const base = 20\n const value = self.progress * base\n gsap.set(bgRef.current, { yPercent: value })\n },\n })\n }\n }\n if (inView) gsapResize()\n return () => {\n // ScrollTrigger.getAll().forEach((t: any) => t.kill())\n scrollTriggerRef.current && scrollTriggerRef.current.kill()\n boxTriggerRef.current && boxTriggerRef.current.kill()\n bgTriggerRef.current && bgTriggerRef.current.kill()\n }\n }, [inView])\n\n return (\n <div ref={inViewRef} data-ui-component-id=\"HeroBanner\">\n <div\n ref={boxRef}\n className={cn(\n theme === 'dark' ? 'aiui-dark' : '',\n 'text-info-primary relative w-full overflow-hidden',\n {\n 'lg-desktop:aspect-[1920/930] desktop:aspect-[1440/700] laptop:aspect-[1024/520] tablet:aspect-[768/660] aspect-[390/660]':\n size === 'default',\n 'lg-desktop:aspect-[1920/800] desktop:aspect-[1440/640] laptop:aspect-[1024/480] tablet:aspect-[768/560] aspect-[390/560]':\n size === 'sm',\n },\n className\n )}\n >\n {blockLink && (\n <a\n className=\"absolute inset-0 z-10\"\n href={trackUrlRef(blockLink, `${componentType}_${componentName}`)}\n data-headless-type-name={`${componentType}#${componentName}`}\n data-headless-title-desc-button={`${title}#${subtitle}`}\n tabIndex={-1}\n aria-hidden=\"true\"\n aria-label={title}\n ></a>\n )}\n <div ref={bgRef} className={cn('absolute left-0 top-0 size-full')}>\n {isShowVideo ? (\n <ScrollLoadVideo\n poster={isMobile ? mobileImage?.url : isPad ? padImage?.url || mobileImage?.url : pcImage?.url}\n src={\n isMobile\n ? (mobileVideo?.url as string)\n : isPad\n ? (padVideo?.url as string) || (mobileVideo?.url as string)\n : (pcVideo?.url as string)\n }\n className=\"laptop:w-full h-full\"\n videoClassName=\"h-full object-cover\"\n muted\n loop={isVideoLoop}\n playsInline\n />\n ) : (\n <Picture\n className=\"laptop:w-full h-full\"\n imgClassName=\"h-full object-cover\"\n loading=\"eager\"\n fetchPriority=\"high\"\n alt={pcImage?.alt || ''}\n source={`${pcImage?.url || ''} , ${padImage?.url ?? (mobileImage?.url || '')} 1024, ${mobileImage?.url || ''} 767`}\n />\n )}\n </div>\n\n {/* \u5185\u5BB9\u533A\u57DF */}\n <div className={contentVariants({ align })}>\n <div className={textVariants({ align })}>\n {label && (\n <Text\n size={2}\n as=\"p\"\n className={cn('hero-banner-label font-heading lg-desktop:text-[18px] desktop:text-base text-sm')}\n html={label}\n />\n )}\n {title && (\n <Heading\n as={titleSize === '4' ? 'h1' : 'h2'}\n html={title}\n className={cn('hero-banner-title', classNames.title)}\n size={titleSize ? (Number(titleSize || '5') as any) : size === 'sm' ? 4 : 5}\n />\n )}\n {subtitle && (\n <Text\n as=\"p\"\n size={2}\n className={cn(\n 'hero-banner-subtitle font-heading lg-desktop:text-[18px] desktop:text-base laptop:mt-2 lg-desktop:mt-4 mt-1 text-sm'\n )}\n html={subtitle}\n />\n )}\n {endDate && (\n <div className=\"mt-3\">\n <Countdown\n endDate={endDate}\n endDate_tz={endDate_tz}\n dateFormat={dateFormat}\n variant=\"spacious\"\n align={align}\n />\n </div>\n )}\n </div>\n {/* \u6309\u94AE\u7EC4 */}\n <div className={buttonGroupVariants({ align })}>\n {secondaryButton?.isShowPlayVideoButton && secondaryButton?.playVideoButtonText ? (\n <Button\n onClick={() => setVisible(true)}\n size=\"lg\"\n variant=\"secondary\"\n className=\"hero-banner-play-video-button\"\n data-headless-type-name={`${componentType}#${componentName}`}\n data-headless-title-desc-button={`${title}#${subtitle}#${secondaryButton?.playVideoButtonText}`}\n >\n {secondaryButton?.playVideoButtonText} <PlayButtonAppendIcon size=\"lg\" />\n </Button>\n ) : secondaryButton?.text ? (\n <Button\n aria-label={title ?? subtitle}\n size=\"lg\"\n variant=\"secondary\"\n className=\"hero-banner-secondary-button\"\n as={secondaryButton?.isCustomSecondaryButton ? 'button' : 'a'}\n href={trackUrlRef(secondaryButton?.link, `${componentType}_${componentName}`)}\n onClick={e =>\n secondaryButton?.isCustomSecondaryButton &&\n onSecondaryClick?.(data, e, secondaryButton?.customSecondaryEventId)\n }\n data-headless-type-name={`${componentType}#${componentName}`}\n data-headless-title-desc-button={`${title}#${subtitle}#${secondaryButton?.text}`}\n >\n {secondaryButton?.text}\n <span className=\"sr-only\">{title ?? subtitle}</span>\n </Button>\n ) : null}\n {primaryButton && primaryButton.text && (\n <Button\n aria-label={title ?? subtitle}\n size=\"lg\"\n variant=\"primary\"\n className=\"hero-banner-primary-button\"\n as={primaryButton?.isCustomPrimaryButton ? 'button' : 'a'}\n href={trackUrlRef(primaryButton.link, `${componentType}_${componentName}`)}\n onClick={e =>\n primaryButton?.isCustomPrimaryButton && onPrimaryClick?.(data, e, primaryButton?.customPrimaryEventId)\n }\n data-headless-type-name={`${componentType}#${componentName}`}\n data-headless-title-desc-button={`${title}#${subtitle}#${primaryButton?.text}`}\n >\n {primaryButton.text}\n </Button>\n )}\n </div>\n <div className={iconGroupVariants({ align })}>\n {iconArray?.map(icon => (\n <div key={icon?.pcImage?.url || icon?.pcImage?.alt} className=\"h-12\">\n <Picture\n className=\"laptop:w-full h-full\"\n imgClassName=\"h-full object-cover\"\n loading=\"eager\"\n alt={icon?.pcImage?.alt || ''}\n source={icon?.pcImage?.url}\n />\n </div>\n ))}\n </div>\n </div>\n\n {/* \u5E95\u90E8\u4EA7\u54C1\u5217\u8868 */}\n {caption.length > 0 && (\n <div\n className={cn(\n 'hero-banner-caption-group laptop:gap-3 tablet:px-[32px] laptop:px-[64px] lg-desktop:px-[calc(50%-832px)] desktop:pb-[24px] absolute bottom-0 z-10 flex items-stretch gap-2 px-[16px] pb-[16px]',\n classNames.captionGroup\n )}\n >\n {caption.map((c, index) => (\n <React.Fragment key={c.title}>\n <Text\n size={2}\n className={cn(\n 'hero-banner-product-text tablet:w-[108px] loptop:w-[150px] desktop:w-[156px] lg-desktop:w-[180px] laptop:text-[14px] flex-1 text-[12px]'\n )}\n html={c.title}\n />\n {index < caption.length - 1 && <div className={cn('bg-info-primary w-px')} />}\n </React.Fragment>\n ))}\n </div>\n )}\n\n {/* \u89C6\u9891\u5F39\u7A97 */}\n {visible && (\n <VideoModal\n visible={visible}\n videoUrl={secondaryButton?.videoUrl?.url}\n youTubeId={secondaryButton?.youtubeId}\n onCloseModal={() => setVisible(false)}\n />\n )}\n </div>\n </div>\n )\n})\n\nHeroBanner.displayName = 'HeroBanner'\n\nexport default withLayout(HeroBanner)\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["jsx", "jsxs", "React", "useImperativeHandle", "useRef", "useState", "useEffect", "gsap", "ScrollTrigger", "useMediaQuery", "useInView", "ScrollLoadVideo", "Button", "Heading", "Picture", "Text", "Countdown", "cn", "cva", "withLayout", "useExposure", "trackUrlRef", "sizeMap", "VideoModal", "componentType", "componentName", "contentVariants", "textVariants", "buttonGroupVariants", "iconGroupVariants", "PlayButtonAppendIcon", "size", "width", "height", "HeroBanner", "data", "className", "classNames", "onSecondaryClick", "onPrimaryClick", "ref", "label", "title", "subtitle", "endDate", "endDate_tz", "dateFormat", "pcImage", "padImage", "mobileImage", "pcVideo", "padVideo", "mobileVideo", "isShowVideo", "isVideoLoop", "primaryButton", "secondaryButton", "theme", "titleSize", "caption", "blockLink", "iconArray", "align", "isMobile", "isPad", "visible", "setVisible", "inViewRef", "inView", "scrollTriggerRef", "bgTriggerRef", "boxTriggerRef", "bgRef", "boxRef", "gsapResize", "clientHeight", "self", "value", "e", "icon", "c", "index", "HeroBanner_default"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import{jsx as t,jsxs as v}from"react/jsx-runtime";import Q,{useEffect as W,useRef as u,useImperativeHandle as X,useState as Y}from"react";import{gsap as w}from"gsap";import{SplitText as L}from"gsap/dist/SplitText";import{ScrollTrigger as R}from"gsap/dist/ScrollTrigger";import{cn as c}from"../../helpers/utils.js";import{cva as E}from"class-variance-authority";import{Heading as tt,Text as et}from"../../components/index.js";import{withLayout as nt}from"../../shared/Styles.js";import{trackUrlRef as rt}from"../../shared/trackUrlRef.js";import{useInView as it}from"react-intersection-observer";import st from"./Countdown.js";const H="link",V="title",ot=E("",{variants:{theme:{light:"text-[#080A0F]",dark:"text-[#F5F6F7]"}},defaultVariants:{theme:"light"}}),at=E("desktop:text-base desktop:mt-2 lg-desktop:text-[18px] mt-1 text-[14px] font-bold leading-[1.4] tracking-[-0.36px]",{variants:{theme:{light:"text-[#080A0F]",dark:"text-[#F5F6F7]"}},defaultVariants:{theme:"light"}}),M=({data:r,className:
|
|
1
|
+
"use client";import{jsx as t,jsxs as v}from"react/jsx-runtime";import Q,{useEffect as W,useRef as u,useImperativeHandle as X,useState as Y}from"react";import{gsap as w}from"gsap";import{SplitText as L}from"gsap/dist/SplitText";import{ScrollTrigger as R}from"gsap/dist/ScrollTrigger";import{cn as c}from"../../helpers/utils.js";import{cva as E}from"class-variance-authority";import{Heading as tt,Text as et}from"../../components/index.js";import{withLayout as nt}from"../../shared/Styles.js";import{trackUrlRef as rt}from"../../shared/trackUrlRef.js";import{useInView as it}from"react-intersection-observer";import st from"./Countdown.js";const H="link",V="title",ot=E("",{variants:{theme:{light:"text-[#080A0F]",dark:"text-[#F5F6F7]"}},defaultVariants:{theme:"light"}}),at=E("desktop:text-base desktop:mt-2 lg-desktop:text-[18px] mt-1 text-[14px] font-bold leading-[1.4] tracking-[-0.36px]",{variants:{theme:{light:"text-[#080A0F]",dark:"text-[#F5F6F7]"}},defaultVariants:{theme:"light"}}),M=({data:r,className:p})=>{const{theme:e="light",extensions:i,title:f,caption:d,align:s}=r;return i?.textLink?v("a",{className:c({"aiui-dark":e==="dark"},"hover:text-brand-0 [&_svg_path]:hover:fill-brand-0 lg-desktop:text-base flex items-center overflow-hidden text-sm font-[700] leading-[1.4] transition-all duration-[0.4s]",{"text-[#080A0F]":e==="light"},{"text-[#F5F6F7]":e==="dark"},{"justify-center mt-4":s==="center"},{"mt-1 laptop:mt-0":s==="left"},p),href:rt(i?.link,`${H}_${V}`),"data-headless-type-name":`${H}#${V}`,"data-headless-title-desc-button":`${f}#${d}`,children:[t("div",{className:"truncate whitespace-nowrap",children:i?.textLink}),t("div",{className:"lg-desktop:size-5 size-4",children:t("svg",{xmlns:"http://www.w3.org/2000/svg",width:"100%",height:"100%",viewBox:"0 0 20 20",fill:"none",children:t("path",{d:"M6.91058 4.41083C7.23602 4.08539 7.76353 4.08539 8.08897 4.41083L13.089 9.41083C13.4144 9.73626 13.4144 10.2638 13.089 10.5892L8.08897 15.5892C7.76353 15.9146 7.23602 15.9146 6.91058 15.5892C6.58515 15.2638 6.58514 14.7363 6.91058 14.4108L11.3214 10L6.91058 5.58921C6.58514 5.26377 6.58514 4.73626 6.91058 4.41083Z",fill:e==="dark"?"#F5F6F7":"#080A0F",className:"transition-all duration-[0.4s]"})})})]}):null},$=Q.forwardRef(({data:r,className:p,as:e="h2",weight:i="bold"},f)=>{const{title:d,caption:s,subtitle:k,countdown:b,showCountdown:z=!1,theme:m="light",extensions:P,align:o="left"}=r,T=u(null),a=u(null),n=u(null),l=u(null),[S,j]=Y(!0),{ref:A,inView:F}=it();X(f,()=>T.current);const I=()=>{j(!1)};return W(()=>{w.registerPlugin(L,R);function B(){if(!a.current)return;const D=a.current?.clientHeight||80;n.current&&n.current.revert(),l.current&&l.current.kill(),n.current=new L(a.current,{type:"words",wordsClass:"word"});const g=n.current.words;w.set(g,{opacity:0}),l.current=R.create({trigger:a.current,start:"bottom bottom-=4%",end:`bottom+=${D*1.5+60}px bottom-=4%`,scrub:!0,invalidateOnRefresh:!0,onUpdate:_=>{const U=_.progress,y=g.length||1,O=.5,h=1/y,N=h*(1-O),C=(y-1)*N+h,Z=Math.min(1,C>0?U/C:0);g.forEach((q,G)=>{const J=G*N,K=h;let x=(Z-J)/K;x=Math.max(0,Math.min(1,x)),w.set(q,{opacity:x})})}})}return F&&B(),()=>{n.current&&n.current.revert(),l.current&&l.current.kill()}},[F]),v("div",{id:P?.id,className:"titleBottom title-box flex items-end justify-between gap-2 pb-6",ref:T,children:[v("div",{ref:A,className:c("flex-1",p,{"aiui-dark":m==="dark","text-center":o==="center","text-left":o==="left"}),children:[(s||d)&&t(tt,{ref:a,as:e,size:4,html:s||d,weight:i,className:ot({theme:m})}),k&&t(et,{html:k,as:"p",className:at({theme:m})}),t(M,{data:r,className:c({"laptop:hidden":o==="left"})}),z&&b&&S&&t(st,{className:c("mt-4 justify-start",{"justify-center":o==="center"}),config:b,onCountdownEnd:I,theme:m})]}),t(M,{data:r,className:c("hidden",{"laptop:flex":o==="left"})})]})});$.displayName="Title";var vt=nt($);export{vt as default};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/biz-components/Title/index.tsx"],
|
|
4
|
-
"sourcesContent": ["'use client'\nimport React, { useEffect, useRef, useImperativeHandle, useState } from 'react'\nimport { gsap } from 'gsap'\nimport { SplitText } from 'gsap/dist/SplitText'\nimport { ScrollTrigger } from 'gsap/dist/ScrollTrigger'\nimport { cn } from '../../helpers/utils.js'\nimport { cva } from 'class-variance-authority'\nimport { Heading, Text } from '../../components/index.js'\nimport { withLayout } from '../../shared/Styles.js'\nimport type { TitleProps } from './types.js'\nimport { trackUrlRef } from '../../shared/trackUrlRef.js'\nimport { useInView } from 'react-intersection-observer'\nimport Countdown from './Countdown.js'\n\nconst componentType = 'link'\nconst componentName = 'title'\n\n/**\n * \u6807\u9898\u6837\u5F0F\u53D8\u4F53\n */\nconst titleHeadingVariants = cva('', {\n variants: {\n theme: {\n light: 'text-[#080A0F]',\n dark: 'text-[#F5F6F7]',\n },\n },\n defaultVariants: {\n theme: 'light',\n },\n})\n\n/**\n * \u526F\u6807\u9898\u6837\u5F0F\u53D8\u4F53\n */\nconst subtitleVariants = cva(\n 'desktop:text-base desktop:mt-2 lg-desktop:text-[18px] mt-1 text-[14px] font-bold leading-[1.4] tracking-[-0.36px]',\n {\n variants: {\n theme: {\n light: 'text-[#080A0F]',\n dark: 'text-[#F5F6F7]',\n },\n },\n defaultVariants: {\n theme: 'light',\n },\n }\n)\n\nconst TitleButton = ({ data, className }: { data: TitleProps['data']; className?: string }) => {\n const { theme = 'light', extensions, title, caption, align } = data\n if (!extensions?.textLink) return null\n return (\n <a\n className={cn(\n { 'aiui-dark': theme === 'dark' },\n 'hover:text-brand-0 [&_svg_path]:hover:fill-brand-0 lg-desktop:text-base flex items-center overflow-hidden text-sm font-[700] leading-[1.4] transition-all duration-[0.4s]',\n { 'text-[#080A0F]': theme === 'light' },\n { 'text-[#F5F6F7]': theme === 'dark' },\n { 'justify-center mt-4': align === 'center' },\n { 'mt-1 laptop:mt-0': align === 'left' },\n className\n )}\n href={trackUrlRef(extensions?.link, `${componentType}_${componentName}`)}\n data-headless-type-name={`${componentType}#${componentName}`}\n data-headless-title-desc-button={`${title}#${caption}`}\n >\n <div className=\"truncate whitespace-nowrap\">{extensions?.textLink}</div>\n <div className=\"lg-desktop:size-5 size-4\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"100%\" height=\"100%\" viewBox=\"0 0 20 20\" fill=\"none\">\n <path\n d=\"M6.91058 4.41083C7.23602 4.08539 7.76353 4.08539 8.08897 4.41083L13.089 9.41083C13.4144 9.73626 13.4144 10.2638 13.089 10.5892L8.08897 15.5892C7.76353 15.9146 7.23602 15.9146 6.91058 15.5892C6.58515 15.2638 6.58514 14.7363 6.91058 14.4108L11.3214 10L6.91058 5.58921C6.58514 5.26377 6.58514 4.73626 6.91058 4.41083Z\"\n fill={theme === 'dark' ? '#F5F6F7' : '#080A0F'}\n className=\"transition-all duration-[0.4s]\"\n />\n </svg>\n </div>\n </a>\n )\n}\n\nconst Title = React.forwardRef<HTMLDivElement, TitleProps>(({ data, className, as = 'h2', weight = 'bold' }, ref) => {\n const {\n title,\n caption,\n subtitle,\n countdown,\n showCountdown = false,\n theme = 'light',\n extensions,\n align = 'left',\n } = data\n const innerRef = useRef<HTMLDivElement>(null)\n const titleRef = useRef<HTMLHeadingElement>(null)\n const splitTextInstance = useRef<SplitText | null>(null)\n const scrollTriggerRef = useRef<ScrollTrigger | null>(null)\n\n // \u63A7\u5236\u5012\u8BA1\u65F6\u663E\u793A\u72B6\u6001\n const [isCountdownVisible, setIsCountdownVisible] = useState(true)\n\n const { ref: inViewRef, inView } = useInView()\n\n useImperativeHandle(ref, () => innerRef.current as HTMLDivElement)\n\n // \u5012\u8BA1\u65F6\u7ED3\u675F\u56DE\u8C03\n const handleCountdownEnd = () => {\n setIsCountdownVisible(false)\n }\n\n useEffect(() => {\n gsap.registerPlugin(SplitText, ScrollTrigger)\n function gsapResize() {\n if (!titleRef.current) return\n const height = titleRef.current?.clientHeight || 80\n if (splitTextInstance.current) {\n splitTextInstance.current.revert()\n }\n if (scrollTriggerRef.current) {\n scrollTriggerRef.current.kill()\n }\n splitTextInstance.current = new SplitText(titleRef.current, {\n type: 'words',\n wordsClass: 'word',\n })\n const words = splitTextInstance.current.words\n gsap.set(words, { opacity: 0 })\n scrollTriggerRef.current = ScrollTrigger.create({\n trigger: titleRef.current,\n start: 'bottom bottom-=4%',\n end: `bottom+=${height * 1.5 + 60}px bottom-=4%`,\n scrub: true,\n invalidateOnRefresh: true,\n onUpdate: (self: any) => {\n const progress = self.progress\n const total = words.length || 1\n const overlap = 0.5\n const interval = 1 / total\n const step = interval * (1 - overlap)\n const lastEnd = (total - 1) * step + interval\n const normalizedProgress = Math.min(1, lastEnd > 0 ? progress / lastEnd : 0)\n words.forEach((word: any, i: number) => {\n const start = i * step\n const width = interval\n let opacity = (normalizedProgress - start) / width\n opacity = Math.max(0, Math.min(1, opacity))\n gsap.set(word, { opacity })\n })\n },\n })\n }\n\n if (inView) {\n gsapResize()\n }\n\n return () => {\n splitTextInstance.current && splitTextInstance.current.revert()\n // ScrollTrigger.getAll().forEach((t: { kill: () => any }) => t.kill())\n scrollTriggerRef.current && scrollTriggerRef.current.kill()\n }\n }, [inView])\n\n return (\n <div id={extensions?.id} className=\"titleBottom title-box
|
|
4
|
+
"sourcesContent": ["'use client'\nimport React, { useEffect, useRef, useImperativeHandle, useState } from 'react'\nimport { gsap } from 'gsap'\nimport { SplitText } from 'gsap/dist/SplitText'\nimport { ScrollTrigger } from 'gsap/dist/ScrollTrigger'\nimport { cn } from '../../helpers/utils.js'\nimport { cva } from 'class-variance-authority'\nimport { Heading, Text } from '../../components/index.js'\nimport { withLayout } from '../../shared/Styles.js'\nimport type { TitleProps } from './types.js'\nimport { trackUrlRef } from '../../shared/trackUrlRef.js'\nimport { useInView } from 'react-intersection-observer'\nimport Countdown from './Countdown.js'\n\nconst componentType = 'link'\nconst componentName = 'title'\n\n/**\n * \u6807\u9898\u6837\u5F0F\u53D8\u4F53\n */\nconst titleHeadingVariants = cva('', {\n variants: {\n theme: {\n light: 'text-[#080A0F]',\n dark: 'text-[#F5F6F7]',\n },\n },\n defaultVariants: {\n theme: 'light',\n },\n})\n\n/**\n * \u526F\u6807\u9898\u6837\u5F0F\u53D8\u4F53\n */\nconst subtitleVariants = cva(\n 'desktop:text-base desktop:mt-2 lg-desktop:text-[18px] mt-1 text-[14px] font-bold leading-[1.4] tracking-[-0.36px]',\n {\n variants: {\n theme: {\n light: 'text-[#080A0F]',\n dark: 'text-[#F5F6F7]',\n },\n },\n defaultVariants: {\n theme: 'light',\n },\n }\n)\n\nconst TitleButton = ({ data, className }: { data: TitleProps['data']; className?: string }) => {\n const { theme = 'light', extensions, title, caption, align } = data\n if (!extensions?.textLink) return null\n return (\n <a\n className={cn(\n { 'aiui-dark': theme === 'dark' },\n 'hover:text-brand-0 [&_svg_path]:hover:fill-brand-0 lg-desktop:text-base flex items-center overflow-hidden text-sm font-[700] leading-[1.4] transition-all duration-[0.4s]',\n { 'text-[#080A0F]': theme === 'light' },\n { 'text-[#F5F6F7]': theme === 'dark' },\n { 'justify-center mt-4': align === 'center' },\n { 'mt-1 laptop:mt-0': align === 'left' },\n className\n )}\n href={trackUrlRef(extensions?.link, `${componentType}_${componentName}`)}\n data-headless-type-name={`${componentType}#${componentName}`}\n data-headless-title-desc-button={`${title}#${caption}`}\n >\n <div className=\"truncate whitespace-nowrap\">{extensions?.textLink}</div>\n <div className=\"lg-desktop:size-5 size-4\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"100%\" height=\"100%\" viewBox=\"0 0 20 20\" fill=\"none\">\n <path\n d=\"M6.91058 4.41083C7.23602 4.08539 7.76353 4.08539 8.08897 4.41083L13.089 9.41083C13.4144 9.73626 13.4144 10.2638 13.089 10.5892L8.08897 15.5892C7.76353 15.9146 7.23602 15.9146 6.91058 15.5892C6.58515 15.2638 6.58514 14.7363 6.91058 14.4108L11.3214 10L6.91058 5.58921C6.58514 5.26377 6.58514 4.73626 6.91058 4.41083Z\"\n fill={theme === 'dark' ? '#F5F6F7' : '#080A0F'}\n className=\"transition-all duration-[0.4s]\"\n />\n </svg>\n </div>\n </a>\n )\n}\n\nconst Title = React.forwardRef<HTMLDivElement, TitleProps>(({ data, className, as = 'h2', weight = 'bold' }, ref) => {\n const {\n title,\n caption,\n subtitle,\n countdown,\n showCountdown = false,\n theme = 'light',\n extensions,\n align = 'left',\n } = data\n const innerRef = useRef<HTMLDivElement>(null)\n const titleRef = useRef<HTMLHeadingElement>(null)\n const splitTextInstance = useRef<SplitText | null>(null)\n const scrollTriggerRef = useRef<ScrollTrigger | null>(null)\n\n // \u63A7\u5236\u5012\u8BA1\u65F6\u663E\u793A\u72B6\u6001\n const [isCountdownVisible, setIsCountdownVisible] = useState(true)\n\n const { ref: inViewRef, inView } = useInView()\n\n useImperativeHandle(ref, () => innerRef.current as HTMLDivElement)\n\n // \u5012\u8BA1\u65F6\u7ED3\u675F\u56DE\u8C03\n const handleCountdownEnd = () => {\n setIsCountdownVisible(false)\n }\n\n useEffect(() => {\n gsap.registerPlugin(SplitText, ScrollTrigger)\n function gsapResize() {\n if (!titleRef.current) return\n const height = titleRef.current?.clientHeight || 80\n if (splitTextInstance.current) {\n splitTextInstance.current.revert()\n }\n if (scrollTriggerRef.current) {\n scrollTriggerRef.current.kill()\n }\n splitTextInstance.current = new SplitText(titleRef.current, {\n type: 'words',\n wordsClass: 'word',\n })\n const words = splitTextInstance.current.words\n gsap.set(words, { opacity: 0 })\n scrollTriggerRef.current = ScrollTrigger.create({\n trigger: titleRef.current,\n start: 'bottom bottom-=4%',\n end: `bottom+=${height * 1.5 + 60}px bottom-=4%`,\n scrub: true,\n invalidateOnRefresh: true,\n onUpdate: (self: any) => {\n const progress = self.progress\n const total = words.length || 1\n const overlap = 0.5\n const interval = 1 / total\n const step = interval * (1 - overlap)\n const lastEnd = (total - 1) * step + interval\n const normalizedProgress = Math.min(1, lastEnd > 0 ? progress / lastEnd : 0)\n words.forEach((word: any, i: number) => {\n const start = i * step\n const width = interval\n let opacity = (normalizedProgress - start) / width\n opacity = Math.max(0, Math.min(1, opacity))\n gsap.set(word, { opacity })\n })\n },\n })\n }\n\n if (inView) {\n gsapResize()\n }\n\n return () => {\n splitTextInstance.current && splitTextInstance.current.revert()\n // ScrollTrigger.getAll().forEach((t: { kill: () => any }) => t.kill())\n scrollTriggerRef.current && scrollTriggerRef.current.kill()\n }\n }, [inView])\n\n return (\n <div id={extensions?.id} className=\"titleBottom title-box flex items-end justify-between gap-2 pb-6\" ref={innerRef}>\n <div\n ref={inViewRef}\n className={cn('flex-1', className, {\n 'aiui-dark': theme === 'dark',\n 'text-center': align === 'center',\n 'text-left': align === 'left',\n })}\n >\n {(caption || title) && (\n <Heading\n ref={titleRef}\n as={as}\n size={4}\n html={caption || title}\n weight={weight}\n className={titleHeadingVariants({ theme })}\n />\n )}\n {subtitle && <Text html={subtitle} as=\"p\" className={subtitleVariants({ theme })} />}\n <TitleButton data={data} className={cn({ 'laptop:hidden': align === 'left' })} />\n {showCountdown && countdown && isCountdownVisible && (\n <Countdown\n className={cn('mt-4 justify-start', {\n 'justify-center': align === 'center',\n })}\n config={countdown}\n onCountdownEnd={handleCountdownEnd}\n theme={theme}\n />\n )}\n </div>\n <TitleButton data={data} className={cn('hidden', { ['laptop:flex']: align === 'left' })} />\n </div>\n )\n})\n\nTitle.displayName = 'Title'\n\nexport default withLayout(Title)\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": ["jsx", "jsxs", "React", "useEffect", "useRef", "useImperativeHandle", "useState", "gsap", "SplitText", "ScrollTrigger", "cn", "cva", "Heading", "Text", "withLayout", "trackUrlRef", "useInView", "Countdown", "componentType", "componentName", "titleHeadingVariants", "subtitleVariants", "TitleButton", "data", "className", "theme", "extensions", "title", "caption", "align", "Title", "as", "weight", "ref", "subtitle", "countdown", "showCountdown", "innerRef", "titleRef", "splitTextInstance", "scrollTriggerRef", "isCountdownVisible", "setIsCountdownVisible", "inViewRef", "inView", "handleCountdownEnd", "gsapResize", "height", "words", "self", "progress", "total", "overlap", "interval", "step", "lastEnd", "normalizedProgress", "word", "i", "start", "width", "opacity", "Title_default"]
|
|
7
7
|
}
|
|
@@ -2,6 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { type VariantProps } from 'class-variance-authority';
|
|
3
3
|
declare const countdownVariants: (props?: ({
|
|
4
4
|
variant?: "outline" | "spacious" | null | undefined;
|
|
5
|
+
align?: "left" | "center" | null | undefined;
|
|
5
6
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
6
7
|
/**
|
|
7
8
|
* 时间标签配置接口
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import{jsx as n,jsxs as o}from"react/jsx-runtime";import
|
|
1
|
+
"use client";import{jsx as n,jsxs as o}from"react/jsx-runtime";import A,{useEffect as E,useRef as B,useState as L,useMemo as J}from"react";import{cva as d}from"class-variance-authority";import{cn as i}from"../helpers/index.js";const $=d("countdown-container flex w-full items-center",{variants:{variant:{outline:"gap-1",spacious:"gap-1"},align:{left:"justify-start",center:"justify-center"}},defaultVariants:{variant:"outline",align:"left"}}),u=d("time-block border-box rounded-box-small flex flex-col items-center justify-center overflow-hidden text-center text-xs",{variants:{variant:{outline:"border-info-primary text-info-primary desktop:size-12 desktop:p-1 size-10 border bg-transparent p-[2px]",spacious:"bg-info-white text-info-primary desktop:size-12 desktop:p-1 size-10 p-[2px]"}},defaultVariants:{variant:"outline"}}),m=d("time-number lg-desktop:text-[24px] desktop:leading-[120%] translate-y-[2px] whitespace-nowrap text-center text-[20px] font-bold leading-none"),w=d("separator desktop:text-2xl text-xl font-bold",{variants:{variant:{outline:"text-info-primary",spacious:"text-info-primary"}},defaultVariants:{variant:"outline"}}),p=(a,t=2)=>String(Math.abs(a)).padStart(t,"0"),f=()=>({day:"Day",hour:"Hours",minute:"Mins",second:"Secs"}),q=a=>{try{let t=a?.trim?.();return!t?.startsWith?.("{")||!t?.endsWith?.("}")?f():(t=t?.replace?.(/(\w+)\s*:/g,'"$1":'),{...f(),...JSON.parse(t)})}catch{return f()}},S=A.forwardRef(({className:a,endDate:t,endDate_tz:G,locale:K,timeLabels:x,dateFormat:v,onExpire:h,separator:b=":",hideWhenExpired:R=!0,variant:s,align:z,...C},H)=>{const c=J(()=>x||(v?q(v):f()),[x,v]),r=B(Date.parse(t)),[I,y]=L(()=>{const e=r.current;return isNaN(e)?0:Math.max(0,e-Date.now())}),[N,M]=L(()=>{const e=r.current;return!isNaN(e)&&e<=Date.now()});E(()=>{r.current=Date.parse(t);const e=r.current,l=isNaN(e)?0:Math.max(0,e-Date.now()),g=!isNaN(e)&&e<=Date.now();y(l),M(g)},[t]),E(()=>{if(N||isNaN(r.current))return;let e=!1;const l=()=>{const _=Date.now(),V=Math.max(0,r.current-_);y(V),V<=0&&!e&&(e=!0,M(!0),h?.())};l();const g=window.setInterval(l,1e3);return()=>clearInterval(g)},[h,N,t]);const D=Math.floor(I/1e3),j=D%60,k=Math.floor(D/60),P=k%60,T=Math.floor(k/60),O=T%24,W=Math.floor(T/24);return N&&R?null:o("div",{ref:H,className:i($({variant:s,align:z}),a),role:"timer","aria-live":"polite","aria-label":"countdown timer",...C,children:[o("div",{className:i(u({variant:s}),"time-days-box"),children:[n("div",{className:m(),children:p(W,2)}),n("div",{className:"truncate text-center text-[12px] font-bold",children:c.day})]}),n("div",{className:w({variant:s}),children:b}),o("div",{className:i(u({variant:s}),"time-hours-box"),children:[n("div",{className:m(),children:p(O,2)}),n("div",{className:"truncate text-center text-[12px] font-bold",children:c.hour})]}),n("div",{className:w({variant:s}),children:b}),o("div",{className:i(u({variant:s}),"time-minutes-box"),children:[n("div",{className:m(),children:p(P,2)}),n("div",{className:"truncate text-center text-[12px] font-bold",children:c.minute})]}),n("div",{className:w({variant:s}),children:b}),o("div",{className:i(u({variant:s}),"time-seconds-box"),children:[n("div",{className:m(),children:p(j,2)}),n("div",{className:"truncate text-center text-[12px] font-bold",children:c.second})]})]})});S.displayName="Countdown";var Y=S;export{Y as default};
|
|
2
2
|
//# sourceMappingURL=Countdown.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/components/Countdown.tsx"],
|
|
4
|
-
"sourcesContent": ["'use client'\n\nimport React, { useEffect, useRef, useState, useMemo } from 'react'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { cn } from '../helpers/index.js'\n\n// \u5B9A\u4E49\u6837\u5F0F\u53D8\u4F53\nconst countdownVariants = cva(\n // \u57FA\u7840\u6837\u5F0F\uFF1A\u5012\u8BA1\u65F6\u5BB9\u5668\n 'countdown-container flex w-full items-center',\n {\n variants: {\n variant: {\n outline: 'gap-1',\n spacious: 'gap-1',\n },\n },\n defaultVariants: {\n variant: 'outline',\n },\n }\n)\n\nconst timeBlockVariants = cva(\n // \u57FA\u7840\u6837\u5F0F\uFF1A\u65F6\u95F4\u5757\n 'time-block border-box rounded-box-small flex flex-col items-center justify-center overflow-hidden text-center text-xs',\n {\n variants: {\n variant: {\n outline:\n 'border-info-primary text-info-primary desktop:size-12 desktop:p-1 size-10 border bg-transparent p-[2px]',\n spacious: 'bg-info-white text-info-primary desktop:size-12 desktop:p-1 size-10 p-[2px]',\n },\n },\n defaultVariants: {\n variant: 'outline',\n },\n }\n)\n\nconst timeNumberVariants = cva(\n 'time-number lg-desktop:text-[24px] desktop:leading-[120%] translate-y-[2px] whitespace-nowrap text-center text-[20px] font-bold leading-none'\n)\n\nconst separatorVariants = cva(\n // \u57FA\u7840\u6837\u5F0F\uFF1A\u5206\u9694\u7B26\n 'separator desktop:text-2xl text-xl font-bold',\n {\n variants: {\n variant: {\n outline: 'text-info-primary',\n spacious: 'text-info-primary',\n },\n },\n defaultVariants: {\n variant: 'outline',\n },\n }\n)\n\n/**\n * \u65F6\u95F4\u6807\u7B7E\u914D\u7F6E\u63A5\u53E3\n */\nexport interface TimeLabels {\n /** \u5929\u7684\u6807\u7B7E */\n day: string\n /** \u5C0F\u65F6\u7684\u6807\u7B7E */\n hour: string\n /** \u5206\u949F\u7684\u6807\u7B7E */\n minute: string\n /** \u79D2\u7684\u6807\u7B7E */\n second: string\n}\n\n/**\n * \u5012\u8BA1\u65F6\u7EC4\u4EF6Props\u63A5\u53E3\n */\nexport interface CountdownProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onExpire'>, VariantProps<typeof countdownVariants> {\n /** \u7ED3\u675F\u65F6\u95F4 - ISO\u683C\u5F0F\u5B57\u7B26\u4E32 */\n endDate: string\n /** \u7ED3\u675F\u65F6\u95F4\u65F6\u533A\uFF0C\u5982: America/Los_Angeles */\n endDate_tz?: string\n /** \u683C\u5F0F\u5316\u7528\u7684locale\uFF0C\u9ED8\u8BA4\u4F7F\u7528navigator.language */\n locale?: string\n /** \u65F6\u95F4\u6807\u7B7E\u914D\u7F6E\uFF0C\u7528\u4E8E\u56FD\u9645\u5316 */\n timeLabels?: TimeLabels\n /** JSON\u5B57\u7B26\u4E32\u683C\u5F0F\u7684\u65F6\u95F4\u6807\u7B7E\uFF08\u5411\u540E\u517C\u5BB9\uFF09 */\n dateFormat?: string\n /** \u5012\u8BA1\u65F6\u7ED3\u675F\u56DE\u8C03 */\n onExpire?: () => void\n /** \u5206\u9694\u7B26\u5B57\u7B26\uFF0C\u9ED8\u8BA4\u4E3A ':' */\n separator?: string\n /** \u9690\u85CF\u5DF2\u8FC7\u671F\u7684\u5012\u8BA1\u65F6\uFF0C\u9ED8\u8BA4\u4E3A true */\n hideWhenExpired?: boolean\n}\n\n/**\n * \u6570\u5B57\u8865\u96F6\u51FD\u6570\n */\nconst pad = (n: number, len = 2) => String(Math.abs(n)).padStart(len, '0')\n\n/**\n * \u9ED8\u8BA4\u65F6\u95F4\u6807\u7B7E\n */\nconst getDefaultTimeLabels = (): TimeLabels => ({\n day: 'Day',\n hour: 'Hours',\n minute: 'Mins',\n second: 'Secs',\n})\n\n/**\n * \u89E3\u6790dateFormat JSON\u5B57\u7B26\u4E32\uFF08\u5411\u540E\u517C\u5BB9\uFF09\n */\nconst safeStringToObject = (str: string): TimeLabels => {\n try {\n let jsonStr = str?.trim?.()\n if (!jsonStr?.startsWith?.('{') || !jsonStr?.endsWith?.('}')) {\n return getDefaultTimeLabels()\n }\n jsonStr = jsonStr?.replace?.(/(\\w+)\\s*:/g, '\"$1\":')\n return { ...getDefaultTimeLabels(), ...JSON.parse(jsonStr) }\n } catch (err) {\n return getDefaultTimeLabels()\n }\n}\n\n/**\n * Countdown - \u5012\u8BA1\u65F6\u539F\u5B50\u7EC4\u4EF6\n *\n * @description \u7528\u4E8E\u663E\u793A\u5012\u8BA1\u65F6\u7684\u7EC4\u4EF6\uFF0C\u652F\u6301\u5929\u3001\u65F6\u3001\u5206\u3001\u79D2\u663E\u793A\uFF0C\u652F\u6301\u591A\u79CD\u6837\u5F0F\u53D8\u4F53\u548C\u5C3A\u5BF8\n */\nconst Countdown = React.forwardRef<HTMLDivElement, CountdownProps>(\n (\n {\n className,\n endDate,\n endDate_tz,\n locale,\n timeLabels,\n dateFormat,\n onExpire,\n separator = ':',\n hideWhenExpired = true,\n variant,\n ...props\n },\n ref\n ) => {\n // \u786E\u5B9A\u6700\u7EC8\u4F7F\u7528\u7684\u65F6\u95F4\u6807\u7B7E\n const finalTimeLabels = useMemo(() => {\n if (timeLabels) return timeLabels\n if (dateFormat) return safeStringToObject(dateFormat)\n return getDefaultTimeLabels()\n }, [timeLabels, dateFormat])\n\n // \u89E3\u6790\u76EE\u6807\u65F6\u95F4\n const targetMsRef = useRef<number>(Date.parse(endDate))\n const [remainingMs, setRemainingMs] = useState<number>(() => {\n const t = targetMsRef.current\n return isNaN(t) ? 0 : Math.max(0, t - Date.now())\n })\n\n // \u5224\u65AD\u662F\u5426\u5DF2\u8FC7\u671F\n const [isExpired, setIsExpired] = useState<boolean>(() => {\n const t = targetMsRef.current\n return !isNaN(t) && t <= Date.now()\n })\n\n // \u5F53endDate\u6539\u53D8\u65F6\u66F4\u65B0\u76EE\u6807\u65F6\u95F4\n useEffect(() => {\n targetMsRef.current = Date.parse(endDate)\n const t = targetMsRef.current\n const newRemaining = isNaN(t) ? 0 : Math.max(0, t - Date.now())\n const newIsExpired = !isNaN(t) && t <= Date.now()\n\n setRemainingMs(newRemaining)\n setIsExpired(newIsExpired)\n }, [endDate])\n\n // \u542F\u52A8\u5012\u8BA1\u65F6\u5B9A\u65F6\u5668\n useEffect(() => {\n if (isExpired) return // \u5DF2\u8FC7\u671F\u5219\u4E0D\u542F\u52A8\n if (isNaN(targetMsRef.current)) return // \u65E0\u6548\u65E5\u671F\u4E0D\u542F\u52A8\n\n let expiredCalled = false\n const tick = () => {\n const now = Date.now()\n const remaining = Math.max(0, targetMsRef.current - now)\n setRemainingMs(remaining)\n\n if (remaining <= 0 && !expiredCalled) {\n expiredCalled = true\n setIsExpired(true)\n onExpire?.()\n }\n }\n\n tick() // \u7ACB\u5373\u6267\u884C\u4E00\u6B21\n const intervalId = window.setInterval(tick, 1000)\n\n return () => clearInterval(intervalId)\n }, [onExpire, isExpired, endDate])\n\n // \u8BA1\u7B97\u65F6\u95F4\u5355\u4F4D\n const totalSeconds = Math.floor(remainingMs / 1000)\n const seconds = totalSeconds % 60\n const totalMinutes = Math.floor(totalSeconds / 60)\n const minutes = totalMinutes % 60\n const totalHours = Math.floor(totalMinutes / 60)\n const hours = totalHours % 24\n const days = Math.floor(totalHours / 24)\n\n // \u5982\u679C\u5DF2\u8FC7\u671F\u4E14\u9700\u8981\u9690\u85CF\uFF0C\u5219\u8FD4\u56DEnull\n if (isExpired && hideWhenExpired) {\n return null\n }\n\n return (\n <div\n ref={ref}\n className={cn(countdownVariants({ variant }), className)}\n role=\"timer\"\n aria-live=\"polite\"\n aria-label=\"countdown timer\"\n {...props}\n >\n {/* \u5929 */}\n <div className={cn(timeBlockVariants({ variant }), 'time-days-box')}>\n <div className={timeNumberVariants()}>{pad(days, 2)}</div>\n <div className=\"truncate text-center text-[12px] font-bold\">{finalTimeLabels.day}</div>\n </div>\n\n <div className={separatorVariants({ variant })}>{separator}</div>\n\n {/* \u65F6 */}\n <div className={cn(timeBlockVariants({ variant }), 'time-hours-box')}>\n <div className={timeNumberVariants()}>{pad(hours, 2)}</div>\n <div className=\"truncate text-center text-[12px] font-bold\">{finalTimeLabels.hour}</div>\n </div>\n\n <div className={separatorVariants({ variant })}>{separator}</div>\n\n {/* \u5206 */}\n <div className={cn(timeBlockVariants({ variant }), 'time-minutes-box')}>\n <div className={timeNumberVariants()}>{pad(minutes, 2)}</div>\n <div className=\"truncate text-center text-[12px] font-bold\">{finalTimeLabels.minute}</div>\n </div>\n\n <div className={separatorVariants({ variant })}>{separator}</div>\n\n {/* \u79D2 */}\n <div className={cn(timeBlockVariants({ variant }), 'time-seconds-box')}>\n <div className={timeNumberVariants()}>{pad(seconds, 2)}</div>\n <div className=\"truncate text-center text-[12px] font-bold\">{finalTimeLabels.second}</div>\n </div>\n </div>\n )\n }\n)\n\nCountdown.displayName = 'Countdown'\n\nexport default Countdown\n"],
|
|
5
|
-
"mappings": "
|
|
6
|
-
"names": ["jsx", "jsxs", "React", "useEffect", "useRef", "useState", "useMemo", "cva", "cn", "countdownVariants", "timeBlockVariants", "timeNumberVariants", "separatorVariants", "pad", "n", "len", "getDefaultTimeLabels", "safeStringToObject", "str", "jsonStr", "Countdown", "className", "endDate", "endDate_tz", "locale", "timeLabels", "dateFormat", "onExpire", "separator", "hideWhenExpired", "variant", "props", "ref", "finalTimeLabels", "targetMsRef", "remainingMs", "setRemainingMs", "t", "isExpired", "setIsExpired", "newRemaining", "newIsExpired", "expiredCalled", "tick", "now", "remaining", "intervalId", "totalSeconds", "seconds", "totalMinutes", "minutes", "totalHours", "hours", "days", "Countdown_default"]
|
|
4
|
+
"sourcesContent": ["'use client'\n\nimport React, { useEffect, useRef, useState, useMemo } from 'react'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { cn } from '../helpers/index.js'\n\n// \u5B9A\u4E49\u6837\u5F0F\u53D8\u4F53\nconst countdownVariants = cva(\n // \u57FA\u7840\u6837\u5F0F\uFF1A\u5012\u8BA1\u65F6\u5BB9\u5668\n 'countdown-container flex w-full items-center',\n {\n variants: {\n variant: {\n outline: 'gap-1',\n spacious: 'gap-1',\n },\n align: {\n left: 'justify-start',\n center: 'justify-center',\n },\n },\n defaultVariants: {\n variant: 'outline',\n align: 'left',\n },\n }\n)\n\nconst timeBlockVariants = cva(\n // \u57FA\u7840\u6837\u5F0F\uFF1A\u65F6\u95F4\u5757\n 'time-block border-box rounded-box-small flex flex-col items-center justify-center overflow-hidden text-center text-xs',\n {\n variants: {\n variant: {\n outline:\n 'border-info-primary text-info-primary desktop:size-12 desktop:p-1 size-10 border bg-transparent p-[2px]',\n spacious: 'bg-info-white text-info-primary desktop:size-12 desktop:p-1 size-10 p-[2px]',\n },\n },\n defaultVariants: {\n variant: 'outline',\n },\n }\n)\n\nconst timeNumberVariants = cva(\n 'time-number lg-desktop:text-[24px] desktop:leading-[120%] translate-y-[2px] whitespace-nowrap text-center text-[20px] font-bold leading-none'\n)\n\nconst separatorVariants = cva(\n // \u57FA\u7840\u6837\u5F0F\uFF1A\u5206\u9694\u7B26\n 'separator desktop:text-2xl text-xl font-bold',\n {\n variants: {\n variant: {\n outline: 'text-info-primary',\n spacious: 'text-info-primary',\n },\n },\n defaultVariants: {\n variant: 'outline',\n },\n }\n)\n\n/**\n * \u65F6\u95F4\u6807\u7B7E\u914D\u7F6E\u63A5\u53E3\n */\nexport interface TimeLabels {\n /** \u5929\u7684\u6807\u7B7E */\n day: string\n /** \u5C0F\u65F6\u7684\u6807\u7B7E */\n hour: string\n /** \u5206\u949F\u7684\u6807\u7B7E */\n minute: string\n /** \u79D2\u7684\u6807\u7B7E */\n second: string\n}\n\n/**\n * \u5012\u8BA1\u65F6\u7EC4\u4EF6Props\u63A5\u53E3\n */\nexport interface CountdownProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onExpire'>, VariantProps<typeof countdownVariants> {\n /** \u7ED3\u675F\u65F6\u95F4 - ISO\u683C\u5F0F\u5B57\u7B26\u4E32 */\n endDate: string\n /** \u7ED3\u675F\u65F6\u95F4\u65F6\u533A\uFF0C\u5982: America/Los_Angeles */\n endDate_tz?: string\n /** \u683C\u5F0F\u5316\u7528\u7684locale\uFF0C\u9ED8\u8BA4\u4F7F\u7528navigator.language */\n locale?: string\n /** \u65F6\u95F4\u6807\u7B7E\u914D\u7F6E\uFF0C\u7528\u4E8E\u56FD\u9645\u5316 */\n timeLabels?: TimeLabels\n /** JSON\u5B57\u7B26\u4E32\u683C\u5F0F\u7684\u65F6\u95F4\u6807\u7B7E\uFF08\u5411\u540E\u517C\u5BB9\uFF09 */\n dateFormat?: string\n /** \u5012\u8BA1\u65F6\u7ED3\u675F\u56DE\u8C03 */\n onExpire?: () => void\n /** \u5206\u9694\u7B26\u5B57\u7B26\uFF0C\u9ED8\u8BA4\u4E3A ':' */\n separator?: string\n /** \u9690\u85CF\u5DF2\u8FC7\u671F\u7684\u5012\u8BA1\u65F6\uFF0C\u9ED8\u8BA4\u4E3A true */\n hideWhenExpired?: boolean\n}\n\n/**\n * \u6570\u5B57\u8865\u96F6\u51FD\u6570\n */\nconst pad = (n: number, len = 2) => String(Math.abs(n)).padStart(len, '0')\n\n/**\n * \u9ED8\u8BA4\u65F6\u95F4\u6807\u7B7E\n */\nconst getDefaultTimeLabels = (): TimeLabels => ({\n day: 'Day',\n hour: 'Hours',\n minute: 'Mins',\n second: 'Secs',\n})\n\n/**\n * \u89E3\u6790dateFormat JSON\u5B57\u7B26\u4E32\uFF08\u5411\u540E\u517C\u5BB9\uFF09\n */\nconst safeStringToObject = (str: string): TimeLabels => {\n try {\n let jsonStr = str?.trim?.()\n if (!jsonStr?.startsWith?.('{') || !jsonStr?.endsWith?.('}')) {\n return getDefaultTimeLabels()\n }\n jsonStr = jsonStr?.replace?.(/(\\w+)\\s*:/g, '\"$1\":')\n return { ...getDefaultTimeLabels(), ...JSON.parse(jsonStr) }\n } catch (err) {\n return getDefaultTimeLabels()\n }\n}\n\n/**\n * Countdown - \u5012\u8BA1\u65F6\u539F\u5B50\u7EC4\u4EF6\n *\n * @description \u7528\u4E8E\u663E\u793A\u5012\u8BA1\u65F6\u7684\u7EC4\u4EF6\uFF0C\u652F\u6301\u5929\u3001\u65F6\u3001\u5206\u3001\u79D2\u663E\u793A\uFF0C\u652F\u6301\u591A\u79CD\u6837\u5F0F\u53D8\u4F53\u548C\u5C3A\u5BF8\n */\nconst Countdown = React.forwardRef<HTMLDivElement, CountdownProps>(\n (\n {\n className,\n endDate,\n endDate_tz,\n locale,\n timeLabels,\n dateFormat,\n onExpire,\n separator = ':',\n hideWhenExpired = true,\n variant,\n align,\n ...props\n },\n ref\n ) => {\n // \u786E\u5B9A\u6700\u7EC8\u4F7F\u7528\u7684\u65F6\u95F4\u6807\u7B7E\n const finalTimeLabels = useMemo(() => {\n if (timeLabels) return timeLabels\n if (dateFormat) return safeStringToObject(dateFormat)\n return getDefaultTimeLabels()\n }, [timeLabels, dateFormat])\n\n // \u89E3\u6790\u76EE\u6807\u65F6\u95F4\n const targetMsRef = useRef<number>(Date.parse(endDate))\n const [remainingMs, setRemainingMs] = useState<number>(() => {\n const t = targetMsRef.current\n return isNaN(t) ? 0 : Math.max(0, t - Date.now())\n })\n\n // \u5224\u65AD\u662F\u5426\u5DF2\u8FC7\u671F\n const [isExpired, setIsExpired] = useState<boolean>(() => {\n const t = targetMsRef.current\n return !isNaN(t) && t <= Date.now()\n })\n\n // \u5F53endDate\u6539\u53D8\u65F6\u66F4\u65B0\u76EE\u6807\u65F6\u95F4\n useEffect(() => {\n targetMsRef.current = Date.parse(endDate)\n const t = targetMsRef.current\n const newRemaining = isNaN(t) ? 0 : Math.max(0, t - Date.now())\n const newIsExpired = !isNaN(t) && t <= Date.now()\n\n setRemainingMs(newRemaining)\n setIsExpired(newIsExpired)\n }, [endDate])\n\n // \u542F\u52A8\u5012\u8BA1\u65F6\u5B9A\u65F6\u5668\n useEffect(() => {\n if (isExpired) return // \u5DF2\u8FC7\u671F\u5219\u4E0D\u542F\u52A8\n if (isNaN(targetMsRef.current)) return // \u65E0\u6548\u65E5\u671F\u4E0D\u542F\u52A8\n\n let expiredCalled = false\n const tick = () => {\n const now = Date.now()\n const remaining = Math.max(0, targetMsRef.current - now)\n setRemainingMs(remaining)\n\n if (remaining <= 0 && !expiredCalled) {\n expiredCalled = true\n setIsExpired(true)\n onExpire?.()\n }\n }\n\n tick() // \u7ACB\u5373\u6267\u884C\u4E00\u6B21\n const intervalId = window.setInterval(tick, 1000)\n\n return () => clearInterval(intervalId)\n }, [onExpire, isExpired, endDate])\n\n // \u8BA1\u7B97\u65F6\u95F4\u5355\u4F4D\n const totalSeconds = Math.floor(remainingMs / 1000)\n const seconds = totalSeconds % 60\n const totalMinutes = Math.floor(totalSeconds / 60)\n const minutes = totalMinutes % 60\n const totalHours = Math.floor(totalMinutes / 60)\n const hours = totalHours % 24\n const days = Math.floor(totalHours / 24)\n\n // \u5982\u679C\u5DF2\u8FC7\u671F\u4E14\u9700\u8981\u9690\u85CF\uFF0C\u5219\u8FD4\u56DEnull\n if (isExpired && hideWhenExpired) {\n return null\n }\n\n return (\n <div\n ref={ref}\n className={cn(countdownVariants({ variant, align }), className)}\n role=\"timer\"\n aria-live=\"polite\"\n aria-label=\"countdown timer\"\n {...props}\n >\n {/* \u5929 */}\n <div className={cn(timeBlockVariants({ variant }), 'time-days-box')}>\n <div className={timeNumberVariants()}>{pad(days, 2)}</div>\n <div className=\"truncate text-center text-[12px] font-bold\">{finalTimeLabels.day}</div>\n </div>\n\n <div className={separatorVariants({ variant })}>{separator}</div>\n\n {/* \u65F6 */}\n <div className={cn(timeBlockVariants({ variant }), 'time-hours-box')}>\n <div className={timeNumberVariants()}>{pad(hours, 2)}</div>\n <div className=\"truncate text-center text-[12px] font-bold\">{finalTimeLabels.hour}</div>\n </div>\n\n <div className={separatorVariants({ variant })}>{separator}</div>\n\n {/* \u5206 */}\n <div className={cn(timeBlockVariants({ variant }), 'time-minutes-box')}>\n <div className={timeNumberVariants()}>{pad(minutes, 2)}</div>\n <div className=\"truncate text-center text-[12px] font-bold\">{finalTimeLabels.minute}</div>\n </div>\n\n <div className={separatorVariants({ variant })}>{separator}</div>\n\n {/* \u79D2 */}\n <div className={cn(timeBlockVariants({ variant }), 'time-seconds-box')}>\n <div className={timeNumberVariants()}>{pad(seconds, 2)}</div>\n <div className=\"truncate text-center text-[12px] font-bold\">{finalTimeLabels.second}</div>\n </div>\n </div>\n )\n }\n)\n\nCountdown.displayName = 'Countdown'\n\nexport default Countdown\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["jsx", "jsxs", "React", "useEffect", "useRef", "useState", "useMemo", "cva", "cn", "countdownVariants", "timeBlockVariants", "timeNumberVariants", "separatorVariants", "pad", "n", "len", "getDefaultTimeLabels", "safeStringToObject", "str", "jsonStr", "Countdown", "className", "endDate", "endDate_tz", "locale", "timeLabels", "dateFormat", "onExpire", "separator", "hideWhenExpired", "variant", "align", "props", "ref", "finalTimeLabels", "targetMsRef", "remainingMs", "setRemainingMs", "t", "isExpired", "setIsExpired", "newRemaining", "newIsExpired", "expiredCalled", "tick", "now", "remaining", "intervalId", "totalSeconds", "seconds", "totalMinutes", "minutes", "totalHours", "hours", "days", "Countdown_default"]
|
|
7
7
|
}
|
package/package.json
CHANGED