@anker-in/headless-ui 1.3.78 → 1.3.79

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.
Files changed (45) hide show
  1. package/dist/cjs/biz-components/HeroBanner/HeroBanner.js +1 -1
  2. package/dist/cjs/biz-components/HeroBanner/HeroBannerCarousel.d.ts +9 -10
  3. package/dist/cjs/biz-components/HeroBanner/HeroBannerCarousel.js +1 -1
  4. package/dist/cjs/biz-components/HeroBanner/index.d.ts +3 -0
  5. package/dist/cjs/biz-components/HeroBanner/index.js +1 -1
  6. package/dist/cjs/biz-components/HeroBanner/mediaResolver.d.ts +58 -0
  7. package/dist/cjs/biz-components/HeroBanner/mediaResolver.js +1 -0
  8. package/dist/cjs/biz-components/HeroBanner/types.d.ts +116 -8
  9. package/dist/cjs/biz-components/HeroBanner/types.js +1 -1
  10. package/dist/cjs/biz-components/SecondaryBanner/SecondaryBannerCarousel.d.ts +9 -9
  11. package/dist/cjs/biz-components/SecondaryBanner/SecondaryBannerCarousel.js +1 -1
  12. package/dist/cjs/biz-components/SecondaryBanner/index.d.ts +53 -6
  13. package/dist/cjs/biz-components/SecondaryBanner/index.js +1 -1
  14. package/dist/cjs/biz-components/index.d.ts +1 -0
  15. package/dist/cjs/biz-components/index.js +1 -1
  16. package/dist/cjs/helpers/ScrollLoadVideo.js +1 -1
  17. package/dist/cjs/hooks/useCarouselPlayback.d.ts +110 -0
  18. package/dist/cjs/hooks/useCarouselPlayback.js +1 -0
  19. package/dist/cjs/index.d.ts +4 -0
  20. package/dist/cjs/index.js +1 -1
  21. package/dist/cjs/shared/CarouselControls.d.ts +75 -0
  22. package/dist/cjs/shared/CarouselControls.js +1 -0
  23. package/dist/esm/biz-components/HeroBanner/HeroBanner.js +1 -1
  24. package/dist/esm/biz-components/HeroBanner/HeroBannerCarousel.d.ts +9 -10
  25. package/dist/esm/biz-components/HeroBanner/HeroBannerCarousel.js +1 -1
  26. package/dist/esm/biz-components/HeroBanner/index.d.ts +3 -0
  27. package/dist/esm/biz-components/HeroBanner/index.js +1 -1
  28. package/dist/esm/biz-components/HeroBanner/mediaResolver.d.ts +58 -0
  29. package/dist/esm/biz-components/HeroBanner/mediaResolver.js +1 -0
  30. package/dist/esm/biz-components/HeroBanner/types.d.ts +116 -8
  31. package/dist/esm/biz-components/SecondaryBanner/SecondaryBannerCarousel.d.ts +9 -9
  32. package/dist/esm/biz-components/SecondaryBanner/SecondaryBannerCarousel.js +1 -1
  33. package/dist/esm/biz-components/SecondaryBanner/index.d.ts +53 -6
  34. package/dist/esm/biz-components/SecondaryBanner/index.js +1 -1
  35. package/dist/esm/biz-components/index.d.ts +1 -0
  36. package/dist/esm/biz-components/index.js +1 -1
  37. package/dist/esm/helpers/ScrollLoadVideo.js +1 -1
  38. package/dist/esm/hooks/useCarouselPlayback.d.ts +110 -0
  39. package/dist/esm/hooks/useCarouselPlayback.js +1 -0
  40. package/dist/esm/index.d.ts +4 -0
  41. package/dist/esm/index.js +1 -1
  42. package/dist/esm/shared/CarouselControls.d.ts +75 -0
  43. package/dist/esm/shared/CarouselControls.js +1 -0
  44. package/package.json +1 -1
  45. package/style.css +32 -23
