tour-guide-coach 1.0.0 → 1.0.2

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
@@ -20,7 +20,7 @@
20
20
  ```bash
21
21
  npm install tour-guide-coach
22
22
  # 或从 GitHub
23
- npm install github:2729305948/vue-tour-guide
23
+ npm install github:2729305948/tour-guide-coach
24
24
  ```
25
25
 
26
26
  Peer dependencies:`vue@^3.4`。**零外部依赖,不需要 UI 组件库,不需要 Pinia。**
package/dist/index.cjs CHANGED
@@ -1 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("vue"),K=150,J=12e3,l=t.shallowReactive({active:!1,config:null,stepIndex:0,totalSteps:0,highlightRect:null,targetEl:null,gatePass:!0,waitingTarget:!1,waitTimedOut:!1});let $=null,_=null,h=null,d=null,V=null,k=null,w=null,v=null,x=null,y=null;function O(){var e;return((e=l.config)==null?void 0:e.steps[l.stepIndex])??null}function Q(){return O()}function X(e,o,a){l.active&&b(),l.config=e,l.stepIndex=0,l.totalSteps=e.steps.length,l.gatePass=!0,$=a??null,_=o??null,l.active=!0,W()}function b(){R(),l.active=!1,l.config=null,l.highlightRect=null,l.targetEl=null,_=null,$=null}function L(){R(),l.active=!1,l.highlightRect=null,l.targetEl=null;const e=$;_=null,$=null,e==null||e()}function p(){R();const e=l.config;if(e){if(l.stepIndex>=e.steps.length-1){L();return}l.stepIndex+=1,W()}}function P(){p()}function W(){var a;const e=O();if(!e){L();return}y=e,l.gatePass=!e.gate,l.waitingTarget=!0,l.waitTimedOut=!1,l.highlightRect=null,l.targetEl=null;const o=(a=e.beforeEnter)==null?void 0:a.call(e);o instanceof Promise?o.then(()=>M(e)):requestAnimationFrame(()=>M(e))}function M(e){if(e.trigger==="auto"){l.waitingTarget=!1,et(e);return}if(e.trigger==="wait-dom"){F(e);return}const o=T(e.target);if(o){I(o,e);return}H(e.target,()=>{const a=T(e.target);I(a,e)})}function T(e){if(_){const o=_(e);if(o)return o}try{return document.querySelector(e)}catch{return null}}function I(e,o){if(!e){l.waitTimedOut=!0;return}l.waitingTarget=!1,l.waitTimedOut=!1,l.targetEl=e,N(e),Z(e,o),tt(o),Y(e)}function N(e){const o=e.getBoundingClientRect(),a=6;let i={top:o.top-a,left:o.left-a,width:o.width+a*2,height:o.height+a*2};const s=y==null?void 0:y.expandSelector;if(s){const m=document.querySelectorAll(s);let E=null;for(const u of m)if(u.offsetHeight>0){E=u;break}if(E){const u=E.getBoundingClientRect(),B=Math.min(i.top,u.top-a),f=Math.min(i.left,u.left-a),C=Math.max(i.left+i.width,u.right+a),z=Math.max(i.top+i.height,u.bottom+a);i={top:B,left:f,width:C-f,height:z-B}}}l.highlightRect=i}function Y(e){A(),v=()=>N(e),window.addEventListener("scroll",v,!0),window.addEventListener("resize",v),w=new ResizeObserver(()=>N(e)),w.observe(e),(y==null?void 0:y.expandSelector)&&(x=new MutationObserver(()=>N(e)),x.observe(document.body,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["style","class"]}))}function A(){v&&(window.removeEventListener("scroll",v,!0),window.removeEventListener("resize",v)),v=null,w==null||w.disconnect(),w=null,x==null||x.disconnect(),x=null}function Z(e,o){if(o.trigger==="click"){const a=()=>{e.removeEventListener("click",a);const i=o.clickDelay??350;o.afterClickWait?F({waitForElement:o.afterClickWait,clickDelay:i}):k=setTimeout(()=>p(),i)};e.addEventListener("click",a)}}function tt(e){if(!e.gate){l.gatePass=!0;return}const o=a=>T(a);l.gatePass=e.gate(o),!l.gatePass&&(h=setInterval(()=>{e.gate(o)&&(l.gatePass=!0,h&&(clearInterval(h),h=null))},K))}function F(e){const o=e.waitForElement;if(!o){p();return}if(T(o)){k=setTimeout(()=>p(),e.clickDelay??300);return}H(o,()=>{k=setTimeout(()=>p(),e.clickDelay??300)})}function H(e,o){let a=!1;const i=()=>{a||(a=!0,d==null||d.disconnect(),d=null,o())};d=new MutationObserver(()=>{T(e)&&i()}),d.observe(document.body,{childList:!0,subtree:!0}),V=setTimeout(i,J)}function et(e){k=setTimeout(()=>p(),e.autoDelay??600)}function R(){A(),h&&(clearInterval(h),h=null),d&&(d.disconnect(),d=null),V&&(clearTimeout(V),V=null),k&&(clearTimeout(k),k=null)}const nt={key:0,class:"tour-root"},ot={class:"tp-head"},lt={key:0,class:"tp-required"},it={class:"tp-title"},at={class:"tp-of"},rt={class:"tp-content"},ct={key:0,class:"tp-tip"},st={key:1,class:"tp-warn"},ut={class:"tp-foot"},dt={key:0,class:"tp-click-hint"},pt={key:1,class:"tp-btns"},mt={key:2,class:"tp-gate"},ft={key:2,class:"tour-waiting"},gt={key:0,class:"tg-spin",viewBox:"0 0 1024 1024",width:"28",height:"28",fill:"currentColor"},ht={key:1,viewBox:"0 0 1024 1024",width:"28",height:"28",fill:"#e6a23c"},vt=t.defineComponent({__name:"TourOverlay",setup(e){const o=l;function a(n){n.key==="Escape"&&o.active&&b()}t.watch(()=>o.active,n=>{n?window.addEventListener("keydown",a):window.removeEventListener("keydown",a)}),t.onBeforeUnmount(()=>window.removeEventListener("keydown",a));const i=t.computed(()=>Q()),s=t.computed(()=>o.highlightRect),m=t.computed(()=>{var n,r;return((n=i.value)==null?void 0:n.accent)??((r=o.config)==null?void 0:r.accent)??"#409eff"}),E=t.computed(()=>o.stepIndex>=o.totalSteps-1),u=t.computed(()=>{const n=i.value;return n?!n.gate&&n.trigger==="manual":!1});function B(){const n=s.value;return n?{top:{left:0,top:0,width:"100vw",height:`${Math.max(n.top,0)}px`},bottom:{left:0,top:`${n.top+n.height}px`,width:"100vw",height:`calc(100vh - ${n.top+n.height}px)`},left:{left:0,top:`${n.top}px`,width:`${Math.max(n.left,0)}px`,height:`${n.height}px`},right:{left:`${n.left+n.width}px`,top:`${n.top}px`,width:`calc(100vw - ${n.left+n.width}px)`,height:`${n.height}px`}}:null}const f=t.computed(B),C=t.computed(()=>{var n;return((n=f.value)==null?void 0:n.top)??{display:"none"}}),z=t.computed(()=>{var n;return((n=f.value)==null?void 0:n.bottom)??{display:"none"}}),q=t.computed(()=>{var n;return((n=f.value)==null?void 0:n.left)??{display:"none"}}),G=t.computed(()=>{var n;return((n=f.value)==null?void 0:n.right)??{display:"none"}}),U=t.computed(()=>{const n=s.value;return n?{position:"fixed",top:`${n.top}px`,left:`${n.left}px`,width:`${n.width}px`,height:`${n.height}px`,borderRadius:"8px",border:`2px solid ${m.value}`,boxShadow:`0 0 0 3px ${m.value}33, 0 0 20px ${m.value}44`,pointerEvents:"none",transition:"all 0.35s cubic-bezier(0.4,0,0.2,1)"}:{display:"none"}}),j=t.computed(()=>{var D;const n=s.value;if(!n)return{position:"fixed",top:"50%",left:"50%",transform:"translate(-50%,-50%)"};const r=((D=i.value)==null?void 0:D.placement)??"bottom",g=14,c={position:"fixed",zIndex:100002};switch(r){case"top":return{...c,left:`${n.left}px`,bottom:`calc(100vh - ${n.top-g}px)`,maxWidth:"420px"};case"bottom":return{...c,left:`${n.left}px`,top:`${n.top+n.height+g}px`,maxWidth:"420px"};case"left":return{...c,right:`calc(100vw - ${n.left-g}px)`,top:`${n.top}px`,maxWidth:"360px"};case"right":return{...c,left:`${n.left+n.width+g}px`,top:`${n.top}px`,maxWidth:"360px"};default:return{...c,top:"50%",left:"50%",transform:"translate(-50%,-50%)",maxWidth:"480px"}}});function S(){}return(n,r)=>{var g;return t.openBlock(),t.createBlock(t.Teleport,{to:"body"},[t.unref(o).active?(t.openBlock(),t.createElementBlock("div",nt,[t.createElementVNode("div",{class:"tour-mask",style:t.normalizeStyle(C.value),onClick:S},null,4),t.createElementVNode("div",{class:"tour-mask",style:t.normalizeStyle(z.value),onClick:S},null,4),t.createElementVNode("div",{class:"tour-mask",style:t.normalizeStyle(q.value),onClick:S},null,4),t.createElementVNode("div",{class:"tour-mask",style:t.normalizeStyle(G.value),onClick:S},null,4),s.value?(t.openBlock(),t.createElementBlock("div",{key:0,class:"tour-highlight",style:t.normalizeStyle(U.value)},null,4)):t.createCommentVNode("",!0),i.value&&!t.unref(o).waitingTarget?(t.openBlock(),t.createElementBlock("div",{key:1,class:"tour-popover",style:t.normalizeStyle(j.value)},[t.createElementVNode("div",ot,[t.createElementVNode("span",{class:"tp-step-no",style:t.normalizeStyle({background:m.value})},t.toDisplayString(t.unref(o).stepIndex+1),5),i.value.gate?(t.openBlock(),t.createElementBlock("span",lt,"*")):t.createCommentVNode("",!0),t.createElementVNode("span",it,t.toDisplayString(i.value.title),1),t.createElementVNode("span",at,"第 "+t.toDisplayString(t.unref(o).stepIndex+1)+" / "+t.toDisplayString(t.unref(o).totalSteps)+" 步",1)]),t.createElementVNode("p",rt,t.toDisplayString(i.value.content),1),i.value.tip?(t.openBlock(),t.createElementBlock("div",ct,"💡 "+t.toDisplayString(i.value.tip),1)):t.createCommentVNode("",!0),i.value.warn?(t.openBlock(),t.createElementBlock("div",st,"⚠️ "+t.toDisplayString(i.value.warn),1)):t.createCommentVNode("",!0),t.createElementVNode("div",ut,[t.createElementVNode("button",{class:"tg-btn tg-btn--link tg-btn--sm",onClick:r[0]||(r[0]=c=>t.unref(b)())},"退出引导"),i.value.trigger==="click"?(t.openBlock(),t.createElementBlock("span",dt," 👆 请点击高亮区域 ")):t.unref(o).gatePass?(t.openBlock(),t.createElementBlock("span",pt,[u.value?(t.openBlock(),t.createElementBlock("button",{key:0,class:"tg-btn tg-btn--sm",onClick:r[1]||(r[1]=c=>t.unref(P)())},"跳过此步")):t.createCommentVNode("",!0),t.createElementVNode("button",{class:"tg-btn tg-btn--primary tg-btn--sm",style:t.normalizeStyle({background:m.value,borderColor:m.value}),onClick:r[2]||(r[2]=c=>t.unref(p)())},t.toDisplayString(E.value?"完成":"下一步"),5)])):(t.openBlock(),t.createElementBlock("span",mt,[r[5]||(r[5]=t.createElementVNode("svg",{class:"tp-gate-icon",viewBox:"0 0 1024 1024",width:"14",height:"14",fill:"currentColor"},[t.createElementVNode("path",{d:"M512 160a96 96 0 0 1 96 96v64H416v-64a96 96 0 0 1 96-96zm0-64a160 160 0 0 0-160 160v64h-32a64 64 0 0 0-64 64v384a64 64 0 0 0 64 64h384a64 64 0 0 0 64-64V384a64 64 0 0 0-64-64h-32v-64A160 160 0 0 0 512 96zM320 448h384v320H320V448z"})],-1)),t.createTextVNode(" "+t.toDisplayString(i.value.gateHint||"请先完成本步操作"),1)]))])],4)):t.createCommentVNode("",!0),t.unref(o).waitingTarget?(t.openBlock(),t.createElementBlock("div",ft,[t.unref(o).waitTimedOut?(t.openBlock(),t.createElementBlock("svg",ht,[...r[7]||(r[7]=[t.createElementVNode("path",{d:"M512 64L64 896h896L512 64zm0 192l288 576H224l288-576zm-32 224v128h64V480h-64zm0 160v64h64v-64h-64z"},null,-1)])])):(t.openBlock(),t.createElementBlock("svg",gt,[...r[6]||(r[6]=[t.createElementVNode("path",{d:"M512 64a448 448 0 1 1 0 896 448 448 0 0 1 0-896zm0 64a384 384 0 1 0 0 768 384 384 0 0 0 0-768z",opacity:".25"},null,-1),t.createElementVNode("path",{d:"M512 64a448 448 0 0 1 448 448h-64A384 384 0 0 0 512 128V64z"},null,-1)])])),t.createElementVNode("p",null,t.toDisplayString(t.unref(o).waitTimedOut?"未找到目标元素,可能是页面状态不符":((g=i.value)==null?void 0:g.content)??"等待页面加载..."),1),t.unref(o).waitTimedOut?(t.openBlock(),t.createElementBlock("button",{key:2,class:"tg-btn tg-btn--warning tg-btn--sm",onClick:r[3]||(r[3]=c=>t.unref(p)())},"跳过此步")):t.createCommentVNode("",!0),t.createElementVNode("button",{class:"tg-btn tg-btn--sm",onClick:r[4]||(r[4]=c=>t.unref(b)())},"退出引导")])):t.createCommentVNode("",!0)])):t.createCommentVNode("",!0)])}}}),kt=(e,o)=>{const a=e.__vccOpts||e;for(const[i,s]of o)a[i]=s;return a},yt=kt(vt,[["__scopeId","data-v-9602901d"]]);exports.TourOverlay=yt;exports.abort=b;exports.complete=L;exports.next=p;exports.skip=P;exports.startTour=X;exports.tourState=l;
1
+ (function(){"use strict";try{if(typeof document<"u"){var t=document.createElement("style");t.appendChild(document.createTextNode(".tour-root{--tg-primary: var(--el-color-primary, #409eff);--tg-success: var(--el-color-success, #67c23a);--tg-warning: var(--el-color-warning, #e6a23c);--tg-danger: var(--el-color-danger, #f56c6c);--tg-text-1: var(--el-text-color-primary, #303133);--tg-text-2: var(--el-text-color-regular, #606266);--tg-text-3: var(--el-text-color-secondary, #909399);--tg-border: var(--el-border-color-lighter, #ebeef5);--tg-fill-light: var(--el-fill-color-light, #f5f7fa);--tg-radius: var(--el-border-radius-base, 4px);position:fixed;top:0;right:0;bottom:0;left:0;z-index:100000;pointer-events:none;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,sans-serif}.tour-mask{position:fixed;background:#0000008c;transition:all .35s cubic-bezier(.4,0,.2,1);cursor:not-allowed;pointer-events:auto}.tour-highlight{z-index:100001}.tg-btn{display:inline-flex;align-items:center;justify-content:center;border:1px solid var(--tg-border);border-radius:var(--tg-radius);background:#fff;color:var(--tg-text-2);font-size:14px;font-weight:500;line-height:1;padding:8px 15px;cursor:pointer;transition:color .2s,border-color .2s,background .2s;outline:none;white-space:nowrap;-webkit-user-select:none;user-select:none}.tg-btn:hover{color:var(--tg-primary);border-color:var(--tg-primary);background:#ecf5ff}.tg-btn--sm{padding:5px 11px;font-size:12px}.tg-btn--primary{background:var(--tg-primary);border-color:var(--tg-primary);color:#fff}.tg-btn--primary:hover{opacity:.85;background:var(--tg-primary);color:#fff}.tg-btn--warning{background:var(--tg-warning);border-color:var(--tg-warning);color:#fff}.tg-btn--warning:hover{opacity:.85;background:var(--tg-warning);color:#fff}.tg-btn--link{border:none;background:none;padding:4px 6px;color:var(--tg-text-3)}.tg-btn--link:hover{color:var(--tg-primary);background:none}.tour-popover{z-index:100002;background:#fff;border-radius:12px;padding:20px 24px;box-shadow:0 8px 40px #0000001f,0 2px 8px #0000000f;animation:tp-in .3s ease;pointer-events:auto;min-width:280px;max-width:420px}@keyframes tp-in{0%{opacity:0;transform:translateY(6px) scale(.97)}to{opacity:1;transform:translateY(0) scale(1)}}.tp-head{display:flex;align-items:center;gap:10px;margin-bottom:12px}.tp-step-no{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:50%;color:#fff;font-size:14px;font-weight:700;flex-shrink:0}.tp-required{color:var(--tg-danger);font-size:20px;font-weight:700;line-height:1}.tp-title{font-size:16px;font-weight:700;color:var(--tg-text-1)}.tp-of{font-size:13px;color:var(--tg-text-3);margin-left:auto;font-variant-numeric:tabular-nums}.tp-content{margin:0 0 14px;font-size:14px;line-height:1.8;color:var(--tg-text-2);white-space:pre-line}.tp-tip{font-size:13px;color:#529b2e;background:#f0f9eb;padding:8px 12px;border-radius:6px;margin-bottom:10px;border-left:3px solid #67c23a}.tp-warn{font-size:13px;color:#b88230;background:#fdf6ec;padding:8px 12px;border-radius:6px;margin-bottom:10px;border-left:3px solid #e6a23c}.tp-foot{display:flex;align-items:center;justify-content:space-between;padding-top:14px;border-top:1px solid var(--tg-border)}.tp-btns{display:flex;gap:10px}.tp-gate{display:inline-flex;align-items:center;gap:5px;font-size:13px;color:var(--tg-warning);font-weight:500}.tp-gate-icon{flex-shrink:0}.tp-click-hint{font-size:14px;color:var(--tg-primary);font-weight:500;animation:pulse-hint 1.5s ease-in-out infinite}@keyframes pulse-hint{0%,to{opacity:1}50%{opacity:.5}}.tour-waiting{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:100002;background:#fff;padding:32px 40px;border-radius:12px;box-shadow:0 8px 32px #00000026;text-align:center;pointer-events:auto;display:flex;flex-direction:column;align-items:center;gap:8px}.tour-waiting p{margin:4px 0 8px;font-size:14px;color:var(--tg-text-2)}.tg-spin{animation:tg-rotate 1s linear infinite}@keyframes tg-rotate{0%{transform:rotate(0)}to{transform:rotate(360deg)}}")),document.head.appendChild(t)}}catch(e){console.error("vite-plugin-css-injected-by-js",e)}})();
2
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),J=150,Q=12e3,o=e.shallowReactive({active:!1,config:null,stepIndex:0,totalSteps:0,highlightRect:null,targetEl:null,gatePass:!0,waitingTarget:!1,waitTimedOut:!1});let $=null,T=null,h=null,u=null,V=null,k=null,w=null,v=null,x=null,y=null;function O(){var t;return((t=o.config)==null?void 0:t.steps[o.stepIndex])??null}function P(){return O()}function X(t,l,a){o.active&&b(),o.config=t,o.stepIndex=0,o.totalSteps=t.steps.length,o.gatePass=!0,$=a??null,T=l??null,o.active=!0,A()}function b(){R(),o.active=!1,o.config=null,o.highlightRect=null,o.targetEl=null,T=null,$=null}function L(){R(),o.active=!1,o.highlightRect=null,o.targetEl=null;const t=$;T=null,$=null,t==null||t()}function d(){R();const t=o.config;if(t){if(o.stepIndex>=t.steps.length-1){L();return}o.stepIndex+=1,A()}}function W(){d()}function A(){var a;const t=O();if(!t){L();return}y=t,o.gatePass=!t.gate,o.waitingTarget=!0,o.waitTimedOut=!1,o.highlightRect=null,o.targetEl=null;const l=(a=t.beforeEnter)==null?void 0:a.call(t);l instanceof Promise?l.then(()=>M(t)):requestAnimationFrame(()=>M(t))}function M(t){if(t.trigger==="auto"){o.waitingTarget=!1,te(t);return}if(t.trigger==="wait-dom"){H(t);return}const l=_(t.target);if(l){I(l,t);return}q(t.target,()=>{const a=_(t.target);I(a,t)})}function _(t){if(T){const l=T(t);if(l)return l}try{return document.querySelector(t)}catch{return null}}function I(t,l){if(!t){o.waitTimedOut=!0;return}o.waitingTarget=!1,o.waitTimedOut=!1,o.targetEl=t,N(t),Z(t,l),ee(l),Y(t)}function N(t){const l=t.getBoundingClientRect(),a=6;let i={top:l.top-a,left:l.left-a,width:l.width+a*2,height:l.height+a*2};const m=y==null?void 0:y.expandSelector;if(m){const p=document.querySelectorAll(m);let E=null;for(const s of p)if(s.offsetHeight>0){E=s;break}if(E){const s=E.getBoundingClientRect(),B=Math.min(i.top,s.top-a),f=Math.min(i.left,s.left-a),C=Math.max(i.left+i.width,s.right+a),z=Math.max(i.top+i.height,s.bottom+a);i={top:B,left:f,width:C-f,height:z-B}}}o.highlightRect=i}function Y(t){F(),v=()=>N(t),window.addEventListener("scroll",v,!0),window.addEventListener("resize",v),w=new ResizeObserver(()=>N(t)),w.observe(t),(y==null?void 0:y.expandSelector)&&(x=new MutationObserver(()=>N(t)),x.observe(document.body,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["style","class"]}))}function F(){v&&(window.removeEventListener("scroll",v,!0),window.removeEventListener("resize",v)),v=null,w==null||w.disconnect(),w=null,x==null||x.disconnect(),x=null}function Z(t,l){if(l.trigger==="click"){const a=()=>{t.removeEventListener("click",a);const i=l.clickDelay??350;l.afterClickWait?H({waitForElement:l.afterClickWait,clickDelay:i}):k=setTimeout(()=>d(),i)};t.addEventListener("click",a)}}function ee(t){if(!t.gate){o.gatePass=!0;return}const l=a=>_(a);o.gatePass=t.gate(l),!o.gatePass&&(h=setInterval(()=>{t.gate(l)&&(o.gatePass=!0,h&&(clearInterval(h),h=null))},J))}function H(t){const l=t.waitForElement;if(!l){d();return}if(_(l)){k=setTimeout(()=>d(),t.clickDelay??300);return}q(l,()=>{k=setTimeout(()=>d(),t.clickDelay??300)})}function q(t,l){let a=!1;const i=()=>{a||(a=!0,u==null||u.disconnect(),u=null,l())};u=new MutationObserver(()=>{_(t)&&i()}),u.observe(document.body,{childList:!0,subtree:!0}),V=setTimeout(i,Q)}function te(t){k=setTimeout(()=>d(),t.autoDelay??600)}function R(){F(),h&&(clearInterval(h),h=null),u&&(u.disconnect(),u=null),V&&(clearTimeout(V),V=null),k&&(clearTimeout(k),k=null)}const ne={key:0,class:"tour-root"},le={class:"tp-head"},oe={key:0,class:"tp-required"},ie={class:"tp-title"},ae={class:"tp-of"},re={class:"tp-content"},ce={key:0,class:"tp-tip"},se={key:1,class:"tp-warn"},ue={class:"tp-foot"},de={key:0,class:"tp-click-hint"},pe={key:1,class:"tp-btns"},me={key:2,class:"tp-gate"},fe={key:2,class:"tour-waiting"},ge={key:0,class:"tg-spin",viewBox:"0 0 1024 1024",width:"28",height:"28",fill:"currentColor"},he={key:1,viewBox:"0 0 1024 1024",width:"28",height:"28",fill:"#e6a23c"},ve=e.defineComponent({__name:"TourOverlay",setup(t){const l=o;function a(n){n.key==="Escape"&&l.active&&b()}e.watch(()=>l.active,n=>{n?window.addEventListener("keydown",a):window.removeEventListener("keydown",a)}),e.onBeforeUnmount(()=>window.removeEventListener("keydown",a));const i=e.computed(()=>P()),m=e.computed(()=>l.highlightRect),p=e.computed(()=>{var n,r;return((n=i.value)==null?void 0:n.accent)??((r=l.config)==null?void 0:r.accent)??"#409eff"}),E=e.computed(()=>l.stepIndex>=l.totalSteps-1),s=e.computed(()=>{const n=i.value;return n?!n.gate&&n.trigger==="manual":!1});function B(){const n=m.value;return n?{top:{left:0,top:0,width:"100vw",height:`${Math.max(n.top,0)}px`},bottom:{left:0,top:`${n.top+n.height}px`,width:"100vw",height:`calc(100vh - ${n.top+n.height}px)`},left:{left:0,top:`${n.top}px`,width:`${Math.max(n.left,0)}px`,height:`${n.height}px`},right:{left:`${n.left+n.width}px`,top:`${n.top}px`,width:`calc(100vw - ${n.left+n.width}px)`,height:`${n.height}px`}}:null}const f=e.computed(B),C=e.computed(()=>{var n;return((n=f.value)==null?void 0:n.top)??{display:"none"}}),z=e.computed(()=>{var n;return((n=f.value)==null?void 0:n.bottom)??{display:"none"}}),G=e.computed(()=>{var n;return((n=f.value)==null?void 0:n.left)??{display:"none"}}),U=e.computed(()=>{var n;return((n=f.value)==null?void 0:n.right)??{display:"none"}}),j=e.computed(()=>{const n=m.value;return n?{position:"fixed",top:`${n.top}px`,left:`${n.left}px`,width:`${n.width}px`,height:`${n.height}px`,borderRadius:"8px",border:`2px solid ${p.value}`,boxShadow:`0 0 0 3px ${p.value}33, 0 0 20px ${p.value}44`,pointerEvents:"none",transition:"all 0.35s cubic-bezier(0.4,0,0.2,1)"}:{display:"none"}}),K=e.computed(()=>{var D;const n=m.value;if(!n)return{position:"fixed",top:"50%",left:"50%",transform:"translate(-50%,-50%)"};const r=((D=i.value)==null?void 0:D.placement)??"bottom",g=14,c={position:"fixed",zIndex:100002};switch(r){case"top":return{...c,left:`${n.left}px`,bottom:`calc(100vh - ${n.top-g}px)`,maxWidth:"420px"};case"bottom":return{...c,left:`${n.left}px`,top:`${n.top+n.height+g}px`,maxWidth:"420px"};case"left":return{...c,right:`calc(100vw - ${n.left-g}px)`,top:`${n.top}px`,maxWidth:"360px"};case"right":return{...c,left:`${n.left+n.width+g}px`,top:`${n.top}px`,maxWidth:"360px"};default:return{...c,top:"50%",left:"50%",transform:"translate(-50%,-50%)",maxWidth:"480px"}}});function S(){}return(n,r)=>{var g;return e.openBlock(),e.createBlock(e.Teleport,{to:"body"},[e.unref(l).active?(e.openBlock(),e.createElementBlock("div",ne,[e.createElementVNode("div",{class:"tour-mask",style:e.normalizeStyle(C.value),onClick:S},null,4),e.createElementVNode("div",{class:"tour-mask",style:e.normalizeStyle(z.value),onClick:S},null,4),e.createElementVNode("div",{class:"tour-mask",style:e.normalizeStyle(G.value),onClick:S},null,4),e.createElementVNode("div",{class:"tour-mask",style:e.normalizeStyle(U.value),onClick:S},null,4),m.value?(e.openBlock(),e.createElementBlock("div",{key:0,class:"tour-highlight",style:e.normalizeStyle(j.value)},null,4)):e.createCommentVNode("",!0),i.value&&!e.unref(l).waitingTarget?(e.openBlock(),e.createElementBlock("div",{key:1,class:"tour-popover",style:e.normalizeStyle(K.value)},[e.createElementVNode("div",le,[e.createElementVNode("span",{class:"tp-step-no",style:e.normalizeStyle({background:p.value})},e.toDisplayString(e.unref(l).stepIndex+1),5),i.value.gate?(e.openBlock(),e.createElementBlock("span",oe,"*")):e.createCommentVNode("",!0),e.createElementVNode("span",ie,e.toDisplayString(i.value.title),1),e.createElementVNode("span",ae,"第 "+e.toDisplayString(e.unref(l).stepIndex+1)+" / "+e.toDisplayString(e.unref(l).totalSteps)+" 步",1)]),e.createElementVNode("p",re,e.toDisplayString(i.value.content),1),i.value.tip?(e.openBlock(),e.createElementBlock("div",ce,"💡 "+e.toDisplayString(i.value.tip),1)):e.createCommentVNode("",!0),i.value.warn?(e.openBlock(),e.createElementBlock("div",se,"⚠️ "+e.toDisplayString(i.value.warn),1)):e.createCommentVNode("",!0),e.createElementVNode("div",ue,[e.createElementVNode("button",{class:"tg-btn tg-btn--link tg-btn--sm",onClick:r[0]||(r[0]=c=>e.unref(b)())},"退出引导"),i.value.trigger==="click"?(e.openBlock(),e.createElementBlock("span",de," 👆 请点击高亮区域 ")):e.unref(l).gatePass?(e.openBlock(),e.createElementBlock("span",pe,[s.value?(e.openBlock(),e.createElementBlock("button",{key:0,class:"tg-btn tg-btn--sm",onClick:r[1]||(r[1]=c=>e.unref(W)())},"跳过此步")):e.createCommentVNode("",!0),e.createElementVNode("button",{class:"tg-btn tg-btn--primary tg-btn--sm",style:e.normalizeStyle({background:p.value,borderColor:p.value}),onClick:r[2]||(r[2]=c=>e.unref(d)())},e.toDisplayString(E.value?"完成":"下一步"),5)])):(e.openBlock(),e.createElementBlock("span",me,[r[5]||(r[5]=e.createElementVNode("svg",{class:"tp-gate-icon",viewBox:"0 0 1024 1024",width:"14",height:"14",fill:"currentColor"},[e.createElementVNode("path",{d:"M512 160a96 96 0 0 1 96 96v64H416v-64a96 96 0 0 1 96-96zm0-64a160 160 0 0 0-160 160v64h-32a64 64 0 0 0-64 64v384a64 64 0 0 0 64 64h384a64 64 0 0 0 64-64V384a64 64 0 0 0-64-64h-32v-64A160 160 0 0 0 512 96zM320 448h384v320H320V448z"})],-1)),e.createTextVNode(" "+e.toDisplayString(i.value.gateHint||"请先完成本步操作"),1)]))])],4)):e.createCommentVNode("",!0),e.unref(l).waitingTarget?(e.openBlock(),e.createElementBlock("div",fe,[e.unref(l).waitTimedOut?(e.openBlock(),e.createElementBlock("svg",he,[...r[7]||(r[7]=[e.createElementVNode("path",{d:"M512 64L64 896h896L512 64zm0 192l288 576H224l288-576zm-32 224v128h64V480h-64zm0 160v64h64v-64h-64z"},null,-1)])])):(e.openBlock(),e.createElementBlock("svg",ge,[...r[6]||(r[6]=[e.createElementVNode("path",{d:"M512 64a448 448 0 1 1 0 896 448 448 0 0 1 0-896zm0 64a384 384 0 1 0 0 768 384 384 0 0 0 0-768z",opacity:".25"},null,-1),e.createElementVNode("path",{d:"M512 64a448 448 0 0 1 448 448h-64A384 384 0 0 0 512 128V64z"},null,-1)])])),e.createElementVNode("p",null,e.toDisplayString(e.unref(l).waitTimedOut?"未找到目标元素,可能是页面状态不符":((g=i.value)==null?void 0:g.content)??"等待页面加载..."),1),e.unref(l).waitTimedOut?(e.openBlock(),e.createElementBlock("button",{key:2,class:"tg-btn tg-btn--warning tg-btn--sm",onClick:r[3]||(r[3]=c=>e.unref(d)())},"跳过此步")):e.createCommentVNode("",!0),e.createElementVNode("button",{class:"tg-btn tg-btn--sm",onClick:r[4]||(r[4]=c=>e.unref(b)())},"退出引导")])):e.createCommentVNode("",!0)])):e.createCommentVNode("",!0)])}}});exports.TourOverlay=ve;exports.abort=b;exports.complete=L;exports.currentStep=P;exports.next=d;exports.skip=W;exports.startTour=X;exports.tourState=o;
package/dist/index.d.ts CHANGED
@@ -4,11 +4,12 @@
4
4
  * 零外部依赖(仅需 Vue 3),全局单例模式。
