@trailguide/core 0.0.1

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.
@@ -0,0 +1,27 @@
1
+ (function(w,S){typeof exports=="object"&&typeof module<"u"?S(exports):typeof define=="function"&&define.amd?define(["exports"],S):(w=typeof globalThis<"u"?globalThis:w||self,S(w.Trailguide={}))})(this,function(w){"use strict";var He=Object.defineProperty;var Ie=(w,S,T)=>S in w?He(w,S,{enumerable:!0,configurable:!0,writable:!0,value:T}):w[S]=T;var M=(w,S,T)=>Ie(w,typeof S!="symbol"?S+"":S,T);const S=Math.min,T=Math.max,it=Math.round,$=t=>({x:t,y:t}),It={left:"right",right:"left",bottom:"top",top:"bottom"},qt={start:"end",end:"start"};function ut(t,e,i){return T(t,S(e,i))}function J(t,e){return typeof t=="function"?t(e):t}function q(t){return t.split("-")[0]}function Q(t){return t.split("-")[1]}function xt(t){return t==="x"?"y":"x"}function dt(t){return t==="y"?"height":"width"}const jt=new Set(["top","bottom"]);function W(t){return jt.has(q(t))?"y":"x"}function ht(t){return xt(W(t))}function Xt(t,e,i){i===void 0&&(i=!1);const n=Q(t),o=ht(t),s=dt(o);let r=o==="x"?n===(i?"end":"start")?"right":"left":n==="start"?"bottom":"top";return e.reference[s]>e.floating[s]&&(r=ot(r)),[r,ot(r)]}function _t(t){const e=ot(t);return[pt(t),e,pt(e)]}function pt(t){return t.replace(/start|end/g,e=>qt[e])}const vt=["left","right"],bt=["right","left"],Yt=["top","bottom"],zt=["bottom","top"];function Kt(t,e,i){switch(t){case"top":case"bottom":return i?e?bt:vt:e?vt:bt;case"left":case"right":return e?Yt:zt;default:return[]}}function Gt(t,e,i,n){const o=Q(t);let s=Kt(q(t),i==="start",n);return o&&(s=s.map(r=>r+"-"+o),e&&(s=s.concat(s.map(pt)))),s}function ot(t){return t.replace(/left|right|bottom|top/g,e=>It[e])}function Jt(t){return{top:0,right:0,bottom:0,left:0,...t}}function St(t){return typeof t!="number"?Jt(t):{top:t,right:t,bottom:t,left:t}}function st(t){const{x:e,y:i,width:n,height:o}=t;return{width:n,height:o,top:i,left:e,right:e+n,bottom:i+o,x:e,y:i}}function At(t,e,i){let{reference:n,floating:o}=t;const s=W(e),r=ht(e),l=dt(r),c=q(e),a=s==="y",d=n.x+n.width/2-o.width/2,u=n.y+n.height/2-o.height/2,p=n[l]/2-o[l]/2;let f;switch(c){case"top":f={x:d,y:n.y-o.height};break;case"bottom":f={x:d,y:n.y+n.height};break;case"right":f={x:n.x+n.width,y:u};break;case"left":f={x:n.x-o.width,y:u};break;default:f={x:n.x,y:n.y}}switch(Q(e)){case"start":f[r]-=p*(i&&a?-1:1);break;case"end":f[r]+=p*(i&&a?-1:1);break}return f}async function Qt(t,e){var i;e===void 0&&(e={});const{x:n,y:o,platform:s,rects:r,elements:l,strategy:c}=t,{boundary:a="clippingAncestors",rootBoundary:d="viewport",elementContext:u="floating",altBoundary:p=!1,padding:f=0}=J(e,t),h=St(f),m=l[p?u==="floating"?"reference":"floating":u],y=st(await s.getClippingRect({element:(i=await(s.isElement==null?void 0:s.isElement(m)))==null||i?m:m.contextElement||await(s.getDocumentElement==null?void 0:s.getDocumentElement(l.floating)),boundary:a,rootBoundary:d,strategy:c})),x=u==="floating"?{x:n,y:o,width:r.floating.width,height:r.floating.height}:r.reference,v=await(s.getOffsetParent==null?void 0:s.getOffsetParent(l.floating)),b=await(s.isElement==null?void 0:s.isElement(v))?await(s.getScale==null?void 0:s.getScale(v))||{x:1,y:1}:{x:1,y:1},k=st(s.convertOffsetParentRelativeRectToViewportRelativeRect?await s.convertOffsetParentRelativeRectToViewportRelativeRect({elements:l,rect:x,offsetParent:v,strategy:c}):x);return{top:(y.top-k.top+h.top)/b.y,bottom:(k.bottom-y.bottom+h.bottom)/b.y,left:(y.left-k.left+h.left)/b.x,right:(k.right-y.right+h.right)/b.x}}const Ut=async(t,e,i)=>{const{placement:n="bottom",strategy:o="absolute",middleware:s=[],platform:r}=i,l=s.filter(Boolean),c=await(r.isRTL==null?void 0:r.isRTL(e));let a=await r.getElementRects({reference:t,floating:e,strategy:o}),{x:d,y:u}=At(a,n,c),p=n,f={},h=0;for(let m=0;m<l.length;m++){var g;const{name:y,fn:x}=l[m],{x:v,y:b,data:k,reset:E}=await x({x:d,y:u,initialPlacement:n,placement:p,strategy:o,middlewareData:f,rects:a,platform:{...r,detectOverflow:(g=r.detectOverflow)!=null?g:Qt},elements:{reference:t,floating:e}});d=v??d,u=b??u,f={...f,[y]:{...f[y],...k}},E&&h<=50&&(h++,typeof E=="object"&&(E.placement&&(p=E.placement),E.rects&&(a=E.rects===!0?await r.getElementRects({reference:t,floating:e,strategy:o}):E.rects),{x:d,y:u}=At(a,p,c)),m=-1)}return{x:d,y:u,placement:p,strategy:o,middlewareData:f}},Zt=t=>({name:"arrow",options:t,async fn(e){const{x:i,y:n,placement:o,rects:s,platform:r,elements:l,middlewareData:c}=e,{element:a,padding:d=0}=J(t,e)||{};if(a==null)return{};const u=St(d),p={x:i,y:n},f=ht(o),h=dt(f),g=await r.getDimensions(a),m=f==="y",y=m?"top":"left",x=m?"bottom":"right",v=m?"clientHeight":"clientWidth",b=s.reference[h]+s.reference[f]-p[f]-s.floating[h],k=p[f]-s.reference[f],E=await(r.getOffsetParent==null?void 0:r.getOffsetParent(a));let j=E?E[v]:0;(!j||!await(r.isElement==null?void 0:r.isElement(E)))&&(j=l.floating[v]||s.floating[h]);const tt=b/2-k/2,X=j/2-g[h]/2-1,V=S(u[y],X),et=S(u[x],X),_=V,nt=j-g[h]-et,C=j/2-g[h]/2+tt,Y=ut(_,C,nt),N=!c.arrow&&Q(o)!=null&&C!==Y&&s.reference[h]/2-(C<_?V:et)-g[h]/2<0,P=N?C<_?C-_:C-nt:0;return{[f]:p[f]+P,data:{[f]:Y,centerOffset:C-Y-P,...N&&{alignmentOffset:P}},reset:N}}}),te=function(t){return t===void 0&&(t={}),{name:"flip",options:t,async fn(e){var i,n;const{placement:o,middlewareData:s,rects:r,initialPlacement:l,platform:c,elements:a}=e,{mainAxis:d=!0,crossAxis:u=!0,fallbackPlacements:p,fallbackStrategy:f="bestFit",fallbackAxisSideDirection:h="none",flipAlignment:g=!0,...m}=J(t,e);if((i=s.arrow)!=null&&i.alignmentOffset)return{};const y=q(o),x=W(l),v=q(l)===l,b=await(c.isRTL==null?void 0:c.isRTL(a.floating)),k=p||(v||!g?[ot(l)]:_t(l)),E=h!=="none";!p&&E&&k.push(...Gt(l,g,h,b));const j=[l,...k],tt=await c.detectOverflow(e,m),X=[];let V=((n=s.flip)==null?void 0:n.overflows)||[];if(d&&X.push(tt[y]),u){const C=Xt(o,r,b);X.push(tt[C[0]],tt[C[1]])}if(V=[...V,{placement:o,overflows:X}],!X.every(C=>C<=0)){var et,_;const C=(((et=s.flip)==null?void 0:et.index)||0)+1,Y=j[C];if(Y&&(!(u==="alignment"?x!==W(Y):!1)||V.every(D=>W(D.placement)===x?D.overflows[0]>0:!0)))return{data:{index:C,overflows:V},reset:{placement:Y}};let N=(_=V.filter(P=>P.overflows[0]<=0).sort((P,D)=>P.overflows[1]-D.overflows[1])[0])==null?void 0:_.placement;if(!N)switch(f){case"bestFit":{var nt;const P=(nt=V.filter(D=>{if(E){const I=W(D.placement);return I===x||I==="y"}return!0}).map(D=>[D.placement,D.overflows.filter(I=>I>0).reduce((I,We)=>I+We,0)]).sort((D,I)=>D[1]-I[1])[0])==null?void 0:nt[0];P&&(N=P);break}case"initialPlacement":N=l;break}if(o!==N)return{reset:{placement:N}}}return{}}}},ee=new Set(["left","top"]);async function ne(t,e){const{placement:i,platform:n,elements:o}=t,s=await(n.isRTL==null?void 0:n.isRTL(o.floating)),r=q(i),l=Q(i),c=W(i)==="y",a=ee.has(r)?-1:1,d=s&&c?-1:1,u=J(e,t);let{mainAxis:p,crossAxis:f,alignmentAxis:h}=typeof u=="number"?{mainAxis:u,crossAxis:0,alignmentAxis:null}:{mainAxis:u.mainAxis||0,crossAxis:u.crossAxis||0,alignmentAxis:u.alignmentAxis};return l&&typeof h=="number"&&(f=l==="end"?h*-1:h),c?{x:f*d,y:p*a}:{x:p*a,y:f*d}}const ie=function(t){return t===void 0&&(t=0),{name:"offset",options:t,async fn(e){var i,n;const{x:o,y:s,placement:r,middlewareData:l}=e,c=await ne(e,t);return r===((i=l.offset)==null?void 0:i.placement)&&(n=l.arrow)!=null&&n.alignmentOffset?{}:{x:o+c.x,y:s+c.y,data:{...c,placement:r}}}}},oe=function(t){return t===void 0&&(t={}),{name:"shift",options:t,async fn(e){const{x:i,y:n,placement:o,platform:s}=e,{mainAxis:r=!0,crossAxis:l=!1,limiter:c={fn:y=>{let{x,y:v}=y;return{x,y:v}}},...a}=J(t,e),d={x:i,y:n},u=await s.detectOverflow(e,a),p=W(q(o)),f=xt(p);let h=d[f],g=d[p];if(r){const y=f==="y"?"top":"left",x=f==="y"?"bottom":"right",v=h+u[y],b=h-u[x];h=ut(v,h,b)}if(l){const y=p==="y"?"top":"left",x=p==="y"?"bottom":"right",v=g+u[y],b=g-u[x];g=ut(v,g,b)}const m=c.fn({...e,[f]:h,[p]:g});return{...m,data:{x:m.x-i,y:m.y-n,enabled:{[f]:r,[p]:l}}}}}};function rt(){return typeof window<"u"}function z(t){return Ct(t)?(t.nodeName||"").toLowerCase():"#document"}function O(t){var e;return(t==null||(e=t.ownerDocument)==null?void 0:e.defaultView)||window}function B(t){var e;return(e=(Ct(t)?t.ownerDocument:t.document)||window.document)==null?void 0:e.documentElement}function Ct(t){return rt()?t instanceof Node||t instanceof O(t).Node:!1}function L(t){return rt()?t instanceof Element||t instanceof O(t).Element:!1}function F(t){return rt()?t instanceof HTMLElement||t instanceof O(t).HTMLElement:!1}function Et(t){return!rt()||typeof ShadowRoot>"u"?!1:t instanceof ShadowRoot||t instanceof O(t).ShadowRoot}const se=new Set(["inline","contents"]);function U(t){const{overflow:e,overflowX:i,overflowY:n,display:o}=R(t);return/auto|scroll|overlay|hidden|clip/.test(e+n+i)&&!se.has(o)}const re=new Set(["table","td","th"]);function le(t){return re.has(z(t))}const ce=[":popover-open",":modal"];function lt(t){return ce.some(e=>{try{return t.matches(e)}catch{return!1}})}const ae=["transform","translate","scale","rotate","perspective"],fe=["transform","translate","scale","rotate","perspective","filter"],ue=["paint","layout","strict","content"];function gt(t){const e=mt(),i=L(t)?R(t):t;return ae.some(n=>i[n]?i[n]!=="none":!1)||(i.containerType?i.containerType!=="normal":!1)||!e&&(i.backdropFilter?i.backdropFilter!=="none":!1)||!e&&(i.filter?i.filter!=="none":!1)||fe.some(n=>(i.willChange||"").includes(n))||ue.some(n=>(i.contain||"").includes(n))}function de(t){let e=H(t);for(;F(e)&&!K(e);){if(gt(e))return e;if(lt(e))return null;e=H(e)}return null}function mt(){return typeof CSS>"u"||!CSS.supports?!1:CSS.supports("-webkit-backdrop-filter","none")}const he=new Set(["html","body","#document"]);function K(t){return he.has(z(t))}function R(t){return O(t).getComputedStyle(t)}function ct(t){return L(t)?{scrollLeft:t.scrollLeft,scrollTop:t.scrollTop}:{scrollLeft:t.scrollX,scrollTop:t.scrollY}}function H(t){if(z(t)==="html")return t;const e=t.assignedSlot||t.parentNode||Et(t)&&t.host||B(t);return Et(e)?e.host:e}function Ot(t){const e=H(t);return K(e)?t.ownerDocument?t.ownerDocument.body:t.body:F(e)&&U(e)?e:Ot(e)}function Tt(t,e,i){var n;e===void 0&&(e=[]);const o=Ot(t),s=o===((n=t.ownerDocument)==null?void 0:n.body),r=O(o);return s?(wt(r),e.concat(r,r.visualViewport||[],U(o)?o:[],[])):e.concat(o,Tt(o,[]))}function wt(t){return t.parent&&Object.getPrototypeOf(t.parent)?t.frameElement:null}function Lt(t){const e=R(t);let i=parseFloat(e.width)||0,n=parseFloat(e.height)||0;const o=F(t),s=o?t.offsetWidth:i,r=o?t.offsetHeight:n,l=it(i)!==s||it(n)!==r;return l&&(i=s,n=r),{width:i,height:n,$:l}}function Rt(t){return L(t)?t:t.contextElement}function G(t){const e=Rt(t);if(!F(e))return $(1);const i=e.getBoundingClientRect(),{width:n,height:o,$:s}=Lt(e);let r=(s?it(i.width):i.width)/n,l=(s?it(i.height):i.height)/o;return(!r||!Number.isFinite(r))&&(r=1),(!l||!Number.isFinite(l))&&(l=1),{x:r,y:l}}const pe=$(0);function kt(t){const e=O(t);return!mt()||!e.visualViewport?pe:{x:e.visualViewport.offsetLeft,y:e.visualViewport.offsetTop}}function ge(t,e,i){return e===void 0&&(e=!1),!i||e&&i!==O(t)?!1:e}function Z(t,e,i,n){e===void 0&&(e=!1),i===void 0&&(i=!1);const o=t.getBoundingClientRect(),s=Rt(t);let r=$(1);e&&(n?L(n)&&(r=G(n)):r=G(t));const l=ge(s,i,n)?kt(s):$(0);let c=(o.left+l.x)/r.x,a=(o.top+l.y)/r.y,d=o.width/r.x,u=o.height/r.y;if(s){const p=O(s),f=n&&L(n)?O(n):n;let h=p,g=wt(h);for(;g&&n&&f!==h;){const m=G(g),y=g.getBoundingClientRect(),x=R(g),v=y.left+(g.clientLeft+parseFloat(x.paddingLeft))*m.x,b=y.top+(g.clientTop+parseFloat(x.paddingTop))*m.y;c*=m.x,a*=m.y,d*=m.x,u*=m.y,c+=v,a+=b,h=O(g),g=wt(h)}}return st({width:d,height:u,x:c,y:a})}function at(t,e){const i=ct(t).scrollLeft;return e?e.left+i:Z(B(t)).left+i}function Pt(t,e){const i=t.getBoundingClientRect(),n=i.left+e.scrollLeft-at(t,i),o=i.top+e.scrollTop;return{x:n,y:o}}function me(t){let{elements:e,rect:i,offsetParent:n,strategy:o}=t;const s=o==="fixed",r=B(n),l=e?lt(e.floating):!1;if(n===r||l&&s)return i;let c={scrollLeft:0,scrollTop:0},a=$(1);const d=$(0),u=F(n);if((u||!u&&!s)&&((z(n)!=="body"||U(r))&&(c=ct(n)),F(n))){const f=Z(n);a=G(n),d.x=f.x+n.clientLeft,d.y=f.y+n.clientTop}const p=r&&!u&&!s?Pt(r,c):$(0);return{width:i.width*a.x,height:i.height*a.y,x:i.x*a.x-c.scrollLeft*a.x+d.x+p.x,y:i.y*a.y-c.scrollTop*a.y+d.y+p.y}}function we(t){return Array.from(t.getClientRects())}function ye(t){const e=B(t),i=ct(t),n=t.ownerDocument.body,o=T(e.scrollWidth,e.clientWidth,n.scrollWidth,n.clientWidth),s=T(e.scrollHeight,e.clientHeight,n.scrollHeight,n.clientHeight);let r=-i.scrollLeft+at(t);const l=-i.scrollTop;return R(n).direction==="rtl"&&(r+=T(e.clientWidth,n.clientWidth)-o),{width:o,height:s,x:r,y:l}}const Dt=25;function xe(t,e){const i=O(t),n=B(t),o=i.visualViewport;let s=n.clientWidth,r=n.clientHeight,l=0,c=0;if(o){s=o.width,r=o.height;const d=mt();(!d||d&&e==="fixed")&&(l=o.offsetLeft,c=o.offsetTop)}const a=at(n);if(a<=0){const d=n.ownerDocument,u=d.body,p=getComputedStyle(u),f=d.compatMode==="CSS1Compat"&&parseFloat(p.marginLeft)+parseFloat(p.marginRight)||0,h=Math.abs(n.clientWidth-u.clientWidth-f);h<=Dt&&(s-=h)}else a<=Dt&&(s+=a);return{width:s,height:r,x:l,y:c}}const ve=new Set(["absolute","fixed"]);function be(t,e){const i=Z(t,!0,e==="fixed"),n=i.top+t.clientTop,o=i.left+t.clientLeft,s=F(t)?G(t):$(1),r=t.clientWidth*s.x,l=t.clientHeight*s.y,c=o*s.x,a=n*s.y;return{width:r,height:l,x:c,y:a}}function $t(t,e,i){let n;if(e==="viewport")n=xe(t,i);else if(e==="document")n=ye(B(t));else if(L(e))n=be(e,i);else{const o=kt(t);n={x:e.x-o.x,y:e.y-o.y,width:e.width,height:e.height}}return st(n)}function Ft(t,e){const i=H(t);return i===e||!L(i)||K(i)?!1:R(i).position==="fixed"||Ft(i,e)}function Se(t,e){const i=e.get(t);if(i)return i;let n=Tt(t,[]).filter(l=>L(l)&&z(l)!=="body"),o=null;const s=R(t).position==="fixed";let r=s?H(t):t;for(;L(r)&&!K(r);){const l=R(r),c=gt(r);!c&&l.position==="fixed"&&(o=null),(s?!c&&!o:!c&&l.position==="static"&&!!o&&ve.has(o.position)||U(r)&&!c&&Ft(t,r))?n=n.filter(d=>d!==r):o=l,r=H(r)}return e.set(t,n),n}function Ae(t){let{element:e,boundary:i,rootBoundary:n,strategy:o}=t;const r=[...i==="clippingAncestors"?lt(e)?[]:Se(e,this._c):[].concat(i),n],l=r[0],c=r.reduce((a,d)=>{const u=$t(e,d,o);return a.top=T(u.top,a.top),a.right=S(u.right,a.right),a.bottom=S(u.bottom,a.bottom),a.left=T(u.left,a.left),a},$t(e,l,o));return{width:c.right-c.left,height:c.bottom-c.top,x:c.left,y:c.top}}function Ce(t){const{width:e,height:i}=Lt(t);return{width:e,height:i}}function Ee(t,e,i){const n=F(e),o=B(e),s=i==="fixed",r=Z(t,!0,s,e);let l={scrollLeft:0,scrollTop:0};const c=$(0);function a(){c.x=at(o)}if(n||!n&&!s)if((z(e)!=="body"||U(o))&&(l=ct(e)),n){const f=Z(e,!0,s,e);c.x=f.x+e.clientLeft,c.y=f.y+e.clientTop}else o&&a();s&&!n&&o&&a();const d=o&&!n&&!s?Pt(o,l):$(0),u=r.left+l.scrollLeft-c.x-d.x,p=r.top+l.scrollTop-c.y-d.y;return{x:u,y:p,width:r.width,height:r.height}}function yt(t){return R(t).position==="static"}function Bt(t,e){if(!F(t)||R(t).position==="fixed")return null;if(e)return e(t);let i=t.offsetParent;return B(t)===i&&(i=i.ownerDocument.body),i}function Vt(t,e){const i=O(t);if(lt(t))return i;if(!F(t)){let o=H(t);for(;o&&!K(o);){if(L(o)&&!yt(o))return o;o=H(o)}return i}let n=Bt(t,e);for(;n&&le(n)&&yt(n);)n=Bt(n,e);return n&&K(n)&&yt(n)&&!gt(n)?i:n||de(t)||i}const Oe=async function(t){const e=this.getOffsetParent||Vt,i=this.getDimensions,n=await i(t.floating);return{reference:Ee(t.reference,await e(t.floating),t.strategy),floating:{x:0,y:0,width:n.width,height:n.height}}};function Te(t){return R(t).direction==="rtl"}const Le={convertOffsetParentRelativeRectToViewportRelativeRect:me,getDocumentElement:B,getClippingRect:Ae,getOffsetParent:Vt,getElementRects:Oe,getClientRects:we,getDimensions:Ce,getScale:G,isElement:L,isRTL:Te},Re=ie,ke=oe,Pe=te,De=Zt,$e=(t,e,i)=>{const n=new Map,o={platform:Le,...i},s={...o.platform,_c:n};return Ut(t,e,{...o,platform:s})};function Nt(t){try{return document.querySelector(t)}catch{return console.warn(`[Trailguide] Invalid selector: ${t}`),null}}function Mt(t){const e=t.getBoundingClientRect(),i=window.getComputedStyle(t);return e.width>0&&e.height>0&&i.visibility!=="hidden"&&i.display!=="none"&&i.opacity!=="0"}function Wt(t){t.scrollIntoView({behavior:"smooth",block:"center",inline:"center"})}function ft(t,e,i){const n=document.createElement(t);return e&&(n.className=e),i&&i.appendChild(n),n}class Ht{constructor(e={}){M(this,"trail",null);M(this,"currentStepIndex",0);M(this,"isActive",!1);M(this,"options",{});M(this,"overlay",null);M(this,"tooltip",null);M(this,"arrowEl",null);M(this,"cleanupFns",[]);this.options=e}start(e){this.trail=e,this.currentStepIndex=0,this.isActive=!0,this.createOverlay(),this.showStep(),this.bindKeyboard()}stop(){this.isActive=!1,this.cleanup()}next(){!this.trail||!this.isActive||(this.currentStepIndex<this.trail.steps.length-1?(this.currentStepIndex++,this.showStep()):this.complete())}prev(){!this.trail||!this.isActive||this.currentStepIndex>0&&(this.currentStepIndex--,this.showStep())}skip(){var e,i;this.isActive=!1,this.cleanup(),(i=(e=this.options).onSkip)==null||i.call(e)}goToStep(e){!this.trail||!this.isActive||e>=0&&e<this.trail.steps.length&&(this.currentStepIndex=e,this.showStep())}complete(){var e,i;this.isActive=!1,this.cleanup(),(i=(e=this.options).onComplete)==null||i.call(e)}createOverlay(){var i,n,o;this.overlay=ft("div","trailguide-overlay"),document.body.appendChild(this.overlay);const e=ft("div","trailguide-spotlight",this.overlay);e.innerHTML=`
2
+ <svg width="100%" height="100%">
3
+ <defs>
4
+ <mask id="trailguide-mask">
5
+ <rect x="0" y="0" width="100%" height="100%" fill="white" />
6
+ <rect class="trailguide-cutout" rx="4" fill="black" />
7
+ </mask>
8
+ </defs>
9
+ <rect x="0" y="0" width="100%" height="100%" fill="rgba(0,0,0,0.5)" mask="url(#trailguide-mask)" />
10
+ </svg>
11
+ `,ft("div","trailguide-highlight",this.overlay),this.tooltip=ft("div","trailguide-tooltip"),this.tooltip.innerHTML=`
12
+ <div class="trailguide-tooltip-content">
13
+ <div class="trailguide-tooltip-header">
14
+ <h3 class="trailguide-tooltip-title"></h3>
15
+ <button class="trailguide-tooltip-close" aria-label="Skip tour">&times;</button>
16
+ </div>
17
+ <div class="trailguide-tooltip-body"></div>
18
+ <div class="trailguide-tooltip-footer">
19
+ <span class="trailguide-tooltip-progress"></span>
20
+ <div class="trailguide-tooltip-nav">
21
+ <button class="trailguide-btn trailguide-btn-secondary trailguide-btn-prev">Back</button>
22
+ <button class="trailguide-btn trailguide-btn-primary trailguide-btn-next">Next</button>
23
+ </div>
24
+ </div>
25
+ <div class="trailguide-tooltip-arrow"></div>
26
+ </div>
27
+ `,document.body.appendChild(this.tooltip),this.arrowEl=this.tooltip.querySelector(".trailguide-tooltip-arrow"),(i=this.tooltip.querySelector(".trailguide-tooltip-close"))==null||i.addEventListener("click",()=>this.skip()),(n=this.tooltip.querySelector(".trailguide-btn-prev"))==null||n.addEventListener("click",()=>this.prev()),(o=this.tooltip.querySelector(".trailguide-btn-next"))==null||o.addEventListener("click",()=>this.next())}showStep(){if(!this.trail||!this.overlay||!this.tooltip)return;const e=this.trail.steps[this.currentStepIndex];if(!e)return;const i=Nt(e.target);if(!i||!Mt(i)){console.warn(`[Trailguide] Target not found or not visible: ${e.target}`);return}Wt(i),setTimeout(()=>{var n,o;this.updateSpotlight(i),this.updateTooltip(e,i),(o=(n=this.options).onStepChange)==null||o.call(n,e,this.currentStepIndex)},100)}updateSpotlight(e){if(!this.overlay)return;const i=e.getBoundingClientRect(),n=8,o=this.overlay.querySelector(".trailguide-cutout");o&&(o.setAttribute("x",String(i.left-n)),o.setAttribute("y",String(i.top-n)),o.setAttribute("width",String(i.width+n*2)),o.setAttribute("height",String(i.height+n*2)));const s=this.overlay.querySelector(".trailguide-highlight");s&&(s.style.top=`${i.top-n}px`,s.style.left=`${i.left-n}px`,s.style.width=`${i.width+n*2}px`,s.style.height=`${i.height+n*2}px`);const r=()=>{if(!this.isActive)return;const l=e.getBoundingClientRect();o&&(o.setAttribute("x",String(l.left-n)),o.setAttribute("y",String(l.top-n)),o.setAttribute("width",String(l.width+n*2)),o.setAttribute("height",String(l.height+n*2))),s&&(s.style.top=`${l.top-n}px`,s.style.left=`${l.left-n}px`,s.style.width=`${l.width+n*2}px`,s.style.height=`${l.height+n*2}px`)};window.addEventListener("scroll",r,!0),window.addEventListener("resize",r),this.cleanupFns.push(()=>{window.removeEventListener("scroll",r,!0),window.removeEventListener("resize",r)})}async updateTooltip(e,i){if(!this.tooltip||!this.trail||!this.arrowEl)return;const n=this.currentStepIndex===0,o=this.currentStepIndex===this.trail.steps.length-1,s=this.tooltip.querySelector(".trailguide-tooltip-title"),r=this.tooltip.querySelector(".trailguide-tooltip-body"),l=this.tooltip.querySelector(".trailguide-tooltip-progress"),c=this.tooltip.querySelector(".trailguide-btn-prev"),a=this.tooltip.querySelector(".trailguide-btn-next");s&&(s.textContent=e.title),r&&(r.textContent=e.content),l&&(l.textContent=`${this.currentStepIndex+1} of ${this.trail.steps.length}`),c&&(c.style.display=n?"none":"block"),a&&(a.textContent=o?"Finish":"Next");const{x:d,y:u,middlewareData:p}=await $e(i,this.tooltip,{placement:e.placement,middleware:[Re(12),Pe(),ke({padding:8}),De({element:this.arrowEl})]});if(this.tooltip.style.left=`${d}px`,this.tooltip.style.top=`${u}px`,p.arrow&&this.arrowEl){const{x:f,y:h}=p.arrow;this.arrowEl.style.left=f!=null?`${f}px`:"",this.arrowEl.style.top=h!=null?`${h}px`:""}}bindKeyboard(){const e=i=>{if(this.isActive)switch(i.key){case"ArrowRight":case"Enter":this.next();break;case"ArrowLeft":this.prev();break;case"Escape":this.skip();break}};window.addEventListener("keydown",e),this.cleanupFns.push(()=>window.removeEventListener("keydown",e))}cleanup(){var e,i;this.cleanupFns.forEach(n=>n()),this.cleanupFns=[],(e=this.overlay)==null||e.remove(),(i=this.tooltip)==null||i.remove(),this.overlay=null,this.tooltip=null}}let A=null;function Fe(t,e){return A&&A.stop(),A=new Ht(e),A.start(t),A}function Be(){A==null||A.stop()}function Ve(){A==null||A.next()}function Ne(){A==null||A.prev()}function Me(){A==null||A.skip()}w.Trailguide=Ht,w.findElement=Nt,w.isElementVisible=Mt,w.next=Ve,w.prev=Ne,w.scrollToElement=Wt,w.skip=Me,w.start=Fe,w.stop=Be,Object.defineProperty(w,Symbol.toStringTag,{value:"Module"})});
@@ -0,0 +1,29 @@
1
+ export type Placement = 'top' | 'bottom' | 'left' | 'right';
2
+ export type StepAction = 'click' | 'input' | 'hover' | 'none';
3
+ export type NextTrigger = 'click' | 'manual';
4
+ export interface Step {
5
+ id: string;
6
+ target: string;
7
+ placement: Placement;
8
+ title: string;
9
+ content: string;
10
+ action?: StepAction;
11
+ nextOn?: NextTrigger;
12
+ }
13
+ export interface Trail {
14
+ id: string;
15
+ title: string;
16
+ version: string;
17
+ steps: Step[];
18
+ }
19
+ export interface TrailguideOptions {
20
+ onComplete?: () => void;
21
+ onSkip?: () => void;
22
+ onStepChange?: (step: Step, index: number) => void;
23
+ }
24
+ export interface TrailguideState {
25
+ trail: Trail | null;
26
+ currentStepIndex: number;
27
+ isActive: boolean;
28
+ }
29
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;AAE5D,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC;AAE9D,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE7C,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,SAAS,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,IAAI,EAAE,CAAC;CACf;AAED,MAAM,WAAW,iBAAiB;IAChC,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACpD;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;CACnB"}
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@trailguide/core",
3
+ "version": "0.0.1",
4
+ "description": "Framework-agnostic product tours. Tutorials as code for any web app.",
5
+ "type": "module",
6
+ "main": "./dist/trailguide.js",
7
+ "module": "./dist/trailguide.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/trailguide.js",
13
+ "require": "./dist/trailguide.umd.js"
14
+ },
15
+ "./dist/style.css": "./dist/style.css"
16
+ },
17
+ "files": [
18
+ "dist"
19
+ ],
20
+ "scripts": {
21
+ "dev": "vite build --watch",
22
+ "build": "vite build && tsc --emitDeclarationOnly",
23
+ "typecheck": "tsc --noEmit"
24
+ },
25
+ "keywords": [
26
+ "product-tour",
27
+ "onboarding",
28
+ "walkthrough",
29
+ "tutorial",
30
+ "guide",
31
+ "tooltip",
32
+ "popover",
33
+ "user-onboarding"
34
+ ],
35
+ "author": "Branden Langhals",
36
+ "license": "MIT",
37
+ "repository": {
38
+ "type": "git",
39
+ "url": "git+https://github.com/brandenlanghals/trailguide.git",
40
+ "directory": "packages/core"
41
+ },
42
+ "homepage": "https://github.com/brandenlanghals/trailguide#readme",
43
+ "bugs": {
44
+ "url": "https://github.com/brandenlanghals/trailguide/issues"
45
+ },
46
+ "dependencies": {
47
+ "@floating-ui/dom": "^1.6.0"
48
+ },
49
+ "devDependencies": {
50
+ "typescript": "^5.4.0",
51
+ "vite": "^5.2.0",
52
+ "vite-plugin-dts": "^3.8.0"
53
+ }
54
+ }