coverflow-carousel 0.2.0 → 0.3.0

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/README.md CHANGED
@@ -49,7 +49,6 @@ registerCoverflowCarouselElement();
49
49
  import {
50
50
  registerCoverflowCarouselElement,
51
51
  initCoverflowCarousels,
52
- coverflowCarouselCssText,
53
52
  } from 'coverflow-carousel';
54
53
 
55
54
  registerCoverflowCarouselElement();
@@ -73,34 +72,38 @@ initCoverflowCarousels({
73
72
  else if (detail.index === 1) (el as any).goTo?.(2);
74
73
  else if (detail.index === 2) console.log('final');
75
74
  },
76
- // Optional styles:
77
- // - CSSStyleSheet (constructable stylesheet)
78
- // - string (e.g. imported via ?raw)
79
- // stylesheet: coverflowCarouselCssText,
80
- //
81
- // Optional overrides (applied on top of the base stylesheet):
82
- // styleOverrides: `
83
- // .cfc { --cfc-card-ar-num: 1.6; }
84
- // .cfc__arrow { background: Black; }
85
- // `,
86
75
  });
87
76
  ```
88
77
 
89
- <sub>JS: custom styles from `?raw` (CSS/SCSS)</sub>
78
+ <sub>Recommended: single overrides file (`?raw`) — variables + rules in one place</sub>
90
79
  ```javascript
91
80
  import { registerCoverflowCarouselElement, initCoverflowCarousels } from 'coverflow-carousel';
92
- import MyCfcCss from './assets/cfc.custom.css?raw';
93
- import MyCfcOverrides from './assets/cfc.overrides.css?raw';
81
+ import CfcOverrides from './assets/cfc.overrides.css?raw';
94
82
 
95
83
  registerCoverflowCarouselElement();
96
84
 
97
85
  initCoverflowCarousels({
98
- stylesheet: MyCfcCss,
99
- styleOverrides: MyCfcOverrides,
86
+ styleOverrides: CfcOverrides,
100
87
  });
101
88
  ```
102
89
 
103
- <sub>JS: default styles shipped with the package</sub>
90
+ <sub>`cfc.overrides.css` example</sub>
91
+ ```css
92
+ :host {
93
+ /* CSS variables (override defaults) */
94
+ --cfc-card-ar-num: 1.6;
95
+ }
96
+
97
+ /* Example rule: only active slide is interactive */
98
+ .cfc__card slot::slotted(*) {
99
+ pointer-events: none;
100
+ }
101
+ .cfc__card[data-active="true"] slot::slotted(*) {
102
+ pointer-events: auto;
103
+ }
104
+ ```
105
+
106
+ <sub>Advanced: replace base styles completely</sub>
104
107
  ```javascript