5
5
  *
6
6
  * 使用方式:
7
- * import { tourState, startTour, abort, TourOverlay } from 'vue-tour-guide'
7
+ * import { startTour, TourOverlay } from 'tour-guide-coach'
8
8
  * // 在 layout 中挂 <TourOverlay />
9
9
  * // 业务页调用 startTour(config)
10
+ * // CSS 已内联到 JS,无需手动引入样式文件
10
11
  */
11
- export { tourState, startTour, abort, next, skip, complete } from './store';
12
+ export { tourState, startTour, abort, next, skip, complete, currentStep } from './store';
12
13
  export type { TargetResolver } from './store';
13
14
  export { default as TourOverlay } from './TourOverlay.vue';
14
15
  export type { TourConfig, TourStep, StepTrigger, PopPlacement, HighlightRect } from './types';
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
- import { shallowReactive as tt, defineComponent as et, watch as nt, onBeforeUnmount as lt, computed as d, openBlock as r, createBlock as ot, Teleport as it, unref as c, createElementBlock as u, createElementVNode as s, normalizeStyle as x, createCommentVNode as v, toDisplayString as p, createTextVNode as at } from "vue";
1
+ (function(){"use strict";try{if(typeof document<"u"){var t=document.createElement("style");t.appendChild(document.createTextNode(".tour-root{--tg-primary: var(--el-color-primary, #409eff);--tg-success: var(--el-color-success, #67c23a);--tg-warning: var(--el-color-warning, #e6a23c);--tg-danger: var(--el-color-danger, #f56c6c);--tg-text-1: var(--el-text-color-primary, #303133);--tg-text-2: var(--el-text-color-regular, #606266);--tg-text-3: var(--el-text-color-secondary, #909399);--tg-border: var(--el-border-color-lighter, #ebeef5);--tg-fill-light: var(--el-fill-color-light, #f5f7fa);--tg-radius: var(--el-border-radius-base, 4px);position:fixed;top:0;right:0;bottom:0;left:0;z-index:100000;pointer-events:none;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,sans-serif}.tour-mask{position:fixed;background:#0000008c;transition:all .35s cubic-bezier(.4,0,.2,1);cursor:not-allowed;pointer-events:auto}.tour-highlight{z-index:100001}.tg-btn{display:inline-flex;align-items:center;justify-content:center;border:1px solid var(--tg-border);border-radius:var(--tg-radius);background:#fff;color:var(--tg-text-2);font-size:14px;font-weight:500;line-height:1;padding:8px 15px;cursor:pointer;transition:color .2s,border-color .2s,background .2s;outline:none;white-space:nowrap;-webkit-user-select:none;user-select:none}.tg-btn:hover{color:var(--tg-primary);border-color:var(--tg-primary);background:#ecf5ff}.tg-btn--sm{padding:5px 11px;font-size:12px}.tg-btn--primary{background:var(--tg-primary);border-color:var(--tg-primary);color:#fff}.tg-btn--primary:hover{opacity:.85;background:var(--tg-primary);color:#fff}.tg-btn--warning{background:var(--tg-warning);border-color:var(--tg-warning);color:#fff}.tg-btn--warning:hover{opacity:.85;background:var(--tg-warning);color:#fff}.tg-btn--link{border:none;background:none;padding:4px 6px;color:var(--tg-text-3)}.tg-btn--link:hover{color:var(--tg-primary);background:none}.tour-popover{z-index:100002;background:#fff;border-radius:12px;padding:20px 24px;box-shadow:0 8px 40px #0000001f,0 2px 8px #0000000f;animation:tp-in .3s ease;pointer-events:auto;min-width:280px;max-width:420px}@keyframes tp-in{0%{opacity:0;transform:translateY(6px) scale(.97)}to{opacity:1;transform:translateY(0) scale(1)}}.tp-head{display:flex;align-items:center;gap:10px;margin-bottom:12px}.tp-step-no{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:50%;color:#fff;font-size:14px;font-weight:700;flex-shrink:0}.tp-required{color:var(--tg-danger);font-size:20px;font-weight:700;line-height:1}.tp-title{font-size:16px;font-weight:700;color:var(--tg-text-1)}.tp-of{font-size:13px;color:var(--tg-text-3);margin-left:auto;font-variant-numeric:tabular-nums}.tp-content{margin:0 0 14px;font-size:14px;line-height:1.8;color:var(--tg-text-2);white-space:pre-line}.tp-tip{font-size:13px;color:#529b2e;background:#f0f9eb;padding:8px 12px;border-radius:6px;margin-bottom:10px;border-left:3px solid #67c23a}.tp-warn{font-size:13px;color:#b88230;background:#fdf6ec;padding:8px 12px;border-radius:6px;margin-bottom:10px;border-left:3px solid #e6a23c}.tp-foot{display:flex;align-items:center;justify-content:space-between;padding-top:14px;border-top:1px solid var(--tg-border)}.tp-btns{display:flex;gap:10px}.tp-gate{display:inline-flex;align-items:center;gap:5px;font-size:13px;color:var(--tg-warning);font-weight:500}.tp-gate-icon{flex-shrink:0}.tp-click-hint{font-size:14px;color:var(--tg-primary);font-weight:500;animation:pulse-hint 1.5s ease-in-out infinite}@keyframes pulse-hint{0%,to{opacity:1}50%{opacity:.5}}.tour-waiting{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:100002;background:#fff;padding:32px 40px;border-radius:12px;box-shadow:0 8px 32px #00000026;text-align:center;pointer-events:auto;display:flex;flex-direction:column;align-items:center;gap:8px}.tour-waiting p{margin:4px 0 8px;font-size:14px;color:var(--tg-text-2)}.tg-spin{animation:tg-rotate 1s linear infinite}@keyframes tg-rotate{0%{transform:rotate(0)}to{transform:rotate(360deg)}}")),document.head.appendChild(t)}}catch(e){console.error("vite-plugin-css-injected-by-js",e)}})();
2
+ import { shallowReactive as tt, defineComponent as et, watch as nt, onBeforeUnmount as lt, computed as d, openBlock as r, createBlock as it, Teleport as ot, unref as c, createElementBlock as u, createElementVNode as s, normalizeStyle as w, createCommentVNode as h, toDisplayString as p, createTextVNode as at } from "vue";
2
3
  const st = 150, rt = 12e3, l = tt({
3
4
  active: !1,
4
5
  config: null,
@@ -10,7 +11,7 @@ const st = 150, rt = 12e3, l = tt({
10
11
  waitingTarget: !1,
11
12
  waitTimedOut: !1
12
13
  });
13
- let W = null, S = null, _ = null, m = null, O = null, $ = null, C = null, T = null, L = null, E = null;
14
+ let W = null, S = null, T = null, v = null, B = null, $ = null, C = null, _ = null, L = null, E = null;
14
15
  function q() {
15
16
  var t;
16
17
  return ((t = l.config) == null ? void 0 : t.steps[l.stepIndex]) ?? null;
@@ -18,10 +19,10 @@ function q() {
18
19
  function ct() {
19
20
  return q();
20
21
  }
21
- function zt(t, n, i) {
22
- l.active && B(), l.config = t, l.stepIndex = 0, l.totalSteps = t.steps.length, l.gatePass = !0, W = i ?? null, S = n ?? null, l.active = !0, U();
22
+ function Mt(t, n, o) {
23
+ l.active && O(), l.config = t, l.stepIndex = 0, l.totalSteps = t.steps.length, l.gatePass = !0, W = o ?? null, S = n ?? null, l.active = !0, U();
23
24
  }
24
- function B() {
25
+ function O() {
25
26
  V(), l.active = !1, l.config = null, l.highlightRect = null, l.targetEl = null, S = null, W = null;
26
27
  }
27
28
  function G() {
@@ -29,7 +30,7 @@ function G() {
29
30
  const t = W;
30
31
  S = null, W = null, t == null || t();
31
32
  }
32
- function k() {
33
+ function x() {
33
34
  V();
34
35
  const t = l.config;
35
36
  if (t) {
@@ -41,17 +42,17 @@ function k() {
41
42
  }
42
43
  }
43
44
  function ut() {
44
- k();
45
+ x();
45
46
  }
46
47
  function U() {
47
- var i;
48
+ var o;
48
49
  const t = q();
49
50
  if (!t) {
50
51
  G();
51
52
  return;
52
53
  }
53
54
  E = t, l.gatePass = !t.gate, l.waitingTarget = !0, l.waitTimedOut = !1, l.highlightRect = null, l.targetEl = null;
54
- const n = (i = t.beforeEnter) == null ? void 0 : i.call(t);
55
+ const n = (o = t.beforeEnter) == null ? void 0 : o.call(t);
55
56
  n instanceof Promise ? n.then(() => H(t)) : requestAnimationFrame(() => H(t));
56
57
  }
57
58
  function H(t) {
@@ -63,17 +64,17 @@ function H(t) {
63
64
  j(t);
64
65
  return;
65
66
  }
66
- const n = I(t.target);
67
+ const n = M(t.target);
67
68
  if (n) {
68
69
  N(n, t);
69
70
  return;
70
71
  }
71
72
  J(t.target, () => {
72
- const i = I(t.target);
73
- N(i, t);
73
+ const o = M(t.target);
74
+ N(o, t);
74
75
  });
75
76
  }
76
- function I(t) {
77
+ function M(t) {
77
78
  if (S) {
78
79
  const n = S(t);
79
80
  if (n) return n;
@@ -92,43 +93,43 @@ function N(t, n) {
92
93
  l.waitingTarget = !1, l.waitTimedOut = !1, l.targetEl = t, P(t), ft(t, n), pt(n), dt(t);
93
94
  }
94
95
  function P(t) {
95
- const n = t.getBoundingClientRect(), i = 6;
96
- let o = {
97
- top: n.top - i,
98
- left: n.left - i,
99
- width: n.width + i * 2,
100
- height: n.height + i * 2
96
+ const n = t.getBoundingClientRect(), o = 6;
97
+ let i = {
98
+ top: n.top - o,
99
+ left: n.left - o,
100
+ width: n.width + o * 2,
101
+ height: n.height + o * 2
101
102
  };
102
- const g = E == null ? void 0 : E.expandSelector;
103
- if (g) {
104
- const w = document.querySelectorAll(g);
103
+ const k = E == null ? void 0 : E.expandSelector;
104
+ if (k) {
105
+ const m = document.querySelectorAll(k);
105
106
  let R = null;
106
- for (const h of w)
107
- if (h.offsetHeight > 0) {
108
- R = h;
107
+ for (const g of m)
108
+ if (g.offsetHeight > 0) {
109
+ R = g;
109
110
  break;
110
111
  }
111
112
  if (R) {
112
- const h = R.getBoundingClientRect(), M = Math.min(o.top, h.top - i), y = Math.min(o.left, h.left - i), A = Math.max(o.left + o.width, h.right + i), D = Math.max(o.top + o.height, h.bottom + i);
113
- o = { top: M, left: y, width: A - y, height: D - M };
113
+ const g = R.getBoundingClientRect(), z = Math.min(i.top, g.top - o), y = Math.min(i.left, g.left - o), A = Math.max(i.left + i.width, g.right + o), D = Math.max(i.top + i.height, g.bottom + o);
114
+ i = { top: z, left: y, width: A - y, height: D - z };
114
115
  }
115
116
  }
116
- l.highlightRect = o;
117
+ l.highlightRect = i;
117
118
  }
118
119
  function dt(t) {
119
- K(), T = () => P(t), window.addEventListener("scroll", T, !0), window.addEventListener("resize", T), C = new ResizeObserver(() => P(t)), C.observe(t), (E == null ? void 0 : E.expandSelector) && (L = new MutationObserver(() => P(t)), L.observe(document.body, { childList: !0, subtree: !0, attributes: !0, attributeFilter: ["style", "class"] }));
120
+ K(), _ = () => P(t), window.addEventListener("scroll", _, !0), window.addEventListener("resize", _), C = new ResizeObserver(() => P(t)), C.observe(t), (E == null ? void 0 : E.expandSelector) && (L = new MutationObserver(() => P(t)), L.observe(document.body, { childList: !0, subtree: !0, attributes: !0, attributeFilter: ["style", "class"] }));
120
121
  }
121
122
  function K() {
122
- T && (window.removeEventListener("scroll", T, !0), window.removeEventListener("resize", T)), T = null, C == null || C.disconnect(), C = null, L == null || L.disconnect(), L = null;
123
+ _ && (window.removeEventListener("scroll", _, !0), window.removeEventListener("resize", _)), _ = null, C == null || C.disconnect(), C = null, L == null || L.disconnect(), L = null;
123
124
  }
124
125
  function ft(t, n) {
125
126
  if (n.trigger === "click") {
126
- const i = () => {
127
- t.removeEventListener("click", i);
128
- const o = n.clickDelay ?? 350;
129
- n.afterClickWait ? j({ waitForElement: n.afterClickWait, clickDelay: o }) : $ = setTimeout(() => k(), o);
127
+ const o = () => {
128
+ t.removeEventListener("click", o);
129
+ const i = n.clickDelay ?? 350;
130
+ n.afterClickWait ? j({ waitForElement: n.afterClickWait, clickDelay: i }) : $ = setTimeout(() => x(), i);
130
131
  };
131
- t.addEventListener("click", i);
132
+ t.addEventListener("click", o);
132
133
  }
133
134
  }
134
135
  function pt(t) {
@@ -136,39 +137,39 @@ function pt(t) {
136
137
  l.gatePass = !0;
137
138
  return;
138
139
  }
139
- const n = (i) => I(i);
140
- l.gatePass = t.gate(n), !l.gatePass && (_ = setInterval(() => {
141
- t.gate(n) && (l.gatePass = !0, _ && (clearInterval(_), _ = null));
140
+ const n = (o) => M(o);
141
+ l.gatePass = t.gate(n), !l.gatePass && (T = setInterval(() => {
142
+ t.gate(n) && (l.gatePass = !0, T && (clearInterval(T), T = null));
142
143
  }, st));
143
144
  }
144
145
  function j(t) {
145
146
  const n = t.waitForElement;
146
147
  if (!n) {
147
- k();
148
+ x();
148
149
  return;
149
150
  }
150
- if (I(n)) {
151
- $ = setTimeout(() => k(), t.clickDelay ?? 300);
151
+ if (M(n)) {
152
+ $ = setTimeout(() => x(), t.clickDelay ?? 300);
152
153
  return;
153
154
  }
154
155
  J(n, () => {
155
- $ = setTimeout(() => k(), t.clickDelay ?? 300);
156
+ $ = setTimeout(() => x(), t.clickDelay ?? 300);
156
157
  });
157
158
  }
158
159
  function J(t, n) {
159
- let i = !1;
160
- const o = () => {
161
- i || (i = !0, m == null || m.disconnect(), m = null, n());
160
+ let o = !1;
161
+ const i = () => {
162
+ o || (o = !0, v == null || v.disconnect(), v = null, n());
162
163
  };
163
- m = new MutationObserver(() => {
164
- I(t) && o();
165
- }), m.observe(document.body, { childList: !0, subtree: !0 }), O = setTimeout(o, rt);
164
+ v = new MutationObserver(() => {
165
+ M(t) && i();
166
+ }), v.observe(document.body, { childList: !0, subtree: !0 }), B = setTimeout(i, rt);
166
167
  }
167
168
  function gt(t) {
168
- $ = setTimeout(() => k(), t.autoDelay ?? 600);
169
+ $ = setTimeout(() => x(), t.autoDelay ?? 600);
169
170
  }
170
171
  function V() {
171
- K(), _ && (clearInterval(_), _ = null), m && (m.disconnect(), m = null), O && (clearTimeout(O), O = null), $ && (clearTimeout($), $ = null);
172
+ K(), T && (clearInterval(T), T = null), v && (v.disconnect(), v = null), B && (clearTimeout(B), B = null), $ && (clearTimeout($), $ = null);
172
173
  }
173
174
  const ht = {
174
175
  key: 0,
@@ -182,7 +183,7 @@ const ht = {
182
183
  }, bt = {
183
184
  key: 1,
184
185
  class: "tp-warn"
185
- }, _t = { class: "tp-foot" }, Tt = {
186
+ }, Tt = { class: "tp-foot" }, _t = {
186
187
  key: 0,
187
188
  class: "tp-click-hint"
188
189
  }, $t = {
@@ -207,25 +208,25 @@ const ht = {
207
208
  width: "28",
208
209
  height: "28",
209
210
  fill: "#e6a23c"
210
- }, St = /* @__PURE__ */ et({
211
+ }, zt = /* @__PURE__ */ et({
211
212
  __name: "TourOverlay",
212
213
  setup(t) {
213
214
  const n = l;
214
- function i(e) {
215
- e.key === "Escape" && n.active && B();
215
+ function o(e) {
216
+ e.key === "Escape" && n.active && O();
216
217
  }
217
218
  nt(() => n.active, (e) => {
218
- e ? window.addEventListener("keydown", i) : window.removeEventListener("keydown", i);
219
- }), lt(() => window.removeEventListener("keydown", i));
220
- const o = d(() => ct()), g = d(() => n.highlightRect), w = d(() => {
219
+ e ? window.addEventListener("keydown", o) : window.removeEventListener("keydown", o);
220
+ }), lt(() => window.removeEventListener("keydown", o));
221
+ const i = d(() => ct()), k = d(() => n.highlightRect), m = d(() => {
221
222
  var e, a;
222
- return ((e = o.value) == null ? void 0 : e.accent) ?? ((a = n.config) == null ? void 0 : a.accent) ?? "#409eff";
223
- }), R = d(() => n.stepIndex >= n.totalSteps - 1), h = d(() => {
224
- const e = o.value;
223
+ return ((e = i.value) == null ? void 0 : e.accent) ?? ((a = n.config) == null ? void 0 : a.accent) ?? "#409eff";
224
+ }), R = d(() => n.stepIndex >= n.totalSteps - 1), g = d(() => {
225
+ const e = i.value;
225
226
  return e ? !e.gate && e.trigger === "manual" : !1;
226
227
  });
227
- function M() {
228
- const e = g.value;
228
+ function z() {
229
+ const e = k.value;
229
230
  return e ? {
230
231
  top: { left: 0, top: 0, width: "100vw", height: `${Math.max(e.top, 0)}px` },
231
232
  bottom: { left: 0, top: `${e.top + e.height}px`, width: "100vw", height: `calc(100vh - ${e.top + e.height}px)` },
@@ -233,7 +234,7 @@ const ht = {
233
234
  right: { left: `${e.left + e.width}px`, top: `${e.top}px`, width: `calc(100vw - ${e.left + e.width}px)`, height: `${e.height}px` }
234
235
  } : null;
235
236
  }
236
- const y = d(M), A = d(() => {
237
+ const y = d(z), A = d(() => {
237
238
  var e;
238
239
  return ((e = y.value) == null ? void 0 : e.top) ?? { display: "none" };
239
240
  }), D = d(() => {
@@ -246,7 +247,7 @@ const ht = {
246
247
  var e;
247
248
  return ((e = y.value) == null ? void 0 : e.right) ?? { display: "none" };
248
249
  }), Y = d(() => {
249
- const e = g.value;
250
+ const e = k.value;
250
251
  return e ? {
251
252
  position: "fixed",
252
253
  top: `${e.top}px`,
@@ -254,16 +255,16 @@ const ht = {
254
255
  width: `${e.width}px`,
255
256
  height: `${e.height}px`,
256
257
  borderRadius: "8px",
257
- border: `2px solid ${w.value}`,
258
- boxShadow: `0 0 0 3px ${w.value}33, 0 0 20px ${w.value}44`,
258
+ border: `2px solid ${m.value}`,
259
+ boxShadow: `0 0 0 3px ${m.value}33, 0 0 20px ${m.value}44`,
259
260
  pointerEvents: "none",
260
261
  transition: "all 0.35s cubic-bezier(0.4,0,0.2,1)"
261
262
  } : { display: "none" };
262
263
  }), Z = d(() => {
263
264
  var F;
264
- const e = g.value;
265
+ const e = k.value;
265
266
  if (!e) return { position: "fixed", top: "50%", left: "50%", transform: "translate(-50%,-50%)" };
266
- const a = ((F = o.value) == null ? void 0 : F.placement) ?? "bottom", b = 14, f = { position: "fixed", zIndex: 100002 };
267
+ const a = ((F = i.value) == null ? void 0 : F.placement) ?? "bottom", b = 14, f = { position: "fixed", zIndex: 100002 };
267
268
  switch (a) {
268
269
  case "top":
269
270
  return { ...f, left: `${e.left}px`, bottom: `calc(100vh - ${e.top - b}px)`, maxWidth: "420px" };
@@ -277,69 +278,69 @@ const ht = {
277
278
  return { ...f, top: "50%", left: "50%", transform: "translate(-50%,-50%)", maxWidth: "480px" };
278
279
  }
279
280
  });
280
- function z() {
281
+ function I() {
281
282
  }
282
283
  return (e, a) => {
283
284
  var b;
284
- return r(), ot(it, { to: "body" }, [
285
+ return r(), it(ot, { to: "body" }, [
285
286
  c(n).active ? (r(), u("div", ht, [
286
287
  s("div", {
287
288
  class: "tour-mask",
288
- style: x(A.value),
289
- onClick: z
289
+ style: w(A.value),
290
+ onClick: I
290
291
  }, null, 4),
291
292
  s("div", {
292
293
  class: "tour-mask",
293
- style: x(D.value),
294
- onClick: z
294
+ style: w(D.value),
295
+ onClick: I
295
296
  }, null, 4),
296
297
  s("div", {
297
298
  class: "tour-mask",
298
- style: x(Q.value),
299
- onClick: z
299
+ style: w(Q.value),
300
+ onClick: I
300
301
  }, null, 4),
301
302
  s("div", {
302
303
  class: "tour-mask",
303
- style: x(X.value),
304
- onClick: z
304
+ style: w(X.value),
305
+ onClick: I
305
306
  }, null, 4),
306
- g.value ? (r(), u("div", {
307
+ k.value ? (r(), u("div", {
307
308
  key: 0,
308
309
  class: "tour-highlight",
309
- style: x(Y.value)
310
- }, null, 4)) : v("", !0),
311
- o.value && !c(n).waitingTarget ? (r(), u("div", {
310
+ style: w(Y.value)
311
+ }, null, 4)) : h("", !0),
312
+ i.value && !c(n).waitingTarget ? (r(), u("div", {
312
313
  key: 1,
313
314
  class: "tour-popover",
314
- style: x(Z.value)
315
+ style: w(Z.value)
315
316
  }, [
316
317
  s("div", vt, [
317
318
  s("span", {
318
319
  class: "tp-step-no",
319
- style: x({ background: w.value })
320
+ style: w({ background: m.value })
320
321
  }, p(c(n).stepIndex + 1), 5),
321
- o.value.gate ? (r(), u("span", mt, "*")) : v("", !0),
322
- s("span", wt, p(o.value.title), 1),
322
+ i.value.gate ? (r(), u("span", mt, "*")) : h("", !0),
323
+ s("span", wt, p(i.value.title), 1),
323
324
  s("span", xt, "第 " + p(c(n).stepIndex + 1) + " / " + p(c(n).totalSteps) + " 步", 1)
324
325
  ]),
325
- s("p", kt, p(o.value.content), 1),
326
- o.value.tip ? (r(), u("div", yt, "💡 " + p(o.value.tip), 1)) : v("", !0),
327
- o.value.warn ? (r(), u("div", bt, "⚠️ " + p(o.value.warn), 1)) : v("", !0),
328
- s("div", _t, [
326
+ s("p", kt, p(i.value.content), 1),
327
+ i.value.tip ? (r(), u("div", yt, "💡 " + p(i.value.tip), 1)) : h("", !0),
328
+ i.value.warn ? (r(), u("div", bt, "⚠️ " + p(i.value.warn), 1)) : h("", !0),
329
+ s("div", Tt, [
329
330
  s("button", {
330
331
  class: "tg-btn tg-btn--link tg-btn--sm",
331
- onClick: a[0] || (a[0] = (f) => c(B)())
332
+ onClick: a[0] || (a[0] = (f) => c(O)())
332
333
  }, "退出引导"),
333
- o.value.trigger === "click" ? (r(), u("span", Tt, " 👆 请点击高亮区域 ")) : c(n).gatePass ? (r(), u("span", $t, [
334
- h.value ? (r(), u("button", {
334
+ i.value.trigger === "click" ? (r(), u("span", _t, " 👆 请点击高亮区域 ")) : c(n).gatePass ? (r(), u("span", $t, [
335
+ g.value ? (r(), u("button", {
335
336
  key: 0,
336
337
  class: "tg-btn tg-btn--sm",
337
338
  onClick: a[1] || (a[1] = (f) => c(ut)())
338
- }, "跳过此步")) : v("", !0),
339
+ }, "跳过此步")) : h("", !0),
339
340
  s("button", {
340
341
  class: "tg-btn tg-btn--primary tg-btn--sm",
341
- style: x({ background: w.value, borderColor: w.value }),
342
- onClick: a[2] || (a[2] = (f) => c(k)())
342
+ style: w({ background: m.value, borderColor: m.value }),
343
+ onClick: a[2] || (a[2] = (f) => c(x)())
343
344
  }, p(R.value ? "完成" : "下一步"), 5)
344
345
  ])) : (r(), u("span", Et, [
345
346
  a[5] || (a[5] = s("svg", {
@@ -351,10 +352,10 @@ const ht = {
351
352
  }, [
352
353
  s("path", { d: "M512 160a96 96 0 0 1 96 96v64H416v-64a96 96 0 0 1 96-96zm0-64a160 160 0 0 0-160 160v64h-32a64 64 0 0 0-64 64v384a64 64 0 0 0 64 64h384a64 64 0 0 0 64-64V384a64 64 0 0 0-64-64h-32v-64A160 160 0 0 0 512 96zM320 448h384v320H320V448z" })
353
354
  ], -1)),
354
- at(" " + p(o.value.gateHint || "请先完成本步操作"), 1)
355
+ at(" " + p(i.value.gateHint || "请先完成本步操作"), 1)
355
356
  ]))
356
357
  ])
357
- ], 4)) : v("", !0),
358
+ ], 4)) : h("", !0),
358
359
  c(n).waitingTarget ? (r(), u("div", Ct, [
359
360
  c(n).waitTimedOut ? (r(), u("svg", Rt, [...a[7] || (a[7] = [
360
361
  s("path", { d: "M512 64L64 896h896L512 64zm0 192l288 576H224l288-576zm-32 224v128h64V480h-64zm0 160v64h64v-64h-64z" }, null, -1)
@@ -365,33 +366,29 @@ const ht = {
365
366
  }, null, -1),
366
367
  s("path", { d: "M512 64a448 448 0 0 1 448 448h-64A384 384 0 0 0 512 128V64z" }, null, -1)
367
368
  ])])),
368
- s("p", null, p(c(n).waitTimedOut ? "未找到目标元素,可能是页面状态不符" : ((b = o.value) == null ? void 0 : b.content) ?? "等待页面加载..."), 1),
369
+ s("p", null, p(c(n).waitTimedOut ? "未找到目标元素,可能是页面状态不符" : ((b = i.value) == null ? void 0 : b.content) ?? "等待页面加载..."), 1),
369
370
  c(n).waitTimedOut ? (r(), u("button", {
370
371
  key: 2,
371
372
  class: "tg-btn tg-btn--warning tg-btn--sm",
372
- onClick: a[3] || (a[3] = (f) => c(k)())
373
- }, "跳过此步")) : v("", !0),
373
+ onClick: a[3] || (a[3] = (f) => c(x)())
374
+ }, "跳过此步")) : h("", !0),
374
375
  s("button", {
375
376
  class: "tg-btn tg-btn--sm",
376
- onClick: a[4] || (a[4] = (f) => c(B)())
377
+ onClick: a[4] || (a[4] = (f) => c(O)())
377
378
  }, "退出引导")
378
- ])) : v("", !0)
379
- ])) : v("", !0)
379
+ ])) : h("", !0)
380
+ ])) : h("", !0)
380
381
  ]);
381
382
  };
382
383
  }
383
- }), It = (t, n) => {
384
- const i = t.__vccOpts || t;
385
- for (const [o, g] of n)
386
- i[o] = g;
387
- return i;
388
- }, Ot = /* @__PURE__ */ It(St, [["__scopeId", "data-v-9602901d"]]);
384
+ });
389
385
  export {
390
- Ot as TourOverlay,
391
- B as abort,
386
+ zt as TourOverlay,
387
+ O as abort,
392
388
  G as complete,
393
- k as next,
389
+ ct as currentStep,
390
+ x as next,
394
391
  ut as skip,
395
- zt as startTour,
392
+ Mt as startTour,
396
393
  l as tourState
397
394
  };
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "tour-guide-coach",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "轻量级交互式漫游引导引擎(Vue 3,零外部依赖,Element Plus 风格)",
5
5
  "type": "module",
6
+ "sideEffects": true,
6
7
  "main": "./dist/index.cjs",
7
8
  "module": "./dist/index.js",
8
9
  "types": "./dist/index.d.ts",
@@ -14,7 +15,10 @@
14
15
  },
15
16
  "./configs/*": "./src/configs/*.ts"
16
17
  },
17
- "files": ["dist", "src"],
18
+ "files": [
19
+ "dist",
20
+ "src"
21
+ ],
18
22
  "peerDependencies": {
19
23
  "vue": "^3.4"
20
24
  },
@@ -24,6 +28,7 @@
24
28
  "element-plus": "^2.7.5",
25
29
  "typescript": "^5.4",
26
30
  "vite": "^5.2",
31
+ "vite-plugin-css-injected-by-js": "^5.0.2",
27
32
  "vite-plugin-dts": "^5.1.1",
28
33
  "vue": "^3.4.27",
29
34
  "vue-tsc": "^2.0"
@@ -132,7 +132,7 @@ const popoverStyle = computed<CSSProperties>(() => {
132
132
  function onBlockedClick(): void { /* 静默拦截 */ }
133
133
  </script>
134
134
 
135
- <style scoped>
135
+ <style>
136
136
  /* ---------- CSS 变量:自动 fallback 到 --el-*(兼容 EP 项目) ---------- */
137
137
  .tour-root {
138
138
  --tg-primary: var(--el-color-primary, #409eff);
package/src/index.ts CHANGED
@@ -4,11 +4,12 @@
4
4
  * 零外部依赖(仅需 Vue 3),全局单例模式。
5
5
  *
6
6
  * 使用方式:
7
- * import { tourState, startTour, abort, TourOverlay } from 'vue-tour-guide'
7
+ * import { startTour, TourOverlay } from 'tour-guide-coach'
8
8
  * // 在 layout 中挂 <TourOverlay />
9
9
  * // 业务页调用 startTour(config)
10
+ * // CSS 已内联到 JS,无需手动引入样式文件
10
11
  */
11
- export { tourState, startTour, abort, next, skip, complete } from './store'
12
+ export { tourState, startTour, abort, next, skip, complete, currentStep } from './store'
12
13
  export type { TargetResolver } from './store'
13
14
  export { default as TourOverlay } from './TourOverlay.vue'
14
15
  export type { TourConfig, TourStep, StepTrigger, PopPlacement, HighlightRect } from './types'
package/dist/style.css DELETED
@@ -1 +0,0 @@
1
- .tour-root[data-v-9602901d]{--tg-primary: var(--el-color-primary, #409eff);--tg-success: var(--el-color-success, #67c23a);--tg-warning: var(--el-color-warning, #e6a23c);--tg-danger: var(--el-color-danger, #f56c6c);--tg-text-1: var(--el-text-color-primary, #303133);--tg-text-2: var(--el-text-color-regular, #606266);--tg-text-3: var(--el-text-color-secondary, #909399);--tg-border: var(--el-border-color-lighter, #ebeef5);--tg-fill-light: var(--el-fill-color-light, #f5f7fa);--tg-radius: var(--el-border-radius-base, 4px);position:fixed;top:0;right:0;bottom:0;left:0;z-index:100000;pointer-events:none;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,sans-serif}.tour-mask[data-v-9602901d]{position:fixed;background:#0000008c;transition:all .35s cubic-bezier(.4,0,.2,1);cursor:not-allowed;pointer-events:auto}.tour-highlight[data-v-9602901d]{z-index:100001}.tg-btn[data-v-9602901d]{display:inline-flex;align-items:center;justify-content:center;border:1px solid var(--tg-border);border-radius:var(--tg-radius);background:#fff;color:var(--tg-text-2);font-size:14px;font-weight:500;line-height:1;padding:8px 15px;cursor:pointer;transition:color .2s,border-color .2s,background .2s;outline:none;white-space:nowrap;-webkit-user-select:none;user-select:none}.tg-btn[data-v-9602901d]:hover{color:var(--tg-primary);border-color:var(--tg-primary);background:#ecf5ff}.tg-btn--sm[data-v-9602901d]{padding:5px 11px;font-size:12px}.tg-btn--primary[data-v-9602901d]{background:var(--tg-primary);border-color:var(--tg-primary);color:#fff}.tg-btn--primary[data-v-9602901d]:hover{opacity:.85;background:var(--tg-primary);color:#fff}.tg-btn--warning[data-v-9602901d]{background:var(--tg-warning);border-color:var(--tg-warning);color:#fff}.tg-btn--warning[data-v-9602901d]:hover{opacity:.85;background:var(--tg-warning);color:#fff}.tg-btn--link[data-v-9602901d]{border:none;background:none;padding:4px 6px;color:var(--tg-text-3)}.tg-btn--link[data-v-9602901d]:hover{color:var(--tg-primary);background:none}.tour-popover[data-v-9602901d]{z-index:100002;background:#fff;border-radius:12px;padding:20px 24px;box-shadow:0 8px 40px #0000001f,0 2px 8px #0000000f;animation:tp-in-9602901d .3s ease;pointer-events:auto;min-width:280px;max-width:420px}@keyframes tp-in-9602901d{0%{opacity:0;transform:translateY(6px) scale(.97)}to{opacity:1;transform:translateY(0) scale(1)}}.tp-head[data-v-9602901d]{display:flex;align-items:center;gap:10px;margin-bottom:12px}.tp-step-no[data-v-9602901d]{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:50%;color:#fff;font-size:14px;font-weight:700;flex-shrink:0}.tp-required[data-v-9602901d]{color:var(--tg-danger);font-size:20px;font-weight:700;line-height:1}.tp-title[data-v-9602901d]{font-size:16px;font-weight:700;color:var(--tg-text-1)}.tp-of[data-v-9602901d]{font-size:13px;color:var(--tg-text-3);margin-left:auto;font-variant-numeric:tabular-nums}.tp-content[data-v-9602901d]{margin:0 0 14px;font-size:14px;line-height:1.8;color:var(--tg-text-2);white-space:pre-line}.tp-tip[data-v-9602901d]{font-size:13px;color:#529b2e;background:#f0f9eb;padding:8px 12px;border-radius:6px;margin-bottom:10px;border-left:3px solid #67c23a}.tp-warn[data-v-9602901d]{font-size:13px;color:#b88230;background:#fdf6ec;padding:8px 12px;border-radius:6px;margin-bottom:10px;border-left:3px solid #e6a23c}.tp-foot[data-v-9602901d]{display:flex;align-items:center;justify-content:space-between;padding-top:14px;border-top:1px solid var(--tg-border)}.tp-btns[data-v-9602901d]{display:flex;gap:10px}.tp-gate[data-v-9602901d]{display:inline-flex;align-items:center;gap:5px;font-size:13px;color:var(--tg-warning);font-weight:500}.tp-gate-icon[data-v-9602901d]{flex-shrink:0}.tp-click-hint[data-v-9602901d]{font-size:14px;color:var(--tg-primary);font-weight:500;animation:pulse-hint-9602901d 1.5s ease-in-out infinite}@keyframes pulse-hint-9602901d{0%,to{opacity:1}50%{opacity:.5}}.tour-waiting[data-v-9602901d]{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:100002;background:#fff;padding:32px 40px;border-radius:12px;box-shadow:0 8px 32px #00000026;text-align:center;pointer-events:auto;display:flex;flex-direction:column;align-items:center;gap:8px}.tour-waiting p[data-v-9602901d]{margin:4px 0 8px;font-size:14px;color:var(--tg-text-2)}.tg-spin[data-v-9602901d]{animation:tg-rotate-9602901d 1s linear infinite}@keyframes tg-rotate-9602901d{0%{transform:rotate(0)}to{transform:rotate(360deg)}}