{"version":3,"file":"BrowserTabNotify.fS5nBuzP.mjs","names":["useRef"],"sources":["https:/framerusercontent.com/modules/SkWtow76vkGTqjCqCXyf/MLDjCL6WrgIvGFodmik7/BrowserTabNotify.js"],"sourcesContent":["// ─────────────────────────────────────────────────────────────────────────────\n//  BrowserTabNotify — Framer Marketplace Component\n//  Drop onto any page. Invisible on canvas. Works on published sites.\n// ─────────────────────────────────────────────────────────────────────────────\nimport{jsx as _jsx,jsxs as _jsxs}from\"react/jsx-runtime\";import{useEffect,useRef}from\"react\";import{addPropertyControls,ControlType}from\"framer\";// ── Canvas placeholder (shown only inside Framer editor) ──────────────────────\nfunction EditorPlaceholder(){return /*#__PURE__*/_jsxs(\"div\",{style:{width:\"100%\",height:\"100%\",minWidth:200,minHeight:64,display:\"flex\",flexDirection:\"column\",alignItems:\"center\",justifyContent:\"center\",gap:8,borderRadius:12,border:\"1.5px dashed rgba(108,99,255,0.5)\",background:\"radial-gradient(ellipse at 50% 0%, rgba(108,99,255,0.12) 0%, transparent 70%)\",fontFamily:\"'Sora', system-ui, sans-serif\",padding:16,boxSizing:\"border-box\",cursor:\"default\",userSelect:\"none\"},children:[/*#__PURE__*/_jsx(\"span\",{style:{fontSize:26},children:\"🔔\"}),/*#__PURE__*/_jsx(\"div\",{style:{fontSize:12,fontWeight:700,color:\"rgba(108,99,255,0.9)\",letterSpacing:\"0.04em\"},children:\"Browser Tab Notify\"}),/*#__PURE__*/_jsx(\"div\",{style:{fontSize:10,color:\"rgba(255,255,255,0.35)\",textAlign:\"center\",lineHeight:1.6,maxWidth:160},children:\"Invisible on published site. Configure messages in the panel →\"})]});}// ── Soft bell tone using Web Audio API ────────────────────────────────────────\nfunction playBell(){try{const ctx=new(window.AudioContext||window.webkitAudioContext);const osc=ctx.createOscillator();const gain=ctx.createGain();osc.connect(gain);gain.connect(ctx.destination);osc.type=\"sine\";osc.frequency.setValueAtTime(880,ctx.currentTime);osc.frequency.exponentialRampToValueAtTime(440,ctx.currentTime+.4);gain.gain.setValueAtTime(.18,ctx.currentTime);gain.gain.exponentialRampToValueAtTime(1e-4,ctx.currentTime+.6);osc.start(ctx.currentTime);osc.stop(ctx.currentTime+.6);}catch(_){// AudioContext not available — silently skip\n}}// ── Main component ────────────────────────────────────────────────────────────\nexport default function BrowserTabNotify(props){const{message1,message2,message3,message4,message5,messageCount,triggerDelay,messageInterval,maxRotations,enableWelcomeBack,welcomeBackMessage,welcomeBackDuration,restoreOriginalTitle,enableSound}=props;// Collect active messages based on messageCount slider\nconst allMessages=[message1,message2,message3,message4,message5];const messages=allMessages.slice(0,messageCount).filter(Boolean);const originalTitle=useRef(\"\");const delayTimer=useRef(null);const rotateTimer=useRef(null);const welcomeTimer=useRef(null);const isAway=useRef(false);const msgIdx=useRef(0);const rotationsDone=useRef(0);const stopAll=()=>{if(delayTimer.current)clearTimeout(delayTimer.current);if(rotateTimer.current)clearInterval(rotateTimer.current);if(welcomeTimer.current)clearTimeout(welcomeTimer.current);};const startRotating=()=>{if(messages.length===0)return;msgIdx.current=0;rotationsDone.current=0;const tick=()=>{if(!isAway.current)return;document.title=messages[msgIdx.current%messages.length];msgIdx.current++;// Track full cycles (one cycle = all messages shown once)\nif(msgIdx.current%messages.length===0){rotationsDone.current++;if(maxRotations>0&&rotationsDone.current>=maxRotations){clearInterval(rotateTimer.current);}}};tick()// fire immediately, then repeat\n;rotateTimer.current=setInterval(tick,messageInterval*1e3);};useEffect(()=>{// Only run on published site / preview — not inside Framer editor\nif(typeof document===\"undefined\")return;originalTitle.current=document.title;const onVisibilityChange=()=>{if(document.hidden){// ── User left the tab ────────────────────────────────────────\nisAway.current=true;if(enableSound)playBell();stopAll();if(messages.length>0){delayTimer.current=setTimeout(startRotating,triggerDelay*1e3);}}else{// ── User returned ────────────────────────────────────────────\nisAway.current=false;stopAll();if(enableWelcomeBack&&welcomeBackMessage){document.title=welcomeBackMessage;welcomeTimer.current=setTimeout(()=>{if(restoreOriginalTitle){document.title=originalTitle.current;}},welcomeBackDuration*1e3);}else if(restoreOriginalTitle){document.title=originalTitle.current;}}};document.addEventListener(\"visibilitychange\",onVisibilityChange);return()=>{document.removeEventListener(\"visibilitychange\",onVisibilityChange);stopAll();// Always restore original title on unmount\ndocument.title=originalTitle.current;};},[messages.join(\"|\"),triggerDelay,messageInterval,maxRotations,enableWelcomeBack,welcomeBackMessage,welcomeBackDuration,restoreOriginalTitle,enableSound]);// Render canvas placeholder in Framer editor; nothing in live site\nreturn /*#__PURE__*/_jsx(EditorPlaceholder,{});}// ── Default Props ─────────────────────────────────────────────────────────────\nBrowserTabNotify.defaultProps={message1:\"👀 Come back! We miss you\",message2:\"🛒 Your cart is waiting\",message3:\"🔥 Don't miss out!\",message4:\"⚡ Limited time offer!\",message5:\"🎁 Something special for you\",messageCount:3,triggerDelay:1.5,messageInterval:2,maxRotations:0,enableWelcomeBack:true,welcomeBackMessage:\"👋 Welcome back!\",welcomeBackDuration:2.5,restoreOriginalTitle:true,enableSound:false};// ── Property Controls (Framer sidebar) ───────────────────────────────────────\naddPropertyControls(BrowserTabNotify,{// ── Away Messages ──────────────────────────────────────────────────────\nmessageCount:{type:ControlType.Number,title:\"# Messages\",min:1,max:5,step:1,displayStepper:true,defaultValue:3,description:\"How many away messages to rotate through.\"},message1:{type:ControlType.String,title:\"Message 1\",defaultValue:\"👀 Come back! We miss you\",placeholder:\"Type a tab message…\"},message2:{type:ControlType.String,title:\"Message 2\",defaultValue:\"🛒 Your cart is waiting\",placeholder:\"Type a tab message…\",hidden:props=>props.messageCount<2},message3:{type:ControlType.String,title:\"Message 3\",defaultValue:\"🔥 Don't miss out!\",placeholder:\"Type a tab message…\",hidden:props=>props.messageCount<3},message4:{type:ControlType.String,title:\"Message 4\",defaultValue:\"⚡ Limited time offer!\",placeholder:\"Type a tab message…\",hidden:props=>props.messageCount<4},message5:{type:ControlType.String,title:\"Message 5\",defaultValue:\"🎁 Something special for you\",placeholder:\"Type a tab message…\",hidden:props=>props.messageCount<5},// ── Timing ─────────────────────────────────────────────────────────────\ntriggerDelay:{type:ControlType.Number,title:\"Trigger Delay\",min:0,max:10,step:.5,unit:\"s\",defaultValue:1.5,description:\"Seconds to wait after tab switch before rotating starts.\"},messageInterval:{type:ControlType.Number,title:\"Msg Interval\",min:.5,max:10,step:.5,unit:\"s\",defaultValue:2,description:\"Seconds each message stays in the tab title.\"},maxRotations:{type:ControlType.Number,title:\"Max Cycles\",min:0,max:20,step:1,displayStepper:true,defaultValue:0,description:\"Full cycles before stopping. 0 = loop forever.\"},// ── Welcome Back ───────────────────────────────────────────────────────\nenableWelcomeBack:{type:ControlType.Boolean,title:\"Welcome Back\",defaultValue:true,enabledTitle:\"On\",disabledTitle:\"Off\",description:\"Show a greeting message when the user returns.\"},welcomeBackMessage:{type:ControlType.String,title:\"↳ Message\",defaultValue:\"👋 Welcome back!\",placeholder:\"Welcome message…\",hidden:props=>!props.enableWelcomeBack},welcomeBackDuration:{type:ControlType.Number,title:\"↳ Duration\",min:.5,max:10,step:.5,unit:\"s\",defaultValue:2.5,hidden:props=>!props.enableWelcomeBack,description:\"How long the welcome message shows before restoring.\"},// ── Behaviour ──────────────────────────────────────────────────────────\nrestoreOriginalTitle:{type:ControlType.Boolean,title:\"Restore Title\",defaultValue:true,enabledTitle:\"Yes\",disabledTitle:\"No\",description:\"Restore the original page title when user returns.\"},enableSound:{type:ControlType.Boolean,title:\"Bell Sound\",defaultValue:false,enabledTitle:\"On\",disabledTitle:\"Off\",description:\"Play a soft bell when the user switches away. Requires user interaction first (browser policy).\"}});\nexport const __FramerMetadata__ = {\"exports\":{\"default\":{\"type\":\"reactComponent\",\"name\":\"BrowserTabNotify\",\"slots\":[],\"annotations\":{\"framerContractVersion\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./BrowserTabNotify.map"],"mappings":"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"}