flowlight
Version:
A lightweight command interface library with floating button, search functionality, and React integration
3 lines (2 loc) • 36.5 kB
JavaScript
class e{constructor(){this.events=new Map}on(e,t){return this.events.has(e)||this.events.set(e,new Set),this.events.get(e).add(t),()=>{this.off(e,t)}}off(e,t){this.events.has(e)&&(this.events.get(e).delete(t),0===this.events.get(e).size&&this.events.delete(e))}emit(e,t){this.events.has(e)&&this.events.get(e).forEach(s=>{try{s(t)}catch(t){console.error(`Error in event handler for ${e}:`,t)}})}once(e,t){const s=i=>{t(i),this.off(e,s)};return this.on(e,s)}clear(){this.events.clear()}getEvents(){return Array.from(this.events.keys())}getSubscriberCount(e){return this.events.has(e)?this.events.get(e).size:0}}const t={apiBaseUrl:"https://api.flowvana.tech",apiEndpoints:(()=>{const e="https://api.flowvana.tech";return{search:`${e}/flow/search`,flowDetails:`${e}/flow`}})(),isProduction:"undefined"!=typeof process&&process.env&&!0},s={debug:!1,buttonSize:60,buttonPosition:{bottom:20,right:20},zIndex:9999,searchDebounceDelay:500,autoDismissDelay:3500,inputIdleDelay:500,errorDisplayDuration:3e3,keyboardShortcuts:!0},i=["How do I use this feature?","What are the keyboard shortcuts?","Show me the documentation","How to customize the interface?","What are the available options?","Help me get started","Troubleshooting guide","API reference","Examples and demos","Contact support"],o="flowlight_flow_points",n="flowlight_flow_current_idx",l=t.apiEndpoints,r=3,a=2;class h{constructor(e={}){this.options=e,this.baseUrl=e.baseUrl||""}async get(e,t={}){return this.request(e,{method:"GET",...t})}async post(e,t={},s={}){return this.request(e,{method:"POST",headers:{"Content-Type":"application/json",...s.headers},body:JSON.stringify(t),...s})}async request(e,t={}){const s=this.baseUrl+e;try{const e=await fetch(s,t);if(!e.ok)throw new Error(`HTTP error! status: ${e.status}`);return await e.json()}catch(e){throw console.error("API request failed:",e),e}}async searchFlows(e,t={}){const s={query:e,project_id:"proj_bTs8cbhOyBLgcjzQ2qNQgQ",limit:t.limit||3,...t};return this.post(l.search,s)}async getFlowDetails(e){return this.get(`${l.flowDetails}/${e}`)}async isAvailable(){try{return await this.get(l.search),!0}catch(e){return!1}}}class d{static createElement(e,t="",s={},i=""){const o=document.createElement(e);return t&&(o.className=t),i&&(o.innerHTML=i),Object.keys(s).length>0&&Object.assign(o.style,s),o}static applyStyles(e,t){Object.assign(e.style,t)}static addEventListeners(e,t){Object.entries(t).forEach(([t,s])=>{e.addEventListener(t,s)})}static removeEventListeners(e,t){Object.entries(t).forEach(([t,s])=>{e.removeEventListener(t,s)})}static removeElement(e){e&&e.parentNode&&e.parentNode.removeChild(e)}static isInViewport(e){const t=e.getBoundingClientRect();return t.top>=0&&t.left>=0&&t.bottom<=(window.innerHeight||document.documentElement.clientHeight)&&t.right<=(window.innerWidth||document.documentElement.clientWidth)}static getComputedStyle(e,t){return window.getComputedStyle(e).getPropertyValue(t)}static addStyles(e,t=null){const s=document.createElement("style");return t&&(s.id=t),s.textContent=e,document.head.appendChild(s),s}static removeStyles(e){const t=document.getElementById(e);t&&t.remove()}}class c{constructor(e={},t){this.options=e,this.eventBus=t,this.element=null,this.isVisible=!0}create(){return this.element=d.createElement("div","flowlight-button",{position:"fixed",width:`${this.options.buttonSize}px`,height:`${this.options.buttonSize}px`,bottom:`${this.options.buttonPosition.bottom}px`,right:`${this.options.buttonPosition.right}px`,backgroundColor:"#000000",borderRadius:"50%",border:"none",cursor:"pointer",zIndex:this.options.zIndex,display:"flex",alignItems:"center",justifyContent:"center",color:"white",boxShadow:"0 4px 20px rgba(0, 0, 0, 0.3)",transition:"all 0.3s ease",userSelect:"none"},this.getButtonIcon()),this.bindEvents(),this.element}getButtonIcon(){return'\n <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path d="M21 21L16.514 16.506L21 21ZM19 10.5C19 15.194 15.194 19 10.5 19C5.806 19 2 15.194 2 10.5C2 5.806 5.806 2 10.5 2C15.194 2 19 5.806 19 10.5Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>\n </svg>\n '}bindEvents(){this.element&&(this.element.addEventListener("mouseenter",()=>{this.element.style.transform="scale(1.1)",this.element.style.boxShadow="0 6px 25px rgba(0, 0, 0, 0.4)"}),this.element.addEventListener("mouseleave",()=>{this.element.style.transform="scale(1)",this.element.style.boxShadow="0 4px 20px rgba(0, 0, 0, 0.3)"}),this.element.addEventListener("click",()=>{console.log("button clicked"),this.eventBus.emit("button:click")}))}render(){this.element||this.create(),this.isVisible&&document.body.appendChild(this.element)}show(){this.element&&!this.isVisible&&(this.element.style.display="flex",this.isVisible=!0)}hide(){this.element&&this.isVisible&&(this.element.style.display="none",this.isVisible=!1)}toggle(){this.isVisible?this.hide():this.show()}updatePosition(e){this.element&&(this.element.style.bottom=`${e.bottom}px`,this.element.style.right=`${e.right}px`)}updateSize(e){this.element&&(this.element.style.width=`${e}px`,this.element.style.height=`${e}px`)}destroy(){this.element&&this.element.parentNode&&this.element.parentNode.removeChild(this.element),this.element=null}}class g{static isKeyCombination(e,t){const{key:s,ctrlKey:i=!1,metaKey:o=!1,shiftKey:n=!1,altKey:l=!1}=t;return e.key===s&&e.ctrlKey===i&&e.metaKey===o&&e.shiftKey===n&&e.altKey===l}static isSearchShortcut(e){const t=("k"===e.key||"K"===e.key)&&(e.ctrlKey||e.metaKey)&&!e.shiftKey&&!e.altKey;return("k"===e.key||"K"===e.key||e.ctrlKey||e.metaKey)&&console.log("🔍 Keyboard shortcut check:",{key:e.key,ctrlKey:e.ctrlKey,metaKey:e.metaKey,shiftKey:e.shiftKey,altKey:e.altKey,isShortcut:t,target:e.target.tagName,targetId:e.target.id,targetClass:e.target.className}),t}static testKeyboardEvent(e){return{key:e.key,ctrlKey:e.ctrlKey,metaKey:e.metaKey,shiftKey:e.shiftKey,altKey:e.altKey,isSearchShortcut:this.isSearchShortcut(e),keyCode:e.keyCode,which:e.which,code:e.code}}static isEscape(e){return"Escape"===e.key}static isEnter(e){return"Enter"===e.key}static isArrowDown(e){return"ArrowDown"===e.key}static isArrowUp(e){return"ArrowUp"===e.key}static isTab(e){return"Tab"===e.key}static isNavigationKey(e){return this.isArrowDown(e)||this.isArrowUp(e)}static preventDefault(e){e.preventDefault(),e.stopPropagation()}static addKeyboardListener(e,t="keydown",s){const i=e=>{s(e)};return e.addEventListener(t,i),()=>{e.removeEventListener(t,i)}}static addGlobalKeyboardListener(e="keydown",t){return this.addKeyboardListener(document,e,t)}}const u="Ask me anything...",p="Search...",m="Powered by",y="Flowvana",f="Thinking...",b="No description available",w="Search Error",S="No more points to highlight",x="Element clicked - calling next API",v="Input detected - waiting 500ms for idle before calling next API",E="500ms idle after input - calling next API",k="Highlighting point:",C="Overlay:",I="Read action detected - highlighter will auto-dismiss in 3.5 seconds (mouse dismissal disabled)",K="Click action detected - waiting for user to click the element",T="Type action detected - waiting for user input with 500ms debounce",R="Dismissing highlight",L="Highlight dismissed",B="Search interface shown",z="Search interface hidden",D="FlowLight initialized with options:",F="Element highlighted:",P="Invalid XPath or error during XPath evaluation:",O="highlightElement: No element provided";class M{static setCookie(e,t,s){let i="";if("number"==typeof s){const e=new Date;e.setTime(e.getTime()+24*s*60*60*1e3),i="; expires="+e.toUTCString()}document.cookie=e+"="+encodeURIComponent(t)+i+"; path=/"}static getCookie(e){const t=e+"=",s=document.cookie.split(";");for(let e=0;e<s.length;e++){let i=s[e];for(;" "===i.charAt(0);)i=i.substring(1,i.length);if(0===i.indexOf(t))return decodeURIComponent(i.substring(t.length,i.length))}return null}static deleteCookie(e){this.setCookie(e,"",-1)}static hasCookie(e){return null!==this.getCookie(e)}}class V{constructor(e={},t){this.options=e,this.eventBus=t,this.isVisible=!1,this.searchInput=null,this.overlayElement=null,this.searchElement=null,this.suggestionsElement=null,this.resultsElement=null,this.loadingElement=null,this.badgeElement=null,this.errorElement=null,this.searchTimeout=null,this.selectedResultIndex=-1,this.currentResults=[],this.selectedSuggestionIndex=-1,this.flowPointsCookieName=o,this.flowCurrentIdxCookieName=n,this.apiService=new h(e)}create(){this.createOverlay(),this.createSearchContainer(),this.createSearchInput(),this.createAISuggestionBlock(),this.createSuggestions(),this.createBadge(),this.bindEvents(),this.updateSuggestions()}createOverlay(){this.overlayElement=d.createElement("div","flowlight-overlay",{position:"fixed",top:"0",left:"0",width:"100%",height:"100%",backgroundColor:"rgba(0, 0, 0, 0.5)",zIndex:this.options.zIndex-1,display:"none",opacity:"0",transition:"opacity 0.3s ease"}),document.body.appendChild(this.overlayElement)}createSearchContainer(){this.searchElement=d.createElement("div","flowlight-search",{position:"fixed",top:"25%",left:"50%",transform:"translate(-50%, -50%) scale(0.8)",width:"800px",maxWidth:"90vw",backgroundColor:"white",borderRadius:"12px",boxShadow:"0 8px 32px rgba(0, 0, 0, 0.12)",zIndex:this.options.zIndex,display:"none",opacity:"0",transition:"all 0.3s ease",overflow:"hidden",border:"1px solid #f0f0f0"}),document.body.appendChild(this.searchElement)}createSearchInput(){const e=d.createElement("div","flowlight-search-input-container",{position:"relative",display:"flex",alignItems:"center",width:"100%"});this.searchInput=d.createElement("input","flowlight-search-input",{flex:"1",padding:"20px 24px",paddingRight:"80px",border:"none",outline:"none",fontSize:"16px",backgroundColor:"transparent",color:"#333",fontFamily:'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',fontWeight:"400"}),this.searchInput.type="text",this.updateSearchPlaceholder();const t=d.createElement("div","flowlight-shortcut-indicator",{position:"absolute",right:"16px",top:"50%",transform:"translateY(-50%)",padding:"4px 8px",backgroundColor:"#f3f4f6",borderRadius:"6px",fontSize:"12px",color:"#6b7280",fontFamily:'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',fontWeight:"500",border:"1px solid #e5e7eb",pointerEvents:"none",userSelect:"none"}),s=navigator.platform.toUpperCase().indexOf("MAC")>=0;t.textContent=s?"⌘K":"Ctrl+K",e.appendChild(this.searchInput),e.appendChild(t),this.searchElement.appendChild(e)}updateSearchPlaceholder(){const e=this.searchInput&&this.searchInput.offsetWidth<400;this.searchInput.placeholder=e?p:u}updateShortcutIndicator(){const e=this.searchElement?.querySelector(".flowlight-shortcut-indicator");if(e){const t=navigator.platform.toUpperCase().indexOf("MAC")>=0;e.textContent=t?"⌘K":"Ctrl+K"}}setSearchPlaceholder(e){this.searchInput&&(this.searchInput.placeholder=e)}createSuggestions(){this.suggestionsElement=d.createElement("div","flowlight-suggestions",{padding:"16px 24px",backgroundColor:"#f8f9fa",borderTop:"1px solid #e9ecef",display:"flex",flexWrap:"wrap",gap:"8px",maxHeight:"120px",overflowY:"auto"}),this.searchElement.appendChild(this.suggestionsElement)}createAISuggestionBlock(){const e=d.createElement("div","flowlight-ai-suggestion",{margin:"0 24px 16px 24px",padding:"16px 20px",backgroundColor:"#f3f4f6",borderRadius:"8px",display:"flex",alignItems:"center",justifyContent:"space-between",border:"1px solid #e5e7eb"}),t=d.createElement("div","flowlight-ai-left",{display:"flex",alignItems:"center",gap:"12px"}),s=d.createElement("div","flowlight-sparkle-icon",{width:"20px",height:"20px",backgroundColor:"#8b5cf6",borderRadius:"4px",display:"flex",alignItems:"center",justifyContent:"center",color:"white",fontSize:"12px",fontWeight:"bold"});s.innerHTML="✨";const i=d.createElement("div","flowlight-ai-text",{display:"flex",flexDirection:"column",gap:"2px"}),o=d.createElement("div","flowlight-ai-main-text",{color:"#6b21a8",fontSize:"14px",fontWeight:"600",fontFamily:'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'}),n=d.createElement("div","flowlight-ai-sub-text",{color:"#6b7280",fontSize:"12px",fontFamily:'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'});i.appendChild(o),i.appendChild(n),t.appendChild(s),t.appendChild(i);const l=d.createElement("div","flowlight-ai-right",{width:"16px",height:"16px",backgroundColor:"#8b5cf6",borderRadius:"3px",display:"flex",alignItems:"center",justifyContent:"center",color:"white",fontSize:"10px"});l.innerHTML="↗",e.appendChild(t),e.appendChild(l),this.aiMainText=o,this.aiSubText=n,this.searchElement.appendChild(e),this.aiSuggestionBlock=e}createBadge(){this.badgeElement=d.createElement("div","flowlight-powered-by",{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"16px 24px",backgroundColor:"white",borderTop:"1px solid #e5e7eb",fontSize:"12px",color:"#6c757d",fontFamily:'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'});const e=d.createElement("div","flowlight-powered-left",{display:"flex",alignItems:"center",gap:"6px"});e.innerHTML=`\n <span style="color: #9ca3af;">${m}</span>\n <span style="color: #374151; font-weight: 600;">▶</span>\n <span style="color: #111827; font-weight: 600;">${y}</span>\n `;const t=d.createElement("div","flowlight-navigation",{display:"flex",alignItems:"center",gap:"16px"}),s=d.createElement("div","flowlight-navigate",{display:"flex",alignItems:"center",gap:"6px"});s.innerHTML='\n <span style="color: #9ca3af; font-size: 10px;">↑</span>\n <span style="color: #9ca3af; font-size: 10px;">↓</span>\n <span style="color: #9ca3af;">Navigate</span>\n ';const i=d.createElement("div","flowlight-select",{display:"flex",alignItems:"center",gap:"6px"});i.innerHTML='\n <span style="color: #9ca3af; font-size: 10px;">↵</span>\n <span style="color: #9ca3af;">Select</span>\n ',t.appendChild(s),t.appendChild(i),this.badgeElement.appendChild(e),this.badgeElement.appendChild(t),this.searchElement.appendChild(this.badgeElement)}bindEvents(){this.overlayElement.addEventListener("click",e=>{e.target===this.overlayElement&&this.hide()}),this.handleResize=()=>{this.isVisible&&(this.updateSearchPlaceholder(),this.updateShortcutIndicator())},window.addEventListener("resize",this.handleResize),this.searchInput.addEventListener("keydown",e=>{g.isEscape(e)?this.hide():g.isArrowDown(e)?(e.preventDefault(),this.suggestionsElement&&"none"!==this.suggestionsElement.style.display?this.navigateSuggestions("down"):this.navigateResults("down")):g.isArrowUp(e)?(e.preventDefault(),this.suggestionsElement&&"none"!==this.suggestionsElement.style.display?this.navigateSuggestions("up"):this.navigateResults("up")):g.isEnter(e)?(e.preventDefault(),this.selectedSuggestionIndex>=0?this.selectCurrentSuggestion():this.selectCurrentResult().catch(e=>{console.error("Error selecting current result:",e)})):g.isTab(e)&&(e.preventDefault(),this.selectFirstSuggestion())}),this.searchInput.addEventListener("input",e=>{const t=e.target.value.trim();this.updateSuggestions(t),this.searchTimeout&&clearTimeout(this.searchTimeout),t.length>=a?this.searchTimeout=setTimeout(()=>{this.handleSearch(t)},this.options.searchDebounceDelay||500):0===t.length&&this.clearSearchResults()})}show(){this.isVisible=!0,this.overlayElement.style.display="block",setTimeout(()=>{this.overlayElement.style.opacity="1"},10),this.searchElement.style.display="block",setTimeout(()=>{this.searchElement.style.opacity="1",this.searchElement.style.transform="translate(-50%, -50%) scale(1)"},10),setTimeout(()=>{this.searchInput.focus(),this.updateSearchPlaceholder(),this.updateShortcutIndicator()},100),this.options.debug&&console.log(B)}hide(){this.isVisible=!1,this.searchElement.style.opacity="0",this.searchElement.style.transform="translate(-50%, -50%) scale(0.8)",this.overlayElement.style.opacity="0",setTimeout(()=>{this.searchElement.style.display="none",this.overlayElement.style.display="none",this.searchInput.value="",this.searchTimeout&&(clearTimeout(this.searchTimeout),this.searchTimeout=null),this.resultsElement&&(this.resultsElement.remove(),this.resultsElement=null),this.loadingElement&&(this.loadingElement.style.display="none"),this.selectedResultIndex=-1,this.currentResults=[],this.updateSuggestions()},300),this.options.debug&&console.log(z)}toggle(){this.isVisible?this.hide():this.show()}updateSuggestions(e=""){if(!this.suggestionsElement)return;console.log("📝 Updating suggestions:",{query:e,timestamp:(new Date).toISOString()}),this.aiMainText&&this.aiSubText&&(e?(this.aiMainText.textContent=`Ask "${e}"`,this.aiSubText.textContent="Get an answer with AI",this.aiSuggestionBlock.style.display="flex"):this.aiSuggestionBlock.style.display="none"),this.suggestionsElement.innerHTML="",this.selectedSuggestionIndex=-1;const t=i.filter(t=>t.toLowerCase().includes(e.toLowerCase())),s=(e?t:i).slice(0,6);s.forEach((e,t)=>{const s=d.createElement("button","flowlight-suggestion",{padding:"6px 12px",backgroundColor:"white",border:"1px solid #dee2e6",borderRadius:"16px",fontSize:"12px",color:"#495057",cursor:"pointer",transition:"all 0.2s ease",fontFamily:'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',outline:"none"},e);s.dataset.suggestion=e,s.dataset.index=t,s.addEventListener("mouseenter",()=>{console.log("🖱️ Suggestion hover enter:",{suggestion:e,index:t,timestamp:(new Date).toISOString()}),this.selectedSuggestionIndex=t,this.updateSuggestionSelection()}),s.addEventListener("mouseleave",()=>{console.log("🖱️ Suggestion hover leave:",{suggestion:e,index:t,timestamp:(new Date).toISOString()}),this.selectedSuggestionIndex=-1,this.updateSuggestionSelection()}),s.addEventListener("click",i=>{i.preventDefault(),i.stopPropagation(),console.log("🎯 Suggestion clicked!",{suggestion:e,index:t,element:s,eventTarget:i.target,timestamp:(new Date).toISOString()}),this.options.debug&&(console.log("Suggestion clicked:",e),console.log("Suggestion element:",s),console.log("Event target:",i.target)),this.selectSuggestion(e)}),s.addEventListener("mousedown",s=>{console.log("👆 Suggestion mousedown:",{suggestion:e,index:t,timestamp:(new Date).toISOString()}),this.options.debug&&console.log("Suggestion mousedown:",e)}),this.suggestionsElement.appendChild(s),console.log("➕ Suggestion element created:",{suggestion:e,index:t,element:s,timestamp:(new Date).toISOString()})}),console.log("✅ Suggestions update completed:",{totalSuggestions:s.length,query:e,timestamp:(new Date).toISOString()})}async handleSearch(e){if(this.options.debug&&console.log("Search query:",e),e.length<a)return this.hideLoadingState(),void this.showSearchResults([]);this.showLoadingState(),this.eventBus.emit("search:query",{query:e});try{const t=await this.apiService.searchFlows(e,{limit:r});this.options.debug&&console.log("Search results:",t),this.hideLoadingState(),this.showSearchResults(t.flows||t||[])}catch(e){this.options.debug&&console.error("Search API error:",e),this.hideLoadingState(),this.showSearchError(e.message)}}showLoadingState(){this.searchTimeout&&(clearTimeout(this.searchTimeout),this.searchTimeout=null),this.suggestionsElement&&(this.suggestionsElement.style.display="none"),this.aiSuggestionBlock&&(this.aiSuggestionBlock.style.display="none"),this.loadingElement||(this.loadingElement=d.createElement("div","flowlight-loading",{padding:"20px 24px",backgroundColor:"white",borderTop:"1px solid #e5e7eb",display:"flex",alignItems:"center",justifyContent:"center",gap:"12px"}),this.loadingElement.innerHTML=`\n <div class="flowlight-waves">\n <div class="wave"></div>\n <div class="wave"></div>\n <div class="wave"></div>\n </div>\n <span style="color: #6b7280; font-size: 14px; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;">${f}</span>\n `,d.addStyles("\n .flowlight-waves {\n display: flex;\n align-items: center;\n gap: 4px;\n }\n .flowlight-waves .wave {\n width: 4px;\n height: 20px;\n background: #8b5cf6;\n border-radius: 2px;\n animation: flowlight-wave 1.2s ease-in-out infinite;\n }\n .flowlight-waves .wave:nth-child(2) {\n animation-delay: 0.2s;\n }\n .flowlight-waves .wave:nth-child(3) {\n animation-delay: 0.4s;\n }\n @keyframes flowlight-wave {\n 0%, 40%, 100% {\n transform: scaleY(0.4);\n }\n 20% {\n transform: scaleY(1);\n }\n }\n ","flowlight-wave-styles"),this.searchElement.insertBefore(this.loadingElement,this.badgeElement)),this.loadingElement.style.display="flex"}hideLoadingState(){this.loadingElement&&(this.loadingElement.style.display="none"),this.aiSuggestionBlock&&!this.resultsElement&&(this.aiSuggestionBlock.style.display="flex")}showErrorState(e){this.hideLoadingState(),this.errorElement||(this.errorElement=d.createElement("div","flowlight-error",{padding:"16px 24px",backgroundColor:"#f8d7da",border:"1px solid #f5c6cb",borderRadius:"8px",color:"#721c24",fontSize:"14px",fontFamily:'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',marginTop:"8px"}),this.searchElement.appendChild(this.errorElement)),this.errorElement.textContent=e,this.errorElement.style.display="block",setTimeout(()=>{this.errorElement&&(this.errorElement.style.display="none")},3e3)}showSearchError(e){this.resultsElement&&this.resultsElement.remove(),this.resultsElement=d.createElement("div","flowlight-results",{padding:"16px 24px",backgroundColor:"#f8f9fa",borderTop:"1px solid #e9ecef",maxHeight:"300px",overflowY:"auto"}),this.resultsElement.innerHTML=`\n <div style="text-align: center; color: #dc3545; font-size: 14px; padding: 20px;">\n <div style="margin-bottom: 8px; font-weight: 600;">${w}</div>\n <div style="font-size: 12px; color: #6c757d;">${e}</div>\n </div>\n `,this.searchElement.insertBefore(this.resultsElement,this.badgeElement)}showSearchResults(e){this.resultsElement&&this.resultsElement.remove(),this.aiSuggestionBlock&&(this.aiSuggestionBlock.style.display="none"),this.currentResults=e,this.selectedResultIndex=-1,this.resultsElement=d.createElement("div","flowlight-results",{padding:"16px 24px",backgroundColor:"white",borderTop:"1px solid #e5e7eb",maxHeight:"300px",overflowY:"auto"}),0===e.length?this.resultsElement.innerHTML="\n <div style=\"text-align: center; color: #9ca3af; font-size: 14px; padding: 20px; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\">\n No results found 😉\n </div>\n ":e.forEach((e,t)=>{const s=d.createElement("div","flowlight-flow-item",{padding:"12px 16px",backgroundColor:"white",border:"1px solid #e5e7eb",borderRadius:"8px",marginBottom:"8px",cursor:"pointer",transition:"all 0.2s ease",fontFamily:'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'});s.addEventListener("mouseenter",()=>{s.style.backgroundColor="#f9fafb",s.style.borderColor="#d1d5db"}),s.addEventListener("mouseleave",()=>{s.style.backgroundColor="white",s.style.borderColor="#e5e7eb"}),s.addEventListener("click",async()=>{this.selectedResultIndex=t,await this.selectFlow(e)}),s.innerHTML=`\n <div style="font-weight: 600; color: #111827; margin-bottom: 4px;">\n ${e.name||e.title||`Flow ${t+1}`}\n </div>\n <div style="font-size: 12px; color: #6b7280;">\n ${e.description||b}\n </div>\n `,this.resultsElement.appendChild(s)}),this.searchElement.insertBefore(this.resultsElement,this.badgeElement)}clearSearchResults(){this.resultsElement&&(this.resultsElement.remove(),this.resultsElement=null),this.loadingElement&&(this.loadingElement.style.display="none"),this.selectedResultIndex=-1,this.currentResults=[],this.aiSuggestionBlock&&(this.aiSuggestionBlock.style.display="flex"),this.showSuggestions()}showSuggestions(){this.suggestionsElement&&(this.suggestionsElement.style.display="flex"),this.aiSuggestionBlock&&(this.aiSuggestionBlock.style.display="flex")}selectSuggestion(e){console.log("🚀 Selecting suggestion:",{suggestion:e,currentInputValue:this.searchInput.value,isVisible:this.isVisible,timestamp:(new Date).toISOString()}),this.options.debug&&console.log("selectSuggestion called with:",e),this.searchInput.value=e,this.searchInput.focus(),this.handleSearch(e),this.eventBus.emit("suggestion:selected",{suggestion:e}),console.log("✅ Suggestion selection completed:",{suggestion:e,newInputValue:this.searchInput.value,timestamp:(new Date).toISOString()}),this.options.debug&&console.log("Suggestion selected:",e)}selectFirstSuggestion(){const e=this.suggestionsElement?.querySelector(".flowlight-suggestion");if(e){const t=e.dataset.suggestion;this.selectSuggestion(t)}}updateSuggestionSelection(){const e=this.suggestionsElement?.querySelectorAll(".flowlight-suggestion");e&&e.forEach((e,t)=>{t===this.selectedSuggestionIndex?(e.style.backgroundColor="#e3f2fd",e.style.borderColor="#2196f3",e.style.color="#1976d2",e.style.boxShadow="0 2px 8px rgba(33, 150, 243, 0.3)"):(e.style.backgroundColor="white",e.style.borderColor="#dee2e6",e.style.color="#495057",e.style.boxShadow="none")})}navigateSuggestions(e){const t=this.suggestionsElement?.querySelectorAll(".flowlight-suggestion");t&&0!==t.length&&("down"===e?this.selectedSuggestionIndex=Math.min(this.selectedSuggestionIndex+1,t.length-1):"up"===e&&(this.selectedSuggestionIndex=Math.max(this.selectedSuggestionIndex-1,-1)),this.updateSuggestionSelection())}selectCurrentSuggestion(){if(this.selectedSuggestionIndex>=0){const e=this.suggestionsElement?.querySelectorAll(".flowlight-suggestion");if(e&&e[this.selectedSuggestionIndex]){const t=e[this.selectedSuggestionIndex].dataset.suggestion;this.selectSuggestion(t)}}}navigateResults(e){this.currentResults&&0!==this.currentResults.length&&("down"===e?this.selectedResultIndex=Math.min(this.selectedResultIndex+1,this.currentResults.length-1):"up"===e&&(this.selectedResultIndex=Math.max(this.selectedResultIndex-1,-1)),this.updateResultSelection())}updateResultSelection(){if(!this.resultsElement)return;this.resultsElement.querySelectorAll(".flowlight-flow-item").forEach((e,t)=>{t===this.selectedResultIndex?(e.style.backgroundColor="#e3f2fd",e.style.borderColor="#2196f3",e.style.boxShadow="0 2px 8px rgba(33, 150, 243, 0.3)"):(e.style.backgroundColor="white",e.style.borderColor="#dee2e6",e.style.boxShadow="none")})}async selectCurrentResult(){this.selectedResultIndex>=0&&this.selectedResultIndex<this.currentResults.length&&await this.selectFlow(this.currentResults[this.selectedResultIndex])}async selectFlow(e){this.options.debug&&(console.log("Selected flow:",e),console.log("Flow object keys:",Object.keys(e))),this.showLoadingState();try{const t=e.id||e.flow_id||e._id||e.flowId;if(!t)throw new Error("Flow ID not found in flow object");const s=await this.apiService.getFlowDetails(t);this.options.debug&&console.log("Flow details received:",s),this.hideLoadingState(),this.hide(),this.eventBus.emit("flow:selected",{flow:e,flowDetails:s}),s.success&&s.points&&s.points.length>0&&(this.setCookie(this.flowCurrentIdxCookieName,0),this.setCookie(this.flowPointsCookieName,JSON.stringify(s.points)),this.highlightFlowPoints())}catch(e){console.error("Error fetching flow details:",e),this.hideLoadingState(),this.showErrorState("Failed to load flow details. Please try again.")}}setCookie(e,t,s=7){M.setCookie(e,t,s)}getCookie(e){return M.getCookie(e)}highlightFlowPoints(){let e=JSON.parse(this.getCookie(this.flowPointsCookieName)),t=parseInt(this.getCookie(this.flowCurrentIdxCookieName),10);if(t>=e.length)return void console.log(S);let s=e[t].locator,i=e[t].action||"click",o=e[t].description||"";console.log(k,s,i,o);let n=null;try{n=document.evaluate(s,document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue}catch(e){console.error(P,s,e),n=null}if(n){const e={dismissOnMouseEnter:"read"!==i,autoDismissDelay:"read"===i?3500:null};let s=this.highlightElement(n,e);if(console.log(C,s),"read"===i&&console.log(I),o&&s){const e=s.querySelector(".flowlight-highlight-border");if(e){const t=document.createElement("div");t.className="flowlight-suggestion-text",Object.assign(t.style,{position:"absolute",top:"-40px",left:"50%",transform:"translateX(-50%)",backgroundColor:"rgba(0, 0, 0, 0.9)",color:"white",padding:"8px 12px",borderRadius:"6px",fontSize:"14px",fontFamily:"system-ui, -apple-system, sans-serif",fontWeight:"500",boxShadow:"0 4px 12px rgba(0, 0, 0, 0.3)",zIndex:"10",maxWidth:"300px",textAlign:"center",wordWrap:"break-word",whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"}),t.textContent=o;const s=document.createElement("div");Object.assign(s.style,{position:"absolute",top:"100%",left:"50%",transform:"translateX(-50%)",width:"0",height:"0",borderLeft:"6px solid transparent",borderRight:"6px solid transparent",borderTop:"6px solid rgba(0, 0, 0, 0.9)"}),t.appendChild(s),e.appendChild(t)}}if("click"===i)n.addEventListener("click",()=>{console.log(x),l()}),console.log(K);else if("type"===i){let e;const t=()=>{console.log(v),e&&clearTimeout(e),e=setTimeout(()=>{console.log(E),l()},500)};n.addEventListener("input",t),n.addEventListener("change",t),console.log(T)}else n.addEventListener("click",()=>{console.log(x),l()});const l=()=>{t=parseInt(this.getCookie(this.flowCurrentIdxCookieName),10),this.setCookie(this.flowCurrentIdxCookieName,t+1),setTimeout(()=>{this.highlightFlowPoints()},500)};return n}return null}highlightElement(e,t={}){if(!e)return console.error(O),null;this.removeHighlight();const s=document.createElement("div");s.className="flowlight-highlight-overlay",s.style.cssText=`\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n pointer-events: none;\n z-index: ${this.options.zIndex-2};\n `;const i=document.createElement("div");i.className="flowlight-highlight-border";const o=e.getBoundingClientRect(),n=window.pageYOffset||document.documentElement.scrollTop,l=window.pageXOffset||document.documentElement.scrollLeft;if(i.style.cssText=`\n position: absolute;\n top: ${o.top+n}px;\n left: ${o.left+l}px;\n width: ${o.width}px;\n height: ${o.height}px;\n border: 3px solid #007bff;\n border-radius: 4px;\n box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.3);\n pointer-events: none;\n z-index: ${this.options.zIndex-1};\n animation: flowlight-pulse 2s infinite;\n `,!document.getElementById("flowlight-highlight-styles")){const e=document.createElement("style");e.id="flowlight-highlight-styles",e.textContent="\n @keyframes flowlight-pulse {\n 0% { box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.3), 0 0 0 0 rgba(0, 123, 255, 0.7); }\n 70% { box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.3), 0 0 0 10px rgba(0, 123, 255, 0); }\n 100% { box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.3), 0 0 0 0 rgba(0, 123, 255, 0); }\n }\n ",document.head.appendChild(e)}return s.appendChild(i),document.body.appendChild(s),t.autoDismissDelay&&setTimeout(()=>{this.removeHighlight()},t.autoDismissDelay),!1!==t.dismissOnMouseEnter&&e.addEventListener("mouseenter",()=>{console.log(R),this.removeHighlight(),console.log(L)},{once:!0}),this.options.debug&&console.log(F,e),s}removeHighlight(){const e=document.querySelector(".flowlight-highlight-overlay");e&&e.remove()}destroy(){this.overlayElement&&this.overlayElement.parentNode&&this.overlayElement.parentNode.removeChild(this.overlayElement),this.searchElement&&this.searchElement.parentNode&&this.searchElement.parentNode.removeChild(this.searchElement),window.removeEventListener("resize",this.handleResize);const e=document.getElementById("flowlight-highlight-styles");e&&e.remove(),d.removeStyles("flowlight-wave-styles")}}class N{constructor(t={}){this.options={...s,...t},this.eventBus=new e,this.apiService=new h(this.options),this.components={button:new c(this.options,this.eventBus),search:new V(this.options,this.eventBus)},this.isInitialized=!1,this.isSearchVisible=!1,"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>this.init()):this.init(),this.options.debug&&console.log(D,this.options)}init(){if(!this.isInitialized)try{this.components.button.render(),this.components.search.create(),this.bindEvents(),this.bindKeyboardShortcuts(),this.isInitialized=!0,this.options.debug&&console.log("FlowLight initialized successfully")}catch(e){console.error("Failed to initialize FlowLight:",e)}}bindEvents(){this.eventBus.on("button:click",()=>{this.toggleSearch()}),this.eventBus.on("search:toggle",()=>{this.toggleSearch()})}bindKeyboardShortcuts(){if(!this.options.keyboardShortcuts)return void(this.options.debug&&console.log("Keyboard shortcuts disabled in options"));this.keyboardCleanup&&(this.keyboardCleanup(),this.keyboardCleanup=null);const e=g.addGlobalKeyboardListener("keydown",e=>{this.options.debug&&console.log("🔍 Keyboard event detected:",{key:e.key,ctrlKey:e.ctrlKey,metaKey:e.metaKey,shiftKey:e.shiftKey,altKey:e.altKey,isSearchShortcut:g.isSearchShortcut(e),isSearchVisible:this.isSearchVisible}),g.isSearchShortcut(e)&&(g.preventDefault(e),this.options.debug&&console.log("⌨️ Search shortcut triggered!"),this.toggleSearch())});this.keyboardCleanup=e,this.options.debug&&console.log("✅ Keyboard shortcuts bound successfully")}refreshKeyboardShortcuts(){this.options.debug&&console.log("🔄 Refreshing keyboard shortcuts..."),this.disableKeyboardShortcuts(),this.enableKeyboardShortcuts(),this.options.debug&&console.log("✅ Keyboard shortcuts refreshed")}toggleSearch(){this.options.debug&&console.log("🔄 Toggle search called:",{isSearchVisible:this.isSearchVisible,searchInterfaceVisible:this.components.search.isVisible}),this.isSearchVisible?this.hideSearch():this.showSearch()}showSearch(){this.isSearchVisible=!0,this.components.search.show(),this.eventBus.emit("search:shown"),this.options.debug&&console.log(B)}hideSearch(){this.isSearchVisible=!1,this.components.search.hide(),this.eventBus.emit("search:hidden"),this.options.debug&&console.log(z)}getSearchState(){return{isVisible:this.isSearchVisible}}updateOptions(e){this.options={...this.options,...e},this.components.button&&(this.components.button.updateSize(this.options.buttonSize),this.components.button.updatePosition(this.options.buttonPosition)),e.hasOwnProperty("keyboardShortcuts")&&(e.keyboardShortcuts?this.enableKeyboardShortcuts():this.disableKeyboardShortcuts()),this.options.debug&&console.log("FlowLight options updated:",this.options)}enableKeyboardShortcuts(){this.keyboardCleanup||(this.bindKeyboardShortcuts(),this.options.debug&&console.log("Keyboard shortcuts enabled"))}disableKeyboardShortcuts(){this.keyboardCleanup&&(this.keyboardCleanup(),this.keyboardCleanup=null,this.options.debug&&console.log("Keyboard shortcuts disabled"))}areKeyboardShortcutsEnabled(){return this.options.keyboardShortcuts&&null!==this.keyboardCleanup}getKeyboardShortcutInfo(){return{enabled:this.areKeyboardShortcutsEnabled(),shortcut:"Cmd+K (Mac) or Ctrl+K (Windows/Linux)",description:"Toggle search interface"}}getInstance(){return this}highlightElement(e,t={}){return this.components.search.highlightElement(e,t)}removeHighlight(){this.components.search.removeHighlight()}setSearchPlaceholder(e){this.components.search.setSearchPlaceholder(e)}updateSearchPlaceholder(){this.components.search.updateSearchPlaceholder()}getDebugState(){return{isSearchVisible:this.isSearchVisible,searchInterfaceVisible:this.components.search.isVisible,keyboardShortcutsEnabled:this.areKeyboardShortcutsEnabled(),keyboardCleanupExists:null!==this.keyboardCleanup,options:{keyboardShortcuts:this.options.keyboardShortcuts,debug:this.options.debug}}}destroy(){try{Object.values(this.components).forEach(e=>{e&&"function"==typeof e.destroy&&e.destroy()}),this.eventBus.clear(),this.keyboardCleanup&&this.keyboardCleanup(),this.isInitialized=!1,this.isSearchVisible=!1,this.components={},this.options.debug&&console.log("FlowLight destroyed")}catch(e){console.error("Error destroying FlowLight:",e)}}}"undefined"!=typeof window&&(window.FlowLight=N),"undefined"!=typeof module&&module.exports&&(module.exports=N);export{N as default};
//# sourceMappingURL=flowlight.esm.js.map