iteration-deck
Version:
AI-first prototyping web components for comparing interactive UI variations. Perfect for designers working with AI coding agents to create multiple design iterations in prototypes.
451 lines (396 loc) • 32.2 kB
JavaScript
;Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("lit"),t=require("lit/decorators.js"),i=()=>{if("undefined"!=typeof process&&"production"===process.env?.NODE_ENV)return"production";if("undefined"!=typeof window){const e=window.location.hostname;if("localhost"===e||"127.0.0.1"===e||e.startsWith("localhost:")||e.startsWith("127.0.0.1:")||/^localhost:\d+$/.test(window.location.host)||/^127\.0\.0\.1:\d+$/.test(window.location.host))return"development"}return"development"},r=()=>"development"===i(),s=(e,t)=>`${e}-${(t||"slide").toLowerCase().replace(/[^a-z0-9]/g,"-")}`,o=e=>/^[a-z0-9-_]+$/i.test(e),n=(e,t)=>{!("undefined"!=typeof process&&"test"===process.env?.NODE_ENV||"undefined"!=typeof globalThis&&"vi"in globalThis||"undefined"!=typeof globalThis&&"expect"in globalThis&&"test"in globalThis||"undefined"!=typeof window&&window.location?.href?.includes("test"))||!e.includes("not inside an iteration-deck element")&&e.includes("Cannot activate slide: no parent deck found")},d=(e,t)=>{},l=(e,t)=>{let i=null,r=0;return(...s)=>{const o=Date.now();o-r>t?(e(...s),r=o):(i&&clearTimeout(i),i=setTimeout(()=>{e(...s),r=Date.now()},t-(o-r)))}},a=e=>{const{code:t,metaKey:i,ctrlKey:r,altKey:s}=e;if(!((i||r)&&s))return null;switch(t){case"BracketLeft":return"prev";case"BracketRight":return"next";case"Home":return"first";case"End":return"last";default:return null}};const c=new class{constructor(){this.activeDecks={},this.deckMetadata={},this._environmentDetected=!1,this._cachedIsProduction=!0,this.listeners=new Set}_ensureEnvironmentDetected(){this._environmentDetected||"undefined"==typeof window||(this._cachedIsProduction=!r(),this._environmentDetected=!0)}get isProduction(){return void 0!==this._testProductionModeOverride?this._testProductionModeOverride:(this._ensureEnvironmentDetected(),this._cachedIsProduction)}updateEnvironmentDetection(){this._environmentDetected=!1,this._ensureEnvironmentDetected()}_setProductionModeForTesting(e){this._testProductionModeOverride=e,this.notifyListeners()}registerDeck(e,t,i,r=!0,s){const o=s||t.map(e=>({id:e,label:e}));this.deckMetadata[e]={slideIds:[...t],slides:o,activeSlideId:t[0]||"",label:i,isInteractive:r};const n=this.activeDecks[e],d=t.includes(n)?n:t[0];this.activeDecks[e]=d,this.deckMetadata[e].activeSlideId=d,this.notifyListeners()}setActiveSlide(e,t){this.activeDecks[e]=t,this.deckMetadata[e]&&(this.deckMetadata[e].activeSlideId=t),this.notifyListeners()}removeDeck(e){if(delete this.activeDecks[e],delete this.deckMetadata[e],this.selectedDeckId===e){const e=this.getRegisteredDecks();this.selectedDeckId=e.length>0?e[0]:void 0}this.notifyListeners()}getActiveSlide(e){return this.activeDecks[e]}getDeckSlides(e){return this.deckMetadata[e]?.slideIds||[]}getDeckMetadata(e){return this.deckMetadata[e]}getRegisteredDecks(){return Object.keys(this.activeDecks)}getInteractiveDecks(){return Object.keys(this.deckMetadata).filter(e=>!0===this.deckMetadata[e]?.isInteractive)}setSelectedDeck(e){this.selectedDeckId=e,this.notifyListeners()}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}notifyListeners(){this.listeners.forEach(e=>e(this))}},h=e=>c.subscribe(e),u=()=>c,p=()=>!c.isProduction,b={container:["block min-h-1"].join(" ")};var g=Object.defineProperty,v=Object.getOwnPropertyDescriptor,m=(e,t,i,r)=>{for(var s,o=r>1?void 0:r?v(t,i):t,n=e.length-1;n>=0;n--)(s=e[n])&&(o=(r?s(t,i,o):s(o))||o);return r&&o&&g(t,i,o),o};let f=null;function k(){if(!function(){if(p())return!0;const e=document.querySelectorAll("iteration-deck");for(const t of e)if(t.hasAttribute("enable-in-production"))return!0;return!1}())return;if(document.querySelector("iteration-deck-toolbar"))return;const e=new exports.IterationDeckToolbar;document.body.appendChild(e)}function S(){setTimeout(()=>{if(0===u().getInteractiveDecks().length){const e=document.querySelector("iteration-deck-toolbar");e&&e.remove()}},100)}exports.IterationDeckToolbar=class extends e.LitElement{constructor(){super(),this.throttledKeyboardHandler=l(this.handleKeyboardNavigation.bind(this),100),this.storeState=u(),f&&f!==this&&f.parentNode&&f.parentNode.removeChild(f),f=this}connectedCallback(){super.connectedCallback(),this.shouldShowToolbar()&&(this.unsubscribeFromStore=h(e=>{this.storeState=e,this.requestUpdate();const t=e.getInteractiveDecks();if(t.length>0&&!e.selectedDeckId){u().setSelectedDeck(t[0])}}),document.addEventListener("keydown",this.throttledKeyboardHandler),this.setAttribute("visible",""))}disconnectedCallback(){super.disconnectedCallback(),this.unsubscribeFromStore?.(),document.removeEventListener("keydown",this.throttledKeyboardHandler),f===this&&(f=null)}shouldShowToolbar(){if(p())return!0;const e=document.querySelectorAll("iteration-deck");for(const t of e)if(t.hasAttribute("enable-in-production"))return!0;return!1}handleKeyboardNavigation(e){const t=e.target;if(t&&("INPUT"===t.tagName||"TEXTAREA"===t.tagName||"SELECT"===t.tagName||t.isContentEditable))return;const i=a(e);i&&(e.preventDefault(),e.stopPropagation(),this.navigateSelectedDeck(i))}navigateSelectedDeck(e){const t=this.getSelectedDeckId();if(!t)return;const i=this.getCurrentDeck(t);if(!i)return;const r=i.slideIds.indexOf(i.activeSlideId);let s;switch(e){case"prev":s=r>0?r-1:i.slideIds.length-1;break;case"next":s=r<i.slideIds.length-1?r+1:0;break;case"first":s=0;break;case"last":s=i.slideIds.length-1;break;default:return}const o=i.slideIds[s];if(o){u().setActiveSlide(t,o)}}getSelectedDeckId(){const e=this.storeState.getInteractiveDecks();return 1===e.length?e[0]:this.storeState.selectedDeckId}getCurrentDeck(e){if(!e)return null;const t=u().getDeckMetadata(e);return t?{id:e,label:t.label||e,slideIds:t.slideIds,activeSlideId:t.activeSlideId,registeredAt:Date.now()}:null}handleDeckSelection(e){const t=e.target.value;if(t){u().setSelectedDeck(t),this.scrollToDeckAndHighlight(t)}}scrollToDeckAndHighlight(e){const t=document.querySelector(`iteration-deck[id="${e}"]`);if(!t)return;const i=t.querySelector('iteration-deck-slide[aria-hidden="false"]'),r=i?.getPrimarySlottedElement(),s=r||i||t,o=t.getBoundingClientRect(),n=window.scrollY,d=o.top+n-.15*window.innerHeight,l=Math.max(0,d);window.scrollTo({top:l,behavior:"smooth"}),this.waitForScrollComplete(l,()=>{this.addGlowEffect(s)})}waitForScrollComplete(e,t){let i,r;const s=()=>{clearTimeout(i),i=window.setTimeout(()=>{const i=window.scrollY;Math.abs(i-e)<=5&&(window.removeEventListener("scroll",s),clearTimeout(r),t())},150)};r=window.setTimeout(()=>{window.removeEventListener("scroll",s),clearTimeout(i),t()},3e3),window.addEventListener("scroll",s);const o=window.scrollY;Math.abs(o-e)<=5&&(window.removeEventListener("scroll",s),clearTimeout(r),setTimeout(t,100))}static ensureGlowStyles(){const e="iteration-deck-glow-styles";if(document.getElementById(e))return;const t=document.createElement("style");t.id=e,t.textContent="\n /* Iteration Deck Glow Effect Global Styles */\n [data-iteration-glow] {\n border-radius: 8px;\n position: relative;\n animation: iteration-deck-glow 1s ease-in-out;\n }\n \n @keyframes iteration-deck-glow {\n 0% {\n box-shadow: 0 0 0 3px rgba(236, 72, 153, 0.2), 0 0 25px rgba(236, 72, 153, 0.1);\n outline: 2px solid rgba(236, 72, 153, 0.2);\n }\n 50% {\n box-shadow: 0 0 0 3px rgba(236, 72, 153, 0.4), 0 0 25px rgba(236, 72, 153, 0.3);\n outline: 2px solid rgba(236, 72, 153, 0.6);\n }\n 100% {\n box-shadow: 0 0 0 3px rgba(236, 72, 153, 0.2), 0 0 25px rgba(236, 72, 153, 0.1);\n outline: 2px solid rgba(236, 72, 153, 0);\n }\n }\n \n /* Accessibility: respect reduced motion preference */\n @media (prefers-reduced-motion: reduce) {\n [data-iteration-glow] {\n animation: none;\n border: 2px solid rgba(236, 72, 153, 0.6);\n box-shadow: 0 0 0 3px rgba(236, 72, 153, 0.3), 0 0 25px rgba(236, 72, 153, 0.2);\n }\n }\n ",document.head.appendChild(t)}addGlowEffect(e){exports.IterationDeckToolbar.ensureGlowStyles(),e.setAttribute("data-iteration-glow",""),setTimeout(()=>{e.removeAttribute("data-iteration-glow")},800)}handlePrevSlide(){try{this.navigateSelectedDeck("prev")}catch(e){n("Error navigating to previous slide:")}}handleNextSlide(){try{this.navigateSelectedDeck("next")}catch(e){n("Error navigating to next slide:")}}getDeckLabel(e){const t=u().getDeckMetadata(e);return t?.label||e}getCurrentSlideLabel(){const e=this.getSelectedDeckId();if(!e)return"No deck selected";const t=u().getDeckMetadata(e);if(!t||!t.activeSlideId)return"No slide active";const i=t.slides?.find(e=>e.id===t.activeSlideId)?.label;return i||"No slide selected"}canNavigatePrev(){const e=this.getSelectedDeckId();if(!e)return!1;const t=this.getCurrentDeck(e);return!!t&&!(t.slideIds.length<=1)}renderSlideIndicators(){const t=this.getSelectedDeckId();if(!t)return"";const i=this.getCurrentDeck(t);if(!i||i.slideIds.length<=1)return"";const r=i.slideIds.indexOf(i.activeSlideId);return e.html`
<div class="indicators-container" aria-hidden="true">
${i.slideIds.map((t,i)=>e.html`
<div
class="indicator-dot ${i===r?"dot-active":"dot-inactive"}"
></div>
`)}
</div>
`}canNavigateNext(){const e=this.getSelectedDeckId();if(!e)return!1;const t=this.getCurrentDeck(e);return!!t&&!(t.slideIds.length<=1)}render(){if(!this.shouldShowToolbar())return e.nothing;const t=this.storeState.getInteractiveDecks(),i=this.getSelectedDeckId(),r=t.length>1;return t.length>0?e.html`
<div class="toolbar-root" role="toolbar" aria-label="Iteration Deck Toolbar">
${r?e.html`
<div class="selector-container">
<select
class="selector-select"
@change=${this.handleDeckSelection}
.value=${i||""}
aria-label="Select iteration deck"
>
${t.map(t=>e.html`
<option
value=${t}
?selected=${t===i}
>
${this.getDeckLabel(t)}
</option>
`)}
</select>
<div class="selector-button">
<span class="selector-text">${this.getDeckLabel(i||"")}</span>
<span class="selector-arrow">▼</span>
</div>
</div>
<div class="toolbar-separator"></div>
`:""}
<div class="slide-nav-container">
<nav class="nav-container">
<button
class="nav-button prev-button"
@click=${this.handlePrevSlide}
?disabled=${!this.canNavigatePrev()}
aria-label="Previous slide (Ctrl/Cmd+Alt+[)"
title="Previous slide (Ctrl/Cmd+Alt+[)"
>
<svg width="18" height="12" viewBox="0 0 18 12" fill="currentColor" aria-hidden="true">
<path d="M7 6l6-4v8l-6-4z" />
</svg>
</button>
<button
class="nav-button next-button"
@click=${this.handleNextSlide}
?disabled=${!this.canNavigateNext()}
aria-label="Next slide (Ctrl/Cmd+Alt+])"
title="Next slide (Ctrl/Cmd+Alt+])"
>
<svg width="18" height="12" viewBox="0 0 18 12" fill="currentColor" aria-hidden="true">
<path d="M11 6l-6 4V2l6 4z" />
</svg>
</button>
</nav>
<div class="slide-info-container">
<span class="slide-info-label"
title=${this.getCurrentSlideLabel()}>
${this.getCurrentSlideLabel()}
</span>
${this.renderSlideIndicators()}
</div>
</div>
</div>
`:e.nothing}},exports.IterationDeckToolbar.styles=e.css`
:host {
position: fixed;
bottom: 1rem;
left: 50%;
transform: translateX(-50%);
z-index: 9999;
}
.toolbar-root {
display: flex;
flex-direction: row;
align-items: center;
min-width: 24rem;
gap: 0.5rem;
padding: 0.75rem;
border-radius: 2.5rem;
backdrop-filter: blur(12px);
box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
font-weight: 500;
font-size: 0.875rem;
line-height: 1;
color: rgb(55 65 81);
background-color: rgb(229 231 235 / 0.8);
}
@media (prefers-color-scheme: dark) {
.toolbar-root {
background-color: rgb(17 24 39 / 0.7);
color: rgb(229 231 235);
}
}
.toolbar-separator {
width: 1px;
height: 1.5rem;
background-color: rgb(156 163 175 / 0.6);
}
@media (prefers-color-scheme: dark) {
.toolbar-separator {
background-color: rgb(107 114 128 / 0.7);
}
}
/* Deck Selector */
.selector-container {
position: relative;
display: flex;
align-items: center;
}
.selector-select {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
cursor: pointer;
z-index: 2;
}
.selector-button {
display: flex;
align-items: center;
justify-content: space-between;
height: 1.75rem;
min-width: 7.5rem;
gap: 0.75rem;
padding: 0 0.75rem;
background-color: white;
border: 2px solid rgb(209 213 219);
border-radius: 1.5rem;
font-size: 0.875rem;
font-weight: 400;
line-height: 0.75rem;
color: rgb(55 65 81);
cursor: pointer;
user-select: none;
transition: all 150ms ease-out;
}
.selector-button:hover {
background-color: rgb(249 250 251);
color: rgb(31 41 55);
}
.selector-button:focus {
outline: none;
box-shadow: 0 0 0 2px rgb(59 130 246);
}
@media (prefers-color-scheme: dark) {
.selector-button {
background-color: rgb(31 41 55);
border-color: rgb(75 85 99);
color: rgb(229 231 235);
}
.selector-button:hover {
background-color: rgb(75 85 99);
color: rgb(243 244 246);
}
.selector-button:focus {
box-shadow: 0 0 0 2px rgb(96 165 250);
}
}
.selector-text {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.selector-arrow {
font-size: 0.5rem;
color: rgb(107 114 128);
pointer-events: none;
}
@media (prefers-color-scheme: dark) {
.selector-arrow {
color: rgb(156 163 175);
}
}
/* Slide Navigation */
.slide-nav-container {
display: flex;
align-items: center;
height: 1.75rem;
}
.nav-container {
display: flex;
align-items: center;
height: 1.75rem;
border-radius: 1.5rem;
border: 2px solid rgb(209 213 219);
overflow: hidden;
background-color: rgb(229 231 235);
}
@media (prefers-color-scheme: dark) {
.nav-container {
background-color: rgb(75 85 99);
border-color: rgb(75 85 99);
}
}
.nav-button {
display: flex;
align-items: center;
justify-content: center;
width: 2rem;
height: 100%;
background-color: white;
transition: all 150ms ease-out;
color: rgb(75 85 99);
font-size: 0.875rem;
cursor: pointer;
user-select: none;
border: none;
outline: none;
}
.nav-button:hover:not(:disabled) {
background-color: rgb(249 250 251);
color: rgb(31 41 55);
}
.nav-button:active:not(:disabled) {
background-color: rgb(243 244 246);
transform: scale(0.95);
}
.nav-button:focus:not(:disabled) {
box-shadow: inset 0 0 0 2px rgb(59 130 246);
}
.nav-button:disabled {
opacity: 0.4;
cursor: not-allowed;
}
.nav-button:disabled:hover {
background-color: white;
color: rgb(75 85 99);
transform: none;
}
@media (prefers-color-scheme: dark) {
.nav-button {
background-color: rgb(31 41 55);
color: rgb(209 213 219);
}
.nav-button:hover:not(:disabled) {
background-color: rgb(75 85 99);
color: rgb(243 244 246);
}
.nav-button:active:not(:disabled) {
background-color: rgb(107 114 128);
}
.nav-button:focus:not(:disabled) {
box-shadow: inset 0 0 0 2px rgb(96 165 250);
}
.nav-button:disabled:hover {
background-color: rgb(55 65 81);
color: rgb(209 213 219);
}
}
.prev-button {
border-top-left-radius: 1.5rem;
border-bottom-left-radius: 1.5rem;
border-right: 0;
}
.next-button {
border-top-right-radius: 1.5rem;
border-bottom-right-radius: 1.5rem;
border-left: 0;
}
/* Slide Info */
.slide-info-container {
flex: 1;
display: flex;
flex-direction: column;
gap: 0.125rem;
padding: 0 0.5rem;
width: 20rem;
}
.slide-info-label {
color: rgb(55 65 81);
font-size: 0.875rem;
font-weight: 500;
line-height: 1rem;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
@media (prefers-color-scheme: dark) {
.slide-info-label {
color: rgb(229 231 235);
}
}
/* Slide Indicators */
.indicators-container {
display: flex;
align-items: center;
justify-content: flex-start;
gap: 0.25rem;
width: 100%;
}
.indicator-dot {
width: 0.25rem;
height: 0.25rem;
border-radius: 50%;
background-color: rgb(156 163 175);
transition: opacity 200ms;
}
.dot-active {
opacity: 0.9;
}
.dot-inactive {
opacity: 0.5;
}
`,m([t.state()],exports.IterationDeckToolbar.prototype,"storeState",2),exports.IterationDeckToolbar=m([t.customElement("iteration-deck-toolbar")],exports.IterationDeckToolbar);var I=Object.defineProperty,x=Object.getOwnPropertyDescriptor,y=(e,t,i,r)=>{for(var s,o=r>1?void 0:r?x(t,i):t,n=e.length-1;n>=0;n--)(s=e[n])&&(o=(r?s(t,i,o):s(o))||o);return r&&o&&I(t,i,o),o};exports.IterationDeck=class extends e.LitElement{constructor(){super(...arguments),this.enableInProduction=!1,this._isProduction=!r(),this._activeSlideId="",this._slides=[],this._isRegistered=!1}connectedCallback(){super.connectedCallback(),this.id?o(this.id)?(this._setupSlotObserver(),this._shouldActivate()&&k(),this._detectSlidesAndRegister(),setTimeout(()=>{this._subscribeToStore(),this._detectSlidesAndRegister()},0)):n(`Invalid deck ID format: ${this.id}`):n("IterationDeck requires an id property")}disconnectedCallback(){if(super.disconnectedCallback(),this._unsubscribeStore?.(),this._slotObserver?.disconnect(),this._isRegistered){u().removeDeck(this.id),this.dispatchEvent(new CustomEvent("deck-unregistered",{detail:{deckId:this.id},bubbles:!0,composed:!0}))}S()}updated(e){super.updated(e),(e.has("id")||e.has("label"))&&setTimeout(()=>{this._detectSlidesAndRegister()},0)}_subscribeToStore(){this._unsubscribeStore=h(e=>{const t=e.activeDecks[this.id]||"",i=this._activeSlideId;if(t!==i&&(this.requestUpdate("_activeSlideId",i),this._activeSlideId=t,i&&t)){const e=this._slides.findIndex(e=>e.id===t);this.dispatchEvent(new CustomEvent("slide-change",{detail:{deckId:this.id,previousSlideId:i,currentSlideId:t,slideIndex:e},bubbles:!0,composed:!0}))}const r=e.isProduction;r!==this._isProduction&&(this.requestUpdate("_isProduction",this._isProduction),this._isProduction=r)})}_setupSlotObserver(){this._slotObserver=new MutationObserver(e=>{let t=!1;e.forEach(e=>{"childList"===e.type&&(t=!0)}),t&&this._detectSlidesAndRegister()}),this._slotObserver.observe(this,{childList:!0,subtree:!0})}_detectSlidesAndRegister(){const e=Array.from(this.querySelectorAll("iteration-deck-slide"));if(0===e.length)return void this.id;const t=e.map((e,t)=>{const i=e.getAttribute("label")||`Slide ${t+1}`,r=e.getAttribute("id")||e.getAttribute("slide-id")||s(this.id,i);return e.getAttribute("id")||e.getAttribute("slide-id")||e.setAttribute("slide-id",r),{id:r,label:i,element:e,aiPrompt:e.getAttribute("ai-prompt")||void 0,notes:e.getAttribute("notes")||void 0,confidence:e.getAttribute("confidence")?parseFloat(e.getAttribute("confidence")):void 0}});JSON.stringify(t.map(e=>e.id))!==JSON.stringify(this._slides.map(e=>e.id))&&(this.requestUpdate("_slides",this._slides),this._slides=t),this._registerWithStore()}_registerWithStore(){if(0===this._slides.length)return;const e=u(),t=this._slides.map(e=>e.id),i=this._shouldActivate(),r=this._slides.map(e=>({id:e.id,label:e.label}));e.registerDeck(this.id,t,this.label,i,r);const s=e.getActiveSlide(this.id)||t[0];s!==this._activeSlideId&&(this.requestUpdate("_activeSlideId",this._activeSlideId),this._activeSlideId=s),this._isRegistered||(this.requestUpdate("_isRegistered",this._isRegistered),this._isRegistered=!0),this.dispatchEvent(new CustomEvent("deck-registered",{detail:{deckId:this.id,label:this.label||this.id,slideCount:this._slides.length},bubbles:!0,composed:!0}))}_getActiveSlide(){return this._slides.find(e=>e.id===this._activeSlideId)}_shouldActivate(){return!this._isProduction||this.enableInProduction}render(){if(!this.id||0===this._slides.length)return e.html`<slot></slot>`;const t=[b.container,this._shouldActivate()?"development":"production","animated"].join(" ");return e.html`
<div class="${t} min-h-[1px]">
<div class="block min-h-inherit">
<slot></slot>
</div>
</div>
`}navigateToSlide(e){if(!this._slides.find(t=>t.id===e))return this.id,!1;return u().setActiveSlide(this.id,e),!0}navigateToNext(){if(0===this._slides.length&&this._detectSlidesAndRegister(),this._slides.length<=1)return!1;const e=(this._slides.findIndex(e=>e.id===this._activeSlideId)+1)%this._slides.length,t=this._slides[e].id;return this.navigateToSlide(t)}navigateToPrev(){if(0===this._slides.length&&this._detectSlidesAndRegister(),this._slides.length<=1)return!1;const e=this._slides.findIndex(e=>e.id===this._activeSlideId),t=e<=0?this._slides.length-1:e-1,i=this._slides[t].id;return this.navigateToSlide(i)}getCurrentSlide(){return this._getActiveSlide()||null}getAllSlides(){return[...this._slides]}getDeckInfo(){return{id:this.id,label:this.label||this.id,prompt:this.prompt,description:this.description,slideCount:this._slides.length,activeSlideId:this._activeSlideId,isProduction:this._isProduction,enableInProduction:this.enableInProduction,isRegistered:this._isRegistered}}},y([t.property({type:String,reflect:!0})],exports.IterationDeck.prototype,"id",2),y([t.property({type:String,reflect:!1})],exports.IterationDeck.prototype,"label",2),y([t.property({type:String,reflect:!1})],exports.IterationDeck.prototype,"prompt",2),y([t.property({type:String,reflect:!1})],exports.IterationDeck.prototype,"description",2),y([t.property({type:Boolean,attribute:"enable-in-production"})],exports.IterationDeck.prototype,"enableInProduction",2),y([t.state()],exports.IterationDeck.prototype,"_isProduction",2),y([t.state()],exports.IterationDeck.prototype,"_activeSlideId",2),y([t.state()],exports.IterationDeck.prototype,"_slides",2),y([t.state()],exports.IterationDeck.prototype,"_isRegistered",2),exports.IterationDeck=y([t.customElement("iteration-deck")],exports.IterationDeck);var w=Object.defineProperty,D=Object.getOwnPropertyDescriptor,_=(e,t,i,r)=>{for(var s,o=r>1?void 0:r?D(t,i):t,n=e.length-1;n>=0;n--)(s=e[n])&&(o=(r?s(t,i,o):s(o))||o);return r&&o&&w(t,i,o),o};exports.IterationDeckSlide=class extends e.LitElement{constructor(){super(...arguments),this.isActive=!1,this.deckId=null,this._internalSlideId="",this.isDevelopment=!1,this.parentEnableInProduction=!1,this.isInitializing=!0}willUpdate(e){super.willUpdate(e),void 0!==this.confidence&&(this.confidence<0||this.confidence>1)&&(n(`Invalid confidence score for slide "${this.label}": ${this.confidence}. Must be between 0 and 1.`),this.confidence=void 0)}connectedCallback(){super.connectedCallback();const e=u();this.isDevelopment=!e.isProduction,this.findParentDeck(),this._internalSlideId||(this._internalSlideId=this.slideId||this.getAttribute("slide-id")||s(this.deckId||"unknown",this.label||"slide")),this.deckId?(this.subscribeToStore(),this.updateActiveState(),this.isInitializing=!1):setTimeout(()=>{this.findParentDeck(),this.deckId&&(this._internalSlideId=this.slideId||this.getAttribute("slide-id")||s(this.deckId,this.label||"slide"),this.subscribeToStore(),this.updateActiveState(),this.isInitializing=!1,this.requestUpdate())},10),setTimeout(()=>{this.findParentDeck(),!this.unsubscribeStore&&this.deckId&&(this.subscribeToStore(),this.updateActiveState(),this.isInitializing=!1,this.requestUpdate())},10)}disconnectedCallback(){super.disconnectedCallback(),this.unsubscribeStore?.()}findParentDeck(){let e=this.parentElement;for(;e&&"ITERATION-DECK"!==e.tagName;)e=e.parentElement;e?(this.deckId=e.getAttribute("id"),this.parentEnableInProduction=e.hasAttribute("enable-in-production")):n(`IterationDeckSlide "${this.label}" is not inside an iteration-deck element`)}shouldActivate(){return this.isDevelopment||this.parentEnableInProduction}subscribeToStore(){this.unsubscribeStore=h(e=>{const t=!e.isProduction;t!==this.isDevelopment&&(this.isDevelopment=t,this.requestUpdate()),this.updateActiveState(e)})}updateActiveState(e){if(!this.deckId)return;const t=(e||u()).activeDecks[this.deckId],i=t===this._internalSlideId,r=!t&&this.parentElement&&this.parentElement.querySelector("iteration-deck-slide")===this,s=i||!!r;s!==this.isActive&&(this.isActive=s,this.setAttribute("aria-hidden",this.isActive?"false":"true"),this.setAttribute("role","tabpanel"),this.requestUpdate())}render(){const t=["slide-wrapper",this.isActive?"active":"hidden",this.isInitializing?"initializing":"","min-h-inherit"].filter(Boolean).join(" ");return e.html`
<div class="${t}">
<div class="slide-wrapper min-h-inherit">
<slot @slotchange=${this.handleSlotChange}></slot>
</div>
</div>
`}handleSlotChange(e){if(e.target.assignedElements().length>0&&this.deckId&&!this.isActive){const e=u();e.getActiveSlide(this.deckId)||e.setActiveSlide(this.deckId,this._internalSlideId)}}activate(){if(!this.deckId)return void n("Cannot activate slide: no parent deck found");u().setActiveSlide(this.deckId,this._internalSlideId)}isActiveSlide(){return this.isActive}getSlideData(){return{id:this._internalSlideId,label:this.label,aiPrompt:this.aiPrompt,notes:this.notes,confidence:this.confidence,isActive:this.isActive,deckId:this.deckId,isDevelopment:this.isDevelopment,parentEnableInProduction:this.parentEnableInProduction}}getSlottedElements(){return this._slottedElements}getPrimarySlottedElement(){return this._slottedElements?.[0]||null}dispatchSlideEvent(e,t){const i=new CustomEvent(`iteration-slide-${e}`,{detail:t,bubbles:!0,composed:!0});this.dispatchEvent(i)}handleSlideClick(){this.shouldActivate()&&!this.isActive&&(this.activate(),this.dispatchSlideEvent("activated",this.getSlideData()))}updated(e){super.updated(e),this.shouldActivate()?(this.style.cursor=this.isActive?"default":"pointer",this.onclick=()=>this.handleSlideClick()):(this.style.cursor="default",this.onclick=null)}},exports.IterationDeckSlide.styles=e.css`
:host {
display: block;
}
.slide-wrapper {
display: block;
}
.slide-wrapper.active {
display: block;
}
.slide-wrapper.hidden {
display: none;
}
.min-h-inherit {
min-height: inherit;
}
.initializing {
opacity: 0.5;
}
`,_([t.property({type:String,reflect:!0})],exports.IterationDeckSlide.prototype,"label",2),_([t.property({type:String,attribute:"ai-prompt",reflect:!1})],exports.IterationDeckSlide.prototype,"aiPrompt",2),_([t.property({type:String,reflect:!1})],exports.IterationDeckSlide.prototype,"notes",2),_([t.property({type:Number,reflect:!1})],exports.IterationDeckSlide.prototype,"confidence",2),_([t.property({type:String,reflect:!0,attribute:"slide-id"})],exports.IterationDeckSlide.prototype,"slideId",2),_([t.state()],exports.IterationDeckSlide.prototype,"isActive",2),_([t.state()],exports.IterationDeckSlide.prototype,"deckId",2),_([t.state()],exports.IterationDeckSlide.prototype,"_internalSlideId",2),_([t.state()],exports.IterationDeckSlide.prototype,"isDevelopment",2),_([t.state()],exports.IterationDeckSlide.prototype,"parentEnableInProduction",2),_([t.state()],exports.IterationDeckSlide.prototype,"isInitializing",2),_([t.queryAssignedElements()],exports.IterationDeckSlide.prototype,"_slottedElements",2),exports.IterationDeckSlide=_([t.customElement("iteration-deck-slide")],exports.IterationDeckSlide);var A=Object.defineProperty,E=Object.getOwnPropertyDescriptor,C=(e,t,i,r)=>{for(var s,o=r>1?void 0:r?E(t,i):t,n=e.length-1;n>=0;n--)(s=e[n])&&(o=(r?s(t,i,o):s(o))||o);return r&&o&&A(t,i,o),o};exports.IterationConfidenceBar=class extends e.LitElement{constructor(){super(...arguments),this.size="medium",this.showInProduction=!1}get shouldShow(){return!("production"===process.env.NODE_ENV)||this.showInProduction}get validatedConfidence(){if(void 0===this.confidence||null===this.confidence)return null;return Math.max(0,Math.min(1,this.confidence))}getConfidenceLevel(){const e=this.validatedConfidence;return null===e?null:e>=.8?"high":e>=.6?"medium":"low"}getAriaLabel(){const e=this.validatedConfidence;if(null===e)return"No confidence score";return`AI confidence: ${Math.round(100*e)}% (${this.getConfidenceLevel()} confidence)`}render(){const t=this.validatedConfidence;if(!this.shouldShow)return e.html``;if(null===t)return e.html``;const i=this.getConfidenceLevel(),r=Math.round(100*t);return e.html`
<div
class="indicator ${this.size}"
role="progressbar"
aria-valuenow="${r}"
aria-valuemin="0"
aria-valuemax="100"
aria-label="${this.getAriaLabel()}"
title="${this.getAriaLabel()}"
>
<div
class="bar"
style="width: ${r}%"
data-level="${i}"
></div>
</div>
`}},exports.IterationConfidenceBar.styles=e.css`
:host {
display: inline-block;
}
.indicator {
background: #f3f4f6;
border-radius: 9999px;
overflow: hidden;
border: 1px solid #e5e7eb;
}
.indicator.small {
height: 8px;
width: 60px;
}
.indicator.medium {
height: 12px;
width: 80px;
}
.indicator.large {
height: 16px;
width: 120px;
}
.bar {
height: 100%;
transition: width 0.3s ease;
border-radius: inherit;
}
.bar[data-level="low"] {
background: linear-gradient(90deg, #ef4444, #f59e0b);
}
.bar[data-level="medium"] {
background: linear-gradient(90deg, #f59e0b, #eab308);
}
.bar[data-level="high"] {
background: linear-gradient(90deg, #22c55e, #16a34a);
}
`,C([t.property({type:Number})],exports.IterationConfidenceBar.prototype,"confidence",2),C([t.property({type:String})],exports.IterationConfidenceBar.prototype,"size",2),C([t.property({type:Boolean,attribute:"show-in-production"})],exports.IterationConfidenceBar.prototype,"showInProduction",2),exports.IterationConfidenceBar=C([t.customElement("iteration-confidence-bar")],exports.IterationConfidenceBar),exports.cleanupToolbarIfEmpty=S,exports.debounce=(e,t)=>{let i=null;return(...r)=>{i&&clearTimeout(i),i=setTimeout(()=>{e(...r)},t)}},exports.detectEnvironment=i,exports.ensureToolbarMounted=k,exports.errorLog=n,exports.generateSlideId=s,exports.getIterationStoreState=u,exports.isDevelopment=r,exports.isDevelopmentMode=p,exports.isNavigationShortcut=a,exports.subscribeToIterationStore=h,exports.throttle=l,exports.validateDeckId=o,exports.warnLog=d;
//# sourceMappingURL=wc.cjs.map