@ds-mo/ui 0.8.0 → 0.8.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.
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{p as a,H as e,c as n,h as t,a as i,t as o}from"./index.js";import{d as s}from"./p-Bi2mMcOi.js";import{d as r}from"./p-CIMd6yG3.js";const l=()=>`.panel-nav.sc-ds-panel-nav{--_nav-width:200px;--_nav-width-collapsed:48px;--_nav-item-height:var(--dimension-size-400, 32px);--_nav-padding-x:var(--dimension-space-100, 8px);--_nav-padding-y:var(--dimension-space-100, 8px);--_nav-footer-btn-w:calc(var(--dimension-space-075, 6px) * 2 + var(--dimension-iconography-md, 20px));--_nav-speed:var(--ds-panel-nav-speed, 1);--_nav-expand-dur:calc(var(--_nav-speed) * var(--effect-animation-duration-medium-1, 300ms));--_nav-expand-motion:var(--_nav-expand-dur) var(--effect-animation-easing-ease-in-out, ease);--_nav-label-fade-dur:calc(var(--_nav-speed) * var(--effect-animation-duration-medium-1, 300ms));--_nav-label-fade-motion:var(--_nav-label-fade-dur) var(--effect-animation-easing-ease-in-out, ease);--_nav-label-fade-out-dur:calc(var(--_nav-speed) * var(--effect-animation-duration-medium-1, 300ms));--_nav-label-fade-out-motion:var(--_nav-label-fade-out-dur) var(--effect-animation-easing-ease-in-out, ease);--_nav-bg:var(--color-navigation-background);--_nav-border:var(--color-navigation-border-tertiary);--_nav-divider:var(--color-navigation-divider);--_nav-fg-primary:var(--color-navigation-foreground-primary);--_nav-fg-secondary:var(--color-navigation-foreground-secondary);--_nav-fg-tertiary:var(--color-navigation-foreground-tertiary);--_nav-hover:var(--color-navigation-interaction-hover);--_nav-pressed:var(--color-navigation-interaction-pressed);--_nav-focus:var(--color-navigation-interaction-focus);--_nav-dot:var(--color-navigation-foreground-brand)}.panel-nav--settings.sc-ds-panel-nav{--_nav-bg:var(--color-background-secondary);--_nav-border:var(--color-border-tertiary);--_nav-divider:var(--color-border-tertiary);--_nav-fg-primary:var(--color-foreground-primary);--_nav-fg-secondary:var(--color-foreground-secondary);--_nav-fg-tertiary:var(--color-foreground-tertiary);--_nav-hover:var(--color-interaction-hover);--_nav-pressed:var(--color-interaction-pressed);--_nav-focus:var(--color-interaction-focus);--_nav-dot:var(--color-foreground-bold-brand)}.panel-nav.sc-ds-panel-nav{display:flex;flex-direction:column;width:var(--_nav-width);min-width:var(--_nav-width);height:100%;background:var(--_nav-bg);border-right:var(--dimension-stroke-width-012, 1px) solid var(--_nav-border);box-sizing:border-box;overflow:hidden;transition:width var(--_nav-expand-motion), min-width var(--_nav-expand-motion), background var(--effect-motion-short-3, 200ms ease), border-color var(--effect-motion-short-3, 200ms ease);font-family:var(--typography-font-family, system-ui)}.panel-nav--collapsed.sc-ds-panel-nav{width:var(--_nav-width-collapsed);min-width:var(--_nav-width-collapsed)}.panel-nav__header.sc-ds-panel-nav{display:flex;align-items:center;padding:var(--dimension-space-100, 8px);flex-shrink:0;box-sizing:border-box;border-bottom:var(--dimension-stroke-width-012, 1px) solid var(--_nav-divider);transition:border-color var(--effect-motion-short-3, 200ms ease)}.panel-nav__header-btn.sc-ds-panel-nav{all:unset;display:flex;align-items:center;justify-content:center;padding:var(--dimension-space-075, 6px);border-radius:var(--dimension-radius-025, 2px);cursor:pointer;color:var(--_nav-fg-primary);position:relative;flex-shrink:0;box-sizing:border-box;transition:color var(--effect-motion-short-3, 200ms ease)}.panel-nav__header-btn.sc-ds-panel-nav::after{content:'';position:absolute;inset:0;border-radius:var(--dimension-radius-025, 2px);background:transparent;transition:background var(--effect-animation-duration-short-3, 200ms) var(--effect-animation-easing-ease-out, ease);pointer-events:none}.panel-nav__header-btn.sc-ds-panel-nav:hover::after{background:var(--_nav-hover);transition:none}.panel-nav__header-btn.sc-ds-panel-nav:active::after{background:var(--_nav-pressed);transition:none}.panel-nav__header-btn.sc-ds-panel-nav:focus-visible{outline:none}.panel-nav__header-btn.sc-ds-panel-nav:focus-visible::after{outline:var(--dimension-stroke-width-025, 2px) solid var(--_nav-focus);outline-offset:calc(-1 * var(--dimension-stroke-width-025, 2px))}.panel-nav__header-logo.sc-ds-panel-nav{display:flex;align-items:center;justify-content:center;position:relative;z-index:1;transition:opacity var(--effect-motion-short-2, 100ms ease)}.panel-nav__m-mark.sc-ds-panel-nav{width:var(--dimension-iconography-md, 20px);height:var(--dimension-iconography-md, 20px);display:block}.panel-nav__header-toggle.sc-ds-panel-nav{display:none;align-items:center;justify-content:center;position:absolute;inset:0;z-index:1}.panel-nav__header-btn.sc-ds-panel-nav:hover .panel-nav__header-logo.sc-ds-panel-nav{opacity:0}.panel-nav__header-btn.sc-ds-panel-nav:hover .panel-nav__header-toggle.sc-ds-panel-nav{display:flex}.panel-nav__body.sc-ds-panel-nav{flex:1;overflow-y:auto;overflow-x:hidden;display:flex;flex-direction:column;gap:var(--dimension-space-200, 16px);padding:var(--dimension-space-100, 8px);box-sizing:border-box;scrollbar-width:none}.panel-nav__body.sc-ds-panel-nav::-webkit-scrollbar{display:none}.panel-nav__group.sc-ds-panel-nav{display:flex;flex-direction:column;gap:var(--dimension-space-050, 4px)}.panel-nav__group-label.sc-ds-panel-nav{text-transform:uppercase;color:var(--_nav-fg-tertiary);padding:0 var(--dimension-space-050, 4px);margin-bottom:var(--dimension-space-025, 2px);white-space:nowrap;overflow:hidden;max-height:2em;opacity:1;transition:opacity var(--_nav-label-fade-motion) 0ms, max-height var(--_nav-label-fade-motion) 0ms, margin-bottom var(--_nav-label-fade-motion) 0ms, color var(--effect-motion-short-3, 200ms ease)}.panel-nav__item.sc-ds-panel-nav{all:unset;display:flex;align-items:center;gap:var(--dimension-space-050, 4px);padding:0 var(--dimension-space-075, 6px);height:var(--dimension-size-400, 32px);border-radius:var(--dimension-radius-025, 2px);cursor:pointer;color:var(--_nav-fg-secondary);position:relative;box-sizing:border-box;width:100%;user-select:none;transition:color var(--effect-motion-short-1, 50ms ease-in-out)}.panel-nav__item.sc-ds-panel-nav::after{content:'';position:absolute;inset:0;border-radius:var(--dimension-radius-025, 2px);background:transparent;pointer-events:none;transition:background var(--effect-animation-duration-short-3, 200ms) var(--effect-animation-easing-ease-out, ease)}.panel-nav__item.sc-ds-panel-nav:hover::after{background:var(--_nav-hover);transition:none}.panel-nav__item.sc-ds-panel-nav:active::after{background:var(--_nav-pressed);transition:none}.panel-nav__item.sc-ds-panel-nav:focus-visible{outline:none}.panel-nav__item.sc-ds-panel-nav:focus-visible::after{outline:var(--dimension-stroke-width-025, 2px) solid var(--_nav-focus);outline-offset:calc(-1 * var(--dimension-stroke-width-025, 2px))}.panel-nav__item--active.sc-ds-panel-nav{color:var(--_nav-fg-primary)}.panel-nav__item-icon.sc-ds-panel-nav{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:var(--dimension-iconography-md, 20px);height:var(--dimension-iconography-md, 20px);position:relative}.panel-nav__item-label.sc-ds-panel-nav{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;height:var(--typography-lineheight-md, 20px);line-height:var(--typography-lineheight-md, 20px);opacity:1;mask-image:linear-gradient(to right, black 50%, transparent 100%);-webkit-mask-image:linear-gradient(to right, black 50%, transparent 100%);mask-size:200% 100%;-webkit-mask-size:200% 100%;mask-position:0% 0;-webkit-mask-position:0% 0;transition:opacity var(--_nav-label-fade-motion) 0ms, mask-position var(--_nav-label-fade-motion) 0ms, -webkit-mask-position var(--_nav-label-fade-motion) 0ms}.panel-nav__item-label-text.sc-ds-panel-nav{padding:0 var(--dimension-space-025, 2px)}.panel-nav__item-dot.sc-ds-panel-nav{position:absolute;right:13px;top:13px;width:var(--dimension-space-075, 6px);height:var(--dimension-space-075, 6px);border-radius:var(--dimension-radius-full, 999px);background:var(--_nav-dot);box-shadow:0 0 0 var(--dimension-stroke-width-018, 1.5px) var(--_nav-bg);pointer-events:none;transition:right var(--_nav-expand-motion), top var(--_nav-expand-motion), background var(--effect-motion-short-3, 200ms ease), box-shadow var(--effect-motion-short-3, 200ms ease)}.panel-nav--collapsed.sc-ds-panel-nav .panel-nav__item-dot.sc-ds-panel-nav{right:6px;top:6px}.panel-nav--animating.sc-ds-panel-nav .panel-nav__item-label.sc-ds-panel-nav{text-overflow:clip}.panel-nav--collapsed.sc-ds-panel-nav .panel-nav__item-label.sc-ds-panel-nav{opacity:0;pointer-events:none;text-overflow:clip;mask-position:100% 0;-webkit-mask-position:100% 0;transition:opacity var(--_nav-label-fade-out-motion) 0ms, mask-position var(--_nav-label-fade-out-motion) 0ms, -webkit-mask-position var(--_nav-label-fade-out-motion) 0ms}.panel-nav--collapsed.sc-ds-panel-nav .panel-nav__group-label.sc-ds-panel-nav{opacity:0;max-height:0;margin-bottom:0;pointer-events:none;transition:opacity var(--_nav-label-fade-out-motion) 0ms, max-height var(--_nav-label-fade-out-motion) 0ms, margin-bottom var(--_nav-label-fade-out-motion) 0ms, color var(--effect-motion-short-3, 200ms ease)}.panel-nav__footer.sc-ds-panel-nav{position:relative;flex-shrink:0;height:calc(var(--_nav-padding-y) * 2 + var(--_nav-item-height));transition:height var(--_nav-expand-motion)}.panel-nav--collapsed.sc-ds-panel-nav .panel-nav__footer.sc-ds-panel-nav{height:calc(var(--_nav-padding-y) * 2 + var(--_nav-item-height) * 2 + var(--dimension-space-050, 4px))}.panel-nav__footer.sc-ds-panel-nav::before{content:'';position:absolute;bottom:100%;left:0;right:0;height:calc(var(--dimension-base, 8px) * 6);background:linear-gradient(to bottom, transparent, var(--_nav-bg));pointer-events:none;opacity:1;transition:opacity var(--effect-animation-duration-short-3, 200ms) var(--effect-animation-easing-ease-out, ease)}.panel-nav--at-bottom.sc-ds-panel-nav .panel-nav__footer.sc-ds-panel-nav::before{opacity:0}.panel-nav__footer-btn.sc-ds-panel-nav{all:unset;display:flex;align-items:center;justify-content:center;position:absolute;left:var(--_nav-padding-x);top:var(--_nav-padding-y);padding:var(--dimension-space-075, 6px);border-radius:var(--dimension-radius-half, 9999px);cursor:pointer;color:var(--_nav-fg-secondary);box-sizing:border-box;background:transparent;transition:background var(--effect-animation-duration-short-3, 200ms) var(--effect-animation-easing-ease-out, ease), color var(--effect-animation-duration-short-3, 200ms) var(--effect-animation-easing-ease-out, ease)}.panel-nav__footer-btn.sc-ds-panel-nav:focus-visible{outline:var(--dimension-stroke-width-025, 2px) solid var(--_nav-focus);outline-offset:calc(-1 * var(--dimension-stroke-width-025, 2px))}.panel-nav--dashboard.sc-ds-panel-nav .panel-nav__footer-btn.sc-ds-panel-nav:hover{background:var(--color-background-secondary);color:var(--color-foreground-secondary);transition:none}.panel-nav--settings.sc-ds-panel-nav .panel-nav__footer-btn.sc-ds-panel-nav:hover{background:var(--color-navigation-background);color:var(--color-navigation-foreground-secondary);transition:none}.panel-nav__footer-user.sc-ds-panel-nav{position:absolute;left:calc(var(--_nav-padding-x) + var(--_nav-footer-btn-w) + var(--dimension-space-050, 4px));right:var(--_nav-padding-x);top:var(--_nav-padding-y);width:auto;min-width:0;transition:left var(--_nav-expand-motion), right var(--_nav-expand-motion), top var(--_nav-expand-motion), color var(--effect-motion-short-3, 200ms ease)}.panel-nav--collapsed.sc-ds-panel-nav .panel-nav__footer-user.sc-ds-panel-nav{left:var(--_nav-padding-x);right:var(--_nav-padding-x);top:calc(var(--_nav-padding-y) + var(--_nav-item-height) + var(--dimension-space-050, 4px))}.panel-nav__footer-user-label.sc-ds-panel-nav{text-align:right;position:absolute;left:var(--dimension-space-075, 6px);right:calc(var(--dimension-space-075, 6px) + var(--dimension-iconography-md, 20px) + var(--dimension-space-050, 4px));top:50%;transform:translateY(-50%);flex:none;height:var(--typography-lineheight-md, 20px);mask-image:none;-webkit-mask-image:none;transition:opacity var(--_nav-label-fade-motion)}.panel-nav--collapsed.sc-ds-panel-nav .panel-nav__footer-user-label.sc-ds-panel-nav{opacity:0;pointer-events:none;mask-position:0% 0;-webkit-mask-position:0% 0}.panel-nav__footer-user-icon.sc-ds-panel-nav{position:absolute;left:calc(100% - var(--dimension-iconography-md, 20px) - var(--dimension-space-075, 6px));top:0;bottom:0;height:auto;display:flex;align-items:center;justify-content:center;transition:left var(--_nav-expand-motion)}.panel-nav--collapsed.sc-ds-panel-nav .panel-nav__footer-user-icon.sc-ds-panel-nav{left:var(--dimension-space-075, 6px)}.panel-nav__footer-icon-expanded.sc-ds-panel-nav,.panel-nav__footer-icon-collapsed.sc-ds-panel-nav{position:absolute;inset:0;display:flex;align-items:center;justify-content:center}.panel-nav__footer-icon-expanded.sc-ds-panel-nav{opacity:1;transition:opacity var(--_nav-label-fade-motion)}.panel-nav__footer-icon-collapsed.sc-ds-panel-nav{opacity:0;transition:opacity var(--_nav-label-fade-motion)}.panel-nav--collapsed.sc-ds-panel-nav .panel-nav__footer-icon-expanded.sc-ds-panel-nav{opacity:0;transition:opacity var(--_nav-label-fade-out-motion)}.panel-nav--collapsed.sc-ds-panel-nav .panel-nav__footer-icon-collapsed.sc-ds-panel-nav{opacity:1;transition:opacity var(--_nav-label-fade-out-motion)}.panel-nav__user-initial.sc-ds-panel-nav{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:var(--_nav-fg-secondary);text-transform:uppercase;line-height:1;pointer-events:none;transition:color var(--effect-motion-short-3, 200ms ease)}.panel-nav__resize-handle.sc-ds-panel-nav{position:absolute;top:0;right:var(--dimension-space-n050, -4px);bottom:0;width:var(--dimension-space-100, 8px);z-index:10;cursor:ew-resize;touch-action:none;background:transparent}.panel-nav__resize-handle.sc-ds-panel-nav::before{content:'';position:absolute;inset:0;background:rgba(0, 0, 0, 0.001)}.panel-nav__resize-handle.sc-ds-panel-nav::after{content:'';position:absolute;top:0;bottom:0;left:50%;transform:translateX(-50%);width:var(--dimension-stroke-width-025, 2px);background:var(--color-background-bold-brand);opacity:0;pointer-events:none;transition:opacity var(--effect-motion-short-2, 100ms ease-in-out)}.panel-nav__resize-handle--overlay.sc-ds-panel-nav::after{opacity:1}@media (prefers-reduced-motion: reduce){.panel-nav.sc-ds-panel-nav,.panel-nav.sc-ds-panel-nav *.sc-ds-panel-nav,.panel-nav.sc-ds-panel-nav *.sc-ds-panel-nav::before,.panel-nav.sc-ds-panel-nav *.sc-ds-panel-nav::after,.panel-nav__resize-handle.sc-ds-panel-nav,.panel-nav__resize-handle.sc-ds-panel-nav::before,.panel-nav__resize-handle.sc-ds-panel-nav::after{transition-duration:0.01ms !important;animation-duration:0.01ms !important;transition-delay:0.01ms !important}}`;const d=a(class a extends e{constructor(a){super();if(a!==false){this.__registerHost()}this.dsNavSelect=n(this,"dsNavSelect");this.dsNavToggle=n(this,"dsNavToggle");this.dsNavFooterAction=n(this,"dsNavFooterAction");this.variant="dashboard";this.groups="[]";this.activeId="";this.collapsed=false;this.breakpoint=0;this.storageKey="";this.currentUrl="";this.userName="";this.userInitial="";this.parsedGroups=[];this.atBottom=false;this.isAnimating=false;this.rovingIndex=0;this.viewportNarrow=false;this.urlDerivedActiveId="";this.isDragging=false;this.dragStartX=0;this.didSnap=false;this.lastDeltaX=0;this.edgeOverlayTimer=null;this.showEdgeOverlay=false}get effectiveActiveId(){return this.urlDerivedActiveId||this.activeId}onCollapsedChange(){this.startCollapseAnimation()}onBreakpointChange(){this.disconnectResizeObserver();if(this.breakpoint>0)this.connectResizeObserver()}onGroupsChange(a){try{this.parsedGroups=JSON.parse(a)}catch{this.parsedGroups=[]}this.syncRovingIndex()}onActiveIdChange(){this.syncRovingIndex()}onCurrentUrlChange(){this.syncActiveFromUrl()}componentWillLoad(){if(this.storageKey){try{const a=localStorage.getItem(this.storageKey);if(a!==null)this.collapsed=a==="true"}catch{}}this.onGroupsChange(this.groups);this.syncActiveFromUrl()}componentDidLoad(){this.checkScroll();if(this.breakpoint>0)this.connectResizeObserver()}disconnectedCallback(){this.disconnectResizeObserver();this.clearEdgeOverlayTimer();if(this.globalMouseMoveHandler){window.removeEventListener("mousemove",this.globalMouseMoveHandler)}if(this.globalMouseUpHandler){window.removeEventListener("mouseup",this.globalMouseUpHandler)}}startCollapseAnimation(){this.isAnimating=true;const a=this.el.querySelector(".panel-nav");if(this.transitionEndHandler){a?.removeEventListener("transitionend",this.transitionEndHandler)}this.transitionEndHandler=e=>{if(e.propertyName==="width"){this.isAnimating=false;a?.removeEventListener("transitionend",this.transitionEndHandler)}};a?.addEventListener("transitionend",this.transitionEndHandler)}connectResizeObserver(){this.viewportNarrow=window.innerWidth<this.breakpoint;this.resizeObserver=new ResizeObserver((()=>{this.viewportNarrow=window.innerWidth<this.breakpoint}));this.resizeObserver.observe(document.documentElement)}disconnectResizeObserver(){this.resizeObserver?.disconnect();this.resizeObserver=undefined}syncActiveFromUrl(){if(!this.currentUrl){this.urlDerivedActiveId="";return}let a;let e=0;for(const n of this.getAllItems()){if(n.href&&this.currentUrl.startsWith(n.href)&&n.href.length>e){a=n;e=n.href.length}}this.urlDerivedActiveId=a?.id??""}applyToggle(a){this.dsNavToggle.emit(a);if(this.storageKey){this.collapsed=a;try{localStorage.setItem(this.storageKey,String(a))}catch{}}}getAllItems(){return this.parsedGroups.flatMap((a=>a.items))}syncRovingIndex(){const a=this.getAllItems().findIndex((a=>a.id===this.effectiveActiveId));this.rovingIndex=a>=0?a:0}handleItemKeyDown(a,e){const n=this.getAllItems().length;let t=e;switch(a.key){case"ArrowDown":a.preventDefault();t=(e+1)%n;break;case"ArrowUp":a.preventDefault();t=(e-1+n)%n;break;case"Home":a.preventDefault();t=0;break;case"End":a.preventDefault();t=n-1;break;default:return}this.rovingIndex=t;const i=Array.from(this.el.querySelectorAll(".panel-nav__body .panel-nav__item"));i[t]?.focus()}checkScroll(){const a=this.el.querySelector(".panel-nav__body");if(!a)return;const e=a.scrollHeight-a.scrollTop-a.clientHeight;this.atBottom=e<2}handleBodyScroll(a){const e=a.target;const n=e.scrollHeight-e.scrollTop-e.clientHeight;this.atBottom=n<2}handleItemClick(a){this.dsNavSelect.emit(a)}handleToggle(){this.applyToggle(!this.collapsed)}handleFooterAction(){this.dsNavFooterAction.emit()}clearEdgeOverlayTimer(){if(this.edgeOverlayTimer!==null){window.clearTimeout(this.edgeOverlayTimer);this.edgeOverlayTimer=null}}handleResizeHandleMouseEnter(){this.clearEdgeOverlayTimer();this.edgeOverlayTimer=window.setTimeout((()=>{this.showEdgeOverlay=true;this.edgeOverlayTimer=null}),500)}handleResizeHandleMouseLeave(){if(this.isDragging)return;this.clearEdgeOverlayTimer();this.showEdgeOverlay=false}handleResizeHandleMouseDown(a){a.preventDefault();a.stopPropagation();const e=this.collapsed||this.viewportNarrow;this.isDragging=true;this.dragStartX=a.clientX;this.didSnap=false;this.lastDeltaX=0;this.clearEdgeOverlayTimer();this.showEdgeOverlay=false;document.body.style.cursor="ew-resize";document.body.style.userSelect="none";const n=a=>{const n=a.clientX-this.dragStartX;this.lastDeltaX=Math.abs(n);if(this.didSnap)return;if(!e&&n<-8){this.applyToggle(true);this.didSnap=true}else if(e&&n>8){this.applyToggle(false);this.didSnap=true}};const t=()=>{if(!this.didSnap&&this.lastDeltaX<3){this.applyToggle(!e)}this.isDragging=false;this.showEdgeOverlay=false;document.body.style.cursor="";document.body.style.userSelect="";window.removeEventListener("mousemove",n);window.removeEventListener("mouseup",t);this.globalMouseMoveHandler=undefined;this.globalMouseUpHandler=undefined};this.globalMouseMoveHandler=n;this.globalMouseUpHandler=t;window.addEventListener("mousemove",n);window.addEventListener("mouseup",t)}renderNavItem(a,e,n){const i=a.id===this.effectiveActiveId;const o=[t("span",{class:"panel-nav__item-icon"},t("ds-icon",{name:a.icon,size:"md",color:"inherit",flag:a.flag})),t("span",{class:"panel-nav__item-label"},t("span",{class:"panel-nav__item-label-text"},t("ds-text",{as:"span",variant:i?"text-body-medium-emphasis":"text-body-medium",color:"inherit"},a.label))),a.dot&&t("span",{class:"panel-nav__item-dot","aria-hidden":"true"})];const s={class:{"panel-nav__item":true,"panel-nav__item--active":i},"aria-current":i?"page":undefined,title:n?a.label:undefined,tabIndex:e===this.rovingIndex?0:-1,onClick:()=>this.handleItemClick(a.id),onKeyDown:a=>this.handleItemKeyDown(a,e),onFocus:()=>{this.rovingIndex=e}};return a.href?t("a",{...s,href:a.href},o):t("button",{...s,type:"button"},o)}render(){const a=this.variant==="dashboard";const e=this.collapsed||this.viewportNarrow;const{userName:n,userInitial:o}=this;const s={"panel-nav":true,"panel-nav--dashboard":a,"panel-nav--settings":!a,"panel-nav--collapsed":e,"panel-nav--animating":this.isAnimating,"panel-nav--at-bottom":this.atBottom};return t(i,{key:"44e0bb244829d3df63e246373469c57d2de40d64",style:{display:"block",position:"relative"}},t("nav",{key:"46856fc3c5e2cb5341c916e45d1a7b871d6225a8",class:s,"aria-label":a?"Main navigation":"Settings navigation"},t("div",{key:"59d83b742058b1ff70155eee8c4f33953cb65e1f",class:"panel-nav__header"},t("button",{key:"24a0e3bad0986e6c074833163ac573d4855f4d43",type:"button",class:"panel-nav__header-btn",onClick:()=>this.handleToggle(),"aria-label":e?"Expand navigation":"Collapse navigation","aria-expanded":e?"false":"true"},t("span",{key:"9561f03443419ac7c8783af99ea763d9b397c905",class:"panel-nav__header-logo","aria-hidden":"true"},t("svg",{key:"6c26fc494042ee13f171493badaa0ad03260e9d6",class:"panel-nav__m-mark",viewBox:"0 0 20 20",fill:"none",xmlns:"http://www.w3.org/2000/svg"},t("path",{key:"29cbf2b9039b58de07333f90b8189a7125498c97",d:"M11.1159 4.31537H7.67021L2.53401 13.0703H0V15.6875H4.02716L8.24319 8.49978V15.6846H11.6342L15.8289 8.47829V15.6846H18.7122V4.3125H15.2559L11.1159 11.3648V4.31537Z",fill:"currentColor"}))),t("span",{key:"dc35fd85851b16c90439b8e015a25dc013421975",class:"panel-nav__header-toggle","aria-hidden":"true"},t("ds-icon",{key:"ad1a470183e94844245c0d93ba6a9451830f445f",name:e?"LeftExpandB":"LeftCollapseB",size:"md",color:"inherit"})))),t("div",{key:"66bbb51740b20e60d975413752da2fbe65f16063",class:"panel-nav__body",onScroll:a=>this.handleBodyScroll(a)},(()=>{let a=0;return this.parsedGroups.map((n=>t("div",{class:"panel-nav__group"},n.label&&t("span",{class:"panel-nav__group-label"},t("ds-text",{as:"span",variant:"text-caption-emphasis",color:"inherit"},n.label)),n.items.map((n=>this.renderNavItem(n,a++,e))))))})()),t("div",{key:"daae3e83ad3b945d5480d2c0b09f3f74b38a9604",class:"panel-nav__footer"},t("button",{key:"e2876afecfab631d00e466e66ed3748d51a67249",type:"button",class:"panel-nav__footer-btn",title:a?"Settings":"Dashboard","aria-label":a?"Open settings":"Go to dashboard",onClick:()=>this.handleFooterAction()},t("ds-icon",{key:"8938dccb48417cfedae256bdc2afc2ac43ff5e58",name:a?"Gear":"Dashboard",size:"md",color:"inherit"})),t("button",{key:"38de37144be2e84234f9c460dab556d4274118b2",type:"button",class:"panel-nav__item panel-nav__footer-user","aria-label":e?`User: ${n}`:`User menu for ${n}`},t("span",{key:"59b65c4e2ced6e2acb62eae491392b44431a1429",class:"panel-nav__item-label panel-nav__footer-user-label"},t("span",{key:"c8b9cd642dfe2bf104ea280d33c304795d075281",class:"panel-nav__item-label-text"},t("ds-text",{key:"db0168fcdc56276f96c0e88241573d8a9cce73d4",as:"span",variant:"text-body-medium-emphasis",color:"inherit"},n))),t("span",{key:"b4c9af4b3a500d38c21a9c313a8a8596211e8397",class:"panel-nav__item-icon panel-nav__footer-user-icon","aria-hidden":"true"},t("span",{key:"f7d6fe5052b8e1d203bc4ed608f32146a74dbc59",class:"panel-nav__footer-icon-expanded"},t("ds-icon",{key:"26fa53376d882984fe60cd64729f43b68258c64e",name:"ChevronUpDown",size:"md",color:"inherit"})),t("span",{key:"a38a6d373dc1ea932c85a14beb1c54d4acf1c3fc",class:"panel-nav__footer-icon-collapsed"},t("ds-icon",{key:"353c3019fbf72bbf0739e47caa98f79ecf52b1b6",name:"Circle",size:"md",color:"inherit"}),t("span",{key:"46d0201df56c6ca01380f6f69badd850fe52e853",class:"panel-nav__user-initial"},t("ds-text",{key:"1169443c0a8205cfc2b718aa7affdc3d8ce2cf9b",as:"span",variant:"text-caption-emphasis",color:"inherit"},o))))))),!this.viewportNarrow&&t("div",{key:"8af05d483b922466faa307e0ef3e9df19d30b333",class:{"panel-nav__resize-handle":true,"panel-nav__resize-handle--overlay":this.showEdgeOverlay},onMouseEnter:()=>this.handleResizeHandleMouseEnter(),onMouseLeave:()=>this.handleResizeHandleMouseLeave(),onMouseDown:a=>this.handleResizeHandleMouseDown(a),"aria-hidden":"true"}))}get el(){return this}static get watchers(){return{collapsed:[{onCollapsedChange:0}],viewportNarrow:[{onCollapsedChange:0}],breakpoint:[{onBreakpointChange:0}],groups:[{onGroupsChange:0}],activeId:[{onActiveIdChange:0}],urlDerivedActiveId:[{onActiveIdChange:0}],currentUrl:[{onCurrentUrlChange:0}]}}static get style(){return l()}},[2,"ds-panel-nav",{variant:[1],groups:[1],activeId:[1,"active-id"],collapsed:[1028],breakpoint:[2],storageKey:[1,"storage-key"],currentUrl:[1,"current-url"],userName:[1,"user-name"],userInitial:[1,"user-initial"],parsedGroups:[32],atBottom:[32],isAnimating:[32],rovingIndex:[32],viewportNarrow:[32],urlDerivedActiveId:[32],showEdgeOverlay:[32]},undefined,{collapsed:[{onCollapsedChange:0}],viewportNarrow:[{onCollapsedChange:0}],breakpoint:[{onBreakpointChange:0}],groups:[{onGroupsChange:0}],activeId:[{onActiveIdChange:0}],urlDerivedActiveId:[{onActiveIdChange:0}],currentUrl:[{onCurrentUrlChange:0}]}]);function c(){if(typeof customElements==="undefined"){return}const a=["ds-panel-nav","ds-icon","ds-text"];a.forEach((a=>{switch(a){case"ds-panel-nav":if(!customElements.get(o(a))){customElements.define(o(a),d)}break;case"ds-icon":if(!customElements.get(o(a))){s()}break;case"ds-text":if(!customElements.get(o(a))){r()}break}}))}c();const v=d;const p=c;export{v as DsPanelNav,p as defineCustomElement};
|
|
1
|
+
import{p as a,H as e,c as n,h as t,a as i,t as o}from"./index.js";import{d as s}from"./p-Bi2mMcOi.js";import{d as r}from"./p-CIMd6yG3.js";const d=()=>`.panel-nav.sc-ds-panel-nav{--_nav-width:200px;--_nav-width-collapsed:48px;--_nav-item-height:var(--dimension-size-400, 32px);--_nav-padding-x:var(--dimension-space-100, 8px);--_nav-padding-y:var(--dimension-space-100, 8px);--_nav-footer-btn-w:calc(var(--dimension-space-075, 6px) * 2 + var(--dimension-iconography-md, 20px));--_nav-speed:var(--ds-panel-nav-speed, 1);--_nav-expand-dur:calc(var(--_nav-speed) * var(--effect-animation-duration-medium-1, 300ms));--_nav-expand-motion:var(--_nav-expand-dur) var(--effect-animation-easing-ease-in-out, ease);--_nav-label-fade-dur:calc(var(--_nav-speed) * var(--effect-animation-duration-medium-1, 300ms));--_nav-label-fade-motion:var(--_nav-label-fade-dur) var(--effect-animation-easing-ease-in-out, ease);--_nav-label-fade-out-dur:calc(var(--_nav-speed) * var(--effect-animation-duration-medium-1, 300ms));--_nav-label-fade-out-motion:var(--_nav-label-fade-out-dur) var(--effect-animation-easing-ease-in-out, ease);--_nav-bg:var(--color-navigation-background);--_nav-border:var(--color-navigation-border-tertiary);--_nav-divider:var(--color-navigation-divider);--_nav-fg-primary:var(--color-navigation-foreground-primary);--_nav-fg-secondary:var(--color-navigation-foreground-secondary);--_nav-fg-tertiary:var(--color-navigation-foreground-tertiary);--_nav-hover:var(--color-navigation-interaction-hover);--_nav-pressed:var(--color-navigation-interaction-pressed);--_nav-focus:var(--color-navigation-interaction-focus);--_nav-dot:var(--color-navigation-foreground-brand)}.panel-nav--settings.sc-ds-panel-nav{--_nav-bg:var(--color-background-secondary);--_nav-border:var(--color-border-tertiary);--_nav-divider:var(--color-border-tertiary);--_nav-fg-primary:var(--color-foreground-primary);--_nav-fg-secondary:var(--color-foreground-secondary);--_nav-fg-tertiary:var(--color-foreground-tertiary);--_nav-hover:var(--color-interaction-hover);--_nav-pressed:var(--color-interaction-pressed);--_nav-focus:var(--color-interaction-focus);--_nav-dot:var(--color-foreground-bold-brand)}.panel-nav.sc-ds-panel-nav{display:flex;flex-direction:column;width:var(--_nav-width);min-width:var(--_nav-width);height:100%;background:var(--_nav-bg);border-right:var(--dimension-stroke-width-012, 1px) solid var(--_nav-border);box-sizing:border-box;overflow:hidden;transition:width var(--_nav-expand-motion), min-width var(--_nav-expand-motion), background var(--effect-motion-short-3, 200ms ease), border-color var(--effect-motion-short-3, 200ms ease);font-family:var(--typography-font-family, system-ui)}.panel-nav--collapsed.sc-ds-panel-nav{width:var(--_nav-width-collapsed);min-width:var(--_nav-width-collapsed)}.panel-nav__header.sc-ds-panel-nav{display:flex;align-items:center;padding:var(--dimension-space-100, 8px);flex-shrink:0;box-sizing:border-box;border-bottom:var(--dimension-stroke-width-012, 1px) solid var(--_nav-divider);transition:border-color var(--effect-motion-short-3, 200ms ease)}.panel-nav__header-btn.sc-ds-panel-nav{all:unset;display:flex;align-items:center;justify-content:center;padding:var(--dimension-space-075, 6px);border-radius:var(--dimension-radius-025, 2px);cursor:pointer;color:var(--_nav-fg-primary);position:relative;flex-shrink:0;box-sizing:border-box;transition:color var(--effect-motion-short-3, 200ms ease)}.panel-nav__header-btn.sc-ds-panel-nav::after{content:'';position:absolute;inset:0;border-radius:var(--dimension-radius-025, 2px);background:transparent;transition:background var(--effect-animation-duration-short-3, 200ms) var(--effect-animation-easing-ease-out, ease);pointer-events:none}.panel-nav__header-btn.sc-ds-panel-nav:hover::after{background:var(--_nav-hover);transition:none}.panel-nav__header-btn.sc-ds-panel-nav:active::after{background:var(--_nav-pressed);transition:none}.panel-nav__header-btn.sc-ds-panel-nav:focus-visible{outline:none}.panel-nav__header-btn.sc-ds-panel-nav:focus-visible::after{outline:var(--dimension-stroke-width-025, 2px) solid var(--_nav-focus);outline-offset:calc(-1 * var(--dimension-stroke-width-025, 2px))}.panel-nav__header-logo.sc-ds-panel-nav{display:flex;align-items:center;justify-content:center;position:relative;z-index:1;transition:opacity var(--effect-motion-short-2, 100ms ease)}.panel-nav__m-mark.sc-ds-panel-nav{width:var(--dimension-iconography-md, 20px);height:var(--dimension-iconography-md, 20px);display:block}.panel-nav__header-toggle.sc-ds-panel-nav{display:none;align-items:center;justify-content:center;position:absolute;inset:0;z-index:1}.panel-nav__header-btn.sc-ds-panel-nav:hover .panel-nav__header-logo.sc-ds-panel-nav{opacity:0}.panel-nav__header-btn.sc-ds-panel-nav:hover .panel-nav__header-toggle.sc-ds-panel-nav{display:flex}.panel-nav__body.sc-ds-panel-nav{flex:1;overflow-y:auto;overflow-x:hidden;display:flex;flex-direction:column;gap:var(--dimension-space-200, 16px);padding:var(--dimension-space-100, 8px);box-sizing:border-box;scrollbar-width:none}.panel-nav__body.sc-ds-panel-nav::-webkit-scrollbar{display:none}.panel-nav__group.sc-ds-panel-nav{display:flex;flex-direction:column;gap:var(--dimension-space-050, 4px)}.panel-nav__group-label.sc-ds-panel-nav{text-transform:uppercase;color:var(--_nav-fg-tertiary);padding:0 var(--dimension-space-050, 4px);margin-bottom:var(--dimension-space-025, 2px);white-space:nowrap;overflow:hidden;max-height:2em;opacity:1;transition:opacity var(--_nav-label-fade-motion) 0ms, max-height var(--_nav-label-fade-motion) 0ms, margin-bottom var(--_nav-label-fade-motion) 0ms, color var(--effect-motion-short-3, 200ms ease)}.panel-nav__item.sc-ds-panel-nav{all:unset;display:flex;align-items:center;gap:var(--dimension-space-050, 4px);padding:0 var(--dimension-space-075, 6px);height:var(--dimension-size-400, 32px);border-radius:var(--dimension-radius-025, 2px);cursor:pointer;color:var(--_nav-fg-secondary);position:relative;box-sizing:border-box;width:100%;user-select:none;transition:color var(--effect-motion-short-1, 50ms ease-in-out)}.panel-nav__item.sc-ds-panel-nav::after{content:'';position:absolute;inset:0;border-radius:var(--dimension-radius-025, 2px);background:transparent;pointer-events:none;transition:background var(--effect-animation-duration-short-3, 200ms) var(--effect-animation-easing-ease-out, ease)}.panel-nav__item.sc-ds-panel-nav:hover::after{background:var(--_nav-hover);transition:none}.panel-nav__item.sc-ds-panel-nav:active::after{background:var(--_nav-pressed);transition:none}.panel-nav__item.sc-ds-panel-nav:focus-visible{outline:none}.panel-nav__item.sc-ds-panel-nav:focus-visible::after{outline:var(--dimension-stroke-width-025, 2px) solid var(--_nav-focus);outline-offset:calc(-1 * var(--dimension-stroke-width-025, 2px))}.panel-nav__item--active.sc-ds-panel-nav{color:var(--_nav-fg-primary)}.panel-nav__item-icon.sc-ds-panel-nav{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:var(--dimension-iconography-md, 20px);height:var(--dimension-iconography-md, 20px);position:relative}.panel-nav__item-label.sc-ds-panel-nav{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;height:var(--typography-lineheight-md, 20px);line-height:var(--typography-lineheight-md, 20px);opacity:1;mask-image:linear-gradient(to right, black 50%, transparent 100%);-webkit-mask-image:linear-gradient(to right, black 50%, transparent 100%);mask-size:200% 100%;-webkit-mask-size:200% 100%;mask-position:0% 0;-webkit-mask-position:0% 0;transition:opacity var(--_nav-label-fade-motion) 0ms, mask-position var(--_nav-label-fade-motion) 0ms, -webkit-mask-position var(--_nav-label-fade-motion) 0ms}.panel-nav__item-label-text.sc-ds-panel-nav{padding:0 var(--dimension-space-025, 2px)}.panel-nav__item-dot.sc-ds-panel-nav{position:absolute;right:13px;top:13px;width:var(--dimension-space-075, 6px);height:var(--dimension-space-075, 6px);border-radius:var(--dimension-radius-full, 999px);background:var(--_nav-dot);box-shadow:0 0 0 var(--dimension-stroke-width-018, 1.5px) var(--_nav-bg);pointer-events:none;transition:right var(--_nav-expand-motion), top var(--_nav-expand-motion), background var(--effect-motion-short-3, 200ms ease), box-shadow var(--effect-motion-short-3, 200ms ease)}.panel-nav--collapsed.sc-ds-panel-nav .panel-nav__item-dot.sc-ds-panel-nav{right:6px;top:6px}.panel-nav--animating.sc-ds-panel-nav .panel-nav__item-label.sc-ds-panel-nav{text-overflow:clip}.panel-nav--collapsed.sc-ds-panel-nav .panel-nav__item-label.sc-ds-panel-nav{opacity:0;pointer-events:none;text-overflow:clip;mask-position:100% 0;-webkit-mask-position:100% 0;transition:opacity var(--_nav-label-fade-out-motion) 0ms, mask-position var(--_nav-label-fade-out-motion) 0ms, -webkit-mask-position var(--_nav-label-fade-out-motion) 0ms}.panel-nav--collapsed.sc-ds-panel-nav .panel-nav__group-label.sc-ds-panel-nav{opacity:0;max-height:0;margin-bottom:0;pointer-events:none;transition:opacity var(--_nav-label-fade-out-motion) 0ms, max-height var(--_nav-label-fade-out-motion) 0ms, margin-bottom var(--_nav-label-fade-out-motion) 0ms, color var(--effect-motion-short-3, 200ms ease)}.panel-nav__footer.sc-ds-panel-nav{position:relative;flex-shrink:0;height:calc(var(--_nav-padding-y) * 2 + var(--_nav-item-height));transition:height var(--_nav-expand-motion)}.panel-nav--collapsed.sc-ds-panel-nav .panel-nav__footer.sc-ds-panel-nav{height:calc(var(--_nav-padding-y) * 2 + var(--_nav-item-height) * 2 + var(--dimension-space-050, 4px))}.panel-nav__footer.sc-ds-panel-nav::before{content:'';position:absolute;bottom:100%;left:0;right:0;height:calc(var(--dimension-base, 8px) * 6);background:linear-gradient(to bottom, transparent, var(--_nav-bg));pointer-events:none;opacity:1;transition:opacity var(--effect-animation-duration-short-3, 200ms) var(--effect-animation-easing-ease-out, ease)}.panel-nav--at-bottom.sc-ds-panel-nav .panel-nav__footer.sc-ds-panel-nav::before{opacity:0}.panel-nav__footer-btn.sc-ds-panel-nav{all:unset;display:flex;align-items:center;justify-content:center;position:absolute;left:var(--_nav-padding-x);top:var(--_nav-padding-y);padding:var(--dimension-space-075, 6px);border-radius:var(--dimension-radius-half, 9999px);cursor:pointer;color:var(--_nav-fg-secondary);box-sizing:border-box;background:transparent;transition:background var(--effect-animation-duration-short-3, 200ms) var(--effect-animation-easing-ease-out, ease), color var(--effect-animation-duration-short-3, 200ms) var(--effect-animation-easing-ease-out, ease)}.panel-nav__footer-btn.sc-ds-panel-nav:focus-visible{outline:var(--dimension-stroke-width-025, 2px) solid var(--_nav-focus);outline-offset:calc(-1 * var(--dimension-stroke-width-025, 2px))}.panel-nav--dashboard.sc-ds-panel-nav .panel-nav__footer-btn.sc-ds-panel-nav:hover{background:var(--color-background-secondary);color:var(--color-foreground-secondary);transition:none}.panel-nav--settings.sc-ds-panel-nav .panel-nav__footer-btn.sc-ds-panel-nav:hover{background:var(--color-navigation-background);color:var(--color-navigation-foreground-secondary);transition:none}.panel-nav__footer-user.sc-ds-panel-nav{position:absolute;left:calc(var(--_nav-padding-x) + var(--_nav-footer-btn-w) + var(--dimension-space-050, 4px));right:var(--_nav-padding-x);top:var(--_nav-padding-y);width:auto;min-width:0;transition:left var(--_nav-expand-motion), right var(--_nav-expand-motion), top var(--_nav-expand-motion), color var(--effect-motion-short-3, 200ms ease)}.panel-nav--collapsed.sc-ds-panel-nav .panel-nav__footer-user.sc-ds-panel-nav{left:var(--_nav-padding-x);right:var(--_nav-padding-x);top:calc(var(--_nav-padding-y) + var(--_nav-item-height) + var(--dimension-space-050, 4px))}.panel-nav__footer-user-label.sc-ds-panel-nav{text-align:right;position:absolute;left:var(--dimension-space-075, 6px);right:calc(var(--dimension-space-075, 6px) + var(--dimension-iconography-md, 20px) + var(--dimension-space-050, 4px));top:50%;transform:translateY(-50%);flex:none;height:var(--typography-lineheight-md, 20px);mask-image:none;-webkit-mask-image:none;transition:opacity var(--_nav-label-fade-motion)}.panel-nav--collapsed.sc-ds-panel-nav .panel-nav__footer-user-label.sc-ds-panel-nav{opacity:0;pointer-events:none;mask-position:0% 0;-webkit-mask-position:0% 0}.panel-nav__footer-user-icon.sc-ds-panel-nav{position:absolute;left:calc(100% - var(--dimension-iconography-md, 20px) - var(--dimension-space-075, 6px));top:0;bottom:0;height:auto;display:flex;align-items:center;justify-content:center;transition:left var(--_nav-expand-motion)}.panel-nav--collapsed.sc-ds-panel-nav .panel-nav__footer-user-icon.sc-ds-panel-nav{left:var(--dimension-space-075, 6px)}.panel-nav__footer-icon-expanded.sc-ds-panel-nav,.panel-nav__footer-icon-collapsed.sc-ds-panel-nav{position:absolute;inset:0;display:flex;align-items:center;justify-content:center}.panel-nav__footer-icon-expanded.sc-ds-panel-nav{opacity:1;transition:opacity var(--_nav-label-fade-motion)}.panel-nav__footer-icon-collapsed.sc-ds-panel-nav{opacity:0;transition:opacity var(--_nav-label-fade-motion)}.panel-nav--collapsed.sc-ds-panel-nav .panel-nav__footer-icon-expanded.sc-ds-panel-nav{opacity:0;transition:opacity var(--_nav-label-fade-out-motion)}.panel-nav--collapsed.sc-ds-panel-nav .panel-nav__footer-icon-collapsed.sc-ds-panel-nav{opacity:1;transition:opacity var(--_nav-label-fade-out-motion)}.panel-nav__user-initial.sc-ds-panel-nav{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:var(--_nav-fg-secondary);text-transform:uppercase;line-height:1;pointer-events:none;transition:color var(--effect-motion-short-3, 200ms ease)}.panel-nav__resize-handle.sc-ds-panel-nav{position:absolute;top:0;right:var(--dimension-space-n050, -4px);bottom:0;width:var(--dimension-space-100, 8px);z-index:10;cursor:ew-resize;touch-action:none;background:transparent}.panel-nav__resize-handle.sc-ds-panel-nav::before{content:'';position:absolute;inset:0;background:rgba(0, 0, 0, 0.001)}.panel-nav__resize-handle.sc-ds-panel-nav::after{content:'';position:absolute;top:0;bottom:0;left:50%;transform:translateX(-50%);width:var(--dimension-stroke-width-025, 2px);background:var(--color-background-bold-brand);opacity:0;pointer-events:none;transition:opacity var(--effect-motion-short-2, 100ms ease-in-out)}.panel-nav__resize-handle--overlay.sc-ds-panel-nav::after{opacity:1}@media (prefers-reduced-motion: reduce){.panel-nav.sc-ds-panel-nav,.panel-nav.sc-ds-panel-nav *.sc-ds-panel-nav,.panel-nav.sc-ds-panel-nav *.sc-ds-panel-nav::before,.panel-nav.sc-ds-panel-nav *.sc-ds-panel-nav::after,.panel-nav__resize-handle.sc-ds-panel-nav,.panel-nav__resize-handle.sc-ds-panel-nav::before,.panel-nav__resize-handle.sc-ds-panel-nav::after{transition-duration:0.01ms !important;animation-duration:0.01ms !important;transition-delay:0.01ms !important}}`;const l=a(class a extends e{constructor(a){super();if(a!==false){this.__registerHost()}this.dsNavSelect=n(this,"dsNavSelect");this.dsNavToggle=n(this,"dsNavToggle");this.dsNavFooterAction=n(this,"dsNavFooterAction");this.variant="dashboard";this.groups="[]";this.activeId="";this.collapsed=false;this.breakpoint=0;this.storageKey="";this.currentUrl="";this.userName="";this.userInitial="";this.parsedGroups=[];this.atBottom=false;this.isAnimating=false;this.rovingIndex=0;this.viewportNarrow=false;this.urlDerivedActiveId="";this.isDragging=false;this.dragStartX=0;this.didSnap=false;this.lastDeltaX=0;this.edgeOverlayTimer=null;this.showEdgeOverlay=false}get effectiveActiveId(){return this.urlDerivedActiveId||this.activeId}onCollapsedChange(){this.startCollapseAnimation()}onBreakpointChange(){this.disconnectResizeObserver();if(this.breakpoint>0)this.connectResizeObserver()}onGroupsChange(a){try{this.parsedGroups=JSON.parse(a)}catch{this.parsedGroups=[]}this.syncRovingIndex()}onActiveIdChange(){this.syncRovingIndex()}onCurrentUrlChange(){this.syncActiveFromUrl()}componentWillLoad(){if(this.storageKey){try{const a=localStorage.getItem(this.storageKey);if(a!==null)this.collapsed=a==="true"}catch{}}this.onGroupsChange(this.groups);this.syncActiveFromUrl()}componentDidLoad(){this.checkScroll();if(this.breakpoint>0)this.connectResizeObserver();this.onGroupsChange(this.groups)}disconnectedCallback(){this.disconnectResizeObserver();this.clearEdgeOverlayTimer();if(this.globalMouseMoveHandler){window.removeEventListener("mousemove",this.globalMouseMoveHandler)}if(this.globalMouseUpHandler){window.removeEventListener("mouseup",this.globalMouseUpHandler)}}startCollapseAnimation(){this.isAnimating=true;const a=this.el.querySelector(".panel-nav");if(this.transitionEndHandler){a?.removeEventListener("transitionend",this.transitionEndHandler)}this.transitionEndHandler=e=>{if(e.propertyName==="width"){this.isAnimating=false;a?.removeEventListener("transitionend",this.transitionEndHandler)}};a?.addEventListener("transitionend",this.transitionEndHandler)}connectResizeObserver(){this.viewportNarrow=window.innerWidth<this.breakpoint;this.resizeObserver=new ResizeObserver((()=>{this.viewportNarrow=window.innerWidth<this.breakpoint}));this.resizeObserver.observe(document.documentElement)}disconnectResizeObserver(){this.resizeObserver?.disconnect();this.resizeObserver=undefined}syncActiveFromUrl(){if(!this.currentUrl){this.urlDerivedActiveId="";return}let a;let e=0;for(const n of this.getAllItems()){if(n.href&&this.currentUrl.startsWith(n.href)&&n.href.length>e){a=n;e=n.href.length}}this.urlDerivedActiveId=a?.id??""}applyToggle(a){this.dsNavToggle.emit(a);if(this.storageKey){this.collapsed=a;try{localStorage.setItem(this.storageKey,String(a))}catch{}}}getAllItems(){return this.parsedGroups.flatMap((a=>a.items))}syncRovingIndex(){const a=this.getAllItems().findIndex((a=>a.id===this.effectiveActiveId));this.rovingIndex=a>=0?a:0}handleItemKeyDown(a,e){const n=this.getAllItems().length;let t=e;switch(a.key){case"ArrowDown":a.preventDefault();t=(e+1)%n;break;case"ArrowUp":a.preventDefault();t=(e-1+n)%n;break;case"Home":a.preventDefault();t=0;break;case"End":a.preventDefault();t=n-1;break;default:return}this.rovingIndex=t;const i=Array.from(this.el.querySelectorAll(".panel-nav__body .panel-nav__item"));i[t]?.focus()}checkScroll(){const a=this.el.querySelector(".panel-nav__body");if(!a)return;const e=a.scrollHeight-a.scrollTop-a.clientHeight;this.atBottom=e<2}handleBodyScroll(a){const e=a.target;const n=e.scrollHeight-e.scrollTop-e.clientHeight;this.atBottom=n<2}handleItemClick(a){this.dsNavSelect.emit(a)}handleToggle(){this.applyToggle(!this.collapsed)}handleFooterAction(){this.dsNavFooterAction.emit()}clearEdgeOverlayTimer(){if(this.edgeOverlayTimer!==null){window.clearTimeout(this.edgeOverlayTimer);this.edgeOverlayTimer=null}}handleResizeHandleMouseEnter(){this.clearEdgeOverlayTimer();this.edgeOverlayTimer=window.setTimeout((()=>{this.showEdgeOverlay=true;this.edgeOverlayTimer=null}),500)}handleResizeHandleMouseLeave(){if(this.isDragging)return;this.clearEdgeOverlayTimer();this.showEdgeOverlay=false}handleResizeHandleMouseDown(a){a.preventDefault();a.stopPropagation();const e=this.collapsed||this.viewportNarrow;this.isDragging=true;this.dragStartX=a.clientX;this.didSnap=false;this.lastDeltaX=0;this.clearEdgeOverlayTimer();this.showEdgeOverlay=false;document.body.style.cursor="ew-resize";document.body.style.userSelect="none";const n=a=>{const n=a.clientX-this.dragStartX;this.lastDeltaX=Math.abs(n);if(this.didSnap)return;if(!e&&n<-8){this.applyToggle(true);this.didSnap=true}else if(e&&n>8){this.applyToggle(false);this.didSnap=true}};const t=()=>{if(!this.didSnap&&this.lastDeltaX<3){this.applyToggle(!e)}this.isDragging=false;this.showEdgeOverlay=false;document.body.style.cursor="";document.body.style.userSelect="";window.removeEventListener("mousemove",n);window.removeEventListener("mouseup",t);this.globalMouseMoveHandler=undefined;this.globalMouseUpHandler=undefined};this.globalMouseMoveHandler=n;this.globalMouseUpHandler=t;window.addEventListener("mousemove",n);window.addEventListener("mouseup",t)}renderNavItem(a,e,n){const i=a.id===this.effectiveActiveId;const o=[t("span",{class:"panel-nav__item-icon"},t("ds-icon",{name:a.icon,size:"md",color:"inherit",flag:a.flag})),t("span",{class:"panel-nav__item-label"},t("span",{class:"panel-nav__item-label-text"},t("ds-text",{as:"span",variant:i?"text-body-medium-emphasis":"text-body-medium",color:"inherit"},a.label))),a.dot&&t("span",{class:"panel-nav__item-dot","aria-hidden":"true"})];const s={class:{"panel-nav__item":true,"panel-nav__item--active":i},"aria-current":i?"page":undefined,title:n?a.label:undefined,tabIndex:e===this.rovingIndex?0:-1,onClick:()=>this.handleItemClick(a.id),onKeyDown:a=>this.handleItemKeyDown(a,e),onFocus:()=>{this.rovingIndex=e}};return a.href?t("a",{...s,href:a.href},o):t("button",{...s,type:"button"},o)}render(){const a=this.variant==="dashboard";const e=this.collapsed||this.viewportNarrow;const{userName:n,userInitial:o}=this;const s={"panel-nav":true,"panel-nav--dashboard":a,"panel-nav--settings":!a,"panel-nav--collapsed":e,"panel-nav--animating":this.isAnimating,"panel-nav--at-bottom":this.atBottom};return t(i,{key:"97de47c51d294d28589afdb45a33a1007ec5730e",style:{display:"block",position:"relative"}},t("nav",{key:"eed4b271682d18a3df9284ba032170066f1288f3",class:s,"aria-label":a?"Main navigation":"Settings navigation"},t("div",{key:"e5299fed299b5b5a29ae9f1da71c5294f264da05",class:"panel-nav__header"},t("button",{key:"03eff6f3f309ad618f138e03b55a0276b23bc195",type:"button",class:"panel-nav__header-btn",onClick:()=>this.handleToggle(),"aria-label":e?"Expand navigation":"Collapse navigation","aria-expanded":e?"false":"true"},t("span",{key:"53604e969748bbcee2b5a693c2f6454303ce2747",class:"panel-nav__header-logo","aria-hidden":"true"},t("svg",{key:"5fbdfb4d3595a9cd92b3fab3b125238000c2e48e",class:"panel-nav__m-mark",viewBox:"0 0 20 20",fill:"none",xmlns:"http://www.w3.org/2000/svg"},t("path",{key:"e019b32685d144d0e6188acbcda60e1bd71a0de2",d:"M11.1159 4.31537H7.67021L2.53401 13.0703H0V15.6875H4.02716L8.24319 8.49978V15.6846H11.6342L15.8289 8.47829V15.6846H18.7122V4.3125H15.2559L11.1159 11.3648V4.31537Z",fill:"currentColor"}))),t("span",{key:"483bc9e37ab47918e168af6d273048134d38536c",class:"panel-nav__header-toggle","aria-hidden":"true"},t("ds-icon",{key:"32e42a1dba85a8804b2d9e9cf45e1cc1ab264b4d",name:e?"LeftExpandB":"LeftCollapseB",size:"md",color:"inherit"})))),t("div",{key:"9a29267053b19d6875761da0d8274ee627cc9779",class:"panel-nav__body",onScroll:a=>this.handleBodyScroll(a)},(()=>{let a=0;return this.parsedGroups.map((n=>t("div",{class:"panel-nav__group"},n.label&&t("span",{class:"panel-nav__group-label"},t("ds-text",{as:"span",variant:"text-caption-emphasis",color:"inherit"},n.label)),n.items.map((n=>this.renderNavItem(n,a++,e))))))})()),t("div",{key:"0b9723c82972e647ed6d554469dc98ac0d350f19",class:"panel-nav__footer"},t("button",{key:"f720d5a657096ddacc28c2a44d8149c63dfcce69",type:"button",class:"panel-nav__footer-btn",title:a?"Settings":"Dashboard","aria-label":a?"Open settings":"Go to dashboard",onClick:()=>this.handleFooterAction()},t("ds-icon",{key:"67ac2a9adc29de4d98ce36dba1f69ddcfc912307",name:a?"Gear":"Dashboard",size:"md",color:"inherit"})),t("button",{key:"5d132b01612defc8f7897c7f5af86896a6e5e2b5",type:"button",class:"panel-nav__item panel-nav__footer-user","aria-label":e?`User: ${n}`:`User menu for ${n}`},t("span",{key:"24bca248545e9de7f908bdf06ee870e8e2d707c1",class:"panel-nav__item-label panel-nav__footer-user-label"},t("span",{key:"c6307c5ca1186b9606b4de718e96a0bed0f9ea8b",class:"panel-nav__item-label-text"},t("ds-text",{key:"6067035cd59cdfc945cc12e672697132b2b9ce2d",as:"span",variant:"text-body-medium-emphasis",color:"inherit"},n))),t("span",{key:"e8304e265e11000af9fd6b66e4e7ef296704d89c",class:"panel-nav__item-icon panel-nav__footer-user-icon","aria-hidden":"true"},t("span",{key:"6970f6bb4061061d05d4d651a220b2d4432f91a6",class:"panel-nav__footer-icon-expanded"},t("ds-icon",{key:"686c73294725e84b0e8614f28c9fa225d62ecfe9",name:"ChevronUpDown",size:"md",color:"inherit"})),t("span",{key:"1238875631f9ab6d2f0823d0af1b7f6cad2c9dd1",class:"panel-nav__footer-icon-collapsed"},t("ds-icon",{key:"29ff8527307ecfcbc8c38cd1c0bf6d8c48cf2131",name:"Circle",size:"md",color:"inherit"}),t("span",{key:"7eb7282ff7c00f68ff00e2dbf9b7cb2e06533afc",class:"panel-nav__user-initial"},t("ds-text",{key:"2a55e0cbaa54284a49984cff33fddc84ff1deef8",as:"span",variant:"text-caption-emphasis",color:"inherit"},o))))))),!this.viewportNarrow&&t("div",{key:"6e3735a359f4e325fc58d452061cc1ac6a402058",class:{"panel-nav__resize-handle":true,"panel-nav__resize-handle--overlay":this.showEdgeOverlay},onMouseEnter:()=>this.handleResizeHandleMouseEnter(),onMouseLeave:()=>this.handleResizeHandleMouseLeave(),onMouseDown:a=>this.handleResizeHandleMouseDown(a),"aria-hidden":"true"}))}get el(){return this}static get watchers(){return{collapsed:[{onCollapsedChange:0}],viewportNarrow:[{onCollapsedChange:0}],breakpoint:[{onBreakpointChange:0}],groups:[{onGroupsChange:0}],activeId:[{onActiveIdChange:0}],urlDerivedActiveId:[{onActiveIdChange:0}],currentUrl:[{onCurrentUrlChange:0}]}}static get style(){return d()}},[2,"ds-panel-nav",{variant:[1],groups:[1],activeId:[1,"active-id"],collapsed:[1028],breakpoint:[2],storageKey:[1,"storage-key"],currentUrl:[1,"current-url"],userName:[1,"user-name"],userInitial:[1,"user-initial"],parsedGroups:[32],atBottom:[32],isAnimating:[32],rovingIndex:[32],viewportNarrow:[32],urlDerivedActiveId:[32],showEdgeOverlay:[32]},undefined,{collapsed:[{onCollapsedChange:0}],viewportNarrow:[{onCollapsedChange:0}],breakpoint:[{onBreakpointChange:0}],groups:[{onGroupsChange:0}],activeId:[{onActiveIdChange:0}],urlDerivedActiveId:[{onActiveIdChange:0}],currentUrl:[{onCurrentUrlChange:0}]}]);function c(){if(typeof customElements==="undefined"){return}const a=["ds-panel-nav","ds-icon","ds-text"];a.forEach((a=>{switch(a){case"ds-panel-nav":if(!customElements.get(o(a))){customElements.define(o(a),l)}break;case"ds-icon":if(!customElements.get(o(a))){s()}break;case"ds-text":if(!customElements.get(o(a))){r()}break}}))}c();const v=l;const p=c;export{v as DsPanelNav,p as defineCustomElement};
|
|
2
2
|
//# sourceMappingURL=ds-panel-nav.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["panelNavCss","PanelNav","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","variant","groups","activeId","collapsed","breakpoint","storageKey","currentUrl","userName","userInitial","parsedGroups","atBottom","isAnimating","rovingIndex","viewportNarrow","urlDerivedActiveId","isDragging","dragStartX","didSnap","lastDeltaX","edgeOverlayTimer","showEdgeOverlay","effectiveActiveId","onCollapsedChange","startCollapseAnimation","onBreakpointChange","disconnectResizeObserver","connectResizeObserver","onGroupsChange","val","JSON","parse","syncRovingIndex","onActiveIdChange","onCurrentUrlChange","syncActiveFromUrl","componentWillLoad","stored","localStorage","getItem","componentDidLoad","checkScroll","disconnectedCallback","clearEdgeOverlayTimer","globalMouseMoveHandler","window","removeEventListener","globalMouseUpHandler","panel","el","querySelector","transitionEndHandler","e","propertyName","addEventListener","innerWidth","resizeObserver","ResizeObserver","observe","document","documentElement","disconnect","undefined","best","bestLen","item","getAllItems","href","startsWith","length","id","applyToggle","next","dsNavToggle","emit","setItem","String","flatMap","g","items","idx","findIndex","i","handleItemKeyDown","index","total","key","preventDefault","Array","from","querySelectorAll","focus","body","remaining","scrollHeight","scrollTop","clientHeight","handleBodyScroll","target","handleItemClick","dsNavSelect","handleToggle","handleFooterAction","dsNavFooterAction","clearTimeout","handleResizeHandleMouseEnter","setTimeout","handleResizeHandleMouseLeave","handleResizeHandleMouseDown","stopPropagation","wasCollapsed","clientX","style","cursor","userSelect","onMove","ev","deltaX","Math","abs","onUp","renderNavItem","isActive","itemContent","h","class","name","icon","size","color","flag","as","label","dot","sharedProps","title","tabIndex","onClick","onKeyDown","onFocus","type","render","isDashboard","navCls","Host","display","position","viewBox","fill","xmlns","d","onScroll","flatIdx","map","group","onMouseEnter","onMouseLeave","onMouseDown"],"sources":["src/wc/components/PanelNav/PanelNav.css?tag=ds-panel-nav&encapsulation=scoped","src/wc/components/PanelNav/PanelNav.tsx"],"sourcesContent":["/* ── Theme variables ──────────────────────────────────────────────────────── */\n\n.panel-nav {\n /* ─ Sizes ─ */\n --_nav-width: 200px;\n --_nav-width-collapsed: 48px;\n --_nav-item-height: var(--dimension-size-400, 32px);\n --_nav-padding-x: var(--dimension-space-100, 8px);\n --_nav-padding-y: var(--dimension-space-100, 8px);\n /* gear button outer width = padding*2 + icon */\n --_nav-footer-btn-w: calc(var(--dimension-space-075, 6px) * 2 + var(--dimension-iconography-md, 20px));\n\n /* ─ Motion ─ */\n /* --ds-panel-nav-speed: unitless multiplier; override in Storybook to slow-mo (e.g. 10 = 10×).\n *-dur vars are duration-only (needed for calc); *-motion vars add easing for use in transitions. */\n --_nav-speed: var(--ds-panel-nav-speed, 1);\n --_nav-expand-dur: calc(var(--_nav-speed) * var(--effect-animation-duration-medium-1, 300ms));\n --_nav-expand-motion: var(--_nav-expand-dur) var(--effect-animation-easing-ease-in-out, ease);\n --_nav-label-fade-dur: calc(var(--_nav-speed) * var(--effect-animation-duration-medium-1, 300ms));\n --_nav-label-fade-motion: var(--_nav-label-fade-dur) var(--effect-animation-easing-ease-in-out, ease);\n --_nav-label-fade-out-dur: calc(var(--_nav-speed) * var(--effect-animation-duration-medium-1, 300ms));\n --_nav-label-fade-out-motion: var(--_nav-label-fade-out-dur) var(--effect-animation-easing-ease-in-out, ease);\n\n /* ─ Colours – dashboard defaults ─ */\n --_nav-bg: var(--color-navigation-background);\n --_nav-border: var(--color-navigation-border-tertiary);\n --_nav-divider: var(--color-navigation-divider);\n --_nav-fg-primary: var(--color-navigation-foreground-primary);\n --_nav-fg-secondary: var(--color-navigation-foreground-secondary);\n --_nav-fg-tertiary: var(--color-navigation-foreground-tertiary);\n --_nav-hover: var(--color-navigation-interaction-hover);\n --_nav-pressed: var(--color-navigation-interaction-pressed);\n --_nav-focus: var(--color-navigation-interaction-focus);\n --_nav-dot: var(--color-navigation-foreground-brand);\n}\n\n/* ── Settings overrides ──────────────────────────────────────────────────── */\n\n.panel-nav--settings {\n --_nav-bg: var(--color-background-secondary);\n --_nav-border: var(--color-border-tertiary);\n --_nav-divider: var(--color-border-tertiary);\n --_nav-fg-primary: var(--color-foreground-primary);\n --_nav-fg-secondary: var(--color-foreground-secondary);\n --_nav-fg-tertiary: var(--color-foreground-tertiary);\n --_nav-hover: var(--color-interaction-hover);\n --_nav-pressed: var(--color-interaction-pressed);\n --_nav-focus: var(--color-interaction-focus);\n --_nav-dot: var(--color-foreground-bold-brand);\n}\n\n/* ── Shell ───────────────────────────────────────────────────────────────── */\n\n.panel-nav {\n display: flex;\n flex-direction: column;\n width: var(--_nav-width);\n min-width: var(--_nav-width);\n height: 100%;\n background: var(--_nav-bg);\n border-right: var(--dimension-stroke-width-012, 1px) solid var(--_nav-border);\n box-sizing: border-box;\n overflow: hidden;\n transition:\n width var(--_nav-expand-motion),\n min-width var(--_nav-expand-motion),\n background var(--effect-motion-short-3, 200ms ease),\n border-color var(--effect-motion-short-3, 200ms ease);\n font-family: var(--typography-font-family, system-ui);\n}\n\n.panel-nav--collapsed {\n width: var(--_nav-width-collapsed);\n min-width: var(--_nav-width-collapsed);\n}\n\n/* ── Header ──────────────────────────────────────────────────────────────── */\n\n.panel-nav__header {\n display: flex;\n align-items: center;\n padding: var(--dimension-space-100, 8px);\n flex-shrink: 0;\n box-sizing: border-box;\n border-bottom: var(--dimension-stroke-width-012, 1px) solid var(--_nav-divider);\n transition: border-color var(--effect-motion-short-3, 200ms ease);\n}\n\n.panel-nav__header-btn {\n all: unset;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: var(--dimension-space-075, 6px);\n border-radius: var(--dimension-radius-025, 2px);\n cursor: pointer;\n color: var(--_nav-fg-primary);\n position: relative;\n flex-shrink: 0;\n box-sizing: border-box;\n transition: color var(--effect-motion-short-3, 200ms ease);\n}\n\n/* Interaction pseudo-element */\n.panel-nav__header-btn::after {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: var(--dimension-radius-025, 2px);\n background: transparent;\n transition: background var(--effect-animation-duration-short-3, 200ms) var(--effect-animation-easing-ease-out, ease);\n pointer-events: none;\n}\n\n.panel-nav__header-btn:hover::after { background: var(--_nav-hover); transition: none; }\n.panel-nav__header-btn:active::after { background: var(--_nav-pressed); transition: none; }\n.panel-nav__header-btn:focus-visible { outline: none; }\n.panel-nav__header-btn:focus-visible::after {\n outline: var(--dimension-stroke-width-025, 2px) solid var(--_nav-focus);\n outline-offset: calc(-1 * var(--dimension-stroke-width-025, 2px));\n}\n\n/* Logo — visible by default, hidden on hover */\n.panel-nav__header-logo {\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n z-index: 1;\n transition: opacity var(--effect-motion-short-2, 100ms ease);\n}\n\n.panel-nav__m-mark {\n width: var(--dimension-iconography-md, 20px);\n height: var(--dimension-iconography-md, 20px);\n display: block;\n}\n\n/* Toggle icon — hidden by default, revealed on hover */\n.panel-nav__header-toggle {\n display: none;\n align-items: center;\n justify-content: center;\n position: absolute;\n inset: 0;\n z-index: 1;\n}\n\n.panel-nav__header-btn:hover .panel-nav__header-logo { opacity: 0; }\n.panel-nav__header-btn:hover .panel-nav__header-toggle { display: flex; }\n\n/* ── Scrollable body ─────────────────────────────────────────────────────── */\n\n.panel-nav__body {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n display: flex;\n flex-direction: column;\n gap: var(--dimension-space-200, 16px);\n padding: var(--dimension-space-100, 8px);\n box-sizing: border-box;\n scrollbar-width: none;\n}\n\n.panel-nav__body::-webkit-scrollbar { display: none; }\n\n/* ── Group ───────────────────────────────────────────────────────────────── */\n\n.panel-nav__group {\n display: flex;\n flex-direction: column;\n gap: var(--dimension-space-050, 4px);\n}\n\n.panel-nav__group-label {\n /* Typography via ds-text (text-caption-emphasis) */\n text-transform: uppercase;\n color: var(--_nav-fg-tertiary);\n padding: 0 var(--dimension-space-050, 4px);\n margin-bottom: var(--dimension-space-025, 2px);\n white-space: nowrap;\n overflow: hidden;\n max-height: 2em;\n opacity: 1;\n transition:\n opacity var(--_nav-label-fade-motion) 0ms,\n max-height var(--_nav-label-fade-motion) 0ms,\n margin-bottom var(--_nav-label-fade-motion) 0ms,\n color var(--effect-motion-short-3, 200ms ease);\n}\n\n/* ── Item ────────────────────────────────────────────────────────────────── */\n\n.panel-nav__item {\n all: unset;\n display: flex;\n align-items: center;\n gap: var(--dimension-space-050, 4px);\n padding: 0 var(--dimension-space-075, 6px);\n height: var(--dimension-size-400, 32px);\n border-radius: var(--dimension-radius-025, 2px);\n cursor: pointer;\n color: var(--_nav-fg-secondary);\n position: relative;\n box-sizing: border-box;\n width: 100%;\n user-select: none;\n transition: color var(--effect-motion-short-1, 50ms ease-in-out);\n}\n\n/* Interaction layer */\n.panel-nav__item::after {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: var(--dimension-radius-025, 2px);\n background: transparent;\n pointer-events: none;\n transition: background var(--effect-animation-duration-short-3, 200ms) var(--effect-animation-easing-ease-out, ease);\n}\n\n.panel-nav__item:hover::after { background: var(--_nav-hover); transition: none; }\n.panel-nav__item:active::after { background: var(--_nav-pressed); transition: none; }\n.panel-nav__item:focus-visible { outline: none; }\n.panel-nav__item:focus-visible::after {\n outline: var(--dimension-stroke-width-025, 2px) solid var(--_nav-focus);\n outline-offset: calc(-1 * var(--dimension-stroke-width-025, 2px));\n}\n\n/* ── Active item ─────────────────────────────────────────────────────────── */\n\n.panel-nav__item--active {\n color: var(--_nav-fg-primary);\n /* Bold typography via ds-text (text-body-medium-emphasis) on the label */\n}\n\n/* ── Item icon ───────────────────────────────────────────────────────────── */\n\n.panel-nav__item-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: var(--dimension-iconography-md, 20px);\n height: var(--dimension-iconography-md, 20px);\n position: relative;\n}\n\n/* ── Item label ──────────────────────────────────────────────────────────── */\n\n.panel-nav__item-label {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n min-width: 0;\n height: var(--typography-lineheight-md, 20px);\n line-height: var(--typography-lineheight-md, 20px);\n opacity: 1;\n /* Gradient wipe: mask sweeps left-to-right on expand, right-to-left on collapse */\n mask-image: linear-gradient(to right, black 50%, transparent 100%);\n -webkit-mask-image: linear-gradient(to right, black 50%, transparent 100%);\n mask-size: 200% 100%;\n -webkit-mask-size: 200% 100%;\n mask-position: 0% 0;\n -webkit-mask-position: 0% 0;\n transition:\n opacity var(--_nav-label-fade-motion) 0ms,\n mask-position var(--_nav-label-fade-motion) 0ms,\n -webkit-mask-position var(--_nav-label-fade-motion) 0ms;\n}\n\n.panel-nav__item-label-text {\n padding: 0 var(--dimension-space-025, 2px);\n}\n\n/* ── Item notification dot — single element, moves between positions ──────── */\n\n.panel-nav__item-dot {\n position: absolute;\n right: 13px;\n top: 13px;\n width: var(--dimension-space-075, 6px);\n height: var(--dimension-space-075, 6px);\n border-radius: var(--dimension-radius-full, 999px);\n background: var(--_nav-dot);\n box-shadow: 0 0 0 var(--dimension-stroke-width-018, 1.5px) var(--_nav-bg);\n pointer-events: none;\n transition:\n right var(--_nav-expand-motion),\n top var(--_nav-expand-motion),\n background var(--effect-motion-short-3, 200ms ease),\n box-shadow var(--effect-motion-short-3, 200ms ease);\n}\n\n.panel-nav--collapsed .panel-nav__item-dot {\n right: 6px;\n top: 6px;\n}\n\n.panel-nav--animating .panel-nav__item-label {\n text-overflow: clip;\n}\n\n.panel-nav--collapsed .panel-nav__item-label {\n opacity: 0;\n pointer-events: none;\n text-overflow: clip;\n mask-position: 100% 0;\n -webkit-mask-position: 100% 0;\n transition:\n opacity var(--_nav-label-fade-out-motion) 0ms,\n mask-position var(--_nav-label-fade-out-motion) 0ms,\n -webkit-mask-position var(--_nav-label-fade-out-motion) 0ms;\n}\n\n.panel-nav--collapsed .panel-nav__group-label {\n opacity: 0;\n max-height: 0;\n margin-bottom: 0;\n pointer-events: none;\n transition:\n opacity var(--_nav-label-fade-out-motion) 0ms,\n max-height var(--_nav-label-fade-out-motion) 0ms,\n margin-bottom var(--_nav-label-fade-out-motion) 0ms,\n color var(--effect-motion-short-3, 200ms ease);\n}\n\n/* ── Footer ──────────────────────────────────────────────────────────────── */\n\n.panel-nav__footer {\n position: relative;\n flex-shrink: 0;\n /* single row: padding*2 + item */\n height: calc(var(--_nav-padding-y) * 2 + var(--_nav-item-height));\n transition: height var(--_nav-expand-motion);\n}\n\n.panel-nav--collapsed .panel-nav__footer {\n /* two rows: padding*2 + item*2 + gap */\n height: calc(var(--_nav-padding-y) * 2 + var(--_nav-item-height) * 2 + var(--dimension-space-050, 4px));\n}\n\n/* Gradient fade — floats above the footer, masks content scrolling under it */\n.panel-nav__footer::before {\n content: '';\n position: absolute;\n bottom: 100%;\n left: 0;\n right: 0;\n height: calc(var(--dimension-base, 8px) * 6);\n background: linear-gradient(to bottom, transparent, var(--_nav-bg));\n pointer-events: none;\n opacity: 1;\n transition: opacity var(--effect-animation-duration-short-3, 200ms) var(--effect-animation-easing-ease-out, ease);\n}\n\n.panel-nav--at-bottom .panel-nav__footer::before {\n opacity: 0;\n}\n\n/* ── Footer icon button (gear / dashboard) ───────────────────────────────── */\n\n.panel-nav__footer-btn {\n all: unset;\n display: flex;\n align-items: center;\n justify-content: center;\n position: absolute;\n left: var(--_nav-padding-x);\n top: var(--_nav-padding-y);\n padding: var(--dimension-space-075, 6px);\n border-radius: var(--dimension-radius-half, 9999px);\n cursor: pointer;\n color: var(--_nav-fg-secondary);\n box-sizing: border-box;\n background: transparent;\n transition:\n background var(--effect-animation-duration-short-3, 200ms) var(--effect-animation-easing-ease-out, ease),\n color var(--effect-animation-duration-short-3, 200ms) var(--effect-animation-easing-ease-out, ease);\n}\n\n.panel-nav__footer-btn:focus-visible {\n outline: var(--dimension-stroke-width-025, 2px) solid var(--_nav-focus);\n outline-offset: calc(-1 * var(--dimension-stroke-width-025, 2px));\n}\n\n/* Dashboard: hover previews settings surface */\n.panel-nav--dashboard .panel-nav__footer-btn:hover {\n background: var(--color-background-secondary);\n color: var(--color-foreground-secondary);\n transition: none;\n}\n\n/* Settings: hover previews dashboard nav surface */\n.panel-nav--settings .panel-nav__footer-btn:hover {\n background: var(--color-navigation-background);\n color: var(--color-navigation-foreground-secondary);\n transition: none;\n}\n\n/* ── Footer user — absolutely positioned, slides from row to below gear ───── */\n\n.panel-nav__footer-user {\n position: absolute;\n /* row position: right of gear button */\n left: calc(var(--_nav-padding-x) + var(--_nav-footer-btn-w) + var(--dimension-space-050, 4px));\n right: var(--_nav-padding-x);\n top: var(--_nav-padding-y);\n width: auto;\n min-width: 0;\n transition:\n left var(--_nav-expand-motion),\n right var(--_nav-expand-motion),\n top var(--_nav-expand-motion),\n color var(--effect-motion-short-3, 200ms ease);\n}\n\n.panel-nav--collapsed .panel-nav__footer-user {\n /* column position: full-width row below gear */\n left: var(--_nav-padding-x);\n right: var(--_nav-padding-x);\n top: calc(var(--_nav-padding-y) + var(--_nav-item-height) + var(--dimension-space-050, 4px));\n}\n\n/* Label: absolute so it stays in place and only fades — no mask slide */\n.panel-nav__footer-user-label {\n text-align: right;\n position: absolute;\n left: var(--dimension-space-075, 6px);\n right: calc(var(--dimension-space-075, 6px) + var(--dimension-iconography-md, 20px) + var(--dimension-space-050, 4px));\n top: 50%;\n transform: translateY(-50%);\n flex: none;\n height: var(--typography-lineheight-md, 20px);\n mask-image: none;\n -webkit-mask-image: none;\n transition: opacity var(--_nav-label-fade-motion);\n}\n\n.panel-nav--collapsed .panel-nav__footer-user-label {\n opacity: 0;\n pointer-events: none;\n mask-position: 0% 0;\n -webkit-mask-position: 0% 0;\n}\n\n/* ── Footer user icon — cross-fades chevron ↔ circle+initial ────────────── */\n\n/* Absolute — right-anchored in expanded, left-anchored in collapsed to match regular item icon position */\n.panel-nav__footer-user-icon {\n position: absolute;\n left: calc(100% - var(--dimension-iconography-md, 20px) - var(--dimension-space-075, 6px));\n top: 0;\n bottom: 0;\n height: auto;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: left var(--_nav-expand-motion);\n}\n\n.panel-nav--collapsed .panel-nav__footer-user-icon {\n left: var(--dimension-space-075, 6px);\n}\n\n.panel-nav__footer-icon-expanded,\n.panel-nav__footer-icon-collapsed {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.panel-nav__footer-icon-expanded {\n opacity: 1;\n transition: opacity var(--_nav-label-fade-motion);\n}\n\n.panel-nav__footer-icon-collapsed {\n opacity: 0;\n transition: opacity var(--_nav-label-fade-motion);\n}\n\n.panel-nav--collapsed .panel-nav__footer-icon-expanded {\n opacity: 0;\n transition: opacity var(--_nav-label-fade-out-motion);\n}\n\n.panel-nav--collapsed .panel-nav__footer-icon-collapsed {\n opacity: 1;\n transition: opacity var(--_nav-label-fade-out-motion);\n}\n\n/* ── User initial — overlaid on the circle icon ─────────────────────────── */\n\n.panel-nav__user-initial {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--_nav-fg-secondary);\n text-transform: uppercase;\n line-height: 1;\n pointer-events: none;\n transition: color var(--effect-motion-short-3, 200ms ease);\n}\n\n/* ── Drag-to-resize handle ───────────────────────────────────────────────── */\n\n.panel-nav__resize-handle {\n position: absolute;\n top: 0;\n /* Centered on the right edge: --dimension-space-050 outside + inside = --dimension-space-100 hit zone */\n right: var(--dimension-space-n050, -4px);\n bottom: 0;\n width: var(--dimension-space-100, 8px);\n z-index: 10;\n cursor: ew-resize;\n touch-action: none;\n /* Needs a real background for Safari hit-testing */\n background: transparent;\n}\n\n/* Safari requires non-transparent fill for hit testing */\n.panel-nav__resize-handle::before {\n content: '';\n position: absolute;\n inset: 0;\n background: rgba(0, 0, 0, 0.001);\n}\n\n/* The brand-bold overlay line */\n.panel-nav__resize-handle::after {\n content: '';\n position: absolute;\n top: 0;\n bottom: 0;\n left: 50%;\n transform: translateX(-50%);\n width: var(--dimension-stroke-width-025, 2px);\n background: var(--color-background-bold-brand);\n opacity: 0;\n pointer-events: none;\n transition: opacity var(--effect-motion-short-2, 100ms ease-in-out);\n}\n\n.panel-nav__resize-handle--overlay::after {\n opacity: 1;\n}\n\n/* ── Reduced motion ──────────────────────────────────────────────────────── */\n\n@media (prefers-reduced-motion: reduce) {\n .panel-nav,\n .panel-nav *,\n .panel-nav *::before,\n .panel-nav *::after,\n .panel-nav__resize-handle,\n .panel-nav__resize-handle::before,\n .panel-nav__resize-handle::after {\n transition-duration: 0.01ms !important;\n animation-duration: 0.01ms !important;\n transition-delay: 0.01ms !important;\n }\n}\n","import { Component, Prop, Event, EventEmitter, Watch, State, Element, h, Host } from '@stencil/core';\n\nexport type PanelNavVariant = 'dashboard' | 'settings';\n\nexport interface PanelNavItem {\n id: string;\n icon: string;\n label: string;\n /** Show a notification dot badge on the item */\n dot?: boolean;\n flag?: boolean;\n /** When set, the item renders as an `<a>` element so any router that\n * intercepts anchor clicks (Angular Router, React Router, etc.) handles\n * navigation automatically. `dsNavSelect` still fires on click. */\n href?: string;\n}\n\nexport interface PanelNavGroup {\n id?: string;\n label?: string;\n items: PanelNavItem[];\n}\n\n@Component({\n tag: 'ds-panel-nav',\n styleUrl: 'PanelNav.css',\n scoped: true,\n})\nexport class PanelNav {\n /** Visual variant: `dashboard` = always-dark surface, `settings` = light surface */\n @Prop() variant: PanelNavVariant = 'dashboard';\n\n /** JSON string of `PanelNavGroup[]` */\n @Prop() groups: string = '[]';\n\n /** ID of the currently active/selected nav item. Overridden by `currentUrl` matching when set. */\n @Prop() activeId: string = '';\n\n /** Whether the nav is in collapsed (icon-only) state.\n * When `storageKey` is set the component manages this internally —\n * do not also bind it from outside in that mode. */\n @Prop({ mutable: true }) collapsed: boolean = false;\n\n /** Viewport width (px) below which the nav auto-collapses to icon-only mode. 0 = disabled. */\n @Prop() breakpoint: number = 0;\n\n /** `localStorage` key used to persist the collapsed state across page loads.\n * When set the component is self-managing for collapsed state; `dsNavToggle`\n * still fires for consumers that want to observe the change. */\n @Prop() storageKey: string = '';\n\n /** Current route URL (e.g. `window.location.pathname` or the router's active URL).\n * When set the component derives the active item by matching item `href` values\n * against this string (longest prefix wins), overriding `activeId`. */\n @Prop() currentUrl: string = '';\n\n /** Display name for the footer user section */\n @Prop() userName: string = '';\n\n /** Single character shown in the collapsed avatar */\n @Prop() userInitial: string = '';\n\n /** Emitted when a nav item is clicked. Detail = the item's `id`. */\n @Event() dsNavSelect!: EventEmitter<string>;\n\n /** Emitted when the collapse toggle is clicked. Detail = new collapsed state. */\n @Event() dsNavToggle!: EventEmitter<boolean>;\n\n /** Emitted when the footer left button (gear / dashboard) is clicked. */\n @Event() dsNavFooterAction!: EventEmitter<void>;\n\n @Element() el!: HTMLElement;\n\n @State() private parsedGroups: PanelNavGroup[] = [];\n @State() private atBottom = false;\n @State() private isAnimating = false;\n @State() private rovingIndex: number = 0;\n @State() private viewportNarrow: boolean = false;\n @State() private urlDerivedActiveId: string = '';\n\n private transitionEndHandler?: (e: TransitionEvent) => void;\n private resizeObserver?: ResizeObserver;\n\n // Drag-to-resize state (not @State — no re-render needed)\n private isDragging = false;\n private dragStartX = 0;\n private didSnap = false;\n private lastDeltaX = 0;\n private edgeOverlayTimer: number | null = null;\n private globalMouseMoveHandler?: (e: MouseEvent) => void;\n private globalMouseUpHandler?: () => void;\n\n @State() private showEdgeOverlay = false;\n\n /** The ID that should be treated as active. `currentUrl` matching takes precedence\n * over `activeId` when both are present. */\n private get effectiveActiveId(): string {\n return this.urlDerivedActiveId || this.activeId;\n }\n\n @Watch('collapsed')\n @Watch('viewportNarrow')\n onCollapsedChange() {\n this.startCollapseAnimation();\n }\n\n @Watch('breakpoint')\n onBreakpointChange() {\n this.disconnectResizeObserver();\n if (this.breakpoint > 0) this.connectResizeObserver();\n }\n\n @Watch('groups')\n onGroupsChange(val: string) {\n try {\n this.parsedGroups = JSON.parse(val);\n } catch {\n this.parsedGroups = [];\n }\n this.syncRovingIndex();\n }\n\n @Watch('activeId')\n @Watch('urlDerivedActiveId')\n onActiveIdChange() {\n this.syncRovingIndex();\n }\n\n @Watch('currentUrl')\n onCurrentUrlChange() {\n this.syncActiveFromUrl();\n }\n\n componentWillLoad() {\n if (this.storageKey) {\n try {\n const stored = localStorage.getItem(this.storageKey);\n if (stored !== null) this.collapsed = stored === 'true';\n } catch { /* localStorage unavailable */ }\n }\n this.onGroupsChange(this.groups);\n this.syncActiveFromUrl();\n }\n\n componentDidLoad() {\n this.checkScroll();\n if (this.breakpoint > 0) this.connectResizeObserver();\n }\n\n disconnectedCallback() {\n this.disconnectResizeObserver();\n this.clearEdgeOverlayTimer();\n if (this.globalMouseMoveHandler) {\n window.removeEventListener('mousemove', this.globalMouseMoveHandler);\n }\n if (this.globalMouseUpHandler) {\n window.removeEventListener('mouseup', this.globalMouseUpHandler);\n }\n }\n\n private startCollapseAnimation() {\n this.isAnimating = true;\n const panel = this.el.querySelector('.panel-nav') as HTMLElement | null;\n if (this.transitionEndHandler) {\n panel?.removeEventListener('transitionend', this.transitionEndHandler);\n }\n this.transitionEndHandler = (e: TransitionEvent) => {\n if (e.propertyName === 'width') {\n this.isAnimating = false;\n panel?.removeEventListener('transitionend', this.transitionEndHandler!);\n }\n };\n panel?.addEventListener('transitionend', this.transitionEndHandler);\n }\n\n private connectResizeObserver() {\n this.viewportNarrow = window.innerWidth < this.breakpoint;\n this.resizeObserver = new ResizeObserver(() => {\n this.viewportNarrow = window.innerWidth < this.breakpoint;\n });\n this.resizeObserver.observe(document.documentElement);\n }\n\n private disconnectResizeObserver() {\n this.resizeObserver?.disconnect();\n this.resizeObserver = undefined;\n }\n\n /** Derive active ID from the current URL by matching item `href` values.\n * Uses longest-prefix match so `/fleet/detail` correctly activates `/fleet`. */\n private syncActiveFromUrl() {\n if (!this.currentUrl) {\n this.urlDerivedActiveId = '';\n return;\n }\n let best: PanelNavItem | undefined;\n let bestLen = 0;\n for (const item of this.getAllItems()) {\n if (item.href && this.currentUrl.startsWith(item.href) && item.href.length > bestLen) {\n best = item;\n bestLen = item.href.length;\n }\n }\n this.urlDerivedActiveId = best?.id ?? '';\n }\n\n /** Centralised toggle: always emits `dsNavToggle`; when `storageKey` is set\n * also mutates `collapsed` directly and persists to `localStorage`. */\n private applyToggle(next: boolean) {\n this.dsNavToggle.emit(next);\n if (this.storageKey) {\n this.collapsed = next;\n try { localStorage.setItem(this.storageKey, String(next)); } catch { /* unavailable */ }\n }\n }\n\n private getAllItems(): PanelNavItem[] {\n return this.parsedGroups.flatMap(g => g.items);\n }\n\n private syncRovingIndex() {\n const idx = this.getAllItems().findIndex(i => i.id === this.effectiveActiveId);\n this.rovingIndex = idx >= 0 ? idx : 0;\n }\n\n private handleItemKeyDown(e: KeyboardEvent, index: number) {\n const total = this.getAllItems().length;\n let next = index;\n switch (e.key) {\n case 'ArrowDown': e.preventDefault(); next = (index + 1) % total; break;\n case 'ArrowUp': e.preventDefault(); next = (index - 1 + total) % total; break;\n case 'Home': e.preventDefault(); next = 0; break;\n case 'End': e.preventDefault(); next = total - 1; break;\n default: return;\n }\n this.rovingIndex = next;\n const items = Array.from(\n this.el.querySelectorAll<HTMLElement>('.panel-nav__body .panel-nav__item')\n );\n items[next]?.focus();\n }\n\n private checkScroll() {\n const body = this.el.querySelector('.panel-nav__body') as HTMLElement | null;\n if (!body) return;\n const remaining = body.scrollHeight - body.scrollTop - body.clientHeight;\n this.atBottom = remaining < 2;\n }\n\n private handleBodyScroll(e: Event) {\n const body = e.target as HTMLElement;\n const remaining = body.scrollHeight - body.scrollTop - body.clientHeight;\n this.atBottom = remaining < 2;\n }\n\n private handleItemClick(id: string) {\n this.dsNavSelect.emit(id);\n }\n\n private handleToggle() {\n this.applyToggle(!this.collapsed);\n }\n\n private handleFooterAction() {\n this.dsNavFooterAction.emit();\n }\n\n private clearEdgeOverlayTimer() {\n if (this.edgeOverlayTimer !== null) {\n window.clearTimeout(this.edgeOverlayTimer);\n this.edgeOverlayTimer = null;\n }\n }\n\n private handleResizeHandleMouseEnter() {\n this.clearEdgeOverlayTimer();\n this.edgeOverlayTimer = window.setTimeout(() => {\n this.showEdgeOverlay = true;\n this.edgeOverlayTimer = null;\n }, 500);\n }\n\n private handleResizeHandleMouseLeave() {\n if (this.isDragging) return;\n this.clearEdgeOverlayTimer();\n this.showEdgeOverlay = false;\n }\n\n private handleResizeHandleMouseDown(e: MouseEvent) {\n e.preventDefault();\n e.stopPropagation();\n\n const wasCollapsed = this.collapsed || this.viewportNarrow;\n this.isDragging = true;\n this.dragStartX = e.clientX;\n this.didSnap = false;\n this.lastDeltaX = 0;\n this.clearEdgeOverlayTimer();\n this.showEdgeOverlay = false;\n\n document.body.style.cursor = 'ew-resize';\n document.body.style.userSelect = 'none';\n\n const onMove = (ev: MouseEvent) => {\n const deltaX = ev.clientX - this.dragStartX;\n this.lastDeltaX = Math.abs(deltaX);\n if (this.didSnap) return;\n if (!wasCollapsed && deltaX < -8) {\n this.applyToggle(true);\n this.didSnap = true;\n } else if (wasCollapsed && deltaX > 8) {\n this.applyToggle(false);\n this.didSnap = true;\n }\n };\n\n const onUp = () => {\n if (!this.didSnap && this.lastDeltaX < 3) {\n this.applyToggle(!wasCollapsed);\n }\n this.isDragging = false;\n this.showEdgeOverlay = false;\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n window.removeEventListener('mousemove', onMove);\n window.removeEventListener('mouseup', onUp);\n this.globalMouseMoveHandler = undefined;\n this.globalMouseUpHandler = undefined;\n };\n\n this.globalMouseMoveHandler = onMove;\n this.globalMouseUpHandler = onUp;\n window.addEventListener('mousemove', onMove);\n window.addEventListener('mouseup', onUp);\n }\n\n private renderNavItem(item: PanelNavItem, idx: number, collapsed: boolean) {\n const isActive = item.id === this.effectiveActiveId;\n\n const itemContent = [\n <span class=\"panel-nav__item-icon\">\n <ds-icon name={item.icon} size=\"md\" color=\"inherit\" flag={item.flag} />\n </span>,\n <span class=\"panel-nav__item-label\">\n <span class=\"panel-nav__item-label-text\">\n <ds-text\n as=\"span\"\n variant={isActive ? 'text-body-medium-emphasis' : 'text-body-medium'}\n color=\"inherit\"\n >\n {item.label}\n </ds-text>\n </span>\n </span>,\n item.dot && <span class=\"panel-nav__item-dot\" aria-hidden=\"true\" />,\n ];\n\n const sharedProps = {\n class: { 'panel-nav__item': true, 'panel-nav__item--active': isActive },\n 'aria-current': isActive ? ('page' as const) : undefined,\n title: collapsed ? item.label : undefined,\n tabIndex: idx === this.rovingIndex ? 0 : -1,\n onClick: () => this.handleItemClick(item.id),\n onKeyDown: (e: KeyboardEvent) => this.handleItemKeyDown(e, idx),\n onFocus: () => { this.rovingIndex = idx; },\n };\n\n return item.href\n ? <a {...sharedProps} href={item.href}>{itemContent}</a>\n : <button {...sharedProps} type=\"button\">{itemContent}</button>;\n }\n\n render() {\n const isDashboard = this.variant === 'dashboard';\n const collapsed = this.collapsed || this.viewportNarrow;\n const { userName, userInitial } = this;\n\n const navCls: Record<string, boolean> = {\n 'panel-nav': true,\n 'panel-nav--dashboard': isDashboard,\n 'panel-nav--settings': !isDashboard,\n 'panel-nav--collapsed': collapsed,\n 'panel-nav--animating': this.isAnimating,\n 'panel-nav--at-bottom': this.atBottom,\n };\n\n return (\n <Host style={{ display: 'block', position: 'relative' }}>\n <nav class={navCls} aria-label={isDashboard ? 'Main navigation' : 'Settings navigation'}>\n\n {/* ── Header: Motive logo, reveals collapse toggle on hover ── */}\n <div class=\"panel-nav__header\">\n <button\n type=\"button\"\n class=\"panel-nav__header-btn\"\n onClick={() => this.handleToggle()}\n aria-label={collapsed ? 'Expand navigation' : 'Collapse navigation'}\n aria-expanded={collapsed ? 'false' : 'true'}\n >\n {/* Motive M mark — fades out on hover to reveal collapse toggle */}\n <span class=\"panel-nav__header-logo\" aria-hidden=\"true\">\n <svg class=\"panel-nav__m-mark\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M11.1159 4.31537H7.67021L2.53401 13.0703H0V15.6875H4.02716L8.24319 8.49978V15.6846H11.6342L15.8289 8.47829V15.6846H18.7122V4.3125H15.2559L11.1159 11.3648V4.31537Z\" fill=\"currentColor\"/>\n </svg>\n </span>\n {/* Collapse / expand icon — revealed on hover via CSS */}\n <span class=\"panel-nav__header-toggle\" aria-hidden=\"true\">\n <ds-icon\n name={collapsed ? 'LeftExpandB' : 'LeftCollapseB'}\n size=\"md\"\n color=\"inherit\"\n />\n </span>\n </button>\n </div>\n\n {/* ── Scrollable body ── */}\n <div class=\"panel-nav__body\" onScroll={e => this.handleBodyScroll(e)}>\n {(() => {\n let flatIdx = 0;\n return this.parsedGroups.map(group => (\n <div class=\"panel-nav__group\">\n {group.label && (\n <span class=\"panel-nav__group-label\">\n <ds-text as=\"span\" variant=\"text-caption-emphasis\" color=\"inherit\">\n {group.label}\n </ds-text>\n </span>\n )}\n {group.items.map(item => this.renderNavItem(item, flatIdx++, collapsed))}\n </div>\n ));\n })()}\n </div>\n\n {/* ── Footer ── */}\n <div class=\"panel-nav__footer\">\n {/* Left icon button — Gear in dashboard, Dashboard in settings */}\n <button\n type=\"button\"\n class=\"panel-nav__footer-btn\"\n title={isDashboard ? 'Settings' : 'Dashboard'}\n aria-label={isDashboard ? 'Open settings' : 'Go to dashboard'}\n onClick={() => this.handleFooterAction()}\n >\n <ds-icon name={isDashboard ? 'Gear' : 'Dashboard'} size=\"md\" color=\"inherit\" />\n </button>\n\n {/* Right user — label fades like nav items; right icon cross-fades chevron ↔ circle+initial */}\n <button\n type=\"button\"\n class=\"panel-nav__item panel-nav__footer-user\"\n aria-label={collapsed ? `User: ${userName}` : `User menu for ${userName}`}\n >\n <span class=\"panel-nav__item-label panel-nav__footer-user-label\">\n <span class=\"panel-nav__item-label-text\">\n <ds-text as=\"span\" variant=\"text-body-medium-emphasis\" color=\"inherit\">\n {userName}\n </ds-text>\n </span>\n </span>\n <span class=\"panel-nav__item-icon panel-nav__footer-user-icon\" aria-hidden=\"true\">\n <span class=\"panel-nav__footer-icon-expanded\">\n <ds-icon name=\"ChevronUpDown\" size=\"md\" color=\"inherit\" />\n </span>\n <span class=\"panel-nav__footer-icon-collapsed\">\n <ds-icon name=\"Circle\" size=\"md\" color=\"inherit\" />\n <span class=\"panel-nav__user-initial\">\n <ds-text as=\"span\" variant=\"text-caption-emphasis\" color=\"inherit\">\n {userInitial}\n </ds-text>\n </span>\n </span>\n </span>\n </button>\n </div>\n\n </nav>\n\n {/* Drag-to-resize handle — always rendered, hidden only when auto-collapsed by breakpoint */}\n {!this.viewportNarrow && (\n <div\n class={{\n 'panel-nav__resize-handle': true,\n 'panel-nav__resize-handle--overlay': this.showEdgeOverlay,\n }}\n onMouseEnter={() => this.handleResizeHandleMouseEnter()}\n onMouseLeave={() => this.handleResizeHandleMouseLeave()}\n onMouseDown={(e: MouseEvent) => this.handleResizeHandleMouseDown(e)}\n aria-hidden=\"true\"\n />\n )}\n </Host>\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["panelNavCss","PanelNav","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","variant","groups","activeId","collapsed","breakpoint","storageKey","currentUrl","userName","userInitial","parsedGroups","atBottom","isAnimating","rovingIndex","viewportNarrow","urlDerivedActiveId","isDragging","dragStartX","didSnap","lastDeltaX","edgeOverlayTimer","showEdgeOverlay","effectiveActiveId","onCollapsedChange","startCollapseAnimation","onBreakpointChange","disconnectResizeObserver","connectResizeObserver","onGroupsChange","val","JSON","parse","syncRovingIndex","onActiveIdChange","onCurrentUrlChange","syncActiveFromUrl","componentWillLoad","stored","localStorage","getItem","componentDidLoad","checkScroll","disconnectedCallback","clearEdgeOverlayTimer","globalMouseMoveHandler","window","removeEventListener","globalMouseUpHandler","panel","el","querySelector","transitionEndHandler","e","propertyName","addEventListener","innerWidth","resizeObserver","ResizeObserver","observe","document","documentElement","disconnect","undefined","best","bestLen","item","getAllItems","href","startsWith","length","id","applyToggle","next","dsNavToggle","emit","setItem","String","flatMap","g","items","idx","findIndex","i","handleItemKeyDown","index","total","key","preventDefault","Array","from","querySelectorAll","focus","body","remaining","scrollHeight","scrollTop","clientHeight","handleBodyScroll","target","handleItemClick","dsNavSelect","handleToggle","handleFooterAction","dsNavFooterAction","clearTimeout","handleResizeHandleMouseEnter","setTimeout","handleResizeHandleMouseLeave","handleResizeHandleMouseDown","stopPropagation","wasCollapsed","clientX","style","cursor","userSelect","onMove","ev","deltaX","Math","abs","onUp","renderNavItem","isActive","itemContent","h","class","name","icon","size","color","flag","as","label","dot","sharedProps","title","tabIndex","onClick","onKeyDown","onFocus","type","render","isDashboard","navCls","Host","display","position","viewBox","fill","xmlns","d","onScroll","flatIdx","map","group","onMouseEnter","onMouseLeave","onMouseDown"],"sources":["src/wc/components/PanelNav/PanelNav.css?tag=ds-panel-nav&encapsulation=scoped","src/wc/components/PanelNav/PanelNav.tsx"],"sourcesContent":["/* ── Theme variables ──────────────────────────────────────────────────────── */\n\n.panel-nav {\n /* ─ Sizes ─ */\n --_nav-width: 200px;\n --_nav-width-collapsed: 48px;\n --_nav-item-height: var(--dimension-size-400, 32px);\n --_nav-padding-x: var(--dimension-space-100, 8px);\n --_nav-padding-y: var(--dimension-space-100, 8px);\n /* gear button outer width = padding*2 + icon */\n --_nav-footer-btn-w: calc(var(--dimension-space-075, 6px) * 2 + var(--dimension-iconography-md, 20px));\n\n /* ─ Motion ─ */\n /* --ds-panel-nav-speed: unitless multiplier; override in Storybook to slow-mo (e.g. 10 = 10×).\n *-dur vars are duration-only (needed for calc); *-motion vars add easing for use in transitions. */\n --_nav-speed: var(--ds-panel-nav-speed, 1);\n --_nav-expand-dur: calc(var(--_nav-speed) * var(--effect-animation-duration-medium-1, 300ms));\n --_nav-expand-motion: var(--_nav-expand-dur) var(--effect-animation-easing-ease-in-out, ease);\n --_nav-label-fade-dur: calc(var(--_nav-speed) * var(--effect-animation-duration-medium-1, 300ms));\n --_nav-label-fade-motion: var(--_nav-label-fade-dur) var(--effect-animation-easing-ease-in-out, ease);\n --_nav-label-fade-out-dur: calc(var(--_nav-speed) * var(--effect-animation-duration-medium-1, 300ms));\n --_nav-label-fade-out-motion: var(--_nav-label-fade-out-dur) var(--effect-animation-easing-ease-in-out, ease);\n\n /* ─ Colours – dashboard defaults ─ */\n --_nav-bg: var(--color-navigation-background);\n --_nav-border: var(--color-navigation-border-tertiary);\n --_nav-divider: var(--color-navigation-divider);\n --_nav-fg-primary: var(--color-navigation-foreground-primary);\n --_nav-fg-secondary: var(--color-navigation-foreground-secondary);\n --_nav-fg-tertiary: var(--color-navigation-foreground-tertiary);\n --_nav-hover: var(--color-navigation-interaction-hover);\n --_nav-pressed: var(--color-navigation-interaction-pressed);\n --_nav-focus: var(--color-navigation-interaction-focus);\n --_nav-dot: var(--color-navigation-foreground-brand);\n}\n\n/* ── Settings overrides ──────────────────────────────────────────────────── */\n\n.panel-nav--settings {\n --_nav-bg: var(--color-background-secondary);\n --_nav-border: var(--color-border-tertiary);\n --_nav-divider: var(--color-border-tertiary);\n --_nav-fg-primary: var(--color-foreground-primary);\n --_nav-fg-secondary: var(--color-foreground-secondary);\n --_nav-fg-tertiary: var(--color-foreground-tertiary);\n --_nav-hover: var(--color-interaction-hover);\n --_nav-pressed: var(--color-interaction-pressed);\n --_nav-focus: var(--color-interaction-focus);\n --_nav-dot: var(--color-foreground-bold-brand);\n}\n\n/* ── Shell ───────────────────────────────────────────────────────────────── */\n\n.panel-nav {\n display: flex;\n flex-direction: column;\n width: var(--_nav-width);\n min-width: var(--_nav-width);\n height: 100%;\n background: var(--_nav-bg);\n border-right: var(--dimension-stroke-width-012, 1px) solid var(--_nav-border);\n box-sizing: border-box;\n overflow: hidden;\n transition:\n width var(--_nav-expand-motion),\n min-width var(--_nav-expand-motion),\n background var(--effect-motion-short-3, 200ms ease),\n border-color var(--effect-motion-short-3, 200ms ease);\n font-family: var(--typography-font-family, system-ui);\n}\n\n.panel-nav--collapsed {\n width: var(--_nav-width-collapsed);\n min-width: var(--_nav-width-collapsed);\n}\n\n/* ── Header ──────────────────────────────────────────────────────────────── */\n\n.panel-nav__header {\n display: flex;\n align-items: center;\n padding: var(--dimension-space-100, 8px);\n flex-shrink: 0;\n box-sizing: border-box;\n border-bottom: var(--dimension-stroke-width-012, 1px) solid var(--_nav-divider);\n transition: border-color var(--effect-motion-short-3, 200ms ease);\n}\n\n.panel-nav__header-btn {\n all: unset;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: var(--dimension-space-075, 6px);\n border-radius: var(--dimension-radius-025, 2px);\n cursor: pointer;\n color: var(--_nav-fg-primary);\n position: relative;\n flex-shrink: 0;\n box-sizing: border-box;\n transition: color var(--effect-motion-short-3, 200ms ease);\n}\n\n/* Interaction pseudo-element */\n.panel-nav__header-btn::after {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: var(--dimension-radius-025, 2px);\n background: transparent;\n transition: background var(--effect-animation-duration-short-3, 200ms) var(--effect-animation-easing-ease-out, ease);\n pointer-events: none;\n}\n\n.panel-nav__header-btn:hover::after { background: var(--_nav-hover); transition: none; }\n.panel-nav__header-btn:active::after { background: var(--_nav-pressed); transition: none; }\n.panel-nav__header-btn:focus-visible { outline: none; }\n.panel-nav__header-btn:focus-visible::after {\n outline: var(--dimension-stroke-width-025, 2px) solid var(--_nav-focus);\n outline-offset: calc(-1 * var(--dimension-stroke-width-025, 2px));\n}\n\n/* Logo — visible by default, hidden on hover */\n.panel-nav__header-logo {\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n z-index: 1;\n transition: opacity var(--effect-motion-short-2, 100ms ease);\n}\n\n.panel-nav__m-mark {\n width: var(--dimension-iconography-md, 20px);\n height: var(--dimension-iconography-md, 20px);\n display: block;\n}\n\n/* Toggle icon — hidden by default, revealed on hover */\n.panel-nav__header-toggle {\n display: none;\n align-items: center;\n justify-content: center;\n position: absolute;\n inset: 0;\n z-index: 1;\n}\n\n.panel-nav__header-btn:hover .panel-nav__header-logo { opacity: 0; }\n.panel-nav__header-btn:hover .panel-nav__header-toggle { display: flex; }\n\n/* ── Scrollable body ─────────────────────────────────────────────────────── */\n\n.panel-nav__body {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n display: flex;\n flex-direction: column;\n gap: var(--dimension-space-200, 16px);\n padding: var(--dimension-space-100, 8px);\n box-sizing: border-box;\n scrollbar-width: none;\n}\n\n.panel-nav__body::-webkit-scrollbar { display: none; }\n\n/* ── Group ───────────────────────────────────────────────────────────────── */\n\n.panel-nav__group {\n display: flex;\n flex-direction: column;\n gap: var(--dimension-space-050, 4px);\n}\n\n.panel-nav__group-label {\n /* Typography via ds-text (text-caption-emphasis) */\n text-transform: uppercase;\n color: var(--_nav-fg-tertiary);\n padding: 0 var(--dimension-space-050, 4px);\n margin-bottom: var(--dimension-space-025, 2px);\n white-space: nowrap;\n overflow: hidden;\n max-height: 2em;\n opacity: 1;\n transition:\n opacity var(--_nav-label-fade-motion) 0ms,\n max-height var(--_nav-label-fade-motion) 0ms,\n margin-bottom var(--_nav-label-fade-motion) 0ms,\n color var(--effect-motion-short-3, 200ms ease);\n}\n\n/* ── Item ────────────────────────────────────────────────────────────────── */\n\n.panel-nav__item {\n all: unset;\n display: flex;\n align-items: center;\n gap: var(--dimension-space-050, 4px);\n padding: 0 var(--dimension-space-075, 6px);\n height: var(--dimension-size-400, 32px);\n border-radius: var(--dimension-radius-025, 2px);\n cursor: pointer;\n color: var(--_nav-fg-secondary);\n position: relative;\n box-sizing: border-box;\n width: 100%;\n user-select: none;\n transition: color var(--effect-motion-short-1, 50ms ease-in-out);\n}\n\n/* Interaction layer */\n.panel-nav__item::after {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: var(--dimension-radius-025, 2px);\n background: transparent;\n pointer-events: none;\n transition: background var(--effect-animation-duration-short-3, 200ms) var(--effect-animation-easing-ease-out, ease);\n}\n\n.panel-nav__item:hover::after { background: var(--_nav-hover); transition: none; }\n.panel-nav__item:active::after { background: var(--_nav-pressed); transition: none; }\n.panel-nav__item:focus-visible { outline: none; }\n.panel-nav__item:focus-visible::after {\n outline: var(--dimension-stroke-width-025, 2px) solid var(--_nav-focus);\n outline-offset: calc(-1 * var(--dimension-stroke-width-025, 2px));\n}\n\n/* ── Active item ─────────────────────────────────────────────────────────── */\n\n.panel-nav__item--active {\n color: var(--_nav-fg-primary);\n /* Bold typography via ds-text (text-body-medium-emphasis) on the label */\n}\n\n/* ── Item icon ───────────────────────────────────────────────────────────── */\n\n.panel-nav__item-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: var(--dimension-iconography-md, 20px);\n height: var(--dimension-iconography-md, 20px);\n position: relative;\n}\n\n/* ── Item label ──────────────────────────────────────────────────────────── */\n\n.panel-nav__item-label {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n min-width: 0;\n height: var(--typography-lineheight-md, 20px);\n line-height: var(--typography-lineheight-md, 20px);\n opacity: 1;\n /* Gradient wipe: mask sweeps left-to-right on expand, right-to-left on collapse */\n mask-image: linear-gradient(to right, black 50%, transparent 100%);\n -webkit-mask-image: linear-gradient(to right, black 50%, transparent 100%);\n mask-size: 200% 100%;\n -webkit-mask-size: 200% 100%;\n mask-position: 0% 0;\n -webkit-mask-position: 0% 0;\n transition:\n opacity var(--_nav-label-fade-motion) 0ms,\n mask-position var(--_nav-label-fade-motion) 0ms,\n -webkit-mask-position var(--_nav-label-fade-motion) 0ms;\n}\n\n.panel-nav__item-label-text {\n padding: 0 var(--dimension-space-025, 2px);\n}\n\n/* ── Item notification dot — single element, moves between positions ──────── */\n\n.panel-nav__item-dot {\n position: absolute;\n right: 13px;\n top: 13px;\n width: var(--dimension-space-075, 6px);\n height: var(--dimension-space-075, 6px);\n border-radius: var(--dimension-radius-full, 999px);\n background: var(--_nav-dot);\n box-shadow: 0 0 0 var(--dimension-stroke-width-018, 1.5px) var(--_nav-bg);\n pointer-events: none;\n transition:\n right var(--_nav-expand-motion),\n top var(--_nav-expand-motion),\n background var(--effect-motion-short-3, 200ms ease),\n box-shadow var(--effect-motion-short-3, 200ms ease);\n}\n\n.panel-nav--collapsed .panel-nav__item-dot {\n right: 6px;\n top: 6px;\n}\n\n.panel-nav--animating .panel-nav__item-label {\n text-overflow: clip;\n}\n\n.panel-nav--collapsed .panel-nav__item-label {\n opacity: 0;\n pointer-events: none;\n text-overflow: clip;\n mask-position: 100% 0;\n -webkit-mask-position: 100% 0;\n transition:\n opacity var(--_nav-label-fade-out-motion) 0ms,\n mask-position var(--_nav-label-fade-out-motion) 0ms,\n -webkit-mask-position var(--_nav-label-fade-out-motion) 0ms;\n}\n\n.panel-nav--collapsed .panel-nav__group-label {\n opacity: 0;\n max-height: 0;\n margin-bottom: 0;\n pointer-events: none;\n transition:\n opacity var(--_nav-label-fade-out-motion) 0ms,\n max-height var(--_nav-label-fade-out-motion) 0ms,\n margin-bottom var(--_nav-label-fade-out-motion) 0ms,\n color var(--effect-motion-short-3, 200ms ease);\n}\n\n/* ── Footer ──────────────────────────────────────────────────────────────── */\n\n.panel-nav__footer {\n position: relative;\n flex-shrink: 0;\n /* single row: padding*2 + item */\n height: calc(var(--_nav-padding-y) * 2 + var(--_nav-item-height));\n transition: height var(--_nav-expand-motion);\n}\n\n.panel-nav--collapsed .panel-nav__footer {\n /* two rows: padding*2 + item*2 + gap */\n height: calc(var(--_nav-padding-y) * 2 + var(--_nav-item-height) * 2 + var(--dimension-space-050, 4px));\n}\n\n/* Gradient fade — floats above the footer, masks content scrolling under it */\n.panel-nav__footer::before {\n content: '';\n position: absolute;\n bottom: 100%;\n left: 0;\n right: 0;\n height: calc(var(--dimension-base, 8px) * 6);\n background: linear-gradient(to bottom, transparent, var(--_nav-bg));\n pointer-events: none;\n opacity: 1;\n transition: opacity var(--effect-animation-duration-short-3, 200ms) var(--effect-animation-easing-ease-out, ease);\n}\n\n.panel-nav--at-bottom .panel-nav__footer::before {\n opacity: 0;\n}\n\n/* ── Footer icon button (gear / dashboard) ───────────────────────────────── */\n\n.panel-nav__footer-btn {\n all: unset;\n display: flex;\n align-items: center;\n justify-content: center;\n position: absolute;\n left: var(--_nav-padding-x);\n top: var(--_nav-padding-y);\n padding: var(--dimension-space-075, 6px);\n border-radius: var(--dimension-radius-half, 9999px);\n cursor: pointer;\n color: var(--_nav-fg-secondary);\n box-sizing: border-box;\n background: transparent;\n transition:\n background var(--effect-animation-duration-short-3, 200ms) var(--effect-animation-easing-ease-out, ease),\n color var(--effect-animation-duration-short-3, 200ms) var(--effect-animation-easing-ease-out, ease);\n}\n\n.panel-nav__footer-btn:focus-visible {\n outline: var(--dimension-stroke-width-025, 2px) solid var(--_nav-focus);\n outline-offset: calc(-1 * var(--dimension-stroke-width-025, 2px));\n}\n\n/* Dashboard: hover previews settings surface */\n.panel-nav--dashboard .panel-nav__footer-btn:hover {\n background: var(--color-background-secondary);\n color: var(--color-foreground-secondary);\n transition: none;\n}\n\n/* Settings: hover previews dashboard nav surface */\n.panel-nav--settings .panel-nav__footer-btn:hover {\n background: var(--color-navigation-background);\n color: var(--color-navigation-foreground-secondary);\n transition: none;\n}\n\n/* ── Footer user — absolutely positioned, slides from row to below gear ───── */\n\n.panel-nav__footer-user {\n position: absolute;\n /* row position: right of gear button */\n left: calc(var(--_nav-padding-x) + var(--_nav-footer-btn-w) + var(--dimension-space-050, 4px));\n right: var(--_nav-padding-x);\n top: var(--_nav-padding-y);\n width: auto;\n min-width: 0;\n transition:\n left var(--_nav-expand-motion),\n right var(--_nav-expand-motion),\n top var(--_nav-expand-motion),\n color var(--effect-motion-short-3, 200ms ease);\n}\n\n.panel-nav--collapsed .panel-nav__footer-user {\n /* column position: full-width row below gear */\n left: var(--_nav-padding-x);\n right: var(--_nav-padding-x);\n top: calc(var(--_nav-padding-y) + var(--_nav-item-height) + var(--dimension-space-050, 4px));\n}\n\n/* Label: absolute so it stays in place and only fades — no mask slide */\n.panel-nav__footer-user-label {\n text-align: right;\n position: absolute;\n left: var(--dimension-space-075, 6px);\n right: calc(var(--dimension-space-075, 6px) + var(--dimension-iconography-md, 20px) + var(--dimension-space-050, 4px));\n top: 50%;\n transform: translateY(-50%);\n flex: none;\n height: var(--typography-lineheight-md, 20px);\n mask-image: none;\n -webkit-mask-image: none;\n transition: opacity var(--_nav-label-fade-motion);\n}\n\n.panel-nav--collapsed .panel-nav__footer-user-label {\n opacity: 0;\n pointer-events: none;\n mask-position: 0% 0;\n -webkit-mask-position: 0% 0;\n}\n\n/* ── Footer user icon — cross-fades chevron ↔ circle+initial ────────────── */\n\n/* Absolute — right-anchored in expanded, left-anchored in collapsed to match regular item icon position */\n.panel-nav__footer-user-icon {\n position: absolute;\n left: calc(100% - var(--dimension-iconography-md, 20px) - var(--dimension-space-075, 6px));\n top: 0;\n bottom: 0;\n height: auto;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: left var(--_nav-expand-motion);\n}\n\n.panel-nav--collapsed .panel-nav__footer-user-icon {\n left: var(--dimension-space-075, 6px);\n}\n\n.panel-nav__footer-icon-expanded,\n.panel-nav__footer-icon-collapsed {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.panel-nav__footer-icon-expanded {\n opacity: 1;\n transition: opacity var(--_nav-label-fade-motion);\n}\n\n.panel-nav__footer-icon-collapsed {\n opacity: 0;\n transition: opacity var(--_nav-label-fade-motion);\n}\n\n.panel-nav--collapsed .panel-nav__footer-icon-expanded {\n opacity: 0;\n transition: opacity var(--_nav-label-fade-out-motion);\n}\n\n.panel-nav--collapsed .panel-nav__footer-icon-collapsed {\n opacity: 1;\n transition: opacity var(--_nav-label-fade-out-motion);\n}\n\n/* ── User initial — overlaid on the circle icon ─────────────────────────── */\n\n.panel-nav__user-initial {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--_nav-fg-secondary);\n text-transform: uppercase;\n line-height: 1;\n pointer-events: none;\n transition: color var(--effect-motion-short-3, 200ms ease);\n}\n\n/* ── Drag-to-resize handle ───────────────────────────────────────────────── */\n\n.panel-nav__resize-handle {\n position: absolute;\n top: 0;\n /* Centered on the right edge: --dimension-space-050 outside + inside = --dimension-space-100 hit zone */\n right: var(--dimension-space-n050, -4px);\n bottom: 0;\n width: var(--dimension-space-100, 8px);\n z-index: 10;\n cursor: ew-resize;\n touch-action: none;\n /* Needs a real background for Safari hit-testing */\n background: transparent;\n}\n\n/* Safari requires non-transparent fill for hit testing */\n.panel-nav__resize-handle::before {\n content: '';\n position: absolute;\n inset: 0;\n background: rgba(0, 0, 0, 0.001);\n}\n\n/* The brand-bold overlay line */\n.panel-nav__resize-handle::after {\n content: '';\n position: absolute;\n top: 0;\n bottom: 0;\n left: 50%;\n transform: translateX(-50%);\n width: var(--dimension-stroke-width-025, 2px);\n background: var(--color-background-bold-brand);\n opacity: 0;\n pointer-events: none;\n transition: opacity var(--effect-motion-short-2, 100ms ease-in-out);\n}\n\n.panel-nav__resize-handle--overlay::after {\n opacity: 1;\n}\n\n/* ── Reduced motion ──────────────────────────────────────────────────────── */\n\n@media (prefers-reduced-motion: reduce) {\n .panel-nav,\n .panel-nav *,\n .panel-nav *::before,\n .panel-nav *::after,\n .panel-nav__resize-handle,\n .panel-nav__resize-handle::before,\n .panel-nav__resize-handle::after {\n transition-duration: 0.01ms !important;\n animation-duration: 0.01ms !important;\n transition-delay: 0.01ms !important;\n }\n}\n","import { Component, Prop, Event, EventEmitter, Watch, State, Element, h, Host } from '@stencil/core';\n\nexport type PanelNavVariant = 'dashboard' | 'settings';\n\nexport interface PanelNavItem {\n id: string;\n icon: string;\n label: string;\n /** Show a notification dot badge on the item */\n dot?: boolean;\n flag?: boolean;\n /** When set, the item renders as an `<a>` element so any router that\n * intercepts anchor clicks (Angular Router, React Router, etc.) handles\n * navigation automatically. `dsNavSelect` still fires on click. */\n href?: string;\n}\n\nexport interface PanelNavGroup {\n id?: string;\n label?: string;\n items: PanelNavItem[];\n}\n\n@Component({\n tag: 'ds-panel-nav',\n styleUrl: 'PanelNav.css',\n scoped: true,\n})\nexport class PanelNav {\n /** Visual variant: `dashboard` = always-dark surface, `settings` = light surface */\n @Prop() variant: PanelNavVariant = 'dashboard';\n\n /** JSON string of `PanelNavGroup[]` */\n @Prop() groups: string = '[]';\n\n /** ID of the currently active/selected nav item. Overridden by `currentUrl` matching when set. */\n @Prop() activeId: string = '';\n\n /** Whether the nav is in collapsed (icon-only) state.\n * When `storageKey` is set the component manages this internally —\n * do not also bind it from outside in that mode. */\n @Prop({ mutable: true }) collapsed: boolean = false;\n\n /** Viewport width (px) below which the nav auto-collapses to icon-only mode. 0 = disabled. */\n @Prop() breakpoint: number = 0;\n\n /** `localStorage` key used to persist the collapsed state across page loads.\n * When set the component is self-managing for collapsed state; `dsNavToggle`\n * still fires for consumers that want to observe the change. */\n @Prop() storageKey: string = '';\n\n /** Current route URL (e.g. `window.location.pathname` or the router's active URL).\n * When set the component derives the active item by matching item `href` values\n * against this string (longest prefix wins), overriding `activeId`. */\n @Prop() currentUrl: string = '';\n\n /** Display name for the footer user section */\n @Prop() userName: string = '';\n\n /** Single character shown in the collapsed avatar */\n @Prop() userInitial: string = '';\n\n /** Emitted when a nav item is clicked. Detail = the item's `id`. */\n @Event() dsNavSelect!: EventEmitter<string>;\n\n /** Emitted when the collapse toggle is clicked. Detail = new collapsed state. */\n @Event() dsNavToggle!: EventEmitter<boolean>;\n\n /** Emitted when the footer left button (gear / dashboard) is clicked. */\n @Event() dsNavFooterAction!: EventEmitter<void>;\n\n @Element() el!: HTMLElement;\n\n @State() private parsedGroups: PanelNavGroup[] = [];\n @State() private atBottom = false;\n @State() private isAnimating = false;\n @State() private rovingIndex: number = 0;\n @State() private viewportNarrow: boolean = false;\n @State() private urlDerivedActiveId: string = '';\n\n private transitionEndHandler?: (e: TransitionEvent) => void;\n private resizeObserver?: ResizeObserver;\n\n // Drag-to-resize state (not @State — no re-render needed)\n private isDragging = false;\n private dragStartX = 0;\n private didSnap = false;\n private lastDeltaX = 0;\n private edgeOverlayTimer: number | null = null;\n private globalMouseMoveHandler?: (e: MouseEvent) => void;\n private globalMouseUpHandler?: () => void;\n\n @State() private showEdgeOverlay = false;\n\n /** The ID that should be treated as active. `currentUrl` matching takes precedence\n * over `activeId` when both are present. */\n private get effectiveActiveId(): string {\n return this.urlDerivedActiveId || this.activeId;\n }\n\n @Watch('collapsed')\n @Watch('viewportNarrow')\n onCollapsedChange() {\n this.startCollapseAnimation();\n }\n\n @Watch('breakpoint')\n onBreakpointChange() {\n this.disconnectResizeObserver();\n if (this.breakpoint > 0) this.connectResizeObserver();\n }\n\n @Watch('groups')\n onGroupsChange(val: string) {\n try {\n this.parsedGroups = JSON.parse(val);\n } catch {\n this.parsedGroups = [];\n }\n this.syncRovingIndex();\n }\n\n @Watch('activeId')\n @Watch('urlDerivedActiveId')\n onActiveIdChange() {\n this.syncRovingIndex();\n }\n\n @Watch('currentUrl')\n onCurrentUrlChange() {\n this.syncActiveFromUrl();\n }\n\n componentWillLoad() {\n if (this.storageKey) {\n try {\n const stored = localStorage.getItem(this.storageKey);\n if (stored !== null) this.collapsed = stored === 'true';\n } catch { /* localStorage unavailable */ }\n }\n this.onGroupsChange(this.groups);\n this.syncActiveFromUrl();\n }\n\n componentDidLoad() {\n this.checkScroll();\n if (this.breakpoint > 0) this.connectResizeObserver();\n // Re-sync groups in case componentWillLoad ran before host bindings were applied\n // (common with Angular's property binding timing)\n this.onGroupsChange(this.groups);\n }\n\n disconnectedCallback() {\n this.disconnectResizeObserver();\n this.clearEdgeOverlayTimer();\n if (this.globalMouseMoveHandler) {\n window.removeEventListener('mousemove', this.globalMouseMoveHandler);\n }\n if (this.globalMouseUpHandler) {\n window.removeEventListener('mouseup', this.globalMouseUpHandler);\n }\n }\n\n private startCollapseAnimation() {\n this.isAnimating = true;\n const panel = this.el.querySelector('.panel-nav') as HTMLElement | null;\n if (this.transitionEndHandler) {\n panel?.removeEventListener('transitionend', this.transitionEndHandler);\n }\n this.transitionEndHandler = (e: TransitionEvent) => {\n if (e.propertyName === 'width') {\n this.isAnimating = false;\n panel?.removeEventListener('transitionend', this.transitionEndHandler!);\n }\n };\n panel?.addEventListener('transitionend', this.transitionEndHandler);\n }\n\n private connectResizeObserver() {\n this.viewportNarrow = window.innerWidth < this.breakpoint;\n this.resizeObserver = new ResizeObserver(() => {\n this.viewportNarrow = window.innerWidth < this.breakpoint;\n });\n this.resizeObserver.observe(document.documentElement);\n }\n\n private disconnectResizeObserver() {\n this.resizeObserver?.disconnect();\n this.resizeObserver = undefined;\n }\n\n /** Derive active ID from the current URL by matching item `href` values.\n * Uses longest-prefix match so `/fleet/detail` correctly activates `/fleet`. */\n private syncActiveFromUrl() {\n if (!this.currentUrl) {\n this.urlDerivedActiveId = '';\n return;\n }\n let best: PanelNavItem | undefined;\n let bestLen = 0;\n for (const item of this.getAllItems()) {\n if (item.href && this.currentUrl.startsWith(item.href) && item.href.length > bestLen) {\n best = item;\n bestLen = item.href.length;\n }\n }\n this.urlDerivedActiveId = best?.id ?? '';\n }\n\n /** Centralised toggle: always emits `dsNavToggle`; when `storageKey` is set\n * also mutates `collapsed` directly and persists to `localStorage`. */\n private applyToggle(next: boolean) {\n this.dsNavToggle.emit(next);\n if (this.storageKey) {\n this.collapsed = next;\n try { localStorage.setItem(this.storageKey, String(next)); } catch { /* unavailable */ }\n }\n }\n\n private getAllItems(): PanelNavItem[] {\n return this.parsedGroups.flatMap(g => g.items);\n }\n\n private syncRovingIndex() {\n const idx = this.getAllItems().findIndex(i => i.id === this.effectiveActiveId);\n this.rovingIndex = idx >= 0 ? idx : 0;\n }\n\n private handleItemKeyDown(e: KeyboardEvent, index: number) {\n const total = this.getAllItems().length;\n let next = index;\n switch (e.key) {\n case 'ArrowDown': e.preventDefault(); next = (index + 1) % total; break;\n case 'ArrowUp': e.preventDefault(); next = (index - 1 + total) % total; break;\n case 'Home': e.preventDefault(); next = 0; break;\n case 'End': e.preventDefault(); next = total - 1; break;\n default: return;\n }\n this.rovingIndex = next;\n const items = Array.from(\n this.el.querySelectorAll<HTMLElement>('.panel-nav__body .panel-nav__item')\n );\n items[next]?.focus();\n }\n\n private checkScroll() {\n const body = this.el.querySelector('.panel-nav__body') as HTMLElement | null;\n if (!body) return;\n const remaining = body.scrollHeight - body.scrollTop - body.clientHeight;\n this.atBottom = remaining < 2;\n }\n\n private handleBodyScroll(e: Event) {\n const body = e.target as HTMLElement;\n const remaining = body.scrollHeight - body.scrollTop - body.clientHeight;\n this.atBottom = remaining < 2;\n }\n\n private handleItemClick(id: string) {\n this.dsNavSelect.emit(id);\n }\n\n private handleToggle() {\n this.applyToggle(!this.collapsed);\n }\n\n private handleFooterAction() {\n this.dsNavFooterAction.emit();\n }\n\n private clearEdgeOverlayTimer() {\n if (this.edgeOverlayTimer !== null) {\n window.clearTimeout(this.edgeOverlayTimer);\n this.edgeOverlayTimer = null;\n }\n }\n\n private handleResizeHandleMouseEnter() {\n this.clearEdgeOverlayTimer();\n this.edgeOverlayTimer = window.setTimeout(() => {\n this.showEdgeOverlay = true;\n this.edgeOverlayTimer = null;\n }, 500);\n }\n\n private handleResizeHandleMouseLeave() {\n if (this.isDragging) return;\n this.clearEdgeOverlayTimer();\n this.showEdgeOverlay = false;\n }\n\n private handleResizeHandleMouseDown(e: MouseEvent) {\n e.preventDefault();\n e.stopPropagation();\n\n const wasCollapsed = this.collapsed || this.viewportNarrow;\n this.isDragging = true;\n this.dragStartX = e.clientX;\n this.didSnap = false;\n this.lastDeltaX = 0;\n this.clearEdgeOverlayTimer();\n this.showEdgeOverlay = false;\n\n document.body.style.cursor = 'ew-resize';\n document.body.style.userSelect = 'none';\n\n const onMove = (ev: MouseEvent) => {\n const deltaX = ev.clientX - this.dragStartX;\n this.lastDeltaX = Math.abs(deltaX);\n if (this.didSnap) return;\n if (!wasCollapsed && deltaX < -8) {\n this.applyToggle(true);\n this.didSnap = true;\n } else if (wasCollapsed && deltaX > 8) {\n this.applyToggle(false);\n this.didSnap = true;\n }\n };\n\n const onUp = () => {\n if (!this.didSnap && this.lastDeltaX < 3) {\n this.applyToggle(!wasCollapsed);\n }\n this.isDragging = false;\n this.showEdgeOverlay = false;\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n window.removeEventListener('mousemove', onMove);\n window.removeEventListener('mouseup', onUp);\n this.globalMouseMoveHandler = undefined;\n this.globalMouseUpHandler = undefined;\n };\n\n this.globalMouseMoveHandler = onMove;\n this.globalMouseUpHandler = onUp;\n window.addEventListener('mousemove', onMove);\n window.addEventListener('mouseup', onUp);\n }\n\n private renderNavItem(item: PanelNavItem, idx: number, collapsed: boolean) {\n const isActive = item.id === this.effectiveActiveId;\n\n const itemContent = [\n <span class=\"panel-nav__item-icon\">\n <ds-icon name={item.icon} size=\"md\" color=\"inherit\" flag={item.flag} />\n </span>,\n <span class=\"panel-nav__item-label\">\n <span class=\"panel-nav__item-label-text\">\n <ds-text\n as=\"span\"\n variant={isActive ? 'text-body-medium-emphasis' : 'text-body-medium'}\n color=\"inherit\"\n >\n {item.label}\n </ds-text>\n </span>\n </span>,\n item.dot && <span class=\"panel-nav__item-dot\" aria-hidden=\"true\" />,\n ];\n\n const sharedProps = {\n class: { 'panel-nav__item': true, 'panel-nav__item--active': isActive },\n 'aria-current': isActive ? ('page' as const) : undefined,\n title: collapsed ? item.label : undefined,\n tabIndex: idx === this.rovingIndex ? 0 : -1,\n onClick: () => this.handleItemClick(item.id),\n onKeyDown: (e: KeyboardEvent) => this.handleItemKeyDown(e, idx),\n onFocus: () => { this.rovingIndex = idx; },\n };\n\n return item.href\n ? <a {...sharedProps} href={item.href}>{itemContent}</a>\n : <button {...sharedProps} type=\"button\">{itemContent}</button>;\n }\n\n render() {\n const isDashboard = this.variant === 'dashboard';\n const collapsed = this.collapsed || this.viewportNarrow;\n const { userName, userInitial } = this;\n\n const navCls: Record<string, boolean> = {\n 'panel-nav': true,\n 'panel-nav--dashboard': isDashboard,\n 'panel-nav--settings': !isDashboard,\n 'panel-nav--collapsed': collapsed,\n 'panel-nav--animating': this.isAnimating,\n 'panel-nav--at-bottom': this.atBottom,\n };\n\n return (\n <Host style={{ display: 'block', position: 'relative' }}>\n <nav class={navCls} aria-label={isDashboard ? 'Main navigation' : 'Settings navigation'}>\n\n {/* ── Header: Motive logo, reveals collapse toggle on hover ── */}\n <div class=\"panel-nav__header\">\n <button\n type=\"button\"\n class=\"panel-nav__header-btn\"\n onClick={() => this.handleToggle()}\n aria-label={collapsed ? 'Expand navigation' : 'Collapse navigation'}\n aria-expanded={collapsed ? 'false' : 'true'}\n >\n {/* Motive M mark — fades out on hover to reveal collapse toggle */}\n <span class=\"panel-nav__header-logo\" aria-hidden=\"true\">\n <svg class=\"panel-nav__m-mark\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M11.1159 4.31537H7.67021L2.53401 13.0703H0V15.6875H4.02716L8.24319 8.49978V15.6846H11.6342L15.8289 8.47829V15.6846H18.7122V4.3125H15.2559L11.1159 11.3648V4.31537Z\" fill=\"currentColor\"/>\n </svg>\n </span>\n {/* Collapse / expand icon — revealed on hover via CSS */}\n <span class=\"panel-nav__header-toggle\" aria-hidden=\"true\">\n <ds-icon\n name={collapsed ? 'LeftExpandB' : 'LeftCollapseB'}\n size=\"md\"\n color=\"inherit\"\n />\n </span>\n </button>\n </div>\n\n {/* ── Scrollable body ── */}\n <div class=\"panel-nav__body\" onScroll={e => this.handleBodyScroll(e)}>\n {(() => {\n let flatIdx = 0;\n return this.parsedGroups.map(group => (\n <div class=\"panel-nav__group\">\n {group.label && (\n <span class=\"panel-nav__group-label\">\n <ds-text as=\"span\" variant=\"text-caption-emphasis\" color=\"inherit\">\n {group.label}\n </ds-text>\n </span>\n )}\n {group.items.map(item => this.renderNavItem(item, flatIdx++, collapsed))}\n </div>\n ));\n })()}\n </div>\n\n {/* ── Footer ── */}\n <div class=\"panel-nav__footer\">\n {/* Left icon button — Gear in dashboard, Dashboard in settings */}\n <button\n type=\"button\"\n class=\"panel-nav__footer-btn\"\n title={isDashboard ? 'Settings' : 'Dashboard'}\n aria-label={isDashboard ? 'Open settings' : 'Go to dashboard'}\n onClick={() => this.handleFooterAction()}\n >\n <ds-icon name={isDashboard ? 'Gear' : 'Dashboard'} size=\"md\" color=\"inherit\" />\n </button>\n\n {/* Right user — label fades like nav items; right icon cross-fades chevron ↔ circle+initial */}\n <button\n type=\"button\"\n class=\"panel-nav__item panel-nav__footer-user\"\n aria-label={collapsed ? `User: ${userName}` : `User menu for ${userName}`}\n >\n <span class=\"panel-nav__item-label panel-nav__footer-user-label\">\n <span class=\"panel-nav__item-label-text\">\n <ds-text as=\"span\" variant=\"text-body-medium-emphasis\" color=\"inherit\">\n {userName}\n </ds-text>\n </span>\n </span>\n <span class=\"panel-nav__item-icon panel-nav__footer-user-icon\" aria-hidden=\"true\">\n <span class=\"panel-nav__footer-icon-expanded\">\n <ds-icon name=\"ChevronUpDown\" size=\"md\" color=\"inherit\" />\n </span>\n <span class=\"panel-nav__footer-icon-collapsed\">\n <ds-icon name=\"Circle\" size=\"md\" color=\"inherit\" />\n <span class=\"panel-nav__user-initial\">\n <ds-text as=\"span\" variant=\"text-caption-emphasis\" color=\"inherit\">\n {userInitial}\n </ds-text>\n </span>\n </span>\n </span>\n </button>\n </div>\n\n </nav>\n\n {/* Drag-to-resize handle — always rendered, hidden only when auto-collapsed by breakpoint */}\n {!this.viewportNarrow && (\n <div\n class={{\n 'panel-nav__resize-handle': true,\n 'panel-nav__resize-handle--overlay': this.showEdgeOverlay,\n }}\n onMouseEnter={() => this.handleResizeHandleMouseEnter()}\n onMouseLeave={() => this.handleResizeHandleMouseLeave()}\n onMouseDown={(e: MouseEvent) => this.handleResizeHandleMouseDown(e)}\n aria-hidden=\"true\"\n />\n )}\n </Host>\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ds-mo/ui",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"description": "CompoMo — composable web components styled with TokoMo design tokens",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"web-components",
|
|
@@ -31,7 +31,8 @@
|
|
|
31
31
|
},
|
|
32
32
|
"./angular": {
|
|
33
33
|
"import": "./src/angular/index.ts"
|
|
34
|
-
}
|
|
34
|
+
},
|
|
35
|
+
"./dist/components/*": "./dist/components/*"
|
|
35
36
|
},
|
|
36
37
|
"files": [
|
|
37
38
|
"dist",
|