@@ -0,0 +1,110 @@
1
+ import { type MutableRefObject } from 'react';
2
+ import type { Swiper as SwiperType } from 'swiper';
3
+ /**
4
+ * 2-state carousel playback machine (final interaction matrix 2026-10-12):
5
+ * - AUTOPLAYING: the hook's own countdown timer drives slideNext; progress fill runs
6
+ * - STOPPED: manual pause via the ⏸/▶ button; resumed via ▶ — OR implicitly
7
+ * reset to AUTOPLAYING by ANY manual navigation (arrow / swipe / replay)
8
+ * PC hover has NO effect on the carousel (removed in the interaction-matrix revision).
9
+ *
10
+ * 2026-10-10 beta-bugfix round: the countdown timer is SELF-OWNED
11
+ * (setTimeout + remaining-ms bookkeeping) instead of delegating to Swiper's
12
+ * Autoplay module, whose internal transitionend/touchEnd resume() resurrected
13
+ * stopped carousels (CODING #1452/#1460) and fell back to the module default
14
+ * delay on frames without data-swiper-autoplay (#1453). Keyboard focus within
15
+ * the carousel freezes the countdown until focus leaves (WCAG 2.2.2, #1461).
16
+ *
17
+ * 2026-10-12 final matrix: navigation no longer stops autoplay — the earlier
18
+ * swipe→STOPPED (D4) / arrow-keeps-STOPPED semantics were superseded by the
19
+ * product matrix (arrow/swipe/replay all reset to AUTOPLAYING + fresh budget).
20
+ */
21
+ export type CarouselPlaybackState = 'AUTOPLAYING' | 'STOPPED';
22
+ /**
23
+ * What caused a slide change. `initial` is reserved for the consumer's mount
24
+ * emission; the hook itself only produces autoplay / arrow / swipe.
25
+ */
26
+ export type CarouselSlideTrigger = 'initial' | 'autoplay' | 'arrow' | 'swipe';
27
+ export interface UseCarouselPlaybackOptions {
28
+ /** Total slide count */
29
+ frameCount: number;
30
+ /** Resolve the effective autoplay interval (seconds) for a frame; undefined = the frame holds */
31
+ resolveFrameIntervalSec: (index: number) => number | undefined;
32
+ /** Master gate: autoplay runs only when true (valid intervals AND frameCount > 1) */
33
+ isAutoplayEnabled: boolean;
34
+ /** Ref holding the live Swiper instance (populated via handleSwiperInit) */
35
+ swiperRef: MutableRefObject<SwiperType | null>;
36
+ /** Noun used in the aria-live announcement: `${slideStatusLabel} ${n} / ${total}` */
37
+ slideStatusLabel: string;
38
+ /**
39
+ * Optional media choreography on slide change (e.g. pause outgoing videos,
40
+ * play the incoming one). Image-only carousels omit this.
41
+ */
42
+ onSlideMediaSync?: (newIndex: number) => void;
43
+ /** Fired when the active slide changes, with the cause of the change */
44
+ onSlideChange?: (newIndex: number, trigger: CarouselSlideTrigger) => void;
45
+ /** Fired on arrow navigation, before Swiper confirms the transition */
46
+ onArrowNavigate?: (direction: 'prev' | 'next', fromIndex: number, toIndex: number) => void;
47
+ /** Fired when the pause/play button toggles playback (paused = entered STOPPED) */
48
+ onPauseToggle?: (paused: boolean, activeIndex: number) => void;
49
+ /**
50
+ * 1488: per-frame gate — video frames return true so the countdown RESTARTS
51
+ * with a fresh full budget when the frame's video actually starts playing
52
+ * (slow networks: the poster window no longer eats the frame's interval).
53
+ * If the video never plays, the activation-time budget still ticks away as
54
+ * the fallback deadline, so the frame can never stall forever.
55
+ */
56
+ delaysCountdownForVideo?: (index: number) => boolean;
57
+ }
58
+ export interface UseCarouselPlaybackResult {
59
+ /** Attach to the carousel root element (merge with any forwarded ref) */
60
+ rootRef: MutableRefObject<Element | null>;
61
+ activeIndex: number;
62
+ playbackState: CarouselPlaybackState;
63
+ /** Bump-key for the progress-fill CSS animation; changes restart the fill */
64
+ resetNonce: number;
65
+ /** aria-live announcement text for manual slide switches (D16) */
66
+ announcement: string;
67
+ /** Effective autoplay interval (seconds) of the active frame; undefined = hold */
68
+ activeFrameIntervalSec: number | undefined;
69
+ /**
70
+ * True while the frame countdown is actually ticking. Drives the progress
71
+ * fill's animationPlayState so the visual fill and the real timer can never
72
+ * desync (unlike the old Swiper-module design).
73
+ */
74
+ isTimerRunning: boolean;
75
+ /** Wire to Swiper's onSwiper — stores the instance and syncs slide a11y */
76
+ handleSwiperInit: (swiper: SwiperType) => void;
77
+ handleSlideChange: (swiper: SwiperType) => void;
78
+ /** Wire to Swiper's onSlideChangeTransitionEnd — re-syncs inert/aria-hidden after loopFix */
79
+ handleTransitionEnd: (swiper: SwiperType) => void;
80
+ handleSliderFirstMove: (swiper: SwiperType, event: TouchEvent) => void;
81
+ goToSlide: (direction: 'prev' | 'next') => void;
82
+ /** Jump to an arbitrary frame (progress-segment click). Same reset semantics as arrows. */
83
+ goToSlideIndex: (index: number) => void;
84
+ handlePausePlayClick: () => void;
85
+ /**
86
+ * Replay path (final matrix): reset to AUTOPLAYING and restart the current
87
+ * frame with a fresh full countdown (进度圆点从0重新填充).
88
+ */
89
+ resumeWithFreshCountdown: () => void;
90
+ /** 1488: 视频帧开始真实播放时调用——重启该帧倒计时(每次进场仅生效一次) */
91
+ notifyVideoPlaying: (index: number) => void;
92
+ /** Attach to the carousel root: keyboard focus freezes the countdown (#1461) */
93
+ handleFocus: () => void;
94
+ handleBlur: (e: React.FocusEvent<HTMLElement>) => void;
95
+ }
96
+ /**
97
+ * useCarouselPlayback — shared carousel interaction state machine + countdown.
98
+ *
99
+ * Owns: playback state machine, self-managed countdown timer (with true
100
+ * freeze/resume), pause/play toggle, IntersectionObserver viewport gating
101
+ * (D17), keyboard-focus gating (WCAG 2.2.2), touch-swipe detection (D4),
102
+ * aria-live announcements (D16), slide inert/aria-hidden sync (#1461) and the
103
+ * progress-fill restart nonce.
104
+ *
105
+ * Video-specific behavior (play-once on STOPPED, replay button, multi-theme)
106
+ * is intentionally NOT here — consumers wire it off the returned
107
+ * playbackState/activeIndex so image-only carousels get a clean subset.
108
+ */
109
+ export declare const useCarouselPlayback: (options: UseCarouselPlaybackOptions) => UseCarouselPlaybackResult;
110
+ export default useCarouselPlayback;
@@ -0,0 +1 @@
1
+ "use client";import{useCallback as o,useEffect as u,useRef as t,useState as y}from"react";const ue=x=>{const{frameCount:R,resolveFrameIntervalSec:B,isAutoplayEnabled:S,swiperRef:s,slideStatusLabel:Y}=x,C=t(null),E=t(!1),T=t(!1),[c,L]=y(0),[$,g]=y(0),[H,k]=y(""),[w,p]=y(S?"AUTOPLAYING":"STOPPED"),[q,K]=y(!0),[z,D]=y(!1),O=t(w);u(()=>{O.current=w},[w]);const a=t(c);u(()=>{a.current=c},[c]);const h=t(R);u(()=>{h.current=R});const v=t(S);u(()=>{v.current=S});const I=t(Y);u(()=>{I.current=Y});const l=t(x);u(()=>{l.current=x});const d=B(c),N=S&&R>1&&w==="AUTOPLAYING"&&q&&!z&&d!==void 0,m=t(null),V=t(0),W=t(0),F=t(null),b=t({index:c,interval:d}),M=t(null),_=o(e=>{l.current.delaysCountdownForVideo?.(e)&&e===a.current&&M.current!==e&&(M.current=e,b.current={index:-1,interval:void 0},g(n=>n+1))},[]),A=o(()=>{m.current!=null&&(clearTimeout(m.current),m.current=null)},[]),U=o(()=>{if(m.current!=null){const e=Date.now()-V.current;F.current=Math.max(0,W.current-e),A()}},[A]),j=o(()=>{m.current=null;const e=s.current;!e||e.destroyed||e.slideNext()},[s]);u(()=>{const e=b.current.index===-1;if((b.current.index!==c||b.current.interval!==d)&&(b.current={index:c,interval:d},F.current=null,e||(M.current=null)),!N||d===void 0){U();return}const n=F.current??d*1e3;return W.current=n,V.current=Date.now(),m.current=setTimeout(j,n),U},[N,c,d,$,j,U]),u(()=>A,[A]),u(()=>{const e=C.current;if(!e||typeof IntersectionObserver>"u")return;const n=new IntersectionObserver(r=>{const i=r[0];i&&K(i.isIntersecting)},{threshold:.1});return n.observe(e),()=>n.disconnect()},[]);const f=o(()=>{const e=C.current;if(!e||typeof e.querySelectorAll!="function")return;const n=e.querySelectorAll(".swiper-slide");!n.length||!Array.from(n).some(i=>i.classList.contains("swiper-slide-active"))||n.forEach(i=>{const P=i.classList.contains("swiper-slide-active");i.toggleAttribute("inert",!P),P?i.removeAttribute("aria-hidden"):i.setAttribute("aria-hidden","true")})},[]),J=o(e=>{s.current=e,f()},[s,f]);u(()=>{f()},[f]);const Q=o(()=>{f()},[f]),X=o(e=>{const n=e.realIndex;l.current.onSlideMediaSync?.(n);let r=null;E.current?(E.current=!1,k(`${I.current} ${n+1} / ${h.current}`),v.current&&p("AUTOPLAYING"),r="swipe"):T.current?(T.current=!1,r="arrow"):O.current==="AUTOPLAYING"&&(r="autoplay"),L(n),r&&l.current.onSlideChange?.(n,r),f()},[f]),Z=o(e=>{const n=h.current;if(n<2)return;const r=a.current,i=e==="next"?(r+1)%n:(r-1+n)%n;k(`${I.current} ${i+1} / ${n}`),L(i),T.current=!0,e==="next"?s.current?.slideNext():s.current?.slidePrev(),v.current&&(p("AUTOPLAYING"),g(P=>P+1)),l.current.onArrowNavigate?.(e,r,i)},[s]),ee=o(e=>{const n=h.current;n<2||e===a.current||e<0||e>=n||(k(`${I.current} ${e+1} / ${n}`),L(e),T.current=!0,s.current?.slideToLoop(e),v.current&&(p("AUTOPLAYING"),g(r=>r+1)),l.current.onArrowNavigate?.(e>a.current?"next":"prev",a.current,e))},[s]),ne=o(()=>{v.current&&(b.current={index:-1,interval:void 0},p("AUTOPLAYING"),g(e=>e+1))},[]),re=o(()=>{v.current&&(O.current==="STOPPED"?(p("AUTOPLAYING"),l.current.onPauseToggle?.(!1,a.current)):(p("STOPPED"),l.current.onPauseToggle?.(!0,a.current)))},[]),te=o((e,n)=>{const r=n.pointerType;E.current=r!=="mouse"},[]),G=t(!1);u(()=>{const e=r=>{r.key==="Tab"&&(G.current=!0)},n=()=>{G.current=!1};return window.addEventListener("keydown",e),window.addEventListener("pointerdown",n),()=>{window.removeEventListener("keydown",e),window.removeEventListener("pointerdown",n)}},[]);const oe=o(()=>{G.current&&D(!0)},[]),ie=o(e=>{e.currentTarget.contains(e.relatedTarget)||D(!1)},[]);return{rootRef:C,activeIndex:c,playbackState:w,resetNonce:$,announcement:H,activeFrameIntervalSec:d,isTimerRunning:N,handleSwiperInit:J,handleSlideChange:X,handleTransitionEnd:Q,handleSliderFirstMove:te,goToSlide:Z,goToSlideIndex:ee,handlePausePlayClick:re,resumeWithFreshCountdown:ne,notifyVideoPlaying:_,handleFocus:oe,handleBlur:ie}};var ce=ue;export{ce as default,ue as useCarouselPlayback};
@@ -10,6 +10,10 @@ export { useGridRowCount } from './hooks/useGridRowCount.js';
10
10
  export { useIntersectionObserverDelay } from './hooks/useIntersectionObserver.js';
