unfold-nav 0.1.0
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/CHANGELOG.md +15 -0
- package/LICENSE +21 -0
- package/README.md +421 -0
- package/dist/element.d.cts +37 -0
- package/dist/element.d.ts +37 -0
- package/dist/icons.d.cts +12 -0
- package/dist/icons.d.ts +12 -0
- package/dist/index.d.cts +32 -0
- package/dist/index.d.ts +32 -0
- package/dist/insets.d.cts +4 -0
- package/dist/insets.d.ts +4 -0
- package/dist/layout.d.cts +197 -0
- package/dist/layout.d.ts +197 -0
- package/dist/navigation.d.cts +2 -0
- package/dist/navigation.d.ts +2 -0
- package/dist/options.d.cts +6 -0
- package/dist/options.d.ts +6 -0
- package/dist/styles.d.cts +1 -0
- package/dist/styles.d.ts +1 -0
- package/dist/tree.d.cts +22 -0
- package/dist/tree.d.ts +22 -0
- package/dist/types.d.cts +108 -0
- package/dist/types.d.ts +108 -0
- package/dist/unfold-nav.js +2211 -0
- package/dist/unfold-nav.js.map +1 -0
- package/dist/unfold-nav.umd.cjs +446 -0
- package/dist/unfold-nav.umd.cjs.map +1 -0
- package/package.json +71 -0
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
(function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports):typeof define==`function`&&define.amd?define([`exports`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.UnfoldNav={}))})(this,function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var t=/^(https?:|data:|blob:|\/|\.\.?\/)|\.(svg|png|jpe?g|gif|webp|avif)(\?.*)?$/i,n=/^[a-z][\w-]{2,}$/i;function r(e,i,a,o=0){if(e==null||e===``||o>3)return null;if(typeof e==`function`)return r(e(),i,a,o+1);if(typeof e!=`string`)return e.cloneNode(!0);let s=e.trim();if(s.startsWith(`<`)){let e=document.createElement(`template`);return e.innerHTML=s,e.content}if(t.test(s)){let e=document.createElement(`img`);return e.src=s,e.alt=``,e.decoding=`async`,e.draggable=!1,e}if(n.test(s)){let e=i?.(s,a);return e==null||e===s?null:r(e,void 0,a,o+1)}let c=document.createElement(`span`);return c.className=`glyph`,c.textContent=s,c}function i(e){let t=document.createElement(`span`);return t.className=`mono`,t.textContent=Array.from(e.trim())[0]?.toUpperCase()??`•`,t}var a=e=>`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${e}</svg>`,o=a(`<path d="M12 17.5 6 8.6M12 17.5V6.2M12 17.5l6-8.9"/><circle cx="12" cy="18.2" r="2.5" fill="currentColor" stroke="none"/><circle cx="5.6" cy="8" r="2" fill="currentColor" stroke="none"/><circle cx="12" cy="5.4" r="2" fill="currentColor" stroke="none"/><circle cx="18.4" cy="8" r="2" fill="currentColor" stroke="none"/>`),s=a(`<path d="M6.5 6.5l11 11M17.5 6.5l-11 11"/>`),c=a(`<path d="M19 12H5.5M11 6l-6 6 6 6"/>`),l=e=>Array.isArray(e)?e:[e],u=Math.PI*2,d=Math.PI/180,f=4;function p(e,t){let n=Math.max(t.x-e.x,0,e.x-(t.x+t.w)),r=Math.max(t.y-e.y,0,e.y-(t.y+t.h));return Math.hypot(n,r)}function m(e,t,n=0){return e.x<t.x+t.w+n&&t.x<e.x+e.w+n&&e.y<t.y+t.h+n&&t.y<e.y+e.h+n}var h=(e,t)=>t.x>=e.x&&t.x<=e.x+e.w&&t.y>=e.y&&t.y<=e.y+e.h,g=(e,t)=>t.x>=e.x-.5&&t.y>=e.y-.5&&t.x+t.w<=e.x+e.w+.5&&t.y+t.h<=e.y+e.h+.5,_=(e,t)=>({x:e.x-t,y:e.y-t,w:e.w+t*2,h:e.h+t*2});function v(e,t,n){let r=n.x-t.x,i=n.y-t.y,a=r*r+i*i,o=a?Math.max(0,Math.min(1,((e.x-t.x)*r+(e.y-t.y)*i)/a)):0;return Math.hypot(e.x-(t.x+o*r),e.y-(t.y+o*i))}function y(e,t){let n=1/0;for(let r=0;r<t.length-1;r++)n=Math.min(n,v(e,t[r],t[r+1]));return n}function ee(e,t,n){let r=0,i=1,a=t.x-e.x,o=t.y-e.y,s=[-a,a,-o,o],c=[e.x-n.x,n.x+n.w-e.x,e.y-n.y,n.y+n.h-e.y];for(let e=0;e<4;e++)if(s[e]===0){if(c[e]<0)return!1}else{let t=c[e]/s[e];if(s[e]<0){if(t>i)return!1;t>r&&(r=t)}else{if(t<r)return!1;t<i&&(i=t)}}return!0}function b(e,t){for(let n=0;n<e.length-1;n++)if(ee(e[n],e[n+1],t))return!0;return!1}function x(e,t,n){let r=t.x-e.x,i=t.y-e.y,a=Math.hypot(r,i)||1;return{x:e.x+r/a*n,y:e.y+i/a*n}}var S=e=>e.toFixed(1);function C(e,t,n,r){let i=()=>{let n=x(e,t,e.r),r=x(t,e,t.r);return{d:`M${S(n.x)} ${S(n.y)}L${S(r.x)} ${S(r.y)}`,points:[n,r]}};if(n===`step`){let n=x(e,t,e.r),r=x(t,e,t.r);if(Math.min(Math.abs(r.x-n.x),Math.abs(r.y-n.y))<1||Math.hypot(t.x-e.x,t.y-e.y)<=e.r+t.r)return i();let a=Math.abs(t.x-e.x)>=Math.abs(t.y-e.y),o=a?(n.x+r.x)/2:(n.y+r.y)/2,s=a?[{x:o,y:n.y},{x:o,y:r.y}]:[{x:n.x,y:o},{x:r.x,y:o}],c=[n,...s,r],l=[n],u=`M${S(n.x)} ${S(n.y)}`;return s.forEach((e,t)=>{let n=c[t],r=c[t+2],i=Math.min(10,Math.hypot(e.x-n.x,e.y-n.y)/2,Math.hypot(r.x-e.x,r.y-e.y)/2),a=x(e,n,i),o=x(e,r,i);u+=`L${S(a.x)} ${S(a.y)}Q${S(e.x)} ${S(e.y)} ${S(o.x)} ${S(o.y)}`,l.push(a);for(let t=1;t<=4;t++){let n=t/4,r=1-n;l.push({x:r*r*a.x+2*r*n*e.x+n*n*o.x,y:r*r*a.y+2*r*n*e.y+n*n*o.y})}}),l.push(r),{d:`${u}L${S(r.x)} ${S(r.y)}`,points:l}}if(n!==`curved`||r==null)return i();let a=Math.hypot(t.x-e.x,t.y-e.y)||1,o={x:e.x+Math.cos(r)*a*.5,y:e.y+Math.sin(r)*a*.5},s=x(e,o,e.r),c=x(t,o,t.r),l=[];for(let e=0;e<=6;e++){let t=e/6,n=1-t;l.push({x:n*n*s.x+2*n*t*o.x+t*t*c.x,y:n*n*s.y+2*n*t*o.y+t*t*c.y})}return{d:`M${S(s.x)} ${S(s.y)}Q${S(o.x)} ${S(o.y)} ${S(c.x)} ${S(c.y)}`,points:l}}var w=[0,...Array.from({length:7},(e,t)=>[(t+1)*22.5,-(t+1)*22.5]).flat(),180].map(e=>e*d),T=[0,12,28],te=[0,12,28,48];function E(e,t,n,r,i,a){let o=Math.cos(i),s=Math.sin(i),c=0,l=a+n+r;for(let i=0;i<14;i++){let i=(c+l)/2;p({x:e,y:t},{x:e+o*i-n/2,y:t+s*i-r/2,w:n,h:r})>=a?l=i:c=i}return{x:e+o*l-n/2,y:t+s*l-r/2,w:n,h:r}}function D(e,t,n){for(let r of n.circles)if(r!==t&&p(r,e)<r.r+n.pad)return!0;for(let t of n.taken)if(m(e,t,f))return!0;if(n.edges.length){let t=_(e,2);for(let e of n.edges)if(b(e,t))return!0}return!1}function ne(e,t,n,r){let i=l(t)[0],a=0;for(let t of T)for(let o of w){let s=E(e.x,e.y,i.w,i.h,n+o,e.r+(r.ownPad??r.pad)+t);g(r.bounds,s)&&!D(s,e,r)&&a++}return a}function O(e,t,n=(e,t)=>k(e.node,e.size,e.angle,t)){let r=r=>{let i=e.map(()=>null),a={...t,taken:[...t.taken]},o=0;for(let t of r){let r=n(e[t],a);r?a.taken.push(r):o++,i[t]=r}return{out:i,missing:o}},i=e.map((e,t)=>t),a=r(i);if(a.missing===0||e.length<2)return a.out;let o=e.map(e=>ne(e.node,e.size,e.angle,t));for(let e of[[...i].sort((e,t)=>o[e]-o[t]),[...i].reverse()]){let t=r(e);if(t.missing<a.missing&&(a=t),a.missing===0)break}return a.out}function k(e,t,n,r){for(let i of l(t)){let t=re(e,i,n,r);if(t)return t}return null}function re(e,t,n,r){for(let i of r.rings??T)for(let a of w){let o=E(e.x,e.y,t.w,t.h,n+a,e.r+(r.ownPad??r.pad)+i);if(g(r.bounds,o)&&!D(o,e,r))return o}return null}var ie=Array.from({length:41},(e,t)=>1+t*.06),A=[1,1.15,1.3,1.5,1.75,2,2.3],j=5*d,ae=200;function M(e,t,n,r,i){let a=r-i*(n-1)/2;return Array.from({length:n},(n,r)=>{let o=a+r*i;return{x:e.x+t*Math.cos(o),y:e.y+t*Math.sin(o)}})}function oe(e,t,n,r){return Array.from({length:n},(i,a)=>{let o=r+a*u/n;return{x:e.x+t*Math.cos(o),y:e.y+t*Math.sin(o)}})}function se(e,t,n,r=!1){let{bounds:i,radius:a}=t,o=t.labelPad??8,s=0,c=0;for(let n of e){s+=Math.max(0,i.x+a-n.x)+Math.max(0,n.x+a-(i.x+i.w)),s+=Math.max(0,i.y+a-n.y)+Math.max(0,n.y+a-(i.y+i.h));for(let e of t.obstacles){let r=a+e.r+t.gap*.75,i=Math.hypot(n.x-e.x,n.y-e.y);i<r&&(s+=r-i)}if(!r)for(let e of t.blocked??[]){let t=p(n,e);t<a+o&&(s+=a+o-t)}}if(n&&t.edgeStyle!==`none`&&s===0){let n=t.edgeStyle??`straight`;for(let n of e)for(let e of t.edges??[]){let t=y(n,e);t<a+4&&(c+=a+4-t)}e.forEach((r,i)=>{let o=C(t.origin,{...r,r:a},n,t.parentAngle).points;for(let e of t.obstacles){let t=y(e,o);t<e.r+4&&(c+=e.r+4-t)}e.forEach((e,t)=>{if(t===i)return;let n=y(e,o);n<a+4&&(c+=a+4-n)})})}return{base:s,edges:c}}function N(e,t,n,r,i=`optional`){if(!t.labels?.some(Boolean)&&!t.originLabel)return{labels:e.map(()=>null),originLabel:null};let a=t.radius,o=t.edgeStyle??`straight`,s=e.map(e=>({x:e.x,y:e.y,r:a})),c=o===`none`?[]:s.map(e=>C(t.origin,e,o,t.parentAngle).points),l=o===`none`?[]:[...t.edges??[],...c],u={bounds:t.bounds,circles:[...t.obstacles,t.origin,...s],taken:[...t.blocked??[]],edges:l,pad:t.labelPad??8},d=s.map((e,n)=>({i:n,node:e,size:t.labels?.[n]??null,angle:Math.atan2(e.y-t.origin.y,e.x-t.origin.x)})).filter(e=>!!e.size),f=O(d,u,(e,t)=>{let r=e.i;return k(e.node,e.size,e.angle,t)??(n===`strict`?null:k(e.node,e.size,e.angle,{...t,edges:c}))??(n===`loose`?k(e.node,e.size,e.angle,{...t,edges:c.length?[c[r]]:[]}):null)}),p=s.map(()=>null);if(d.forEach((e,t)=>p[e.i]=f[t]),!r&&d.some((e,t)=>!f[t]))return null;let m=null;if(t.originLabel){let e={...u,taken:[...u.taken,...p.filter(e=>!!e)],rings:te},n=t.parentEdge?[t.parentEdge]:[];if(m=k(t.origin,t.originLabel,t.direction,{...e,edges:[...e.edges,...n]}),!m&&i!==`clean`&&(m=k(t.origin,t.originLabel,t.direction+Math.PI,{...e,edges:e.edges.filter(e=>e!==t.parentEdge)})),!m&&i!==`optional`&&!r)return null}return{labels:p,originLabel:m}}function P(e){let{origin:t,count:n,radius:r,gap:i}=e;if(n<=0)return{points:[],labels:[]};let a=2*r+i,o=null,s=(t,n,r,i)=>{let a=se(t,e,n);if((!o||a.base<o.penalty)&&(o={points:t,penalty:a.base}),a.base>0||n&&a.edges>0||r.left<=0)return null;r.left--;let s=N(t,e,n?`strict`:`relaxed`,!1,i);return s?{points:t,...s}:null},c=ie.map(t=>e.distance*t);if(n>1&&e.maxSpread!=null){let t=a/(2*Math.sin(e.maxSpread/(2*(n-1))))+.5;t>e.distance&&c.push(t)}c.sort((e,t)=>e-t);let l=Math.min(e.maxDeviation??Math.PI,Math.PI),u=e.maxSpread!=null&&!e.ring?Math.min(e.maxSpread*1.5,1.4*Math.PI):e.maxSpread,d=[{dev:l,strict:!0,spread:e.maxSpread},{dev:Math.PI,strict:!0,spread:u},{dev:Math.PI,strict:!1,spread:u}],f=(e.originLabel?[`clean`,`breadcrumb`,`optional`]:[`optional`]).flatMap(e=>d.map(t=>({...t,needOrigin:e})));for(let r of f){if(e.ring&&n>=3){let i=Math.max(e.distance,a/(2*Math.sin(Math.PI/n)));for(let a of A){let o=s(oe(t,i*a,n,e.direction),r.strict,{left:1},r.needOrigin);if(o)return o}}for(let i of c){if(a>=2*i)continue;let o=2*Math.asin(a/(2*i)),c=Math.max(o,e.preferredStep??0),l=c>o+1e-9?[c,o]:[o],u=[];for(let t of l){if(n>1&&r.spread!=null&&t*(n-1)>r.spread+1e-9)continue;let i=t===c?0:.15;for(let n=0;n*j<=r.dev+1e-9;n++)for(let r of n===0?[0]:[1,-1]){let a=r*n*j;u.push({dir:e.direction+a,step:t,cost:Math.abs(a)+i})}}u.sort((e,t)=>e.cost-t.cost);let d={left:ae};for(let e of u){let a=s(M(t,i,n,e.dir,e.step),r.strict,d,r.needOrigin);if(a)return a}}}let p=null,m=-1,h=0,g=e.edgeStyle??`straight`,_=t=>{if(se(t,e,!1,!0).base>0)return;h++;let i=N(t,e,`loose`,!0),a=i.labels,o=g===`none`?[]:[...e.edges??[],...t.map(t=>C(e.origin,{...t,r},g,e.parentAngle).points)],s=a.filter(Boolean).length+ +!!i.originLabel,c=a.filter(e=>e&&!o.some(t=>b(t,e))).length,l=s*(n+2)+c;l>m&&(p={points:t,...i},m=l)};if(e.ring&&n>=3){let r=Math.max(e.distance,a/(2*Math.sin(Math.PI/n)));for(let i of A)_(oe(t,r*i,n,e.direction))}for(let r of c){let i=(n+ +!!e.originLabel)*(n+2)+n;if(h>=160||m===i||a>=2*r)continue;let o=2*Math.asin(a/(2*r));for(let a=0;a*j<=Math.PI&&h<160&&m<i;a++)for(let i of a===0?[0]:[1,-1])_(M(t,r,n,e.direction+i*a*j,o))}if(p)return p;let v=o?.points??M(t,e.distance,n,e.direction,a/e.distance);return{points:v,...N(v,e,`loose`,!0)}}function F(e,t=new Map){let n=new Map,r=e.edgeStyle??`straight`,i=e.nodeRadius,a=[e.hub],o=[],s=[],c=new Set,l={x:e.bounds.x+e.bounds.w/2,y:e.bounds.y+e.bounds.h/2};for(let u of e.levels){let f=u.parentId==null?null:n.get(u.parentId);if(u.parentId!=null&&!f)continue;u.parentId!=null&&c.add(u.parentId);let m=f?{x:f.x,y:f.y,r:i}:e.hub,h=t.get(u.key);if(!h||h.points.length!==u.childIds.length){let n=Math.atan2(l.y-e.hub.y,l.x-e.hub.x),p=Math.hypot(l.x-e.hub.x,l.y-e.hub.y)<1;h=P({origin:m,parentAngle:f?f.angle:null,count:u.childIds.length,direction:f?f.angle:p?-Math.PI/2:n,radius:i,distance:e.distance,gap:e.gap,bounds:e.bounds,obstacles:a.filter(e=>e.x!==m.x||e.y!==m.y),blocked:s.filter(e=>!c.has(e.id)).map(e=>e.rect),edges:o,edgeStyle:r,labels:u.childIds.map(t=>e.labelSize?.(t)??null),originLabel:f&&u.parentId?(e.branchLabelSize??e.labelSize)?.(u.parentId)??null:null,parentEdge:f?f.edge:null,labelPad:e.labelPad,...f?{maxSpread:150*d,maxDeviation:110*d}:{ring:!0,preferredStep:50*d,maxSpread:Math.PI}}),t.set(u.key,h)}f&&(f.pathLabel=h.originLabel??null,f.pathLabel&&s.push({id:`${u.parentId}\u0000open`,rect:f.pathLabel}));let g=e.labelPad??8;for(let e of s){if(c.has(e.id)||!h.points.some(t=>p(t,e.rect)<i+g-.5))continue;let[t,r]=e.id.split(`\0`),a=n.get(t);a&&(r?a.pathLabel=null:a.label=null)}u.childIds.forEach((e,t)=>{let c=h.points[t],l={x:c.x,y:c.y,r:i},u=f?f.angle:null,d=C(m,l,r,u).points;n.set(e,{x:c.x,y:c.y,from:{x:m.x,y:m.y},angle:Math.atan2(c.y-m.y,c.x-m.x),parentAngle:u,label:h.labels[t]??null,edge:d}),a.push(l),r!==`none`&&o.push(d);let p=h.labels[t];p&&s.push({id:e,rect:p})})}let u=e.levels[e.levels.length-1];if(u&&e.labelSize){let t=e.labelPad??8,a=new Map;for(let[e,t]of n)a.set(e,{x:t.x,y:t.y,r:i});let s=u.childIds.filter(e=>n.has(e)),c=e=>o.some(t=>b(t,e)),l=s.filter(t=>{let r=n.get(t).label;return e.labelSize(t)&&(!r||c(r))});if(l.length){let i={bounds:e.bounds,circles:[e.hub,...a.values()],taken:s.filter(e=>!l.includes(e)).map(e=>n.get(e).label).filter(e=>!!e),edges:o,pad:t},c=l.map(t=>({id:t,node:a.get(t),size:e.labelSize(t),angle:n.get(t).angle})),u=O(c,i,(e,t)=>{let i=n.get(e.id);return k(e.node,e.size,e.angle,t)??i.label??k(e.node,e.size,e.angle,{...t,edges:r===`none`?[]:[i.edge]})});c.forEach((e,t)=>{let r=n.get(e.id);u[t]&&u[t]!==r.label&&(r.label=u[t],r.borrowed=!0)})}}if(r===`step`&&u&&e.labelSize){let t=new Set(e.levels.flatMap(e=>e.parentId==null?[]:[e.parentId])),r=[...new Set([...t,...u.childIds])].filter(e=>n.has(e)),a=e=>t.has(e)?n.get(e).pathLabel:n.get(e).label;for(let s of r){let c=n.get(s),l=a(s),u=t.has(s)?o.filter(e=>e!==c.edge):o;if(l&&!u.some(e=>b(e,l)))continue;let d=(t.has(s)?e.branchLabelSize??e.labelSize:e.labelSize)(s);if(!d)continue;let f={x:c.x,y:c.y,r:i},p={bounds:e.bounds,circles:[e.hub,...[...n.values()].map(e=>({x:e.x,y:e.y,r:i}))],taken:r.filter(e=>e!==s).map(a).filter(e=>!!e),edges:u,pad:e.labelPad??8,rings:[...te,64,80]},m=k(f,d,c.angle,p);t.has(s)?c.pathLabel=m:c.label=m,m&&(c.borrowed=!0)}}return n}function ce(e,t,n){let r=-1,i=1/0;return t.forEach((t,a)=>{let o=Math.hypot(e.x-t.x,e.y-t.y);o<=t.r+n&&o<i&&(r=a,i=o)}),r}var le=`
|
|
2
|
+
--_fg: var(--unfold-fg, #17171c);
|
|
3
|
+
--_muted: var(--unfold-muted, rgb(23 23 28 / .68));
|
|
4
|
+
--_surface: var(--unfold-surface, rgb(255 255 255 / .78));
|
|
5
|
+
--_surface-active: var(--unfold-surface-active, rgb(255 255 255 / .96));
|
|
6
|
+
--_border: var(--unfold-border, rgb(255 255 255 / .7));
|
|
7
|
+
--_outline: var(--unfold-outline, rgb(15 15 30 / .09));
|
|
8
|
+
--_shadow: var(--unfold-shadow, 0 1px 2px rgb(15 15 30 / .08), 0 10px 28px -8px rgb(15 15 30 / .28));
|
|
9
|
+
--_edge: var(--unfold-edge, rgb(23 23 28 / .2));
|
|
10
|
+
--_label-bg: var(--unfold-label-bg, rgb(255 255 255 / .9));
|
|
11
|
+
--_label-fg: var(--unfold-label-fg, var(--_fg));
|
|
12
|
+
--_backdrop: var(--unfold-backdrop, rgb(244 244 248 / .42));
|
|
13
|
+
`,I=`
|
|
14
|
+
--_fg: var(--unfold-fg, #f3f3f6);
|
|
15
|
+
--_muted: var(--unfold-muted, rgb(243 243 246 / .7));
|
|
16
|
+
--_surface: var(--unfold-surface, rgb(38 38 44 / .72));
|
|
17
|
+
--_surface-active: var(--unfold-surface-active, rgb(56 56 64 / .92));
|
|
18
|
+
--_border: var(--unfold-border, rgb(255 255 255 / .12));
|
|
19
|
+
--_outline: var(--unfold-outline, rgb(0 0 0 / .4));
|
|
20
|
+
--_shadow: var(--unfold-shadow, 0 1px 2px rgb(0 0 0 / .3), 0 12px 30px -8px rgb(0 0 0 / .6));
|
|
21
|
+
--_edge: var(--unfold-edge, rgb(243 243 246 / .22));
|
|
22
|
+
--_label-bg: var(--unfold-label-bg, rgb(30 30 36 / .9));
|
|
23
|
+
--_label-fg: var(--unfold-label-fg, var(--_fg));
|
|
24
|
+
--_backdrop: var(--unfold-backdrop, rgb(8 8 12 / .45));
|
|
25
|
+
`,ue=`
|
|
26
|
+
:host {
|
|
27
|
+
display: inline-block;
|
|
28
|
+
vertical-align: middle;
|
|
29
|
+
}
|
|
30
|
+
:host([hidden]) { display: none; }
|
|
31
|
+
|
|
32
|
+
.root {
|
|
33
|
+
--_accent: var(--unfold-accent, #5b5bf0);
|
|
34
|
+
--_accent-fg: var(--unfold-accent-fg, #fff);
|
|
35
|
+
--_blur: var(--unfold-blur, 18px);
|
|
36
|
+
--_backdrop-blur: var(--unfold-backdrop-blur, 6px);
|
|
37
|
+
--_edge-width: var(--unfold-edge-width, 1.5px);
|
|
38
|
+
--_icon-size: var(--unfold-icon-size, 22px);
|
|
39
|
+
--_dur: var(--unfold-duration, 340ms);
|
|
40
|
+
--_spring: var(--unfold-easing, cubic-bezier(.22, 1.2, .36, 1));
|
|
41
|
+
--_ease: cubic-bezier(.3, .7, .2, 1);
|
|
42
|
+
--_z: var(--unfold-z-index, 2147483000);
|
|
43
|
+
--_node-radius: var(--unfold-node-radius, 50%);
|
|
44
|
+
--_trigger-radius: var(--unfold-trigger-radius, 50%);
|
|
45
|
+
--_border-width: var(--unfold-border-width, 1px);
|
|
46
|
+
--_active-scale: var(--unfold-active-scale, 1.14);
|
|
47
|
+
--_dim-opacity: var(--unfold-dim-opacity, .7);
|
|
48
|
+
--_dim-scale: var(--unfold-dim-scale, .86);
|
|
49
|
+
--_label-radius: var(--unfold-label-radius, 9px);
|
|
50
|
+
/* Follows the reader's font-size preference, never smaller than 13px. */
|
|
51
|
+
--_label-size: var(--unfold-label-size, max(13px, .8125rem));
|
|
52
|
+
--_desc-size: var(--unfold-description-size, max(12px, .75rem));
|
|
53
|
+
--_dock-bg: var(--unfold-dock-bg, color-mix(in srgb, var(--_surface-active) 88%, transparent));
|
|
54
|
+
--_dock-border: var(--unfold-dock-border, var(--_outline));
|
|
55
|
+
--_dock-blur: var(--unfold-dock-blur, 16px);
|
|
56
|
+
--_label-weight: var(--unfold-label-weight, 600);
|
|
57
|
+
--_label-tracking: var(--unfold-label-tracking, normal);
|
|
58
|
+
--_label-case: var(--unfold-label-case, none);
|
|
59
|
+
${le}
|
|
60
|
+
/* Longhands on purpose: with no --unfold-font the family declaration is invalid and simply inherits the
|
|
61
|
+
page's font, while size and weight stay ours. (A shorthand with an inherited part would be dropped.) */
|
|
62
|
+
font-family: var(--unfold-font);
|
|
63
|
+
font-size: 13px;
|
|
64
|
+
font-weight: 500;
|
|
65
|
+
line-height: 1.25;
|
|
66
|
+
color: var(--_fg);
|
|
67
|
+
}
|
|
68
|
+
.root[data-theme="dark"] { ${I} }
|
|
69
|
+
@media (prefers-color-scheme: dark) {
|
|
70
|
+
.root[data-theme="auto"] { ${I} }
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/* ---------------------------------------------------------------- button */
|
|
74
|
+
|
|
75
|
+
/* dock="bar": a strip along the button's edge, so page content never sits under the button. */
|
|
76
|
+
.dock-bar {
|
|
77
|
+
display: none;
|
|
78
|
+
position: fixed;
|
|
79
|
+
z-index: calc(var(--_z) - 1);
|
|
80
|
+
background: var(--_dock-bg);
|
|
81
|
+
border: 0 solid var(--_dock-border);
|
|
82
|
+
-webkit-backdrop-filter: blur(var(--_dock-blur)) saturate(1.4);
|
|
83
|
+
backdrop-filter: blur(var(--_dock-blur)) saturate(1.4);
|
|
84
|
+
}
|
|
85
|
+
.root[data-dock="bar"] .dock-bar[data-edge] { display: block; }
|
|
86
|
+
.dock-bar[data-edge="top"], .dock-bar[data-edge="bottom"] { left: 0; right: 0; }
|
|
87
|
+
.dock-bar[data-edge="left"], .dock-bar[data-edge="right"] { top: 0; bottom: 0; }
|
|
88
|
+
.dock-bar[data-edge="top"] { top: 0; height: calc(var(--_trigger-size) + var(--_offset-y) * 2 + env(safe-area-inset-top, 0px)); border-bottom-width: 1px; }
|
|
89
|
+
.dock-bar[data-edge="bottom"] { bottom: 0; height: calc(var(--_trigger-size) + var(--_offset-y) * 2 + env(safe-area-inset-bottom, 0px)); border-top-width: 1px; }
|
|
90
|
+
.dock-bar[data-edge="left"] { left: 0; width: calc(var(--_trigger-size) + var(--_offset-x) * 2 + env(safe-area-inset-left, 0px)); border-right-width: 1px; }
|
|
91
|
+
.dock-bar[data-edge="right"] { right: 0; width: calc(var(--_trigger-size) + var(--_offset-x) * 2 + env(safe-area-inset-right, 0px)); border-left-width: 1px; }
|
|
92
|
+
|
|
93
|
+
.dock {
|
|
94
|
+
position: fixed;
|
|
95
|
+
z-index: var(--_z);
|
|
96
|
+
width: var(--_trigger-size);
|
|
97
|
+
height: var(--_trigger-size);
|
|
98
|
+
--_ox: calc(var(--_offset-x) + env(safe-area-inset-left, 0px));
|
|
99
|
+
--_ox-r: calc(var(--_offset-x) + env(safe-area-inset-right, 0px));
|
|
100
|
+
--_oy: calc(var(--_offset-y) + env(safe-area-inset-top, 0px));
|
|
101
|
+
--_oy-b: calc(var(--_offset-y) + env(safe-area-inset-bottom, 0px));
|
|
102
|
+
}
|
|
103
|
+
.dock[data-position="inline"] { position: relative; z-index: auto; }
|
|
104
|
+
.dock[data-position^="top"] { top: var(--_oy); }
|
|
105
|
+
.dock[data-position^="bottom"] { bottom: var(--_oy-b); }
|
|
106
|
+
.dock[data-position$="left"] { left: var(--_ox); }
|
|
107
|
+
.dock[data-position$="right"] { right: var(--_ox-r); }
|
|
108
|
+
.dock[data-position="top"], .dock[data-position="bottom"], .dock[data-position="center"] {
|
|
109
|
+
left: calc(50% - var(--_trigger-size) / 2);
|
|
110
|
+
}
|
|
111
|
+
.dock[data-position="left"], .dock[data-position="right"], .dock[data-position="center"] {
|
|
112
|
+
top: calc(50% - var(--_trigger-size) / 2);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.trigger, .hub, .node {
|
|
116
|
+
all: unset;
|
|
117
|
+
box-sizing: border-box;
|
|
118
|
+
display: grid;
|
|
119
|
+
place-items: center;
|
|
120
|
+
border-radius: var(--_node-radius);
|
|
121
|
+
color: var(--_fg);
|
|
122
|
+
background: var(--_surface);
|
|
123
|
+
border: var(--_border-width) solid var(--_border);
|
|
124
|
+
box-shadow: var(--_shadow), 0 0 0 .5px var(--_outline);
|
|
125
|
+
-webkit-backdrop-filter: blur(var(--_blur)) saturate(1.8);
|
|
126
|
+
backdrop-filter: blur(var(--_blur)) saturate(1.8);
|
|
127
|
+
cursor: pointer;
|
|
128
|
+
touch-action: none;
|
|
129
|
+
user-select: none;
|
|
130
|
+
-webkit-user-select: none;
|
|
131
|
+
-webkit-touch-callout: none;
|
|
132
|
+
-webkit-tap-highlight-color: transparent;
|
|
133
|
+
}
|
|
134
|
+
.trigger:focus-visible, .hub:focus-visible, .node:focus-visible {
|
|
135
|
+
outline: 3px solid var(--_accent);
|
|
136
|
+
outline-offset: 3px;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.trigger, .hub { border-radius: var(--_trigger-radius); }
|
|
140
|
+
.trigger {
|
|
141
|
+
position: relative;
|
|
142
|
+
width: 100%;
|
|
143
|
+
height: 100%;
|
|
144
|
+
transition: scale 220ms var(--_ease), box-shadow 220ms;
|
|
145
|
+
}
|
|
146
|
+
.trigger:hover { box-shadow: var(--_shadow), 0 0 0 .5px var(--_outline), 0 0 0 6px color-mix(in srgb, var(--_accent) 10%, transparent); }
|
|
147
|
+
.trigger[data-pressing] { scale: .92; }
|
|
148
|
+
.trigger-icon, .hub-icon {
|
|
149
|
+
display: grid;
|
|
150
|
+
place-items: center;
|
|
151
|
+
width: var(--_icon-size);
|
|
152
|
+
height: var(--_icon-size);
|
|
153
|
+
pointer-events: none;
|
|
154
|
+
}
|
|
155
|
+
.trigger-icon[data-default] { rotate: var(--_icon-rotate, 0deg); }
|
|
156
|
+
.icon-own { display: contents; }
|
|
157
|
+
.trigger-icon[data-slotted] .icon-own { display: none; }
|
|
158
|
+
.icon-own > svg, .icon-own > img, .hub-icon > svg, .trigger-icon ::slotted(*) { width: 100%; height: 100%; display: block; }
|
|
159
|
+
.icon-own > img { object-fit: contain; }
|
|
160
|
+
|
|
161
|
+
.hold {
|
|
162
|
+
position: absolute;
|
|
163
|
+
inset: -5px;
|
|
164
|
+
width: calc(100% + 10px);
|
|
165
|
+
height: calc(100% + 10px);
|
|
166
|
+
rotate: -90deg;
|
|
167
|
+
pointer-events: none;
|
|
168
|
+
overflow: visible;
|
|
169
|
+
}
|
|
170
|
+
.hold circle {
|
|
171
|
+
fill: none;
|
|
172
|
+
stroke: var(--_accent);
|
|
173
|
+
stroke-width: 2.5;
|
|
174
|
+
stroke-linecap: round;
|
|
175
|
+
stroke-dasharray: 1 1;
|
|
176
|
+
stroke-dashoffset: 1;
|
|
177
|
+
opacity: 0;
|
|
178
|
+
transition: opacity 120ms, stroke-dashoffset 120ms;
|
|
179
|
+
}
|
|
180
|
+
.trigger[data-pressing] .hold circle {
|
|
181
|
+
opacity: 1;
|
|
182
|
+
stroke-dashoffset: 0;
|
|
183
|
+
transition: opacity 80ms, stroke-dashoffset var(--_hold) linear;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/* --------------------------------------------------------------- overlay */
|
|
187
|
+
|
|
188
|
+
.overlay {
|
|
189
|
+
position: fixed;
|
|
190
|
+
inset: 0;
|
|
191
|
+
width: 100%;
|
|
192
|
+
height: 100%;
|
|
193
|
+
max-width: none;
|
|
194
|
+
max-height: none;
|
|
195
|
+
margin: 0;
|
|
196
|
+
padding: 0;
|
|
197
|
+
border: 0;
|
|
198
|
+
background: transparent;
|
|
199
|
+
color: inherit;
|
|
200
|
+
overflow: hidden;
|
|
201
|
+
overscroll-behavior: none;
|
|
202
|
+
z-index: var(--_z);
|
|
203
|
+
touch-action: none;
|
|
204
|
+
}
|
|
205
|
+
.overlay:not([data-state]) { display: none; }
|
|
206
|
+
.overlay::backdrop { background: transparent; }
|
|
207
|
+
.overlay:focus { outline: none; }
|
|
208
|
+
|
|
209
|
+
.backdrop {
|
|
210
|
+
position: absolute;
|
|
211
|
+
inset: 0;
|
|
212
|
+
background: var(--_backdrop);
|
|
213
|
+
-webkit-backdrop-filter: blur(var(--_backdrop-blur)) saturate(1.2);
|
|
214
|
+
backdrop-filter: blur(var(--_backdrop-blur)) saturate(1.2);
|
|
215
|
+
opacity: 0;
|
|
216
|
+
transition: opacity var(--_dur) var(--_ease);
|
|
217
|
+
}
|
|
218
|
+
.root:not([data-backdrop]) .backdrop { background: transparent; -webkit-backdrop-filter: none; backdrop-filter: none; }
|
|
219
|
+
.overlay[data-state="open"] .backdrop { opacity: 1; }
|
|
220
|
+
|
|
221
|
+
.edges {
|
|
222
|
+
position: absolute;
|
|
223
|
+
inset: 0;
|
|
224
|
+
width: 100%;
|
|
225
|
+
height: 100%;
|
|
226
|
+
overflow: visible;
|
|
227
|
+
pointer-events: none;
|
|
228
|
+
}
|
|
229
|
+
.edge {
|
|
230
|
+
fill: none;
|
|
231
|
+
stroke: var(--_edge);
|
|
232
|
+
stroke-width: var(--_edge-width);
|
|
233
|
+
stroke-linecap: round;
|
|
234
|
+
stroke-dasharray: 1 1;
|
|
235
|
+
stroke-dashoffset: 1;
|
|
236
|
+
opacity: 0;
|
|
237
|
+
transition: stroke-dashoffset var(--_dur) var(--_ease) var(--_delay, 0ms), opacity 160ms var(--_delay, 0ms), stroke 160ms, stroke-width 160ms;
|
|
238
|
+
}
|
|
239
|
+
.edge[data-shown] { stroke-dashoffset: 0; opacity: 1; }
|
|
240
|
+
.edge[data-dim] { opacity: .45; }
|
|
241
|
+
.edge[data-lit] { stroke: var(--_lit, var(--_accent)); stroke-width: calc(var(--_edge-width) + .5px); }
|
|
242
|
+
|
|
243
|
+
.root[data-edges="none"] .edges { display: none; }
|
|
244
|
+
|
|
245
|
+
.layer, .labels { position: absolute; inset: 0; pointer-events: none; }
|
|
246
|
+
|
|
247
|
+
/* ----------------------------------------------------------------- nodes */
|
|
248
|
+
|
|
249
|
+
.hub {
|
|
250
|
+
position: absolute;
|
|
251
|
+
pointer-events: auto;
|
|
252
|
+
transition: scale 220ms var(--_ease);
|
|
253
|
+
}
|
|
254
|
+
.hub[data-active] { scale: 1.08; }
|
|
255
|
+
.hub-icon { transition: rotate var(--_dur) var(--_spring), opacity 160ms; }
|
|
256
|
+
.overlay:not([data-state="open"]) .hub-icon { rotate: -90deg; opacity: 0; }
|
|
257
|
+
|
|
258
|
+
.node {
|
|
259
|
+
position: absolute;
|
|
260
|
+
left: 0;
|
|
261
|
+
top: 0;
|
|
262
|
+
width: var(--_node-size);
|
|
263
|
+
height: var(--_node-size);
|
|
264
|
+
margin: calc(var(--_node-size) / -2) 0 0 calc(var(--_node-size) / -2);
|
|
265
|
+
pointer-events: auto;
|
|
266
|
+
scale: 1;
|
|
267
|
+
--_tint: var(--_node-accent, var(--_accent));
|
|
268
|
+
transition:
|
|
269
|
+
translate var(--_dur) var(--_spring) var(--_delay, 0ms),
|
|
270
|
+
scale var(--_dur) var(--_spring) var(--_delay, 0ms),
|
|
271
|
+
opacity calc(var(--_dur) * .6) var(--_ease) var(--_delay, 0ms),
|
|
272
|
+
background-color 160ms, border-color 160ms, box-shadow 160ms, color 160ms;
|
|
273
|
+
}
|
|
274
|
+
.node[data-state="dim"] { opacity: var(--_dim-opacity); scale: var(--_dim-scale); }
|
|
275
|
+
.node[data-state="path"] { border-color: color-mix(in srgb, var(--_tint) 55%, transparent); color: var(--_tint); }
|
|
276
|
+
.node[data-active] {
|
|
277
|
+
background: var(--_surface-active);
|
|
278
|
+
color: var(--_tint);
|
|
279
|
+
opacity: 1;
|
|
280
|
+
scale: var(--_active-scale);
|
|
281
|
+
box-shadow: var(--_shadow), 0 0 0 2px var(--_tint), 0 0 0 7px color-mix(in srgb, var(--_tint) 18%, transparent);
|
|
282
|
+
}
|
|
283
|
+
.node[data-current] { color: var(--_tint); }
|
|
284
|
+
.node[data-current]::before {
|
|
285
|
+
content: "";
|
|
286
|
+
position: absolute;
|
|
287
|
+
inset: -4px;
|
|
288
|
+
border-radius: inherit;
|
|
289
|
+
border: 1.5px dashed color-mix(in srgb, var(--_tint) 70%, transparent);
|
|
290
|
+
pointer-events: none;
|
|
291
|
+
}
|
|
292
|
+
.node[aria-disabled="true"] { opacity: .35; cursor: not-allowed; }
|
|
293
|
+
.node[data-enter], .node[data-leave] { scale: .35; opacity: 0; }
|
|
294
|
+
.node[data-leave] { pointer-events: none; transition-duration: calc(var(--_dur) * .7); }
|
|
295
|
+
|
|
296
|
+
/* A knob on the rim, pointing where the children will unfold. */
|
|
297
|
+
.node[data-branch]::after {
|
|
298
|
+
content: "";
|
|
299
|
+
position: absolute;
|
|
300
|
+
width: 7px;
|
|
301
|
+
height: 7px;
|
|
302
|
+
border-radius: 50%;
|
|
303
|
+
background: var(--_surface-active);
|
|
304
|
+
box-shadow: 0 0 0 1.5px var(--_muted);
|
|
305
|
+
translate: calc(cos(var(--_a, 0deg)) * (var(--_node-size) / 2 - 1px)) calc(sin(var(--_a, 0deg)) * (var(--_node-size) / 2 - 1px));
|
|
306
|
+
transition: background-color 160ms, box-shadow 160ms;
|
|
307
|
+
}
|
|
308
|
+
.node[data-branch][data-current-trail]::after,
|
|
309
|
+
.node[data-branch][data-state="path"]::after,
|
|
310
|
+
.node[data-branch][data-active]::after { background: var(--_tint); box-shadow: 0 0 0 1.5px var(--_tint); }
|
|
311
|
+
.node[data-state="path"]::after { opacity: 0; }
|
|
312
|
+
|
|
313
|
+
.icon {
|
|
314
|
+
display: grid;
|
|
315
|
+
place-items: center;
|
|
316
|
+
width: var(--_icon-size);
|
|
317
|
+
height: var(--_icon-size);
|
|
318
|
+
pointer-events: none;
|
|
319
|
+
}
|
|
320
|
+
.icon > svg, .icon > img { width: 100%; height: 100%; display: block; }
|
|
321
|
+
.icon > img { object-fit: contain; border-radius: 4px; }
|
|
322
|
+
.glyph { font-size: calc(var(--_icon-size) * .92); line-height: 1; }
|
|
323
|
+
.mono { font-weight: 650; font-size: calc(var(--_icon-size) * .8); line-height: 1; letter-spacing: -.01em; }
|
|
324
|
+
|
|
325
|
+
/* ---------------------------------------------------------------- labels */
|
|
326
|
+
|
|
327
|
+
.label {
|
|
328
|
+
position: absolute;
|
|
329
|
+
left: 0;
|
|
330
|
+
top: 0;
|
|
331
|
+
box-sizing: border-box;
|
|
332
|
+
width: max-content;
|
|
333
|
+
max-width: var(--unfold-label-max-width, 160px);
|
|
334
|
+
padding: 5px 10px 6px;
|
|
335
|
+
border-radius: var(--_label-radius);
|
|
336
|
+
background: var(--_label-bg);
|
|
337
|
+
color: var(--_label-fg);
|
|
338
|
+
box-shadow: 0 1px 2px rgb(0 0 0 / .06), 0 4px 14px -4px rgb(0 0 0 / .18), 0 0 0 .5px var(--_outline);
|
|
339
|
+
-webkit-backdrop-filter: blur(var(--_blur));
|
|
340
|
+
backdrop-filter: blur(var(--_blur));
|
|
341
|
+
overflow-wrap: anywhere;
|
|
342
|
+
pointer-events: none;
|
|
343
|
+
opacity: 0;
|
|
344
|
+
/* Labels never slide: a sliding label could cross another one on its way. */
|
|
345
|
+
transition: opacity 140ms var(--_ease);
|
|
346
|
+
}
|
|
347
|
+
.label[data-visible] { opacity: 1; transition-delay: var(--_label-delay, 0ms), 0ms; }
|
|
348
|
+
.label[data-instant] { transition: none; }
|
|
349
|
+
.label .title {
|
|
350
|
+
display: block;
|
|
351
|
+
text-wrap: balance;
|
|
352
|
+
font-family: var(--unfold-label-font, var(--unfold-font));
|
|
353
|
+
font-size: var(--_label-size);
|
|
354
|
+
font-weight: var(--_label-weight);
|
|
355
|
+
line-height: 1.25;
|
|
356
|
+
letter-spacing: var(--_label-tracking);
|
|
357
|
+
text-transform: var(--_label-case);
|
|
358
|
+
}
|
|
359
|
+
.label[data-go] .title::after { content: " →"; color: var(--_muted); font-weight: 500; }
|
|
360
|
+
.label .desc { display: none; margin-top: 2px; font-weight: 450; font-size: var(--_desc-size); line-height: 1.35; color: var(--_muted); }
|
|
361
|
+
.label[data-active] { max-width: var(--unfold-label-max-width-active, 240px); }
|
|
362
|
+
/* The wrapped variant, used where a one-line label doesn't fit. Words stay whole (hyphenated if needed). */
|
|
363
|
+
.label[data-narrow] {
|
|
364
|
+
max-width: var(--unfold-label-narrow-width, 96px);
|
|
365
|
+
min-width: min-content;
|
|
366
|
+
overflow-wrap: normal;
|
|
367
|
+
hyphens: auto;
|
|
368
|
+
}
|
|
369
|
+
.label[data-active]:not([data-compact]) .desc { display: block; }
|
|
370
|
+
.labels .measure { position: absolute; left: 0; top: 0; visibility: hidden; }
|
|
371
|
+
|
|
372
|
+
.sr-only {
|
|
373
|
+
position: absolute;
|
|
374
|
+
width: 1px;
|
|
375
|
+
height: 1px;
|
|
376
|
+
overflow: hidden;
|
|
377
|
+
clip-path: inset(50%);
|
|
378
|
+
white-space: nowrap;
|
|
379
|
+
}
|
|
380
|
+
.safe-probe {
|
|
381
|
+
position: fixed;
|
|
382
|
+
inset: 0;
|
|
383
|
+
visibility: hidden;
|
|
384
|
+
pointer-events: none;
|
|
385
|
+
padding: env(safe-area-inset-top, 0px) env(safe-area-inset-right, 0px) env(safe-area-inset-bottom, 0px) env(safe-area-inset-left, 0px);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/* Right-to-left: "back" points the other way. */
|
|
389
|
+
:host(:dir(rtl)) .hub[data-icon="back"] .hub-icon { scale: -1 1; }
|
|
390
|
+
|
|
391
|
+
@media (prefers-contrast: more) {
|
|
392
|
+
.root {
|
|
393
|
+
--_border-width: 2px;
|
|
394
|
+
--_border: currentColor;
|
|
395
|
+
--_muted: var(--_fg);
|
|
396
|
+
--_surface: var(--_surface-active);
|
|
397
|
+
--_label-bg: var(--_surface-active);
|
|
398
|
+
--_edge: color-mix(in srgb, var(--_fg) 60%, transparent);
|
|
399
|
+
--_dim-opacity: 1;
|
|
400
|
+
--_blur: 0px;
|
|
401
|
+
}
|
|
402
|
+
.label { border: 1.5px solid currentColor; }
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
@media (prefers-reduced-transparency: reduce) {
|
|
406
|
+
.root { --_surface: var(--_surface-active); --_label-bg: var(--_surface-active); --_blur: 0px; --_backdrop-blur: 0px; --_dock-blur: 0px; }
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/* Windows High Contrast and other forced palettes: states move from colour/shadow to outlines. */
|
|
410
|
+
@media (forced-colors: active) {
|
|
411
|
+
.trigger, .hub, .node { border: 2px solid ButtonText; }
|
|
412
|
+
.node[data-active], .hub[data-active] { outline: 3px solid Highlight; outline-offset: 2px; }
|
|
413
|
+
.node[data-state="path"] { border-color: Highlight; }
|
|
414
|
+
.node[data-state="dim"] { opacity: 1; }
|
|
415
|
+
.node[data-current]::before { border-color: Highlight; }
|
|
416
|
+
.node[data-branch]::after { background: ButtonText; box-shadow: none; }
|
|
417
|
+
.edge { stroke: CanvasText; }
|
|
418
|
+
.edge[data-lit] { stroke: Highlight; }
|
|
419
|
+
.label { border: 1px solid CanvasText; }
|
|
420
|
+
.backdrop { background: Canvas; opacity: .9; }
|
|
421
|
+
.hold circle { stroke: Highlight; }
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
@media (prefers-reduced-motion: reduce) {
|
|
425
|
+
.root { --_dur: 1ms; --_spring: linear; }
|
|
426
|
+
.label { transition: opacity 120ms; }
|
|
427
|
+
}
|
|
428
|
+
`,L=Object.freeze({pages:`Pages`,close:`Close navigation`,backToTop:`Back to all pages`,back:`Back to {label}`}),R=Object.freeze({pages:Object.freeze([]),position:`bottom-right`,dock:`float`,offset:24,holdDelay:220,expandDelay:140,openOnTap:!0,nodeSize:52,triggerSize:60,spacing:96,gap:16,labels:`auto`,edges:`curved`,backdrop:!0,haptics:!0,theme:`auto`,current:void 0,label:`Navigation`,arrowKeys:`tree`,strings:Object.freeze({}),triggerIcon:void 0,iconResolver:void 0,navigate:void 0});function z(e){return typeof e==`string`||typeof e==`function`||typeof e==`object`&&!!e&&`cloneNode`in e&&typeof e.cloneNode==`function`}var de={position:[`top-left`,`top`,`top-right`,`left`,`center`,`right`,`bottom-left`,`bottom`,`bottom-right`,`inline`],dock:[`float`,`bar`],labels:[`auto`,`always`,`hover`,`none`],edges:[`curved`,`straight`,`step`,`none`],theme:[`auto`,`light`,`dark`],arrowKeys:[`tree`,`spatial`]};function fe(e,t){if(!t||typeof t!=`object`||Array.isArray(t))throw TypeError(`[unfold-nav] Options must be an object.`);let n={...e};for(let[e,r]of Object.entries(t)){if(!Object.hasOwn(R,e))continue;let t=e;n[t]=r===void 0?R[t]:r}for(let[e,t]of Object.entries(de))if(!t.includes(n[e]))throw TypeError(`[unfold-nav] Invalid ${e}. Expected ${t.join(`, `)}.`);for(let e of[`nodeSize`,`triggerSize`,`spacing`,`gap`,`holdDelay`,`expandDelay`]){let t=n[e],r=e===`nodeSize`||e===`triggerSize`||e===`spacing`;if(typeof t!=`number`||!Number.isFinite(t)||(r?t<=0:t<0))throw RangeError(`[unfold-nav] ${e} must be a finite ${r?`positive`:`non-negative`} number.`)}let r=n.offset,i=typeof r==`number`?[r]:r&&typeof r==`object`?[r.x,r.y]:[];if(!i.length||i.some(e=>typeof e!=`number`||!Number.isFinite(e)||e<0))throw RangeError(`[unfold-nav] offset must be a non-negative number or { x, y }.`);for(let e of[`openOnTap`,`backdrop`,`haptics`])if(typeof n[e]!=`boolean`)throw TypeError(`[unfold-nav] ${e} must be a boolean.`);if(typeof n.label!=`string`||!n.label.trim())throw TypeError(`[unfold-nav] label must be a non-empty string.`);if(n.current!=null&&typeof n.current!=`string`)throw TypeError(`[unfold-nav] current must be a URL string, null or undefined.`);for(let e of[`navigate`,`iconResolver`])if(n[e]!==void 0&&typeof n[e]!=`function`)throw TypeError(`[unfold-nav] ${e} must be a function.`);if(n.triggerIcon!==void 0&&!z(n.triggerIcon))throw TypeError(`[unfold-nav] Invalid triggerIcon.`);if(!n.strings||typeof n.strings!=`object`||Array.isArray(n.strings))throw TypeError(`[unfold-nav] strings must be an object.`);for(let e of Object.keys(L))if(n.strings[e]!==void 0&&typeof n.strings[e]!=`string`)throw TypeError(`[unfold-nav] strings.${e} must be a string.`);return n.strings=Object.fromEntries(Object.entries(n.strings).filter(([e,t])=>Object.hasOwn(L,e)&&t!==void 0)),n}function B(e){let t=Array.isArray(e)?{label:`Navigation`,children:e}:e??{label:`Navigation`,children:[]},n=new Map,r={id:``,page:t,parent:null,children:[],depth:0,index:0},i=new WeakSet,a=(e,t)=>{if(!e||typeof e!=`object`||Array.isArray(e))throw TypeError(`[unfold-nav] ${t} must be a page object.`);if(typeof e.label!=`string`||!e.label.trim())throw TypeError(`[unfold-nav] ${t}.label must be a non-empty string.`);for(let n of[`id`,`href`,`target`,`description`,`color`])if(e[n]!==void 0&&typeof e[n]!=`string`)throw TypeError(`[unfold-nav] ${t}.${n} must be a string.`);if(e.children!==void 0&&!Array.isArray(e.children))throw TypeError(`[unfold-nav] ${t}.children must be an array.`);if(e.disabled!==void 0&&typeof e.disabled!=`boolean`)throw TypeError(`[unfold-nav] ${t}.disabled must be a boolean.`);if(e.icon!==void 0&&!z(e.icon))throw TypeError(`[unfold-nav] ${t}.icon is invalid.`);if(i.has(e))throw TypeError(`[unfold-nav] ${t} contains a cyclic page tree.`)};a(t,`pages`),i.add(t);let o=(e,t,r)=>{(t??[]).forEach((t,s)=>{let c=[...r,s];a(t,`pages[${c.join(`].children[`)}]`);let l=t.id!=null&&t.id!==``?String(t.id):`n${c.join(`.`)}`;if(n.has(l)){let e=2;for(;n.has(`${l}~${e}`);)e++;l=`${l}~${e}`}let u={id:l,page:t,parent:e,children:[],depth:e.depth+1,index:s};n.set(l,u),e.children.push(u),i.add(t),o(u,t.children,c),i.delete(t)})};return o(r,t.children,[]),{root:r,byId:n}}function V(e){let t=[];for(let n=e;n&&n.depth>0;n=n.parent)t.unshift(n.id);return t}var H=e=>e.length>1?e.replace(/\/+$/,``):e;function U(e,t,n){let r;try{r=new URL(t,n)}catch{return null}let i=H(r.pathname),a=null,o=-1,s=null,c=-1;for(let t of e.byId.values()){let e=t.page.href;if(!e)continue;let l;try{l=new URL(e,n)}catch{continue}if(l.origin!==r.origin||l.search&&l.search!==r.search||l.hash&&l.hash!==r.hash)continue;let u=H(l.pathname);if(u===i){let e=+!!l.search+ +!!l.hash;(!a||e>o||e===o&&t.depth>a.depth)&&(a=t,o=e)}else u!==`/`&&i.startsWith(u+`/`)&&u.length>c&&(s=t,c=u.length)}return a??s}var pe=[`top`,`right`,`bottom`,`left`],W=new WeakMap;function me(e,t,n,r=0){let i=W.get(t);if(!i&&!n)return;i||(i={owners:new Map,previous:new Map},W.set(t,i)),n?i.owners.set(e,{edge:n,size:r}):i.owners.delete(e);let a=t.documentElement.style;for(let e of pe){let t=`--unfold-inset-${e}`,n=[...i.owners.values()].filter(t=>t.edge===e).map(e=>e.size);if(n.length)i.previous.has(e)||i.previous.set(e,{value:a.getPropertyValue(t),priority:a.getPropertyPriority(t)}),a.setProperty(t,`calc(${Math.max(...n)}px + env(safe-area-inset-${e}, 0px))`);else{let n=i.previous.get(e);n&&(n.value?a.setProperty(t,n.value,n.priority):a.removeProperty(t),i.previous.delete(e))}}i.owners.size||W.delete(t)}function he(e,t){try{let n=new URL(e,t);return[`http:`,`https:`,`mailto:`,`tel:`,`sms:`].includes(n.protocol)?n.href:null}catch{return null}}var G=Object.keys(R),K={pages:`pages`,position:`position`,dock:`dock`,offset:`offset`,"hold-delay":`holdDelay`,"expand-delay":`expandDelay`,"open-on-tap":`openOnTap`,"node-size":`nodeSize`,"trigger-size":`triggerSize`,spacing:`spacing`,gap:`gap`,labels:`labels`,edges:`edges`,backdrop:`backdrop`,haptics:`haptics`,theme:`theme`,current:`current`,label:`label`,"arrow-keys":`arrowKeys`,"trigger-icon":`triggerIcon`};function ge(e,t){if(t===null)return R[e];if(e===`offset`){let[e,n=e]=t.trim().split(/[\s,]+/).map(Number);return{x:e,y:n}}if(e===`pages`)return JSON.parse(t);switch(typeof R[e]){case`number`:return Number(t);case`boolean`:return!/^(false|0|off|no)$/i.test(t.trim())}return t}var _e=`http://www.w3.org/2000/svg`,ve=``,q=typeof HTMLElement<`u`&&`showPopover`in HTMLElement.prototype,ye=typeof HTMLElement>`u`?class{}:HTMLElement,J={ArrowUp:{x:0,y:-1},ArrowDown:{x:0,y:1},ArrowLeft:{x:-1,y:0},ArrowRight:{x:1,y:0}};function Y(e,t,n,r=``){n?e.setAttribute(t,r):e.removeAttribute(t)}function X(e,t,n){let r=[t];for(let[e,i]of Object.entries(n))i&&r.push(`${t}-${e}`);let i=r.join(` `);e.getAttribute(`part`)!==i&&e.setAttribute(`part`,i)}var Z=class extends ye{static get observedAttributes(){return Object.keys(K)}opts={...R};text=L;tree=B([]);currentId=null;currentTrail=new Set;state=`closed`;mode=`tap`;path=[];active=null;focusId=null;views=new Map;placed=new Map;fanCache=new Map;labelSizes=new Map;branchLabelSizes=new Map;narrowSizes=new Map;narrowBranchSizes=new Map;hub={x:0,y:0,r:30};bounds={x:0,y:0,w:0,h:0};animationTimers=new Set;pointerId=null;pointerType=`mouse`;downAt={x:0,y:0};lastPoint={x:0,y:0};leftHub=!1;holdTimer=0;dwellTimer=0;dwellTarget=null;closeTimer=0;resizeFrame=0;openedAt=0;lastPointerUp=-1/0;typeahead={text:``,at:0};lastKeyActivation=-1/0;els;constructor(){if(typeof document>`u`)throw Error(`[unfold-nav] Create navigation elements in a browser after mounting.`);super();let e=this.attachShadow({mode:`open`});e.innerHTML=`<style>${ue}</style>
|
|
429
|
+
<div class="root" part="root">
|
|
430
|
+
<div class="dock-bar" part="dock-bar" aria-hidden="true"></div>
|
|
431
|
+
<div class="dock" part="dock">
|
|
432
|
+
<button class="trigger" part="trigger" type="button" aria-haspopup="dialog" aria-expanded="false" aria-controls="graph">
|
|
433
|
+
<svg class="hold" viewBox="0 0 100 100" aria-hidden="true"><circle cx="50" cy="50" r="47" pathLength="1"/></svg>
|
|
434
|
+
<span class="trigger-icon" part="trigger-icon" aria-hidden="true"><slot name="icon"></slot><span class="icon-own"></span></span>
|
|
435
|
+
</button>
|
|
436
|
+
</div>
|
|
437
|
+
<dialog class="overlay" part="overlay" id="graph">
|
|
438
|
+
<div class="backdrop" part="backdrop" aria-hidden="true"></div>
|
|
439
|
+
<svg class="edges" part="edges" aria-hidden="true"></svg>
|
|
440
|
+
<div class="layer" role="tree"></div>
|
|
441
|
+
<div class="labels" aria-hidden="true"><div class="measure"></div></div>
|
|
442
|
+
<button class="hub" part="hub" type="button"><span class="hub-icon" aria-hidden="true"></span></button>
|
|
443
|
+
</dialog>
|
|
444
|
+
<div class="safe-probe" aria-hidden="true"></div>
|
|
445
|
+
</div>`;let t=t=>e.querySelector(t);this.els={root:t(`.root`),dockBar:t(`.dock-bar`),dock:t(`.dock`),trigger:t(`.trigger`),triggerIcon:t(`.trigger-icon`),iconSlot:t(`slot[name="icon"]`),iconOwn:t(`.icon-own`),overlay:t(`.overlay`),edges:t(`.edges`),layer:t(`.layer`),labels:t(`.labels`),measure:t(`.measure`),hub:t(`.hub`),hubIcon:t(`.hub-icon`),probe:t(`.safe-probe`)},q&&this.els.overlay.setAttribute(`popover`,`manual`),this.els.iconSlot.addEventListener(`slotchange`,()=>this.syncSlotted());let{trigger:n,overlay:r}=this.els;n.addEventListener(`pointerdown`,this.onPointerDown),n.addEventListener(`pointermove`,this.onPointerMove),n.addEventListener(`pointerup`,this.onPointerUp),n.addEventListener(`pointercancel`,this.onPointerCancel),n.addEventListener(`lostpointercapture`,this.onLostCapture),n.addEventListener(`click`,this.onTriggerClick),n.addEventListener(`keydown`,this.onTriggerKey),n.addEventListener(`contextmenu`,e=>e.preventDefault()),r.addEventListener(`click`,this.onOverlayClick),r.addEventListener(`pointermove`,this.onOverlayHover),r.addEventListener(`keydown`,this.onOverlayKey),r.addEventListener(`cancel`,this.onCancel),r.addEventListener(`close`,this.onDialogClose),r.addEventListener(`wheel`,e=>e.preventDefault(),{passive:!1}),r.addEventListener(`touchmove`,e=>e.preventDefault(),{passive:!1}),r.addEventListener(`contextmenu`,e=>e.preventDefault()),this.applyOptions()}configure(e){let t=fe(this.opts,e),n=Object.hasOwn(e,`pages`),r=n?B(t.pages):this.tree;if(this.opts=t,this.tree=r,n&&this.state!==`closed`){let e=this.state===`open`,t=this.focusInside();this.finishClose(),t&&this.isConnected&&this.els.trigger.focus({preventScroll:!0}),e&&this.emit(`unfold-close`)}return this.fanCache.clear(),this.clearLabelSizes(),this.applyOptions(),this.state===`open`&&(this.measure(),this.render()),this}get isOpen(){return this.state===`open`}open({focus:e=!1}={}){this.show(`tap`,e?`keyboard`:`pointer`)}close({focusTrigger:e=!1}={}){if(this.state!==`open`)return;let t=this.focusInside();this.state=`closing`,window.clearTimeout(this.holdTimer),window.clearTimeout(this.dwellTimer),this.holdTimer=this.dwellTimer=0,this.dwellTarget=null,this.pointerId=null,window.removeEventListener(`keydown`,this.onWindowKey,!0);let{overlay:n,trigger:r,hub:i}=this.els;if(n.dataset.state=`closing`,n.setAttribute(`aria-hidden`,`true`),i.tabIndex=-1,n.open&&(n.close(),q))try{n.showPopover()}catch{}r.setAttribute(`aria-expanded`,`false`);let a=[...this.views.values()].filter(e=>!e.leaveTimer).reverse(),o=this.reducedMotion?0:Math.min(12,120/Math.max(1,a.length));a.forEach((e,t)=>this.leave(e,this.hub,t*o)),this.closeTimer=window.setTimeout(()=>this.finishClose(),this.duration+a.length*o+60),(e||t)&&r.focus({preventScroll:!0}),this.emit(`unfold-close`)}toggle(){this.state===`open`?this.close():this.open()}connectedCallback(){for(let e of G)this.upgradeProperty(e);if(!this.tree.root.children.length){let e=this.querySelector(`script[type="application/json"]`);if(e?.textContent?.trim())try{this.configure({pages:JSON.parse(e.textContent)})}catch(e){console.warn(`[unfold-nav] Invalid inline pages:`,e)}}window.addEventListener(`resize`,this.onResize),document.fonts?.addEventListener(`loadingdone`,this.onFontsLoaded),this.publishInsets(),this.onResize()}disconnectedCallback(){window.removeEventListener(`resize`,this.onResize),window.removeEventListener(`keydown`,this.onWindowKey,!0),document.fonts?.removeEventListener(`loadingdone`,this.onFontsLoaded),window.clearTimeout(this.holdTimer),window.clearTimeout(this.dwellTimer),this.holdTimer=this.dwellTimer=0,this.pointerId=null,this.els.trigger.removeAttribute(`data-pressing`),cancelAnimationFrame(this.resizeFrame),this.resizeFrame=0,this.finishClose(),this.publishInsets()}attributeChangedCallback(e,t,n){if(t===n)return;let r=K[e];if(r)try{this.configure({[r]:ge(r,n)})}catch(t){console.warn(`[unfold-nav] Ignoring invalid ${e} attribute:`,t)}}upgradeProperty(e){if(Object.prototype.hasOwnProperty.call(this,e)){let t=this[e];delete this[e],this.configure({[e]:t})}}applyOptions(){let e=this.opts,{root:t,dock:n,dockBar:r,trigger:i,layer:a,overlay:o}=this.els;this.text={...L,...e.strings},t.dataset.theme=e.theme,t.dataset.edges=e.edges,t.dataset.dock=e.dock,Y(t,`data-backdrop`,e.backdrop),n.dataset.position=e.position;let s=this.dockEdge();Y(r,`data-edge`,!!s,s??``);let c=this.offsets;t.style.setProperty(`--_offset-x`,`${c.x}px`),t.style.setProperty(`--_offset-y`,`${c.y}px`),t.style.setProperty(`--_trigger-size`,`${e.triggerSize}px`),t.style.setProperty(`--_node-size`,`${e.nodeSize}px`),t.style.setProperty(`--_hold`,`${e.holdDelay}ms`),i.setAttribute(`aria-label`,e.label),o.setAttribute(`aria-label`,e.label),a.setAttribute(`aria-label`,this.text.pages),this.syncIcon(),this.publishInsets()}get offsets(){let e=this.opts.offset;return typeof e==`number`?{x:e,y:e}:e}dockEdge(){let e=this.opts.position;return e===`center`||e===`inline`?null:e.startsWith(`top`)?`top`:e.startsWith(`bottom`)?`bottom`:e}publishInsets(){let e=this.isConnected?this.dockEdge():null,t=this.offsets,n=this.opts.triggerSize+2*(e===`top`||e===`bottom`?t.y:t.x);me(this,this.ownerDocument,e,n)}syncIcon(){let e=this.opts,t=r(e.triggerIcon??this.tree.root.page.icon,e.iconResolver);this.els.iconOwn.replaceChildren(t??r(o,void 0)),this.els.iconOwn.toggleAttribute(`data-custom`,!!t),this.syncSlotted()}syncSlotted(){let e=this.els.iconSlot.assignedNodes().length>0;Y(this.els.triggerIcon,`data-slotted`,e),Y(this.els.triggerIcon,`data-default`,!e&&!this.els.iconOwn.hasAttribute(`data-custom`)),this.isConnected&&this.orientIcon()}show(e,t){if(this.state===`open`||!this.isConnected)return;window.clearTimeout(this.closeTimer),this.state=`open`,this.mode=e,this.path=[],this.active=null,this.focusId=null,this.dwellTarget=null,this.computeCurrent();let{overlay:n,trigger:r,hub:i}=this.els;if(n.dataset.state=`open`,n.dataset.mode=e,n.removeAttribute(`aria-hidden`),i.tabIndex=0,this.present(e===`tap`),r.setAttribute(`aria-expanded`,`true`),this.openedAt=performance.now(),this.measure(),this.render(),this.haptic(10),e===`drag`&&window.addEventListener(`keydown`,this.onWindowKey,!0),this.emit(`unfold-open`,{mode:e}),e===`tap`&&t!==`none`){let e=this.initialFocusId();e&&this.focusNode(e,t===`keyboard`)}}present(e){let t=this.els.overlay;try{e?(q&&t.matches(`:popover-open`)&&t.hidePopover(),t.open||t.showModal()):!t.open&&!(q&&t.matches(`:popover-open`))&&(q?t.showPopover():t.show())}catch{}}finishClose(){window.clearTimeout(this.closeTimer),this.state=`closed`,window.removeEventListener(`keydown`,this.onWindowKey,!0),window.clearTimeout(this.holdTimer),window.clearTimeout(this.dwellTimer),this.holdTimer=this.dwellTimer=0,this.dwellTarget=null,this.pointerId=null,this.els.trigger.removeAttribute(`data-pressing`);for(let e of this.animationTimers)window.clearTimeout(e);this.animationTimers.clear();for(let e of this.views.values())window.clearTimeout(e.leaveTimer),e.node.remove(),e.label.remove(),e.edge.remove();this.views.clear(),this.placed.clear();let{overlay:e}=this.els;try{e.open&&e.close(),q&&e.matches(`:popover-open`)&&e.hidePopover()}catch{}e.removeAttribute(`data-state`),e.removeAttribute(`aria-hidden`),this.els.trigger.setAttribute(`aria-expanded`,`false`)}onCancel=e=>{e.preventDefault(),this.state===`open`&&(this.path.length?this.goUp(!0):this.close({focusTrigger:!0}))};onDialogClose=()=>{this.state===`open`&&!this.els.overlay.open&&!(q&&this.els.overlay.matches(`:popover-open`))&&(this.finishClose(),this.emit(`unfold-close`),this.els.trigger.focus({preventScroll:!0}))};onWindowKey=e=>{e.key===`Escape`&&this.state===`open`&&this.mode===`drag`&&(e.preventDefault(),this.close())};focusInside(){let e=this.shadowRoot?.activeElement;return!!e&&this.els.overlay.contains(e)}computeCurrent(){let e=this.opts.current===void 0?location.href:this.opts.current,t=e?U(this.tree,e,location.href):null;this.currentId=t?.id??null,this.currentTrail=new Set(V(t))}initialFocusId(){return(this.currentId?V(this.tree.byId.get(this.currentId)):[])[0]??this.tree.root.children[0]?.id??null}measure(){let{trigger:e,hub:t,probe:n,overlay:r}=this.els,i=e.getBoundingClientRect(),a=e.offsetWidth/2,o={x:i.left+i.width/2,y:i.top+i.height/2,r:a};(o.x!==this.hub.x||o.y!==this.hub.y||o.r!==this.hub.r)&&this.fanCache.clear(),this.hub=o,Object.assign(t.style,{left:`${o.x-a}px`,top:`${o.y-a}px`,width:`${a*2}px`,height:`${a*2}px`});let s=r.getBoundingClientRect(),c=s.width||document.documentElement.clientWidth,l=s.height||window.innerHeight,u=getComputedStyle(n),d={t:parseFloat(u.paddingTop)||0,r:parseFloat(u.paddingRight)||0,b:parseFloat(u.paddingBottom)||0,l:parseFloat(u.paddingLeft)||0},f={x:d.l+8,y:d.t+8,w:c-d.l-d.r-16,h:l-d.t-d.b-16};(f.w!==this.bounds.w||f.h!==this.bounds.h)&&this.fanCache.clear(),this.bounds=f}orientIcon(){let e=this.els.trigger.getBoundingClientRect(),t=e.left+e.width/2,n=e.top+e.height/2,r=document.documentElement.clientWidth/2-t,i=window.innerHeight/2-n,a=Math.hypot(r,i)<2?0:Math.atan2(i,r)*180/Math.PI+90;this.els.root.style.setProperty(`--_icon-rotate`,`${a.toFixed(1)}deg`)}onResize=()=>{cancelAnimationFrame(this.resizeFrame),this.resizeFrame=requestAnimationFrame(()=>{this.resizeFrame=0,this.isConnected&&(this.orientIcon(),this.state===`open`&&(this.measure(),this.render()))})};clearLabelSizes(){for(let e of[this.labelSizes,this.branchLabelSizes,this.narrowSizes,this.narrowBranchSizes])e.clear()}onFontsLoaded=()=>{this.clearLabelSizes(),this.fanCache.clear(),this.state===`open`&&this.render()};render(){if(this.state!==`open`)return;let{root:e,byId:t}=this.tree,n=this.opts.nodeSize/2,r=[{key:``,parentId:null,childIds:e.children.map(e=>e.id)}],i=[];for(let e of this.path){let n=t.get(e);if(!n||!n.children.length||(n.parent?.id??``)!==(i[i.length-1]??``))break;i.push(e),r.push({key:i.join(ve),parentId:e,childIds:n.children.map(e=>e.id)})}this.path=i;let a=new Set(i),o=r[r.length-1].parentId??``,l=this.opts.labels!==`none`;l&&this.measureLabels(r.flatMap(e=>e.childIds)),this.placed=F({hub:this.hub,bounds:this.bounds,levels:r,nodeRadius:n,distance:this.opts.spacing,gap:this.opts.gap,edgeStyle:this.opts.edges,labelSize:l?e=>this.sizesOf(e,!1):void 0,branchLabelSize:l?e=>this.sizesOf(e,!0):void 0,labelPad:this.labelPad},this.fanCache);for(let e of this.views.values())!this.placed.has(e.tree.id)&&!e.leaveTimer&&this.leave(e,e.from,0);let u=this.focusId&&this.placed.has(this.focusId)?this.focusId:this.initialFocusId(),d=[];for(let e of r){let r=(e.parentId?this.views.get(e.parentId):null)?.node??null;for(let i of e.childIds){let s=this.placed.get(i),c=this.views.get(i);c?c.leaveTimer&&(window.clearTimeout(c.leaveTimer),c.leaveTimer=0,c.node.removeAttribute(`data-leave`),c.edge.setAttribute(`data-shown`,``)):(c=this.createView(t.get(i),s),this.views.set(i,c),r?r.after(c.node):this.els.layer.append(c.node),d.push(c)),r=c.node,c.from=s.from;let{node:l,edge:f,tree:p}=c,m=a.has(i)?`path`:(p.parent?.id??``)===o?`frontier`:`dim`;l.dataset.state=m,Y(l,`data-active`,i===this.active),Y(l,`data-current`,i===this.currentId),Y(l,`data-current-trail`,this.currentTrail.has(i)&&i!==this.currentId),i===this.currentId?l.setAttribute(`aria-current`,`page`):l.removeAttribute(`aria-current`),p.children.length&&l.setAttribute(`aria-expanded`,String(a.has(i))),l.tabIndex=i===u?0:-1,l.style.setProperty(`--_a`,`${s.angle.toFixed(4)}rad`),d.includes(c)||(l.style.translate=`${s.x}px ${s.y}px`),X(l,`node`,{active:i===this.active,current:i===this.currentId,trail:this.currentTrail.has(i)&&i!==this.currentId,path:m===`path`,frontier:m===`frontier`,dim:m===`dim`,branch:p.children.length>0,disabled:!!p.page.disabled});let h=e.parentId==null?this.hub:{...this.placed.get(e.parentId),r:n},g=a.has(i)||i===this.active,_=m===`dim`&&i!==this.active;f.setAttribute(`d`,C(h,{x:s.x,y:s.y,r:n},this.opts.edges,s.parentAngle).d),Y(f,`data-lit`,g),Y(f,`data-dim`,_),X(f,`edge`,{lit:g,dim:_})}}d.length&&this.animateIn(d),this.renderLabels();let f=this.els.hub,p=i.length?`back`:`close`;f.dataset.icon!==p&&(f.dataset.icon=p,this.els.hubIcon.innerHTML=i.length?c:s);let m=i.length>1?t.get(i[i.length-2]).page.label:null;f.setAttribute(`aria-label`,i.length?m?this.text.back.replace(`{label}`,m):this.text.backToTop:this.text.close),Y(f,`data-active`,this.mode===`drag`&&this.dwellTarget===`hub`),X(f,`hub`,{back:i.length>0,active:f.hasAttribute(`data-active`)})}get labelPad(){let e=parseFloat(getComputedStyle(this.els.root).getPropertyValue(`--_active-scale`))||1.14;return this.opts.nodeSize/2*Math.max(0,e-1)+8}buildLabel(e){let t=document.createElement(`div`);t.className=`label`,t.setAttribute(`part`,`label`);let n=document.createElement(`span`);if(n.className=`title`,n.textContent=e.page.label,t.append(n),e.page.description){let n=document.createElement(`span`);n.className=`desc`,n.textContent=e.page.description,t.append(n)}return t}sizesOf(e,t){let n=(t?this.branchLabelSizes.get(e):null)??this.labelSizes.get(e);if(!n)return null;let r=(t?this.narrowBranchSizes.get(e):null)??this.narrowSizes.get(e);return r?[n,r]:n}measureLabels(e){let t=e.filter(e=>!this.labelSizes.has(e));if(!t.length)return;let n=this.els.measure,r=e=>e.children.length&&e.page.href?[!1,!0]:[!1],i=t.flatMap(e=>{let t=this.tree.byId.get(e);return r(t).flatMap(r=>[!1,!0].map(i=>{let a=this.buildLabel(t);return Y(a,`data-go`,r),Y(a,`data-narrow`,i),n.append(a),{id:e,el:a,go:r,narrow:i}}))}),a=e=>({w:Math.ceil(e.offsetWidth)+1,h:Math.ceil(e.offsetHeight)+1});for(let{id:e,el:t,go:n,narrow:r}of i)(r?n?this.narrowBranchSizes:this.narrowSizes:n?this.branchLabelSizes:this.labelSizes).set(e,a(t));for(let[e,n]of[[this.labelSizes,this.narrowSizes],[this.branchLabelSizes,this.narrowBranchSizes]])for(let r of t){let t=n.get(r);t&&t.w>=(e.get(r)?.w??0)-1&&n.delete(r)}n.replaceChildren()}createView(e,t){let n=e.page,a=document.createElement(`button`);a.type=`button`,a.className=`node`,a.setAttribute(`part`,`node`),a.setAttribute(`role`,`treeitem`),a.setAttribute(`aria-label`,n.label),a.setAttribute(`aria-level`,String(e.depth)),a.setAttribute(`aria-setsize`,String(e.parent?.children.length??1)),a.setAttribute(`aria-posinset`,String(e.index+1)),n.description&&a.setAttribute(`aria-description`,n.description),n.disabled&&a.setAttribute(`aria-disabled`,`true`),e.children.length&&(a.dataset.branch=``),n.color&&a.style.setProperty(`--_node-accent`,n.color),a.dataset.id=e.id;let o=document.createElement(`span`);o.className=`icon`,o.setAttribute(`part`,`icon`),o.setAttribute(`aria-hidden`,`true`),o.append(r(n.icon,this.opts.iconResolver,n)??i(n.label)),a.append(o);let s=this.buildLabel(e);this.els.labels.append(s);let c=document.createElementNS(_e,`path`);return c.setAttribute(`class`,`edge`),c.setAttribute(`part`,`edge`),c.setAttribute(`pathLength`,`1`),n.color&&c.style.setProperty(`--_lit`,n.color),this.els.edges.append(c),{tree:e,node:a,label:s,edge:c,from:t.from,leaveTimer:0,shownAt:null}}animateIn(e){let t=this.reducedMotion?0:22;for(let t of e)t.node.style.transition=`none`,t.node.style.translate=`${t.from.x}px ${t.from.y}px`,t.node.dataset.enter=``;this.els.layer.offsetWidth,e.forEach((e,n)=>{let r=this.placed.get(e.tree.id),i=n*t;e.node.style.transition=``,e.node.style.setProperty(`--_delay`,`${i}ms`),e.edge.style.setProperty(`--_delay`,`${i}ms`),e.label.style.setProperty(`--_label-delay`,`${i+this.duration*.6}ms`),e.node.style.translate=`${r.x}px ${r.y}px`,e.node.removeAttribute(`data-enter`),e.edge.setAttribute(`data-shown`,``);let a=window.setTimeout(()=>{this.animationTimers.delete(a),e.node.style.removeProperty(`--_delay`),e.edge.style.removeProperty(`--_delay`),e.label.style.removeProperty(`--_label-delay`)},i+this.duration);this.animationTimers.add(a)})}leave(e,t,n){let{node:r,edge:i,label:a}=e;if(this.shadowRoot?.activeElement===r&&this.state===`open`){let t=e.tree.parent?this.views.get(e.tree.parent.id):null;t&&!t.leaveTimer?(this.focusId=t.tree.id,t.node.tabIndex=0,t.node.focus({preventScroll:!0})):this.els.hub.focus({preventScroll:!0})}r.style.setProperty(`--_delay`,`${n}ms`),i.style.setProperty(`--_delay`,`${n}ms`),r.style.translate=`${t.x}px ${t.y}px`,r.setAttribute(`data-leave`,``),r.removeAttribute(`data-active`),r.setAttribute(`part`,`node node-leaving`),i.setAttribute(`part`,`edge`),a.setAttribute(`part`,`label`),r.tabIndex=-1,i.removeAttribute(`data-shown`),a.removeAttribute(`data-visible`),e.shownAt=null,e.leaveTimer=window.setTimeout(()=>{r.remove(),a.remove(),i.remove(),this.views.delete(e.tree.id)},n+this.duration*.7+40)}renderLabels(){let e=this.opts.labels,t=this.opts.nodeSize/2,n=[...this.views.values()].filter(e=>!e.leaveTimer),r=new Map;for(let e of n){let n=this.placed.get(e.tree.id);r.set(e.tree.id,{x:n.x,y:n.y,r:t})}let i=this.opts.edges===`none`?[]:n.map(e=>this.placed.get(e.tree.id).edge),a=new Map,o=new Set,s=new Set,c=this.labelPad,l=(e,t=i)=>({bounds:this.bounds,circles:[this.hub,...r.values()],taken:[...a].filter(([t])=>t!==e).map(([,e])=>e),edges:t,pad:c}),u=(e,t=i)=>{let n=l(e,t),a=this.active?r.get(this.active):null,o=r.get(e),s=n.circles.map(e=>e===a&&e!==o?{...e,r:e.r+c-6}:e);return{...n,circles:s,pad:6,ownPad:c}},d=(e,t)=>![...a].some(([n,r])=>n!==t&&m(e,r,4)),f=(e,t,n)=>{a.set(e,t),t.w<n.w-1?o.add(e):o.delete(e)},p=(e,t)=>!!e&&!!t&&e.w>=t.w-1&&e.h>=t.h-1;for(let e of n)Y(e.label,`data-go`,this.mode===`tap`&&e.node.dataset.state===`path`&&!!e.tree.page.href),e.tree.id!==this.active&&e.label.removeAttribute(`data-active`),e.label.removeAttribute(`data-compact`),e.label.removeAttribute(`data-narrow`);if(e===`auto`||e===`always`){let t=[...n].sort((e,t)=>Number(t.node.dataset.state===`frontier`)-Number(e.node.dataset.state===`frontier`));for(let n of t){let t=n.tree.id,r=n.node.dataset.state,i=this.placed.get(t).label;(r===`frontier`||r===`dim`&&e===`always`)&&i&&d(i,t)&&f(t,i,this.labelSizes.get(t)??i)}for(let e of n){let t=e.tree.id;if(a.has(t)||t===this.active||e.node.dataset.state!==`frontier`)continue;let n=this.placed.get(t),i=this.sizesOf(t,!1);if(!i)continue;let o=r.get(t),s=u(t),c=k(o,i,n.angle,s)??k(o,i,n.angle,{...s,edges:[n.edge]});c&&f(t,c,this.labelSizes.get(t))}}let h=this.active?this.views.get(this.active):null;if(h&&!h.leaveTimer&&e!==`none`){let e=h.tree.id,t=this.placed.get(e),n=r.get(e),i=h.label,o=h.node.dataset.state===`path`,c=r=>{let i=u(e);return k(n,r,t.angle,i)??k(n,r,t.angle,{...i,edges:[t.edge]})??(o?k(n,r,t.angle,{...i,edges:[]}):null)},l=()=>({w:i.offsetWidth+1,h:i.offsetHeight+1});i.setAttribute(`data-active`,``);let m=l(),g=h.tree.page.description?c(m):null;if(!g){s.add(e),i.setAttribute(`data-compact`,``),m=l();let n=(o?this.narrowBranchSizes.get(e):null)??this.narrowSizes.get(e),r=n?[m,n]:m,f=o?t.pathLabel:t.label,h=a.get(e)??(f&&d(f,e)?f:null);if(g=h&&(p(h,m)||p(h,n))?h:c(r),!g){let t=u(e),n=Math.atan2(this.bounds.y+this.bounds.h/2-this.hub.y,this.bounds.x+this.bounds.w/2-this.hub.x);g=k(this.hub,r,n,t)??k(this.hub,r,n,{...t,edges:[]})}}g?f(e,g,m):a.delete(e)}if(e===`auto`||e===`always`)for(let e of this.path){if(e===this.active||a.has(e))continue;let t=this.views.get(e);if(!t||t.leaveTimer)continue;let n=this.placed.get(e),o={w:t.label.offsetWidth+1,h:t.label.offsetHeight+1},s=this.narrowBranchSizes.get(e)??this.narrowSizes.get(e),c=s?[o,s]:o,l=n.pathLabel&&(p(n.pathLabel,o)||p(n.pathLabel,s))&&d(n.pathLabel,e)?n.pathLabel:null,m=r.get(e),h=[0,12,28,48],g=l??k(m,c,n.angle,{...u(e),rings:h})??k(m,c,n.angle+Math.PI,{...u(e,i.filter(e=>e!==n.edge)),rings:h});g&&f(e,g,o)}for(let e of this.views.values()){let t=e.tree.id,n=e.leaveTimer?null:a.get(t)??null,r=t===this.active&&!!n;if(Y(e.label,`data-active`,r),Y(e.label,`data-narrow`,!!n&&o.has(t)),s.has(t)||e.label.removeAttribute(`data-compact`),X(e.label,`label`,{active:r,path:e.node.dataset.state===`path`}),!n){e.label.removeAttribute(`data-visible`),e.shownAt=null;continue}let i=e.shownAt&&(Math.abs(e.shownAt.x-n.x)>1||Math.abs(e.shownAt.y-n.y)>1);e.label.style.translate=`${n.x.toFixed(1)}px ${n.y.toFixed(1)}px`,e.label.setAttribute(`data-visible`,``),i&&!this.reducedMotion&&e.label.animate([{opacity:0},{opacity:1}],{duration:160,easing:`ease-out`}),e.shownAt=n}}onPointerDown=e=>{if(!e.isPrimary||e.pointerType===`mouse`&&e.button!==0||this.state===`open`)return;e.preventDefault();let{trigger:t}=this.els;try{t.setPointerCapture(e.pointerId)}catch{}this.pointerId=e.pointerId,this.pointerType=e.pointerType,this.downAt=this.lastPoint={x:e.clientX,y:e.clientY},this.leftHub=!1,t.setAttribute(`data-pressing`,``),this.holdTimer=window.setTimeout(()=>this.beginDrag(),this.opts.holdDelay)};beginDrag(){window.clearTimeout(this.holdTimer),this.holdTimer=0,this.els.trigger.removeAttribute(`data-pressing`),this.show(`drag`,`none`)}onPointerMove=e=>{if(e.pointerId!==this.pointerId)return;let t=this.lastPoint={x:e.clientX,y:e.clientY};if(this.state!==`open`){if(this.holdTimer&&Math.hypot(t.x-this.downAt.x,t.y-this.downAt.y)>10)this.beginDrag();else return}this.mode===`drag`&&this.dragTo(t)};onPointerUp=e=>{if(e.pointerId!==this.pointerId)return;this.pointerId=null,this.lastPointerUp=performance.now();let t=this.holdTimer!==0;if(window.clearTimeout(this.holdTimer),this.holdTimer=0,this.els.trigger.removeAttribute(`data-pressing`),this.state!==`open`){t&&this.opts.openOnTap&&this.show(`tap`,`pointer`);return}this.mode===`drag`&&this.release({x:e.clientX,y:e.clientY})};onPointerCancel=e=>{e.pointerId===this.pointerId&&(this.pointerId=null,window.clearTimeout(this.holdTimer),this.holdTimer=0,this.els.trigger.removeAttribute(`data-pressing`),this.state===`open`&&this.mode===`drag`&&this.close())};onLostCapture=e=>{e.pointerId===this.pointerId&&(this.pointerId=null,window.clearTimeout(this.holdTimer),this.holdTimer=0,this.els.trigger.removeAttribute(`data-pressing`),this.state===`open`&&this.mode===`drag`&&this.release(this.lastPoint))};onTriggerClick=e=>{performance.now()-this.lastPointerUp<700||(this.state===`open`?this.close({focusTrigger:!0}):this.show(`tap`,e.detail===0?`keyboard`:`pointer`))};onTriggerKey=e=>{this.state===`closed`&&(e.key===`ArrowUp`||e.key===`ArrowDown`)&&(e.preventDefault(),this.show(`tap`,`keyboard`))};hitAt(e){let t=[],n=[],r=this.opts.nodeSize/2;for(let[e,i]of this.placed){let a=this.views.get(e);a&&!a.leaveTimer&&(t.push(e),n.push({x:i.x,y:i.y,r}))}t.push(`hub`),n.push(this.hub);let i=ce(e,n,this.pointerType===`mouse`?6:14);if(i>=0)return t[i];for(let t of this.views.values())if(!t.leaveTimer&&t.shownAt&&h(t.shownAt,e))return t.tree.id;return null}dragTo(e){let t=this.hitAt(e);t===`hub`?(this.setActive(null),this.dwell(this.leftHub&&this.path.length?`hub`:null)):t?(this.leftHub=!0,this.setActive(t),this.dwell(t)):(Math.hypot(e.x-this.hub.x,e.y-this.hub.y)>this.hub.r+6&&(this.leftHub=!0),this.setActive(null),this.dwellTarget&&this.dwellTarget!==`hub`&&this.isBeyond(e,this.dwellTarget)||this.dwell(null)),Y(this.els.hub,`data-active`,this.dwellTarget===`hub`)}isBeyond(e,t){let n=this.placed.get(t);if(!n||!this.tree.byId.get(t)?.children.length)return!1;let r=n.x-n.from.x,i=n.y-n.from.y,a=Math.hypot(r,i)||1,o=r/a,s=i/a,c=e.x-n.from.x,l=e.y-n.from.y,u=c*o+l*s,d=Math.abs(c*s-l*o);return u>a&&u<a+this.opts.spacing*1.2&&d<this.opts.spacing*.55}dwell(e){e!==this.dwellTarget&&(window.clearTimeout(this.dwellTimer),this.dwellTimer=0,this.dwellTarget=e,e&&(this.dwellTimer=window.setTimeout(()=>{if(this.dwellTimer=0,e===`hub`)return this.setPath([]);let t=this.tree.byId.get(e);t&&!t.page.disabled&&this.setPath(V(t.children.length?t:t.parent))},this.opts.expandDelay)))}release(e){window.clearTimeout(this.dwellTimer),this.dwellTimer=0,this.dwellTarget=null;let t=this.hitAt(e);if(t&&t!==`hub`){let e=this.tree.byId.get(t);if(!e.page.disabled){if(e.page.href||!e.children.length)return this.select(e,`release`);this.path=V(e)}return this.toTapMode(t)}if(!this.leftHub)return this.toTapMode(null);this.close()}toTapMode(e){this.mode=`tap`,this.els.overlay.dataset.mode=`tap`,window.removeEventListener(`keydown`,this.onWindowKey,!0),this.present(!0),this.render();let t=e??this.initialFocusId();t&&this.focusNode(t,!1)}onOverlayHover=e=>{if(this.state!==`open`||this.mode!==`tap`||e.pointerType!==`mouse`)return;let t=this.hitAt({x:e.clientX,y:e.clientY});this.setActive(t===`hub`?null:t)};onOverlayClick=e=>{if(this.state!==`open`||this.mode!==`tap`)return;let t=performance.now();if(t-this.openedAt<250||e.detail===0&&t-this.lastKeyActivation<500)return;let n=e.target;if(n.closest(`.hub`))return this.hubAction(e.detail===0);let r=n.closest(`.node`)?.dataset.id??null;if(!r&&e.detail!==0){let t=this.hitAt({x:e.clientX,y:e.clientY});r=t===`hub`?null:t}let i=r?this.tree.byId.get(r):null;if(!i)return this.close();let a=e.detail===0?`keyboard`:`click`;this.focusNode(i.id,a===`keyboard`),this.activate(i,a,e.metaKey||e.ctrlKey||e.button===1)};hubAction(e){this.path.length?this.goUp(e):this.close({focusTrigger:!0})}onOverlayKey=e=>{if(this.state!==`open`)return;let t=e.key;if(t===`Escape`){e.preventDefault(),this.close({focusTrigger:!0});return}if(this.mode!==`tap`)return;let n=e.composedPath()[0],r=n instanceof Element?n.closest(`.node`):null;if(!r){if(n===this.els.hub)return;if(t in J||t===`Home`||t===`End`){e.preventDefault();let t=this.focusId&&this.placed.has(this.focusId)?this.focusId:this.initialFocusId();t&&this.focusNode(t)}return}let i=this.tree.byId.get(r.dataset.id);if(i){if(this.focusId!==i.id&&(this.focusId=i.id),t===`Enter`||t===` `)return e.preventDefault(),this.lastKeyActivation=performance.now(),this.activateKey(i,e.metaKey||e.ctrlKey);if(t===`Backspace`)return e.preventDefault(),this.stepBack(i);if(this.opts.arrowKeys===`spatial`?this.spatialKey(i,t):this.treeKey(i,t)){e.preventDefault();return}t.length===1&&!e.metaKey&&!e.ctrlKey&&!e.altKey&&t!==` `&&this.typeAhead(i,t)}};visibleOrder(){let e=[],t=n=>{for(let r of n)e.push(r.id),this.path.includes(r.id)&&t(r.children)};return t(this.tree.root.children),e}treeKey(e,t){let n=getComputedStyle(this).direction===`rtl`,r=this.visibleOrder(),i=r.indexOf(e.id),a=this.path.includes(e.id);if(t===`ArrowDown`)i<r.length-1&&this.focusNode(r[i+1]);else if(t===`ArrowUp`)i>0&&this.focusNode(r[i-1]);else if(t===(n?`ArrowLeft`:`ArrowRight`))e.children.length&&!e.page.disabled&&(a?this.focusNode(e.children[0].id):(this.path=V(e),this.haptic(6),this.focusNode(e.id)));else if(t===(n?`ArrowRight`:`ArrowLeft`))a?(this.path=V(e.parent),this.focusNode(e.id)):e.parent&&e.parent.depth>0&&this.focusNode(e.parent.id);else if(t===`Home`)this.focusNode(r[0]);else if(t===`End`)this.focusNode(r[r.length-1]);else return!1;return!0}spatialKey(e,t){if(t in J){let n=this.placed.get(e.id);if(!n)return!0;let r=J[t],i=null,a=1/0;for(let[t,o]of this.placed){if(t===e.id||this.views.get(t)?.leaveTimer)continue;let s=o.x-n.x,c=o.y-n.y,l=s*r.x+c*r.y;if(l<=1)continue;let u=Math.abs(s*r.y-c*r.x);if(u>l*2.2)continue;let d=l+u*2;d<a&&(a=d,i=t)}return i&&this.focusNode(i),!0}if(t===`Home`||t===`End`){let n=e.parent?.children??[],r=t===`Home`?n[0]:n[n.length-1];return r&&this.focusNode(r.id),!0}return!1}activateKey(e,t){if(!e.page.disabled){if(this.opts.arrowKeys===`spatial`)return this.activate(e,`keyboard`,t);if(e.page.href||!e.children.length)return this.select(e,`keyboard`,t);this.path=this.path.includes(e.id)?V(e.parent):V(e),this.haptic(6),this.focusNode(e.id)}}stepBack(e){e.parent&&e.parent.depth>0?(this.path=V(e.parent.parent),this.focusNode(e.parent.id)):this.path.length&&(this.path=[],this.focusNode(e.id))}typeAhead(e,t){let n=performance.now();this.typeahead.text=n-this.typeahead.at<700?this.typeahead.text+t.toLowerCase():t.toLowerCase(),this.typeahead.at=n;let r=this.opts.arrowKeys===`spatial`?(e.parent?.children??[]).map(e=>e.id):this.visibleOrder(),i=this.typeahead.text,a=r.indexOf(e.id),o=i.length===1?a+1:a;for(let e=0;e<r.length;e++){let t=r[(o+e)%r.length];if(this.tree.byId.get(t).page.label.toLowerCase().startsWith(i))return this.focusNode(t)}}goUp(e){let t=this.path[this.path.length-1];this.path=this.path.slice(0,-1),t?this.focusNode(t,e):this.render()}focusNode(e,t=!0){this.focusId=e,t&&(this.active=e),this.render(),this.views.get(e)?.node.focus({preventScroll:!0}),t&&this.emitHighlight()}activate(e,t,n=!1){if(e.page.disabled)return;if(n&&e.page.href)return this.select(e,t,!0);let r=this.path.includes(e.id);if(e.children.length&&!r){this.path=V(e),this.haptic(6),t===`keyboard`?this.focusNode(e.children[0].id):(this.active=e.id,this.render());return}if(e.children.length&&!e.page.href){this.path=V(e.parent),t===`keyboard`?this.focusNode(e.id):this.render();return}this.select(e,t,n)}select(e,t,n=!1){let r={page:e.page,trail:V(e).map(e=>this.tree.byId.get(e).page),via:t},i=this.emit(`unfold-select`,r,!0);if(this.haptic(12),this.close({focusTrigger:t===`keyboard`}),!i)return;let{href:a,target:o}=e.page;if(this.opts.navigate&&!(a&&(n||o&&o!==`_self`))){this.opts.navigate(e.page,r);return}if(!a)return;let s=he(a,document.baseURI);if(!s){console.warn(`[unfold-nav] Refusing an unsupported navigation URL:`,a);return}n||o&&o!==`_self`?window.open(s,n?`_blank`:o,`noopener`):location.assign(s)}setActive(e){e!==this.active&&(this.active=e,e&&this.mode===`drag`&&this.haptic(4),this.render(),this.emitHighlight())}setPath(e){e.length===this.path.length&&e.every((e,t)=>e===this.path[t])||(this.path=e,this.haptic(6),this.render())}emit(e,t,n=!1){return this.dispatchEvent(new CustomEvent(e,{detail:t,bubbles:!0,composed:!0,cancelable:n}))}emitHighlight(){let e=this.active?this.tree.byId.get(this.active)?.page??null:null;this.emit(`unfold-highlight`,{page:e})}haptic(e){if(this.opts.haptics)try{navigator.vibrate?.(e)}catch{}}get reducedMotion(){return matchMedia(`(prefers-reduced-motion: reduce)`).matches}get duration(){let e=getComputedStyle(this.els.root).getPropertyValue(`--_dur`).trim(),t=parseFloat(e);return Number.isFinite(t)?e.endsWith(`ms`)?t:e.endsWith(`s`)?t*1e3:t:340}};if(typeof HTMLElement<`u`)for(let e of G)Object.defineProperty(Z.prototype,e,{configurable:!0,enumerable:!0,get(){return this.opts[e]},set(t){this.configure({[e]:t})}});var Q=`unfold-nav`;function $(e=Q){typeof customElements>`u`||customElements.get(e)||customElements.define(e,e===`unfold-nav`?Z:class extends Z{})}$();function be(e,t){if(typeof document>`u`)throw Error(`[unfold-nav] Call createUnfoldNav in a browser after mounting.`);let n=t??document.body;if(!n)throw Error(`[unfold-nav] Wait for document.body or provide a container.`);$();let r=document.createElement(Q);return r.configure(e),n.append(r),r}e.DEFAULT_OPTIONS=R,e.DEFAULT_STRINGS=L,e.TAG=Q,e.UnfoldNav=Z,e.buildTree=B,e.createUnfoldNav=be,e.define=$,e.findCurrent=U,e.layoutGraph=F,e.placeFan=P,e.placeLabel=k});
|
|
446
|
+
//# sourceMappingURL=unfold-nav.umd.cjs.map
|