105
108
  import {
106
109
  registerCoverflowCarouselElement,
@@ -115,13 +118,6 @@ initCoverflowCarousels({
115
118
  });
116
119
  ```
117
120
 
118
- <sub>CSS: override CSS variables (recommended for simple tweaks)</sub>
119
- ```css
120
- coverflow-carousel {
121
- --cfc-card-ar-num: 1.6;
122
- }
123
- ```
124
-
125
121
  <sub>JS: manual control (prev/next/goTo/refresh)</sub>
126
122
  ```javascript
127
123
  import { registerCoverflowCarouselElement } from 'coverflow-carousel';
@@ -147,7 +143,6 @@ el?.refresh();
147
143
  | `index` | `number` | — | Current index. If you update it externally, the carousel will animate to it. The component also reflects the current value back into `index`. |
148
144
  | `show-dots` | `boolean` | `false` | Shows pagination dots (decorative, non-interactive). |
149
145
  | `show-arrows` | `boolean` | `false` | Shows Prev/Next arrows. |
150
- | `announce-changes` | `boolean` | `true` | Enables slide-change announcements via live-region (a11y). |
151
146
 
152
147
  <br>
153
148
 
@@ -1 +1 @@
1
- :host{--cfc-card-ar-num:1.25;--cfc-card-w:clamp(160px,100vw - 120px,380px);--cfc-card-ar:1/var(--cfc-card-ar-num);--cfc-step-x:min(22vw,250px);--cfc-step-z:calc(var(--cfc-card-w)*.5);--cfc-scale-step:.1;--cfc-transition-ms:.55s;--cfc-easing:cubic-bezier(.785,.135,.15,.86);--cfc-arrow-size:50px;--cfc-park-x:0px;--cfc-park-z:calc(var(--cfc-step-z)*-6);--cfc-park-scale:.1;width:100%;height:100%;display:block;overflow:hidden;container-type:inline-size}.cfc{perspective:1000px;width:min(900px,100%);height:100%;margin:auto;position:relative}.cfc__track{width:100%;height:calc(var(--cfc-card-w)*var(--cfc-card-ar-num));transform-style:preserve-3d;position:relative}.cfc__card{--cfc-delta:0;--cfc-abs:0;--cfc-scale:clamp(.1,calc(1 - (var(--cfc-abs)*var(--cfc-scale-step))),1);--cfc-x:calc(var(--cfc-step-x)*var(--cfc-delta));--cfc-z:calc(var(--cfc-step-z)*-1*var(--cfc-abs));--cfc-zIndex:calc(100 - var(--cfc-abs));--cfc-scale-effective:var(--cfc-scale);--cfc-x-effective:var(--cfc-x);--cfc-z-effective:var(--cfc-z);pointer-events:auto;width:var(--cfc-card-w);aspect-ratio:var(--cfc-card-ar);z-index:var(--cfc-zIndex);transform-style:preserve-3d;transform:translate(-50%,-50%)translate3d(var(--cfc-x-effective),0px,var(--cfc-z-effective))scale(var(--cfc-scale-effective));transition:transform var(--cfc-transition-ms)var(--cfc-easing);position:absolute;inset:50% 0 0 50%;overflow:hidden}.cfc__card[aria-hidden=false]{will-change:transform}.cfc__card[aria-hidden=true]{--cfc-x-effective:var(--cfc-park-x);--cfc-z-effective:var(--cfc-park-z);--cfc-scale-effective:var(--cfc-park-scale);pointer-events:none}.cfc__card[data-active=true]{--cfc-scale-effective:1}.cfc__card ::slotted(img),.cfc__card img{object-fit:cover;object-position:center;width:100%;height:100%;display:block}.cfc__arrow{top:calc(50% - var(--cfc-arrow-size));width:var(--cfc-arrow-size);height:var(--cfc-arrow-size);cursor:pointer;z-index:50;background:#dc143c;border:none;transition:background .25s;position:absolute}.cfc__arrow:hover{background:#d3d3d3}.cfc__arrow--left{left:20px}.cfc__arrow--right{right:20px}.cfc__dots{justify-content:center;align-items:center;gap:10px;height:50px;display:flex}.cfc__dot{cursor:default;background:#d3d3d3;border-radius:50%;width:10px;height:10px;transition:transform .25s,background .25s}.cfc__dot[data-active=true]{background:#dc143c;transform:scale(1.2)}.cfc__sr{clip:rect(0,0,0,0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}
1
+ :host{--cfc-card-ar-num:1.25;--cfc-card-w:clamp(160px,100vw - 120px,380px);--cfc-card-ar:1/var(--cfc-card-ar-num);--cfc-step-x:min(22vw,250px);--cfc-step-z:calc(var(--cfc-card-w)*.5);--cfc-scale-step:.1;--cfc-transition-ms:.55s;--cfc-easing:cubic-bezier(.785,.135,.15,.86);--cfc-arrow-size:50px;--cfc-park-x:0px;--cfc-park-z:calc(var(--cfc-step-z)*-6);--cfc-park-scale:.1;width:100%;height:100%;display:block;overflow:hidden;container-type:inline-size}.cfc{perspective:1000px;width:min(900px,100%);height:100%;margin:auto;position:relative}.cfc__track{width:100%;height:calc(var(--cfc-card-w)*var(--cfc-card-ar-num));transform-style:preserve-3d;position:relative}.cfc__card{--cfc-delta:0;--cfc-abs:0;--cfc-scale:clamp(.1,calc(1 - (var(--cfc-abs)*var(--cfc-scale-step))),1);--cfc-x:calc(var(--cfc-step-x)*var(--cfc-delta));--cfc-z:calc(var(--cfc-step-z)*-1*var(--cfc-abs));--cfc-zIndex:calc(100 - var(--cfc-abs));--cfc-scale-effective:var(--cfc-scale);--cfc-x-effective:var(--cfc-x);--cfc-z-effective:var(--cfc-z);pointer-events:auto;width:var(--cfc-card-w);aspect-ratio:var(--cfc-card-ar);z-index:var(--cfc-zIndex);transform-style:preserve-3d;transform:translate(-50%,-50%)translate3d(var(--cfc-x-effective),0px,var(--cfc-z-effective))scale(var(--cfc-scale-effective));transition:transform var(--cfc-transition-ms)var(--cfc-easing);position:absolute;inset:50% 0 0 50%;overflow:hidden}.cfc__card[aria-hidden=false]{will-change:transform}.cfc__card[aria-hidden=true]{--cfc-x-effective:var(--cfc-park-x);--cfc-z-effective:var(--cfc-park-z);--cfc-scale-effective:var(--cfc-park-scale);pointer-events:none}.cfc__card[data-active=true]{--cfc-scale-effective:1}.cfc__card ::slotted(img),.cfc__card img{object-fit:cover;object-position:center;width:100%;height:100%;display:block}.cfc__arrow{top:calc(50% - var(--cfc-arrow-size));width:var(--cfc-arrow-size);height:var(--cfc-arrow-size);cursor:pointer;z-index:50;background:#dc143c;border:none;transition:background .25s;position:absolute}.cfc__arrow:hover{background:#d3d3d3}.cfc__arrow--left{left:20px}.cfc__arrow--right{right:20px}.cfc__dots{justify-content:center;align-items:center;gap:10px;height:50px;display:flex}.cfc__dot{cursor:default;background:#d3d3d3;border-radius:50%;width:10px;height:10px;transition:transform .25s,background .25s}.cfc__dot[data-active=true]{background:#dc143c;transform:scale(1.2)}
@@ -9,7 +9,6 @@ export declare class CoverflowCarouselElement extends HTMLElement {
9
9
  private dotsEl;
10
10
  private prevBtn;
11
11
  private nextBtn;
12
- private liveRegion;
13
12
  private baseStyles;
14
13
  private overrideStyles;
15
14
  private baseStyleEl;
@@ -56,7 +55,6 @@ export declare class CoverflowCarouselElement extends HTMLElement {
56
55
  private unlockAnimation;
57
56
  private emitChange;
58
57
  private dispatchReady;
59
- private announce;
60
58
  private reflectIndexAttr;
61
59
  private setBaseStyles;
62
60
  private setOverrideStyles;
package/dist/index.cjs.js CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const x=`:host {
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const S=`:host {
2
2
  display: block;
3
3
  width: 100%;
4
4
  height: 100%;
@@ -151,17 +151,4 @@
151
151
  background: Crimson;
152
152
  transform: scale(1.2);
153
153
  }
154
-
155
- /* SR-only */
156
- .cfc__sr {
157
- position: absolute;
158
- width: 1px;
159
- height: 1px;
160
- padding: 0;
161
- margin: -1px;
162
- overflow: hidden;
163
- clip: rect(0, 0, 0, 0);
164
- white-space: nowrap;
165
- border: 0;
166
- }
167
- `,A=x;function E(a){return"adoptedStyleSheets"in a}function y(a){try{const t=new CSSStyleSheet;return t.replaceSync(a),t}catch{return null}}const I=y(x),k=x;function b(a){return a.split(",").map(t=>t.trim()).filter(Boolean)}function g(a,t){const n=a.trim();if(!n)return t;if(n.endsWith("ms")){const e=Number(n.slice(0,-2).trim());return Number.isFinite(e)?e:t}if(n.endsWith("s")){const e=Number(n.slice(0,-1).trim());return Number.isFinite(e)?e*1e3:t}const s=Number(n);return Number.isFinite(s)?s:t}function C(a,t){const n=b(a.transitionProperty),s=b(a.transitionDuration),e=b(a.transitionDelay);if(!n.length)return 0;const r=(v=>{const h=n.indexOf(v);if(h>=0)return h;const S=n.indexOf("all");return S>=0?S:-1})(t);if(r<0)return 0;const o=s[Math.min(r,s.length-1)]??"0s",l=e[Math.min(r,e.length-1)]??"0s",c=g(o,0),d=g(l,0);return Math.max(0,c+d)}function _(){return window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches??!1}function f(a,t,n){if(!a.hasAttribute(t))return n;const s=a.getAttribute(t);return s==null||s===""?!0:s!=="false"}function L(a,t,n){const s=a.getAttribute(t);if(s==null)return n;const e=Number(s.trim());return Number.isFinite(e)?Math.trunc(e):n}function w(a,t){const n=a.getAttribute(t);if(n==null)return null;const s=n.trim();return s||null}function p(a,t){return t<=0?0:(a%t+t)%t}function T(a,t,n){const s=t-a,e=n/2;return s>e?s-n:s<-e?s+n:s}const m=1;let D=0;class u extends HTMLElement{static defaultStylesheet=I;static observedAttributes=["start-index","index","show-dots","show-arrows","announce-changes"];shadow=this.attachShadow({mode:"open"});instanceId=`cfc-${++D}`;rootEl;trackEl;dotsEl;prevBtn;nextBtn;liveRegion;baseStyles=null;overrideStyles=null;baseStyleEl=null;overrideStyleEl=null;cards=[];dots=[];currentIndex=0;isAnimating=!1;hasAppliedInitialLayout=!1;lastLayoutIndex=null;lastVisibleSet=new Set;pendingAnimToken=0;animFallbackTimerId=null;cleanup=[];lightDomObserverOptions={childList:!0,attributes:!0,subtree:!0};lightDomObserver=null;refreshScheduled=!1;suppressMutations=!1;reflectGuard=!1;connectedCallback(){this.render(),this.readAttributes({isInit:!0}),this.refresh(),this.setupLightDomObserver()}disconnectedCallback(){this.destroy()}attributeChangedCallback(t,n,s){if(!this.isConnected||this.reflectGuard)return;this.readAttributes({isInit:!1});const e=w(this,"index");if(e!=null){const i=p(Number(e),this.cards.length);if(Number.isFinite(i)&&i!==this.currentIndex){this.goTo(i);return}}this.applyLayoutAndA11y({announce:!0,emitChange:!1})}next(){this.goTo(this.currentIndex+1)}prev(){this.goTo(this.currentIndex-1)}goTo(t){if(this.isAnimating)return;const n=p(t,this.cards.length);n!==this.currentIndex&&(this.isAnimating=!0,this.currentIndex=n,this.reflectIndexAttr(),this.applyLayoutAndA11y({announce:!0,emitChange:!0}),this.lockUntilTransitionEnd())}refresh(){const t=this.lightDomObserver;t&&(this.suppressMutations=!0,t.disconnect(),t.takeRecords()),this.rebuildCardsFromLightDom();const n=L(this,"start-index",0),s=w(this,"index"),e=s!=null?Number(s):n,i=Number.isFinite(e)?e:0;this.currentIndex=p(i,this.cards.length),this.reflectIndexAttr(),this.buildDots(),this.hasAppliedInitialLayout=!1,this.lastLayoutIndex=null,this.lastVisibleSet=new Set,this.applyLayoutAndA11y({announce:!0,emitChange:!1}),this.dispatchReady(),t&&(t.observe(this,this.lightDomObserverOptions),t.takeRecords(),this.suppressMutations=!1)}destroy(){this.animFallbackTimerId!==null&&(window.clearTimeout(this.animFallbackTimerId),this.animFallbackTimerId=null),this.cleanup.forEach(t=>{t()}),this.cleanup=[],this.isAnimating=!1}adoptStylesheet(t){this.setBaseStyles(t)}adoptStyles(t){this.setBaseStyles(t)}adoptStyleOverrides(t){this.setOverrideStyles(t)}readAttributes(t){this.rootEl||this.render();const n=f(this,"show-arrows",!1),s=f(this,"show-dots",!1);this.prevBtn.style.display=n?"":"none",this.nextBtn.style.display=n?"":"none",this.dotsEl.style.display=s?"":"none";const e=this.getAttribute("aria-label");e&&this.rootEl.setAttribute("aria-label",e),t.isInit&&this.setAttribute("aria-roledescription","carousel")}render(){this.applyAllStyles(),this.rootEl=document.createElement("div"),this.rootEl.className="cfc",this.trackEl=document.createElement("div"),this.trackEl.className="cfc__track",this.prevBtn=document.createElement("button"),this.prevBtn.type="button",this.prevBtn.className="cfc__arrow cfc__arrow--left",this.prevBtn.setAttribute("aria-label","Previous"),this.prevBtn.textContent="‹",this.nextBtn=document.createElement("button"),this.nextBtn.type="button",this.nextBtn.className="cfc__arrow cfc__arrow--right",this.nextBtn.setAttribute("aria-label","Next"),this.nextBtn.textContent="›",this.dotsEl=document.createElement("div"),this.dotsEl.className="cfc__dots",this.liveRegion=document.createElement("div"),this.liveRegion.className="cfc__sr",this.liveRegion.setAttribute("aria-live","polite"),this.liveRegion.setAttribute("aria-atomic","true"),this.rootEl.append(this.trackEl,this.prevBtn,this.nextBtn,this.dotsEl,this.liveRegion),this.shadow.innerHTML="",this.baseStyleEl&&this.shadow.append(this.baseStyleEl),this.overrideStyleEl&&this.shadow.append(this.overrideStyleEl),this.shadow.append(this.rootEl),this.bindEvents()}bindEvents(){this.cleanup.forEach(i=>{i()}),this.cleanup=[];const t=()=>this.prev(),n=()=>this.next();this.prevBtn.addEventListener("click",t),this.nextBtn.addEventListener("click",n),this.cleanup.push(()=>this.prevBtn.removeEventListener("click",t)),this.cleanup.push(()=>this.nextBtn.removeEventListener("click",n));const s=i=>{if(!this.isAnimating||i.propertyName!=="transform"||!(i.target instanceof HTMLElement))return;const r=this.cards[this.currentIndex];r&&i.target===r&&this.unlockAnimation()};this.rootEl.addEventListener("transitionend",s),this.cleanup.push(()=>this.rootEl.removeEventListener("transitionend",s));const e=i=>{const r=i.target;if(!(r instanceof HTMLElement)||r.tagName!=="SCRATCH-REVEAL")return;const o=i.composedPath?.();if(!o?.length)return;const l=o.find(h=>h instanceof HTMLElement&&h.classList.contains("cfc__card")&&h.dataset.cfcIndex!=null);if(!l)return;const c=Number(l.dataset.cfcIndex);if(!Number.isFinite(c))return;const v=i.detail?.percent??100;this.dispatchEvent(new CustomEvent("coverflow-carousel:scratch-complete",{detail:{index:c,length:this.cards.length,percent:v},bubbles:!0,composed:!0}))};this.rootEl.addEventListener("complete",e),this.cleanup.push(()=>this.rootEl.removeEventListener("complete",e))}setupLightDomObserver(){this.lightDomObserver||(this.lightDomObserver=new MutationObserver(t=>{this.suppressMutations||!t.some(s=>!(s.type==="attributes"&&s.attributeName==="slot"))||this.scheduleRefreshFromMutations()}),this.lightDomObserver.observe(this,{...this.lightDomObserverOptions}),this.cleanup.push(()=>{this.lightDomObserver?.disconnect(),this.lightDomObserver=null}))}scheduleRefreshFromMutations(){this.refreshScheduled||(this.refreshScheduled=!0,queueMicrotask(()=>{this.refreshScheduled=!1,this.isConnected&&this.refresh()}))}rebuildCardsFromLightDom(){const t=Array.from(this.trackEl.children).filter(e=>e instanceof HTMLElement&&e.classList.contains("cfc__card")),n=[],s=Array.from(this.children).filter(e=>e instanceof HTMLElement);for(let e=0;e<s.length;e++){const i=s[e],r=t[e]??document.createElement("div"),o=`${this.instanceId}-slot-${e}`;t[e]||(r.className="cfc__card",this.trackEl.append(r)),i.getAttribute("slot")!==o&&i.setAttribute("slot",o);const l=r.querySelector("slot");let c;l instanceof HTMLSlotElement?c=l:(c=document.createElement("slot"),r.replaceChildren(c)),c.name!==o&&(c.name=o),n.push(r)}for(let e=s.length;e<t.length;e++)t[e]?.remove();this.cards=n,this.hasAppliedInitialLayout=!1,this.lastLayoutIndex=null,this.lastVisibleSet=new Set}getVisibleSet(){const t=this.cards.length,n=new Set;if(t<=0)return n;const s=Math.floor(t/2);if(m>=s){for(let e=0;e<t;e++)n.add(e);return n}for(let e=-m;e<=m;e++)n.add(p(this.currentIndex+e,t));return n}buildDots(){const t=Array.from(this.dotsEl.children).filter(i=>i instanceof HTMLElement&&i.classList.contains("cfc__dot"));if(!f(this,"show-dots",!1)){t.forEach(i=>{i.remove()}),this.dots=[];return}const s=[],e=this.cards.length;for(let i=0;i<e;i++){const r=t[i]??document.createElement("span");t[i]||this.dotsEl.append(r),r.className="cfc__dot",r.setAttribute("aria-hidden","true"),s.push(r)}for(let i=e;i<t.length;i++)t[i]?.remove();this.dots=s,this.updateDotsVisualState()}computeCardState(t){const n=this.cards.length,s=T(this.currentIndex,t,n),e=Math.abs(s);return{index:t,delta:s,abs:e,isVisible:e<=m,isActive:t===this.currentIndex}}applyCardState(t,n){t.setAttribute("aria-hidden",n.isVisible?"false":"true"),t.dataset.active=n.isActive?"true":"false",t.dataset.cfcIndex=String(n.index),t.setAttribute("role","group"),t.setAttribute("aria-roledescription","slide"),t.setAttribute("aria-setsize",String(this.cards.length)),t.setAttribute("aria-posinset",String(n.index+1));const s=`${this.instanceId}-slide-${n.index}`;t.id=s;const e=String(n.delta),i=String(n.abs),r=t.dataset.cfcDelta,o=t.dataset.cfcAbs;r!==e&&(t.style.setProperty("--cfc-delta",e),t.dataset.cfcDelta=e),o!==i&&(t.style.setProperty("--cfc-abs",i),t.dataset.cfcAbs=i)}applyLayoutAndA11y(t){if(this.cards.length){if(this.hasAppliedInitialLayout){const n=this.getVisibleSet(),s=new Set;this.lastVisibleSet.forEach(e=>{s.add(e)}),n.forEach(e=>{s.add(e)}),this.lastLayoutIndex!=null&&s.add(this.lastLayoutIndex),s.add(this.currentIndex),s.forEach(e=>{const i=this.cards[e];if(!i)return;const r=this.computeCardState(e);this.applyCardState(i,r)}),this.lastLayoutIndex=this.currentIndex,this.lastVisibleSet=n}else{for(let n=0;n<this.cards.length;n++){const s=this.cards[n];if(!s)continue;const e=this.computeCardState(n);this.applyCardState(s,e)}this.hasAppliedInitialLayout=!0,this.lastLayoutIndex=this.currentIndex,this.lastVisibleSet=this.getVisibleSet()}this.updateDotsVisualState(),t.announce&&f(this,"announce-changes",!0)&&this.announce(`Slide ${this.currentIndex+1} of ${this.cards.length}`),t.emitChange&&this.emitChange()}}updateDotsVisualState(){if(this.dots.length)for(let t=0;t<this.dots.length;t++){const n=this.dots[t],s=t===this.currentIndex;n.dataset.active=s?"true":"false"}}lockUntilTransitionEnd(){this.pendingAnimToken++;const t=this.pendingAnimToken;if(_()){this.unlockAnimation();return}const n=this.cards[this.currentIndex];if(!n){this.unlockAnimation();return}const s=getComputedStyle(n),e=C(s,"transform");if(e<=0){this.unlockAnimation();return}const i=g(s.getPropertyValue("--cfc-transition-ms").trim(),400),o=Math.max(e,i)+60;this.animFallbackTimerId!==null&&window.clearTimeout(this.animFallbackTimerId),this.animFallbackTimerId=window.setTimeout(()=>{this.pendingAnimToken===t&&this.unlockAnimation()},o)}unlockAnimation(){this.isAnimating=!1,this.animFallbackTimerId!==null&&(window.clearTimeout(this.animFallbackTimerId),this.animFallbackTimerId=null)}emitChange(){this.dispatchEvent(new CustomEvent("coverflow-carousel:change",{detail:{index:this.currentIndex,length:this.cards.length}}))}dispatchReady(){this.dispatchEvent(new CustomEvent("coverflow-carousel:ready",{detail:{index:this.currentIndex,length:this.cards.length}}))}announce(t){this.liveRegion.textContent="",queueMicrotask(()=>{this.liveRegion.textContent=t})}reflectIndexAttr(){this.reflectGuard=!0;try{this.setAttribute("index",String(this.currentIndex))}finally{this.reflectGuard=!1}}setBaseStyles(t){this.baseStyles=t??null,this.applyAllStyles()}setOverrideStyles(t){this.overrideStyles=t??null,this.applyAllStyles()}applyAllStyles(){const t=this.baseStyles,n=this.overrideStyles;if(E(this.shadow)){const e=[];if(typeof t=="string"){const i=y(t);if(!i){this.applyAllStylesFallback();return}e.push(i)}else if(t)e.push(t);else if(u.defaultStylesheet)e.push(u.defaultStylesheet);else{this.applyAllStylesFallback();return}if(typeof n=="string"){const i=y(n);if(!i){this.applyAllStylesFallback();return}e.push(i)}else n&&e.push(n);this.shadow.adoptedStyleSheets=e,this.baseStyleEl?.remove(),this.overrideStyleEl?.remove(),this.baseStyleEl=null,this.overrideStyleEl=null;return}this.applyAllStylesFallback()}applyAllStylesFallback(){const t=this.baseStyles,n=this.overrideStyles;E(this.shadow)&&(this.shadow.adoptedStyleSheets=[]);const s=typeof t=="string"?t:k,e=typeof n=="string"?n:"";this.baseStyleEl||(this.baseStyleEl=document.createElement("style")),this.baseStyleEl.textContent=s,e?(this.overrideStyleEl||(this.overrideStyleEl=document.createElement("style")),this.overrideStyleEl.textContent=e):(this.overrideStyleEl?.remove(),this.overrideStyleEl=null)}}function F(a={}){const{selector:t="coverflow-carousel",onReady:n,onChange:s,onScratchComplete:e,stylesheet:i,styleOverrides:r}=a,o=Array.from(document.querySelectorAll(t));return(n||s||e)&&o.forEach(l=>{n&&l.addEventListener("coverflow-carousel:ready",c=>{n(l,c.detail)}),s&&l.addEventListener("coverflow-carousel:change",c=>{s(l,c.detail)}),e&&l.addEventListener("coverflow-carousel:scratch-complete",c=>{e(l,c.detail)})}),i&&o.forEach(l=>{const c=l;typeof i=="string"?c.adoptStyles(i):c.adoptStylesheet(i)}),r&&o.forEach(l=>{l.adoptStyleOverrides(r)}),o}function M(a="coverflow-carousel"){typeof window>"u"||!("customElements"in window)||customElements.get(a)||customElements.define(a,u)}exports.CoverflowCarouselElement=u;exports.coverflowCarouselCssText=A;exports.initCoverflowCarousels=F;exports.registerCoverflowCarouselElement=M;
154
+ `,A=S;function E(a){return"adoptedStyleSheets"in a}function y(a){try{const t=new CSSStyleSheet;return t.replaceSync(a),t}catch{return null}}const I=y(S),k=S;function v(a){return a.split(",").map(t=>t.trim()).filter(Boolean)}function g(a,t){const s=a.trim();if(!s)return t;if(s.endsWith("ms")){const e=Number(s.slice(0,-2).trim());return Number.isFinite(e)?e:t}if(s.endsWith("s")){const e=Number(s.slice(0,-1).trim());return Number.isFinite(e)?e*1e3:t}const n=Number(s);return Number.isFinite(n)?n:t}function C(a,t){const s=v(a.transitionProperty),n=v(a.transitionDuration),e=v(a.transitionDelay);if(!s.length)return 0;const r=(m=>{const h=s.indexOf(m);if(h>=0)return h;const x=s.indexOf("all");return x>=0?x:-1})(t);if(r<0)return 0;const o=n[Math.min(r,n.length-1)]??"0s",l=e[Math.min(r,e.length-1)]??"0s",c=g(o,0),d=g(l,0);return Math.max(0,c+d)}function _(){return window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches??!1}function b(a,t,s){if(!a.hasAttribute(t))return s;const n=a.getAttribute(t);return n==null||n===""?!0:n!=="false"}function L(a,t,s){const n=a.getAttribute(t);if(n==null)return s;const e=Number(n.trim());return Number.isFinite(e)?Math.trunc(e):s}function w(a,t){const s=a.getAttribute(t);if(s==null)return null;const n=s.trim();return n||null}function f(a,t){return t<=0?0:(a%t+t)%t}function T(a,t,s){const n=t-a,e=s/2;return n>e?n-s:n<-e?n+s:n}const p=1;let D=0;class u extends HTMLElement{static defaultStylesheet=I;static observedAttributes=["start-index","index","show-dots","show-arrows"];shadow=this.attachShadow({mode:"open"});instanceId=`cfc-${++D}`;rootEl;trackEl;dotsEl;prevBtn;nextBtn;baseStyles=null;overrideStyles=null;baseStyleEl=null;overrideStyleEl=null;cards=[];dots=[];currentIndex=0;isAnimating=!1;hasAppliedInitialLayout=!1;lastLayoutIndex=null;lastVisibleSet=new Set;pendingAnimToken=0;animFallbackTimerId=null;cleanup=[];lightDomObserverOptions={childList:!0,attributes:!0,subtree:!0};lightDomObserver=null;refreshScheduled=!1;suppressMutations=!1;reflectGuard=!1;connectedCallback(){this.render(),this.readAttributes({isInit:!0}),this.refresh(),this.setupLightDomObserver()}disconnectedCallback(){this.destroy()}attributeChangedCallback(t,s,n){if(!this.isConnected||this.reflectGuard)return;this.readAttributes({isInit:!1});const e=w(this,"index");if(e!=null){const i=f(Number(e),this.cards.length);if(Number.isFinite(i)&&i!==this.currentIndex){this.goTo(i);return}}this.applyLayoutAndA11y({emitChange:!1})}next(){this.goTo(this.currentIndex+1)}prev(){this.goTo(this.currentIndex-1)}goTo(t){if(this.isAnimating)return;const s=f(t,this.cards.length);s!==this.currentIndex&&(this.isAnimating=!0,this.currentIndex=s,this.reflectIndexAttr(),this.applyLayoutAndA11y({emitChange:!0}),this.lockUntilTransitionEnd())}refresh(){const t=this.lightDomObserver;t&&(this.suppressMutations=!0,t.disconnect(),t.takeRecords()),this.rebuildCardsFromLightDom();const s=L(this,"start-index",0),n=w(this,"index"),e=n!=null?Number(n):s,i=Number.isFinite(e)?e:0;this.currentIndex=f(i,this.cards.length),this.reflectIndexAttr(),this.buildDots(),this.hasAppliedInitialLayout=!1,this.lastLayoutIndex=null,this.lastVisibleSet=new Set,this.applyLayoutAndA11y({emitChange:!1}),this.dispatchReady(),t&&(t.observe(this,this.lightDomObserverOptions),t.takeRecords(),this.suppressMutations=!1)}destroy(){this.animFallbackTimerId!==null&&(window.clearTimeout(this.animFallbackTimerId),this.animFallbackTimerId=null),this.cleanup.forEach(t=>{t()}),this.cleanup=[],this.isAnimating=!1}adoptStylesheet(t){this.setBaseStyles(t)}adoptStyles(t){this.setBaseStyles(t)}adoptStyleOverrides(t){this.setOverrideStyles(t)}readAttributes(t){this.rootEl||this.render();const s=b(this,"show-arrows",!1),n=b(this,"show-dots",!1);this.prevBtn.style.display=s?"":"none",this.nextBtn.style.display=s?"":"none",this.dotsEl.style.display=n?"":"none";const e=this.getAttribute("aria-label");e&&this.rootEl.setAttribute("aria-label",e),t.isInit&&this.setAttribute("aria-roledescription","carousel")}render(){this.applyAllStyles(),this.rootEl=document.createElement("div"),this.rootEl.className="cfc",this.trackEl=document.createElement("div"),this.trackEl.className="cfc__track",this.prevBtn=document.createElement("button"),this.prevBtn.type="button",this.prevBtn.className="cfc__arrow cfc__arrow--left",this.prevBtn.setAttribute("aria-label","Previous"),this.prevBtn.textContent="‹",this.nextBtn=document.createElement("button"),this.nextBtn.type="button",this.nextBtn.className="cfc__arrow cfc__arrow--right",this.nextBtn.setAttribute("aria-label","Next"),this.nextBtn.textContent="›",this.dotsEl=document.createElement("div"),this.dotsEl.className="cfc__dots",this.rootEl.append(this.trackEl,this.prevBtn,this.nextBtn,this.dotsEl),this.shadow.innerHTML="",this.baseStyleEl&&this.shadow.append(this.baseStyleEl),this.overrideStyleEl&&this.shadow.append(this.overrideStyleEl),this.shadow.append(this.rootEl),this.bindEvents()}bindEvents(){this.cleanup.forEach(i=>{i()}),this.cleanup=[];const t=()=>this.prev(),s=()=>this.next();this.prevBtn.addEventListener("click",t),this.nextBtn.addEventListener("click",s),this.cleanup.push(()=>this.prevBtn.removeEventListener("click",t)),this.cleanup.push(()=>this.nextBtn.removeEventListener("click",s));const n=i=>{if(!this.isAnimating||i.propertyName!=="transform"||!(i.target instanceof HTMLElement))return;const r=this.cards[this.currentIndex];r&&i.target===r&&this.unlockAnimation()};this.rootEl.addEventListener("transitionend",n),this.cleanup.push(()=>this.rootEl.removeEventListener("transitionend",n));const e=i=>{const r=i.target;if(!(r instanceof HTMLElement)||r.tagName!=="SCRATCH-REVEAL")return;const o=i.composedPath?.();if(!o?.length)return;const l=o.find(h=>h instanceof HTMLElement&&h.classList.contains("cfc__card")&&h.dataset.cfcIndex!=null);if(!l)return;const c=Number(l.dataset.cfcIndex);if(!Number.isFinite(c))return;const m=i.detail?.percent??100;this.dispatchEvent(new CustomEvent("coverflow-carousel:scratch-complete",{detail:{index:c,length:this.cards.length,percent:m},bubbles:!0,composed:!0}))};this.rootEl.addEventListener("complete",e),this.cleanup.push(()=>this.rootEl.removeEventListener("complete",e))}setupLightDomObserver(){this.lightDomObserver||(this.lightDomObserver=new MutationObserver(t=>{this.suppressMutations||!t.some(n=>!(n.type==="attributes"&&n.attributeName==="slot"))||this.scheduleRefreshFromMutations()}),this.lightDomObserver.observe(this,{...this.lightDomObserverOptions}),this.cleanup.push(()=>{this.lightDomObserver?.disconnect(),this.lightDomObserver=null}))}scheduleRefreshFromMutations(){this.refreshScheduled||(this.refreshScheduled=!0,queueMicrotask(()=>{this.refreshScheduled=!1,this.isConnected&&this.refresh()}))}rebuildCardsFromLightDom(){const t=Array.from(this.trackEl.children).filter(e=>e instanceof HTMLElement&&e.classList.contains("cfc__card")),s=[],n=Array.from(this.children).filter(e=>e instanceof HTMLElement);for(let e=0;e<n.length;e++){const i=n[e],r=t[e]??document.createElement("div"),o=`${this.instanceId}-slot-${e}`;t[e]||(r.className="cfc__card",this.trackEl.append(r)),i.getAttribute("slot")!==o&&i.setAttribute("slot",o);const l=r.querySelector("slot");let c;l instanceof HTMLSlotElement?c=l:(c=document.createElement("slot"),r.replaceChildren(c)),c.name!==o&&(c.name=o),s.push(r)}for(let e=n.length;e<t.length;e++)t[e]?.remove();this.cards=s,this.hasAppliedInitialLayout=!1,this.lastLayoutIndex=null,this.lastVisibleSet=new Set}getVisibleSet(){const t=this.cards.length,s=new Set;if(t<=0)return s;const n=Math.floor(t/2);if(p>=n){for(let e=0;e<t;e++)s.add(e);return s}for(let e=-p;e<=p;e++)s.add(f(this.currentIndex+e,t));return s}buildDots(){const t=Array.from(this.dotsEl.children).filter(i=>i instanceof HTMLElement&&i.classList.contains("cfc__dot"));if(!b(this,"show-dots",!1)){t.forEach(i=>{i.remove()}),this.dots=[];return}const n=[],e=this.cards.length;for(let i=0;i<e;i++){const r=t[i]??document.createElement("span");t[i]||this.dotsEl.append(r),r.className="cfc__dot",r.setAttribute("aria-hidden","true"),n.push(r)}for(let i=e;i<t.length;i++)t[i]?.remove();this.dots=n,this.updateDotsVisualState()}computeCardState(t){const s=this.cards.length,n=T(this.currentIndex,t,s),e=Math.abs(n);return{index:t,delta:n,abs:e,isVisible:e<=p,isActive:t===this.currentIndex}}applyCardState(t,s){t.setAttribute("aria-hidden",s.isVisible?"false":"true"),t.dataset.active=s.isActive?"true":"false",t.dataset.cfcIndex=String(s.index),t.setAttribute("role","group"),t.setAttribute("aria-roledescription","slide"),t.setAttribute("aria-setsize",String(this.cards.length)),t.setAttribute("aria-posinset",String(s.index+1));const n=`${this.instanceId}-slide-${s.index}`;t.id=n;const e=String(s.delta),i=String(s.abs),r=t.dataset.cfcDelta,o=t.dataset.cfcAbs;r!==e&&(t.style.setProperty("--cfc-delta",e),t.dataset.cfcDelta=e),o!==i&&(t.style.setProperty("--cfc-abs",i),t.dataset.cfcAbs=i)}applyLayoutAndA11y(t){if(this.cards.length){if(this.hasAppliedInitialLayout){const s=this.getVisibleSet(),n=new Set;this.lastVisibleSet.forEach(e=>{n.add(e)}),s.forEach(e=>{n.add(e)}),this.lastLayoutIndex!=null&&n.add(this.lastLayoutIndex),n.add(this.currentIndex),n.forEach(e=>{const i=this.cards[e];if(!i)return;const r=this.computeCardState(e);this.applyCardState(i,r)}),this.lastLayoutIndex=this.currentIndex,this.lastVisibleSet=s}else{for(let s=0;s<this.cards.length;s++){const n=this.cards[s];if(!n)continue;const e=this.computeCardState(s);this.applyCardState(n,e)}this.hasAppliedInitialLayout=!0,this.lastLayoutIndex=this.currentIndex,this.lastVisibleSet=this.getVisibleSet()}this.updateDotsVisualState(),t.emitChange&&this.emitChange()}}updateDotsVisualState(){if(this.dots.length)for(let t=0;t<this.dots.length;t++){const s=this.dots[t],n=t===this.currentIndex;s.dataset.active=n?"true":"false"}}lockUntilTransitionEnd(){this.pendingAnimToken++;const t=this.pendingAnimToken;if(_()){this.unlockAnimation();return}const s=this.cards[this.currentIndex];if(!s){this.unlockAnimation();return}const n=getComputedStyle(s),e=C(n,"transform");if(e<=0){this.unlockAnimation();return}const i=g(n.getPropertyValue("--cfc-transition-ms").trim(),400),o=Math.max(e,i)+60;this.animFallbackTimerId!==null&&window.clearTimeout(this.animFallbackTimerId),this.animFallbackTimerId=window.setTimeout(()=>{this.pendingAnimToken===t&&this.unlockAnimation()},o)}unlockAnimation(){this.isAnimating=!1,this.animFallbackTimerId!==null&&(window.clearTimeout(this.animFallbackTimerId),this.animFallbackTimerId=null)}emitChange(){this.dispatchEvent(new CustomEvent("coverflow-carousel:change",{detail:{index:this.currentIndex,length:this.cards.length}}))}dispatchReady(){this.dispatchEvent(new CustomEvent("coverflow-carousel:ready",{detail:{index:this.currentIndex,length:this.cards.length}}))}reflectIndexAttr(){this.reflectGuard=!0;try{this.setAttribute("index",String(this.currentIndex))}finally{this.reflectGuard=!1}}setBaseStyles(t){this.baseStyles=t??null,this.applyAllStyles()}setOverrideStyles(t){this.overrideStyles=t??null,this.applyAllStyles()}applyAllStyles(){const t=this.baseStyles,s=this.overrideStyles;if(E(this.shadow)){const e=[];if(typeof t=="string"){const i=y(t);if(!i){this.applyAllStylesFallback();return}e.push(i)}else if(t)e.push(t);else if(u.defaultStylesheet)e.push(u.defaultStylesheet);else{this.applyAllStylesFallback();return}if(typeof s=="string"){const i=y(s);if(!i){this.applyAllStylesFallback();return}e.push(i)}else s&&e.push(s);this.shadow.adoptedStyleSheets=e,this.baseStyleEl?.remove(),this.overrideStyleEl?.remove(),this.baseStyleEl=null,this.overrideStyleEl=null;return}this.applyAllStylesFallback()}applyAllStylesFallback(){const t=this.baseStyles,s=this.overrideStyles;E(this.shadow)&&(this.shadow.adoptedStyleSheets=[]);const n=typeof t=="string"?t:k,e=typeof s=="string"?s:"";this.baseStyleEl||(this.baseStyleEl=document.createElement("style")),this.baseStyleEl.textContent=n,e?(this.overrideStyleEl||(this.overrideStyleEl=document.createElement("style")),this.overrideStyleEl.textContent=e):(this.overrideStyleEl?.remove(),this.overrideStyleEl=null)}}function F(a={}){const{selector:t="coverflow-carousel",onReady:s,onChange:n,onScratchComplete:e,stylesheet:i,styleOverrides:r}=a,o=Array.from(document.querySelectorAll(t));return(s||n||e)&&o.forEach(l=>{s&&l.addEventListener("coverflow-carousel:ready",c=>{s(l,c.detail)}),n&&l.addEventListener("coverflow-carousel:change",c=>{n(l,c.detail)}),e&&l.addEventListener("coverflow-carousel:scratch-complete",c=>{e(l,c.detail)})}),i&&o.forEach(l=>{const c=l;typeof i=="string"?c.adoptStyles(i):c.adoptStylesheet(i)}),r&&o.forEach(l=>{l.adoptStyleOverrides(r)}),o}function M(a="coverflow-carousel"){typeof window>"u"||!("customElements"in window)||customElements.get(a)||customElements.define(a,u)}exports.CoverflowCarouselElement=u;exports.coverflowCarouselCssText=A;exports.initCoverflowCarousels=F;exports.registerCoverflowCarouselElement=M;
package/dist/index.es.js CHANGED
@@ -151,19 +151,6 @@ const x = `:host {
151
151
  background: Crimson;
152
152
  transform: scale(1.2);
153
153
  }
154
-
155
- /* SR-only */
156
- .cfc__sr {
157
- position: absolute;
158
- width: 1px;
159
- height: 1px;
160
- padding: 0;
161
- margin: -1px;
162
- overflow: hidden;
163
- clip: rect(0, 0, 0, 0);
164
- white-space: nowrap;
165
- border: 0;
166
- }
167
154
  `, D = x;
168
155
  function E(a) {
169
156
  return "adoptedStyleSheets" in a;
@@ -176,75 +163,69 @@ function y(a) {
176
163
  return null;
177
164
  }
178
165
  }
179
- const A = y(x), I = x;
180
- function b(a) {
166
+ const w = y(x), I = x;
167
+ function v(a) {
181
168
  return a.split(",").map((t) => t.trim()).filter(Boolean);
182
169
  }
183
170
  function g(a, t) {
184
- const n = a.trim();
185
- if (!n) return t;
186
- if (n.endsWith("ms")) {
187
- const e = Number(n.slice(0, -2).trim());
171
+ const s = a.trim();
172
+ if (!s) return t;
173
+ if (s.endsWith("ms")) {
174
+ const e = Number(s.slice(0, -2).trim());
188
175
  return Number.isFinite(e) ? e : t;
189
176
  }
190
- if (n.endsWith("s")) {
191
- const e = Number(n.slice(0, -1).trim());
177
+ if (s.endsWith("s")) {
178
+ const e = Number(s.slice(0, -1).trim());
192
179
  return Number.isFinite(e) ? e * 1e3 : t;
193
180
  }
194
- const s = Number(n);
195
- return Number.isFinite(s) ? s : t;
181
+ const n = Number(s);
182
+ return Number.isFinite(n) ? n : t;
196
183
  }
197
184
  function k(a, t) {
198
- const n = b(a.transitionProperty), s = b(a.transitionDuration), e = b(a.transitionDelay);
199
- if (!n.length) return 0;
200
- const r = ((v) => {
201
- const h = n.indexOf(v);
185
+ const s = v(a.transitionProperty), n = v(a.transitionDuration), e = v(a.transitionDelay);
186
+ if (!s.length) return 0;
187
+ const r = ((m) => {
188
+ const h = s.indexOf(m);
202
189
  if (h >= 0) return h;
203
- const S = n.indexOf("all");
190
+ const S = s.indexOf("all");
204
191
  return S >= 0 ? S : -1;
205
192
  })(t);
206
193
  if (r < 0) return 0;
207
- const o = s[Math.min(r, s.length - 1)] ?? "0s", l = e[Math.min(r, e.length - 1)] ?? "0s", c = g(o, 0), d = g(l, 0);
194
+ const o = n[Math.min(r, n.length - 1)] ?? "0s", l = e[Math.min(r, e.length - 1)] ?? "0s", c = g(o, 0), d = g(l, 0);
208
195
  return Math.max(0, c + d);
209
196
  }
210
197
  function _() {
211
198
  return window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches ?? !1;
212
199
  }
213
- function u(a, t, n) {
214
- if (!a.hasAttribute(t)) return n;
215
- const s = a.getAttribute(t);
216
- return s == null || s === "" ? !0 : s !== "false";
217
- }
218
- function C(a, t, n) {
219
- const s = a.getAttribute(t);
220
- if (s == null) return n;
221
- const e = Number(s.trim());
222
- return Number.isFinite(e) ? Math.trunc(e) : n;
200
+ function b(a, t, s) {
201
+ if (!a.hasAttribute(t)) return s;
202
+ const n = a.getAttribute(t);
203
+ return n == null || n === "" ? !0 : n !== "false";
223
204
  }
224
- function w(a, t) {
205
+ function C(a, t, s) {
225
206
  const n = a.getAttribute(t);
226
- if (n == null) return null;
227
- const s = n.trim();
228
- return s || null;
207
+ if (n == null) return s;
208
+ const e = Number(n.trim());
209
+ return Number.isFinite(e) ? Math.trunc(e) : s;
210
+ }
211
+ function A(a, t) {
212
+ const s = a.getAttribute(t);
213
+ if (s == null) return null;
214
+ const n = s.trim();
215
+ return n || null;
229
216
  }
230
- function f(a, t) {
217
+ function u(a, t) {
231
218
  return t <= 0 ? 0 : (a % t + t) % t;
232
219
  }
233
- function L(a, t, n) {
234
- const s = t - a, e = n / 2;
235
- return s > e ? s - n : s < -e ? s + n : s;
220
+ function L(a, t, s) {
221
+ const n = t - a, e = s / 2;
222
+ return n > e ? n - s : n < -e ? n + s : n;
236
223
  }
237
- const p = 1;
224
+ const f = 1;
238
225
  let T = 0;
239
- class m extends HTMLElement {
240
- static defaultStylesheet = A;
241
- static observedAttributes = [
242
- "start-index",
243
- "index",
244
- "show-dots",
245
- "show-arrows",
246
- "announce-changes"
247
- ];
226
+ class p extends HTMLElement {
227
+ static defaultStylesheet = w;
228
+ static observedAttributes = ["start-index", "index", "show-dots", "show-arrows"];
248
229
  shadow = this.attachShadow({ mode: "open" });
249
230
  instanceId = `cfc-${++T}`;
250
231
  rootEl;
@@ -252,7 +233,6 @@ class m extends HTMLElement {
252
233
  dotsEl;
253
234
  prevBtn;
254
235
  nextBtn;
255
- liveRegion;
256
236
  baseStyles = null;
257
237
  overrideStyles = null;
258
238
  baseStyleEl = null;
@@ -282,18 +262,18 @@ class m extends HTMLElement {
282
262
  disconnectedCallback() {
283
263
  this.destroy();
284
264
  }
285
- attributeChangedCallback(t, n, s) {
265
+ attributeChangedCallback(t, s, n) {
286
266
  if (!this.isConnected || this.reflectGuard) return;
287
267
  this.readAttributes({ isInit: !1 });
288
- const e = w(this, "index");
268
+ const e = A(this, "index");
289
269
  if (e != null) {
290
- const i = f(Number(e), this.cards.length);
270
+ const i = u(Number(e), this.cards.length);
291
271
  if (Number.isFinite(i) && i !== this.currentIndex) {
292
272
  this.goTo(i);
293
273
  return;
294
274
  }
295
275
  }
296
- this.applyLayoutAndA11y({ announce: !0, emitChange: !1 });
276
+ this.applyLayoutAndA11y({ emitChange: !1 });
297
277
  }
298
278
  next() {
299
279
  this.goTo(this.currentIndex + 1);
@@ -303,14 +283,14 @@ class m extends HTMLElement {
303
283
  }
304
284
  goTo(t) {
305
285
  if (this.isAnimating) return;
306
- const n = f(t, this.cards.length);
307
- n !== this.currentIndex && (this.isAnimating = !0, this.currentIndex = n, this.reflectIndexAttr(), this.applyLayoutAndA11y({ announce: !0, emitChange: !0 }), this.lockUntilTransitionEnd());
286
+ const s = u(t, this.cards.length);
287
+ s !== this.currentIndex && (this.isAnimating = !0, this.currentIndex = s, this.reflectIndexAttr(), this.applyLayoutAndA11y({ emitChange: !0 }), this.lockUntilTransitionEnd());
308
288
  }
309
289
  refresh() {
310
290
  const t = this.lightDomObserver;
311
291
  t && (this.suppressMutations = !0, t.disconnect(), t.takeRecords()), this.rebuildCardsFromLightDom();
312
- const n = C(this, "start-index", 0), s = w(this, "index"), e = s != null ? Number(s) : n, i = Number.isFinite(e) ? e : 0;
313
- this.currentIndex = f(i, this.cards.length), this.reflectIndexAttr(), this.buildDots(), this.hasAppliedInitialLayout = !1, this.lastLayoutIndex = null, this.lastVisibleSet = /* @__PURE__ */ new Set(), this.applyLayoutAndA11y({ announce: !0, emitChange: !1 }), this.dispatchReady(), t && (t.observe(this, this.lightDomObserverOptions), t.takeRecords(), this.suppressMutations = !1);
292
+ const s = C(this, "start-index", 0), n = A(this, "index"), e = n != null ? Number(n) : s, i = Number.isFinite(e) ? e : 0;
293
+ this.currentIndex = u(i, this.cards.length), this.reflectIndexAttr(), this.buildDots(), this.hasAppliedInitialLayout = !1, this.lastLayoutIndex = null, this.lastVisibleSet = /* @__PURE__ */ new Set(), this.applyLayoutAndA11y({ emitChange: !1 }), this.dispatchReady(), t && (t.observe(this, this.lightDomObserverOptions), t.takeRecords(), this.suppressMutations = !1);
314
294
  }
315
295
  destroy() {
316
296
  this.animFallbackTimerId !== null && (window.clearTimeout(this.animFallbackTimerId), this.animFallbackTimerId = null), this.cleanup.forEach((t) => {
@@ -328,26 +308,26 @@ class m extends HTMLElement {
328
308
  }
329
309
  readAttributes(t) {
330
310
  this.rootEl || this.render();
331
- const n = u(this, "show-arrows", !1), s = u(this, "show-dots", !1);
332
- this.prevBtn.style.display = n ? "" : "none", this.nextBtn.style.display = n ? "" : "none", this.dotsEl.style.display = s ? "" : "none";
311
+ const s = b(this, "show-arrows", !1), n = b(this, "show-dots", !1);
312
+ this.prevBtn.style.display = s ? "" : "none", this.nextBtn.style.display = s ? "" : "none", this.dotsEl.style.display = n ? "" : "none";
333
313
  const e = this.getAttribute("aria-label");
334
314
  e && this.rootEl.setAttribute("aria-label", e), t.isInit && this.setAttribute("aria-roledescription", "carousel");
335
315
  }
336
316
  render() {
337
- this.applyAllStyles(), this.rootEl = document.createElement("div"), this.rootEl.className = "cfc", this.trackEl = document.createElement("div"), this.trackEl.className = "cfc__track", this.prevBtn = document.createElement("button"), this.prevBtn.type = "button", this.prevBtn.className = "cfc__arrow cfc__arrow--left", this.prevBtn.setAttribute("aria-label", "Previous"), this.prevBtn.textContent = "‹", this.nextBtn = document.createElement("button"), this.nextBtn.type = "button", this.nextBtn.className = "cfc__arrow cfc__arrow--right", this.nextBtn.setAttribute("aria-label", "Next"), this.nextBtn.textContent = "›", this.dotsEl = document.createElement("div"), this.dotsEl.className = "cfc__dots", this.liveRegion = document.createElement("div"), this.liveRegion.className = "cfc__sr", this.liveRegion.setAttribute("aria-live", "polite"), this.liveRegion.setAttribute("aria-atomic", "true"), this.rootEl.append(this.trackEl, this.prevBtn, this.nextBtn, this.dotsEl, this.liveRegion), this.shadow.innerHTML = "", this.baseStyleEl && this.shadow.append(this.baseStyleEl), this.overrideStyleEl && this.shadow.append(this.overrideStyleEl), this.shadow.append(this.rootEl), this.bindEvents();
317
+ this.applyAllStyles(), this.rootEl = document.createElement("div"), this.rootEl.className = "cfc", this.trackEl = document.createElement("div"), this.trackEl.className = "cfc__track", this.prevBtn = document.createElement("button"), this.prevBtn.type = "button", this.prevBtn.className = "cfc__arrow cfc__arrow--left", this.prevBtn.setAttribute("aria-label", "Previous"), this.prevBtn.textContent = "‹", this.nextBtn = document.createElement("button"), this.nextBtn.type = "button", this.nextBtn.className = "cfc__arrow cfc__arrow--right", this.nextBtn.setAttribute("aria-label", "Next"), this.nextBtn.textContent = "›", this.dotsEl = document.createElement("div"), this.dotsEl.className = "cfc__dots", this.rootEl.append(this.trackEl, this.prevBtn, this.nextBtn, this.dotsEl), this.shadow.innerHTML = "", this.baseStyleEl && this.shadow.append(this.baseStyleEl), this.overrideStyleEl && this.shadow.append(this.overrideStyleEl), this.shadow.append(this.rootEl), this.bindEvents();
338
318
  }
339
319
  bindEvents() {
340
320
  this.cleanup.forEach((i) => {
341
321
  i();
342
322
  }), this.cleanup = [];
343
- const t = () => this.prev(), n = () => this.next();
344
- this.prevBtn.addEventListener("click", t), this.nextBtn.addEventListener("click", n), this.cleanup.push(() => this.prevBtn.removeEventListener("click", t)), this.cleanup.push(() => this.nextBtn.removeEventListener("click", n));
345
- const s = (i) => {
323
+ const t = () => this.prev(), s = () => this.next();
324
+ this.prevBtn.addEventListener("click", t), this.nextBtn.addEventListener("click", s), this.cleanup.push(() => this.prevBtn.removeEventListener("click", t)), this.cleanup.push(() => this.nextBtn.removeEventListener("click", s));
325
+ const n = (i) => {
346
326
  if (!this.isAnimating || i.propertyName !== "transform" || !(i.target instanceof HTMLElement)) return;
347
327
  const r = this.cards[this.currentIndex];
348
328
  r && i.target === r && this.unlockAnimation();
349
329
  };
350
- this.rootEl.addEventListener("transitionend", s), this.cleanup.push(() => this.rootEl.removeEventListener("transitionend", s));
330
+ this.rootEl.addEventListener("transitionend", n), this.cleanup.push(() => this.rootEl.removeEventListener("transitionend", n));
351
331
  const e = (i) => {
352
332
  const r = i.target;
353
333
  if (!(r instanceof HTMLElement) || r.tagName !== "SCRATCH-REVEAL") return;
@@ -359,10 +339,10 @@ class m extends HTMLElement {
359
339
  if (!l) return;
360
340
  const c = Number(l.dataset.cfcIndex);
361
341
  if (!Number.isFinite(c)) return;
362
- const v = i.detail?.percent ?? 100;
342
+ const m = i.detail?.percent ?? 100;
363
343
  this.dispatchEvent(
364
344
  new CustomEvent("coverflow-carousel:scratch-complete", {
365
- detail: { index: c, length: this.cards.length, percent: v },
345
+ detail: { index: c, length: this.cards.length, percent: m },
366
346
  bubbles: !0,
367
347
  composed: !0
368
348
  })
@@ -374,7 +354,7 @@ class m extends HTMLElement {
374
354
  }
375
355
  setupLightDomObserver() {
376
356
  this.lightDomObserver || (this.lightDomObserver = new MutationObserver((t) => {
377
- this.suppressMutations || !t.some((s) => !(s.type === "attributes" && s.attributeName === "slot")) || this.scheduleRefreshFromMutations();
357
+ this.suppressMutations || !t.some((n) => !(n.type === "attributes" && n.attributeName === "slot")) || this.scheduleRefreshFromMutations();
378
358
  }), this.lightDomObserver.observe(this, {
379
359
  ...this.lightDomObserverOptions
380
360
  }), this.cleanup.push(() => {
@@ -389,99 +369,99 @@ class m extends HTMLElement {
389
369
  rebuildCardsFromLightDom() {
390
370
  const t = Array.from(this.trackEl.children).filter(
391
371
  (e) => e instanceof HTMLElement && e.classList.contains("cfc__card")
392
- ), n = [], s = Array.from(this.children).filter(
372
+ ), s = [], n = Array.from(this.children).filter(
393
373
  (e) => e instanceof HTMLElement
394
374
  );
395
- for (let e = 0; e < s.length; e++) {
396
- const i = s[e], r = t[e] ?? document.createElement("div"), o = `${this.instanceId}-slot-${e}`;
375
+ for (let e = 0; e < n.length; e++) {
376
+ const i = n[e], r = t[e] ?? document.createElement("div"), o = `${this.instanceId}-slot-${e}`;
397
377
  t[e] || (r.className = "cfc__card", this.trackEl.append(r)), i.getAttribute("slot") !== o && i.setAttribute("slot", o);
398
378
  const l = r.querySelector("slot");
399
379
  let c;
400
- l instanceof HTMLSlotElement ? c = l : (c = document.createElement("slot"), r.replaceChildren(c)), c.name !== o && (c.name = o), n.push(r);
380
+ l instanceof HTMLSlotElement ? c = l : (c = document.createElement("slot"), r.replaceChildren(c)), c.name !== o && (c.name = o), s.push(r);
401
381
  }
402
- for (let e = s.length; e < t.length; e++)
382
+ for (let e = n.length; e < t.length; e++)
403
383
  t[e]?.remove();
404
- this.cards = n, this.hasAppliedInitialLayout = !1, this.lastLayoutIndex = null, this.lastVisibleSet = /* @__PURE__ */ new Set();
384
+ this.cards = s, this.hasAppliedInitialLayout = !1, this.lastLayoutIndex = null, this.lastVisibleSet = /* @__PURE__ */ new Set();
405
385
  }
406
386
  getVisibleSet() {
407
- const t = this.cards.length, n = /* @__PURE__ */ new Set();
408
- if (t <= 0) return n;
409
- const s = Math.floor(t / 2);
410
- if (p >= s) {
411
- for (let e = 0; e < t; e++) n.add(e);
412
- return n;
387
+ const t = this.cards.length, s = /* @__PURE__ */ new Set();
388
+ if (t <= 0) return s;
389
+ const n = Math.floor(t / 2);
390
+ if (f >= n) {
391
+ for (let e = 0; e < t; e++) s.add(e);
392
+ return s;
413
393
  }
414
- for (let e = -p; e <= p; e++)
415
- n.add(f(this.currentIndex + e, t));
416
- return n;
394
+ for (let e = -f; e <= f; e++)
395
+ s.add(u(this.currentIndex + e, t));
396
+ return s;
417
397
  }
418
398
  buildDots() {
419
399
  const t = Array.from(this.dotsEl.children).filter(
420
400
  (i) => i instanceof HTMLElement && i.classList.contains("cfc__dot")
421
401
  );
422
- if (!u(this, "show-dots", !1)) {
402
+ if (!b(this, "show-dots", !1)) {
423
403
  t.forEach((i) => {
424
404
  i.remove();
425
405
  }), this.dots = [];
426
406
  return;
427
407
  }
428
- const s = [], e = this.cards.length;
408
+ const n = [], e = this.cards.length;
429
409
  for (let i = 0; i < e; i++) {
430
410
  const r = t[i] ?? document.createElement("span");
431
- t[i] || this.dotsEl.append(r), r.className = "cfc__dot", r.setAttribute("aria-hidden", "true"), s.push(r);
411
+ t[i] || this.dotsEl.append(r), r.className = "cfc__dot", r.setAttribute("aria-hidden", "true"), n.push(r);
432
412
  }
433
413
  for (let i = e; i < t.length; i++)
434
414
  t[i]?.remove();
435
- this.dots = s, this.updateDotsVisualState();
415
+ this.dots = n, this.updateDotsVisualState();
436
416
  }
437
417
  computeCardState(t) {
438
- const n = this.cards.length, s = L(this.currentIndex, t, n), e = Math.abs(s);
418
+ const s = this.cards.length, n = L(this.currentIndex, t, s), e = Math.abs(n);
439
419
  return {
440
420
  index: t,
441
- delta: s,
421
+ delta: n,
442
422
  abs: e,
443
- isVisible: e <= p,
423
+ isVisible: e <= f,
444
424
  isActive: t === this.currentIndex
445
425
  };
446
426
  }
447
- applyCardState(t, n) {
448
- t.setAttribute("aria-hidden", n.isVisible ? "false" : "true"), t.dataset.active = n.isActive ? "true" : "false", t.dataset.cfcIndex = String(n.index), t.setAttribute("role", "group"), t.setAttribute("aria-roledescription", "slide"), t.setAttribute("aria-setsize", String(this.cards.length)), t.setAttribute("aria-posinset", String(n.index + 1));
449
- const s = `${this.instanceId}-slide-${n.index}`;
450
- t.id = s;
451
- const e = String(n.delta), i = String(n.abs), r = t.dataset.cfcDelta, o = t.dataset.cfcAbs;
427
+ applyCardState(t, s) {
428
+ t.setAttribute("aria-hidden", s.isVisible ? "false" : "true"), t.dataset.active = s.isActive ? "true" : "false", t.dataset.cfcIndex = String(s.index), t.setAttribute("role", "group"), t.setAttribute("aria-roledescription", "slide"), t.setAttribute("aria-setsize", String(this.cards.length)), t.setAttribute("aria-posinset", String(s.index + 1));
429
+ const n = `${this.instanceId}-slide-${s.index}`;
430
+ t.id = n;
431
+ const e = String(s.delta), i = String(s.abs), r = t.dataset.cfcDelta, o = t.dataset.cfcAbs;
452
432
  r !== e && (t.style.setProperty("--cfc-delta", e), t.dataset.cfcDelta = e), o !== i && (t.style.setProperty("--cfc-abs", i), t.dataset.cfcAbs = i);
453
433
  }
454
434
  applyLayoutAndA11y(t) {
455
435
  if (this.cards.length) {
456
436
  if (this.hasAppliedInitialLayout) {
457
- const n = this.getVisibleSet(), s = /* @__PURE__ */ new Set();
437
+ const s = this.getVisibleSet(), n = /* @__PURE__ */ new Set();
458
438
  this.lastVisibleSet.forEach((e) => {
459
- s.add(e);
460
- }), n.forEach((e) => {
461
- s.add(e);
462
- }), this.lastLayoutIndex != null && s.add(this.lastLayoutIndex), s.add(this.currentIndex), s.forEach((e) => {
439
+ n.add(e);
440
+ }), s.forEach((e) => {
441
+ n.add(e);
442
+ }), this.lastLayoutIndex != null && n.add(this.lastLayoutIndex), n.add(this.currentIndex), n.forEach((e) => {
463
443
  const i = this.cards[e];
464
444
  if (!i) return;
465
445
  const r = this.computeCardState(e);
466
446
  this.applyCardState(i, r);
467
- }), this.lastLayoutIndex = this.currentIndex, this.lastVisibleSet = n;
447
+ }), this.lastLayoutIndex = this.currentIndex, this.lastVisibleSet = s;
468
448
  } else {
469
- for (let n = 0; n < this.cards.length; n++) {
470
- const s = this.cards[n];
471
- if (!s) continue;
472
- const e = this.computeCardState(n);
473
- this.applyCardState(s, e);
449
+ for (let s = 0; s < this.cards.length; s++) {
450
+ const n = this.cards[s];
451
+ if (!n) continue;
452
+ const e = this.computeCardState(s);
453
+ this.applyCardState(n, e);
474
454
  }
475
455
  this.hasAppliedInitialLayout = !0, this.lastLayoutIndex = this.currentIndex, this.lastVisibleSet = this.getVisibleSet();
476
456
  }
477
- this.updateDotsVisualState(), t.announce && u(this, "announce-changes", !0) && this.announce(`Slide ${this.currentIndex + 1} of ${this.cards.length}`), t.emitChange && this.emitChange();
457
+ this.updateDotsVisualState(), t.emitChange && this.emitChange();
478
458
  }
479
459
  }
480
460
  updateDotsVisualState() {
481
461
  if (this.dots.length)
482
462
  for (let t = 0; t < this.dots.length; t++) {
483
- const n = this.dots[t], s = t === this.currentIndex;
484
- n.dataset.active = s ? "true" : "false";
463
+ const s = this.dots[t], n = t === this.currentIndex;
464
+ s.dataset.active = n ? "true" : "false";
485
465
  }
486
466
  }
487
467
  lockUntilTransitionEnd() {
@@ -491,17 +471,17 @@ class m extends HTMLElement {
491
471
  this.unlockAnimation();
492
472
  return;
493
473
  }
494
- const n = this.cards[this.currentIndex];
495
- if (!n) {
474
+ const s = this.cards[this.currentIndex];
475
+ if (!s) {
496
476
  this.unlockAnimation();
497
477
  return;
498
478
  }
499
- const s = getComputedStyle(n), e = k(s, "transform");
479
+ const n = getComputedStyle(s), e = k(n, "transform");
500
480
  if (e <= 0) {
501
481
  this.unlockAnimation();
502
482
  return;
503
483
  }
504
- const i = g(s.getPropertyValue("--cfc-transition-ms").trim(), 400), o = Math.max(e, i) + 60;
484
+ const i = g(n.getPropertyValue("--cfc-transition-ms").trim(), 400), o = Math.max(e, i) + 60;
505
485
  this.animFallbackTimerId !== null && window.clearTimeout(this.animFallbackTimerId), this.animFallbackTimerId = window.setTimeout(() => {
506
486
  this.pendingAnimToken === t && this.unlockAnimation();
507
487
  }, o);
@@ -523,11 +503,6 @@ class m extends HTMLElement {
523
503
  })
524
504
  );
525
505
  }
526
- announce(t) {
527
- this.liveRegion.textContent = "", queueMicrotask(() => {
528
- this.liveRegion.textContent = t;
529
- });
530
- }
531
506
  reflectIndexAttr() {
532
507
  this.reflectGuard = !0;
533
508
  try {
@@ -543,7 +518,7 @@ class m extends HTMLElement {
543
518
  this.overrideStyles = t ?? null, this.applyAllStyles();
544
519
  }
545
520
  applyAllStyles() {
546
- const t = this.baseStyles, n = this.overrideStyles;
521
+ const t = this.baseStyles, s = this.overrideStyles;
547
522
  if (E(this.shadow)) {
548
523
  const e = [];
549
524
  if (typeof t == "string") {
@@ -555,46 +530,46 @@ class m extends HTMLElement {
555
530
  e.push(i);
556
531
  } else if (t)
557
532
  e.push(t);
558
- else if (m.defaultStylesheet)
559
- e.push(m.defaultStylesheet);
533
+ else if (p.defaultStylesheet)
534
+ e.push(p.defaultStylesheet);
560
535
  else {
561
536
  this.applyAllStylesFallback();
562
537
  return;
563
538
  }
564
- if (typeof n == "string") {
565
- const i = y(n);
539
+ if (typeof s == "string") {
540
+ const i = y(s);
566
541
  if (!i) {
567
542
  this.applyAllStylesFallback();
568
543
  return;
569
544
  }
570
545
  e.push(i);
571
- } else n && e.push(n);
546
+ } else s && e.push(s);
572
547
  this.shadow.adoptedStyleSheets = e, this.baseStyleEl?.remove(), this.overrideStyleEl?.remove(), this.baseStyleEl = null, this.overrideStyleEl = null;
573
548
  return;
574
549
  }
575
550
  this.applyAllStylesFallback();
576
551
  }
577
552
  applyAllStylesFallback() {
578
- const t = this.baseStyles, n = this.overrideStyles;
553
+ const t = this.baseStyles, s = this.overrideStyles;
579
554
  E(this.shadow) && (this.shadow.adoptedStyleSheets = []);
580
- const s = typeof t == "string" ? t : I, e = typeof n == "string" ? n : "";
581
- this.baseStyleEl || (this.baseStyleEl = document.createElement("style")), this.baseStyleEl.textContent = s, e ? (this.overrideStyleEl || (this.overrideStyleEl = document.createElement("style")), this.overrideStyleEl.textContent = e) : (this.overrideStyleEl?.remove(), this.overrideStyleEl = null);
555
+ const n = typeof t == "string" ? t : I, e = typeof s == "string" ? s : "";
556
+ this.baseStyleEl || (this.baseStyleEl = document.createElement("style")), this.baseStyleEl.textContent = n, e ? (this.overrideStyleEl || (this.overrideStyleEl = document.createElement("style")), this.overrideStyleEl.textContent = e) : (this.overrideStyleEl?.remove(), this.overrideStyleEl = null);
582
557
  }
583
558
  }
584
559
  function F(a = {}) {
585
560
  const {
586
561
  selector: t = "coverflow-carousel",
587
- onReady: n,
588
- onChange: s,
562
+ onReady: s,
563
+ onChange: n,
589
564
  onScratchComplete: e,
590
565
  stylesheet: i,
591
566
  styleOverrides: r
592
567
  } = a, o = Array.from(document.querySelectorAll(t));
593
- return (n || s || e) && o.forEach((l) => {
594
- n && l.addEventListener("coverflow-carousel:ready", (c) => {
595
- n(l, c.detail);
596
- }), s && l.addEventListener("coverflow-carousel:change", (c) => {
568
+ return (s || n || e) && o.forEach((l) => {
569
+ s && l.addEventListener("coverflow-carousel:ready", (c) => {
597
570
  s(l, c.detail);
571
+ }), n && l.addEventListener("coverflow-carousel:change", (c) => {
572
+ n(l, c.detail);
598
573
  }), e && l.addEventListener("coverflow-carousel:scratch-complete", (c) => {
599
574
  e(l, c.detail);
600
575
  });
@@ -606,10 +581,10 @@ function F(a = {}) {
606
581
  }), o;
607
582
  }
608
583
  function M(a = "coverflow-carousel") {
609
- typeof window > "u" || !("customElements" in window) || customElements.get(a) || customElements.define(a, m);
584
+ typeof window > "u" || !("customElements" in window) || customElements.get(a) || customElements.define(a, p);
610
585
  }
611
586
  export {
612
- m as CoverflowCarouselElement,
587
+ p as CoverflowCarouselElement,
613
588
  D as coverflowCarouselCssText,
614
589
  F as initCoverflowCarousels,
615
590
  M as registerCoverflowCarouselElement
package/dist/index.umd.js CHANGED
@@ -1,4 +1,4 @@
1
- (function(h,d){typeof exports=="object"&&typeof module<"u"?d(exports):typeof define=="function"&&define.amd?define(["exports"],d):(h=typeof globalThis<"u"?globalThis:h||self,d(h.CoverflowCarousel={}))})(this,(function(h){"use strict";const d=`:host {
1
+ (function(d,h){typeof exports=="object"&&typeof module<"u"?h(exports):typeof define=="function"&&define.amd?define(["exports"],h):(d=typeof globalThis<"u"?globalThis:d||self,h(d.CoverflowCarousel={}))})(this,(function(d){"use strict";const h=`:host {
2
2
  display: block;
3
3
  width: 100%;
4
4
  height: 100%;
@@ -151,17 +151,4 @@
151
151
  background: Crimson;
152
152
  transform: scale(1.2);
153
153
  }
154
-
155
- /* SR-only */
156
- .cfc__sr {
157
- position: absolute;
158
- width: 1px;
159
- height: 1px;
160
- padding: 0;
161
- margin: -1px;
162
- overflow: hidden;
163
- clip: rect(0, 0, 0, 0);
164
- white-space: nowrap;
165
- border: 0;
166
- }
167
- `,I=d;function E(a){return"adoptedStyleSheets"in a}function y(a){try{const t=new CSSStyleSheet;return t.replaceSync(a),t}catch{return null}}const C=y(d),k=d;function g(a){return a.split(",").map(t=>t.trim()).filter(Boolean)}function x(a,t){const n=a.trim();if(!n)return t;if(n.endsWith("ms")){const e=Number(n.slice(0,-2).trim());return Number.isFinite(e)?e:t}if(n.endsWith("s")){const e=Number(n.slice(0,-1).trim());return Number.isFinite(e)?e*1e3:t}const s=Number(n);return Number.isFinite(s)?s:t}function _(a,t){const n=g(a.transitionProperty),s=g(a.transitionDuration),e=g(a.transitionDelay);if(!n.length)return 0;const r=(S=>{const u=n.indexOf(S);if(u>=0)return u;const A=n.indexOf("all");return A>=0?A:-1})(t);if(r<0)return 0;const o=s[Math.min(r,s.length-1)]??"0s",l=e[Math.min(r,e.length-1)]??"0s",c=x(o,0),p=x(l,0);return Math.max(0,c+p)}function T(){return window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches??!1}function m(a,t,n){if(!a.hasAttribute(t))return n;const s=a.getAttribute(t);return s==null||s===""?!0:s!=="false"}function L(a,t,n){const s=a.getAttribute(t);if(s==null)return n;const e=Number(s.trim());return Number.isFinite(e)?Math.trunc(e):n}function w(a,t){const n=a.getAttribute(t);if(n==null)return null;const s=n.trim();return s||null}function v(a,t){return t<=0?0:(a%t+t)%t}function D(a,t,n){const s=t-a,e=n/2;return s>e?s-n:s<-e?s+n:s}const b=1;let F=0;class f extends HTMLElement{static defaultStylesheet=C;static observedAttributes=["start-index","index","show-dots","show-arrows","announce-changes"];shadow=this.attachShadow({mode:"open"});instanceId=`cfc-${++F}`;rootEl;trackEl;dotsEl;prevBtn;nextBtn;liveRegion;baseStyles=null;overrideStyles=null;baseStyleEl=null;overrideStyleEl=null;cards=[];dots=[];currentIndex=0;isAnimating=!1;hasAppliedInitialLayout=!1;lastLayoutIndex=null;lastVisibleSet=new Set;pendingAnimToken=0;animFallbackTimerId=null;cleanup=[];lightDomObserverOptions={childList:!0,attributes:!0,subtree:!0};lightDomObserver=null;refreshScheduled=!1;suppressMutations=!1;reflectGuard=!1;connectedCallback(){this.render(),this.readAttributes({isInit:!0}),this.refresh(),this.setupLightDomObserver()}disconnectedCallback(){this.destroy()}attributeChangedCallback(t,n,s){if(!this.isConnected||this.reflectGuard)return;this.readAttributes({isInit:!1});const e=w(this,"index");if(e!=null){const i=v(Number(e),this.cards.length);if(Number.isFinite(i)&&i!==this.currentIndex){this.goTo(i);return}}this.applyLayoutAndA11y({announce:!0,emitChange:!1})}next(){this.goTo(this.currentIndex+1)}prev(){this.goTo(this.currentIndex-1)}goTo(t){if(this.isAnimating)return;const n=v(t,this.cards.length);n!==this.currentIndex&&(this.isAnimating=!0,this.currentIndex=n,this.reflectIndexAttr(),this.applyLayoutAndA11y({announce:!0,emitChange:!0}),this.lockUntilTransitionEnd())}refresh(){const t=this.lightDomObserver;t&&(this.suppressMutations=!0,t.disconnect(),t.takeRecords()),this.rebuildCardsFromLightDom();const n=L(this,"start-index",0),s=w(this,"index"),e=s!=null?Number(s):n,i=Number.isFinite(e)?e:0;this.currentIndex=v(i,this.cards.length),this.reflectIndexAttr(),this.buildDots(),this.hasAppliedInitialLayout=!1,this.lastLayoutIndex=null,this.lastVisibleSet=new Set,this.applyLayoutAndA11y({announce:!0,emitChange:!1}),this.dispatchReady(),t&&(t.observe(this,this.lightDomObserverOptions),t.takeRecords(),this.suppressMutations=!1)}destroy(){this.animFallbackTimerId!==null&&(window.clearTimeout(this.animFallbackTimerId),this.animFallbackTimerId=null),this.cleanup.forEach(t=>{t()}),this.cleanup=[],this.isAnimating=!1}adoptStylesheet(t){this.setBaseStyles(t)}adoptStyles(t){this.setBaseStyles(t)}adoptStyleOverrides(t){this.setOverrideStyles(t)}readAttributes(t){this.rootEl||this.render();const n=m(this,"show-arrows",!1),s=m(this,"show-dots",!1);this.prevBtn.style.display=n?"":"none",this.nextBtn.style.display=n?"":"none",this.dotsEl.style.display=s?"":"none";const e=this.getAttribute("aria-label");e&&this.rootEl.setAttribute("aria-label",e),t.isInit&&this.setAttribute("aria-roledescription","carousel")}render(){this.applyAllStyles(),this.rootEl=document.createElement("div"),this.rootEl.className="cfc",this.trackEl=document.createElement("div"),this.trackEl.className="cfc__track",this.prevBtn=document.createElement("button"),this.prevBtn.type="button",this.prevBtn.className="cfc__arrow cfc__arrow--left",this.prevBtn.setAttribute("aria-label","Previous"),this.prevBtn.textContent="‹",this.nextBtn=document.createElement("button"),this.nextBtn.type="button",this.nextBtn.className="cfc__arrow cfc__arrow--right",this.nextBtn.setAttribute("aria-label","Next"),this.nextBtn.textContent="›",this.dotsEl=document.createElement("div"),this.dotsEl.className="cfc__dots",this.liveRegion=document.createElement("div"),this.liveRegion.className="cfc__sr",this.liveRegion.setAttribute("aria-live","polite"),this.liveRegion.setAttribute("aria-atomic","true"),this.rootEl.append(this.trackEl,this.prevBtn,this.nextBtn,this.dotsEl,this.liveRegion),this.shadow.innerHTML="",this.baseStyleEl&&this.shadow.append(this.baseStyleEl),this.overrideStyleEl&&this.shadow.append(this.overrideStyleEl),this.shadow.append(this.rootEl),this.bindEvents()}bindEvents(){this.cleanup.forEach(i=>{i()}),this.cleanup=[];const t=()=>this.prev(),n=()=>this.next();this.prevBtn.addEventListener("click",t),this.nextBtn.addEventListener("click",n),this.cleanup.push(()=>this.prevBtn.removeEventListener("click",t)),this.cleanup.push(()=>this.nextBtn.removeEventListener("click",n));const s=i=>{if(!this.isAnimating||i.propertyName!=="transform"||!(i.target instanceof HTMLElement))return;const r=this.cards[this.currentIndex];r&&i.target===r&&this.unlockAnimation()};this.rootEl.addEventListener("transitionend",s),this.cleanup.push(()=>this.rootEl.removeEventListener("transitionend",s));const e=i=>{const r=i.target;if(!(r instanceof HTMLElement)||r.tagName!=="SCRATCH-REVEAL")return;const o=i.composedPath?.();if(!o?.length)return;const l=o.find(u=>u instanceof HTMLElement&&u.classList.contains("cfc__card")&&u.dataset.cfcIndex!=null);if(!l)return;const c=Number(l.dataset.cfcIndex);if(!Number.isFinite(c))return;const S=i.detail?.percent??100;this.dispatchEvent(new CustomEvent("coverflow-carousel:scratch-complete",{detail:{index:c,length:this.cards.length,percent:S},bubbles:!0,composed:!0}))};this.rootEl.addEventListener("complete",e),this.cleanup.push(()=>this.rootEl.removeEventListener("complete",e))}setupLightDomObserver(){this.lightDomObserver||(this.lightDomObserver=new MutationObserver(t=>{this.suppressMutations||!t.some(s=>!(s.type==="attributes"&&s.attributeName==="slot"))||this.scheduleRefreshFromMutations()}),this.lightDomObserver.observe(this,{...this.lightDomObserverOptions}),this.cleanup.push(()=>{this.lightDomObserver?.disconnect(),this.lightDomObserver=null}))}scheduleRefreshFromMutations(){this.refreshScheduled||(this.refreshScheduled=!0,queueMicrotask(()=>{this.refreshScheduled=!1,this.isConnected&&this.refresh()}))}rebuildCardsFromLightDom(){const t=Array.from(this.trackEl.children).filter(e=>e instanceof HTMLElement&&e.classList.contains("cfc__card")),n=[],s=Array.from(this.children).filter(e=>e instanceof HTMLElement);for(let e=0;e<s.length;e++){const i=s[e],r=t[e]??document.createElement("div"),o=`${this.instanceId}-slot-${e}`;t[e]||(r.className="cfc__card",this.trackEl.append(r)),i.getAttribute("slot")!==o&&i.setAttribute("slot",o);const l=r.querySelector("slot");let c;l instanceof HTMLSlotElement?c=l:(c=document.createElement("slot"),r.replaceChildren(c)),c.name!==o&&(c.name=o),n.push(r)}for(let e=s.length;e<t.length;e++)t[e]?.remove();this.cards=n,this.hasAppliedInitialLayout=!1,this.lastLayoutIndex=null,this.lastVisibleSet=new Set}getVisibleSet(){const t=this.cards.length,n=new Set;if(t<=0)return n;const s=Math.floor(t/2);if(b>=s){for(let e=0;e<t;e++)n.add(e);return n}for(let e=-b;e<=b;e++)n.add(v(this.currentIndex+e,t));return n}buildDots(){const t=Array.from(this.dotsEl.children).filter(i=>i instanceof HTMLElement&&i.classList.contains("cfc__dot"));if(!m(this,"show-dots",!1)){t.forEach(i=>{i.remove()}),this.dots=[];return}const s=[],e=this.cards.length;for(let i=0;i<e;i++){const r=t[i]??document.createElement("span");t[i]||this.dotsEl.append(r),r.className="cfc__dot",r.setAttribute("aria-hidden","true"),s.push(r)}for(let i=e;i<t.length;i++)t[i]?.remove();this.dots=s,this.updateDotsVisualState()}computeCardState(t){const n=this.cards.length,s=D(this.currentIndex,t,n),e=Math.abs(s);return{index:t,delta:s,abs:e,isVisible:e<=b,isActive:t===this.currentIndex}}applyCardState(t,n){t.setAttribute("aria-hidden",n.isVisible?"false":"true"),t.dataset.active=n.isActive?"true":"false",t.dataset.cfcIndex=String(n.index),t.setAttribute("role","group"),t.setAttribute("aria-roledescription","slide"),t.setAttribute("aria-setsize",String(this.cards.length)),t.setAttribute("aria-posinset",String(n.index+1));const s=`${this.instanceId}-slide-${n.index}`;t.id=s;const e=String(n.delta),i=String(n.abs),r=t.dataset.cfcDelta,o=t.dataset.cfcAbs;r!==e&&(t.style.setProperty("--cfc-delta",e),t.dataset.cfcDelta=e),o!==i&&(t.style.setProperty("--cfc-abs",i),t.dataset.cfcAbs=i)}applyLayoutAndA11y(t){if(this.cards.length){if(this.hasAppliedInitialLayout){const n=this.getVisibleSet(),s=new Set;this.lastVisibleSet.forEach(e=>{s.add(e)}),n.forEach(e=>{s.add(e)}),this.lastLayoutIndex!=null&&s.add(this.lastLayoutIndex),s.add(this.currentIndex),s.forEach(e=>{const i=this.cards[e];if(!i)return;const r=this.computeCardState(e);this.applyCardState(i,r)}),this.lastLayoutIndex=this.currentIndex,this.lastVisibleSet=n}else{for(let n=0;n<this.cards.length;n++){const s=this.cards[n];if(!s)continue;const e=this.computeCardState(n);this.applyCardState(s,e)}this.hasAppliedInitialLayout=!0,this.lastLayoutIndex=this.currentIndex,this.lastVisibleSet=this.getVisibleSet()}this.updateDotsVisualState(),t.announce&&m(this,"announce-changes",!0)&&this.announce(`Slide ${this.currentIndex+1} of ${this.cards.length}`),t.emitChange&&this.emitChange()}}updateDotsVisualState(){if(this.dots.length)for(let t=0;t<this.dots.length;t++){const n=this.dots[t],s=t===this.currentIndex;n.dataset.active=s?"true":"false"}}lockUntilTransitionEnd(){this.pendingAnimToken++;const t=this.pendingAnimToken;if(T()){this.unlockAnimation();return}const n=this.cards[this.currentIndex];if(!n){this.unlockAnimation();return}const s=getComputedStyle(n),e=_(s,"transform");if(e<=0){this.unlockAnimation();return}const i=x(s.getPropertyValue("--cfc-transition-ms").trim(),400),o=Math.max(e,i)+60;this.animFallbackTimerId!==null&&window.clearTimeout(this.animFallbackTimerId),this.animFallbackTimerId=window.setTimeout(()=>{this.pendingAnimToken===t&&this.unlockAnimation()},o)}unlockAnimation(){this.isAnimating=!1,this.animFallbackTimerId!==null&&(window.clearTimeout(this.animFallbackTimerId),this.animFallbackTimerId=null)}emitChange(){this.dispatchEvent(new CustomEvent("coverflow-carousel:change",{detail:{index:this.currentIndex,length:this.cards.length}}))}dispatchReady(){this.dispatchEvent(new CustomEvent("coverflow-carousel:ready",{detail:{index:this.currentIndex,length:this.cards.length}}))}announce(t){this.liveRegion.textContent="",queueMicrotask(()=>{this.liveRegion.textContent=t})}reflectIndexAttr(){this.reflectGuard=!0;try{this.setAttribute("index",String(this.currentIndex))}finally{this.reflectGuard=!1}}setBaseStyles(t){this.baseStyles=t??null,this.applyAllStyles()}setOverrideStyles(t){this.overrideStyles=t??null,this.applyAllStyles()}applyAllStyles(){const t=this.baseStyles,n=this.overrideStyles;if(E(this.shadow)){const e=[];if(typeof t=="string"){const i=y(t);if(!i){this.applyAllStylesFallback();return}e.push(i)}else if(t)e.push(t);else if(f.defaultStylesheet)e.push(f.defaultStylesheet);else{this.applyAllStylesFallback();return}if(typeof n=="string"){const i=y(n);if(!i){this.applyAllStylesFallback();return}e.push(i)}else n&&e.push(n);this.shadow.adoptedStyleSheets=e,this.baseStyleEl?.remove(),this.overrideStyleEl?.remove(),this.baseStyleEl=null,this.overrideStyleEl=null;return}this.applyAllStylesFallback()}applyAllStylesFallback(){const t=this.baseStyles,n=this.overrideStyles;E(this.shadow)&&(this.shadow.adoptedStyleSheets=[]);const s=typeof t=="string"?t:k,e=typeof n=="string"?n:"";this.baseStyleEl||(this.baseStyleEl=document.createElement("style")),this.baseStyleEl.textContent=s,e?(this.overrideStyleEl||(this.overrideStyleEl=document.createElement("style")),this.overrideStyleEl.textContent=e):(this.overrideStyleEl?.remove(),this.overrideStyleEl=null)}}function M(a={}){const{selector:t="coverflow-carousel",onReady:n,onChange:s,onScratchComplete:e,stylesheet:i,styleOverrides:r}=a,o=Array.from(document.querySelectorAll(t));return(n||s||e)&&o.forEach(l=>{n&&l.addEventListener("coverflow-carousel:ready",c=>{n(l,c.detail)}),s&&l.addEventListener("coverflow-carousel:change",c=>{s(l,c.detail)}),e&&l.addEventListener("coverflow-carousel:scratch-complete",c=>{e(l,c.detail)})}),i&&o.forEach(l=>{const c=l;typeof i=="string"?c.adoptStyles(i):c.adoptStylesheet(i)}),r&&o.forEach(l=>{l.adoptStyleOverrides(r)}),o}function N(a="coverflow-carousel"){typeof window>"u"||!("customElements"in window)||customElements.get(a)||customElements.define(a,f)}h.CoverflowCarouselElement=f,h.coverflowCarouselCssText=I,h.initCoverflowCarousels=M,h.registerCoverflowCarouselElement=N,Object.defineProperty(h,Symbol.toStringTag,{value:"Module"})}));
154
+ `,I=h;function E(a){return"adoptedStyleSheets"in a}function b(a){try{const t=new CSSStyleSheet;return t.replaceSync(a),t}catch{return null}}const C=b(h),k=h;function y(a){return a.split(",").map(t=>t.trim()).filter(Boolean)}function g(a,t){const s=a.trim();if(!s)return t;if(s.endsWith("ms")){const e=Number(s.slice(0,-2).trim());return Number.isFinite(e)?e:t}if(s.endsWith("s")){const e=Number(s.slice(0,-1).trim());return Number.isFinite(e)?e*1e3:t}const n=Number(s);return Number.isFinite(n)?n:t}function _(a,t){const s=y(a.transitionProperty),n=y(a.transitionDuration),e=y(a.transitionDelay);if(!s.length)return 0;const r=(x=>{const u=s.indexOf(x);if(u>=0)return u;const A=s.indexOf("all");return A>=0?A:-1})(t);if(r<0)return 0;const o=n[Math.min(r,n.length-1)]??"0s",l=e[Math.min(r,e.length-1)]??"0s",c=g(o,0),p=g(l,0);return Math.max(0,c+p)}function T(){return window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches??!1}function S(a,t,s){if(!a.hasAttribute(t))return s;const n=a.getAttribute(t);return n==null||n===""?!0:n!=="false"}function L(a,t,s){const n=a.getAttribute(t);if(n==null)return s;const e=Number(n.trim());return Number.isFinite(e)?Math.trunc(e):s}function w(a,t){const s=a.getAttribute(t);if(s==null)return null;const n=s.trim();return n||null}function m(a,t){return t<=0?0:(a%t+t)%t}function D(a,t,s){const n=t-a,e=s/2;return n>e?n-s:n<-e?n+s:n}const v=1;let F=0;class f extends HTMLElement{static defaultStylesheet=C;static observedAttributes=["start-index","index","show-dots","show-arrows"];shadow=this.attachShadow({mode:"open"});instanceId=`cfc-${++F}`;rootEl;trackEl;dotsEl;prevBtn;nextBtn;baseStyles=null;overrideStyles=null;baseStyleEl=null;overrideStyleEl=null;cards=[];dots=[];currentIndex=0;isAnimating=!1;hasAppliedInitialLayout=!1;lastLayoutIndex=null;lastVisibleSet=new Set;pendingAnimToken=0;animFallbackTimerId=null;cleanup=[];lightDomObserverOptions={childList:!0,attributes:!0,subtree:!0};lightDomObserver=null;refreshScheduled=!1;suppressMutations=!1;reflectGuard=!1;connectedCallback(){this.render(),this.readAttributes({isInit:!0}),this.refresh(),this.setupLightDomObserver()}disconnectedCallback(){this.destroy()}attributeChangedCallback(t,s,n){if(!this.isConnected||this.reflectGuard)return;this.readAttributes({isInit:!1});const e=w(this,"index");if(e!=null){const i=m(Number(e),this.cards.length);if(Number.isFinite(i)&&i!==this.currentIndex){this.goTo(i);return}}this.applyLayoutAndA11y({emitChange:!1})}next(){this.goTo(this.currentIndex+1)}prev(){this.goTo(this.currentIndex-1)}goTo(t){if(this.isAnimating)return;const s=m(t,this.cards.length);s!==this.currentIndex&&(this.isAnimating=!0,this.currentIndex=s,this.reflectIndexAttr(),this.applyLayoutAndA11y({emitChange:!0}),this.lockUntilTransitionEnd())}refresh(){const t=this.lightDomObserver;t&&(this.suppressMutations=!0,t.disconnect(),t.takeRecords()),this.rebuildCardsFromLightDom();const s=L(this,"start-index",0),n=w(this,"index"),e=n!=null?Number(n):s,i=Number.isFinite(e)?e:0;this.currentIndex=m(i,this.cards.length),this.reflectIndexAttr(),this.buildDots(),this.hasAppliedInitialLayout=!1,this.lastLayoutIndex=null,this.lastVisibleSet=new Set,this.applyLayoutAndA11y({emitChange:!1}),this.dispatchReady(),t&&(t.observe(this,this.lightDomObserverOptions),t.takeRecords(),this.suppressMutations=!1)}destroy(){this.animFallbackTimerId!==null&&(window.clearTimeout(this.animFallbackTimerId),this.animFallbackTimerId=null),this.cleanup.forEach(t=>{t()}),this.cleanup=[],this.isAnimating=!1}adoptStylesheet(t){this.setBaseStyles(t)}adoptStyles(t){this.setBaseStyles(t)}adoptStyleOverrides(t){this.setOverrideStyles(t)}readAttributes(t){this.rootEl||this.render();const s=S(this,"show-arrows",!1),n=S(this,"show-dots",!1);this.prevBtn.style.display=s?"":"none",this.nextBtn.style.display=s?"":"none",this.dotsEl.style.display=n?"":"none";const e=this.getAttribute("aria-label");e&&this.rootEl.setAttribute("aria-label",e),t.isInit&&this.setAttribute("aria-roledescription","carousel")}render(){this.applyAllStyles(),this.rootEl=document.createElement("div"),this.rootEl.className="cfc",this.trackEl=document.createElement("div"),this.trackEl.className="cfc__track",this.prevBtn=document.createElement("button"),this.prevBtn.type="button",this.prevBtn.className="cfc__arrow cfc__arrow--left",this.prevBtn.setAttribute("aria-label","Previous"),this.prevBtn.textContent="‹",this.nextBtn=document.createElement("button"),this.nextBtn.type="button",this.nextBtn.className="cfc__arrow cfc__arrow--right",this.nextBtn.setAttribute("aria-label","Next"),this.nextBtn.textContent="›",this.dotsEl=document.createElement("div"),this.dotsEl.className="cfc__dots",this.rootEl.append(this.trackEl,this.prevBtn,this.nextBtn,this.dotsEl),this.shadow.innerHTML="",this.baseStyleEl&&this.shadow.append(this.baseStyleEl),this.overrideStyleEl&&this.shadow.append(this.overrideStyleEl),this.shadow.append(this.rootEl),this.bindEvents()}bindEvents(){this.cleanup.forEach(i=>{i()}),this.cleanup=[];const t=()=>this.prev(),s=()=>this.next();this.prevBtn.addEventListener("click",t),this.nextBtn.addEventListener("click",s),this.cleanup.push(()=>this.prevBtn.removeEventListener("click",t)),this.cleanup.push(()=>this.nextBtn.removeEventListener("click",s));const n=i=>{if(!this.isAnimating||i.propertyName!=="transform"||!(i.target instanceof HTMLElement))return;const r=this.cards[this.currentIndex];r&&i.target===r&&this.unlockAnimation()};this.rootEl.addEventListener("transitionend",n),this.cleanup.push(()=>this.rootEl.removeEventListener("transitionend",n));const e=i=>{const r=i.target;if(!(r instanceof HTMLElement)||r.tagName!=="SCRATCH-REVEAL")return;const o=i.composedPath?.();if(!o?.length)return;const l=o.find(u=>u instanceof HTMLElement&&u.classList.contains("cfc__card")&&u.dataset.cfcIndex!=null);if(!l)return;const c=Number(l.dataset.cfcIndex);if(!Number.isFinite(c))return;const x=i.detail?.percent??100;this.dispatchEvent(new CustomEvent("coverflow-carousel:scratch-complete",{detail:{index:c,length:this.cards.length,percent:x},bubbles:!0,composed:!0}))};this.rootEl.addEventListener("complete",e),this.cleanup.push(()=>this.rootEl.removeEventListener("complete",e))}setupLightDomObserver(){this.lightDomObserver||(this.lightDomObserver=new MutationObserver(t=>{this.suppressMutations||!t.some(n=>!(n.type==="attributes"&&n.attributeName==="slot"))||this.scheduleRefreshFromMutations()}),this.lightDomObserver.observe(this,{...this.lightDomObserverOptions}),this.cleanup.push(()=>{this.lightDomObserver?.disconnect(),this.lightDomObserver=null}))}scheduleRefreshFromMutations(){this.refreshScheduled||(this.refreshScheduled=!0,queueMicrotask(()=>{this.refreshScheduled=!1,this.isConnected&&this.refresh()}))}rebuildCardsFromLightDom(){const t=Array.from(this.trackEl.children).filter(e=>e instanceof HTMLElement&&e.classList.contains("cfc__card")),s=[],n=Array.from(this.children).filter(e=>e instanceof HTMLElement);for(let e=0;e<n.length;e++){const i=n[e],r=t[e]??document.createElement("div"),o=`${this.instanceId}-slot-${e}`;t[e]||(r.className="cfc__card",this.trackEl.append(r)),i.getAttribute("slot")!==o&&i.setAttribute("slot",o);const l=r.querySelector("slot");let c;l instanceof HTMLSlotElement?c=l:(c=document.createElement("slot"),r.replaceChildren(c)),c.name!==o&&(c.name=o),s.push(r)}for(let e=n.length;e<t.length;e++)t[e]?.remove();this.cards=s,this.hasAppliedInitialLayout=!1,this.lastLayoutIndex=null,this.lastVisibleSet=new Set}getVisibleSet(){const t=this.cards.length,s=new Set;if(t<=0)return s;const n=Math.floor(t/2);if(v>=n){for(let e=0;e<t;e++)s.add(e);return s}for(let e=-v;e<=v;e++)s.add(m(this.currentIndex+e,t));return s}buildDots(){const t=Array.from(this.dotsEl.children).filter(i=>i instanceof HTMLElement&&i.classList.contains("cfc__dot"));if(!S(this,"show-dots",!1)){t.forEach(i=>{i.remove()}),this.dots=[];return}const n=[],e=this.cards.length;for(let i=0;i<e;i++){const r=t[i]??document.createElement("span");t[i]||this.dotsEl.append(r),r.className="cfc__dot",r.setAttribute("aria-hidden","true"),n.push(r)}for(let i=e;i<t.length;i++)t[i]?.remove();this.dots=n,this.updateDotsVisualState()}computeCardState(t){const s=this.cards.length,n=D(this.currentIndex,t,s),e=Math.abs(n);return{index:t,delta:n,abs:e,isVisible:e<=v,isActive:t===this.currentIndex}}applyCardState(t,s){t.setAttribute("aria-hidden",s.isVisible?"false":"true"),t.dataset.active=s.isActive?"true":"false",t.dataset.cfcIndex=String(s.index),t.setAttribute("role","group"),t.setAttribute("aria-roledescription","slide"),t.setAttribute("aria-setsize",String(this.cards.length)),t.setAttribute("aria-posinset",String(s.index+1));const n=`${this.instanceId}-slide-${s.index}`;t.id=n;const e=String(s.delta),i=String(s.abs),r=t.dataset.cfcDelta,o=t.dataset.cfcAbs;r!==e&&(t.style.setProperty("--cfc-delta",e),t.dataset.cfcDelta=e),o!==i&&(t.style.setProperty("--cfc-abs",i),t.dataset.cfcAbs=i)}applyLayoutAndA11y(t){if(this.cards.length){if(this.hasAppliedInitialLayout){const s=this.getVisibleSet(),n=new Set;this.lastVisibleSet.forEach(e=>{n.add(e)}),s.forEach(e=>{n.add(e)}),this.lastLayoutIndex!=null&&n.add(this.lastLayoutIndex),n.add(this.currentIndex),n.forEach(e=>{const i=this.cards[e];if(!i)return;const r=this.computeCardState(e);this.applyCardState(i,r)}),this.lastLayoutIndex=this.currentIndex,this.lastVisibleSet=s}else{for(let s=0;s<this.cards.length;s++){const n=this.cards[s];if(!n)continue;const e=this.computeCardState(s);this.applyCardState(n,e)}this.hasAppliedInitialLayout=!0,this.lastLayoutIndex=this.currentIndex,this.lastVisibleSet=this.getVisibleSet()}this.updateDotsVisualState(),t.emitChange&&this.emitChange()}}updateDotsVisualState(){if(this.dots.length)for(let t=0;t<this.dots.length;t++){const s=this.dots[t],n=t===this.currentIndex;s.dataset.active=n?"true":"false"}}lockUntilTransitionEnd(){this.pendingAnimToken++;const t=this.pendingAnimToken;if(T()){this.unlockAnimation();return}const s=this.cards[this.currentIndex];if(!s){this.unlockAnimation();return}const n=getComputedStyle(s),e=_(n,"transform");if(e<=0){this.unlockAnimation();return}const i=g(n.getPropertyValue("--cfc-transition-ms").trim(),400),o=Math.max(e,i)+60;this.animFallbackTimerId!==null&&window.clearTimeout(this.animFallbackTimerId),this.animFallbackTimerId=window.setTimeout(()=>{this.pendingAnimToken===t&&this.unlockAnimation()},o)}unlockAnimation(){this.isAnimating=!1,this.animFallbackTimerId!==null&&(window.clearTimeout(this.animFallbackTimerId),this.animFallbackTimerId=null)}emitChange(){this.dispatchEvent(new CustomEvent("coverflow-carousel:change",{detail:{index:this.currentIndex,length:this.cards.length}}))}dispatchReady(){this.dispatchEvent(new CustomEvent("coverflow-carousel:ready",{detail:{index:this.currentIndex,length:this.cards.length}}))}reflectIndexAttr(){this.reflectGuard=!0;try{this.setAttribute("index",String(this.currentIndex))}finally{this.reflectGuard=!1}}setBaseStyles(t){this.baseStyles=t??null,this.applyAllStyles()}setOverrideStyles(t){this.overrideStyles=t??null,this.applyAllStyles()}applyAllStyles(){const t=this.baseStyles,s=this.overrideStyles;if(E(this.shadow)){const e=[];if(typeof t=="string"){const i=b(t);if(!i){this.applyAllStylesFallback();return}e.push(i)}else if(t)e.push(t);else if(f.defaultStylesheet)e.push(f.defaultStylesheet);else{this.applyAllStylesFallback();return}if(typeof s=="string"){const i=b(s);if(!i){this.applyAllStylesFallback();return}e.push(i)}else s&&e.push(s);this.shadow.adoptedStyleSheets=e,this.baseStyleEl?.remove(),this.overrideStyleEl?.remove(),this.baseStyleEl=null,this.overrideStyleEl=null;return}this.applyAllStylesFallback()}applyAllStylesFallback(){const t=this.baseStyles,s=this.overrideStyles;E(this.shadow)&&(this.shadow.adoptedStyleSheets=[]);const n=typeof t=="string"?t:k,e=typeof s=="string"?s:"";this.baseStyleEl||(this.baseStyleEl=document.createElement("style")),this.baseStyleEl.textContent=n,e?(this.overrideStyleEl||(this.overrideStyleEl=document.createElement("style")),this.overrideStyleEl.textContent=e):(this.overrideStyleEl?.remove(),this.overrideStyleEl=null)}}function M(a={}){const{selector:t="coverflow-carousel",onReady:s,onChange:n,onScratchComplete:e,stylesheet:i,styleOverrides:r}=a,o=Array.from(document.querySelectorAll(t));return(s||n||e)&&o.forEach(l=>{s&&l.addEventListener("coverflow-carousel:ready",c=>{s(l,c.detail)}),n&&l.addEventListener("coverflow-carousel:change",c=>{n(l,c.detail)}),e&&l.addEventListener("coverflow-carousel:scratch-complete",c=>{e(l,c.detail)})}),i&&o.forEach(l=>{const c=l;typeof i=="string"?c.adoptStyles(i):c.adoptStylesheet(i)}),r&&o.forEach(l=>{l.adoptStyleOverrides(r)}),o}function N(a="coverflow-carousel"){typeof window>"u"||!("customElements"in window)||customElements.get(a)||customElements.define(a,f)}d.CoverflowCarouselElement=f,d.coverflowCarouselCssText=I,d.initCoverflowCarousels=M,d.registerCoverflowCarouselElement=N,Object.defineProperty(d,Symbol.toStringTag,{value:"Module"})}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coverflow-carousel",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Tiny coverflow carousel Web Component. Exposes API via attributes + events (explicit element registration).",
5
5
  "author": "ux-ui.pro",
6
6
  "license": "MIT",