11
11
  export { useRollout } from './hooks/useRollout.js';
12
12
  export { useViewItemList } from './hooks/useViewItemList.js';
13
+ export { useCarouselPlayback } from './hooks/useCarouselPlayback.js';
14
+ export type { CarouselPlaybackState, CarouselSlideTrigger, UseCarouselPlaybackOptions, UseCarouselPlaybackResult, } from './hooks/useCarouselPlayback.js';
13
15
  export { cn, getLocalizedPath, noop } from './helpers/index.js';
14
16
  export { formatPrice, languageTerritory, PRICE_SYMBOL } from './helpers/index.js';
15
17
  export { LocalizedLink, type LocalizedLinkProps } from './shared/LocalizedLink.js';
18
+ export { CarouselArrows, CarouselProgressControls } from './shared/CarouselControls.js';
19
+ export type { CarouselArrowsProps, CarouselProgressControlsProps } from './shared/CarouselControls.js';
package/dist/esm/index.js CHANGED
@@ -1 +1 @@
1
- export*from"./components/index.js";import{gaTrack as t}from"./shared/track.js";import{trackUrlRef as s,buildTrackingRef as a}from"./shared/trackUrlRef.js";import{default as m}from"./hooks/useCountDown.js";import{useDraggableScroll as f}from"./hooks/useDraggableScroll.js";import{useExposure as u}from"./hooks/useExposure.js";import{useGridRowCount as c}from"./hooks/useGridRowCount.js";import{useIntersectionObserverDelay as g}from"./hooks/useIntersectionObserver.js";import{useRollout as C}from"./hooks/useRollout.js";import{useViewItemList as L}from"./hooks/useViewItemList.js";import{cn as R,getLocalizedPath as b,noop as T}from"./helpers/index.js";import{formatPrice as D,languageTerritory as E,PRICE_SYMBOL as I}from"./helpers/index.js";import{LocalizedLink as v}from"./shared/LocalizedLink.js";export{v as LocalizedLink,I as PRICE_SYMBOL,a as buildTrackingRef,R as cn,D as formatPrice,t as gaTrack,b as getLocalizedPath,E as languageTerritory,T as noop,s as trackUrlRef,m as useCountDown,f as useDraggableScroll,u as useExposure,c as useGridRowCount,g as useIntersectionObserverDelay,C as useRollout,L as useViewItemList};
1
+ export*from"./components/index.js";import{gaTrack as s}from"./shared/track.js";import{trackUrlRef as t,buildTrackingRef as p}from"./shared/trackUrlRef.js";import{default as u}from"./hooks/useCountDown.js";import{useDraggableScroll as m}from"./hooks/useDraggableScroll.js";import{useExposure as f}from"./hooks/useExposure.js";import{useGridRowCount as C}from"./hooks/useGridRowCount.js";import{useIntersectionObserverDelay as P}from"./hooks/useIntersectionObserver.js";import{useRollout as d}from"./hooks/useRollout.js";import{useViewItemList as k}from"./hooks/useViewItemList.js";import{useCarouselPlayback as L}from"./hooks/useCarouselPlayback.js";import{cn as T,getLocalizedPath as h,noop as w}from"./helpers/index.js";import{formatPrice as j,languageTerritory as z,PRICE_SYMBOL as A}from"./helpers/index.js";import{LocalizedLink as E}from"./shared/LocalizedLink.js";import{CarouselArrows as O,CarouselProgressControls as v}from"./shared/CarouselControls.js";export{O as CarouselArrows,v as CarouselProgressControls,E as LocalizedLink,A as PRICE_SYMBOL,p as buildTrackingRef,T as cn,j as formatPrice,s as gaTrack,h as getLocalizedPath,z as languageTerritory,w as noop,t as trackUrlRef,L as useCarouselPlayback,u as useCountDown,m as useDraggableScroll,f as useExposure,C as useGridRowCount,P as useIntersectionObserverDelay,d as useRollout,k as useViewItemList};
@@ -0,0 +1,75 @@
1
+ export declare const CarouselChevronLeft: () => import("react/jsx-runtime").JSX.Element;
2
+ export declare const CarouselChevronRight: () => import("react/jsx-runtime").JSX.Element;
3
+ export declare const PauseIcon: () => import("react/jsx-runtime").JSX.Element;
4
+ export declare const PlayIcon: () => import("react/jsx-runtime").JSX.Element;
5
+ export interface CarouselArrowsProps {
6
+ onPrev: () => void;
7
+ onNext: () => void;
8
+ prevLabel: string;
9
+ nextLabel: string;
10
+ }
11
+ /**
12
+ * Prev/next arrow overlay. Visible ≥1025 only (D12): hidden below laptop,
13
+ * revealed on group hover / focus-within above it. Rendered at z-20, above
14
+ * any blockLink overlay (z-10).
15
+ */
16
+ export declare const CarouselArrows: ({ onPrev, onNext, prevLabel, nextLabel }: CarouselArrowsProps) => import("react/jsx-runtime").JSX.Element;
17
+ export interface CarouselCornerToggleProps {
18
+ isPaused: boolean;
19
+ onToggle: () => void;
20
+ /** aria-label while paused (shows ▶) */
21
+ pausedLabel: string;
22
+ /** aria-label while playing (shows ⏸) */
23
+ playingLabel: string;
24
+ /** Class prefix, e.g. 'hero-banner' / 'secondary-banner' */
25
+ classPrefix: string;
26
+ /** Same theme axis as the progress controls; defaults to 'light' */
27
+ theme?: 'light' | 'dark';
28
+ }
29
+ /**
30
+ * 合并后的暂停/播放按钮(交互收敛 2026-10):轮播与视频共用一个右下角
31
+ * 圆钮——尺寸与样式与原 dots 区 ⏸ 完全一致(size-8 玻璃材质)。调用方按
32
+ * 当前帧语义决定 isPaused 的状态源(轮播状态机 或 视频真实状态)与点击
33
+ * 行为(同停同播 或 纯视频直控)。
34
+ */
35
+ export declare const CarouselCornerToggle: ({ isPaused, onToggle, pausedLabel, playingLabel, classPrefix, theme, }: CarouselCornerToggleProps) => import("react/jsx-runtime").JSX.Element;
36
+ export interface CarouselProgressControlsProps {
37
+ frameCount: number;
38
+ activeIndex: number;
39
+ /** Change restarts the active segment's fill animation */
40
+ resetNonce: number;
41
+ /** Active frame interval (seconds); undefined = static full segment */
42
+ activeFrameIntervalSec: number | undefined;
43
+ isAutoplayEnabled: boolean;
44
+ /** True while the countdown timer is actually ticking (drives fill playState) */
45
+ isTimerRunning: boolean;
46
+ /**
47
+ * Optional segment click-to-jump handler (1467): when provided, progress
48
+ * segments become focusable buttons that jump to the frame (SecondaryBanner
49
+ * legacy behavior). Omit to keep segments display-only (HeroBanner).
50
+ */
51
+ onSegmentClick?: (index: number) => void;
52
+ /** Accessible label per segment, e.g. (i) => `Go to slide ${i + 1}` */
53
+ segmentLabel?: (index: number) => string;
54
+ /** Class/keyframes prefix, e.g. 'hero-banner' / 'secondary-banner' */
55
+ classPrefix: string;
56
+ /**
57
+ * Frame theme (same axis as the banner content): 'light' = dark text over
58
+ * light media → dark-glass controls; 'dark' = white text over dark media
59
+ * → light-glass controls. Defaults to 'light'.
60
+ */
61
+ theme?: 'light' | 'dark';
62
+ }
63
+ /**
64
+ * Segmented progress capsule, centered at the bottom (Figma 6349:5115:
65
+ * capsule 144×32 with an inset 112×8 indicator row, 8px gap). Material
66
+ * follows the frame theme: black-20% mask + dark icon on light media,
67
+ * white-20% mask + white icon on dark media. The active segment is a
68
+ * stretched white bar whose fill is a CSS animation keyed by
69
+ * `${activeIndex}-${resetNonce}`; animationPlayState freezes it outside
70
+ * AUTOPLAYING so the fill and the Swiper timer stay in sync — resume paths
71
+ * never bump resetNonce, so progress is never lost.
72
+ * 暂停/播放按钮已迁移至右下角 CarouselCornerToggle(交互收敛 2026-10)。
73
+ */
74
+ export declare const CarouselProgressControls: ({ frameCount, activeIndex, resetNonce, activeFrameIntervalSec, isAutoplayEnabled, isTimerRunning, onSegmentClick, segmentLabel, classPrefix, theme, }: CarouselProgressControlsProps) => import("react/jsx-runtime").JSX.Element;
75
+ export default CarouselProgressControls;
@@ -0,0 +1 @@
1
+ "use client";import{jsx as e,jsxs as c}from"react/jsx-runtime";import{cn as a}from"../helpers/index.js";const y=()=>c("svg",{className:"lg-desktop:size-14 size-10",viewBox:"0 0 40 40",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[e("circle",{cx:"20",cy:"20",r:"20",fill:"black",fillOpacity:"0.5"}),e("path",{d:"M23 14L17 19.5L23 25",stroke:"white",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})]}),k=()=>c("svg",{className:"lg-desktop:size-14 size-10",viewBox:"0 0 40 40",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[e("circle",{cx:"20",cy:"20",r:"20",fill:"black",fillOpacity:"0.5"}),e("path",{d:"M17 14L23 19.5L17 25",stroke:"white",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})]}),x=()=>c("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[e("rect",{x:"4",y:"3",width:"2.6",height:"10",rx:"1",fill:"currentColor"}),e("rect",{x:"9.4",y:"3",width:"2.6",height:"10",rx:"1",fill:"currentColor"})]}),C=()=>e("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:e("path",{d:"M5 3.5v9c0 .8.9 1.3 1.6.9l7-4.5c.6-.4.6-1.4 0-1.8l-7-4.5c-.7-.4-1.6.1-1.6.9Z",fill:"currentColor"})}),z=({onPrev:i,onNext:r,prevLabel:n,nextLabel:l})=>c("div",{className:"lg-desktop:px-8 pointer-events-none absolute inset-0 z-20 flex items-center justify-between px-4",children:[e("button",{type:"button",className:"laptop:flex pointer-events-auto hidden scale-95 items-center justify-center opacity-0 transition-all duration-300 ease-out hover:scale-105 focus-visible:scale-105 focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/80 active:scale-95 group-focus-within:scale-100 group-focus-within:opacity-100 group-hover:scale-100 group-hover:opacity-100",onClick:i,"aria-label":n,children:e(y,{})}),e("button",{type:"button",className:"laptop:flex pointer-events-auto hidden scale-95 items-center justify-center opacity-0 transition-all duration-300 ease-out hover:scale-105 focus-visible:scale-105 focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/80 active:scale-95 group-focus-within:scale-100 group-focus-within:opacity-100 group-hover:scale-100 group-hover:opacity-100",onClick:r,"aria-label":l,children:e(k,{})})]}),P=({isPaused:i,onToggle:r,pausedLabel:n,playingLabel:l,classPrefix:u,theme:g="light"})=>{const o=g==="light";return e("button",{type:"button",className:a(`${u}-corner-toggle lg-desktop:bottom-6 lg-desktop:right-8 absolute bottom-4 right-4 z-20 flex size-8 items-center justify-center rounded-full transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/80`,o?"bg-black/20 text-black/60 hover:bg-black/30 active:bg-black/40":"bg-white/20 text-white hover:bg-white/30 active:bg-white/40"),"aria-label":i?n:l,onClick:r,children:i?e(C,{}):e(x,{})})},N=({frameCount:i,activeIndex:r,resetNonce:n,activeFrameIntervalSec:l,isAutoplayEnabled:u,isTimerRunning:g,onSegmentClick:o,segmentLabel:v,classPrefix:t,theme:m="light"})=>{const w=`@keyframes ${t}-progress-fill{from{transform:scaleX(0)}to{transform:scaleX(1)}}`,p=m==="light";return c("div",{className:a(`${t}-controls lg-desktop:bottom-6 absolute bottom-4 left-1/2 z-20 flex -translate-x-1/2 items-center gap-2`),children:[e("style",{children:w}),e("div",{className:a(`${t}-progress flex h-8 items-center gap-2 rounded-full px-4`,p?"bg-black/20":"bg-white/20"),"aria-hidden":o?void 0:"true",role:o?"group":void 0,"aria-label":o?"Slides":void 0,children:Array.from({length:i}).map((L,s)=>{const b=s===r,d=a(`${t}-progress-segment block size-2 rounded-full`,p?"bg-black/40":"bg-white/40"),f=a(`${t}-progress-segment block h-2 w-8 overflow-hidden rounded-full`,p?"bg-black/40":"bg-white/40"),h=u&&l!==void 0?e("span",{className:`${t}-progress-fill block size-full origin-left rounded-full bg-white`,style:{animation:`${t}-progress-fill ${l*1e3}ms linear forwards`,animationPlayState:g?"running":"paused"}},`${r}-${n}`):e("span",{className:`${t}-progress-fill block size-full rounded-full bg-white`});return o?e("button",{type:"button","aria-label":v?.(s)??`Go to slide ${s+1}`,"aria-current":b?"true":void 0,onClick:()=>o(s),className:"flex items-center justify-center focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/80",children:b?e("span",{className:f,children:h}):e("span",{className:d})},s):b?e("span",{className:f,children:h},s):e("span",{className:d},s)})})]})};var j=N;export{z as CarouselArrows,y as CarouselChevronLeft,k as CarouselChevronRight,P as CarouselCornerToggle,N as CarouselProgressControls,x as PauseIcon,C as PlayIcon,j as default};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anker-in/headless-ui",
3
- "version": "1.3.78",
3
+ "version": "1.3.79",
4
4
  "type": "commonjs",
