tour-guide-coach 1.0.1 → 1.0.3
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/dist/css.d.ts +1 -0
- package/dist/index.cjs +34 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +244 -205
- package/package.json +2 -1
- package/src/TourOverlay.vue +3 -105
- package/src/css.ts +52 -0
- package/src/index.ts +1 -1
package/dist/css.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function injectStyles(): void;
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,34 @@
|
|
|
1
|
-
|
|
2
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("vue"),J=150,Q=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 P(){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,A()}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,A()}}function W(){p()}function A(){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"){H(e);return}const o=T(e.target);if(o){I(o,e);return}q(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){F(),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 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(e,o){if(o.trigger==="click"){const a=()=>{e.removeEventListener("click",a);const i=o.clickDelay??350;o.afterClickWait?H({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))},J))}function H(e){const o=e.waitForElement;if(!o){p();return}if(T(o)){k=setTimeout(()=>p(),e.clickDelay??300);return}q(o,()=>{k=setTimeout(()=>p(),e.clickDelay??300)})}function q(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,Q)}function et(e){k=setTimeout(()=>p(),e.autoDelay??600)}function R(){F(),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(()=>P()),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"}}),G=t.computed(()=>{var n;return((n=f.value)==null?void 0:n.left)??{display:"none"}}),U=t.computed(()=>{var n;return((n=f.value)==null?void 0:n.right)??{display:"none"}}),j=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"}}),K=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(G.value),onClick:S},null,4),t.createElementVNode("div",{class:"tour-mask",style:t.normalizeStyle(U.value),onClick:S},null,4),s.value?(t.openBlock(),t.createElementBlock("div",{key:0,class:"tour-highlight",style:t.normalizeStyle(j.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(K.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(W)())},"跳过此步")):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.currentStep=P;exports.next=p;exports.skip=W;exports.startTour=X;exports.tourState=l;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("vue"),Q=150,X=12e3,r=t.shallowReactive({active:!1,config:null,stepIndex:0,totalSteps:0,highlightRect:null,targetEl:null,gatePass:!0,waitingTarget:!1,waitTimedOut:!1});let C=null,S=null,h=null,u=null,z=null,x=null,k=null,v=null,y=null,b=null;function W(){var e;return((e=r.config)==null?void 0:e.steps[r.stepIndex])??null}function A(){return W()}function Z(e,o,i){r.active&&E(),r.config=e,r.stepIndex=0,r.totalSteps=e.steps.length,r.gatePass=!0,C=i??null,S=o??null,r.active=!0,H()}function E(){D(),r.active=!1,r.config=null,r.highlightRect=null,r.targetEl=null,S=null,C=null}function R(){D(),r.active=!1,r.highlightRect=null,r.targetEl=null;const e=C;S=null,C=null,e==null||e()}function p(){D();const e=r.config;if(e){if(r.stepIndex>=e.steps.length-1){R();return}r.stepIndex+=1,H()}}function F(){p()}function H(){var i;const e=W();if(!e){R();return}b=e,r.gatePass=!e.gate,r.waitingTarget=!0,r.waitTimedOut=!1,r.highlightRect=null,r.targetEl=null;const o=(i=e.beforeEnter)==null?void 0:i.call(e);o instanceof Promise?o.then(()=>M(e)):requestAnimationFrame(()=>M(e))}function M(e){if(e.trigger==="auto"){r.waitingTarget=!1,ot(e);return}if(e.trigger==="wait-dom"){q(e);return}const o=T(e.target);if(o){O(o,e);return}U(e.target,()=>{const i=T(e.target);O(i,e)})}function T(e){if(S){const o=S(e);if(o)return o}try{return document.querySelector(e)}catch{return null}}function O(e,o){if(!e){r.waitTimedOut=!0;return}r.waitingTarget=!1,r.waitTimedOut=!1,r.targetEl=e,V(e),et(e,o),nt(o),tt(e)}function V(e){const o=e.getBoundingClientRect(),i=6;let l={top:o.top-i,left:o.left-i,width:o.width+i*2,height:o.height+i*2};const g=b==null?void 0:b.expandSelector;if(g){const d=document.querySelectorAll(g);let w=null;for(const s of d)if(s.offsetHeight>0){w=s;break}if(w){const s=w.getBoundingClientRect(),B=Math.min(l.top,s.top-i),f=Math.min(l.left,s.left-i),N=Math.max(l.left+l.width,s.right+i),$=Math.max(l.top+l.height,s.bottom+i);l={top:B,left:f,width:N-f,height:$-B}}}r.highlightRect=l}function tt(e){j(),v=()=>V(e),window.addEventListener("scroll",v,!0),window.addEventListener("resize",v),k=new ResizeObserver(()=>V(e)),k.observe(e),(b==null?void 0:b.expandSelector)&&(y=new MutationObserver(()=>V(e)),y.observe(document.body,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["style","class"]}))}function j(){v&&(window.removeEventListener("scroll",v,!0),window.removeEventListener("resize",v)),v=null,k==null||k.disconnect(),k=null,y==null||y.disconnect(),y=null}function et(e,o){if(o.trigger==="click"){const i=()=>{e.removeEventListener("click",i);const l=o.clickDelay??350;o.afterClickWait?q({waitForElement:o.afterClickWait,clickDelay:l}):x=setTimeout(()=>p(),l)};e.addEventListener("click",i)}}function nt(e){if(!e.gate){r.gatePass=!0;return}const o=i=>T(i);r.gatePass=e.gate(o),!r.gatePass&&(h=setInterval(()=>{e.gate(o)&&(r.gatePass=!0,h&&(clearInterval(h),h=null))},Q))}function q(e){const o=e.waitForElement;if(!o){p();return}if(T(o)){x=setTimeout(()=>p(),e.clickDelay??300);return}U(o,()=>{x=setTimeout(()=>p(),e.clickDelay??300)})}function U(e,o){let i=!1;const l=()=>{i||(i=!0,u==null||u.disconnect(),u=null,o())};u=new MutationObserver(()=>{T(e)&&l()}),u.observe(document.body,{childList:!0,subtree:!0}),z=setTimeout(l,X)}function ot(e){x=setTimeout(()=>p(),e.autoDelay??600)}function D(){j(),h&&(clearInterval(h),h=null),u&&(u.disconnect(),u=null),z&&(clearTimeout(z),z=null),x&&(clearTimeout(x),x=null)}const P="tour-guide-coach-styles",rt=`
|
|
2
|
+
.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;inset:0;z-index:100000;pointer-events:none;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',sans-serif}
|
|
3
|
+
.tour-mask{position:fixed;background:rgba(0,0,0,.55);transition:all .35s cubic-bezier(.4,0,.2,1);cursor:not-allowed;pointer-events:auto}
|
|
4
|
+
.tour-highlight{z-index:100001}
|
|
5
|
+
.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;user-select:none}
|
|
6
|
+
.tg-btn:hover{color:var(--tg-primary);border-color:var(--tg-primary);background:#ecf5ff}
|
|
7
|
+
.tg-btn--sm{padding:5px 11px;font-size:12px}
|
|
8
|
+
.tg-btn--primary{background:var(--tg-primary);border-color:var(--tg-primary);color:#fff}
|
|
9
|
+
.tg-btn--primary:hover{opacity:.85;background:var(--tg-primary);color:#fff}
|
|
10
|
+
.tg-btn--warning{background:var(--tg-warning);border-color:var(--tg-warning);color:#fff}
|
|
11
|
+
.tg-btn--warning:hover{opacity:.85;background:var(--tg-warning);color:#fff}
|
|
12
|
+
.tg-btn--link{border:none;background:none;padding:4px 6px;color:var(--tg-text-3)}
|
|
13
|
+
.tg-btn--link:hover{color:var(--tg-primary);background:none}
|
|
14
|
+
.tour-popover{z-index:100002;background:#fff;border-radius:12px;padding:20px 24px;box-shadow:0 8px 40px rgba(0,0,0,.12),0 2px 8px rgba(0,0,0,.06);animation:tg-tp-in .3s ease;pointer-events:auto;min-width:280px;max-width:420px}
|
|
15
|
+
@keyframes tg-tp-in{from{opacity:0;transform:translateY(6px) scale(.97)}to{opacity:1;transform:translateY(0) scale(1)}}
|
|
16
|
+
.tp-head{display:flex;align-items:center;gap:10px;margin-bottom:12px}
|
|
17
|
+
.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}
|
|
18
|
+
.tp-required{color:var(--tg-danger);font-size:20px;font-weight:700;line-height:1}
|
|
19
|
+
.tp-title{font-size:16px;font-weight:700;color:var(--tg-text-1)}
|
|
20
|
+
.tp-of{font-size:13px;color:var(--tg-text-3);margin-left:auto;font-variant-numeric:tabular-nums}
|
|
21
|
+
.tp-content{margin:0 0 14px;font-size:14px;line-height:1.8;color:var(--tg-text-2);white-space:pre-line}
|
|
22
|
+
.tp-tip{font-size:13px;color:#529b2e;background:#f0f9eb;padding:8px 12px;border-radius:6px;margin-bottom:10px;border-left:3px solid #67c23a}
|
|
23
|
+
.tp-warn{font-size:13px;color:#b88230;background:#fdf6ec;padding:8px 12px;border-radius:6px;margin-bottom:10px;border-left:3px solid #e6a23c}
|
|
24
|
+
.tp-foot{display:flex;align-items:center;justify-content:space-between;padding-top:14px;border-top:1px solid var(--tg-border)}
|
|
25
|
+
.tp-btns{display:flex;gap:10px}
|
|
26
|
+
.tp-gate{display:inline-flex;align-items:center;gap:5px;font-size:13px;color:var(--tg-warning);font-weight:500}
|
|
27
|
+
.tp-gate-icon{flex-shrink:0}
|
|
28
|
+
.tp-click-hint{font-size:14px;color:var(--tg-primary);font-weight:500;animation:tg-pulse 1.5s ease-in-out infinite}
|
|
29
|
+
@keyframes tg-pulse{0%,100%{opacity:1}50%{opacity:.5}}
|
|
30
|
+
.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 rgba(0,0,0,.15);text-align:center;pointer-events:auto;display:flex;flex-direction:column;align-items:center;gap:8px}
|
|
31
|
+
.tour-waiting p{margin:4px 0 8px;font-size:14px;color:var(--tg-text-2)}
|
|
32
|
+
.tg-spin{animation:tg-rotate 1s linear infinite}
|
|
33
|
+
@keyframes tg-rotate{from{transform:rotate(0)}to{transform:rotate(360deg)}}
|
|
34
|
+
`;let L=!1;function lt(){if(L||typeof document>"u")return;if(document.getElementById(P)){L=!0;return}const e=document.createElement("style");e.id=P,e.textContent=rt,document.head.appendChild(e),L=!0}const it={key:0,class:"tour-root"},at={class:"tp-head"},ct={key:0,class:"tp-required"},st={class:"tp-title"},ut={class:"tp-of"},pt={class:"tp-content"},dt={key:0,class:"tp-tip"},gt={key:1,class:"tp-warn"},ft={class:"tp-foot"},mt={key:0,class:"tp-click-hint"},ht={key:1,class:"tp-btns"},vt={key:2,class:"tp-gate"},xt={key:2,class:"tour-waiting"},bt={key:0,class:"tg-spin",viewBox:"0 0 1024 1024",width:"28",height:"28",fill:"currentColor"},kt={key:1,viewBox:"0 0 1024 1024",width:"28",height:"28",fill:"#e6a23c"},yt=t.defineComponent({__name:"TourOverlay",setup(e){lt();const o=r;function i(n){n.key==="Escape"&&o.active&&E()}t.watch(()=>o.active,n=>{n?window.addEventListener("keydown",i):window.removeEventListener("keydown",i)}),t.onBeforeUnmount(()=>window.removeEventListener("keydown",i));const l=t.computed(()=>A()),g=t.computed(()=>o.highlightRect),d=t.computed(()=>{var n,a;return((n=l.value)==null?void 0:n.accent)??((a=o.config)==null?void 0:a.accent)??"#409eff"}),w=t.computed(()=>o.stepIndex>=o.totalSteps-1),s=t.computed(()=>{const n=l.value;return n?!n.gate&&n.trigger==="manual":!1});function B(){const n=g.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),N=t.computed(()=>{var n;return((n=f.value)==null?void 0:n.top)??{display:"none"}}),$=t.computed(()=>{var n;return((n=f.value)==null?void 0:n.bottom)??{display:"none"}}),Y=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"}}),K=t.computed(()=>{const n=g.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 ${d.value}`,boxShadow:`0 0 0 3px ${d.value}33, 0 0 20px ${d.value}44`,pointerEvents:"none",transition:"all 0.35s cubic-bezier(0.4,0,0.2,1)"}:{display:"none"}}),J=t.computed(()=>{var I;const n=g.value;if(!n)return{position:"fixed",top:"50%",left:"50%",transform:"translate(-50%,-50%)"};const a=((I=l.value)==null?void 0:I.placement)??"bottom",m=14,c={position:"fixed",zIndex:100002};switch(a){case"top":return{...c,left:`${n.left}px`,bottom:`calc(100vh - ${n.top-m}px)`,maxWidth:"420px"};case"bottom":return{...c,left:`${n.left}px`,top:`${n.top+n.height+m}px`,maxWidth:"420px"};case"left":return{...c,right:`calc(100vw - ${n.left-m}px)`,top:`${n.top}px`,maxWidth:"360px"};case"right":return{...c,left:`${n.left+n.width+m}px`,top:`${n.top}px`,maxWidth:"360px"};default:return{...c,top:"50%",left:"50%",transform:"translate(-50%,-50%)",maxWidth:"480px"}}});function _(){}return(n,a)=>{var m;return t.openBlock(),t.createBlock(t.Teleport,{to:"body"},[t.unref(o).active?(t.openBlock(),t.createElementBlock("div",it,[t.createElementVNode("div",{class:"tour-mask",style:t.normalizeStyle(N.value),onClick:_},null,4),t.createElementVNode("div",{class:"tour-mask",style:t.normalizeStyle($.value),onClick:_},null,4),t.createElementVNode("div",{class:"tour-mask",style:t.normalizeStyle(Y.value),onClick:_},null,4),t.createElementVNode("div",{class:"tour-mask",style:t.normalizeStyle(G.value),onClick:_},null,4),g.value?(t.openBlock(),t.createElementBlock("div",{key:0,class:"tour-highlight",style:t.normalizeStyle(K.value)},null,4)):t.createCommentVNode("",!0),l.value&&!t.unref(o).waitingTarget?(t.openBlock(),t.createElementBlock("div",{key:1,class:"tour-popover",style:t.normalizeStyle(J.value)},[t.createElementVNode("div",at,[t.createElementVNode("span",{class:"tp-step-no",style:t.normalizeStyle({background:d.value})},t.toDisplayString(t.unref(o).stepIndex+1),5),l.value.gate?(t.openBlock(),t.createElementBlock("span",ct,"*")):t.createCommentVNode("",!0),t.createElementVNode("span",st,t.toDisplayString(l.value.title),1),t.createElementVNode("span",ut,"第 "+t.toDisplayString(t.unref(o).stepIndex+1)+" / "+t.toDisplayString(t.unref(o).totalSteps)+" 步",1)]),t.createElementVNode("p",pt,t.toDisplayString(l.value.content),1),l.value.tip?(t.openBlock(),t.createElementBlock("div",dt,"💡 "+t.toDisplayString(l.value.tip),1)):t.createCommentVNode("",!0),l.value.warn?(t.openBlock(),t.createElementBlock("div",gt,"⚠️ "+t.toDisplayString(l.value.warn),1)):t.createCommentVNode("",!0),t.createElementVNode("div",ft,[t.createElementVNode("button",{class:"tg-btn tg-btn--link tg-btn--sm",onClick:a[0]||(a[0]=c=>t.unref(E)())},"退出引导"),l.value.trigger==="click"?(t.openBlock(),t.createElementBlock("span",mt," 👆 请点击高亮区域 ")):t.unref(o).gatePass?(t.openBlock(),t.createElementBlock("span",ht,[s.value?(t.openBlock(),t.createElementBlock("button",{key:0,class:"tg-btn tg-btn--sm",onClick:a[1]||(a[1]=c=>t.unref(F)())},"跳过此步")):t.createCommentVNode("",!0),t.createElementVNode("button",{class:"tg-btn tg-btn--primary tg-btn--sm",style:t.normalizeStyle({background:d.value,borderColor:d.value}),onClick:a[2]||(a[2]=c=>t.unref(p)())},t.toDisplayString(w.value?"完成":"下一步"),5)])):(t.openBlock(),t.createElementBlock("span",vt,[a[5]||(a[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(l.value.gateHint||"请先完成本步操作"),1)]))])],4)):t.createCommentVNode("",!0),t.unref(o).waitingTarget?(t.openBlock(),t.createElementBlock("div",xt,[t.unref(o).waitTimedOut?(t.openBlock(),t.createElementBlock("svg",kt,[...a[7]||(a[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",bt,[...a[6]||(a[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?"未找到目标元素,可能是页面状态不符":((m=l.value)==null?void 0:m.content)??"等待页面加载..."),1),t.unref(o).waitTimedOut?(t.openBlock(),t.createElementBlock("button",{key:2,class:"tg-btn tg-btn--warning tg-btn--sm",onClick:a[3]||(a[3]=c=>t.unref(p)())},"跳过此步")):t.createCommentVNode("",!0),t.createElementVNode("button",{class:"tg-btn tg-btn--sm",onClick:a[4]||(a[4]=c=>t.unref(E)())},"退出引导")])):t.createCommentVNode("",!0)])):t.createCommentVNode("",!0)])}}});exports.TourOverlay=yt;exports.abort=E;exports.complete=R;exports.currentStep=A;exports.next=p;exports.skip=F;exports.startTour=Z;exports.tourState=r;
|
package/dist/index.d.ts
CHANGED
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
*
|
|
6
6
|
* 使用方式:
|
|
7
7
|
* import { startTour, TourOverlay } from 'tour-guide-coach'
|
|
8
|
-
* import 'tour-guide-coach/dist/style.css'
|
|
9
8
|
* // 在 layout 中挂 <TourOverlay />
|
|
10
9
|
* // 业务页调用 startTour(config)
|
|
10
|
+
* // CSS 已内联到 JS,无需手动引入样式文件
|
|
11
11
|
*/
|
|
12
12
|
export { tourState, startTour, abort, next, skip, complete, currentStep } from './store';
|
|
13
13
|
export type { TargetResolver } from './store';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const st = 150, rt = 12e3, l = tt({
|
|
1
|
+
import { shallowReactive as nt, defineComponent as ot, watch as it, onBeforeUnmount as rt, computed as p, openBlock as s, createBlock as at, Teleport as lt, unref as c, createElementBlock as u, createElementVNode as l, normalizeStyle as m, createCommentVNode as h, toDisplayString as d, createTextVNode as st } from "vue";
|
|
2
|
+
const ct = 150, ut = 12e3, o = nt({
|
|
4
3
|
active: !1,
|
|
5
4
|
config: null,
|
|
6
5
|
stepIndex: 0,
|
|
@@ -11,72 +10,72 @@ const st = 150, rt = 12e3, l = tt({
|
|
|
11
10
|
waitingTarget: !1,
|
|
12
11
|
waitTimedOut: !1
|
|
13
12
|
});
|
|
14
|
-
let
|
|
15
|
-
function
|
|
13
|
+
let D = null, L = null, T = null, v = null, B = null, z = null, $ = null, _ = null, C = null, E = null;
|
|
14
|
+
function U() {
|
|
16
15
|
var t;
|
|
17
|
-
return ((t =
|
|
16
|
+
return ((t = o.config) == null ? void 0 : t.steps[o.stepIndex]) ?? null;
|
|
18
17
|
}
|
|
19
|
-
function
|
|
20
|
-
return
|
|
18
|
+
function pt() {
|
|
19
|
+
return U();
|
|
21
20
|
}
|
|
22
|
-
function
|
|
23
|
-
|
|
21
|
+
function Ot(t, n, r) {
|
|
22
|
+
o.active && O(), o.config = t, o.stepIndex = 0, o.totalSteps = t.steps.length, o.gatePass = !0, D = r ?? null, L = n ?? null, o.active = !0, G();
|
|
24
23
|
}
|
|
25
|
-
function
|
|
26
|
-
V(),
|
|
24
|
+
function O() {
|
|
25
|
+
V(), o.active = !1, o.config = null, o.highlightRect = null, o.targetEl = null, L = null, D = null;
|
|
27
26
|
}
|
|
28
|
-
function
|
|
29
|
-
V(),
|
|
30
|
-
const t =
|
|
31
|
-
|
|
27
|
+
function Y() {
|
|
28
|
+
V(), o.active = !1, o.highlightRect = null, o.targetEl = null;
|
|
29
|
+
const t = D;
|
|
30
|
+
L = null, D = null, t == null || t();
|
|
32
31
|
}
|
|
33
|
-
function
|
|
32
|
+
function b() {
|
|
34
33
|
V();
|
|
35
|
-
const t =
|
|
34
|
+
const t = o.config;
|
|
36
35
|
if (t) {
|
|
37
|
-
if (
|
|
38
|
-
|
|
36
|
+
if (o.stepIndex >= t.steps.length - 1) {
|
|
37
|
+
Y();
|
|
39
38
|
return;
|
|
40
39
|
}
|
|
41
|
-
|
|
40
|
+
o.stepIndex += 1, G();
|
|
42
41
|
}
|
|
43
42
|
}
|
|
44
|
-
function
|
|
45
|
-
|
|
43
|
+
function gt() {
|
|
44
|
+
b();
|
|
46
45
|
}
|
|
47
|
-
function
|
|
48
|
-
var
|
|
49
|
-
const t =
|
|
46
|
+
function G() {
|
|
47
|
+
var r;
|
|
48
|
+
const t = U();
|
|
50
49
|
if (!t) {
|
|
51
|
-
|
|
50
|
+
Y();
|
|
52
51
|
return;
|
|
53
52
|
}
|
|
54
|
-
E = t,
|
|
55
|
-
const n = (
|
|
56
|
-
n instanceof Promise ? n.then(() =>
|
|
53
|
+
E = t, o.gatePass = !t.gate, o.waitingTarget = !0, o.waitTimedOut = !1, o.highlightRect = null, o.targetEl = null;
|
|
54
|
+
const n = (r = t.beforeEnter) == null ? void 0 : r.call(t);
|
|
55
|
+
n instanceof Promise ? n.then(() => N(t)) : requestAnimationFrame(() => N(t));
|
|
57
56
|
}
|
|
58
|
-
function
|
|
57
|
+
function N(t) {
|
|
59
58
|
if (t.trigger === "auto") {
|
|
60
|
-
|
|
59
|
+
o.waitingTarget = !1, vt(t);
|
|
61
60
|
return;
|
|
62
61
|
}
|
|
63
62
|
if (t.trigger === "wait-dom") {
|
|
64
|
-
|
|
63
|
+
J(t);
|
|
65
64
|
return;
|
|
66
65
|
}
|
|
67
|
-
const n =
|
|
66
|
+
const n = R(t.target);
|
|
68
67
|
if (n) {
|
|
69
|
-
|
|
68
|
+
j(n, t);
|
|
70
69
|
return;
|
|
71
70
|
}
|
|
72
|
-
|
|
73
|
-
const
|
|
74
|
-
|
|
71
|
+
Q(t.target, () => {
|
|
72
|
+
const r = R(t.target);
|
|
73
|
+
j(r, t);
|
|
75
74
|
});
|
|
76
75
|
}
|
|
77
|
-
function
|
|
78
|
-
if (
|
|
79
|
-
const n =
|
|
76
|
+
function R(t) {
|
|
77
|
+
if (L) {
|
|
78
|
+
const n = L(t);
|
|
80
79
|
if (n) return n;
|
|
81
80
|
}
|
|
82
81
|
try {
|
|
@@ -85,148 +84,193 @@ function I(t) {
|
|
|
85
84
|
return null;
|
|
86
85
|
}
|
|
87
86
|
}
|
|
88
|
-
function
|
|
87
|
+
function j(t, n) {
|
|
89
88
|
if (!t) {
|
|
90
|
-
|
|
89
|
+
o.waitTimedOut = !0;
|
|
91
90
|
return;
|
|
92
91
|
}
|
|
93
|
-
|
|
92
|
+
o.waitingTarget = !1, o.waitTimedOut = !1, o.targetEl = t, P(t), ft(t, n), ht(n), dt(t);
|
|
94
93
|
}
|
|
95
94
|
function P(t) {
|
|
96
|
-
const n = t.getBoundingClientRect(),
|
|
97
|
-
let
|
|
98
|
-
top: n.top -
|
|
99
|
-
left: n.left -
|
|
100
|
-
width: n.width +
|
|
101
|
-
height: n.height +
|
|
95
|
+
const n = t.getBoundingClientRect(), r = 6;
|
|
96
|
+
let i = {
|
|
97
|
+
top: n.top - r,
|
|
98
|
+
left: n.left - r,
|
|
99
|
+
width: n.width + r * 2,
|
|
100
|
+
height: n.height + r * 2
|
|
102
101
|
};
|
|
103
|
-
const
|
|
104
|
-
if (
|
|
105
|
-
const
|
|
106
|
-
let
|
|
107
|
-
for (const
|
|
108
|
-
if (
|
|
109
|
-
|
|
102
|
+
const w = E == null ? void 0 : E.expandSelector;
|
|
103
|
+
if (w) {
|
|
104
|
+
const x = document.querySelectorAll(w);
|
|
105
|
+
let S = null;
|
|
106
|
+
for (const f of x)
|
|
107
|
+
if (f.offsetHeight > 0) {
|
|
108
|
+
S = f;
|
|
110
109
|
break;
|
|
111
110
|
}
|
|
112
|
-
if (
|
|
113
|
-
const
|
|
114
|
-
|
|
111
|
+
if (S) {
|
|
112
|
+
const f = S.getBoundingClientRect(), I = Math.min(i.top, f.top - r), y = Math.min(i.left, f.left - r), W = Math.max(i.left + i.width, f.right + r), A = Math.max(i.top + i.height, f.bottom + r);
|
|
113
|
+
i = { top: I, left: y, width: W - y, height: A - I };
|
|
115
114
|
}
|
|
116
115
|
}
|
|
117
|
-
|
|
116
|
+
o.highlightRect = i;
|
|
118
117
|
}
|
|
119
118
|
function dt(t) {
|
|
120
|
-
K(),
|
|
119
|
+
K(), _ = () => P(t), window.addEventListener("scroll", _, !0), window.addEventListener("resize", _), $ = new ResizeObserver(() => P(t)), $.observe(t), (E == null ? void 0 : E.expandSelector) && (C = new MutationObserver(() => P(t)), C.observe(document.body, { childList: !0, subtree: !0, attributes: !0, attributeFilter: ["style", "class"] }));
|
|
121
120
|
}
|
|
122
121
|
function K() {
|
|
123
|
-
|
|
122
|
+
_ && (window.removeEventListener("scroll", _, !0), window.removeEventListener("resize", _)), _ = null, $ == null || $.disconnect(), $ = null, C == null || C.disconnect(), C = null;
|
|
124
123
|
}
|
|
125
124
|
function ft(t, n) {
|
|
126
125
|
if (n.trigger === "click") {
|
|
127
|
-
const
|
|
128
|
-
t.removeEventListener("click",
|
|
129
|
-
const
|
|
130
|
-
n.afterClickWait ?
|
|
126
|
+
const r = () => {
|
|
127
|
+
t.removeEventListener("click", r);
|
|
128
|
+
const i = n.clickDelay ?? 350;
|
|
129
|
+
n.afterClickWait ? J({ waitForElement: n.afterClickWait, clickDelay: i }) : z = setTimeout(() => b(), i);
|
|
131
130
|
};
|
|
132
|
-
t.addEventListener("click",
|
|
131
|
+
t.addEventListener("click", r);
|
|
133
132
|
}
|
|
134
133
|
}
|
|
135
|
-
function
|
|
134
|
+
function ht(t) {
|
|
136
135
|
if (!t.gate) {
|
|
137
|
-
|
|
136
|
+
o.gatePass = !0;
|
|
138
137
|
return;
|
|
139
138
|
}
|
|
140
|
-
const n = (
|
|
141
|
-
|
|
142
|
-
t.gate(n) && (
|
|
143
|
-
},
|
|
139
|
+
const n = (r) => R(r);
|
|
140
|
+
o.gatePass = t.gate(n), !o.gatePass && (T = setInterval(() => {
|
|
141
|
+
t.gate(n) && (o.gatePass = !0, T && (clearInterval(T), T = null));
|
|
142
|
+
}, ct));
|
|
144
143
|
}
|
|
145
|
-
function
|
|
144
|
+
function J(t) {
|
|
146
145
|
const n = t.waitForElement;
|
|
147
146
|
if (!n) {
|
|
148
|
-
|
|
147
|
+
b();
|
|
149
148
|
return;
|
|
150
149
|
}
|
|
151
|
-
if (
|
|
152
|
-
|
|
150
|
+
if (R(n)) {
|
|
151
|
+
z = setTimeout(() => b(), t.clickDelay ?? 300);
|
|
153
152
|
return;
|
|
154
153
|
}
|
|
155
|
-
|
|
156
|
-
|
|
154
|
+
Q(n, () => {
|
|
155
|
+
z = setTimeout(() => b(), t.clickDelay ?? 300);
|
|
157
156
|
});
|
|
158
157
|
}
|
|
159
|
-
function
|
|
160
|
-
let
|
|
161
|
-
const
|
|
162
|
-
|
|
158
|
+
function Q(t, n) {
|
|
159
|
+
let r = !1;
|
|
160
|
+
const i = () => {
|
|
161
|
+
r || (r = !0, v == null || v.disconnect(), v = null, n());
|
|
163
162
|
};
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
}),
|
|
163
|
+
v = new MutationObserver(() => {
|
|
164
|
+
R(t) && i();
|
|
165
|
+
}), v.observe(document.body, { childList: !0, subtree: !0 }), B = setTimeout(i, ut);
|
|
167
166
|
}
|
|
168
|
-
function
|
|
169
|
-
|
|
167
|
+
function vt(t) {
|
|
168
|
+
z = setTimeout(() => b(), t.autoDelay ?? 600);
|
|
170
169
|
}
|
|
171
170
|
function V() {
|
|
172
|
-
K(),
|
|
171
|
+
K(), T && (clearInterval(T), T = null), v && (v.disconnect(), v = null), B && (clearTimeout(B), B = null), z && (clearTimeout(z), z = null);
|
|
173
172
|
}
|
|
174
|
-
const
|
|
173
|
+
const q = "tour-guide-coach-styles", xt = `
|
|
174
|
+
.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;inset:0;z-index:100000;pointer-events:none;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',sans-serif}
|
|
175
|
+
.tour-mask{position:fixed;background:rgba(0,0,0,.55);transition:all .35s cubic-bezier(.4,0,.2,1);cursor:not-allowed;pointer-events:auto}
|
|
176
|
+
.tour-highlight{z-index:100001}
|
|
177
|
+
.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;user-select:none}
|
|
178
|
+
.tg-btn:hover{color:var(--tg-primary);border-color:var(--tg-primary);background:#ecf5ff}
|
|
179
|
+
.tg-btn--sm{padding:5px 11px;font-size:12px}
|
|
180
|
+
.tg-btn--primary{background:var(--tg-primary);border-color:var(--tg-primary);color:#fff}
|
|
181
|
+
.tg-btn--primary:hover{opacity:.85;background:var(--tg-primary);color:#fff}
|
|
182
|
+
.tg-btn--warning{background:var(--tg-warning);border-color:var(--tg-warning);color:#fff}
|
|
183
|
+
.tg-btn--warning:hover{opacity:.85;background:var(--tg-warning);color:#fff}
|
|
184
|
+
.tg-btn--link{border:none;background:none;padding:4px 6px;color:var(--tg-text-3)}
|
|
185
|
+
.tg-btn--link:hover{color:var(--tg-primary);background:none}
|
|
186
|
+
.tour-popover{z-index:100002;background:#fff;border-radius:12px;padding:20px 24px;box-shadow:0 8px 40px rgba(0,0,0,.12),0 2px 8px rgba(0,0,0,.06);animation:tg-tp-in .3s ease;pointer-events:auto;min-width:280px;max-width:420px}
|
|
187
|
+
@keyframes tg-tp-in{from{opacity:0;transform:translateY(6px) scale(.97)}to{opacity:1;transform:translateY(0) scale(1)}}
|
|
188
|
+
.tp-head{display:flex;align-items:center;gap:10px;margin-bottom:12px}
|
|
189
|
+
.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}
|
|
190
|
+
.tp-required{color:var(--tg-danger);font-size:20px;font-weight:700;line-height:1}
|
|
191
|
+
.tp-title{font-size:16px;font-weight:700;color:var(--tg-text-1)}
|
|
192
|
+
.tp-of{font-size:13px;color:var(--tg-text-3);margin-left:auto;font-variant-numeric:tabular-nums}
|
|
193
|
+
.tp-content{margin:0 0 14px;font-size:14px;line-height:1.8;color:var(--tg-text-2);white-space:pre-line}
|
|
194
|
+
.tp-tip{font-size:13px;color:#529b2e;background:#f0f9eb;padding:8px 12px;border-radius:6px;margin-bottom:10px;border-left:3px solid #67c23a}
|
|
195
|
+
.tp-warn{font-size:13px;color:#b88230;background:#fdf6ec;padding:8px 12px;border-radius:6px;margin-bottom:10px;border-left:3px solid #e6a23c}
|
|
196
|
+
.tp-foot{display:flex;align-items:center;justify-content:space-between;padding-top:14px;border-top:1px solid var(--tg-border)}
|
|
197
|
+
.tp-btns{display:flex;gap:10px}
|
|
198
|
+
.tp-gate{display:inline-flex;align-items:center;gap:5px;font-size:13px;color:var(--tg-warning);font-weight:500}
|
|
199
|
+
.tp-gate-icon{flex-shrink:0}
|
|
200
|
+
.tp-click-hint{font-size:14px;color:var(--tg-primary);font-weight:500;animation:tg-pulse 1.5s ease-in-out infinite}
|
|
201
|
+
@keyframes tg-pulse{0%,100%{opacity:1}50%{opacity:.5}}
|
|
202
|
+
.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 rgba(0,0,0,.15);text-align:center;pointer-events:auto;display:flex;flex-direction:column;align-items:center;gap:8px}
|
|
203
|
+
.tour-waiting p{margin:4px 0 8px;font-size:14px;color:var(--tg-text-2)}
|
|
204
|
+
.tg-spin{animation:tg-rotate 1s linear infinite}
|
|
205
|
+
@keyframes tg-rotate{from{transform:rotate(0)}to{transform:rotate(360deg)}}
|
|
206
|
+
`;
|
|
207
|
+
let F = !1;
|
|
208
|
+
function mt() {
|
|
209
|
+
if (F || typeof document > "u") return;
|
|
210
|
+
if (document.getElementById(q)) {
|
|
211
|
+
F = !0;
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
const t = document.createElement("style");
|
|
215
|
+
t.id = q, t.textContent = xt, document.head.appendChild(t), F = !0;
|
|
216
|
+
}
|
|
217
|
+
const bt = {
|
|
175
218
|
key: 0,
|
|
176
219
|
class: "tour-root"
|
|
177
|
-
},
|
|
220
|
+
}, wt = { class: "tp-head" }, yt = {
|
|
178
221
|
key: 0,
|
|
179
222
|
class: "tp-required"
|
|
180
|
-
},
|
|
223
|
+
}, kt = { class: "tp-title" }, Tt = { class: "tp-of" }, _t = { class: "tp-content" }, zt = {
|
|
181
224
|
key: 0,
|
|
182
225
|
class: "tp-tip"
|
|
183
|
-
},
|
|
226
|
+
}, Et = {
|
|
184
227
|
key: 1,
|
|
185
228
|
class: "tp-warn"
|
|
186
|
-
},
|
|
229
|
+
}, $t = { class: "tp-foot" }, Ct = {
|
|
187
230
|
key: 0,
|
|
188
231
|
class: "tp-click-hint"
|
|
189
|
-
},
|
|
232
|
+
}, St = {
|
|
190
233
|
key: 1,
|
|
191
234
|
class: "tp-btns"
|
|
192
|
-
},
|
|
235
|
+
}, Lt = {
|
|
193
236
|
key: 2,
|
|
194
237
|
class: "tp-gate"
|
|
195
|
-
},
|
|
238
|
+
}, Rt = {
|
|
196
239
|
key: 2,
|
|
197
240
|
class: "tour-waiting"
|
|
198
|
-
},
|
|
241
|
+
}, It = {
|
|
199
242
|
key: 0,
|
|
200
243
|
class: "tg-spin",
|
|
201
244
|
viewBox: "0 0 1024 1024",
|
|
202
245
|
width: "28",
|
|
203
246
|
height: "28",
|
|
204
247
|
fill: "currentColor"
|
|
205
|
-
},
|
|
248
|
+
}, Mt = {
|
|
206
249
|
key: 1,
|
|
207
250
|
viewBox: "0 0 1024 1024",
|
|
208
251
|
width: "28",
|
|
209
252
|
height: "28",
|
|
210
253
|
fill: "#e6a23c"
|
|
211
|
-
},
|
|
254
|
+
}, Pt = /* @__PURE__ */ ot({
|
|
212
255
|
__name: "TourOverlay",
|
|
213
256
|
setup(t) {
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
257
|
+
mt();
|
|
258
|
+
const n = o;
|
|
259
|
+
function r(e) {
|
|
260
|
+
e.key === "Escape" && n.active && O();
|
|
217
261
|
}
|
|
218
|
-
|
|
219
|
-
e ? window.addEventListener("keydown",
|
|
220
|
-
}),
|
|
221
|
-
const
|
|
262
|
+
it(() => n.active, (e) => {
|
|
263
|
+
e ? window.addEventListener("keydown", r) : window.removeEventListener("keydown", r);
|
|
264
|
+
}), rt(() => window.removeEventListener("keydown", r));
|
|
265
|
+
const i = p(() => pt()), w = p(() => n.highlightRect), x = p(() => {
|
|
222
266
|
var e, a;
|
|
223
|
-
return ((e =
|
|
224
|
-
}),
|
|
225
|
-
const e =
|
|
267
|
+
return ((e = i.value) == null ? void 0 : e.accent) ?? ((a = n.config) == null ? void 0 : a.accent) ?? "#409eff";
|
|
268
|
+
}), S = p(() => n.stepIndex >= n.totalSteps - 1), f = p(() => {
|
|
269
|
+
const e = i.value;
|
|
226
270
|
return e ? !e.gate && e.trigger === "manual" : !1;
|
|
227
271
|
});
|
|
228
|
-
function
|
|
229
|
-
const e =
|
|
272
|
+
function I() {
|
|
273
|
+
const e = w.value;
|
|
230
274
|
return e ? {
|
|
231
275
|
top: { left: 0, top: 0, width: "100vw", height: `${Math.max(e.top, 0)}px` },
|
|
232
276
|
bottom: { left: 0, top: `${e.top + e.height}px`, width: "100vw", height: `calc(100vh - ${e.top + e.height}px)` },
|
|
@@ -234,20 +278,20 @@ const ht = {
|
|
|
234
278
|
right: { left: `${e.left + e.width}px`, top: `${e.top}px`, width: `calc(100vw - ${e.left + e.width}px)`, height: `${e.height}px` }
|
|
235
279
|
} : null;
|
|
236
280
|
}
|
|
237
|
-
const y =
|
|
281
|
+
const y = p(I), W = p(() => {
|
|
238
282
|
var e;
|
|
239
283
|
return ((e = y.value) == null ? void 0 : e.top) ?? { display: "none" };
|
|
240
|
-
}),
|
|
284
|
+
}), A = p(() => {
|
|
241
285
|
var e;
|
|
242
286
|
return ((e = y.value) == null ? void 0 : e.bottom) ?? { display: "none" };
|
|
243
|
-
}),
|
|
287
|
+
}), X = p(() => {
|
|
244
288
|
var e;
|
|
245
289
|
return ((e = y.value) == null ? void 0 : e.left) ?? { display: "none" };
|
|
246
|
-
}),
|
|
290
|
+
}), Z = p(() => {
|
|
247
291
|
var e;
|
|
248
292
|
return ((e = y.value) == null ? void 0 : e.right) ?? { display: "none" };
|
|
249
|
-
}),
|
|
250
|
-
const e =
|
|
293
|
+
}), tt = p(() => {
|
|
294
|
+
const e = w.value;
|
|
251
295
|
return e ? {
|
|
252
296
|
position: "fixed",
|
|
253
297
|
top: `${e.top}px`,
|
|
@@ -255,145 +299,140 @@ const ht = {
|
|
|
255
299
|
width: `${e.width}px`,
|
|
256
300
|
height: `${e.height}px`,
|
|
257
301
|
borderRadius: "8px",
|
|
258
|
-
border: `2px solid ${
|
|
259
|
-
boxShadow: `0 0 0 3px ${
|
|
302
|
+
border: `2px solid ${x.value}`,
|
|
303
|
+
boxShadow: `0 0 0 3px ${x.value}33, 0 0 20px ${x.value}44`,
|
|
260
304
|
pointerEvents: "none",
|
|
261
305
|
transition: "all 0.35s cubic-bezier(0.4,0,0.2,1)"
|
|
262
306
|
} : { display: "none" };
|
|
263
|
-
}),
|
|
264
|
-
var
|
|
265
|
-
const e =
|
|
307
|
+
}), et = p(() => {
|
|
308
|
+
var H;
|
|
309
|
+
const e = w.value;
|
|
266
310
|
if (!e) return { position: "fixed", top: "50%", left: "50%", transform: "translate(-50%,-50%)" };
|
|
267
|
-
const a = ((
|
|
311
|
+
const a = ((H = i.value) == null ? void 0 : H.placement) ?? "bottom", k = 14, g = { position: "fixed", zIndex: 100002 };
|
|
268
312
|
switch (a) {
|
|
269
313
|
case "top":
|
|
270
|
-
return { ...
|
|
314
|
+
return { ...g, left: `${e.left}px`, bottom: `calc(100vh - ${e.top - k}px)`, maxWidth: "420px" };
|
|
271
315
|
case "bottom":
|
|
272
|
-
return { ...
|
|
316
|
+
return { ...g, left: `${e.left}px`, top: `${e.top + e.height + k}px`, maxWidth: "420px" };
|
|
273
317
|
case "left":
|
|
274
|
-
return { ...
|
|
318
|
+
return { ...g, right: `calc(100vw - ${e.left - k}px)`, top: `${e.top}px`, maxWidth: "360px" };
|
|
275
319
|
case "right":
|
|
276
|
-
return { ...
|
|
320
|
+
return { ...g, left: `${e.left + e.width + k}px`, top: `${e.top}px`, maxWidth: "360px" };
|
|
277
321
|
default:
|
|
278
|
-
return { ...
|
|
322
|
+
return { ...g, top: "50%", left: "50%", transform: "translate(-50%,-50%)", maxWidth: "480px" };
|
|
279
323
|
}
|
|
280
324
|
});
|
|
281
|
-
function
|
|
325
|
+
function M() {
|
|
282
326
|
}
|
|
283
327
|
return (e, a) => {
|
|
284
|
-
var
|
|
285
|
-
return
|
|
286
|
-
c(n).active ? (
|
|
287
|
-
|
|
328
|
+
var k;
|
|
329
|
+
return s(), at(lt, { to: "body" }, [
|
|
330
|
+
c(n).active ? (s(), u("div", bt, [
|
|
331
|
+
l("div", {
|
|
288
332
|
class: "tour-mask",
|
|
289
|
-
style:
|
|
290
|
-
onClick:
|
|
333
|
+
style: m(W.value),
|
|
334
|
+
onClick: M
|
|
291
335
|
}, null, 4),
|
|
292
|
-
|
|
336
|
+
l("div", {
|
|
293
337
|
class: "tour-mask",
|
|
294
|
-
style:
|
|
295
|
-
onClick:
|
|
338
|
+
style: m(A.value),
|
|
339
|
+
onClick: M
|
|
296
340
|
}, null, 4),
|
|
297
|
-
|
|
341
|
+
l("div", {
|
|
298
342
|
class: "tour-mask",
|
|
299
|
-
style:
|
|
300
|
-
onClick:
|
|
343
|
+
style: m(X.value),
|
|
344
|
+
onClick: M
|
|
301
345
|
}, null, 4),
|
|
302
|
-
|
|
346
|
+
l("div", {
|
|
303
347
|
class: "tour-mask",
|
|
304
|
-
style:
|
|
305
|
-
onClick:
|
|
348
|
+
style: m(Z.value),
|
|
349
|
+
onClick: M
|
|
306
350
|
}, null, 4),
|
|
307
|
-
|
|
351
|
+
w.value ? (s(), u("div", {
|
|
308
352
|
key: 0,
|
|
309
353
|
class: "tour-highlight",
|
|
310
|
-
style:
|
|
311
|
-
}, null, 4)) :
|
|
312
|
-
|
|
354
|
+
style: m(tt.value)
|
|
355
|
+
}, null, 4)) : h("", !0),
|
|
356
|
+
i.value && !c(n).waitingTarget ? (s(), u("div", {
|
|
313
357
|
key: 1,
|
|
314
358
|
class: "tour-popover",
|
|
315
|
-
style:
|
|
359
|
+
style: m(et.value)
|
|
316
360
|
}, [
|
|
317
|
-
|
|
318
|
-
|
|
361
|
+
l("div", wt, [
|
|
362
|
+
l("span", {
|
|
319
363
|
class: "tp-step-no",
|
|
320
|
-
style:
|
|
321
|
-
},
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
364
|
+
style: m({ background: x.value })
|
|
365
|
+
}, d(c(n).stepIndex + 1), 5),
|
|
366
|
+
i.value.gate ? (s(), u("span", yt, "*")) : h("", !0),
|
|
367
|
+
l("span", kt, d(i.value.title), 1),
|
|
368
|
+
l("span", Tt, "第 " + d(c(n).stepIndex + 1) + " / " + d(c(n).totalSteps) + " 步", 1)
|
|
325
369
|
]),
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
370
|
+
l("p", _t, d(i.value.content), 1),
|
|
371
|
+
i.value.tip ? (s(), u("div", zt, "💡 " + d(i.value.tip), 1)) : h("", !0),
|
|
372
|
+
i.value.warn ? (s(), u("div", Et, "⚠️ " + d(i.value.warn), 1)) : h("", !0),
|
|
373
|
+
l("div", $t, [
|
|
374
|
+
l("button", {
|
|
331
375
|
class: "tg-btn tg-btn--link tg-btn--sm",
|
|
332
|
-
onClick: a[0] || (a[0] = (
|
|
376
|
+
onClick: a[0] || (a[0] = (g) => c(O)())
|
|
333
377
|
}, "退出引导"),
|
|
334
|
-
|
|
335
|
-
|
|
378
|
+
i.value.trigger === "click" ? (s(), u("span", Ct, " 👆 请点击高亮区域 ")) : c(n).gatePass ? (s(), u("span", St, [
|
|
379
|
+
f.value ? (s(), u("button", {
|
|
336
380
|
key: 0,
|
|
337
381
|
class: "tg-btn tg-btn--sm",
|
|
338
|
-
onClick: a[1] || (a[1] = (
|
|
339
|
-
}, "跳过此步")) :
|
|
340
|
-
|
|
382
|
+
onClick: a[1] || (a[1] = (g) => c(gt)())
|
|
383
|
+
}, "跳过此步")) : h("", !0),
|
|
384
|
+
l("button", {
|
|
341
385
|
class: "tg-btn tg-btn--primary tg-btn--sm",
|
|
342
|
-
style:
|
|
343
|
-
onClick: a[2] || (a[2] = (
|
|
344
|
-
},
|
|
345
|
-
])) : (
|
|
346
|
-
a[5] || (a[5] =
|
|
386
|
+
style: m({ background: x.value, borderColor: x.value }),
|
|
387
|
+
onClick: a[2] || (a[2] = (g) => c(b)())
|
|
388
|
+
}, d(S.value ? "完成" : "下一步"), 5)
|
|
389
|
+
])) : (s(), u("span", Lt, [
|
|
390
|
+
a[5] || (a[5] = l("svg", {
|
|
347
391
|
class: "tp-gate-icon",
|
|
348
392
|
viewBox: "0 0 1024 1024",
|
|
349
393
|
width: "14",
|
|
350
394
|
height: "14",
|
|
351
395
|
fill: "currentColor"
|
|
352
396
|
}, [
|
|
353
|
-
|
|
397
|
+
l("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" })
|
|
354
398
|
], -1)),
|
|
355
|
-
|
|
399
|
+
st(" " + d(i.value.gateHint || "请先完成本步操作"), 1)
|
|
356
400
|
]))
|
|
357
401
|
])
|
|
358
|
-
], 4)) :
|
|
359
|
-
c(n).waitingTarget ? (
|
|
360
|
-
c(n).waitTimedOut ? (
|
|
361
|
-
|
|
362
|
-
])])) : (
|
|
363
|
-
|
|
402
|
+
], 4)) : h("", !0),
|
|
403
|
+
c(n).waitingTarget ? (s(), u("div", Rt, [
|
|
404
|
+
c(n).waitTimedOut ? (s(), u("svg", Mt, [...a[7] || (a[7] = [
|
|
405
|
+
l("path", { d: "M512 64L64 896h896L512 64zm0 192l288 576H224l288-576zm-32 224v128h64V480h-64zm0 160v64h64v-64h-64z" }, null, -1)
|
|
406
|
+
])])) : (s(), u("svg", It, [...a[6] || (a[6] = [
|
|
407
|
+
l("path", {
|
|
364
408
|
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",
|
|
365
409
|
opacity: ".25"
|
|
366
410
|
}, null, -1),
|
|
367
|
-
|
|
411
|
+
l("path", { d: "M512 64a448 448 0 0 1 448 448h-64A384 384 0 0 0 512 128V64z" }, null, -1)
|
|
368
412
|
])])),
|
|
369
|
-
|
|
370
|
-
c(n).waitTimedOut ? (
|
|
413
|
+
l("p", null, d(c(n).waitTimedOut ? "未找到目标元素,可能是页面状态不符" : ((k = i.value) == null ? void 0 : k.content) ?? "等待页面加载..."), 1),
|
|
414
|
+
c(n).waitTimedOut ? (s(), u("button", {
|
|
371
415
|
key: 2,
|
|
372
416
|
class: "tg-btn tg-btn--warning tg-btn--sm",
|
|
373
|
-
onClick: a[3] || (a[3] = (
|
|
374
|
-
}, "跳过此步")) :
|
|
375
|
-
|
|
417
|
+
onClick: a[3] || (a[3] = (g) => c(b)())
|
|
418
|
+
}, "跳过此步")) : h("", !0),
|
|
419
|
+
l("button", {
|
|
376
420
|
class: "tg-btn tg-btn--sm",
|
|
377
|
-
onClick: a[4] || (a[4] = (
|
|
421
|
+
onClick: a[4] || (a[4] = (g) => c(O)())
|
|
378
422
|
}, "退出引导")
|
|
379
|
-
])) :
|
|
380
|
-
])) :
|
|
423
|
+
])) : h("", !0)
|
|
424
|
+
])) : h("", !0)
|
|
381
425
|
]);
|
|
382
426
|
};
|
|
383
427
|
}
|
|
384
|
-
})
|
|
385
|
-
const i = t.__vccOpts || t;
|
|
386
|
-
for (const [o, g] of n)
|
|
387
|
-
i[o] = g;
|
|
388
|
-
return i;
|
|
389
|
-
}, Ot = /* @__PURE__ */ It(St, [["__scopeId", "data-v-9602901d"]]);
|
|
428
|
+
});
|
|
390
429
|
export {
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
430
|
+
Pt as TourOverlay,
|
|
431
|
+
O as abort,
|
|
432
|
+
Y as complete,
|
|
433
|
+
pt as currentStep,
|
|
434
|
+
b as next,
|
|
435
|
+
gt as skip,
|
|
436
|
+
Ot as startTour,
|
|
437
|
+
o as tourState
|
|
399
438
|
};
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tour-guide-coach",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
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",
|
package/src/TourOverlay.vue
CHANGED
|
@@ -59,8 +59,11 @@
|
|
|
59
59
|
<script setup lang="ts">
|
|
60
60
|
import { computed, watch, onBeforeUnmount } from 'vue'
|
|
61
61
|
import { tourState, abort, next, skip, currentStep } from './store'
|
|
62
|
+
import { injectStyles } from './css'
|
|
62
63
|
import type { CSSProperties } from 'vue'
|
|
63
64
|
|
|
65
|
+
injectStyles()
|
|
66
|
+
|
|
64
67
|
const store = tourState
|
|
65
68
|
|
|
66
69
|
/** ESC 退出引导 */
|
|
@@ -132,108 +135,3 @@ const popoverStyle = computed<CSSProperties>(() => {
|
|
|
132
135
|
function onBlockedClick(): void { /* 静默拦截 */ }
|
|
133
136
|
</script>
|
|
134
137
|
|
|
135
|
-
<style scoped>
|
|
136
|
-
/* ---------- CSS 变量:自动 fallback 到 --el-*(兼容 EP 项目) ---------- */
|
|
137
|
-
.tour-root {
|
|
138
|
-
--tg-primary: var(--el-color-primary, #409eff);
|
|
139
|
-
--tg-success: var(--el-color-success, #67c23a);
|
|
140
|
-
--tg-warning: var(--el-color-warning, #e6a23c);
|
|
141
|
-
--tg-danger: var(--el-color-danger, #f56c6c);
|
|
142
|
-
--tg-text-1: var(--el-text-color-primary, #303133);
|
|
143
|
-
--tg-text-2: var(--el-text-color-regular, #606266);
|
|
144
|
-
--tg-text-3: var(--el-text-color-secondary, #909399);
|
|
145
|
-
--tg-border: var(--el-border-color-lighter, #ebeef5);
|
|
146
|
-
--tg-fill-light: var(--el-fill-color-light, #f5f7fa);
|
|
147
|
-
--tg-radius: var(--el-border-radius-base, 4px);
|
|
148
|
-
|
|
149
|
-
position: fixed; inset: 0; z-index: 100000;
|
|
150
|
-
pointer-events: none;
|
|
151
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/* ---------- 遮罩 ---------- */
|
|
155
|
-
.tour-mask {
|
|
156
|
-
position: fixed; background: rgba(0,0,0,0.55);
|
|
157
|
-
transition: all 0.35s cubic-bezier(0.4,0,0.2,1);
|
|
158
|
-
cursor: not-allowed; pointer-events: auto;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/* ---------- 高亮框 ---------- */
|
|
162
|
-
.tour-highlight { z-index: 100001; }
|
|
163
|
-
|
|
164
|
-
/* ---------- 按钮(EP 风格) ---------- */
|
|
165
|
-
.tg-btn {
|
|
166
|
-
display: inline-flex; align-items: center; justify-content: center;
|
|
167
|
-
border: 1px solid var(--tg-border); border-radius: var(--tg-radius);
|
|
168
|
-
background: #fff; color: var(--tg-text-2);
|
|
169
|
-
font-size: 14px; font-weight: 500; line-height: 1;
|
|
170
|
-
padding: 8px 15px; cursor: pointer;
|
|
171
|
-
transition: color .2s, border-color .2s, background .2s;
|
|
172
|
-
outline: none; white-space: nowrap; user-select: none;
|
|
173
|
-
}
|
|
174
|
-
.tg-btn:hover { color: var(--tg-primary); border-color: var(--tg-primary); background: #ecf5ff; }
|
|
175
|
-
.tg-btn--sm { padding: 5px 11px; font-size: 12px; }
|
|
176
|
-
.tg-btn--primary {
|
|
177
|
-
background: var(--tg-primary); border-color: var(--tg-primary); color: #fff;
|
|
178
|
-
}
|
|
179
|
-
.tg-btn--primary:hover { opacity: .85; background: var(--tg-primary); color: #fff; }
|
|
180
|
-
.tg-btn--warning {
|
|
181
|
-
background: var(--tg-warning); border-color: var(--tg-warning); color: #fff;
|
|
182
|
-
}
|
|
183
|
-
.tg-btn--warning:hover { opacity: .85; background: var(--tg-warning); color: #fff; }
|
|
184
|
-
.tg-btn--link {
|
|
185
|
-
border: none; background: none; padding: 4px 6px;
|
|
186
|
-
color: var(--tg-text-3);
|
|
187
|
-
}
|
|
188
|
-
.tg-btn--link:hover { color: var(--tg-primary); background: none; }
|
|
189
|
-
|
|
190
|
-
/* ---------- 气泡 ---------- */
|
|
191
|
-
.tour-popover {
|
|
192
|
-
z-index: 100002; background: #fff; border-radius: 12px;
|
|
193
|
-
padding: 20px 24px; box-shadow: 0 8px 40px rgba(0,0,0,0.12), 0 2px 8px rgba(0,0,0,0.06);
|
|
194
|
-
animation: tp-in 0.3s ease; pointer-events: auto;
|
|
195
|
-
min-width: 280px; max-width: 420px;
|
|
196
|
-
}
|
|
197
|
-
@keyframes tp-in {
|
|
198
|
-
from { opacity: 0; transform: translateY(6px) scale(0.97); }
|
|
199
|
-
to { opacity: 1; transform: translateY(0) scale(1); }
|
|
200
|
-
}
|
|
201
|
-
.tp-head { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
|
|
202
|
-
.tp-step-no {
|
|
203
|
-
display: inline-flex; align-items: center; justify-content: center;
|
|
204
|
-
width: 28px; height: 28px; border-radius: 50%;
|
|
205
|
-
color: #fff; font-size: 14px; font-weight: 700; flex-shrink: 0;
|
|
206
|
-
}
|
|
207
|
-
.tp-required { color: var(--tg-danger); font-size: 20px; font-weight: 700; line-height: 1; }
|
|
208
|
-
.tp-title { font-size: 16px; font-weight: 700; color: var(--tg-text-1); }
|
|
209
|
-
.tp-of { font-size: 13px; color: var(--tg-text-3); margin-left: auto; font-variant-numeric: tabular-nums; }
|
|
210
|
-
.tp-content { margin: 0 0 14px; font-size: 14px; line-height: 1.8; color: var(--tg-text-2); white-space: pre-line; }
|
|
211
|
-
.tp-tip {
|
|
212
|
-
font-size: 13px; color: #529b2e; background: #f0f9eb;
|
|
213
|
-
padding: 8px 12px; border-radius: 6px; margin-bottom: 10px;
|
|
214
|
-
border-left: 3px solid #67c23a;
|
|
215
|
-
}
|
|
216
|
-
.tp-warn {
|
|
217
|
-
font-size: 13px; color: #b88230; background: #fdf6ec;
|
|
218
|
-
padding: 8px 12px; border-radius: 6px; margin-bottom: 10px;
|
|
219
|
-
border-left: 3px solid #e6a23c;
|
|
220
|
-
}
|
|
221
|
-
.tp-foot { display: flex; align-items: center; justify-content: space-between; padding-top: 14px; border-top: 1px solid var(--tg-border); }
|
|
222
|
-
.tp-btns { display: flex; gap: 10px; }
|
|
223
|
-
.tp-gate { display: inline-flex; align-items: center; gap: 5px; font-size: 13px; color: var(--tg-warning); font-weight: 500; }
|
|
224
|
-
.tp-gate-icon { flex-shrink: 0; }
|
|
225
|
-
.tp-click-hint { font-size: 14px; color: var(--tg-primary); font-weight: 500; animation: pulse-hint 1.5s ease-in-out infinite; }
|
|
226
|
-
@keyframes pulse-hint { 0%,100%{opacity:1} 50%{opacity:.5} }
|
|
227
|
-
|
|
228
|
-
/* ---------- 等待态 ---------- */
|
|
229
|
-
.tour-waiting {
|
|
230
|
-
position: fixed; top: 50%; left: 50%; transform: translate(-50%,-50%);
|
|
231
|
-
z-index: 100002; background: #fff; padding: 32px 40px;
|
|
232
|
-
border-radius: 12px; box-shadow: 0 8px 32px rgba(0,0,0,0.15);
|
|
233
|
-
text-align: center; pointer-events: auto;
|
|
234
|
-
display: flex; flex-direction: column; align-items: center; gap: 8px;
|
|
235
|
-
}
|
|
236
|
-
.tour-waiting p { margin: 4px 0 8px; font-size: 14px; color: var(--tg-text-2); }
|
|
237
|
-
.tg-spin { animation: tg-rotate 1s linear infinite; }
|
|
238
|
-
@keyframes tg-rotate { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
|
|
239
|
-
</style>
|
package/src/css.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CSS 自动注入:组件模块加载时把样式注入到 <head>。
|
|
3
|
+
* 不依赖任何构建插件,不管 Vite/Webpack/Rollup 怎么处理预构建都可靠。
|
|
4
|
+
*/
|
|
5
|
+
const STYLE_ID = 'tour-guide-coach-styles'
|
|
6
|
+
|
|
7
|
+
const CSS = `
|
|
8
|
+
.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;inset:0;z-index:100000;pointer-events:none;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',sans-serif}
|
|
9
|
+
.tour-mask{position:fixed;background:rgba(0,0,0,.55);transition:all .35s cubic-bezier(.4,0,.2,1);cursor:not-allowed;pointer-events:auto}
|
|
10
|
+
.tour-highlight{z-index:100001}
|
|
11
|
+
.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;user-select:none}
|
|
12
|
+
.tg-btn:hover{color:var(--tg-primary);border-color:var(--tg-primary);background:#ecf5ff}
|
|
13
|
+
.tg-btn--sm{padding:5px 11px;font-size:12px}
|
|
14
|
+
.tg-btn--primary{background:var(--tg-primary);border-color:var(--tg-primary);color:#fff}
|
|
15
|
+
.tg-btn--primary:hover{opacity:.85;background:var(--tg-primary);color:#fff}
|
|
16
|
+
.tg-btn--warning{background:var(--tg-warning);border-color:var(--tg-warning);color:#fff}
|
|
17
|
+
.tg-btn--warning:hover{opacity:.85;background:var(--tg-warning);color:#fff}
|
|
18
|
+
.tg-btn--link{border:none;background:none;padding:4px 6px;color:var(--tg-text-3)}
|
|
19
|
+
.tg-btn--link:hover{color:var(--tg-primary);background:none}
|
|
20
|
+
.tour-popover{z-index:100002;background:#fff;border-radius:12px;padding:20px 24px;box-shadow:0 8px 40px rgba(0,0,0,.12),0 2px 8px rgba(0,0,0,.06);animation:tg-tp-in .3s ease;pointer-events:auto;min-width:280px;max-width:420px}
|
|
21
|
+
@keyframes tg-tp-in{from{opacity:0;transform:translateY(6px) scale(.97)}to{opacity:1;transform:translateY(0) scale(1)}}
|
|
22
|
+
.tp-head{display:flex;align-items:center;gap:10px;margin-bottom:12px}
|
|
23
|
+
.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}
|
|
24
|
+
.tp-required{color:var(--tg-danger);font-size:20px;font-weight:700;line-height:1}
|
|
25
|
+
.tp-title{font-size:16px;font-weight:700;color:var(--tg-text-1)}
|
|
26
|
+
.tp-of{font-size:13px;color:var(--tg-text-3);margin-left:auto;font-variant-numeric:tabular-nums}
|
|
27
|
+
.tp-content{margin:0 0 14px;font-size:14px;line-height:1.8;color:var(--tg-text-2);white-space:pre-line}
|
|
28
|
+
.tp-tip{font-size:13px;color:#529b2e;background:#f0f9eb;padding:8px 12px;border-radius:6px;margin-bottom:10px;border-left:3px solid #67c23a}
|
|
29
|
+
.tp-warn{font-size:13px;color:#b88230;background:#fdf6ec;padding:8px 12px;border-radius:6px;margin-bottom:10px;border-left:3px solid #e6a23c}
|
|
30
|
+
.tp-foot{display:flex;align-items:center;justify-content:space-between;padding-top:14px;border-top:1px solid var(--tg-border)}
|
|
31
|
+
.tp-btns{display:flex;gap:10px}
|
|
32
|
+
.tp-gate{display:inline-flex;align-items:center;gap:5px;font-size:13px;color:var(--tg-warning);font-weight:500}
|
|
33
|
+
.tp-gate-icon{flex-shrink:0}
|
|
34
|
+
.tp-click-hint{font-size:14px;color:var(--tg-primary);font-weight:500;animation:tg-pulse 1.5s ease-in-out infinite}
|
|
35
|
+
@keyframes tg-pulse{0%,100%{opacity:1}50%{opacity:.5}}
|
|
36
|
+
.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 rgba(0,0,0,.15);text-align:center;pointer-events:auto;display:flex;flex-direction:column;align-items:center;gap:8px}
|
|
37
|
+
.tour-waiting p{margin:4px 0 8px;font-size:14px;color:var(--tg-text-2)}
|
|
38
|
+
.tg-spin{animation:tg-rotate 1s linear infinite}
|
|
39
|
+
@keyframes tg-rotate{from{transform:rotate(0)}to{transform:rotate(360deg)}}
|
|
40
|
+
`
|
|
41
|
+
|
|
42
|
+
let injected = false
|
|
43
|
+
|
|
44
|
+
export function injectStyles(): void {
|
|
45
|
+
if (injected || typeof document === 'undefined') return
|
|
46
|
+
if (document.getElementById(STYLE_ID)) { injected = true; return }
|
|
47
|
+
const style = document.createElement('style')
|
|
48
|
+
style.id = STYLE_ID
|
|
49
|
+
style.textContent = CSS
|
|
50
|
+
document.head.appendChild(style)
|
|
51
|
+
injected = true
|
|
52
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
*
|
|
6
6
|
* 使用方式:
|
|
7
7
|
* import { startTour, TourOverlay } from 'tour-guide-coach'
|
|
8
|
-
* import 'tour-guide-coach/dist/style.css'
|
|
9
8
|
* // 在 layout 中挂 <TourOverlay />
|
|
10
9
|
* // 业务页调用 startTour(config)
|
|
10
|
+
* // CSS 已内联到 JS,无需手动引入样式文件
|
|
11
11
|
*/
|
|
12
12
|
export { tourState, startTour, abort, next, skip, complete, currentStep } from './store'
|
|
13
13
|
export type { TargetResolver } from './store'
|