5
5
  "main": "./dist/cjs/index.js",
6
6
  "types": "./dist/cjs/index.d.ts",
package/style.css CHANGED
@@ -545,9 +545,6 @@ video {
545
545
  .\!bottom-0 {
546
546
  bottom: 0px !important;
547
547
  }
548
- .\!bottom-4 {
549
- bottom: 1rem !important;
550
- }
551
548
  .\!bottom-\[70px\] {
552
549
  bottom: 70px !important;
553
550
  }
@@ -776,9 +773,6 @@ video {
776
773
  .z-\[200\] {
777
774
  z-index: 200;
778
775
  }
779
- .z-\[20\] {
780
- z-index: 20;
781
- }
782
776
  .z-\[210\] {
783
777
  z-index: 210;
784
778
  }
@@ -1255,6 +1249,9 @@ video {
1255
1249
  .aspect-\[358\/480\] {
1256
1250
  aspect-ratio: 358/480;
1257
1251
  }
1252
+ .aspect-\[390\/1440\] {
1253
+ aspect-ratio: 390/1440;
1254
+ }
1258
1255
  .aspect-\[390\/240\] {
1259
1256
  aspect-ratio: 390/240;
1260
1257
  }
@@ -5636,6 +5633,9 @@ video {
5636
5633
  .tablet\:aspect-\[704\/480\] {
5637
5634
  aspect-ratio: 704/480;
5638
5635
  }
5636
+ .tablet\:aspect-\[768\/1320\] {
5637
+ aspect-ratio: 768/1320;
5638
+ }
5639
5639
  .tablet\:aspect-\[768\/240\] {
5640
5640
  aspect-ratio: 768/240;
5641
5641
  }
@@ -6195,6 +6195,9 @@ video {
6195
6195
  .laptop\:top-\[76px\] {
6196
6196
  top: 76px;
6197
6197
  }
6198
+ .laptop\:top-\[min\(50\%\2c 50vh\)\] {
6199
+ top: min(50%, 50vh);
6200
+ }
6198
6201
  .laptop\:-order-1 {
6199
6202
  order: -1;
6200
6203
  }
@@ -6333,20 +6336,20 @@ video {
6333
6336
  .laptop\:aspect-\[1024\/384\] {
6334
6337
  aspect-ratio: 1024/384;
6335
6338
  }
6339
+ .laptop\:aspect-\[1024\/400\] {
6340
+ aspect-ratio: 1024/400;
6341
+ }
6342
+ .laptop\:aspect-\[1024\/432\] {
6343
+ aspect-ratio: 1024/432;
6344
+ }
6336
6345
  .laptop\:aspect-\[1024\/480\] {
6337
6346
  aspect-ratio: 1024/480;
6338
6347
  }
6339
6348
  .laptop\:aspect-\[1024\/520\] {
6340
6349
  aspect-ratio: 1024/520;
6341
6350
  }
6342
- .laptop\:aspect-\[1920\/480\] {
6343
- aspect-ratio: 1920/480;
6344
- }
6345
- .laptop\:aspect-\[1920\/720\] {
6346
- aspect-ratio: 1920/720;
6347
- }
6348
- .laptop\:aspect-\[1920\/930\] {
6349
- aspect-ratio: 1920/930;
6351
+ .laptop\:aspect-\[1024\/864\] {
6352
+ aspect-ratio: 1024/864;
6350
6353
  }
6351
6354
  .laptop\:aspect-\[2\/1\] {
6352
6355
  aspect-ratio: 2/1;
@@ -7545,12 +7548,24 @@ video {
7545
7548
  .desktop\:aspect-\[1312\/512\] {
7546
7549
  aspect-ratio: 1312/512;
7547
7550
  }
7551
+ .desktop\:aspect-\[1440\/1152\] {
7552
+ aspect-ratio: 1440/1152;
7553
+ }
7548
7554
  .desktop\:aspect-\[1440\/384\] {
7549
7555
  aspect-ratio: 1440/384;
7550
7556
  }
7557
+ .desktop\:aspect-\[1440\/480\] {
7558
+ aspect-ratio: 1440/480;
7559
+ }
7551
7560
  .desktop\:aspect-\[1440\/512\] {
7552
7561
  aspect-ratio: 1440/512;
7553
7562
  }
7563
+ .desktop\:aspect-\[1440\/560\] {
7564
+ aspect-ratio: 1440/560;
7565
+ }
7566
+ .desktop\:aspect-\[1440\/576\] {
7567
+ aspect-ratio: 1440/576;
7568
+ }
7554
7569
  .desktop\:aspect-\[1440\/640\] {
7555
7570
  aspect-ratio: 1440/640;
7556
7571
  }
@@ -7563,15 +7578,6 @@ video {
7563
7578
  .desktop\:aspect-\[19\/9\] {
7564
7579
  aspect-ratio: 19/9;
7565
7580
  }
7566
- .desktop\:aspect-\[1920\/480\] {
7567
- aspect-ratio: 1920/480;
7568
- }
7569
- .desktop\:aspect-\[1920\/720\] {
7570
- aspect-ratio: 1920/720;
7571
- }
7572
- .desktop\:aspect-\[1920\/930\] {
7573
- aspect-ratio: 1920/930;
7574
- }
7575
7581
  .desktop\:aspect-\[316\/384\] {
7576
7582
  aspect-ratio: 316/384;
7577
7583
  }
@@ -8281,6 +8287,9 @@ video {
8281
8287
  .lg-desktop\:aspect-\[1664\/640\] {
8282
8288
  aspect-ratio: 1664/640;
8283
8289
  }
8290
+ .lg-desktop\:aspect-\[1920\/1440\] {
8291
+ aspect-ratio: 1920/1440;
8292
+ }
8284
8293
  .lg-desktop\:aspect-\[1920\/480\] {
8285
8294
  aspect-ratio: 1920/480;
8286
8295
  }