@ds-mo/ui 1.11.0 → 1.11.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.
- package/dist/.build-stamp +1 -1
- package/dist/components/ds-app-shell.js +1 -1
- package/dist/components/ds-app-shell.js.map +1 -1
- package/dist/components/ds-bar-nav.js +1 -1
- package/dist/components/ds-bar-nav.js.map +1 -1
- package/dist/components/ds-panel-tools.js +1 -1
- package/dist/components/ds-panel-tools.js.map +1 -1
- package/dist/components/p-1HlgCxGN.js +2 -0
- package/dist/components/p-1HlgCxGN.js.map +1 -0
- package/dist/types/components/AppShell/AppShell.d.ts +2 -2
- package/dist/types/components/BarNav/BarNav.d.ts +2 -2
- package/dist/types/components/PanelTools/panel-tools-utils.d.ts +3 -0
- package/dist/types/nav/chrome-transition.d.ts +14 -0
- package/dist/types/nav/index.d.ts +1 -1
- package/package.json +2 -2
- package/src/wc/components/AppShell/AppShell.tsx +19 -26
- package/src/wc/components/BarNav/BarNav.tsx +18 -19
- package/src/wc/components/PanelTools/PanelTools.tsx +3 -1
- package/src/wc/components/PanelTools/panel-tools-utils.ts +7 -0
- package/src/wc/nav/chrome-transition.ts +46 -0
- package/src/wc/nav/index.ts +3 -0
- package/dist/components/p-DN65lYYc.js +0 -2
- package/dist/components/p-DN65lYYc.js.map +0 -1
package/dist/.build-stamp
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
1783098911712
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{p as s,H as e,h as l,a
|
|
1
|
+
import{p as s,H as e,h as l,a,t}from"./index.js";import{C as i,c as h,r as n,a as r,b as o,d as p,i as c,p as d}from"./p-1HlgCxGN.js";const g="--ds-shell-gradient-image";const f="--ds-shell-gradient-size";const u="--ds-shell-gradient-position-panel";const b="--ds-shell-gradient-position-bar";const _="--ds-shell-gradient-opacity";const m="0.1";const v="100% 100% at 0% 0%";function y(){return`radial-gradient(${v}, var(--color-background-transparent) 0%, var(--color-color-intent-blue-strong-background) 100%)`}function x(s){return`${Math.round(s.width)}px ${Math.round(s.height)}px`}function k(){return"0 0"}function w(s){return`${-Math.round(s)}px 0`}const S=()=>`.sc-ds-app-shell-h{display:block;height:100%;min-height:0;box-sizing:border-box}.app-shell.sc-ds-app-shell{display:flex;flex-direction:column;height:100%;min-height:0;box-sizing:border-box;font-family:var(--typography-font-family, system-ui)}.app-shell--gradient.sc-ds-app-shell-h,.app-shell--grid.sc-ds-app-shell-h{--_shell-chrome-bg:var(--color-background-secondary)}.app-shell--grid.sc-ds-app-shell-h{--_shell-chrome-grid-cell:var(--dimension-size-050);--_shell-chrome-grid-stroke:var(--dimension-stroke-width-012);--_shell-chrome-grid-line:var(--color-foreground-quaternary);--_shell-chrome-grid-opacity:0.1}.app-shell__row.sc-ds-app-shell{display:flex;flex:1 1 auto;min-height:0;height:100%;position:relative}.app-shell__chrome.sc-ds-app-shell{position:absolute;inset:0;pointer-events:none;z-index:0}.app-shell--gradient.sc-ds-app-shell-h .app-shell__chrome.sc-ds-app-shell,.app-shell--grid.sc-ds-app-shell-h .app-shell__chrome.sc-ds-app-shell{background-color:var(--_shell-chrome-bg)}.app-shell--gradient.sc-ds-app-shell-h .app-shell__chrome.sc-ds-app-shell::before,.app-shell--grid.sc-ds-app-shell-h .app-shell__chrome.sc-ds-app-shell::after{content:'';position:absolute;inset:0;pointer-events:none;background-position:0 0;background-attachment:fixed}.app-shell--gradient.sc-ds-app-shell-h .app-shell__chrome.sc-ds-app-shell::before{z-index:1;opacity:var(--ds-shell-gradient-opacity, 1);background-image:var(--ds-shell-gradient-image, none);background-size:var(--ds-shell-gradient-size, auto);background-repeat:no-repeat}.app-shell--grid.sc-ds-app-shell-h .app-shell__chrome.sc-ds-app-shell::after{z-index:2;opacity:var(--_shell-chrome-grid-opacity);background-image:repeating-linear-gradient( 120deg, var(--_shell-chrome-grid-line) 0, var(--_shell-chrome-grid-line) var(--_shell-chrome-grid-stroke), transparent var(--_shell-chrome-grid-stroke), transparent var(--_shell-chrome-grid-cell) )}.app-shell__panel.sc-ds-app-shell{flex:0 0 auto;min-height:0;height:100%;position:relative;z-index:2}.app-shell__panel.sc-ds-app-shell-s>ds-panel-nav,.app-shell__panel .sc-ds-app-shell-s>ds-panel-nav{display:block;height:100%}.app-shell__main.sc-ds-app-shell{flex:1 1 auto;min-width:0;min-height:0;display:flex;flex-direction:row;position:relative;z-index:1}.app-shell__stack.sc-ds-app-shell{flex:1 1 auto;min-width:0;min-height:0;display:flex;flex-direction:column;position:relative;z-index:1;overflow:hidden}.app-shell__bar.sc-ds-app-shell{flex:0 0 auto}.app-shell__bar.sc-ds-app-shell-s>ds-bar-nav,.app-shell__bar .sc-ds-app-shell-s>ds-bar-nav{display:block}.app-shell__content.sc-ds-app-shell{flex:1 1 auto;min-width:0;min-height:0;overflow:auto;contain:layout}.app-shell--gradient.sc-ds-app-shell-h .app-shell__content.sc-ds-app-shell,.app-shell--grid.sc-ds-app-shell-h .app-shell__content.sc-ds-app-shell{position:relative;z-index:1;background-color:var(--color-background-primary)}.app-shell__tools.sc-ds-app-shell{flex:0 0 auto;min-width:0;min-height:0;height:100%;display:flex;position:relative;z-index:0;overflow:hidden}.app-shell__tools.sc-ds-app-shell-s>ds-panel-tools,.app-shell__tools .sc-ds-app-shell-s>ds-panel-tools{display:block;height:100%;min-height:0}`;const z=s(class s extends e{constructor(s){super();if(s!==false){this.__registerHost()}this.navStyle="dashboard";this.gradient=false;this.grid=false;this.gradientSrc="";this.resizeObserver=null;this.panelNavTransition=new i;this.chromeSyncCoalescer=h((()=>this.syncChrome()));this.panelWidthTokens={expandedPx:0,collapsedPx:0};this.cachedShellWidth=0;this.cachedShellHeight=0;this.onChromeTransitionStart=s=>{if(n(s)!=="panel-nav")return;this.panelNavTransition.enter();this.cachedShellWidth=this.el.clientWidth;this.cachedShellHeight=this.el.clientHeight;this.syncChrome()};this.onChromeTransitionEnd=s=>{if(n(s)!=="panel-nav")return;this.panelNavTransition.exit();if(!this.panelNavTransition.isActive){this.scheduleChromeSync()}}}componentDidLoad(){this.syncSlottedNavStyle();this.connectMetricsObserver();this.el.addEventListener(r,this.onChromeTransitionStart);this.el.addEventListener(o,this.onChromeTransitionEnd);requestAnimationFrame((()=>{this.cachePanelWidthTokens();this.scheduleChromeSync()}))}disconnectedCallback(){this.resizeObserver?.disconnect();this.resizeObserver=null;this.chromeSyncCoalescer.cancel();this.el.removeEventListener(r,this.onChromeTransitionStart);this.el.removeEventListener(o,this.onChromeTransitionEnd)}onShellPropsChange(){this.syncSlottedNavStyle();this.scheduleChromeSync()}scheduleChromeSync(){this.chromeSyncCoalescer.schedule()}syncSlottedNavStyle(){const s=this.el.querySelector("ds-panel-nav");const e=this.el.querySelector("ds-bar-nav");if(s){s.setAttribute("nav-style",this.navStyle);s.navStyle=this.navStyle}if(e){e.setAttribute("nav-style",this.navStyle);e.navStyle=this.navStyle}}connectMetricsObserver(){this.resizeObserver=new ResizeObserver((()=>{if(this.panelNavTransition.isActive)return;this.scheduleChromeSync()}));this.resizeObserver.observe(this.el);const s=this.el.querySelector(".app-shell__panel");if(s)this.resizeObserver.observe(s)}cachePanelWidthTokens(){const s=this.el.querySelector("ds-panel-nav .panel-nav");if(!s)return;this.panelWidthTokens=p(s)}applyGradientVars(s,e){const l=s.style;for(const[s,a]of Object.entries(e)){if(a===null)l.removeProperty(s);else l.setProperty(s,a)}}clearGradientPaintVars(s){const e=[g,f,_];for(const l of s){for(const s of e)l.style.removeProperty(s)}}syncChromeLayoutVars(s,e,l,a){if(s){s.style.setProperty(u,l)}if(e){e.style.setProperty(b,a)}}resolvePanelWidthPx(s){const e=s?.querySelector(".panel-nav");if(this.panelNavTransition.isActive&&this.panelWidthTokens.expandedPx>0){const l=c(s,e);return d(this.panelWidthTokens,l)}const l=this.el.querySelector(".app-shell__panel");const a=l?.getBoundingClientRect().width??0;if(a>0)return a;if(this.panelWidthTokens.expandedPx>0){const l=c(s,e);return d(this.panelWidthTokens,l)}return 0}resolveShellDimensions(){if(this.panelNavTransition.isActive&&this.cachedShellWidth>0){return{width:this.cachedShellWidth,height:this.cachedShellHeight||this.el.clientHeight}}const s=this.el.getBoundingClientRect();return{width:s.width,height:s.height}}chromeLayerActive(){return this.gradient||this.grid}syncChrome(){const s=this.el.querySelector("ds-panel-nav");const e=this.el.querySelector("ds-bar-nav");const l=[this.el,s,e].filter((s=>s!==null));const a=()=>{if(s)s.style.removeProperty(u);if(e)e.style.removeProperty(b)};if(!this.chromeLayerActive()){this.clearGradientPaintVars(l);a();return}if(!this.gradient){this.clearGradientPaintVars(l);a();return}const{width:t,height:i}=this.resolveShellDimensions();const h=this.resolvePanelWidthPx(s);const n=k();const r=w(h);this.syncChromeLayoutVars(s,e,n,r);const o=this.gradientSrc.trim()?`url(${this.gradientSrc.trim()})`:y();const p=x({width:t,height:i});const c=m;for(const s of l){if(s===this.el){this.applyGradientVars(s,{[g]:o,[f]:p,[u]:n,[b]:r,[_]:c});continue}const e=s.tagName.toLowerCase()==="ds-bar-nav";this.applyGradientVars(s,{[g]:o,[f]:p,[_]:c,[u]:e?null:n,[b]:e?r:null})}}render(){const s=this.chromeLayerActive();const e={"app-shell":true,"app-shell--gradient":this.gradient,"app-shell--grid":this.grid,[`app-shell--${this.navStyle}`]:true};return l(a,{key:"183ba2c84eef101dc97ab4c984706ebfb8ff5560",class:e},l("div",{key:"6adf1a1cb46c8ea00f8d8dae3b7eafb98edac96e",class:"app-shell__row"},s?l("div",{class:"app-shell__chrome","aria-hidden":"true"}):null,l("div",{key:"01965c0efee86071c9c76372dca36dedf7ff2aec",class:"app-shell__panel"},l("slot",{key:"902d010b5a28a3ad160de64b347b1e5cdd6d340d",name:"panel"})),l("div",{key:"c436b78badfe15f51fa0d13f02ce8ea9a22da067",class:"app-shell__main"},l("div",{key:"c34dbca002833e4502271f00b7cfccd19e9e81e9",class:"app-shell__stack"},l("div",{key:"496d4a058b5c4b86fb4d0ac5fa3be7f4d03b2532",class:"app-shell__bar"},l("slot",{key:"c2afdd14b2296fe7063756099a3917c8621219ec",name:"bar"})),l("div",{key:"cb82292d931c1a2f11ad425b62554841c273e712",class:"app-shell__content"},l("slot",{key:"8c233d03e4ab0f4ad0a9918063c625eafbd95d6a"}))),l("div",{key:"d0aa64ee14ec9f025905965f430b5d373b605eb1",class:"app-shell__tools"},l("slot",{key:"2690b487cd3cee46bdd8967dfa79e80b901d1021",name:"tools"})))))}get el(){return this}static get watchers(){return{navStyle:[{onShellPropsChange:0}],gradient:[{onShellPropsChange:0}],grid:[{onShellPropsChange:0}],gradientSrc:[{onShellPropsChange:0}]}}static get style(){return S()}},[262,"ds-app-shell",{navStyle:[513,"nav-style"],gradient:[516],grid:[516],gradientSrc:[1,"gradient-src"]},undefined,{navStyle:[{onShellPropsChange:0}],gradient:[{onShellPropsChange:0}],grid:[{onShellPropsChange:0}],gradientSrc:[{onShellPropsChange:0}]}]);function C(){if(typeof customElements==="undefined"){return}const s=["ds-app-shell"];s.forEach((s=>{switch(s){case"ds-app-shell":if(!customElements.get(t(s))){customElements.define(t(s),z)}break}}))}C();const P=z;const $=C;export{P as DsAppShell,$ as defineCustomElement};
|
|
2
2
|
//# sourceMappingURL=ds-app-shell.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["SHELL_GRADIENT_IMAGE_VAR","SHELL_GRADIENT_SIZE_VAR","SHELL_GRADIENT_POSITION_PANEL_VAR","SHELL_GRADIENT_POSITION_BAR_VAR","SHELL_GRADIENT_OPACITY_VAR","SHELL_GRADIENT_OPACITY","GRADIENT_GEOMETRY","buildShellRadialGradient","shellGradientSize","layout","Math","round","width","height","shellGradientPositionPanel","shellGradientPositionBar","panelWidth","appShellCss","AppShell","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","navStyle","gradient","grid","gradientSrc","resizeObserver","chromeSyncRafId","chromeTransitionDepth","panelWidthTokens","expandedPx","collapsedPx","cachedShellWidth","cachedShellHeight","onChromeTransitionStart","event","source","detail","el","clientWidth","clientHeight","syncChrome","onChromeTransitionEnd","max","scheduleChromeSync","componentDidLoad","syncSlottedNavStyle","connectMetricsObserver","addEventListener","CHROME_TRANSITION_START","CHROME_TRANSITION_END","requestAnimationFrame","cachePanelWidthTokens","disconnectedCallback","disconnect","cancelAnimationFrame","removeEventListener","onShellPropsChange","panel","querySelector","bar","setAttribute","ResizeObserver","observe","panelWrap","navRoot","readPanelNavWidthTokens","applyGradientVars","target","vars","style","name","value","Object","entries","removeProperty","setProperty","clearGradientPaintVars","targets","keys","key","syncChromeLayoutVars","panelPosition","barPosition","resolvePanelWidthPx","panelNav","collapsed","isPanelNavCollapsed","panelWidthPxFromTokens","measured","getBoundingClientRect","resolveShellDimensions","rect","chromeLayerActive","filter","clearLayoutVars","shellWidth","shellHeight","image","trim","size","opacity","isBar","tagName","toLowerCase","render","chromeActive","shellCls","h","Host","class"],"sources":["src/wc/nav/shell-gradient.ts","src/wc/components/AppShell/AppShell.css?tag=ds-app-shell&encapsulation=scoped","src/wc/components/AppShell/AppShell.tsx"],"sourcesContent":["/** CSS var names consumed by `ds-panel-nav` / `ds-bar-nav` inside `ds-app-shell`. */\nexport const SHELL_GRADIENT_IMAGE_VAR = '--ds-shell-gradient-image';\nexport const SHELL_GRADIENT_SIZE_VAR = '--ds-shell-gradient-size';\nexport const SHELL_GRADIENT_POSITION_PANEL_VAR = '--ds-shell-gradient-position-panel';\nexport const SHELL_GRADIENT_POSITION_BAR_VAR = '--ds-shell-gradient-position-bar';\nexport const SHELL_GRADIENT_OPACITY_VAR = '--ds-shell-gradient-opacity';\n/** Per chrome-surface background-position — offsets wash + grid to shell row origin. */\nexport const SHELL_CHROME_SURFACE_POSITION_VAR = '--ds-shell-chrome-surface-position';\n\n/** Layer opacity for the nav gradient wash. */\nexport const SHELL_GRADIENT_OPACITY = '0.1';\n\n/** Whether the shared chrome layer (bg + optional wash/grid) should mount. */\nexport function shellChromeLayerActive(gradient: boolean, grid: boolean): boolean {\n return gradient || grid;\n}\n\nconst GRADIENT_GEOMETRY = '100% 100% at 0% 0%';\n\n/**\n * Shell radial wash — same for panel and bar nav.\n * Tokens follow `data-theme` (light/dark blue intent).\n */\nexport function buildShellRadialGradient(): string {\n return `radial-gradient(${GRADIENT_GEOMETRY}, var(--color-background-transparent) 0%, var(--color-color-intent-blue-strong-background) 100%)`;\n}\n\n/** Built-in radial image (optional `gradientSrc` on shell overrides). */\nexport function shellGradientImage(): string {\n return buildShellRadialGradient();\n}\n\nexport interface ShellGradientLayout {\n width: number;\n height: number;\n panelWidth: number;\n}\n\nexport function shellGradientSize(layout: ShellGradientLayout): string {\n return `${Math.round(layout.width)}px ${Math.round(layout.height)}px`;\n}\n\nexport function shellGradientPositionPanel(): string {\n return '0 0';\n}\n\nexport function shellGradientPositionBar(panelWidth: number): string {\n return `${-Math.round(panelWidth)}px 0`;\n}\n\n/** Phase-lock a chrome rect to the shell row coordinate system (wash + grid). */\nexport function shellChromeSurfacePosition(leftPx: number, topPx: number): string {\n return `${-Math.round(leftPx)}px ${-Math.round(topPx)}px`;\n}\n",":host {\n display: block;\n height: 100%;\n min-height: 0;\n box-sizing: border-box;\n}\n\n.app-shell {\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 0;\n box-sizing: border-box;\n font-family: var(--typography-font-family, system-ui);\n}\n\n:host(.app-shell--gradient),\n:host(.app-shell--grid) {\n --_shell-chrome-bg: var(--color-background-secondary);\n}\n\n:host(.app-shell--grid) {\n --_shell-chrome-grid-cell: var(--dimension-size-050);\n --_shell-chrome-grid-stroke: var(--dimension-stroke-width-012);\n --_shell-chrome-grid-line: var(--color-foreground-quaternary);\n --_shell-chrome-grid-opacity: 0.1;\n}\n\n.app-shell__row {\n display: flex;\n flex: 1 1 auto;\n min-height: 0;\n height: 100%;\n position: relative;\n}\n\n/*\n * One chrome layer behind the shell row. Wash + grid use background-attachment: fixed\n * so the pattern is locked to the viewport — panel/tools collapse only changes the\n * transparent window, not the pattern phase.\n */\n.app-shell__chrome {\n position: absolute;\n inset: 0;\n pointer-events: none;\n z-index: 0;\n}\n\n:host(.app-shell--gradient) .app-shell__chrome,\n:host(.app-shell--grid) .app-shell__chrome {\n background-color: var(--_shell-chrome-bg);\n}\n\n/* Layer stack (bottom → top): bg → wash (::before) → grid (::after) */\n:host(.app-shell--gradient) .app-shell__chrome::before,\n:host(.app-shell--grid) .app-shell__chrome::after {\n content: '';\n position: absolute;\n inset: 0;\n pointer-events: none;\n background-position: 0 0;\n background-attachment: fixed;\n}\n\n:host(.app-shell--gradient) .app-shell__chrome::before {\n z-index: 1;\n opacity: var(--ds-shell-gradient-opacity, 1);\n background-image: var(--ds-shell-gradient-image, none);\n background-size: var(--ds-shell-gradient-size, auto);\n background-repeat: no-repeat;\n}\n\n:host(.app-shell--grid) .app-shell__chrome::after {\n z-index: 2;\n opacity: var(--_shell-chrome-grid-opacity);\n background-image: repeating-linear-gradient(\n 120deg,\n var(--_shell-chrome-grid-line) 0,\n var(--_shell-chrome-grid-line) var(--_shell-chrome-grid-stroke),\n transparent var(--_shell-chrome-grid-stroke),\n transparent var(--_shell-chrome-grid-cell)\n );\n}\n\n.app-shell__panel {\n flex: 0 0 auto;\n min-height: 0;\n height: 100%;\n position: relative;\n /* Above main so resize handle line can paint over the workspace edge */\n z-index: 2;\n}\n\n.app-shell__panel ::slotted(ds-panel-nav) {\n display: block;\n height: 100%;\n}\n\n.app-shell__main {\n flex: 1 1 auto;\n min-width: 0;\n min-height: 0;\n display: flex;\n flex-direction: row;\n position: relative;\n z-index: 1;\n}\n\n.app-shell__stack {\n flex: 1 1 auto;\n min-width: 0;\n min-height: 0;\n display: flex;\n flex-direction: column;\n position: relative;\n z-index: 1;\n overflow: hidden;\n}\n\n.app-shell__bar {\n flex: 0 0 auto;\n}\n\n.app-shell__bar ::slotted(ds-bar-nav) {\n display: block;\n}\n\n.app-shell__content {\n flex: 1 1 auto;\n min-width: 0;\n min-height: 0;\n overflow: auto;\n /* Limit reflow to the page column — not on __main (breaks tools flex shrink). */\n contain: layout;\n}\n\n/* Opaque page surface — masks the fixed chrome layer in the content column. */\n:host(.app-shell--gradient) .app-shell__content,\n:host(.app-shell--grid) .app-shell__content {\n position: relative;\n z-index: 1;\n background-color: var(--color-background-primary);\n}\n\n.app-shell__tools {\n flex: 0 0 auto;\n min-width: 0;\n min-height: 0;\n height: 100%;\n display: flex;\n position: relative;\n z-index: 0;\n overflow: hidden;\n}\n\n.app-shell__tools ::slotted(ds-panel-tools) {\n display: block;\n height: 100%;\n min-height: 0;\n}\n","import { Component, Prop, Element, Watch, h, Host } from '@stencil/core';\nimport type { NavChromeStyle } from '../../nav/nav-chrome';\nimport {\n CHROME_TRANSITION_END,\n CHROME_TRANSITION_START,\n type ChromeTransitionDetail,\n} from '../../nav/chrome-transition';\nimport {\n isPanelNavCollapsed,\n panelWidthPxFromTokens,\n readPanelNavWidthTokens,\n type PanelNavWidthTokens,\n} from '../../nav/shell-chrome-metrics';\nimport {\n SHELL_GRADIENT_IMAGE_VAR,\n SHELL_GRADIENT_OPACITY,\n SHELL_GRADIENT_OPACITY_VAR,\n SHELL_GRADIENT_POSITION_BAR_VAR,\n SHELL_GRADIENT_POSITION_PANEL_VAR,\n SHELL_GRADIENT_SIZE_VAR,\n buildShellRadialGradient,\n shellGradientPositionBar,\n shellGradientPositionPanel,\n shellGradientSize,\n} from '../../nav/shell-gradient';\n\n@Component({\n tag: 'ds-app-shell',\n styleUrl: 'AppShell.css',\n scoped: true,\n})\nexport class AppShell {\n /** Chrome style propagated to slotted `ds-panel-nav` and `ds-bar-nav`. */\n @Prop({ attribute: 'nav-style', reflect: true }) navStyle: NavChromeStyle = 'dashboard';\n\n /** When `true`, paints the radial wash behind panel, bar, and tools (synced to shell layout). */\n @Prop({ reflect: true }) gradient: boolean = false;\n\n /** When `true`, paints the diagonal grid overlay on the shared chrome layer. Independent of `gradient`. */\n @Prop({ reflect: true }) grid: boolean = false;\n\n /**\n * Optional custom gradient for `background-image` (e.g. SVG URL).\n * When set, overrides the built-in radial wash.\n */\n @Prop() gradientSrc: string = '';\n\n @Element() el!: HTMLElement;\n\n private resizeObserver: ResizeObserver | null = null;\n private chromeSyncRafId = 0;\n private chromeTransitionDepth = 0;\n private panelWidthTokens: PanelNavWidthTokens = { expandedPx: 0, collapsedPx: 0 };\n private cachedShellWidth = 0;\n private cachedShellHeight = 0;\n\n componentDidLoad() {\n this.syncSlottedNavStyle();\n this.connectMetricsObserver();\n this.el.addEventListener(CHROME_TRANSITION_START, this.onChromeTransitionStart);\n this.el.addEventListener(CHROME_TRANSITION_END, this.onChromeTransitionEnd);\n requestAnimationFrame(() => {\n this.cachePanelWidthTokens();\n this.scheduleChromeSync();\n });\n }\n\n disconnectedCallback() {\n this.resizeObserver?.disconnect();\n this.resizeObserver = null;\n if (this.chromeSyncRafId) {\n cancelAnimationFrame(this.chromeSyncRafId);\n this.chromeSyncRafId = 0;\n }\n this.el.removeEventListener(CHROME_TRANSITION_START, this.onChromeTransitionStart);\n this.el.removeEventListener(CHROME_TRANSITION_END, this.onChromeTransitionEnd);\n }\n\n @Watch('navStyle')\n @Watch('gradient')\n @Watch('grid')\n @Watch('gradientSrc')\n onShellPropsChange() {\n this.syncSlottedNavStyle();\n this.scheduleChromeSync();\n }\n\n private onChromeTransitionStart = (event: Event) => {\n const source = (event as CustomEvent<ChromeTransitionDetail>).detail?.source;\n if (source === 'panel-nav') {\n this.chromeTransitionDepth += 1;\n this.cachedShellWidth = this.el.clientWidth;\n this.cachedShellHeight = this.el.clientHeight;\n this.syncChrome();\n }\n };\n\n private onChromeTransitionEnd = (event: Event) => {\n const source = (event as CustomEvent<ChromeTransitionDetail>).detail?.source;\n if (source !== 'panel-nav') return;\n\n this.chromeTransitionDepth = Math.max(0, this.chromeTransitionDepth - 1);\n if (this.chromeTransitionDepth === 0) {\n this.scheduleChromeSync();\n }\n };\n\n /** Coalesce ResizeObserver bursts to one layout read per frame. */\n private scheduleChromeSync() {\n if (this.chromeSyncRafId) return;\n this.chromeSyncRafId = requestAnimationFrame(() => {\n this.chromeSyncRafId = 0;\n this.syncChrome();\n });\n }\n\n private syncSlottedNavStyle() {\n const panel = this.el.querySelector('ds-panel-nav') as (HTMLElement & { navStyle: NavChromeStyle }) | null;\n const bar = this.el.querySelector('ds-bar-nav') as (HTMLElement & { navStyle: NavChromeStyle }) | null;\n if (panel) {\n panel.setAttribute('nav-style', this.navStyle);\n panel.navStyle = this.navStyle;\n }\n if (bar) {\n bar.setAttribute('nav-style', this.navStyle);\n bar.navStyle = this.navStyle;\n }\n }\n\n private connectMetricsObserver() {\n this.resizeObserver = new ResizeObserver(() => {\n if (this.chromeTransitionDepth > 0) return;\n this.scheduleChromeSync();\n });\n this.resizeObserver.observe(this.el);\n const panelWrap = this.el.querySelector('.app-shell__panel');\n if (panelWrap) this.resizeObserver.observe(panelWrap);\n }\n\n private cachePanelWidthTokens() {\n const navRoot = this.el.querySelector('ds-panel-nav .panel-nav') as HTMLElement | null;\n if (!navRoot) return;\n this.panelWidthTokens = readPanelNavWidthTokens(navRoot);\n }\n\n private applyGradientVars(target: HTMLElement, vars: Record<string, string | null>) {\n const style = target.style;\n for (const [name, value] of Object.entries(vars)) {\n if (value === null) style.removeProperty(name);\n else style.setProperty(name, value);\n }\n }\n\n private clearGradientPaintVars(targets: HTMLElement[]) {\n const keys = [\n SHELL_GRADIENT_IMAGE_VAR,\n SHELL_GRADIENT_SIZE_VAR,\n SHELL_GRADIENT_OPACITY_VAR,\n ];\n for (const target of targets) {\n for (const key of keys) target.style.removeProperty(key);\n }\n }\n\n /** Panel/bar wash offsets for scroll fades and badge rings. */\n private syncChromeLayoutVars(\n panel: HTMLElement | null,\n bar: HTMLElement | null,\n panelPosition: string,\n barPosition: string,\n ) {\n if (panel) {\n panel.style.setProperty(SHELL_GRADIENT_POSITION_PANEL_VAR, panelPosition);\n }\n if (bar) {\n bar.style.setProperty(SHELL_GRADIENT_POSITION_BAR_VAR, barPosition);\n }\n }\n\n private resolvePanelWidthPx(panelNav: HTMLElement | null): number {\n const navRoot = panelNav?.querySelector('.panel-nav') as HTMLElement | null;\n\n if (this.chromeTransitionDepth > 0 && this.panelWidthTokens.expandedPx > 0) {\n const collapsed = isPanelNavCollapsed(panelNav, navRoot);\n return panelWidthPxFromTokens(this.panelWidthTokens, collapsed);\n }\n\n const panelWrap = this.el.querySelector('.app-shell__panel') as HTMLElement | null;\n const measured = panelWrap?.getBoundingClientRect().width ?? 0;\n if (measured > 0) return measured;\n\n if (this.panelWidthTokens.expandedPx > 0) {\n const collapsed = isPanelNavCollapsed(panelNav, navRoot);\n return panelWidthPxFromTokens(this.panelWidthTokens, collapsed);\n }\n\n return 0;\n }\n\n private resolveShellDimensions(): { width: number; height: number } {\n if (this.chromeTransitionDepth > 0 && this.cachedShellWidth > 0) {\n return {\n width: this.cachedShellWidth,\n height: this.cachedShellHeight || this.el.clientHeight,\n };\n }\n\n const rect = this.el.getBoundingClientRect();\n return { width: rect.width, height: rect.height };\n }\n\n private chromeLayerActive(): boolean {\n return this.gradient || this.grid;\n }\n\n private syncChrome() {\n const panelNav = this.el.querySelector('ds-panel-nav') as HTMLElement | null;\n const bar = this.el.querySelector('ds-bar-nav') as HTMLElement | null;\n const targets = [this.el, panelNav, bar].filter((el): el is HTMLElement => el !== null);\n\n const clearLayoutVars = () => {\n if (panelNav) panelNav.style.removeProperty(SHELL_GRADIENT_POSITION_PANEL_VAR);\n if (bar) bar.style.removeProperty(SHELL_GRADIENT_POSITION_BAR_VAR);\n };\n\n if (!this.chromeLayerActive()) {\n this.clearGradientPaintVars(targets);\n clearLayoutVars();\n return;\n }\n\n if (!this.gradient) {\n this.clearGradientPaintVars(targets);\n clearLayoutVars();\n return;\n }\n\n const { width: shellWidth, height: shellHeight } = this.resolveShellDimensions();\n const panelWidth = this.resolvePanelWidthPx(panelNav);\n\n const panelPosition = shellGradientPositionPanel();\n const barPosition = shellGradientPositionBar(panelWidth);\n\n this.syncChromeLayoutVars(panelNav, bar, panelPosition, barPosition);\n\n const image = this.gradientSrc.trim()\n ? `url(${this.gradientSrc.trim()})`\n : buildShellRadialGradient();\n\n const size = shellGradientSize({\n width: shellWidth,\n height: shellHeight,\n panelWidth,\n });\n const opacity = SHELL_GRADIENT_OPACITY;\n\n for (const target of targets) {\n if (target === this.el) {\n this.applyGradientVars(target, {\n [SHELL_GRADIENT_IMAGE_VAR]: image,\n [SHELL_GRADIENT_SIZE_VAR]: size,\n [SHELL_GRADIENT_POSITION_PANEL_VAR]: panelPosition,\n [SHELL_GRADIENT_POSITION_BAR_VAR]: barPosition,\n [SHELL_GRADIENT_OPACITY_VAR]: opacity,\n });\n continue;\n }\n\n const isBar = target.tagName.toLowerCase() === 'ds-bar-nav';\n this.applyGradientVars(target, {\n [SHELL_GRADIENT_IMAGE_VAR]: image,\n [SHELL_GRADIENT_SIZE_VAR]: size,\n [SHELL_GRADIENT_OPACITY_VAR]: opacity,\n [SHELL_GRADIENT_POSITION_PANEL_VAR]: isBar ? null : panelPosition,\n [SHELL_GRADIENT_POSITION_BAR_VAR]: isBar ? barPosition : null,\n });\n }\n }\n\n render() {\n const chromeActive = this.chromeLayerActive();\n const shellCls: Record<string, boolean> = {\n 'app-shell': true,\n 'app-shell--gradient': this.gradient,\n 'app-shell--grid': this.grid,\n [`app-shell--${this.navStyle}`]: true,\n };\n\n return (\n <Host class={shellCls}>\n <div class=\"app-shell__row\">\n {chromeActive ? <div class=\"app-shell__chrome\" aria-hidden=\"true\" /> : null}\n <div class=\"app-shell__panel\">\n <slot name=\"panel\" />\n </div>\n <div class=\"app-shell__main\">\n <div class=\"app-shell__stack\">\n <div class=\"app-shell__bar\">\n <slot name=\"bar\" />\n </div>\n <div class=\"app-shell__content\">\n <slot />\n </div>\n </div>\n <div class=\"app-shell__tools\">\n <slot name=\"tools\" />\n </div>\n </div>\n </div>\n </Host>\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["SHELL_GRADIENT_IMAGE_VAR","SHELL_GRADIENT_SIZE_VAR","SHELL_GRADIENT_POSITION_PANEL_VAR","SHELL_GRADIENT_POSITION_BAR_VAR","SHELL_GRADIENT_OPACITY_VAR","SHELL_GRADIENT_OPACITY","GRADIENT_GEOMETRY","buildShellRadialGradient","shellGradientSize","layout","Math","round","width","height","shellGradientPositionPanel","shellGradientPositionBar","panelWidth","appShellCss","AppShell","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","navStyle","gradient","grid","gradientSrc","resizeObserver","panelNavTransition","ChromeTransitionDepth","chromeSyncCoalescer","createRafCoalescer","syncChrome","panelWidthTokens","expandedPx","collapsedPx","cachedShellWidth","cachedShellHeight","onChromeTransitionStart","event","readChromeTransitionSource","enter","el","clientWidth","clientHeight","onChromeTransitionEnd","exit","isActive","scheduleChromeSync","componentDidLoad","syncSlottedNavStyle","connectMetricsObserver","addEventListener","CHROME_TRANSITION_START","CHROME_TRANSITION_END","requestAnimationFrame","cachePanelWidthTokens","disconnectedCallback","disconnect","cancel","removeEventListener","onShellPropsChange","schedule","panel","querySelector","bar","setAttribute","ResizeObserver","observe","panelWrap","navRoot","readPanelNavWidthTokens","applyGradientVars","target","vars","style","name","value","Object","entries","removeProperty","setProperty","clearGradientPaintVars","targets","keys","key","syncChromeLayoutVars","panelPosition","barPosition","resolvePanelWidthPx","panelNav","collapsed","isPanelNavCollapsed","panelWidthPxFromTokens","measured","getBoundingClientRect","resolveShellDimensions","rect","chromeLayerActive","filter","clearLayoutVars","shellWidth","shellHeight","image","trim","size","opacity","isBar","tagName","toLowerCase","render","chromeActive","shellCls","h","Host","class"],"sources":["src/wc/nav/shell-gradient.ts","src/wc/components/AppShell/AppShell.css?tag=ds-app-shell&encapsulation=scoped","src/wc/components/AppShell/AppShell.tsx"],"sourcesContent":["/** CSS var names consumed by `ds-panel-nav` / `ds-bar-nav` inside `ds-app-shell`. */\nexport const SHELL_GRADIENT_IMAGE_VAR = '--ds-shell-gradient-image';\nexport const SHELL_GRADIENT_SIZE_VAR = '--ds-shell-gradient-size';\nexport const SHELL_GRADIENT_POSITION_PANEL_VAR = '--ds-shell-gradient-position-panel';\nexport const SHELL_GRADIENT_POSITION_BAR_VAR = '--ds-shell-gradient-position-bar';\nexport const SHELL_GRADIENT_OPACITY_VAR = '--ds-shell-gradient-opacity';\n/** Per chrome-surface background-position — offsets wash + grid to shell row origin. */\nexport const SHELL_CHROME_SURFACE_POSITION_VAR = '--ds-shell-chrome-surface-position';\n\n/** Layer opacity for the nav gradient wash. */\nexport const SHELL_GRADIENT_OPACITY = '0.1';\n\n/** Whether the shared chrome layer (bg + optional wash/grid) should mount. */\nexport function shellChromeLayerActive(gradient: boolean, grid: boolean): boolean {\n return gradient || grid;\n}\n\nconst GRADIENT_GEOMETRY = '100% 100% at 0% 0%';\n\n/**\n * Shell radial wash — same for panel and bar nav.\n * Tokens follow `data-theme` (light/dark blue intent).\n */\nexport function buildShellRadialGradient(): string {\n return `radial-gradient(${GRADIENT_GEOMETRY}, var(--color-background-transparent) 0%, var(--color-color-intent-blue-strong-background) 100%)`;\n}\n\n/** Built-in radial image (optional `gradientSrc` on shell overrides). */\nexport function shellGradientImage(): string {\n return buildShellRadialGradient();\n}\n\nexport interface ShellGradientLayout {\n width: number;\n height: number;\n panelWidth: number;\n}\n\nexport function shellGradientSize(layout: ShellGradientLayout): string {\n return `${Math.round(layout.width)}px ${Math.round(layout.height)}px`;\n}\n\nexport function shellGradientPositionPanel(): string {\n return '0 0';\n}\n\nexport function shellGradientPositionBar(panelWidth: number): string {\n return `${-Math.round(panelWidth)}px 0`;\n}\n\n/** Phase-lock a chrome rect to the shell row coordinate system (wash + grid). */\nexport function shellChromeSurfacePosition(leftPx: number, topPx: number): string {\n return `${-Math.round(leftPx)}px ${-Math.round(topPx)}px`;\n}\n",":host {\n display: block;\n height: 100%;\n min-height: 0;\n box-sizing: border-box;\n}\n\n.app-shell {\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 0;\n box-sizing: border-box;\n font-family: var(--typography-font-family, system-ui);\n}\n\n:host(.app-shell--gradient),\n:host(.app-shell--grid) {\n --_shell-chrome-bg: var(--color-background-secondary);\n}\n\n:host(.app-shell--grid) {\n --_shell-chrome-grid-cell: var(--dimension-size-050);\n --_shell-chrome-grid-stroke: var(--dimension-stroke-width-012);\n --_shell-chrome-grid-line: var(--color-foreground-quaternary);\n --_shell-chrome-grid-opacity: 0.1;\n}\n\n.app-shell__row {\n display: flex;\n flex: 1 1 auto;\n min-height: 0;\n height: 100%;\n position: relative;\n}\n\n/*\n * One chrome layer behind the shell row. Wash + grid use background-attachment: fixed\n * so the pattern is locked to the viewport — panel/tools collapse only changes the\n * transparent window, not the pattern phase.\n */\n.app-shell__chrome {\n position: absolute;\n inset: 0;\n pointer-events: none;\n z-index: 0;\n}\n\n:host(.app-shell--gradient) .app-shell__chrome,\n:host(.app-shell--grid) .app-shell__chrome {\n background-color: var(--_shell-chrome-bg);\n}\n\n/* Layer stack (bottom → top): bg → wash (::before) → grid (::after) */\n:host(.app-shell--gradient) .app-shell__chrome::before,\n:host(.app-shell--grid) .app-shell__chrome::after {\n content: '';\n position: absolute;\n inset: 0;\n pointer-events: none;\n background-position: 0 0;\n background-attachment: fixed;\n}\n\n:host(.app-shell--gradient) .app-shell__chrome::before {\n z-index: 1;\n opacity: var(--ds-shell-gradient-opacity, 1);\n background-image: var(--ds-shell-gradient-image, none);\n background-size: var(--ds-shell-gradient-size, auto);\n background-repeat: no-repeat;\n}\n\n:host(.app-shell--grid) .app-shell__chrome::after {\n z-index: 2;\n opacity: var(--_shell-chrome-grid-opacity);\n background-image: repeating-linear-gradient(\n 120deg,\n var(--_shell-chrome-grid-line) 0,\n var(--_shell-chrome-grid-line) var(--_shell-chrome-grid-stroke),\n transparent var(--_shell-chrome-grid-stroke),\n transparent var(--_shell-chrome-grid-cell)\n );\n}\n\n.app-shell__panel {\n flex: 0 0 auto;\n min-height: 0;\n height: 100%;\n position: relative;\n /* Above main so resize handle line can paint over the workspace edge */\n z-index: 2;\n}\n\n.app-shell__panel ::slotted(ds-panel-nav) {\n display: block;\n height: 100%;\n}\n\n.app-shell__main {\n flex: 1 1 auto;\n min-width: 0;\n min-height: 0;\n display: flex;\n flex-direction: row;\n position: relative;\n z-index: 1;\n}\n\n.app-shell__stack {\n flex: 1 1 auto;\n min-width: 0;\n min-height: 0;\n display: flex;\n flex-direction: column;\n position: relative;\n z-index: 1;\n overflow: hidden;\n}\n\n.app-shell__bar {\n flex: 0 0 auto;\n}\n\n.app-shell__bar ::slotted(ds-bar-nav) {\n display: block;\n}\n\n.app-shell__content {\n flex: 1 1 auto;\n min-width: 0;\n min-height: 0;\n overflow: auto;\n /* Limit reflow to the page column — not on __main (breaks tools flex shrink). */\n contain: layout;\n}\n\n/* Opaque page surface — masks the fixed chrome layer in the content column. */\n:host(.app-shell--gradient) .app-shell__content,\n:host(.app-shell--grid) .app-shell__content {\n position: relative;\n z-index: 1;\n background-color: var(--color-background-primary);\n}\n\n.app-shell__tools {\n flex: 0 0 auto;\n min-width: 0;\n min-height: 0;\n height: 100%;\n display: flex;\n position: relative;\n z-index: 0;\n overflow: hidden;\n}\n\n.app-shell__tools ::slotted(ds-panel-tools) {\n display: block;\n height: 100%;\n min-height: 0;\n}\n","import { Component, Prop, Element, Watch, h, Host } from '@stencil/core';\nimport type { NavChromeStyle } from '../../nav/nav-chrome';\nimport {\n CHROME_TRANSITION_END,\n CHROME_TRANSITION_START,\n ChromeTransitionDepth,\n createRafCoalescer,\n readChromeTransitionSource,\n} from '../../nav/chrome-transition';\nimport {\n isPanelNavCollapsed,\n panelWidthPxFromTokens,\n readPanelNavWidthTokens,\n type PanelNavWidthTokens,\n} from '../../nav/shell-chrome-metrics';\nimport {\n SHELL_GRADIENT_IMAGE_VAR,\n SHELL_GRADIENT_OPACITY,\n SHELL_GRADIENT_OPACITY_VAR,\n SHELL_GRADIENT_POSITION_BAR_VAR,\n SHELL_GRADIENT_POSITION_PANEL_VAR,\n SHELL_GRADIENT_SIZE_VAR,\n buildShellRadialGradient,\n shellGradientPositionBar,\n shellGradientPositionPanel,\n shellGradientSize,\n} from '../../nav/shell-gradient';\n\n@Component({\n tag: 'ds-app-shell',\n styleUrl: 'AppShell.css',\n scoped: true,\n})\nexport class AppShell {\n /** Chrome style propagated to slotted `ds-panel-nav` and `ds-bar-nav`. */\n @Prop({ attribute: 'nav-style', reflect: true }) navStyle: NavChromeStyle = 'dashboard';\n\n /** When `true`, paints the radial wash behind panel, bar, and tools (synced to shell layout). */\n @Prop({ reflect: true }) gradient: boolean = false;\n\n /** When `true`, paints the diagonal grid overlay on the shared chrome layer. Independent of `gradient`. */\n @Prop({ reflect: true }) grid: boolean = false;\n\n /**\n * Optional custom gradient for `background-image` (e.g. SVG URL).\n * When set, overrides the built-in radial wash.\n */\n @Prop() gradientSrc: string = '';\n\n @Element() el!: HTMLElement;\n\n private resizeObserver: ResizeObserver | null = null;\n private readonly panelNavTransition = new ChromeTransitionDepth();\n private readonly chromeSyncCoalescer = createRafCoalescer(() => this.syncChrome());\n private panelWidthTokens: PanelNavWidthTokens = { expandedPx: 0, collapsedPx: 0 };\n private cachedShellWidth = 0;\n private cachedShellHeight = 0;\n\n componentDidLoad() {\n this.syncSlottedNavStyle();\n this.connectMetricsObserver();\n this.el.addEventListener(CHROME_TRANSITION_START, this.onChromeTransitionStart);\n this.el.addEventListener(CHROME_TRANSITION_END, this.onChromeTransitionEnd);\n requestAnimationFrame(() => {\n this.cachePanelWidthTokens();\n this.scheduleChromeSync();\n });\n }\n\n disconnectedCallback() {\n this.resizeObserver?.disconnect();\n this.resizeObserver = null;\n this.chromeSyncCoalescer.cancel();\n this.el.removeEventListener(CHROME_TRANSITION_START, this.onChromeTransitionStart);\n this.el.removeEventListener(CHROME_TRANSITION_END, this.onChromeTransitionEnd);\n }\n\n @Watch('navStyle')\n @Watch('gradient')\n @Watch('grid')\n @Watch('gradientSrc')\n onShellPropsChange() {\n this.syncSlottedNavStyle();\n this.scheduleChromeSync();\n }\n\n private onChromeTransitionStart = (event: Event) => {\n if (readChromeTransitionSource(event) !== 'panel-nav') return;\n\n this.panelNavTransition.enter();\n this.cachedShellWidth = this.el.clientWidth;\n this.cachedShellHeight = this.el.clientHeight;\n this.syncChrome();\n };\n\n private onChromeTransitionEnd = (event: Event) => {\n if (readChromeTransitionSource(event) !== 'panel-nav') return;\n\n this.panelNavTransition.exit();\n if (!this.panelNavTransition.isActive) {\n this.scheduleChromeSync();\n }\n };\n\n /** Coalesce ResizeObserver bursts to one layout read per frame. */\n private scheduleChromeSync() {\n this.chromeSyncCoalescer.schedule();\n }\n\n private syncSlottedNavStyle() {\n const panel = this.el.querySelector('ds-panel-nav') as (HTMLElement & { navStyle: NavChromeStyle }) | null;\n const bar = this.el.querySelector('ds-bar-nav') as (HTMLElement & { navStyle: NavChromeStyle }) | null;\n if (panel) {\n panel.setAttribute('nav-style', this.navStyle);\n panel.navStyle = this.navStyle;\n }\n if (bar) {\n bar.setAttribute('nav-style', this.navStyle);\n bar.navStyle = this.navStyle;\n }\n }\n\n private connectMetricsObserver() {\n this.resizeObserver = new ResizeObserver(() => {\n if (this.panelNavTransition.isActive) return;\n this.scheduleChromeSync();\n });\n this.resizeObserver.observe(this.el);\n const panelWrap = this.el.querySelector('.app-shell__panel');\n if (panelWrap) this.resizeObserver.observe(panelWrap);\n }\n\n private cachePanelWidthTokens() {\n const navRoot = this.el.querySelector('ds-panel-nav .panel-nav') as HTMLElement | null;\n if (!navRoot) return;\n this.panelWidthTokens = readPanelNavWidthTokens(navRoot);\n }\n\n private applyGradientVars(target: HTMLElement, vars: Record<string, string | null>) {\n const style = target.style;\n for (const [name, value] of Object.entries(vars)) {\n if (value === null) style.removeProperty(name);\n else style.setProperty(name, value);\n }\n }\n\n private clearGradientPaintVars(targets: HTMLElement[]) {\n const keys = [\n SHELL_GRADIENT_IMAGE_VAR,\n SHELL_GRADIENT_SIZE_VAR,\n SHELL_GRADIENT_OPACITY_VAR,\n ];\n for (const target of targets) {\n for (const key of keys) target.style.removeProperty(key);\n }\n }\n\n /** Panel/bar wash offsets for scroll fades and badge rings. */\n private syncChromeLayoutVars(\n panel: HTMLElement | null,\n bar: HTMLElement | null,\n panelPosition: string,\n barPosition: string,\n ) {\n if (panel) {\n panel.style.setProperty(SHELL_GRADIENT_POSITION_PANEL_VAR, panelPosition);\n }\n if (bar) {\n bar.style.setProperty(SHELL_GRADIENT_POSITION_BAR_VAR, barPosition);\n }\n }\n\n private resolvePanelWidthPx(panelNav: HTMLElement | null): number {\n const navRoot = panelNav?.querySelector('.panel-nav') as HTMLElement | null;\n\n if (this.panelNavTransition.isActive && this.panelWidthTokens.expandedPx > 0) {\n const collapsed = isPanelNavCollapsed(panelNav, navRoot);\n return panelWidthPxFromTokens(this.panelWidthTokens, collapsed);\n }\n\n const panelWrap = this.el.querySelector('.app-shell__panel') as HTMLElement | null;\n const measured = panelWrap?.getBoundingClientRect().width ?? 0;\n if (measured > 0) return measured;\n\n if (this.panelWidthTokens.expandedPx > 0) {\n const collapsed = isPanelNavCollapsed(panelNav, navRoot);\n return panelWidthPxFromTokens(this.panelWidthTokens, collapsed);\n }\n\n return 0;\n }\n\n private resolveShellDimensions(): { width: number; height: number } {\n if (this.panelNavTransition.isActive && this.cachedShellWidth > 0) {\n return {\n width: this.cachedShellWidth,\n height: this.cachedShellHeight || this.el.clientHeight,\n };\n }\n\n const rect = this.el.getBoundingClientRect();\n return { width: rect.width, height: rect.height };\n }\n\n private chromeLayerActive(): boolean {\n return this.gradient || this.grid;\n }\n\n private syncChrome() {\n const panelNav = this.el.querySelector('ds-panel-nav') as HTMLElement | null;\n const bar = this.el.querySelector('ds-bar-nav') as HTMLElement | null;\n const targets = [this.el, panelNav, bar].filter((el): el is HTMLElement => el !== null);\n\n const clearLayoutVars = () => {\n if (panelNav) panelNav.style.removeProperty(SHELL_GRADIENT_POSITION_PANEL_VAR);\n if (bar) bar.style.removeProperty(SHELL_GRADIENT_POSITION_BAR_VAR);\n };\n\n if (!this.chromeLayerActive()) {\n this.clearGradientPaintVars(targets);\n clearLayoutVars();\n return;\n }\n\n if (!this.gradient) {\n this.clearGradientPaintVars(targets);\n clearLayoutVars();\n return;\n }\n\n const { width: shellWidth, height: shellHeight } = this.resolveShellDimensions();\n const panelWidth = this.resolvePanelWidthPx(panelNav);\n\n const panelPosition = shellGradientPositionPanel();\n const barPosition = shellGradientPositionBar(panelWidth);\n\n this.syncChromeLayoutVars(panelNav, bar, panelPosition, barPosition);\n\n const image = this.gradientSrc.trim()\n ? `url(${this.gradientSrc.trim()})`\n : buildShellRadialGradient();\n\n const size = shellGradientSize({\n width: shellWidth,\n height: shellHeight,\n panelWidth,\n });\n const opacity = SHELL_GRADIENT_OPACITY;\n\n for (const target of targets) {\n if (target === this.el) {\n this.applyGradientVars(target, {\n [SHELL_GRADIENT_IMAGE_VAR]: image,\n [SHELL_GRADIENT_SIZE_VAR]: size,\n [SHELL_GRADIENT_POSITION_PANEL_VAR]: panelPosition,\n [SHELL_GRADIENT_POSITION_BAR_VAR]: barPosition,\n [SHELL_GRADIENT_OPACITY_VAR]: opacity,\n });\n continue;\n }\n\n const isBar = target.tagName.toLowerCase() === 'ds-bar-nav';\n this.applyGradientVars(target, {\n [SHELL_GRADIENT_IMAGE_VAR]: image,\n [SHELL_GRADIENT_SIZE_VAR]: size,\n [SHELL_GRADIENT_OPACITY_VAR]: opacity,\n [SHELL_GRADIENT_POSITION_PANEL_VAR]: isBar ? null : panelPosition,\n [SHELL_GRADIENT_POSITION_BAR_VAR]: isBar ? barPosition : null,\n });\n }\n }\n\n render() {\n const chromeActive = this.chromeLayerActive();\n const shellCls: Record<string, boolean> = {\n 'app-shell': true,\n 'app-shell--gradient': this.gradient,\n 'app-shell--grid': this.grid,\n [`app-shell--${this.navStyle}`]: true,\n };\n\n return (\n <Host class={shellCls}>\n <div class=\"app-shell__row\">\n {chromeActive ? <div class=\"app-shell__chrome\" aria-hidden=\"true\" /> : null}\n <div class=\"app-shell__panel\">\n <slot name=\"panel\" />\n </div>\n <div class=\"app-shell__main\">\n <div class=\"app-shell__stack\">\n <div class=\"app-shell__bar\">\n <slot name=\"bar\" />\n </div>\n <div class=\"app-shell__content\">\n <slot />\n </div>\n </div>\n <div class=\"app-shell__tools\">\n <slot name=\"tools\" />\n </div>\n </div>\n </div>\n </Host>\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{p as s,H as t,c as e,h as a,a as i,t as n}from"./index.js";import{s as r,p as o,d as h}from"./p-Dl1GvZQ2.js";import{g as d,i as l}from"./p-BQq26pt9.js";import{C as b,a as c,b as v}from"./p-DN65lYYc.js";import{d as f}from"./p-CiEc8Nwx.js";import{d as u}from"./p-CCZFMcLe.js";import{d as p}from"./p-DqBCQRRd.js";import{d as g}from"./p-CuuuDjJJ.js";import{d as m}from"./p-DlsexsFg.js";function _(s,t){if(!s)return null;const e=s.shadowRoot??s;return e.querySelector(t)}function y(s){return _(s,'[role="tablist"]')}function w(s,t){const e=[];let a=[];for(const i of s){if(l(i)){if(a.length>0){e.push({items:a});a=[]}continue}a.push({label:i.label,value:i.id,isSelected:i.id===t,isInactive:i.disabled})}if(a.length>0){e.push({items:a})}return e}function k(s,t){const e=d(s);return e.find((s=>s.id===t))??e[0]}function x(s,t){return k(s,t)?.label??"Tabs"}function C(s,t,e,a=2){const i=s-t;if(e){return i>-a}return i>a}const z=()=>`.sc-ds-bar-nav-h{display:block}.bar-nav.sc-ds-bar-nav{display:flex;align-items:center;position:relative;height:var(--dimension-size-600);padding:var(--dimension-space-100);gap:var(--dimension-space-100);box-sizing:border-box;border-bottom:var(--dimension-stroke-width-012) solid var(--_bar-nav-border);background-color:var(--_bar-nav-bg);color:var(--_bar-nav-fg-primary);-webkit-user-select:none;user-select:none;overflow:hidden;transition:background-color var(--effect-motion-short-3), border-color var(--effect-motion-short-3), color var(--effect-motion-short-3);isolation:isolate;--_bar-nav-bg:var(--color-background-secondary);--_bar-nav-border:var(--color-border-tertiary);--_bar-nav-fg-primary:var(--color-foreground-primary);--_bar-nav-fg-secondary:var(--color-foreground-secondary);--_bar-nav-hover:var(--color-interaction-hover);--_bar-nav-pressed:var(--color-interaction-pressed);--_bar-nav-focus:var(--color-interaction-focus);--_bar-nav-dot:var(--color-foreground-bold-brand)}.bar-nav--dashboard.sc-ds-bar-nav,.bar-nav--settings.sc-ds-bar-nav{--_bar-nav-bg:var(--color-background-secondary);--_bar-nav-border:var(--color-border-tertiary);--_bar-nav-fg-primary:var(--color-foreground-primary);--_bar-nav-fg-secondary:var(--color-foreground-secondary);--_bar-nav-hover:var(--color-interaction-hover);--_bar-nav-pressed:var(--color-interaction-pressed);--_bar-nav-focus:var(--color-interaction-focus);--_bar-nav-dot:var(--color-foreground-bold-brand)}ds-app-shell[gradient].sc-ds-bar-nav-h .bar-nav.sc-ds-bar-nav,ds-app-shell[gradient] .sc-ds-bar-nav-h .bar-nav.sc-ds-bar-nav,ds-app-shell[grid].sc-ds-bar-nav-h .bar-nav.sc-ds-bar-nav,ds-app-shell[grid] .sc-ds-bar-nav-h .bar-nav.sc-ds-bar-nav{background-color:transparent}.bar-nav.sc-ds-bar-nav>.sc-ds-bar-nav:not(.bar-nav__tabs-probe){position:relative;z-index:3}.bar-nav--tabs-collapsed.sc-ds-bar-nav{display:flex;gap:0;align-items:center}.bar-nav--tabs-collapsed.sc-ds-bar-nav .bar-nav__tab-trigger.sc-ds-bar-nav{flex:0 1 auto;min-width:0;max-width:100%;width:auto;overflow:hidden}.bar-nav__between.sc-ds-bar-nav{flex:1 1 0%;min-width:var(--dimension-space-100)}.bar-nav--tabs-collapsed.sc-ds-bar-nav .bar-nav__tab-trigger-label.sc-ds-bar-nav{flex:1 1 0%;min-width:0}.bar-nav--tabs-collapsed.sc-ds-bar-nav .bar-nav__tab-trigger-label-text.sc-ds-bar-nav{display:block;flex:1 1 0%;min-width:0}.bar-nav--tabs-collapsed.sc-ds-bar-nav .bar-nav__actions.sc-ds-bar-nav{flex:0 0 auto;margin-left:0}.bar-nav__left.sc-ds-bar-nav{position:relative;flex:1 1 0%;min-width:0;width:0;display:flex;align-items:center}.bar-nav__left.sc-ds-bar-nav ds-tab-group-nav.sc-ds-bar-nav{flex:1;min-width:0}.bar-nav__tabs-probe.sc-ds-bar-nav{position:absolute;left:0;top:0;visibility:hidden;pointer-events:none;overflow:visible;width:max-content;max-width:none;z-index:-1}.bar-nav__tabs-probe.sc-ds-bar-nav ds-tab-group-nav.sc-ds-bar-nav{width:max-content}.bar-nav__tabs-visible.sc-ds-bar-nav{width:100%;min-width:0}.bar-nav--tools-drawer-opening.sc-ds-bar-nav-h .bar-nav__left.sc-ds-bar-nav{display:none}.bar-nav__tabs-pending.sc-ds-bar-nav{flex:1;min-width:0;height:var(--dimension-size-400);visibility:hidden;pointer-events:none}.bar-nav__tab-trigger.sc-ds-bar-nav{all:unset;box-sizing:border-box;display:inline-flex;align-items:center;gap:var(--dimension-space-050);flex:0 1 auto;min-width:0;width:max-content;max-width:100%;padding:var(--dimension-space-075);background-color:transparent;border-radius:var(--dimension-radius-025);cursor:pointer;-webkit-user-select:none;user-select:none;color:var(--_bar-nav-fg-primary);position:relative;transition:color var(--effect-motion-short-2);height:var(--dimension-size-400);--_hover-bg:var(--_bar-nav-hover);--_pressed-bg:var(--_bar-nav-pressed);--_dot:var(--_bar-nav-dot);--_dot-ring:var(--_bar-nav-bg)}.bar-nav__tab-trigger.sc-ds-bar-nav::after{content:'';position:absolute;inset:0;border-radius:var(--dimension-radius-025);background:transparent;pointer-events:none;transition:none;z-index:2}.bar-nav__tab-trigger.sc-ds-bar-nav:hover::after{background:var(--_hover-bg);transition:none}.bar-nav__tab-trigger.sc-ds-bar-nav:active::after{background:var(--_pressed-bg);transition:none}.bar-nav__tab-trigger.sc-ds-bar-nav:focus-visible{outline:var(--dimension-stroke-width-025) solid var(--_bar-nav-focus);outline-offset:var(--dimension-space-025)}.bar-nav__tab-trigger--open.sc-ds-bar-nav::after{background:var(--_hover-bg)}.bar-nav__tab-trigger-label.sc-ds-bar-nav{position:relative;display:inline-flex;align-items:center;flex:0 1 auto;min-width:0;max-width:100%;padding:0 var(--dimension-space-025);overflow:hidden;--_fade-right:var(--dimension-space-025);z-index:1}.bar-nav__tab-trigger-label--truncated.sc-ds-bar-nav::after{content:'';position:absolute;top:0;right:var(--_fade-right);bottom:0;width:var(--dimension-size-400);background:linear-gradient(to right, transparent, var(--_bar-nav-bg));pointer-events:none;z-index:1}.bar-nav__tab-trigger-label-text.sc-ds-bar-nav{display:inline-block;max-width:100%;box-sizing:border-box;white-space:nowrap;overflow:hidden;vertical-align:bottom}.bar-nav__tab-trigger-label-text--truncated.sc-ds-bar-nav{-webkit-mask-image:linear-gradient( to right, #000 0, #000 calc(100% - var(--dimension-size-400)), transparent 100% );mask-image:linear-gradient( to right, #000 0, #000 calc(100% - var(--dimension-size-400)), transparent 100% );-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%}.bar-nav__tab-trigger-label--dot.sc-ds-bar-nav{padding-right:calc(var(--dimension-space-025) + var(--dimension-space-050));--_fade-right:calc(var(--dimension-space-025) + var(--dimension-space-050))}.bar-nav__tab-trigger-dot.sc-ds-bar-nav{position:absolute;top:0;right:0;pointer-events:none;z-index:1}.bar-nav__tab-trigger-chevron.sc-ds-bar-nav{position:relative;flex-shrink:0;z-index:1}.bar-nav__heading.sc-ds-bar-nav{display:inline-flex;align-items:center;height:var(--dimension-size-400);padding-inline:var(--dimension-space-100);color:var(--_bar-nav-fg-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;-webkit-user-select:none;user-select:none}.bar-nav__actions.sc-ds-bar-nav{display:flex;align-items:center;gap:var(--dimension-space-050);flex:0 0 auto;margin-left:auto}`;const T=s(class s extends t{constructor(s){super();if(s!==false){this.__registerHost()}this.dsTabChange=e(this,"dsTabChange");this.dsActionChange=e(this,"dsActionChange");this.navStyle="dashboard";this.tabs=[];this.tabsJson="";this.value="";this.actions=[];this.actionsJson="";this.basePath="";this.currentUrl="";this.resolvedTabs=[];this.resolvedActions=[];this.urlDerivedValue="";this.hideTabsForDetailRoute=false;this.tabsCollapsed=false;this.menuOpen=false;this.tabLayoutCommitted=false;this.triggerLabelTruncated=false;this.headerEl=null;this.triggerEl=null;this.triggerLabelTextEl=null;this.triggerLabelObserver=null;this.menuEl=null;this.visibleTabGroupEl=null;this.probeTabGroupEl=null;this.resizeObserver=null;this.overflowCheckScheduled=false;this.intrinsicWidthRetryCount=0;this.chromeTransitionDepth=0;this.chromeTransitionShell=null;this.toolsDrawerOpening=false;this.committedSection="";this.pendingSection="";this.onChromeTransitionStart=s=>{const t=s.detail?.source;if(t==="panel-nav"){this.chromeTransitionDepth+=1;return}if(t==="panel-tools"){this.toolsDrawerOpening=true;this.el.classList.add("bar-nav--tools-drawer-opening");if(this.resolvedTabs.length>0&&!this.hideTabsForDetailRoute){this.tabsCollapsed=true;this.menuOpen=false}this.scheduleOverflowCheck()}};this.onChromeTransitionEnd=s=>{const t=s.detail?.source;if(t==="panel-nav"){this.chromeTransitionDepth=Math.max(0,this.chromeTransitionDepth-1);if(this.chromeTransitionDepth===0){this.scheduleOverflowCheck()}return}if(t==="panel-tools"){this.toolsDrawerOpening=false;this.el.classList.remove("bar-nav--tools-drawer-opening");this.scheduleOverflowCheck()}}}get effectiveValue(){if(this.currentUrl&&this.basePath){return this.urlDerivedValue}return this.value}get activeTabLabel(){return x(this.resolvedTabs,this.effectiveValue)}get activeTabHasDot(){return!!k(this.resolvedTabs,this.effectiveValue)?.dot}onHostPropsChange(){this.applyHostProps()}onSelectionChange(){this.syncMenuSections();this.scheduleOverflowCheck()}onMenuOpenChange(s){if(this.menuEl){this.menuEl.open=s}}onTabsCollapsedChange(s,t){if(!s){this.menuOpen=false;this.menuEl=null;this.triggerLabelTruncated=false;this.syncTriggerLabelObserver()}this.scheduleOverflowCheck();if(s){requestAnimationFrame((()=>{this.scheduleOverflowCheck();this.syncTriggerLabelObserver()}))}if(s||t===undefined||t===s)return;requestAnimationFrame((()=>this.scheduleOverflowCheck()));queueMicrotask((()=>this.focusVisibleSelectedTab()))}componentWillLoad(){this.applyHostProps()}componentDidLoad(){this.syncHostPropsIfNeeded();this.scheduleDeferredHostPropSync();this.setupOverflowObserver();this.bindChromeTransitionListeners();this.scheduleOverflowCheck()}componentDidRender(){if(this.chromeTransitionDepth>0){this.syncMenuAnchor();return}this.scheduleOverflowCheck();this.syncMenuAnchor();if(this.tabsCollapsed){this.updateTriggerLabelTruncation()}}disconnectedCallback(){this.resizeObserver?.disconnect();this.resizeObserver=null;this.syncTriggerLabelObserver(true);this.unbindChromeTransitionListeners()}bindChromeTransitionListeners(){const s=this.el.closest("ds-app-shell");if(!s)return;this.chromeTransitionShell=s;s.addEventListener(b,this.onChromeTransitionStart);s.addEventListener(c,this.onChromeTransitionEnd)}unbindChromeTransitionListeners(){if(!this.chromeTransitionShell)return;this.chromeTransitionShell.removeEventListener(b,this.onChromeTransitionStart);this.chromeTransitionShell.removeEventListener(c,this.onChromeTransitionEnd);this.chromeTransitionShell=null}syncHostPropsIfNeeded(){if(r(this.resolvedTabs,this.tabs,this.tabsJson,this.resolvedActions,this.actions,this.actionsJson)){this.applyHostProps()}else if(this.currentUrl&&this.basePath){this.syncValueFromUrl()}}scheduleDeferredHostPropSync(){let t=s.HOST_PROP_SYNC_BUDGET;const e=()=>{this.syncHostPropsIfNeeded();if(--t>0){requestAnimationFrame(e)}};queueMicrotask(e)}setupOverflowObserver(){if(typeof ResizeObserver==="undefined"||!this.headerEl)return;this.resizeObserver?.disconnect();this.resizeObserver=new ResizeObserver((()=>{if(this.chromeTransitionDepth>0)return;this.scheduleOverflowCheck()}));this.resizeObserver.observe(this.headerEl)}scheduleOverflowCheck(){if(this.chromeTransitionDepth>0)return;if(this.overflowCheckScheduled)return;this.overflowCheckScheduled=true;requestAnimationFrame((()=>{this.overflowCheckScheduled=false;if(this.chromeTransitionDepth>0)return;this.updateTabsCollapsed();this.updateTriggerLabelTruncation()}))}syncTriggerLabelObserver(s=false){this.triggerLabelObserver?.disconnect();this.triggerLabelObserver=null;if(s||!this.tabsCollapsed||!this.triggerLabelTextEl){return}this.updateTriggerLabelTruncation();if(typeof ResizeObserver==="undefined")return;this.triggerLabelObserver=new ResizeObserver((()=>this.updateTriggerLabelTruncation()));this.triggerLabelObserver.observe(this.triggerLabelTextEl);if(this.triggerEl){this.triggerLabelObserver.observe(this.triggerEl)}}updateTriggerLabelTruncation(){const s=this.triggerLabelTextEl;if(!s||!this.tabsCollapsed){if(this.triggerLabelTruncated){this.triggerLabelTruncated=false}return}const t=s.scrollWidth>s.clientWidth+1;if(t!==this.triggerLabelTruncated){this.triggerLabelTruncated=t}}getLeftZoneAvailableWidth(){if(!this.headerEl)return 0;const s=getComputedStyle(this.headerEl);const t=parseFloat(s.columnGap||s.gap||"0")||0;const e=this.headerEl.querySelector(".bar-nav__actions");const a=e?.offsetWidth??0;const i=(parseFloat(s.paddingLeft)||0)+(parseFloat(s.paddingRight)||0);const n=this.tabsCollapsed?parseFloat(getComputedStyle(this.headerEl).getPropertyValue("--dimension-space-100").trim())||8:e?t:0;const r=this.headerEl.clientWidth-i-a-n;return Math.max(0,r-this.toolsDrawerOpeningReservePx())}toolsDrawerOpeningReservePx(){if(!this.toolsDrawerOpening)return 0;const s=this.el.closest("ds-app-shell")?.querySelector("ds-panel-tools");if(!s)return 0;const t=v(s,"--_panel-tools-drawer-width");const e=s.querySelector(".panel-tools__drawer")?.getBoundingClientRect().width??0;return Math.max(0,t-e)}getTabsIntrinsicWidth(){const s=y(this.probeTabGroupEl);return s?.scrollWidth??0}scheduleIntrinsicWidthRetry(){if(this.intrinsicWidthRetryCount>=s.INTRINSIC_WIDTH_RETRY_MAX)return;this.intrinsicWidthRetryCount++;requestAnimationFrame((()=>this.scheduleOverflowCheck()))}updateTabsCollapsed(){if(!this.headerEl||this.resolvedTabs.length===0||this.hideTabsForDetailRoute){if(this.tabsCollapsed){this.tabsCollapsed=false;this.menuOpen=false}this.intrinsicWidthRetryCount=0;return}const t=this.getTabsIntrinsicWidth();if(t===0){this.scheduleIntrinsicWidthRetry();return}this.intrinsicWidthRetryCount=0;const e=C(t,this.getLeftZoneAvailableWidth(),this.tabsCollapsed,s.OVERFLOW_HYSTERESIS_PX);if(e!==this.tabsCollapsed){this.tabsCollapsed=e;if(!e){this.menuOpen=false}}}syncMenuAnchor(){if(!this.menuEl||!this.triggerEl||!this.tabsCollapsed)return;this.menuEl.anchor=this.triggerEl;this.syncMenuSections()}handleMenuSelect(s){const t=s.detail;if(t?.value!==undefined){this.selectTab(String(t.value))}this.menuOpen=false}handleMenuClose(){this.menuOpen=false}incomingTabs(){return this.tabsJson?o(this.tabsJson,[]):this.tabs??[]}incomingActions(){return this.actionsJson?o(this.actionsJson,[]):this.actions??[]}applyHostProps(){const s=this.basePath;const t=s!==""&&this.committedSection!==""&&s!==this.committedSection;if(t){this.urlDerivedValue="";this.committedSection="";this.pendingSection=s;this.resolvedTabs=[];this.resolvedActions=this.incomingActions();return}if(this.pendingSection){if(!s||s!==this.pendingSection){return}if(!this.currentUrl.startsWith(this.pendingSection)){return}const t=this.incomingTabs();if(t.length===0){return}this.pendingSection=""}this.resolvedTabs=this.incomingTabs();this.resolvedActions=this.incomingActions();this.syncValueFromUrl();this.committedSection=s;this.intrinsicWidthRetryCount=0;this.scheduleOverflowCheck()}syncMenuSections(){if(!this.menuEl)return;this.menuEl.sections=w(this.resolvedTabs,this.effectiveValue)}syncValueFromUrl(){const s=this.incomingTabs();if(!this.currentUrl||!this.basePath){this.urlDerivedValue="";this.hideTabsForDetailRoute=false;return}if(!this.currentUrl.startsWith(this.basePath)){this.urlDerivedValue="";this.hideTabsForDetailRoute=false;return}const{value:t,hideTabs:e}=h(this.currentUrl,this.basePath,s);this.urlDerivedValue=t;this.hideTabsForDetailRoute=e}selectTab(s){this.value=s;this.dsTabChange.emit(s)}focusVisibleSelectedTab(){const s=_(this.visibleTabGroupEl,`[data-tab-id="${this.effectiveValue}"]`);s?.focus({preventScroll:true})}handleTabChange(s){this.selectTab(s.detail)}handleActionChange(s,t){const e=t.detail;this.dsActionChange.emit({id:s,selected:e})}toggleTabMenu(){if(this.menuOpen){this.menuOpen=false;return}if(this.menuEl&&this.triggerEl){this.menuEl.anchor=this.triggerEl;this.menuEl.minWidth=`${this.triggerEl.offsetWidth}px`;this.syncMenuSections()}this.menuOpen=true}handleTriggerKeyDown(s){if(!this.tabsCollapsed)return;if(!this.menuOpen){if(s.key==="ArrowDown"||s.key==="ArrowUp"||s.key==="Enter"||s.key===" "){s.preventDefault();this.toggleTabMenu()}return}if(s.key==="Escape"){s.preventDefault();this.menuOpen=false;this.triggerEl?.focus()}}render(){const s=this.basePath!==""&&this.committedSection===this.basePath;const t=s&&this.resolvedTabs.length>0&&!this.hideTabsForDetailRoute;const e=this.basePath||"no-section";return a(i,{key:"eda575e15438e24b0ecdc6787376ae313762da99"},a("header",{key:"d059f342a267c9f723d6137f7946abdf373055d8",class:{"bar-nav":true,"bar-nav--dashboard":this.navStyle==="dashboard","bar-nav--settings":this.navStyle==="settings","bar-nav--tabs-collapsed":t&&this.tabsCollapsed},ref:s=>{this.headerEl=s;if(s&&!this.resizeObserver){this.setupOverflowObserver()}}},t&&a("div",{key:"4bb4ff4463c11fb34dff8bb8c7462c3fee04e499",class:"bar-nav__tabs-probe","aria-hidden":"true",inert:true},a("ds-tab-group-nav",{key:`probe-${e}`,ref:s=>{this.probeTabGroupEl=s??null;if(s){this.intrinsicWidthRetryCount=0;this.scheduleOverflowCheck()}},tabs:this.resolvedTabs,value:this.effectiveValue})),t&&!this.tabsCollapsed&&a("div",{key:"59bd2e10649a9bfbcff910fe18d08bef275f22c7",class:"bar-nav__left"},a("ds-tab-group-nav",{key:`visible-${e}`,class:"bar-nav__tabs-visible",ref:s=>{this.visibleTabGroupEl=s??null},tabs:this.resolvedTabs,value:this.effectiveValue,onDsChange:s=>this.handleTabChange(s)})),!t&&this.heading&&a("span",{key:"00fe94834d6d817afa88317e41281e59d71f6eb7",class:"bar-nav__heading text-body-medium-emphasis"},this.heading),t&&this.tabsCollapsed&&a("button",{key:"284b91f0645aad55bd707055e773984c9b0528cb",type:"button",class:{"bar-nav__tab-trigger":true,"bar-nav__tab-trigger--open":this.menuOpen},ref:s=>{this.triggerEl=s},"aria-haspopup":"menu","aria-expanded":this.menuOpen,"aria-label":`${this.activeTabLabel} tabs`,onClick:()=>this.toggleTabMenu(),onKeyDown:s=>this.handleTriggerKeyDown(s)},a("span",{key:"49d22828c030f0f34870d0c84ff2a216e90af045",class:{"bar-nav__tab-trigger-label":true,"bar-nav__tab-trigger-label--dot":this.activeTabHasDot,"bar-nav__tab-trigger-label--truncated":this.triggerLabelTruncated}},a("span",{key:"1195ca4cfa7abeeb78f73668d0361630c9933dd8",class:{"bar-nav__tab-trigger-label-text":true,"bar-nav__tab-trigger-label-text--truncated":this.triggerLabelTruncated,"text-body-medium-emphasis":true},ref:s=>{const t=s??null;if(t===this.triggerLabelTextEl)return;this.triggerLabelTextEl=t;if(this.tabsCollapsed){this.syncTriggerLabelObserver()}}},this.activeTabLabel),this.activeTabHasDot&&a("ds-badge",{key:"d6575de534ddc4e4d07d2f0ed934b937819ce587",class:"bar-nav__tab-trigger-dot",variant:"dot",background:"var(--_bar-nav-bg)",label:"","aria-hidden":"true"})),a("ds-icon",{key:"7ec1c1bc87e8f23d4c7b5fafd9e47dae0e09bbe1",name:"ChevronDown",size:"md",color:"inherit",class:"bar-nav__tab-trigger-chevron"})),t&&this.tabsCollapsed&&this.resolvedActions.length>0&&a("div",{key:"0fb271c1c84d4cce39cd535688e587a14230d32a",class:"bar-nav__between","aria-hidden":"true"}),this.resolvedActions.length>0&&a("div",{key:"478ee4e894c535ca8c7779a24ec9e192a62b2938",class:"bar-nav__actions"},this.resolvedActions.map((s=>a("ds-bar-nav-action",{key:s.id,icon:s.icon,selected:s.selected??false,dot:s.dot??false,inactive:s.inactive,"aria-label":s.ariaLabel??s.id,onDsChange:t=>this.handleActionChange(s.id,t)}))))),t&&this.tabsCollapsed&&a("ds-menu",{key:"d5a2ae069a9a3cb2677f9e20375d3619e48a15b5",ref:s=>{this.menuEl=s??null},open:this.menuOpen,sections:w(this.resolvedTabs,this.effectiveValue),side:"bottom",align:"start",onDsSelect:s=>this.handleMenuSelect(s),onDsClose:()=>this.handleMenuClose()}))}get el(){return this}static get watchers(){return{tabs:[{onHostPropsChange:0}],tabsJson:[{onHostPropsChange:0}],actions:[{onHostPropsChange:0}],actionsJson:[{onHostPropsChange:0}],currentUrl:[{onHostPropsChange:0}],basePath:[{onHostPropsChange:0}],value:[{onSelectionChange:0}],urlDerivedValue:[{onSelectionChange:0}],menuOpen:[{onMenuOpenChange:0}],tabsCollapsed:[{onTabsCollapsedChange:0}]}}static get style(){return z()}},[2,"ds-bar-nav",{navStyle:[513,"nav-style"],tabs:[16],tabsJson:[1,"tabs-json"],value:[1025],actions:[16],actionsJson:[1,"actions-json"],heading:[1],basePath:[1,"base-path"],currentUrl:[1,"current-url"],resolvedTabs:[32],resolvedActions:[32],urlDerivedValue:[32],hideTabsForDetailRoute:[32],tabsCollapsed:[32],menuOpen:[32],tabLayoutCommitted:[32],triggerLabelTruncated:[32],committedSection:[32],pendingSection:[32]},undefined,{tabs:[{onHostPropsChange:0}],tabsJson:[{onHostPropsChange:0}],actions:[{onHostPropsChange:0}],actionsJson:[{onHostPropsChange:0}],currentUrl:[{onHostPropsChange:0}],basePath:[{onHostPropsChange:0}],value:[{onSelectionChange:0}],urlDerivedValue:[{onSelectionChange:0}],menuOpen:[{onMenuOpenChange:0}],tabsCollapsed:[{onTabsCollapsedChange:0}]}]);T.HOST_PROP_SYNC_BUDGET=8;T.INTRINSIC_WIDTH_RETRY_MAX=3;T.OVERFLOW_HYSTERESIS_PX=8;function D(){if(typeof customElements==="undefined"){return}const s=["ds-bar-nav","ds-badge","ds-bar-nav-action","ds-icon","ds-menu","ds-tab-group-nav"];s.forEach((s=>{switch(s){case"ds-bar-nav":if(!customElements.get(n(s))){customElements.define(n(s),T)}break;case"ds-badge":if(!customElements.get(n(s))){f()}break;case"ds-bar-nav-action":if(!customElements.get(n(s))){u()}break;case"ds-icon":if(!customElements.get(n(s))){p()}break;case"ds-menu":if(!customElements.get(n(s))){g()}break;case"ds-tab-group-nav":if(!customElements.get(n(s))){m()}break}}))}D();const P=T;const S=D;export{P as DsBarNav,S as defineCustomElement};
|
|
1
|
+
import{p as s,H as t,c as a,h as e,a as i,t as n}from"./index.js";import{s as r,p as o,d as h}from"./p-Dl1GvZQ2.js";import{g as d,i as b}from"./p-BQq26pt9.js";import{C as l,c,a as v,b as f,e as u,r as p}from"./p-1HlgCxGN.js";import{d as g}from"./p-CiEc8Nwx.js";import{d as m}from"./p-CCZFMcLe.js";import{d as _}from"./p-DqBCQRRd.js";import{d as y}from"./p-CuuuDjJJ.js";import{d as w}from"./p-DlsexsFg.js";function k(s,t){if(!s)return null;const a=s.shadowRoot??s;return a.querySelector(t)}function x(s){return k(s,'[role="tablist"]')}function C(s,t){const a=[];let e=[];for(const i of s){if(b(i)){if(e.length>0){a.push({items:e});e=[]}continue}e.push({label:i.label,value:i.id,isSelected:i.id===t,isInactive:i.disabled})}if(e.length>0){a.push({items:e})}return a}function z(s,t){const a=d(s);return a.find((s=>s.id===t))??a[0]}function T(s,t){return z(s,t)?.label??"Tabs"}function D(s,t,a,e=2){const i=s-t;if(a){return i>-e}return i>e}const P=()=>`.sc-ds-bar-nav-h{display:block}.bar-nav.sc-ds-bar-nav{display:flex;align-items:center;position:relative;height:var(--dimension-size-600);padding:var(--dimension-space-100);gap:var(--dimension-space-100);box-sizing:border-box;border-bottom:var(--dimension-stroke-width-012) solid var(--_bar-nav-border);background-color:var(--_bar-nav-bg);color:var(--_bar-nav-fg-primary);-webkit-user-select:none;user-select:none;overflow:hidden;transition:background-color var(--effect-motion-short-3), border-color var(--effect-motion-short-3), color var(--effect-motion-short-3);isolation:isolate;--_bar-nav-bg:var(--color-background-secondary);--_bar-nav-border:var(--color-border-tertiary);--_bar-nav-fg-primary:var(--color-foreground-primary);--_bar-nav-fg-secondary:var(--color-foreground-secondary);--_bar-nav-hover:var(--color-interaction-hover);--_bar-nav-pressed:var(--color-interaction-pressed);--_bar-nav-focus:var(--color-interaction-focus);--_bar-nav-dot:var(--color-foreground-bold-brand)}.bar-nav--dashboard.sc-ds-bar-nav,.bar-nav--settings.sc-ds-bar-nav{--_bar-nav-bg:var(--color-background-secondary);--_bar-nav-border:var(--color-border-tertiary);--_bar-nav-fg-primary:var(--color-foreground-primary);--_bar-nav-fg-secondary:var(--color-foreground-secondary);--_bar-nav-hover:var(--color-interaction-hover);--_bar-nav-pressed:var(--color-interaction-pressed);--_bar-nav-focus:var(--color-interaction-focus);--_bar-nav-dot:var(--color-foreground-bold-brand)}ds-app-shell[gradient].sc-ds-bar-nav-h .bar-nav.sc-ds-bar-nav,ds-app-shell[gradient] .sc-ds-bar-nav-h .bar-nav.sc-ds-bar-nav,ds-app-shell[grid].sc-ds-bar-nav-h .bar-nav.sc-ds-bar-nav,ds-app-shell[grid] .sc-ds-bar-nav-h .bar-nav.sc-ds-bar-nav{background-color:transparent}.bar-nav.sc-ds-bar-nav>.sc-ds-bar-nav:not(.bar-nav__tabs-probe){position:relative;z-index:3}.bar-nav--tabs-collapsed.sc-ds-bar-nav{display:flex;gap:0;align-items:center}.bar-nav--tabs-collapsed.sc-ds-bar-nav .bar-nav__tab-trigger.sc-ds-bar-nav{flex:0 1 auto;min-width:0;max-width:100%;width:auto;overflow:hidden}.bar-nav__between.sc-ds-bar-nav{flex:1 1 0%;min-width:var(--dimension-space-100)}.bar-nav--tabs-collapsed.sc-ds-bar-nav .bar-nav__tab-trigger-label.sc-ds-bar-nav{flex:1 1 0%;min-width:0}.bar-nav--tabs-collapsed.sc-ds-bar-nav .bar-nav__tab-trigger-label-text.sc-ds-bar-nav{display:block;flex:1 1 0%;min-width:0}.bar-nav--tabs-collapsed.sc-ds-bar-nav .bar-nav__actions.sc-ds-bar-nav{flex:0 0 auto;margin-left:0}.bar-nav__left.sc-ds-bar-nav{position:relative;flex:1 1 0%;min-width:0;width:0;display:flex;align-items:center}.bar-nav__left.sc-ds-bar-nav ds-tab-group-nav.sc-ds-bar-nav{flex:1;min-width:0}.bar-nav__tabs-probe.sc-ds-bar-nav{position:absolute;left:0;top:0;visibility:hidden;pointer-events:none;overflow:visible;width:max-content;max-width:none;z-index:-1}.bar-nav__tabs-probe.sc-ds-bar-nav ds-tab-group-nav.sc-ds-bar-nav{width:max-content}.bar-nav__tabs-visible.sc-ds-bar-nav{width:100%;min-width:0}.bar-nav--tools-drawer-opening.sc-ds-bar-nav-h .bar-nav__left.sc-ds-bar-nav{display:none}.bar-nav__tabs-pending.sc-ds-bar-nav{flex:1;min-width:0;height:var(--dimension-size-400);visibility:hidden;pointer-events:none}.bar-nav__tab-trigger.sc-ds-bar-nav{all:unset;box-sizing:border-box;display:inline-flex;align-items:center;gap:var(--dimension-space-050);flex:0 1 auto;min-width:0;width:max-content;max-width:100%;padding:var(--dimension-space-075);background-color:transparent;border-radius:var(--dimension-radius-025);cursor:pointer;-webkit-user-select:none;user-select:none;color:var(--_bar-nav-fg-primary);position:relative;transition:color var(--effect-motion-short-2);height:var(--dimension-size-400);--_hover-bg:var(--_bar-nav-hover);--_pressed-bg:var(--_bar-nav-pressed);--_dot:var(--_bar-nav-dot);--_dot-ring:var(--_bar-nav-bg)}.bar-nav__tab-trigger.sc-ds-bar-nav::after{content:'';position:absolute;inset:0;border-radius:var(--dimension-radius-025);background:transparent;pointer-events:none;transition:none;z-index:2}.bar-nav__tab-trigger.sc-ds-bar-nav:hover::after{background:var(--_hover-bg);transition:none}.bar-nav__tab-trigger.sc-ds-bar-nav:active::after{background:var(--_pressed-bg);transition:none}.bar-nav__tab-trigger.sc-ds-bar-nav:focus-visible{outline:var(--dimension-stroke-width-025) solid var(--_bar-nav-focus);outline-offset:var(--dimension-space-025)}.bar-nav__tab-trigger--open.sc-ds-bar-nav::after{background:var(--_hover-bg)}.bar-nav__tab-trigger-label.sc-ds-bar-nav{position:relative;display:inline-flex;align-items:center;flex:0 1 auto;min-width:0;max-width:100%;padding:0 var(--dimension-space-025);overflow:hidden;--_fade-right:var(--dimension-space-025);z-index:1}.bar-nav__tab-trigger-label--truncated.sc-ds-bar-nav::after{content:'';position:absolute;top:0;right:var(--_fade-right);bottom:0;width:var(--dimension-size-400);background:linear-gradient(to right, transparent, var(--_bar-nav-bg));pointer-events:none;z-index:1}.bar-nav__tab-trigger-label-text.sc-ds-bar-nav{display:inline-block;max-width:100%;box-sizing:border-box;white-space:nowrap;overflow:hidden;vertical-align:bottom}.bar-nav__tab-trigger-label-text--truncated.sc-ds-bar-nav{-webkit-mask-image:linear-gradient( to right, #000 0, #000 calc(100% - var(--dimension-size-400)), transparent 100% );mask-image:linear-gradient( to right, #000 0, #000 calc(100% - var(--dimension-size-400)), transparent 100% );-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%}.bar-nav__tab-trigger-label--dot.sc-ds-bar-nav{padding-right:calc(var(--dimension-space-025) + var(--dimension-space-050));--_fade-right:calc(var(--dimension-space-025) + var(--dimension-space-050))}.bar-nav__tab-trigger-dot.sc-ds-bar-nav{position:absolute;top:0;right:0;pointer-events:none;z-index:1}.bar-nav__tab-trigger-chevron.sc-ds-bar-nav{position:relative;flex-shrink:0;z-index:1}.bar-nav__heading.sc-ds-bar-nav{display:inline-flex;align-items:center;height:var(--dimension-size-400);padding-inline:var(--dimension-space-100);color:var(--_bar-nav-fg-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;-webkit-user-select:none;user-select:none}.bar-nav__actions.sc-ds-bar-nav{display:flex;align-items:center;gap:var(--dimension-space-050);flex:0 0 auto;margin-left:auto}`;const H=s(class s extends t{constructor(s){super();if(s!==false){this.__registerHost()}this.dsTabChange=a(this,"dsTabChange");this.dsActionChange=a(this,"dsActionChange");this.navStyle="dashboard";this.tabs=[];this.tabsJson="";this.value="";this.actions=[];this.actionsJson="";this.basePath="";this.currentUrl="";this.resolvedTabs=[];this.resolvedActions=[];this.urlDerivedValue="";this.hideTabsForDetailRoute=false;this.tabsCollapsed=false;this.menuOpen=false;this.tabLayoutCommitted=false;this.triggerLabelTruncated=false;this.headerEl=null;this.triggerEl=null;this.triggerLabelTextEl=null;this.triggerLabelObserver=null;this.menuEl=null;this.visibleTabGroupEl=null;this.probeTabGroupEl=null;this.resizeObserver=null;this.intrinsicWidthRetryCount=0;this.panelNavTransition=new l;this.overflowCoalescer=c((()=>{this.updateTabsCollapsed();this.updateTriggerLabelTruncation()}));this.chromeTransitionShell=null;this.toolsDrawerOpening=false;this.committedSection="";this.pendingSection="";this.onChromeTransitionStart=s=>{const t=p(s);if(t==="panel-nav"){this.panelNavTransition.enter();return}if(t==="panel-tools"){this.toolsDrawerOpening=true;this.el.classList.add("bar-nav--tools-drawer-opening");if(this.resolvedTabs.length>0&&!this.hideTabsForDetailRoute){this.tabsCollapsed=true;this.menuOpen=false}this.scheduleOverflowCheck()}};this.onChromeTransitionEnd=s=>{const t=p(s);if(t==="panel-nav"){this.panelNavTransition.exit();if(!this.panelNavTransition.isActive){this.scheduleOverflowCheck()}return}if(t==="panel-tools"){this.toolsDrawerOpening=false;this.el.classList.remove("bar-nav--tools-drawer-opening");this.scheduleOverflowCheck()}}}get effectiveValue(){if(this.currentUrl&&this.basePath){return this.urlDerivedValue}return this.value}get activeTabLabel(){return T(this.resolvedTabs,this.effectiveValue)}get activeTabHasDot(){return!!z(this.resolvedTabs,this.effectiveValue)?.dot}onHostPropsChange(){this.applyHostProps()}onSelectionChange(){this.syncMenuSections();this.scheduleOverflowCheck()}onMenuOpenChange(s){if(this.menuEl){this.menuEl.open=s}}onTabsCollapsedChange(s,t){if(!s){this.menuOpen=false;this.menuEl=null;this.triggerLabelTruncated=false;this.syncTriggerLabelObserver()}this.scheduleOverflowCheck();if(s){requestAnimationFrame((()=>{this.scheduleOverflowCheck();this.syncTriggerLabelObserver()}))}if(s||t===undefined||t===s)return;requestAnimationFrame((()=>this.scheduleOverflowCheck()));queueMicrotask((()=>this.focusVisibleSelectedTab()))}componentWillLoad(){this.applyHostProps()}componentDidLoad(){this.syncHostPropsIfNeeded();this.scheduleDeferredHostPropSync();this.setupOverflowObserver();this.bindChromeTransitionListeners();this.scheduleOverflowCheck()}componentDidRender(){if(this.panelNavTransition.isActive){this.syncMenuAnchor();return}this.scheduleOverflowCheck();this.syncMenuAnchor();if(this.tabsCollapsed){this.updateTriggerLabelTruncation()}}disconnectedCallback(){this.resizeObserver?.disconnect();this.resizeObserver=null;this.overflowCoalescer.cancel();this.syncTriggerLabelObserver(true);this.unbindChromeTransitionListeners()}bindChromeTransitionListeners(){const s=this.el.closest("ds-app-shell");if(!s)return;this.chromeTransitionShell=s;s.addEventListener(v,this.onChromeTransitionStart);s.addEventListener(f,this.onChromeTransitionEnd)}unbindChromeTransitionListeners(){if(!this.chromeTransitionShell)return;this.chromeTransitionShell.removeEventListener(v,this.onChromeTransitionStart);this.chromeTransitionShell.removeEventListener(f,this.onChromeTransitionEnd);this.chromeTransitionShell=null}syncHostPropsIfNeeded(){if(r(this.resolvedTabs,this.tabs,this.tabsJson,this.resolvedActions,this.actions,this.actionsJson)){this.applyHostProps()}else if(this.currentUrl&&this.basePath){this.syncValueFromUrl()}}scheduleDeferredHostPropSync(){let t=s.HOST_PROP_SYNC_BUDGET;const a=()=>{this.syncHostPropsIfNeeded();if(--t>0){requestAnimationFrame(a)}};queueMicrotask(a)}setupOverflowObserver(){if(typeof ResizeObserver==="undefined"||!this.headerEl)return;this.resizeObserver?.disconnect();this.resizeObserver=new ResizeObserver((()=>{if(this.panelNavTransition.isActive)return;this.scheduleOverflowCheck()}));this.resizeObserver.observe(this.headerEl)}scheduleOverflowCheck(){if(this.panelNavTransition.isActive)return;this.overflowCoalescer.schedule()}syncTriggerLabelObserver(s=false){this.triggerLabelObserver?.disconnect();this.triggerLabelObserver=null;if(s||!this.tabsCollapsed||!this.triggerLabelTextEl){return}this.updateTriggerLabelTruncation();if(typeof ResizeObserver==="undefined")return;this.triggerLabelObserver=new ResizeObserver((()=>this.updateTriggerLabelTruncation()));this.triggerLabelObserver.observe(this.triggerLabelTextEl);if(this.triggerEl){this.triggerLabelObserver.observe(this.triggerEl)}}updateTriggerLabelTruncation(){const s=this.triggerLabelTextEl;if(!s||!this.tabsCollapsed){if(this.triggerLabelTruncated){this.triggerLabelTruncated=false}return}const t=s.scrollWidth>s.clientWidth+1;if(t!==this.triggerLabelTruncated){this.triggerLabelTruncated=t}}getLeftZoneAvailableWidth(){if(!this.headerEl)return 0;const s=getComputedStyle(this.headerEl);const t=parseFloat(s.columnGap||s.gap||"0")||0;const a=this.headerEl.querySelector(".bar-nav__actions");const e=a?.offsetWidth??0;const i=(parseFloat(s.paddingLeft)||0)+(parseFloat(s.paddingRight)||0);const n=this.tabsCollapsed?parseFloat(getComputedStyle(this.headerEl).getPropertyValue("--dimension-space-100").trim())||8:a?t:0;const r=this.headerEl.clientWidth-i-e-n;return Math.max(0,r-this.toolsDrawerOpeningReservePx())}toolsDrawerOpeningReservePx(){if(!this.toolsDrawerOpening)return 0;const s=this.el.closest("ds-app-shell")?.querySelector("ds-panel-tools");if(!s)return 0;const t=u(s,"--_panel-tools-drawer-width");const a=s.querySelector(".panel-tools__drawer")?.getBoundingClientRect().width??0;return Math.max(0,t-a)}getTabsIntrinsicWidth(){const s=x(this.probeTabGroupEl);return s?.scrollWidth??0}scheduleIntrinsicWidthRetry(){if(this.intrinsicWidthRetryCount>=s.INTRINSIC_WIDTH_RETRY_MAX)return;this.intrinsicWidthRetryCount++;requestAnimationFrame((()=>this.scheduleOverflowCheck()))}updateTabsCollapsed(){if(!this.headerEl||this.resolvedTabs.length===0||this.hideTabsForDetailRoute){if(this.tabsCollapsed){this.tabsCollapsed=false;this.menuOpen=false}this.intrinsicWidthRetryCount=0;return}const t=this.getTabsIntrinsicWidth();if(t===0){this.scheduleIntrinsicWidthRetry();return}this.intrinsicWidthRetryCount=0;const a=D(t,this.getLeftZoneAvailableWidth(),this.tabsCollapsed,s.OVERFLOW_HYSTERESIS_PX);if(a!==this.tabsCollapsed){this.tabsCollapsed=a;if(!a){this.menuOpen=false}}}syncMenuAnchor(){if(!this.menuEl||!this.triggerEl||!this.tabsCollapsed)return;this.menuEl.anchor=this.triggerEl;this.syncMenuSections()}handleMenuSelect(s){const t=s.detail;if(t?.value!==undefined){this.selectTab(String(t.value))}this.menuOpen=false}handleMenuClose(){this.menuOpen=false}incomingTabs(){return this.tabsJson?o(this.tabsJson,[]):this.tabs??[]}incomingActions(){return this.actionsJson?o(this.actionsJson,[]):this.actions??[]}applyHostProps(){const s=this.basePath;const t=s!==""&&this.committedSection!==""&&s!==this.committedSection;if(t){this.urlDerivedValue="";this.committedSection="";this.pendingSection=s;this.resolvedTabs=[];this.resolvedActions=this.incomingActions();return}if(this.pendingSection){if(!s||s!==this.pendingSection){return}if(!this.currentUrl.startsWith(this.pendingSection)){return}const t=this.incomingTabs();if(t.length===0){return}this.pendingSection=""}this.resolvedTabs=this.incomingTabs();this.resolvedActions=this.incomingActions();this.syncValueFromUrl();this.committedSection=s;this.intrinsicWidthRetryCount=0;this.scheduleOverflowCheck()}syncMenuSections(){if(!this.menuEl)return;this.menuEl.sections=C(this.resolvedTabs,this.effectiveValue)}syncValueFromUrl(){const s=this.incomingTabs();if(!this.currentUrl||!this.basePath){this.urlDerivedValue="";this.hideTabsForDetailRoute=false;return}if(!this.currentUrl.startsWith(this.basePath)){this.urlDerivedValue="";this.hideTabsForDetailRoute=false;return}const{value:t,hideTabs:a}=h(this.currentUrl,this.basePath,s);this.urlDerivedValue=t;this.hideTabsForDetailRoute=a}selectTab(s){this.value=s;this.dsTabChange.emit(s)}focusVisibleSelectedTab(){const s=k(this.visibleTabGroupEl,`[data-tab-id="${this.effectiveValue}"]`);s?.focus({preventScroll:true})}handleTabChange(s){this.selectTab(s.detail)}handleActionChange(s,t){const a=t.detail;this.dsActionChange.emit({id:s,selected:a})}toggleTabMenu(){if(this.menuOpen){this.menuOpen=false;return}if(this.menuEl&&this.triggerEl){this.menuEl.anchor=this.triggerEl;this.menuEl.minWidth=`${this.triggerEl.offsetWidth}px`;this.syncMenuSections()}this.menuOpen=true}handleTriggerKeyDown(s){if(!this.tabsCollapsed)return;if(!this.menuOpen){if(s.key==="ArrowDown"||s.key==="ArrowUp"||s.key==="Enter"||s.key===" "){s.preventDefault();this.toggleTabMenu()}return}if(s.key==="Escape"){s.preventDefault();this.menuOpen=false;this.triggerEl?.focus()}}render(){const s=this.basePath!==""&&this.committedSection===this.basePath;const t=s&&this.resolvedTabs.length>0&&!this.hideTabsForDetailRoute;const a=this.basePath||"no-section";return e(i,{key:"8e49d597a499f3bbf76bff36154455400845e197"},e("header",{key:"4249de386f30b4f850baaf71024c3257927c8c22",class:{"bar-nav":true,"bar-nav--dashboard":this.navStyle==="dashboard","bar-nav--settings":this.navStyle==="settings","bar-nav--tabs-collapsed":t&&this.tabsCollapsed},ref:s=>{this.headerEl=s;if(s&&!this.resizeObserver){this.setupOverflowObserver()}}},t&&e("div",{key:"58b219d8af1cf25dd2aee998f05b55e76f7dd9c7",class:"bar-nav__tabs-probe","aria-hidden":"true",inert:true},e("ds-tab-group-nav",{key:`probe-${a}`,ref:s=>{this.probeTabGroupEl=s??null;if(s){this.intrinsicWidthRetryCount=0;this.scheduleOverflowCheck()}},tabs:this.resolvedTabs,value:this.effectiveValue})),t&&!this.tabsCollapsed&&e("div",{key:"4575e2492845dc3a447074699ddbca45bf96cb9e",class:"bar-nav__left"},e("ds-tab-group-nav",{key:`visible-${a}`,class:"bar-nav__tabs-visible",ref:s=>{this.visibleTabGroupEl=s??null},tabs:this.resolvedTabs,value:this.effectiveValue,onDsChange:s=>this.handleTabChange(s)})),!t&&this.heading&&e("span",{key:"2972ae3d62750b03dcf73305a87f613c05eeecd4",class:"bar-nav__heading text-body-medium-emphasis"},this.heading),t&&this.tabsCollapsed&&e("button",{key:"a27073bd891f4890fdc707b2ea8cbbf6d5d79e30",type:"button",class:{"bar-nav__tab-trigger":true,"bar-nav__tab-trigger--open":this.menuOpen},ref:s=>{this.triggerEl=s},"aria-haspopup":"menu","aria-expanded":this.menuOpen,"aria-label":`${this.activeTabLabel} tabs`,onClick:()=>this.toggleTabMenu(),onKeyDown:s=>this.handleTriggerKeyDown(s)},e("span",{key:"c4af0f40034a4dce4ddb2c92a028119535ef421a",class:{"bar-nav__tab-trigger-label":true,"bar-nav__tab-trigger-label--dot":this.activeTabHasDot,"bar-nav__tab-trigger-label--truncated":this.triggerLabelTruncated}},e("span",{key:"9a0a865c4d1ab896e04c2c63d9f48ca694c14be0",class:{"bar-nav__tab-trigger-label-text":true,"bar-nav__tab-trigger-label-text--truncated":this.triggerLabelTruncated,"text-body-medium-emphasis":true},ref:s=>{const t=s??null;if(t===this.triggerLabelTextEl)return;this.triggerLabelTextEl=t;if(this.tabsCollapsed){this.syncTriggerLabelObserver()}}},this.activeTabLabel),this.activeTabHasDot&&e("ds-badge",{key:"ce6976ac664ce0d37e87bb42289ef411b1278bac",class:"bar-nav__tab-trigger-dot",variant:"dot",background:"var(--_bar-nav-bg)",label:"","aria-hidden":"true"})),e("ds-icon",{key:"6a1c7e1a0cc952e99666952d5e65fb02e9878345",name:"ChevronDown",size:"md",color:"inherit",class:"bar-nav__tab-trigger-chevron"})),t&&this.tabsCollapsed&&this.resolvedActions.length>0&&e("div",{key:"e775e9f56e6c0493a63bc5be865713765eec148f",class:"bar-nav__between","aria-hidden":"true"}),this.resolvedActions.length>0&&e("div",{key:"248aa54886523bfa6e0e0546c4da1ea9af29e9af",class:"bar-nav__actions"},this.resolvedActions.map((s=>e("ds-bar-nav-action",{key:s.id,icon:s.icon,selected:s.selected??false,dot:s.dot??false,inactive:s.inactive,"aria-label":s.ariaLabel??s.id,onDsChange:t=>this.handleActionChange(s.id,t)}))))),t&&this.tabsCollapsed&&e("ds-menu",{key:"d6f15bd70a5918fa7b5321c019887bb88dd04ec9",ref:s=>{this.menuEl=s??null},open:this.menuOpen,sections:C(this.resolvedTabs,this.effectiveValue),side:"bottom",align:"start",onDsSelect:s=>this.handleMenuSelect(s),onDsClose:()=>this.handleMenuClose()}))}get el(){return this}static get watchers(){return{tabs:[{onHostPropsChange:0}],tabsJson:[{onHostPropsChange:0}],actions:[{onHostPropsChange:0}],actionsJson:[{onHostPropsChange:0}],currentUrl:[{onHostPropsChange:0}],basePath:[{onHostPropsChange:0}],value:[{onSelectionChange:0}],urlDerivedValue:[{onSelectionChange:0}],menuOpen:[{onMenuOpenChange:0}],tabsCollapsed:[{onTabsCollapsedChange:0}]}}static get style(){return P()}},[2,"ds-bar-nav",{navStyle:[513,"nav-style"],tabs:[16],tabsJson:[1,"tabs-json"],value:[1025],actions:[16],actionsJson:[1,"actions-json"],heading:[1],basePath:[1,"base-path"],currentUrl:[1,"current-url"],resolvedTabs:[32],resolvedActions:[32],urlDerivedValue:[32],hideTabsForDetailRoute:[32],tabsCollapsed:[32],menuOpen:[32],tabLayoutCommitted:[32],triggerLabelTruncated:[32],committedSection:[32],pendingSection:[32]},undefined,{tabs:[{onHostPropsChange:0}],tabsJson:[{onHostPropsChange:0}],actions:[{onHostPropsChange:0}],actionsJson:[{onHostPropsChange:0}],currentUrl:[{onHostPropsChange:0}],basePath:[{onHostPropsChange:0}],value:[{onSelectionChange:0}],urlDerivedValue:[{onSelectionChange:0}],menuOpen:[{onMenuOpenChange:0}],tabsCollapsed:[{onTabsCollapsedChange:0}]}]);H.HOST_PROP_SYNC_BUDGET=8;H.INTRINSIC_WIDTH_RETRY_MAX=3;H.OVERFLOW_HYSTERESIS_PX=8;function S(){if(typeof customElements==="undefined"){return}const s=["ds-bar-nav","ds-badge","ds-bar-nav-action","ds-icon","ds-menu","ds-tab-group-nav"];s.forEach((s=>{switch(s){case"ds-bar-nav":if(!customElements.get(n(s))){customElements.define(n(s),H)}break;case"ds-badge":if(!customElements.get(n(s))){g()}break;case"ds-bar-nav-action":if(!customElements.get(n(s))){m()}break;case"ds-icon":if(!customElements.get(n(s))){_()}break;case"ds-menu":if(!customElements.get(n(s))){y()}break;case"ds-tab-group-nav":if(!customElements.get(n(s))){w()}break}}))}S();const O=H;const M=S;export{O as DsBarNav,M as defineCustomElement};
|
|
2
2
|
//# sourceMappingURL=ds-bar-nav.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["queryWithinComponentHost","host","selector","root","shadowRoot","querySelector","getTabListFromTabGroup","tabGroupEl","tabsToMenuSections","tabs","selectedId","sections","batch","item","isTabDivider","length","push","items","label","value","id","isSelected","isInactive","disabled","getActiveTab","selectable","getSelectableTabs","find","tab","getActiveTabLabel","tabsOverflowContainer","tabListScrollWidth","containerClientWidth","collapsed","hysteresis","diff","barNavCss","BarNav","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","navStyle","tabsJson","actions","actionsJson","basePath","currentUrl","resolvedTabs","resolvedActions","urlDerivedValue","hideTabsForDetailRoute","tabsCollapsed","menuOpen","tabLayoutCommitted","triggerLabelTruncated","headerEl","triggerEl","triggerLabelTextEl","triggerLabelObserver","menuEl","visibleTabGroupEl","probeTabGroupEl","resizeObserver","overflowCheckScheduled","intrinsicWidthRetryCount","chromeTransitionDepth","chromeTransitionShell","toolsDrawerOpening","committedSection","pendingSection","onChromeTransitionStart","event","source","detail","el","classList","add","scheduleOverflowCheck","onChromeTransitionEnd","Math","max","remove","effectiveValue","activeTabLabel","activeTabHasDot","dot","onHostPropsChange","applyHostProps","onSelectionChange","syncMenuSections","onMenuOpenChange","open","onTabsCollapsedChange","prevCollapsed","syncTriggerLabelObserver","requestAnimationFrame","undefined","queueMicrotask","focusVisibleSelectedTab","componentWillLoad","componentDidLoad","syncHostPropsIfNeeded","scheduleDeferredHostPropSync","setupOverflowObserver","bindChromeTransitionListeners","componentDidRender","syncMenuAnchor","updateTriggerLabelTruncation","disconnectedCallback","disconnect","unbindChromeTransitionListeners","shell","closest","addEventListener","CHROME_TRANSITION_START","CHROME_TRANSITION_END","removeEventListener","shouldResyncBarNavProps","syncValueFromUrl","remaining","HOST_PROP_SYNC_BUDGET","tick","ResizeObserver","observe","updateTabsCollapsed","disconnectOnly","truncated","scrollWidth","clientWidth","getLeftZoneAvailableWidth","headerStyle","getComputedStyle","gap","parseFloat","columnGap","actionsEl","actionsWidth","offsetWidth","horizontalPadding","paddingLeft","paddingRight","spacing","getPropertyValue","trim","available","toolsDrawerOpeningReservePx","tools","drawerTarget","readCssVarWidthPx","drawerNow","getBoundingClientRect","width","getTabsIntrinsicWidth","tabList","scheduleIntrinsicWidthRetry","INTRINSIC_WIDTH_RETRY_MAX","intrinsicWidth","shouldCollapse","OVERFLOW_HYSTERESIS_PX","anchor","handleMenuSelect","e","selectTab","String","handleMenuClose","incomingTabs","parseJsonArrayProp","incomingActions","nextBasePath","sectionChanged","startsWith","hideTabs","deriveBarNavValueFromUrl","dsTabChange","emit","focus","preventScroll","handleTabChange","handleActionChange","actionId","selected","dsActionChange","toggleTabMenu","minWidth","handleTriggerKeyDown","key","preventDefault","render","sectionReady","hasTabs","tabGroupKey","h","Host","class","ref","inert","onDsChange","heading","type","onClick","onKeyDown","next","variant","background","name","size","color","map","action","icon","inactive","ariaLabel","side","align","onDsSelect","onDsClose"],"sources":["src/wc/components/BarNav/bar-nav-dom-utils.ts","src/wc/components/BarNav/bar-nav-tabs-menu-utils.ts","src/wc/components/BarNav/BarNav.css?tag=ds-bar-nav&encapsulation=scoped","src/wc/components/BarNav/BarNav.tsx"],"sourcesContent":["export type QueryableHost = {\n shadowRoot?: ShadowRoot | null;\n querySelector: (selectors: string) => Element | null;\n};\n\n/**\n * Query within a Stencil custom-element host (light DOM today, shadow DOM–safe).\n * Use for child nodes owned by ds-tab-group and similar components.\n */\nexport function queryWithinComponentHost(\n host: QueryableHost | null | undefined,\n selector: string,\n): HTMLElement | null {\n if (!host) return null;\n const root = host.shadowRoot ?? host;\n return root.querySelector(selector) as HTMLElement | null;\n}\n\nexport function getTabListFromTabGroup(\n tabGroupEl: QueryableHost | null | undefined,\n): HTMLElement | null {\n return queryWithinComponentHost(tabGroupEl, '[role=\"tablist\"]');\n}\n","import type { MenuSection } from '../Menu/menu-types';\nimport {\n getSelectableTabs,\n isTabDivider,\n type TabItem,\n type TabItemTab,\n} from '../TabGroup/tab-item-utils';\n\n/** Map BarNav tabs to menu sections, preserving `{ type: 'divider' }` as section breaks. */\nexport function tabsToMenuSections(tabs: TabItem[], selectedId: string): MenuSection[] {\n const sections: MenuSection[] = [];\n let batch: MenuSection['items'] = [];\n\n for (const item of tabs) {\n if (isTabDivider(item)) {\n if (batch.length > 0) {\n sections.push({ items: batch });\n batch = [];\n }\n continue;\n }\n\n batch.push({\n label: item.label,\n value: item.id,\n isSelected: item.id === selectedId,\n isInactive: item.disabled,\n });\n }\n\n if (batch.length > 0) {\n sections.push({ items: batch });\n }\n\n return sections;\n}\n\nexport function getActiveTab(tabs: TabItem[], selectedId: string): TabItemTab | undefined {\n const selectable = getSelectableTabs(tabs);\n return selectable.find(tab => tab.id === selectedId) ?? selectable[0];\n}\n\nexport function getActiveTabLabel(tabs: TabItem[], selectedId: string): string {\n return getActiveTab(tabs, selectedId)?.label ?? 'Tabs';\n}\n\n/** True when tablist content exceeds the available width (with optional hysteresis). */\nexport function tabsOverflowContainer(\n tabListScrollWidth: number,\n containerClientWidth: number,\n collapsed: boolean,\n hysteresis = 2,\n): boolean {\n const diff = tabListScrollWidth - containerClientWidth;\n if (collapsed) {\n return diff > -hysteresis;\n }\n return diff > hysteresis;\n}\n",":host {\n display: block;\n}\n\n.bar-nav {\n display: flex;\n align-items: center;\n position: relative;\n height: var(--dimension-size-600);\n padding: var(--dimension-space-100);\n gap: var(--dimension-space-100);\n box-sizing: border-box;\n border-bottom: var(--dimension-stroke-width-012) solid var(--_bar-nav-border);\n background-color: var(--_bar-nav-bg);\n color: var(--_bar-nav-fg-primary);\n -webkit-user-select: none;\n user-select: none;\n overflow: hidden;\n transition:\n background-color var(--effect-motion-short-3),\n border-color var(--effect-motion-short-3),\n color var(--effect-motion-short-3);\n isolation: isolate;\n /* Default chrome — app surfaces */\n --_bar-nav-bg: var(--color-background-secondary);\n --_bar-nav-border: var(--color-border-tertiary);\n --_bar-nav-fg-primary: var(--color-foreground-primary);\n --_bar-nav-fg-secondary: var(--color-foreground-secondary);\n --_bar-nav-hover: var(--color-interaction-hover);\n --_bar-nav-pressed: var(--color-interaction-pressed);\n --_bar-nav-focus: var(--color-interaction-focus);\n --_bar-nav-dot: var(--color-foreground-bold-brand);\n}\n\n/* Style slots — same app tokens for now; hook texture/glyph layers later. */\n.bar-nav--dashboard,\n.bar-nav--settings {\n --_bar-nav-bg: var(--color-background-secondary);\n --_bar-nav-border: var(--color-border-tertiary);\n --_bar-nav-fg-primary: var(--color-foreground-primary);\n --_bar-nav-fg-secondary: var(--color-foreground-secondary);\n --_bar-nav-hover: var(--color-interaction-hover);\n --_bar-nav-pressed: var(--color-interaction-pressed);\n --_bar-nav-focus: var(--color-interaction-focus);\n --_bar-nav-dot: var(--color-foreground-bold-brand);\n}\n\n/* Shell-owned chrome (bg + wash + grid) — bar is a transparent frame. */\n:host-context(ds-app-shell[gradient]) .bar-nav,\n:host-context(ds-app-shell[grid]) .bar-nav {\n background-color: transparent;\n}\n\n.bar-nav > :not(.bar-nav__tabs-probe) {\n position: relative;\n z-index: 3;\n}\n\n/* Collapsed — explicit spacer keeps the 8px minimum while the trigger can shrink. */\n.bar-nav--tabs-collapsed {\n display: flex;\n gap: 0;\n align-items: center;\n}\n\n.bar-nav--tabs-collapsed .bar-nav__tab-trigger {\n flex: 0 1 auto;\n min-width: 0;\n max-width: 100%;\n width: auto;\n overflow: hidden;\n}\n\n.bar-nav__between {\n flex: 1 1 0%;\n min-width: var(--dimension-space-100);\n}\n\n.bar-nav--tabs-collapsed .bar-nav__tab-trigger-label {\n flex: 1 1 0%;\n min-width: 0;\n}\n\n.bar-nav--tabs-collapsed .bar-nav__tab-trigger-label-text {\n display: block;\n flex: 1 1 0%;\n min-width: 0;\n}\n\n.bar-nav--tabs-collapsed .bar-nav__actions {\n flex: 0 0 auto;\n margin-left: 0;\n}\n\n/* Expanded tabs — consume space between start and actions */\n.bar-nav__left {\n position: relative;\n flex: 1 1 0%;\n min-width: 0;\n width: 0;\n display: flex;\n align-items: center;\n}\n\n.bar-nav__left ds-tab-group-nav {\n flex: 1;\n min-width: 0;\n}\n\n/* Unconstrained width so intrinsic tab row width is measurable while collapsed */\n.bar-nav__tabs-probe {\n position: absolute;\n left: 0;\n top: 0;\n visibility: hidden;\n pointer-events: none;\n overflow: visible;\n width: max-content;\n max-width: none;\n z-index: -1;\n}\n\n.bar-nav__tabs-probe ds-tab-group-nav {\n width: max-content;\n}\n\n.bar-nav__tabs-visible {\n width: 100%;\n min-width: 0;\n}\n\n/* Synchronous hide while tools drawer opens — Stencil collapse state paints a frame later. */\n:host(.bar-nav--tools-drawer-opening) .bar-nav__left {\n display: none;\n}\n\n/* In-flow placeholder while measuring overflow — avoids layout jump; hidden from view/accessibility. */\n.bar-nav__tabs-pending {\n flex: 1;\n min-width: 0;\n height: var(--dimension-size-400);\n visibility: hidden;\n pointer-events: none;\n}\n\n/* Collapsed tab trigger — mirrors TabGroup .tab (+ chevron when collapsed) */\n.bar-nav__tab-trigger {\n all: unset;\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n gap: var(--dimension-space-050);\n flex: 0 1 auto;\n min-width: 0;\n width: max-content;\n max-width: 100%;\n padding: var(--dimension-space-075);\n background-color: transparent;\n border-radius: var(--dimension-radius-025);\n cursor: pointer;\n -webkit-user-select: none;\n user-select: none;\n color: var(--_bar-nav-fg-primary);\n position: relative;\n transition: color var(--effect-motion-short-2);\n height: var(--dimension-size-400);\n --_hover-bg: var(--_bar-nav-hover);\n --_pressed-bg: var(--_bar-nav-pressed);\n --_dot: var(--_bar-nav-dot);\n --_dot-ring: var(--_bar-nav-bg);\n}\n\n.bar-nav__tab-trigger::after {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: var(--dimension-radius-025);\n background: transparent;\n pointer-events: none;\n transition: none;\n z-index: 2;\n}\n\n.bar-nav__tab-trigger:hover::after {\n background: var(--_hover-bg);\n transition: none;\n}\n\n.bar-nav__tab-trigger:active::after {\n background: var(--_pressed-bg);\n transition: none;\n}\n\n.bar-nav__tab-trigger:focus-visible {\n outline: var(--dimension-stroke-width-025) solid var(--_bar-nav-focus);\n outline-offset: var(--dimension-space-025);\n}\n\n.bar-nav__tab-trigger--open::after {\n background: var(--_hover-bg);\n}\n\n.bar-nav__tab-trigger-label {\n position: relative;\n display: inline-flex;\n align-items: center;\n flex: 0 1 auto;\n min-width: 0;\n max-width: 100%;\n padding: 0 var(--dimension-space-025);\n overflow: hidden;\n --_fade-right: var(--dimension-space-025);\n z-index: 1;\n}\n\n.bar-nav__tab-trigger-label--truncated::after {\n content: '';\n position: absolute;\n top: 0;\n right: var(--_fade-right);\n bottom: 0;\n width: var(--dimension-size-400);\n background: linear-gradient(to right, transparent, var(--_bar-nav-bg));\n pointer-events: none;\n z-index: 1;\n}\n\n.bar-nav__tab-trigger-label-text {\n display: inline-block;\n max-width: 100%;\n box-sizing: border-box;\n white-space: nowrap;\n overflow: hidden;\n vertical-align: bottom;\n}\n\n.bar-nav__tab-trigger-label-text--truncated {\n -webkit-mask-image: linear-gradient(\n to right,\n #000 0,\n #000 calc(100% - var(--dimension-size-400)),\n transparent 100%\n );\n mask-image: linear-gradient(\n to right,\n #000 0,\n #000 calc(100% - var(--dimension-size-400)),\n transparent 100%\n );\n -webkit-mask-repeat: no-repeat;\n mask-repeat: no-repeat;\n -webkit-mask-size: 100% 100%;\n mask-size: 100% 100%;\n}\n\n.bar-nav__tab-trigger-label--dot {\n padding-right: calc(var(--dimension-space-025) + var(--dimension-space-050));\n --_fade-right: calc(var(--dimension-space-025) + var(--dimension-space-050));\n}\n\n.bar-nav__tab-trigger-dot {\n position: absolute;\n top: 0;\n right: 0;\n pointer-events: none;\n z-index: 1;\n}\n\n.bar-nav__tab-trigger-chevron {\n position: relative;\n flex-shrink: 0;\n z-index: 1;\n}\n\n/* Fallback heading when no tabs — matches a single (selected) tab so the area\n name shares the tab label's type token, color, height and horizontal inset.\n Inset = tab button padding (space-075, 6px) + label inset (space-025, 2px). */\n.bar-nav__heading {\n display: inline-flex;\n align-items: center;\n height: var(--dimension-size-400);\n padding-inline: var(--dimension-space-100);\n color: var(--_bar-nav-fg-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n -webkit-user-select: none;\n user-select: none;\n}\n\n/* Right zone — pinned to the end; header gap is the min space from tabs/trigger */\n.bar-nav__actions {\n display: flex;\n align-items: center;\n gap: var(--dimension-space-050);\n flex: 0 0 auto;\n margin-left: auto;\n}\n","import {\n Component,\n Prop,\n Event,\n EventEmitter,\n Element,\n Watch,\n State,\n h,\n Host,\n} from '@stencil/core';\nimport type { NavChromeStyle } from '../../nav/nav-chrome';\nimport type { MenuItemData } from '../Menu/menu-types';\nimport type { BarNavActionItem, BarNavTab } from './bar-nav-types';\nimport {\n deriveBarNavValueFromUrl,\n parseJsonArrayProp,\n shouldResyncBarNavProps,\n} from './bar-nav-utils';\nimport {\n getTabListFromTabGroup,\n queryWithinComponentHost,\n type QueryableHost,\n} from './bar-nav-dom-utils';\nimport {\n getActiveTab,\n getActiveTabLabel,\n tabsOverflowContainer,\n tabsToMenuSections,\n} from './bar-nav-tabs-menu-utils';\nimport {\n CHROME_TRANSITION_END,\n CHROME_TRANSITION_START,\n type ChromeTransitionDetail,\n} from '../../nav/chrome-transition';\nimport { readCssVarWidthPx } from '../../nav/shell-chrome-metrics';\n\n@Component({\n tag: 'ds-bar-nav',\n styleUrl: 'BarNav.css',\n scoped: true,\n})\nexport class BarNav {\n /** Style slot: `dashboard` or `settings`. Colors match for now. */\n @Prop({ attribute: 'nav-style', reflect: true }) navStyle: NavChromeStyle = 'dashboard';\n\n @Element() el!: HTMLElement;\n\n /**\n * Tab items for the left section.\n * Set via JS property: `el.tabs = [...]`. Replace the array reference to update.\n */\n @Prop() tabs: BarNavTab[] = [];\n\n /** JSON fallback for `tabs` — useful when framework bindings don't propagate arrays. */\n @Prop({ attribute: 'tabs-json' }) tabsJson: string = '';\n\n /** ID of the currently active tab. Overridden when `currentUrl` + `basePath` are set. */\n @Prop({ mutable: true }) value: string = '';\n\n /**\n * Action items rendered in the right section.\n * Set via JS property: `el.actions = [...]`. Replace the array reference to update.\n */\n @Prop() actions: BarNavActionItem[] = [];\n\n /** JSON fallback for `actions` — useful when framework bindings don't propagate arrays. */\n @Prop({ attribute: 'actions-json' }) actionsJson: string = '';\n\n /**\n * Fallback heading shown when no tabs are provided.\n * When tabs are present the heading is hidden.\n */\n @Prop() heading: string | undefined;\n\n /** Section base path (e.g. `/dashboard/safety`). Used with `currentUrl` to derive `value`. */\n @Prop() basePath: string = '';\n\n /** Current route URL. When set with `basePath`, the active tab is derived automatically. */\n @Prop() currentUrl: string = '';\n\n /** Emitted when the active tab changes. Detail = tab id. */\n @Event() dsTabChange!: EventEmitter<string>;\n\n /** Emitted when an action button is toggled. Detail = { id, selected }. */\n @Event() dsActionChange!: EventEmitter<{ id: string; selected: boolean }>;\n\n @State() private resolvedTabs: BarNavTab[] = [];\n @State() private resolvedActions: BarNavActionItem[] = [];\n @State() private urlDerivedValue: string = '';\n @State() private hideTabsForDetailRoute = false;\n @State() private tabsCollapsed = false;\n @State() private menuOpen = false;\n /** When false, defer showing expanded tabs or the collapsed trigger until intrinsic width is measured (avoids a one-frame flash of the full tab row on narrow viewports). */\n @State() private tabLayoutCommitted = false;\n @State() private triggerLabelTruncated = false;\n\n private static readonly HOST_PROP_SYNC_BUDGET = 8;\n private static readonly INTRINSIC_WIDTH_RETRY_MAX = 3;\n private static readonly OVERFLOW_HYSTERESIS_PX = 8;\n\n private headerEl: HTMLElement | null = null;\n private triggerEl: HTMLButtonElement | null = null;\n private triggerLabelTextEl: HTMLElement | null = null;\n private triggerLabelObserver: ResizeObserver | null = null;\n private menuEl: HTMLDsMenuElement | null = null;\n private visibleTabGroupEl: QueryableHost | null = null;\n private probeTabGroupEl: QueryableHost | null = null;\n private resizeObserver: ResizeObserver | null = null;\n private overflowCheckScheduled = false;\n private intrinsicWidthRetryCount = 0;\n private chromeTransitionDepth = 0;\n private chromeTransitionShell: HTMLElement | null = null;\n private toolsDrawerOpening = false;\n /** Matches `basePath` once tabs + URL are reconciled for the active section. */\n @State() private committedSection = '';\n /** Section waiting for URL + tabs to catch up after a cross-area navigation. */\n @State() private pendingSection = '';\n\n private get effectiveValue(): string {\n if (this.currentUrl && this.basePath) {\n return this.urlDerivedValue;\n }\n return this.value;\n }\n\n private get activeTabLabel(): string {\n return getActiveTabLabel(this.resolvedTabs, this.effectiveValue);\n }\n\n private get activeTabHasDot(): boolean {\n return !!getActiveTab(this.resolvedTabs, this.effectiveValue)?.dot;\n }\n\n @Watch('tabs')\n @Watch('tabsJson')\n @Watch('actions')\n @Watch('actionsJson')\n @Watch('currentUrl')\n @Watch('basePath')\n onHostPropsChange() {\n this.applyHostProps();\n }\n\n @Watch('value')\n @Watch('urlDerivedValue')\n onSelectionChange() {\n this.syncMenuSections();\n this.scheduleOverflowCheck();\n }\n\n @Watch('menuOpen')\n onMenuOpenChange(open: boolean) {\n if (this.menuEl) {\n this.menuEl.open = open;\n }\n }\n\n @Watch('tabsCollapsed')\n onTabsCollapsedChange(collapsed: boolean, prevCollapsed: boolean | undefined) {\n if (!collapsed) {\n this.menuOpen = false;\n this.menuEl = null;\n this.triggerLabelTruncated = false;\n this.syncTriggerLabelObserver();\n }\n this.scheduleOverflowCheck();\n if (collapsed) {\n requestAnimationFrame(() => {\n this.scheduleOverflowCheck();\n this.syncTriggerLabelObserver();\n });\n }\n if (collapsed || prevCollapsed === undefined || prevCollapsed === collapsed) return;\n requestAnimationFrame(() => this.scheduleOverflowCheck());\n queueMicrotask(() => this.focusVisibleSelectedTab());\n }\n\n componentWillLoad() {\n this.applyHostProps();\n }\n\n componentDidLoad() {\n this.syncHostPropsIfNeeded();\n this.scheduleDeferredHostPropSync();\n this.setupOverflowObserver();\n this.bindChromeTransitionListeners();\n this.scheduleOverflowCheck();\n }\n\n componentDidRender() {\n if (this.chromeTransitionDepth > 0) {\n this.syncMenuAnchor();\n return;\n }\n this.scheduleOverflowCheck();\n this.syncMenuAnchor();\n if (this.tabsCollapsed) {\n this.updateTriggerLabelTruncation();\n }\n }\n\n disconnectedCallback() {\n this.resizeObserver?.disconnect();\n this.resizeObserver = null;\n this.syncTriggerLabelObserver(true);\n this.unbindChromeTransitionListeners();\n }\n\n private bindChromeTransitionListeners() {\n const shell = this.el.closest('ds-app-shell');\n if (!shell) return;\n this.chromeTransitionShell = shell;\n shell.addEventListener(CHROME_TRANSITION_START, this.onChromeTransitionStart);\n shell.addEventListener(CHROME_TRANSITION_END, this.onChromeTransitionEnd);\n }\n\n private unbindChromeTransitionListeners() {\n if (!this.chromeTransitionShell) return;\n this.chromeTransitionShell.removeEventListener(\n CHROME_TRANSITION_START,\n this.onChromeTransitionStart,\n );\n this.chromeTransitionShell.removeEventListener(\n CHROME_TRANSITION_END,\n this.onChromeTransitionEnd,\n );\n this.chromeTransitionShell = null;\n }\n\n private onChromeTransitionStart = (event: Event) => {\n const source = (event as CustomEvent<ChromeTransitionDetail>).detail?.source;\n if (source === 'panel-nav') {\n this.chromeTransitionDepth += 1;\n return;\n }\n if (source === 'panel-tools') {\n this.toolsDrawerOpening = true;\n this.el.classList.add('bar-nav--tools-drawer-opening');\n if (this.resolvedTabs.length > 0 && !this.hideTabsForDetailRoute) {\n this.tabsCollapsed = true;\n this.menuOpen = false;\n }\n this.scheduleOverflowCheck();\n }\n };\n\n private onChromeTransitionEnd = (event: Event) => {\n const source = (event as CustomEvent<ChromeTransitionDetail>).detail?.source;\n if (source === 'panel-nav') {\n this.chromeTransitionDepth = Math.max(0, this.chromeTransitionDepth - 1);\n if (this.chromeTransitionDepth === 0) {\n this.scheduleOverflowCheck();\n }\n return;\n }\n if (source === 'panel-tools') {\n this.toolsDrawerOpening = false;\n this.el.classList.remove('bar-nav--tools-drawer-opening');\n this.scheduleOverflowCheck();\n }\n };\n\n /** Re-resolve props assigned by the host after componentWillLoad (Angular ngAfterViewInit). */\n private syncHostPropsIfNeeded() {\n if (\n shouldResyncBarNavProps(\n this.resolvedTabs,\n this.tabs,\n this.tabsJson,\n this.resolvedActions,\n this.actions,\n this.actionsJson,\n )\n ) {\n this.applyHostProps();\n } else if (this.currentUrl && this.basePath) {\n this.syncValueFromUrl();\n }\n }\n\n /** Poll across animation frames — host props may land without triggering @Watch. */\n private scheduleDeferredHostPropSync() {\n let remaining = BarNav.HOST_PROP_SYNC_BUDGET;\n const tick = () => {\n this.syncHostPropsIfNeeded();\n if (--remaining > 0) {\n requestAnimationFrame(tick);\n }\n };\n queueMicrotask(tick);\n }\n\n private setupOverflowObserver() {\n if (typeof ResizeObserver === 'undefined' || !this.headerEl) return;\n this.resizeObserver?.disconnect();\n this.resizeObserver = new ResizeObserver(() => {\n if (this.chromeTransitionDepth > 0) return;\n this.scheduleOverflowCheck();\n });\n this.resizeObserver.observe(this.headerEl);\n }\n\n private scheduleOverflowCheck() {\n if (this.chromeTransitionDepth > 0) return;\n if (this.overflowCheckScheduled) return;\n this.overflowCheckScheduled = true;\n requestAnimationFrame(() => {\n this.overflowCheckScheduled = false;\n if (this.chromeTransitionDepth > 0) return;\n this.updateTabsCollapsed();\n this.updateTriggerLabelTruncation();\n });\n }\n\n private syncTriggerLabelObserver(disconnectOnly = false) {\n this.triggerLabelObserver?.disconnect();\n this.triggerLabelObserver = null;\n\n if (disconnectOnly || !this.tabsCollapsed || !this.triggerLabelTextEl) {\n return;\n }\n\n this.updateTriggerLabelTruncation();\n\n if (typeof ResizeObserver === 'undefined') return;\n\n this.triggerLabelObserver = new ResizeObserver(() => this.updateTriggerLabelTruncation());\n this.triggerLabelObserver.observe(this.triggerLabelTextEl);\n if (this.triggerEl) {\n this.triggerLabelObserver.observe(this.triggerEl);\n }\n }\n\n private updateTriggerLabelTruncation() {\n const el = this.triggerLabelTextEl;\n if (!el || !this.tabsCollapsed) {\n if (this.triggerLabelTruncated) {\n this.triggerLabelTruncated = false;\n }\n return;\n }\n\n const truncated = el.scrollWidth > el.clientWidth + 1;\n if (truncated !== this.triggerLabelTruncated) {\n this.triggerLabelTruncated = truncated;\n }\n }\n\n /** Width left for tabs after actions. */\n private getLeftZoneAvailableWidth(): number {\n if (!this.headerEl) return 0;\n\n const headerStyle = getComputedStyle(this.headerEl);\n const gap = parseFloat(headerStyle.columnGap || headerStyle.gap || '0') || 0;\n const actionsEl = this.headerEl.querySelector('.bar-nav__actions') as HTMLElement | null;\n const actionsWidth = actionsEl?.offsetWidth ?? 0;\n const horizontalPadding =\n (parseFloat(headerStyle.paddingLeft) || 0) + (parseFloat(headerStyle.paddingRight) || 0);\n const spacing = this.tabsCollapsed\n ? parseFloat(\n getComputedStyle(this.headerEl).getPropertyValue('--dimension-space-100').trim(),\n ) || 8\n : actionsEl\n ? gap\n : 0;\n const available =\n this.headerEl.clientWidth - horizontalPadding - actionsWidth - spacing;\n\n return Math.max(0, available - this.toolsDrawerOpeningReservePx());\n }\n\n /** While the tools drawer is opening, reserve width not yet claimed by flex shrink. */\n private toolsDrawerOpeningReservePx(): number {\n if (!this.toolsDrawerOpening) return 0;\n\n const tools = this.el.closest('ds-app-shell')?.querySelector('ds-panel-tools') as HTMLElement | null;\n if (!tools) return 0;\n\n const drawerTarget = readCssVarWidthPx(tools, '--_panel-tools-drawer-width');\n const drawerNow =\n tools.querySelector('.panel-tools__drawer')?.getBoundingClientRect().width ?? 0;\n return Math.max(0, drawerTarget - drawerNow);\n }\n\n private getTabsIntrinsicWidth(): number {\n const tabList = getTabListFromTabGroup(this.probeTabGroupEl);\n return tabList?.scrollWidth ?? 0;\n }\n\n private scheduleIntrinsicWidthRetry() {\n if (this.intrinsicWidthRetryCount >= BarNav.INTRINSIC_WIDTH_RETRY_MAX) return;\n this.intrinsicWidthRetryCount++;\n requestAnimationFrame(() => this.scheduleOverflowCheck());\n }\n\n private updateTabsCollapsed() {\n if (!this.headerEl || this.resolvedTabs.length === 0 || this.hideTabsForDetailRoute) {\n if (this.tabsCollapsed) {\n this.tabsCollapsed = false;\n this.menuOpen = false;\n }\n this.intrinsicWidthRetryCount = 0;\n return;\n }\n\n const intrinsicWidth = this.getTabsIntrinsicWidth();\n if (intrinsicWidth === 0) {\n this.scheduleIntrinsicWidthRetry();\n return;\n }\n this.intrinsicWidthRetryCount = 0;\n\n const shouldCollapse = tabsOverflowContainer(\n intrinsicWidth,\n this.getLeftZoneAvailableWidth(),\n this.tabsCollapsed,\n BarNav.OVERFLOW_HYSTERESIS_PX,\n );\n\n if (shouldCollapse !== this.tabsCollapsed) {\n this.tabsCollapsed = shouldCollapse;\n if (!shouldCollapse) {\n this.menuOpen = false;\n }\n }\n }\n\n private syncMenuAnchor() {\n if (!this.menuEl || !this.triggerEl || !this.tabsCollapsed) return;\n this.menuEl.anchor = this.triggerEl;\n this.syncMenuSections();\n }\n\n private handleMenuSelect(e: Event) {\n const detail = (e as CustomEvent<MenuItemData>).detail;\n if (detail?.value !== undefined) {\n this.selectTab(String(detail.value));\n }\n this.menuOpen = false;\n }\n\n private handleMenuClose() {\n this.menuOpen = false;\n }\n\n /** Batch tabs/basePath/currentUrl updates so URL derivation never runs with a mixed section. */\n private incomingTabs(): BarNavTab[] {\n return this.tabsJson\n ? parseJsonArrayProp(this.tabsJson, [])\n : (this.tabs ?? []);\n }\n\n private incomingActions(): BarNavActionItem[] {\n return this.actionsJson\n ? parseJsonArrayProp(this.actionsJson, [])\n : (this.actions ?? []);\n }\n\n private applyHostProps() {\n const nextBasePath = this.basePath;\n const sectionChanged =\n nextBasePath !== '' &&\n this.committedSection !== '' &&\n nextBasePath !== this.committedSection;\n\n if (sectionChanged) {\n this.urlDerivedValue = '';\n this.committedSection = '';\n this.pendingSection = nextBasePath;\n this.resolvedTabs = [];\n this.resolvedActions = this.incomingActions();\n return;\n }\n\n if (this.pendingSection) {\n if (!nextBasePath || nextBasePath !== this.pendingSection) {\n return;\n }\n if (!this.currentUrl.startsWith(this.pendingSection)) {\n return;\n }\n const tabs = this.incomingTabs();\n if (tabs.length === 0) {\n return;\n }\n this.pendingSection = '';\n }\n\n this.resolvedTabs = this.incomingTabs();\n this.resolvedActions = this.incomingActions();\n this.syncValueFromUrl();\n this.committedSection = nextBasePath;\n this.intrinsicWidthRetryCount = 0;\n this.scheduleOverflowCheck();\n }\n\n private syncMenuSections() {\n if (!this.menuEl) return;\n this.menuEl.sections = tabsToMenuSections(this.resolvedTabs, this.effectiveValue);\n }\n\n private syncValueFromUrl() {\n const tabs = this.incomingTabs();\n\n if (!this.currentUrl || !this.basePath) {\n this.urlDerivedValue = '';\n this.hideTabsForDetailRoute = false;\n return;\n }\n\n if (!this.currentUrl.startsWith(this.basePath)) {\n this.urlDerivedValue = '';\n this.hideTabsForDetailRoute = false;\n return;\n }\n\n const { value, hideTabs } = deriveBarNavValueFromUrl(\n this.currentUrl,\n this.basePath,\n tabs,\n );\n this.urlDerivedValue = value;\n this.hideTabsForDetailRoute = hideTabs;\n }\n\n private selectTab(id: string) {\n this.value = id;\n this.dsTabChange.emit(id);\n }\n\n /** Move focus to the selected tab in the visible tab group (after expand). */\n private focusVisibleSelectedTab() {\n const tab = queryWithinComponentHost(\n this.visibleTabGroupEl,\n `[data-tab-id=\"${this.effectiveValue}\"]`,\n );\n tab?.focus({ preventScroll: true });\n }\n\n private handleTabChange(e: Event) {\n this.selectTab((e as CustomEvent<string>).detail);\n }\n\n private handleActionChange(actionId: string, e: Event) {\n const selected = (e as CustomEvent<boolean>).detail;\n this.dsActionChange.emit({ id: actionId, selected });\n }\n\n private toggleTabMenu() {\n if (this.menuOpen) {\n this.menuOpen = false;\n return;\n }\n\n if (this.menuEl && this.triggerEl) {\n this.menuEl.anchor = this.triggerEl;\n this.menuEl.minWidth = `${this.triggerEl.offsetWidth}px`;\n this.syncMenuSections();\n }\n\n this.menuOpen = true;\n }\n\n private handleTriggerKeyDown(e: KeyboardEvent) {\n if (!this.tabsCollapsed) return;\n\n if (!this.menuOpen) {\n if (e.key === 'ArrowDown' || e.key === 'ArrowUp' || e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n this.toggleTabMenu();\n }\n return;\n }\n\n if (e.key === 'Escape') {\n e.preventDefault();\n this.menuOpen = false;\n this.triggerEl?.focus();\n }\n }\n\n render() {\n const sectionReady =\n this.basePath !== '' && this.committedSection === this.basePath;\n const hasTabs =\n sectionReady && this.resolvedTabs.length > 0 && !this.hideTabsForDetailRoute;\n const tabGroupKey = this.basePath || 'no-section';\n\n return (\n <Host>\n <header\n class={{\n 'bar-nav': true,\n 'bar-nav--dashboard': this.navStyle === 'dashboard',\n 'bar-nav--settings': this.navStyle === 'settings',\n 'bar-nav--tabs-collapsed': hasTabs && this.tabsCollapsed,\n }}\n ref={el => {\n this.headerEl = el as HTMLElement;\n if (el && !this.resizeObserver) {\n this.setupOverflowObserver();\n }\n }}\n >\n {hasTabs && (\n <div class=\"bar-nav__tabs-probe\" aria-hidden=\"true\" inert>\n <ds-tab-group-nav\n key={`probe-${tabGroupKey}`}\n ref={el => {\n this.probeTabGroupEl = el ?? null;\n if (el) {\n this.intrinsicWidthRetryCount = 0;\n this.scheduleOverflowCheck();\n }\n }}\n tabs={this.resolvedTabs}\n value={this.effectiveValue}\n />\n </div>\n )}\n\n {hasTabs && !this.tabsCollapsed && (\n <div class=\"bar-nav__left\">\n <ds-tab-group-nav\n key={`visible-${tabGroupKey}`}\n class=\"bar-nav__tabs-visible\"\n ref={el => {\n this.visibleTabGroupEl = el ?? null;\n }}\n tabs={this.resolvedTabs}\n value={this.effectiveValue}\n onDsChange={(e: Event) => this.handleTabChange(e)}\n />\n </div>\n )}\n\n {!hasTabs && this.heading && (\n <span class=\"bar-nav__heading text-body-medium-emphasis\">{this.heading}</span>\n )}\n\n {hasTabs && this.tabsCollapsed && (\n <button\n type=\"button\"\n class={{\n 'bar-nav__tab-trigger': true,\n 'bar-nav__tab-trigger--open': this.menuOpen,\n }}\n ref={el => {\n this.triggerEl = el as HTMLButtonElement;\n }}\n aria-haspopup=\"menu\"\n aria-expanded={this.menuOpen}\n aria-label={`${this.activeTabLabel} tabs`}\n onClick={() => this.toggleTabMenu()}\n onKeyDown={(e: KeyboardEvent) => this.handleTriggerKeyDown(e)}\n >\n <span\n class={{\n 'bar-nav__tab-trigger-label': true,\n 'bar-nav__tab-trigger-label--dot': this.activeTabHasDot,\n 'bar-nav__tab-trigger-label--truncated': this.triggerLabelTruncated,\n }}\n >\n <span\n class={{\n 'bar-nav__tab-trigger-label-text': true,\n 'bar-nav__tab-trigger-label-text--truncated': this.triggerLabelTruncated,\n 'text-body-medium-emphasis': true,\n }}\n ref={el => {\n const next = el ?? null;\n if (next === this.triggerLabelTextEl) return;\n this.triggerLabelTextEl = next;\n if (this.tabsCollapsed) {\n this.syncTriggerLabelObserver();\n }\n }}\n >\n {this.activeTabLabel}\n </span>\n {this.activeTabHasDot && (\n <ds-badge\n class=\"bar-nav__tab-trigger-dot\"\n variant=\"dot\"\n background=\"var(--_bar-nav-bg)\"\n label=\"\"\n aria-hidden=\"true\"\n />\n )}\n </span>\n <ds-icon\n name=\"ChevronDown\"\n size=\"md\"\n color=\"inherit\"\n class=\"bar-nav__tab-trigger-chevron\"\n />\n </button>\n )}\n\n {hasTabs && this.tabsCollapsed && this.resolvedActions.length > 0 && (\n <div class=\"bar-nav__between\" aria-hidden=\"true\" />\n )}\n\n {this.resolvedActions.length > 0 && (\n <div class=\"bar-nav__actions\">\n {this.resolvedActions.map(action => (\n <ds-bar-nav-action\n key={action.id}\n icon={action.icon}\n selected={action.selected ?? false}\n dot={action.dot ?? false}\n inactive={action.inactive}\n aria-label={action.ariaLabel ?? action.id}\n onDsChange={(e: Event) => this.handleActionChange(action.id, e)}\n />\n ))}\n </div>\n )}\n\n </header>\n\n {hasTabs && this.tabsCollapsed && (\n <ds-menu\n ref={el => {\n this.menuEl = (el as HTMLDsMenuElement) ?? null;\n }}\n open={this.menuOpen}\n sections={tabsToMenuSections(this.resolvedTabs, this.effectiveValue)}\n side=\"bottom\"\n align=\"start\"\n onDsSelect={(e: Event) => this.handleMenuSelect(e)}\n onDsClose={() => this.handleMenuClose()}\n />\n )}\n </Host>\n );\n }\n}\n"],"mappings":"qYASM,SAAUA,EACdC,EACAC,GAEA,IAAKD,EAAM,OAAO,KAClB,MAAME,EAAOF,EAAKG,YAAcH,EAChC,OAAOE,EAAKE,cAAcH,EAC5B,CAEM,SAAUI,EACdC,GAEA,OAAOP,EAAyBO,EAAY,mBAC9C,CCbM,SAAUC,EAAmBC,EAAiBC,GAClD,MAAMC,EAA0B,GAChC,IAAIC,EAA8B,GAElC,IAAK,MAAMC,KAAQJ,EAAM,CACvB,GAAIK,EAAaD,GAAO,CACtB,GAAID,EAAMG,OAAS,EAAG,CACpBJ,EAASK,KAAK,CAAEC,MAAOL,IACvBA,EAAQ,E,CAEV,Q,CAGFA,EAAMI,KAAK,CACTE,MAAOL,EAAKK,MACZC,MAAON,EAAKO,GACZC,WAAYR,EAAKO,KAAOV,EACxBY,WAAYT,EAAKU,U,CAIrB,GAAIX,EAAMG,OAAS,EAAG,CACpBJ,EAASK,KAAK,CAAEC,MAAOL,G,CAGzB,OAAOD,CACT,CAEM,SAAUa,EAAaf,EAAiBC,GAC5C,MAAMe,EAAaC,EAAkBjB,GACrC,OAAOgB,EAAWE,MAAKC,GAAOA,EAAIR,KAAOV,KAAee,EAAW,EACrE,CAEM,SAAUI,EAAkBpB,EAAiBC,GACjD,OAAOc,EAAaf,EAAMC,IAAaQ,OAAS,MAClD,CAGM,SAAUY,EACdC,EACAC,EACAC,EACAC,EAAa,GAEb,MAAMC,EAAOJ,EAAqBC,EAClC,GAAIC,EAAW,CACb,OAAOE,GAAQD,C,CAEjB,OAAOC,EAAOD,CAChB,CC1DA,MAAME,EAAY,IAAM,0pM,MC0CXC,EAAMC,EAAA,MAAAD,UAAAE,EALnB,WAAAC,CAAAC,G,gIAOmDC,KAAAC,SAA2B,YAQpED,KAAAjC,KAAoB,GAGMiC,KAAAE,SAAmB,GAG5BF,KAAAvB,MAAgB,GAMjCuB,KAAAG,QAA8B,GAGDH,KAAAI,YAAsB,GASnDJ,KAAAK,SAAmB,GAGnBL,KAAAM,WAAqB,GAQZN,KAAAO,aAA4B,GAC5BP,KAAAQ,gBAAsC,GACtCR,KAAAS,gBAA0B,GAC1BT,KAAAU,uBAAyB,MACzBV,KAAAW,cAAgB,MAChBX,KAAAY,SAAW,MAEXZ,KAAAa,mBAAqB,MACrBb,KAAAc,sBAAwB,MAMjCd,KAAAe,SAA+B,KAC/Bf,KAAAgB,UAAsC,KACtChB,KAAAiB,mBAAyC,KACzCjB,KAAAkB,qBAA8C,KAC9ClB,KAAAmB,OAAmC,KACnCnB,KAAAoB,kBAA0C,KAC1CpB,KAAAqB,gBAAwC,KACxCrB,KAAAsB,eAAwC,KACxCtB,KAAAuB,uBAAyB,MACzBvB,KAAAwB,yBAA2B,EAC3BxB,KAAAyB,sBAAwB,EACxBzB,KAAA0B,sBAA4C,KAC5C1B,KAAA2B,mBAAqB,MAEZ3B,KAAA4B,iBAAmB,GAEnB5B,KAAA6B,eAAiB,GAiH1B7B,KAAA8B,wBAA2BC,IACjC,MAAMC,EAAUD,EAA8CE,QAAQD,OACtE,GAAIA,IAAW,YAAa,CAC1BhC,KAAKyB,uBAAyB,EAC9B,M,CAEF,GAAIO,IAAW,cAAe,CAC5BhC,KAAK2B,mBAAqB,KAC1B3B,KAAKkC,GAAGC,UAAUC,IAAI,iCACtB,GAAIpC,KAAKO,aAAalC,OAAS,IAAM2B,KAAKU,uBAAwB,CAChEV,KAAKW,cAAgB,KACrBX,KAAKY,SAAW,K,CAElBZ,KAAKqC,uB,GAIDrC,KAAAsC,sBAAyBP,IAC/B,MAAMC,EAAUD,EAA8CE,QAAQD,OACtE,GAAIA,IAAW,YAAa,CAC1BhC,KAAKyB,sBAAwBc,KAAKC,IAAI,EAAGxC,KAAKyB,sBAAwB,GACtE,GAAIzB,KAAKyB,wBAA0B,EAAG,CACpCzB,KAAKqC,uB,CAEP,M,CAEF,GAAIL,IAAW,cAAe,CAC5BhC,KAAK2B,mBAAqB,MAC1B3B,KAAKkC,GAAGC,UAAUM,OAAO,iCACzBzC,KAAKqC,uB,EA+dV,CA3mBC,kBAAYK,GACV,GAAI1C,KAAKM,YAAcN,KAAKK,SAAU,CACpC,OAAOL,KAAKS,e,CAEd,OAAOT,KAAKvB,K,CAGd,kBAAYkE,GACV,OAAOxD,EAAkBa,KAAKO,aAAcP,KAAK0C,e,CAGnD,mBAAYE,GACV,QAAS9D,EAAakB,KAAKO,aAAcP,KAAK0C,iBAAiBG,G,CASjE,iBAAAC,GACE9C,KAAK+C,gB,CAKP,iBAAAC,GACEhD,KAAKiD,mBACLjD,KAAKqC,uB,CAIP,gBAAAa,CAAiBC,GACf,GAAInD,KAAKmB,OAAQ,CACfnB,KAAKmB,OAAOgC,KAAOA,C,EAKvB,qBAAAC,CAAsB7D,EAAoB8D,GACxC,IAAK9D,EAAW,CACdS,KAAKY,SAAW,MAChBZ,KAAKmB,OAAS,KACdnB,KAAKc,sBAAwB,MAC7Bd,KAAKsD,0B,CAEPtD,KAAKqC,wBACL,GAAI9C,EAAW,CACbgE,uBAAsB,KACpBvD,KAAKqC,wBACLrC,KAAKsD,0BAA0B,G,CAGnC,GAAI/D,GAAa8D,IAAkBG,WAAaH,IAAkB9D,EAAW,OAC7EgE,uBAAsB,IAAMvD,KAAKqC,0BACjCoB,gBAAe,IAAMzD,KAAK0D,2B,CAG5B,iBAAAC,GACE3D,KAAK+C,gB,CAGP,gBAAAa,GACE5D,KAAK6D,wBACL7D,KAAK8D,+BACL9D,KAAK+D,wBACL/D,KAAKgE,gCACLhE,KAAKqC,uB,CAGP,kBAAA4B,GACE,GAAIjE,KAAKyB,sBAAwB,EAAG,CAClCzB,KAAKkE,iBACL,M,CAEFlE,KAAKqC,wBACLrC,KAAKkE,iBACL,GAAIlE,KAAKW,cAAe,CACtBX,KAAKmE,8B,EAIT,oBAAAC,GACEpE,KAAKsB,gBAAgB+C,aACrBrE,KAAKsB,eAAiB,KACtBtB,KAAKsD,yBAAyB,MAC9BtD,KAAKsE,iC,CAGC,6BAAAN,GACN,MAAMO,EAAQvE,KAAKkC,GAAGsC,QAAQ,gBAC9B,IAAKD,EAAO,OACZvE,KAAK0B,sBAAwB6C,EAC7BA,EAAME,iBAAiBC,EAAyB1E,KAAK8B,yBACrDyC,EAAME,iBAAiBE,EAAuB3E,KAAKsC,sB,CAG7C,+BAAAgC,GACN,IAAKtE,KAAK0B,sBAAuB,OACjC1B,KAAK0B,sBAAsBkD,oBACzBF,EACA1E,KAAK8B,yBAEP9B,KAAK0B,sBAAsBkD,oBACzBD,EACA3E,KAAKsC,uBAEPtC,KAAK0B,sBAAwB,I,CAqCvB,qBAAAmC,GACN,GACEgB,EACE7E,KAAKO,aACLP,KAAKjC,KACLiC,KAAKE,SACLF,KAAKQ,gBACLR,KAAKG,QACLH,KAAKI,aAEP,CACAJ,KAAK+C,gB,MACA,GAAI/C,KAAKM,YAAcN,KAAKK,SAAU,CAC3CL,KAAK8E,kB,EAKD,4BAAAhB,GACN,IAAIiB,EAAYpF,EAAOqF,sBACvB,MAAMC,EAAO,KACXjF,KAAK6D,wBACL,KAAMkB,EAAY,EAAG,CACnBxB,sBAAsB0B,E,GAG1BxB,eAAewB,E,CAGT,qBAAAlB,GACN,UAAWmB,iBAAmB,cAAgBlF,KAAKe,SAAU,OAC7Df,KAAKsB,gBAAgB+C,aACrBrE,KAAKsB,eAAiB,IAAI4D,gBAAe,KACvC,GAAIlF,KAAKyB,sBAAwB,EAAG,OACpCzB,KAAKqC,uBAAuB,IAE9BrC,KAAKsB,eAAe6D,QAAQnF,KAAKe,S,CAG3B,qBAAAsB,GACN,GAAIrC,KAAKyB,sBAAwB,EAAG,OACpC,GAAIzB,KAAKuB,uBAAwB,OACjCvB,KAAKuB,uBAAyB,KAC9BgC,uBAAsB,KACpBvD,KAAKuB,uBAAyB,MAC9B,GAAIvB,KAAKyB,sBAAwB,EAAG,OACpCzB,KAAKoF,sBACLpF,KAAKmE,8BAA8B,G,CAI/B,wBAAAb,CAAyB+B,EAAiB,OAChDrF,KAAKkB,sBAAsBmD,aAC3BrE,KAAKkB,qBAAuB,KAE5B,GAAImE,IAAmBrF,KAAKW,gBAAkBX,KAAKiB,mBAAoB,CACrE,M,CAGFjB,KAAKmE,+BAEL,UAAWe,iBAAmB,YAAa,OAE3ClF,KAAKkB,qBAAuB,IAAIgE,gBAAe,IAAMlF,KAAKmE,iCAC1DnE,KAAKkB,qBAAqBiE,QAAQnF,KAAKiB,oBACvC,GAAIjB,KAAKgB,UAAW,CAClBhB,KAAKkB,qBAAqBiE,QAAQnF,KAAKgB,U,EAInC,4BAAAmD,GACN,MAAMjC,EAAKlC,KAAKiB,mBAChB,IAAKiB,IAAOlC,KAAKW,cAAe,CAC9B,GAAIX,KAAKc,sBAAuB,CAC9Bd,KAAKc,sBAAwB,K,CAE/B,M,CAGF,MAAMwE,EAAYpD,EAAGqD,YAAcrD,EAAGsD,YAAc,EACpD,GAAIF,IAActF,KAAKc,sBAAuB,CAC5Cd,KAAKc,sBAAwBwE,C,EAKzB,yBAAAG,GACN,IAAKzF,KAAKe,SAAU,OAAO,EAE3B,MAAM2E,EAAcC,iBAAiB3F,KAAKe,UAC1C,MAAM6E,EAAMC,WAAWH,EAAYI,WAAaJ,EAAYE,KAAO,MAAQ,EAC3E,MAAMG,EAAY/F,KAAKe,SAASpD,cAAc,qBAC9C,MAAMqI,EAAeD,GAAWE,aAAe,EAC/C,MAAMC,GACHL,WAAWH,EAAYS,cAAgB,IAAMN,WAAWH,EAAYU,eAAiB,GACxF,MAAMC,EAAUrG,KAAKW,cACjBkF,WACEF,iBAAiB3F,KAAKe,UAAUuF,iBAAiB,yBAAyBC,SACvE,EACLR,EACEH,EACA,EACN,MAAMY,EACJxG,KAAKe,SAASyE,YAAcU,EAAoBF,EAAeK,EAEjE,OAAO9D,KAAKC,IAAI,EAAGgE,EAAYxG,KAAKyG,8B,CAI9B,2BAAAA,GACN,IAAKzG,KAAK2B,mBAAoB,OAAO,EAErC,MAAM+E,EAAQ1G,KAAKkC,GAAGsC,QAAQ,iBAAiB7G,cAAc,kBAC7D,IAAK+I,EAAO,OAAO,EAEnB,MAAMC,EAAeC,EAAkBF,EAAO,+BAC9C,MAAMG,EACJH,EAAM/I,cAAc,yBAAyBmJ,wBAAwBC,OAAS,EAChF,OAAOxE,KAAKC,IAAI,EAAGmE,EAAeE,E,CAG5B,qBAAAG,GACN,MAAMC,EAAUrJ,EAAuBoC,KAAKqB,iBAC5C,OAAO4F,GAAS1B,aAAe,C,CAGzB,2BAAA2B,GACN,GAAIlH,KAAKwB,0BAA4B7B,EAAOwH,0BAA2B,OACvEnH,KAAKwB,2BACL+B,uBAAsB,IAAMvD,KAAKqC,yB,CAG3B,mBAAA+C,GACN,IAAKpF,KAAKe,UAAYf,KAAKO,aAAalC,SAAW,GAAK2B,KAAKU,uBAAwB,CACnF,GAAIV,KAAKW,cAAe,CACtBX,KAAKW,cAAgB,MACrBX,KAAKY,SAAW,K,CAElBZ,KAAKwB,yBAA2B,EAChC,M,CAGF,MAAM4F,EAAiBpH,KAAKgH,wBAC5B,GAAII,IAAmB,EAAG,CACxBpH,KAAKkH,8BACL,M,CAEFlH,KAAKwB,yBAA2B,EAEhC,MAAM6F,EAAiBjI,EACrBgI,EACApH,KAAKyF,4BACLzF,KAAKW,cACLhB,EAAO2H,wBAGT,GAAID,IAAmBrH,KAAKW,cAAe,CACzCX,KAAKW,cAAgB0G,EACrB,IAAKA,EAAgB,CACnBrH,KAAKY,SAAW,K,GAKd,cAAAsD,GACN,IAAKlE,KAAKmB,SAAWnB,KAAKgB,YAAchB,KAAKW,cAAe,OAC5DX,KAAKmB,OAAOoG,OAASvH,KAAKgB,UAC1BhB,KAAKiD,kB,CAGC,gBAAAuE,CAAiBC,GACvB,MAAMxF,EAAUwF,EAAgCxF,OAChD,GAAIA,GAAQxD,QAAU+E,UAAW,CAC/BxD,KAAK0H,UAAUC,OAAO1F,EAAOxD,O,CAE/BuB,KAAKY,SAAW,K,CAGV,eAAAgH,GACN5H,KAAKY,SAAW,K,CAIV,YAAAiH,GACN,OAAO7H,KAAKE,SACR4H,EAAmB9H,KAAKE,SAAU,IACjCF,KAAKjC,MAAQ,E,CAGZ,eAAAgK,GACN,OAAO/H,KAAKI,YACR0H,EAAmB9H,KAAKI,YAAa,IACpCJ,KAAKG,SAAW,E,CAGf,cAAA4C,GACN,MAAMiF,EAAehI,KAAKK,SAC1B,MAAM4H,EACJD,IAAiB,IACjBhI,KAAK4B,mBAAqB,IAC1BoG,IAAiBhI,KAAK4B,iBAExB,GAAIqG,EAAgB,CAClBjI,KAAKS,gBAAkB,GACvBT,KAAK4B,iBAAmB,GACxB5B,KAAK6B,eAAiBmG,EACtBhI,KAAKO,aAAe,GACpBP,KAAKQ,gBAAkBR,KAAK+H,kBAC5B,M,CAGF,GAAI/H,KAAK6B,eAAgB,CACvB,IAAKmG,GAAgBA,IAAiBhI,KAAK6B,eAAgB,CACzD,M,CAEF,IAAK7B,KAAKM,WAAW4H,WAAWlI,KAAK6B,gBAAiB,CACpD,M,CAEF,MAAM9D,EAAOiC,KAAK6H,eAClB,GAAI9J,EAAKM,SAAW,EAAG,CACrB,M,CAEF2B,KAAK6B,eAAiB,E,CAGxB7B,KAAKO,aAAeP,KAAK6H,eACzB7H,KAAKQ,gBAAkBR,KAAK+H,kBAC5B/H,KAAK8E,mBACL9E,KAAK4B,iBAAmBoG,EACxBhI,KAAKwB,yBAA2B,EAChCxB,KAAKqC,uB,CAGC,gBAAAY,GACN,IAAKjD,KAAKmB,OAAQ,OAClBnB,KAAKmB,OAAOlD,SAAWH,EAAmBkC,KAAKO,aAAcP,KAAK0C,e,CAG5D,gBAAAoC,GACN,MAAM/G,EAAOiC,KAAK6H,eAElB,IAAK7H,KAAKM,aAAeN,KAAKK,SAAU,CACtCL,KAAKS,gBAAkB,GACvBT,KAAKU,uBAAyB,MAC9B,M,CAGF,IAAKV,KAAKM,WAAW4H,WAAWlI,KAAKK,UAAW,CAC9CL,KAAKS,gBAAkB,GACvBT,KAAKU,uBAAyB,MAC9B,M,CAGF,MAAMjC,MAAEA,EAAK0J,SAAEA,GAAaC,EAC1BpI,KAAKM,WACLN,KAAKK,SACLtC,GAEFiC,KAAKS,gBAAkBhC,EACvBuB,KAAKU,uBAAyByH,C,CAGxB,SAAAT,CAAUhJ,GAChBsB,KAAKvB,MAAQC,EACbsB,KAAKqI,YAAYC,KAAK5J,E,CAIhB,uBAAAgF,GACN,MAAMxE,EAAM5B,EACV0C,KAAKoB,kBACL,iBAAiBpB,KAAK0C,oBAExBxD,GAAKqJ,MAAM,CAAEC,cAAe,M,CAGtB,eAAAC,CAAgBhB,GACtBzH,KAAK0H,UAAWD,EAA0BxF,O,CAGpC,kBAAAyG,CAAmBC,EAAkBlB,GAC3C,MAAMmB,EAAYnB,EAA2BxF,OAC7CjC,KAAK6I,eAAeP,KAAK,CAAE5J,GAAIiK,EAAUC,Y,CAGnC,aAAAE,GACN,GAAI9I,KAAKY,SAAU,CACjBZ,KAAKY,SAAW,MAChB,M,CAGF,GAAIZ,KAAKmB,QAAUnB,KAAKgB,UAAW,CACjChB,KAAKmB,OAAOoG,OAASvH,KAAKgB,UAC1BhB,KAAKmB,OAAO4H,SAAW,GAAG/I,KAAKgB,UAAUiF,gBACzCjG,KAAKiD,kB,CAGPjD,KAAKY,SAAW,I,CAGV,oBAAAoI,CAAqBvB,GAC3B,IAAKzH,KAAKW,cAAe,OAEzB,IAAKX,KAAKY,SAAU,CAClB,GAAI6G,EAAEwB,MAAQ,aAAexB,EAAEwB,MAAQ,WAAaxB,EAAEwB,MAAQ,SAAWxB,EAAEwB,MAAQ,IAAK,CACtFxB,EAAEyB,iBACFlJ,KAAK8I,e,CAEP,M,CAGF,GAAIrB,EAAEwB,MAAQ,SAAU,CACtBxB,EAAEyB,iBACFlJ,KAAKY,SAAW,MAChBZ,KAAKgB,WAAWuH,O,EAIpB,MAAAY,GACE,MAAMC,EACJpJ,KAAKK,WAAa,IAAML,KAAK4B,mBAAqB5B,KAAKK,SACzD,MAAMgJ,EACJD,GAAgBpJ,KAAKO,aAAalC,OAAS,IAAM2B,KAAKU,uBACxD,MAAM4I,EAActJ,KAAKK,UAAY,aAErC,OACEkJ,EAACC,EAAI,CAAAP,IAAA,4CACHM,EAAA,UAAAN,IAAA,2CACEQ,MAAO,CACL,UAAW,KACX,qBAAsBzJ,KAAKC,WAAa,YACxC,oBAAqBD,KAAKC,WAAa,WACvC,0BAA2BoJ,GAAWrJ,KAAKW,eAE7C+I,IAAKxH,IACHlC,KAAKe,SAAWmB,EAChB,GAAIA,IAAOlC,KAAKsB,eAAgB,CAC9BtB,KAAK+D,uB,IAINsF,GACCE,EAAA,OAAAN,IAAA,2CAAKQ,MAAM,sBAAqB,cAAa,OAAOE,MAAK,MACvDJ,EAAA,oBACEN,IAAK,SAASK,IACdI,IAAKxH,IACHlC,KAAKqB,gBAAkBa,GAAM,KAC7B,GAAIA,EAAI,CACNlC,KAAKwB,yBAA2B,EAChCxB,KAAKqC,uB,GAGTtE,KAAMiC,KAAKO,aACX9B,MAAOuB,KAAK0C,kBAKjB2G,IAAYrJ,KAAKW,eAChB4I,EAAA,OAAAN,IAAA,2CAAKQ,MAAM,iBACTF,EAAA,oBACEN,IAAK,WAAWK,IAChBG,MAAM,wBACNC,IAAKxH,IACHlC,KAAKoB,kBAAoBc,GAAM,IAAI,EAErCnE,KAAMiC,KAAKO,aACX9B,MAAOuB,KAAK0C,eACZkH,WAAanC,GAAazH,KAAKyI,gBAAgBhB,OAKnD4B,GAAWrJ,KAAK6J,SAChBN,EAAA,QAAAN,IAAA,2CAAMQ,MAAM,8CAA8CzJ,KAAK6J,SAGhER,GAAWrJ,KAAKW,eACf4I,EAAA,UAAAN,IAAA,2CACEa,KAAK,SACLL,MAAO,CACL,uBAAwB,KACxB,6BAA8BzJ,KAAKY,UAErC8I,IAAKxH,IACHlC,KAAKgB,UAAYkB,CAAuB,EACzC,gBACa,OAAM,gBACLlC,KAAKY,SAAQ,aAChB,GAAGZ,KAAK2C,sBACpBoH,QAAS,IAAM/J,KAAK8I,gBACpBkB,UAAYvC,GAAqBzH,KAAKgJ,qBAAqBvB,IAE3D8B,EAAA,QAAAN,IAAA,2CACEQ,MAAO,CACL,6BAA8B,KAC9B,kCAAmCzJ,KAAK4C,gBACxC,wCAAyC5C,KAAKc,wBAGhDyI,EAAA,QAAAN,IAAA,2CACEQ,MAAO,CACL,kCAAmC,KACnC,6CAA8CzJ,KAAKc,sBACnD,4BAA6B,MAE/B4I,IAAKxH,IACH,MAAM+H,EAAO/H,GAAM,KACnB,GAAI+H,IAASjK,KAAKiB,mBAAoB,OACtCjB,KAAKiB,mBAAqBgJ,EAC1B,GAAIjK,KAAKW,cAAe,CACtBX,KAAKsD,0B,IAIRtD,KAAK2C,gBAEP3C,KAAK4C,iBACJ2G,EAAA,YAAAN,IAAA,2CACEQ,MAAM,2BACNS,QAAQ,MACRC,WAAW,qBACX3L,MAAM,GAAE,cACI,UAIlB+K,EAAA,WAAAN,IAAA,2CACEmB,KAAK,cACLC,KAAK,KACLC,MAAM,UACNb,MAAM,kCAKXJ,GAAWrJ,KAAKW,eAAiBX,KAAKQ,gBAAgBnC,OAAS,GAC9DkL,EAAA,OAAAN,IAAA,2CAAKQ,MAAM,mBAAkB,cAAa,SAG7CzJ,KAAKQ,gBAAgBnC,OAAS,GAC7BkL,EAAA,OAAAN,IAAA,2CAAKQ,MAAM,oBACRzJ,KAAKQ,gBAAgB+J,KAAIC,GACxBjB,EAAA,qBACEN,IAAKuB,EAAO9L,GACZ+L,KAAMD,EAAOC,KACb7B,SAAU4B,EAAO5B,UAAY,MAC7B/F,IAAK2H,EAAO3H,KAAO,MACnB6H,SAAUF,EAAOE,SAAQ,aACbF,EAAOG,WAAaH,EAAO9L,GACvCkL,WAAanC,GAAazH,KAAK0I,mBAAmB8B,EAAO9L,GAAI+I,SAQtE4B,GAAWrJ,KAAKW,eACf4I,EAAA,WAAAN,IAAA,2CACES,IAAKxH,IACHlC,KAAKmB,OAAUe,GAA4B,IAAI,EAEjDiB,KAAMnD,KAAKY,SACX3C,SAAUH,EAAmBkC,KAAKO,aAAcP,KAAK0C,gBACrDkI,KAAK,SACLC,MAAM,QACNC,WAAarD,GAAazH,KAAKwH,iBAAiBC,GAChDsD,UAAW,IAAM/K,KAAK4H,oB,+qCA3nBRjI,EAAAqF,sBAAwB,EACxBrF,EAAAwH,0BAA4B,EAC5BxH,EAAA2H,uBAAyB,E","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["queryWithinComponentHost","host","selector","root","shadowRoot","querySelector","getTabListFromTabGroup","tabGroupEl","tabsToMenuSections","tabs","selectedId","sections","batch","item","isTabDivider","length","push","items","label","value","id","isSelected","isInactive","disabled","getActiveTab","selectable","getSelectableTabs","find","tab","getActiveTabLabel","tabsOverflowContainer","tabListScrollWidth","containerClientWidth","collapsed","hysteresis","diff","barNavCss","BarNav","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","navStyle","tabsJson","actions","actionsJson","basePath","currentUrl","resolvedTabs","resolvedActions","urlDerivedValue","hideTabsForDetailRoute","tabsCollapsed","menuOpen","tabLayoutCommitted","triggerLabelTruncated","headerEl","triggerEl","triggerLabelTextEl","triggerLabelObserver","menuEl","visibleTabGroupEl","probeTabGroupEl","resizeObserver","intrinsicWidthRetryCount","panelNavTransition","ChromeTransitionDepth","overflowCoalescer","createRafCoalescer","updateTabsCollapsed","updateTriggerLabelTruncation","chromeTransitionShell","toolsDrawerOpening","committedSection","pendingSection","onChromeTransitionStart","event","source","readChromeTransitionSource","enter","el","classList","add","scheduleOverflowCheck","onChromeTransitionEnd","exit","isActive","remove","effectiveValue","activeTabLabel","activeTabHasDot","dot","onHostPropsChange","applyHostProps","onSelectionChange","syncMenuSections","onMenuOpenChange","open","onTabsCollapsedChange","prevCollapsed","syncTriggerLabelObserver","requestAnimationFrame","undefined","queueMicrotask","focusVisibleSelectedTab","componentWillLoad","componentDidLoad","syncHostPropsIfNeeded","scheduleDeferredHostPropSync","setupOverflowObserver","bindChromeTransitionListeners","componentDidRender","syncMenuAnchor","disconnectedCallback","disconnect","cancel","unbindChromeTransitionListeners","shell","closest","addEventListener","CHROME_TRANSITION_START","CHROME_TRANSITION_END","removeEventListener","shouldResyncBarNavProps","syncValueFromUrl","remaining","HOST_PROP_SYNC_BUDGET","tick","ResizeObserver","observe","schedule","disconnectOnly","truncated","scrollWidth","clientWidth","getLeftZoneAvailableWidth","headerStyle","getComputedStyle","gap","parseFloat","columnGap","actionsEl","actionsWidth","offsetWidth","horizontalPadding","paddingLeft","paddingRight","spacing","getPropertyValue","trim","available","Math","max","toolsDrawerOpeningReservePx","tools","drawerTarget","readCssVarWidthPx","drawerNow","getBoundingClientRect","width","getTabsIntrinsicWidth","tabList","scheduleIntrinsicWidthRetry","INTRINSIC_WIDTH_RETRY_MAX","intrinsicWidth","shouldCollapse","OVERFLOW_HYSTERESIS_PX","anchor","handleMenuSelect","e","detail","selectTab","String","handleMenuClose","incomingTabs","parseJsonArrayProp","incomingActions","nextBasePath","sectionChanged","startsWith","hideTabs","deriveBarNavValueFromUrl","dsTabChange","emit","focus","preventScroll","handleTabChange","handleActionChange","actionId","selected","dsActionChange","toggleTabMenu","minWidth","handleTriggerKeyDown","key","preventDefault","render","sectionReady","hasTabs","tabGroupKey","h","Host","class","ref","inert","onDsChange","heading","type","onClick","onKeyDown","next","variant","background","name","size","color","map","action","icon","inactive","ariaLabel","side","align","onDsSelect","onDsClose"],"sources":["src/wc/components/BarNav/bar-nav-dom-utils.ts","src/wc/components/BarNav/bar-nav-tabs-menu-utils.ts","src/wc/components/BarNav/BarNav.css?tag=ds-bar-nav&encapsulation=scoped","src/wc/components/BarNav/BarNav.tsx"],"sourcesContent":["export type QueryableHost = {\n shadowRoot?: ShadowRoot | null;\n querySelector: (selectors: string) => Element | null;\n};\n\n/**\n * Query within a Stencil custom-element host (light DOM today, shadow DOM–safe).\n * Use for child nodes owned by ds-tab-group and similar components.\n */\nexport function queryWithinComponentHost(\n host: QueryableHost | null | undefined,\n selector: string,\n): HTMLElement | null {\n if (!host) return null;\n const root = host.shadowRoot ?? host;\n return root.querySelector(selector) as HTMLElement | null;\n}\n\nexport function getTabListFromTabGroup(\n tabGroupEl: QueryableHost | null | undefined,\n): HTMLElement | null {\n return queryWithinComponentHost(tabGroupEl, '[role=\"tablist\"]');\n}\n","import type { MenuSection } from '../Menu/menu-types';\nimport {\n getSelectableTabs,\n isTabDivider,\n type TabItem,\n type TabItemTab,\n} from '../TabGroup/tab-item-utils';\n\n/** Map BarNav tabs to menu sections, preserving `{ type: 'divider' }` as section breaks. */\nexport function tabsToMenuSections(tabs: TabItem[], selectedId: string): MenuSection[] {\n const sections: MenuSection[] = [];\n let batch: MenuSection['items'] = [];\n\n for (const item of tabs) {\n if (isTabDivider(item)) {\n if (batch.length > 0) {\n sections.push({ items: batch });\n batch = [];\n }\n continue;\n }\n\n batch.push({\n label: item.label,\n value: item.id,\n isSelected: item.id === selectedId,\n isInactive: item.disabled,\n });\n }\n\n if (batch.length > 0) {\n sections.push({ items: batch });\n }\n\n return sections;\n}\n\nexport function getActiveTab(tabs: TabItem[], selectedId: string): TabItemTab | undefined {\n const selectable = getSelectableTabs(tabs);\n return selectable.find(tab => tab.id === selectedId) ?? selectable[0];\n}\n\nexport function getActiveTabLabel(tabs: TabItem[], selectedId: string): string {\n return getActiveTab(tabs, selectedId)?.label ?? 'Tabs';\n}\n\n/** True when tablist content exceeds the available width (with optional hysteresis). */\nexport function tabsOverflowContainer(\n tabListScrollWidth: number,\n containerClientWidth: number,\n collapsed: boolean,\n hysteresis = 2,\n): boolean {\n const diff = tabListScrollWidth - containerClientWidth;\n if (collapsed) {\n return diff > -hysteresis;\n }\n return diff > hysteresis;\n}\n",":host {\n display: block;\n}\n\n.bar-nav {\n display: flex;\n align-items: center;\n position: relative;\n height: var(--dimension-size-600);\n padding: var(--dimension-space-100);\n gap: var(--dimension-space-100);\n box-sizing: border-box;\n border-bottom: var(--dimension-stroke-width-012) solid var(--_bar-nav-border);\n background-color: var(--_bar-nav-bg);\n color: var(--_bar-nav-fg-primary);\n -webkit-user-select: none;\n user-select: none;\n overflow: hidden;\n transition:\n background-color var(--effect-motion-short-3),\n border-color var(--effect-motion-short-3),\n color var(--effect-motion-short-3);\n isolation: isolate;\n /* Default chrome — app surfaces */\n --_bar-nav-bg: var(--color-background-secondary);\n --_bar-nav-border: var(--color-border-tertiary);\n --_bar-nav-fg-primary: var(--color-foreground-primary);\n --_bar-nav-fg-secondary: var(--color-foreground-secondary);\n --_bar-nav-hover: var(--color-interaction-hover);\n --_bar-nav-pressed: var(--color-interaction-pressed);\n --_bar-nav-focus: var(--color-interaction-focus);\n --_bar-nav-dot: var(--color-foreground-bold-brand);\n}\n\n/* Style slots — same app tokens for now; hook texture/glyph layers later. */\n.bar-nav--dashboard,\n.bar-nav--settings {\n --_bar-nav-bg: var(--color-background-secondary);\n --_bar-nav-border: var(--color-border-tertiary);\n --_bar-nav-fg-primary: var(--color-foreground-primary);\n --_bar-nav-fg-secondary: var(--color-foreground-secondary);\n --_bar-nav-hover: var(--color-interaction-hover);\n --_bar-nav-pressed: var(--color-interaction-pressed);\n --_bar-nav-focus: var(--color-interaction-focus);\n --_bar-nav-dot: var(--color-foreground-bold-brand);\n}\n\n/* Shell-owned chrome (bg + wash + grid) — bar is a transparent frame. */\n:host-context(ds-app-shell[gradient]) .bar-nav,\n:host-context(ds-app-shell[grid]) .bar-nav {\n background-color: transparent;\n}\n\n.bar-nav > :not(.bar-nav__tabs-probe) {\n position: relative;\n z-index: 3;\n}\n\n/* Collapsed — explicit spacer keeps the 8px minimum while the trigger can shrink. */\n.bar-nav--tabs-collapsed {\n display: flex;\n gap: 0;\n align-items: center;\n}\n\n.bar-nav--tabs-collapsed .bar-nav__tab-trigger {\n flex: 0 1 auto;\n min-width: 0;\n max-width: 100%;\n width: auto;\n overflow: hidden;\n}\n\n.bar-nav__between {\n flex: 1 1 0%;\n min-width: var(--dimension-space-100);\n}\n\n.bar-nav--tabs-collapsed .bar-nav__tab-trigger-label {\n flex: 1 1 0%;\n min-width: 0;\n}\n\n.bar-nav--tabs-collapsed .bar-nav__tab-trigger-label-text {\n display: block;\n flex: 1 1 0%;\n min-width: 0;\n}\n\n.bar-nav--tabs-collapsed .bar-nav__actions {\n flex: 0 0 auto;\n margin-left: 0;\n}\n\n/* Expanded tabs — consume space between start and actions */\n.bar-nav__left {\n position: relative;\n flex: 1 1 0%;\n min-width: 0;\n width: 0;\n display: flex;\n align-items: center;\n}\n\n.bar-nav__left ds-tab-group-nav {\n flex: 1;\n min-width: 0;\n}\n\n/* Unconstrained width so intrinsic tab row width is measurable while collapsed */\n.bar-nav__tabs-probe {\n position: absolute;\n left: 0;\n top: 0;\n visibility: hidden;\n pointer-events: none;\n overflow: visible;\n width: max-content;\n max-width: none;\n z-index: -1;\n}\n\n.bar-nav__tabs-probe ds-tab-group-nav {\n width: max-content;\n}\n\n.bar-nav__tabs-visible {\n width: 100%;\n min-width: 0;\n}\n\n/* Synchronous hide while tools drawer opens — Stencil collapse state paints a frame later. */\n:host(.bar-nav--tools-drawer-opening) .bar-nav__left {\n display: none;\n}\n\n/* In-flow placeholder while measuring overflow — avoids layout jump; hidden from view/accessibility. */\n.bar-nav__tabs-pending {\n flex: 1;\n min-width: 0;\n height: var(--dimension-size-400);\n visibility: hidden;\n pointer-events: none;\n}\n\n/* Collapsed tab trigger — mirrors TabGroup .tab (+ chevron when collapsed) */\n.bar-nav__tab-trigger {\n all: unset;\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n gap: var(--dimension-space-050);\n flex: 0 1 auto;\n min-width: 0;\n width: max-content;\n max-width: 100%;\n padding: var(--dimension-space-075);\n background-color: transparent;\n border-radius: var(--dimension-radius-025);\n cursor: pointer;\n -webkit-user-select: none;\n user-select: none;\n color: var(--_bar-nav-fg-primary);\n position: relative;\n transition: color var(--effect-motion-short-2);\n height: var(--dimension-size-400);\n --_hover-bg: var(--_bar-nav-hover);\n --_pressed-bg: var(--_bar-nav-pressed);\n --_dot: var(--_bar-nav-dot);\n --_dot-ring: var(--_bar-nav-bg);\n}\n\n.bar-nav__tab-trigger::after {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: var(--dimension-radius-025);\n background: transparent;\n pointer-events: none;\n transition: none;\n z-index: 2;\n}\n\n.bar-nav__tab-trigger:hover::after {\n background: var(--_hover-bg);\n transition: none;\n}\n\n.bar-nav__tab-trigger:active::after {\n background: var(--_pressed-bg);\n transition: none;\n}\n\n.bar-nav__tab-trigger:focus-visible {\n outline: var(--dimension-stroke-width-025) solid var(--_bar-nav-focus);\n outline-offset: var(--dimension-space-025);\n}\n\n.bar-nav__tab-trigger--open::after {\n background: var(--_hover-bg);\n}\n\n.bar-nav__tab-trigger-label {\n position: relative;\n display: inline-flex;\n align-items: center;\n flex: 0 1 auto;\n min-width: 0;\n max-width: 100%;\n padding: 0 var(--dimension-space-025);\n overflow: hidden;\n --_fade-right: var(--dimension-space-025);\n z-index: 1;\n}\n\n.bar-nav__tab-trigger-label--truncated::after {\n content: '';\n position: absolute;\n top: 0;\n right: var(--_fade-right);\n bottom: 0;\n width: var(--dimension-size-400);\n background: linear-gradient(to right, transparent, var(--_bar-nav-bg));\n pointer-events: none;\n z-index: 1;\n}\n\n.bar-nav__tab-trigger-label-text {\n display: inline-block;\n max-width: 100%;\n box-sizing: border-box;\n white-space: nowrap;\n overflow: hidden;\n vertical-align: bottom;\n}\n\n.bar-nav__tab-trigger-label-text--truncated {\n -webkit-mask-image: linear-gradient(\n to right,\n #000 0,\n #000 calc(100% - var(--dimension-size-400)),\n transparent 100%\n );\n mask-image: linear-gradient(\n to right,\n #000 0,\n #000 calc(100% - var(--dimension-size-400)),\n transparent 100%\n );\n -webkit-mask-repeat: no-repeat;\n mask-repeat: no-repeat;\n -webkit-mask-size: 100% 100%;\n mask-size: 100% 100%;\n}\n\n.bar-nav__tab-trigger-label--dot {\n padding-right: calc(var(--dimension-space-025) + var(--dimension-space-050));\n --_fade-right: calc(var(--dimension-space-025) + var(--dimension-space-050));\n}\n\n.bar-nav__tab-trigger-dot {\n position: absolute;\n top: 0;\n right: 0;\n pointer-events: none;\n z-index: 1;\n}\n\n.bar-nav__tab-trigger-chevron {\n position: relative;\n flex-shrink: 0;\n z-index: 1;\n}\n\n/* Fallback heading when no tabs — matches a single (selected) tab so the area\n name shares the tab label's type token, color, height and horizontal inset.\n Inset = tab button padding (space-075, 6px) + label inset (space-025, 2px). */\n.bar-nav__heading {\n display: inline-flex;\n align-items: center;\n height: var(--dimension-size-400);\n padding-inline: var(--dimension-space-100);\n color: var(--_bar-nav-fg-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n -webkit-user-select: none;\n user-select: none;\n}\n\n/* Right zone — pinned to the end; header gap is the min space from tabs/trigger */\n.bar-nav__actions {\n display: flex;\n align-items: center;\n gap: var(--dimension-space-050);\n flex: 0 0 auto;\n margin-left: auto;\n}\n","import {\n Component,\n Prop,\n Event,\n EventEmitter,\n Element,\n Watch,\n State,\n h,\n Host,\n} from '@stencil/core';\nimport type { NavChromeStyle } from '../../nav/nav-chrome';\nimport type { MenuItemData } from '../Menu/menu-types';\nimport type { BarNavActionItem, BarNavTab } from './bar-nav-types';\nimport {\n deriveBarNavValueFromUrl,\n parseJsonArrayProp,\n shouldResyncBarNavProps,\n} from './bar-nav-utils';\nimport {\n getTabListFromTabGroup,\n queryWithinComponentHost,\n type QueryableHost,\n} from './bar-nav-dom-utils';\nimport {\n getActiveTab,\n getActiveTabLabel,\n tabsOverflowContainer,\n tabsToMenuSections,\n} from './bar-nav-tabs-menu-utils';\nimport {\n CHROME_TRANSITION_END,\n CHROME_TRANSITION_START,\n ChromeTransitionDepth,\n createRafCoalescer,\n readChromeTransitionSource,\n} from '../../nav/chrome-transition';\nimport { readCssVarWidthPx } from '../../nav/shell-chrome-metrics';\n\n@Component({\n tag: 'ds-bar-nav',\n styleUrl: 'BarNav.css',\n scoped: true,\n})\nexport class BarNav {\n /** Style slot: `dashboard` or `settings`. Colors match for now. */\n @Prop({ attribute: 'nav-style', reflect: true }) navStyle: NavChromeStyle = 'dashboard';\n\n @Element() el!: HTMLElement;\n\n /**\n * Tab items for the left section.\n * Set via JS property: `el.tabs = [...]`. Replace the array reference to update.\n */\n @Prop() tabs: BarNavTab[] = [];\n\n /** JSON fallback for `tabs` — useful when framework bindings don't propagate arrays. */\n @Prop({ attribute: 'tabs-json' }) tabsJson: string = '';\n\n /** ID of the currently active tab. Overridden when `currentUrl` + `basePath` are set. */\n @Prop({ mutable: true }) value: string = '';\n\n /**\n * Action items rendered in the right section.\n * Set via JS property: `el.actions = [...]`. Replace the array reference to update.\n */\n @Prop() actions: BarNavActionItem[] = [];\n\n /** JSON fallback for `actions` — useful when framework bindings don't propagate arrays. */\n @Prop({ attribute: 'actions-json' }) actionsJson: string = '';\n\n /**\n * Fallback heading shown when no tabs are provided.\n * When tabs are present the heading is hidden.\n */\n @Prop() heading: string | undefined;\n\n /** Section base path (e.g. `/dashboard/safety`). Used with `currentUrl` to derive `value`. */\n @Prop() basePath: string = '';\n\n /** Current route URL. When set with `basePath`, the active tab is derived automatically. */\n @Prop() currentUrl: string = '';\n\n /** Emitted when the active tab changes. Detail = tab id. */\n @Event() dsTabChange!: EventEmitter<string>;\n\n /** Emitted when an action button is toggled. Detail = { id, selected }. */\n @Event() dsActionChange!: EventEmitter<{ id: string; selected: boolean }>;\n\n @State() private resolvedTabs: BarNavTab[] = [];\n @State() private resolvedActions: BarNavActionItem[] = [];\n @State() private urlDerivedValue: string = '';\n @State() private hideTabsForDetailRoute = false;\n @State() private tabsCollapsed = false;\n @State() private menuOpen = false;\n /** When false, defer showing expanded tabs or the collapsed trigger until intrinsic width is measured (avoids a one-frame flash of the full tab row on narrow viewports). */\n @State() private tabLayoutCommitted = false;\n @State() private triggerLabelTruncated = false;\n\n private static readonly HOST_PROP_SYNC_BUDGET = 8;\n private static readonly INTRINSIC_WIDTH_RETRY_MAX = 3;\n private static readonly OVERFLOW_HYSTERESIS_PX = 8;\n\n private headerEl: HTMLElement | null = null;\n private triggerEl: HTMLButtonElement | null = null;\n private triggerLabelTextEl: HTMLElement | null = null;\n private triggerLabelObserver: ResizeObserver | null = null;\n private menuEl: HTMLDsMenuElement | null = null;\n private visibleTabGroupEl: QueryableHost | null = null;\n private probeTabGroupEl: QueryableHost | null = null;\n private resizeObserver: ResizeObserver | null = null;\n private intrinsicWidthRetryCount = 0;\n private readonly panelNavTransition = new ChromeTransitionDepth();\n private readonly overflowCoalescer = createRafCoalescer(() => {\n this.updateTabsCollapsed();\n this.updateTriggerLabelTruncation();\n });\n private chromeTransitionShell: HTMLElement | null = null;\n private toolsDrawerOpening = false;\n /** Matches `basePath` once tabs + URL are reconciled for the active section. */\n @State() private committedSection = '';\n /** Section waiting for URL + tabs to catch up after a cross-area navigation. */\n @State() private pendingSection = '';\n\n private get effectiveValue(): string {\n if (this.currentUrl && this.basePath) {\n return this.urlDerivedValue;\n }\n return this.value;\n }\n\n private get activeTabLabel(): string {\n return getActiveTabLabel(this.resolvedTabs, this.effectiveValue);\n }\n\n private get activeTabHasDot(): boolean {\n return !!getActiveTab(this.resolvedTabs, this.effectiveValue)?.dot;\n }\n\n @Watch('tabs')\n @Watch('tabsJson')\n @Watch('actions')\n @Watch('actionsJson')\n @Watch('currentUrl')\n @Watch('basePath')\n onHostPropsChange() {\n this.applyHostProps();\n }\n\n @Watch('value')\n @Watch('urlDerivedValue')\n onSelectionChange() {\n this.syncMenuSections();\n this.scheduleOverflowCheck();\n }\n\n @Watch('menuOpen')\n onMenuOpenChange(open: boolean) {\n if (this.menuEl) {\n this.menuEl.open = open;\n }\n }\n\n @Watch('tabsCollapsed')\n onTabsCollapsedChange(collapsed: boolean, prevCollapsed: boolean | undefined) {\n if (!collapsed) {\n this.menuOpen = false;\n this.menuEl = null;\n this.triggerLabelTruncated = false;\n this.syncTriggerLabelObserver();\n }\n this.scheduleOverflowCheck();\n if (collapsed) {\n requestAnimationFrame(() => {\n this.scheduleOverflowCheck();\n this.syncTriggerLabelObserver();\n });\n }\n if (collapsed || prevCollapsed === undefined || prevCollapsed === collapsed) return;\n requestAnimationFrame(() => this.scheduleOverflowCheck());\n queueMicrotask(() => this.focusVisibleSelectedTab());\n }\n\n componentWillLoad() {\n this.applyHostProps();\n }\n\n componentDidLoad() {\n this.syncHostPropsIfNeeded();\n this.scheduleDeferredHostPropSync();\n this.setupOverflowObserver();\n this.bindChromeTransitionListeners();\n this.scheduleOverflowCheck();\n }\n\n componentDidRender() {\n if (this.panelNavTransition.isActive) {\n this.syncMenuAnchor();\n return;\n }\n this.scheduleOverflowCheck();\n this.syncMenuAnchor();\n if (this.tabsCollapsed) {\n this.updateTriggerLabelTruncation();\n }\n }\n\n disconnectedCallback() {\n this.resizeObserver?.disconnect();\n this.resizeObserver = null;\n this.overflowCoalescer.cancel();\n this.syncTriggerLabelObserver(true);\n this.unbindChromeTransitionListeners();\n }\n\n private bindChromeTransitionListeners() {\n const shell = this.el.closest('ds-app-shell');\n if (!shell) return;\n this.chromeTransitionShell = shell;\n shell.addEventListener(CHROME_TRANSITION_START, this.onChromeTransitionStart);\n shell.addEventListener(CHROME_TRANSITION_END, this.onChromeTransitionEnd);\n }\n\n private unbindChromeTransitionListeners() {\n if (!this.chromeTransitionShell) return;\n this.chromeTransitionShell.removeEventListener(\n CHROME_TRANSITION_START,\n this.onChromeTransitionStart,\n );\n this.chromeTransitionShell.removeEventListener(\n CHROME_TRANSITION_END,\n this.onChromeTransitionEnd,\n );\n this.chromeTransitionShell = null;\n }\n\n private onChromeTransitionStart = (event: Event) => {\n const source = readChromeTransitionSource(event);\n if (source === 'panel-nav') {\n this.panelNavTransition.enter();\n return;\n }\n if (source === 'panel-tools') {\n this.toolsDrawerOpening = true;\n this.el.classList.add('bar-nav--tools-drawer-opening');\n if (this.resolvedTabs.length > 0 && !this.hideTabsForDetailRoute) {\n this.tabsCollapsed = true;\n this.menuOpen = false;\n }\n this.scheduleOverflowCheck();\n }\n };\n\n private onChromeTransitionEnd = (event: Event) => {\n const source = readChromeTransitionSource(event);\n if (source === 'panel-nav') {\n this.panelNavTransition.exit();\n if (!this.panelNavTransition.isActive) {\n this.scheduleOverflowCheck();\n }\n return;\n }\n if (source === 'panel-tools') {\n this.toolsDrawerOpening = false;\n this.el.classList.remove('bar-nav--tools-drawer-opening');\n this.scheduleOverflowCheck();\n }\n };\n\n /** Re-resolve props assigned by the host after componentWillLoad (Angular ngAfterViewInit). */\n private syncHostPropsIfNeeded() {\n if (\n shouldResyncBarNavProps(\n this.resolvedTabs,\n this.tabs,\n this.tabsJson,\n this.resolvedActions,\n this.actions,\n this.actionsJson,\n )\n ) {\n this.applyHostProps();\n } else if (this.currentUrl && this.basePath) {\n this.syncValueFromUrl();\n }\n }\n\n /** Poll across animation frames — host props may land without triggering @Watch. */\n private scheduleDeferredHostPropSync() {\n let remaining = BarNav.HOST_PROP_SYNC_BUDGET;\n const tick = () => {\n this.syncHostPropsIfNeeded();\n if (--remaining > 0) {\n requestAnimationFrame(tick);\n }\n };\n queueMicrotask(tick);\n }\n\n private setupOverflowObserver() {\n if (typeof ResizeObserver === 'undefined' || !this.headerEl) return;\n this.resizeObserver?.disconnect();\n this.resizeObserver = new ResizeObserver(() => {\n if (this.panelNavTransition.isActive) return;\n this.scheduleOverflowCheck();\n });\n this.resizeObserver.observe(this.headerEl);\n }\n\n private scheduleOverflowCheck() {\n if (this.panelNavTransition.isActive) return;\n this.overflowCoalescer.schedule();\n }\n\n private syncTriggerLabelObserver(disconnectOnly = false) {\n this.triggerLabelObserver?.disconnect();\n this.triggerLabelObserver = null;\n\n if (disconnectOnly || !this.tabsCollapsed || !this.triggerLabelTextEl) {\n return;\n }\n\n this.updateTriggerLabelTruncation();\n\n if (typeof ResizeObserver === 'undefined') return;\n\n this.triggerLabelObserver = new ResizeObserver(() => this.updateTriggerLabelTruncation());\n this.triggerLabelObserver.observe(this.triggerLabelTextEl);\n if (this.triggerEl) {\n this.triggerLabelObserver.observe(this.triggerEl);\n }\n }\n\n private updateTriggerLabelTruncation() {\n const el = this.triggerLabelTextEl;\n if (!el || !this.tabsCollapsed) {\n if (this.triggerLabelTruncated) {\n this.triggerLabelTruncated = false;\n }\n return;\n }\n\n const truncated = el.scrollWidth > el.clientWidth + 1;\n if (truncated !== this.triggerLabelTruncated) {\n this.triggerLabelTruncated = truncated;\n }\n }\n\n /** Width left for tabs after actions. */\n private getLeftZoneAvailableWidth(): number {\n if (!this.headerEl) return 0;\n\n const headerStyle = getComputedStyle(this.headerEl);\n const gap = parseFloat(headerStyle.columnGap || headerStyle.gap || '0') || 0;\n const actionsEl = this.headerEl.querySelector('.bar-nav__actions') as HTMLElement | null;\n const actionsWidth = actionsEl?.offsetWidth ?? 0;\n const horizontalPadding =\n (parseFloat(headerStyle.paddingLeft) || 0) + (parseFloat(headerStyle.paddingRight) || 0);\n const spacing = this.tabsCollapsed\n ? parseFloat(\n getComputedStyle(this.headerEl).getPropertyValue('--dimension-space-100').trim(),\n ) || 8\n : actionsEl\n ? gap\n : 0;\n const available =\n this.headerEl.clientWidth - horizontalPadding - actionsWidth - spacing;\n\n return Math.max(0, available - this.toolsDrawerOpeningReservePx());\n }\n\n /** While the tools drawer is opening, reserve width not yet claimed by flex shrink. */\n private toolsDrawerOpeningReservePx(): number {\n if (!this.toolsDrawerOpening) return 0;\n\n const tools = this.el.closest('ds-app-shell')?.querySelector('ds-panel-tools') as HTMLElement | null;\n if (!tools) return 0;\n\n const drawerTarget = readCssVarWidthPx(tools, '--_panel-tools-drawer-width');\n const drawerNow =\n tools.querySelector('.panel-tools__drawer')?.getBoundingClientRect().width ?? 0;\n return Math.max(0, drawerTarget - drawerNow);\n }\n\n private getTabsIntrinsicWidth(): number {\n const tabList = getTabListFromTabGroup(this.probeTabGroupEl);\n return tabList?.scrollWidth ?? 0;\n }\n\n private scheduleIntrinsicWidthRetry() {\n if (this.intrinsicWidthRetryCount >= BarNav.INTRINSIC_WIDTH_RETRY_MAX) return;\n this.intrinsicWidthRetryCount++;\n requestAnimationFrame(() => this.scheduleOverflowCheck());\n }\n\n private updateTabsCollapsed() {\n if (!this.headerEl || this.resolvedTabs.length === 0 || this.hideTabsForDetailRoute) {\n if (this.tabsCollapsed) {\n this.tabsCollapsed = false;\n this.menuOpen = false;\n }\n this.intrinsicWidthRetryCount = 0;\n return;\n }\n\n const intrinsicWidth = this.getTabsIntrinsicWidth();\n if (intrinsicWidth === 0) {\n this.scheduleIntrinsicWidthRetry();\n return;\n }\n this.intrinsicWidthRetryCount = 0;\n\n const shouldCollapse = tabsOverflowContainer(\n intrinsicWidth,\n this.getLeftZoneAvailableWidth(),\n this.tabsCollapsed,\n BarNav.OVERFLOW_HYSTERESIS_PX,\n );\n\n if (shouldCollapse !== this.tabsCollapsed) {\n this.tabsCollapsed = shouldCollapse;\n if (!shouldCollapse) {\n this.menuOpen = false;\n }\n }\n }\n\n private syncMenuAnchor() {\n if (!this.menuEl || !this.triggerEl || !this.tabsCollapsed) return;\n this.menuEl.anchor = this.triggerEl;\n this.syncMenuSections();\n }\n\n private handleMenuSelect(e: Event) {\n const detail = (e as CustomEvent<MenuItemData>).detail;\n if (detail?.value !== undefined) {\n this.selectTab(String(detail.value));\n }\n this.menuOpen = false;\n }\n\n private handleMenuClose() {\n this.menuOpen = false;\n }\n\n /** Batch tabs/basePath/currentUrl updates so URL derivation never runs with a mixed section. */\n private incomingTabs(): BarNavTab[] {\n return this.tabsJson\n ? parseJsonArrayProp(this.tabsJson, [])\n : (this.tabs ?? []);\n }\n\n private incomingActions(): BarNavActionItem[] {\n return this.actionsJson\n ? parseJsonArrayProp(this.actionsJson, [])\n : (this.actions ?? []);\n }\n\n private applyHostProps() {\n const nextBasePath = this.basePath;\n const sectionChanged =\n nextBasePath !== '' &&\n this.committedSection !== '' &&\n nextBasePath !== this.committedSection;\n\n if (sectionChanged) {\n this.urlDerivedValue = '';\n this.committedSection = '';\n this.pendingSection = nextBasePath;\n this.resolvedTabs = [];\n this.resolvedActions = this.incomingActions();\n return;\n }\n\n if (this.pendingSection) {\n if (!nextBasePath || nextBasePath !== this.pendingSection) {\n return;\n }\n if (!this.currentUrl.startsWith(this.pendingSection)) {\n return;\n }\n const tabs = this.incomingTabs();\n if (tabs.length === 0) {\n return;\n }\n this.pendingSection = '';\n }\n\n this.resolvedTabs = this.incomingTabs();\n this.resolvedActions = this.incomingActions();\n this.syncValueFromUrl();\n this.committedSection = nextBasePath;\n this.intrinsicWidthRetryCount = 0;\n this.scheduleOverflowCheck();\n }\n\n private syncMenuSections() {\n if (!this.menuEl) return;\n this.menuEl.sections = tabsToMenuSections(this.resolvedTabs, this.effectiveValue);\n }\n\n private syncValueFromUrl() {\n const tabs = this.incomingTabs();\n\n if (!this.currentUrl || !this.basePath) {\n this.urlDerivedValue = '';\n this.hideTabsForDetailRoute = false;\n return;\n }\n\n if (!this.currentUrl.startsWith(this.basePath)) {\n this.urlDerivedValue = '';\n this.hideTabsForDetailRoute = false;\n return;\n }\n\n const { value, hideTabs } = deriveBarNavValueFromUrl(\n this.currentUrl,\n this.basePath,\n tabs,\n );\n this.urlDerivedValue = value;\n this.hideTabsForDetailRoute = hideTabs;\n }\n\n private selectTab(id: string) {\n this.value = id;\n this.dsTabChange.emit(id);\n }\n\n /** Move focus to the selected tab in the visible tab group (after expand). */\n private focusVisibleSelectedTab() {\n const tab = queryWithinComponentHost(\n this.visibleTabGroupEl,\n `[data-tab-id=\"${this.effectiveValue}\"]`,\n );\n tab?.focus({ preventScroll: true });\n }\n\n private handleTabChange(e: Event) {\n this.selectTab((e as CustomEvent<string>).detail);\n }\n\n private handleActionChange(actionId: string, e: Event) {\n const selected = (e as CustomEvent<boolean>).detail;\n this.dsActionChange.emit({ id: actionId, selected });\n }\n\n private toggleTabMenu() {\n if (this.menuOpen) {\n this.menuOpen = false;\n return;\n }\n\n if (this.menuEl && this.triggerEl) {\n this.menuEl.anchor = this.triggerEl;\n this.menuEl.minWidth = `${this.triggerEl.offsetWidth}px`;\n this.syncMenuSections();\n }\n\n this.menuOpen = true;\n }\n\n private handleTriggerKeyDown(e: KeyboardEvent) {\n if (!this.tabsCollapsed) return;\n\n if (!this.menuOpen) {\n if (e.key === 'ArrowDown' || e.key === 'ArrowUp' || e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n this.toggleTabMenu();\n }\n return;\n }\n\n if (e.key === 'Escape') {\n e.preventDefault();\n this.menuOpen = false;\n this.triggerEl?.focus();\n }\n }\n\n render() {\n const sectionReady =\n this.basePath !== '' && this.committedSection === this.basePath;\n const hasTabs =\n sectionReady && this.resolvedTabs.length > 0 && !this.hideTabsForDetailRoute;\n const tabGroupKey = this.basePath || 'no-section';\n\n return (\n <Host>\n <header\n class={{\n 'bar-nav': true,\n 'bar-nav--dashboard': this.navStyle === 'dashboard',\n 'bar-nav--settings': this.navStyle === 'settings',\n 'bar-nav--tabs-collapsed': hasTabs && this.tabsCollapsed,\n }}\n ref={el => {\n this.headerEl = el as HTMLElement;\n if (el && !this.resizeObserver) {\n this.setupOverflowObserver();\n }\n }}\n >\n {hasTabs && (\n <div class=\"bar-nav__tabs-probe\" aria-hidden=\"true\" inert>\n <ds-tab-group-nav\n key={`probe-${tabGroupKey}`}\n ref={el => {\n this.probeTabGroupEl = el ?? null;\n if (el) {\n this.intrinsicWidthRetryCount = 0;\n this.scheduleOverflowCheck();\n }\n }}\n tabs={this.resolvedTabs}\n value={this.effectiveValue}\n />\n </div>\n )}\n\n {hasTabs && !this.tabsCollapsed && (\n <div class=\"bar-nav__left\">\n <ds-tab-group-nav\n key={`visible-${tabGroupKey}`}\n class=\"bar-nav__tabs-visible\"\n ref={el => {\n this.visibleTabGroupEl = el ?? null;\n }}\n tabs={this.resolvedTabs}\n value={this.effectiveValue}\n onDsChange={(e: Event) => this.handleTabChange(e)}\n />\n </div>\n )}\n\n {!hasTabs && this.heading && (\n <span class=\"bar-nav__heading text-body-medium-emphasis\">{this.heading}</span>\n )}\n\n {hasTabs && this.tabsCollapsed && (\n <button\n type=\"button\"\n class={{\n 'bar-nav__tab-trigger': true,\n 'bar-nav__tab-trigger--open': this.menuOpen,\n }}\n ref={el => {\n this.triggerEl = el as HTMLButtonElement;\n }}\n aria-haspopup=\"menu\"\n aria-expanded={this.menuOpen}\n aria-label={`${this.activeTabLabel} tabs`}\n onClick={() => this.toggleTabMenu()}\n onKeyDown={(e: KeyboardEvent) => this.handleTriggerKeyDown(e)}\n >\n <span\n class={{\n 'bar-nav__tab-trigger-label': true,\n 'bar-nav__tab-trigger-label--dot': this.activeTabHasDot,\n 'bar-nav__tab-trigger-label--truncated': this.triggerLabelTruncated,\n }}\n >\n <span\n class={{\n 'bar-nav__tab-trigger-label-text': true,\n 'bar-nav__tab-trigger-label-text--truncated': this.triggerLabelTruncated,\n 'text-body-medium-emphasis': true,\n }}\n ref={el => {\n const next = el ?? null;\n if (next === this.triggerLabelTextEl) return;\n this.triggerLabelTextEl = next;\n if (this.tabsCollapsed) {\n this.syncTriggerLabelObserver();\n }\n }}\n >\n {this.activeTabLabel}\n </span>\n {this.activeTabHasDot && (\n <ds-badge\n class=\"bar-nav__tab-trigger-dot\"\n variant=\"dot\"\n background=\"var(--_bar-nav-bg)\"\n label=\"\"\n aria-hidden=\"true\"\n />\n )}\n </span>\n <ds-icon\n name=\"ChevronDown\"\n size=\"md\"\n color=\"inherit\"\n class=\"bar-nav__tab-trigger-chevron\"\n />\n </button>\n )}\n\n {hasTabs && this.tabsCollapsed && this.resolvedActions.length > 0 && (\n <div class=\"bar-nav__between\" aria-hidden=\"true\" />\n )}\n\n {this.resolvedActions.length > 0 && (\n <div class=\"bar-nav__actions\">\n {this.resolvedActions.map(action => (\n <ds-bar-nav-action\n key={action.id}\n icon={action.icon}\n selected={action.selected ?? false}\n dot={action.dot ?? false}\n inactive={action.inactive}\n aria-label={action.ariaLabel ?? action.id}\n onDsChange={(e: Event) => this.handleActionChange(action.id, e)}\n />\n ))}\n </div>\n )}\n\n </header>\n\n {hasTabs && this.tabsCollapsed && (\n <ds-menu\n ref={el => {\n this.menuEl = (el as HTMLDsMenuElement) ?? null;\n }}\n open={this.menuOpen}\n sections={tabsToMenuSections(this.resolvedTabs, this.effectiveValue)}\n side=\"bottom\"\n align=\"start\"\n onDsSelect={(e: Event) => this.handleMenuSelect(e)}\n onDsClose={() => this.handleMenuClose()}\n />\n )}\n </Host>\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{p as e,H as s,c as t,h as o,a,t as i}from"./index.js";import{p as n}from"./p-Dl1GvZQ2.js";import{d as l}from"./p-CiEc8Nwx.js";import{d as r}from"./p-CCZFMcLe.js";import{d}from"./p-DqBCQRRd.js";const c="search";const h={search:"Search",messages:"Messages",stacks:"Stacks",activity:"Activity",agents:"Agents"};function p(e,s){if(s){return n(s,[])}return e??[]}const f=()=>`.sc-ds-panel-tools-h{display:block;flex:0 0 auto;box-sizing:border-box;height:100%;min-height:0;overflow:hidden;--_panel-tools-rail-width:var(--dimension-size-600);--_panel-tools-drawer-width:var(--dimension-panel-width-sm);--_panel-tools-border:var(--dimension-stroke-width-012, 1px) solid var(--color-border-tertiary);--_panel-tools-expand-dur:var(--effect-animation-duration-medium-1, 300ms)}.panel-tools__layout.sc-ds-panel-tools{display:flex;flex-direction:row;align-items:stretch;height:100%;min-height:0;box-sizing:border-box}.panel-tools__drawer.sc-ds-panel-tools{flex:0 0 auto;max-width:0;min-width:0;height:100%;min-height:0;overflow:hidden;box-sizing:border-box;transition:none}.panel-tools--ready.panel-tools--motion-opening.sc-ds-panel-tools-h .panel-tools__drawer.sc-ds-panel-tools{transition:max-width var(--_panel-tools-expand-dur) var(--effect-animation-easing-ease-out, ease-out)}.panel-tools--ready.panel-tools--motion-closing.sc-ds-panel-tools-h .panel-tools__drawer.sc-ds-panel-tools{transition:max-width var(--_panel-tools-expand-dur) var(--effect-animation-easing-ease-in, ease-in)}.panel-tools--open.sc-ds-panel-tools-h .panel-tools__drawer.sc-ds-panel-tools{max-width:var(--_panel-tools-drawer-width)}.panel-tools__drawer--visible.sc-ds-panel-tools{border-left:var(--_panel-tools-border)}.panel-tools__drawer-surface.sc-ds-panel-tools{display:flex;flex-direction:column;width:var(--_panel-tools-drawer-width);height:100%;min-height:0;box-sizing:border-box;background-color:var(--color-background-primary)}ds-app-shell[gradient].sc-ds-panel-tools-h .panel-tools__drawer-surface.sc-ds-panel-tools,ds-app-shell[gradient] .sc-ds-panel-tools-h .panel-tools__drawer-surface.sc-ds-panel-tools,ds-app-shell[grid].sc-ds-panel-tools-h .panel-tools__drawer-surface.sc-ds-panel-tools,ds-app-shell[grid] .sc-ds-panel-tools-h .panel-tools__drawer-surface.sc-ds-panel-tools{background-color:transparent}.panel-tools__header.sc-ds-panel-tools{flex:0 0 auto;display:flex;align-items:center;height:var(--dimension-size-600);padding:var(--dimension-space-100);border-bottom:var(--_panel-tools-border);color:var(--color-foreground-primary);box-sizing:border-box;-webkit-user-select:none;user-select:none}.panel-tools__title.sc-ds-panel-tools{display:inline-flex;align-items:center;height:var(--dimension-size-400);padding-inline:var(--dimension-space-100);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.panel-tools__body.sc-ds-panel-tools{flex:1 1 auto;min-height:0;overflow:auto;position:relative}.panel-tools__view.sc-ds-panel-tools{display:none;height:100%;min-height:0;box-sizing:border-box;padding:var(--dimension-space-200);color:var(--color-foreground-secondary);font-family:var(--typography-font-family);font-size:var(--typography-fontsize-md);line-height:var(--typography-lineheight-md);font-weight:var(--typography-weight-regular);letter-spacing:var(--typography-letterspacing-negative-half)}.panel-tools__view.sc-ds-panel-tools-s>*,.panel-tools__view .sc-ds-panel-tools-s>*{margin:0;color:var(--color-foreground-secondary);font-family:var(--typography-font-family);font-size:var(--typography-fontsize-md);line-height:var(--typography-lineheight-md);font-weight:var(--typography-weight-regular);letter-spacing:var(--typography-letterspacing-negative-half)}.panel-tools__view--active.sc-ds-panel-tools{display:block}.panel-tools__rail.sc-ds-panel-tools{flex:0 0 var(--_panel-tools-rail-width);width:var(--_panel-tools-rail-width);min-width:var(--_panel-tools-rail-width);display:flex;flex-direction:column;box-sizing:border-box;height:100%;min-height:0;border-left:var(--_panel-tools-border)}.panel-tools__rail-header.sc-ds-panel-tools{display:flex;align-items:center;justify-content:center;height:var(--dimension-size-600);padding:var(--dimension-space-100);flex-shrink:0;box-sizing:border-box;border-bottom:var(--_panel-tools-border)}.panel-tools__rail-body.sc-ds-panel-tools{flex:1 1 auto;min-height:0;overflow-y:auto;overflow-x:hidden;display:flex;flex-direction:column;gap:var(--dimension-space-050);padding:var(--dimension-space-100);box-sizing:border-box;scrollbar-width:none}.panel-tools__rail-body.sc-ds-panel-tools::-webkit-scrollbar{display:none}.panel-tools__rail-action.sc-ds-panel-tools{display:flex;align-items:center;justify-content:center;width:100%;height:var(--dimension-size-400);flex-shrink:0}`;const m=e(class e extends s{constructor(e){super();if(e!==false){this.__registerHost()}this.dsToolChange=t(this,"dsToolChange");this.dsChromeTransitionStart=t(this,"dsChromeTransitionStart");this.dsChromeTransitionEnd=t(this,"dsChromeTransitionEnd");this.open=false;this.activeTool="";this.items=[];this.itemsJson="";this.motion="idle";this.readyForMotion=false;this.motionEnableGeneration=0;this.handleTransitionEnd=e=>{if(e.target!==this.el.querySelector(".panel-tools__drawer"))return;if(e.propertyName!=="max-width")return;this.motion="idle";this.dsChromeTransitionEnd.emit({source:"panel-tools"})};this.handleToolChange=e=>{const s=!this.isRailSelected(e);if(s){this.open=true;this.activeTool=e}else{this.open=false}this.dsToolChange.emit({id:e,selected:s})}}get railItems(){return p(this.items,this.itemsJson)}disconnectedCallback(){this.el.removeEventListener("transitionend",this.handleTransitionEnd);this.motionEnableGeneration+=1}deferMotionEnable(){if(this.readyForMotion)return;const e=++this.motionEnableGeneration;requestAnimationFrame((()=>{if(e!==this.motionEnableGeneration)return;requestAnimationFrame((()=>{if(e!==this.motionEnableGeneration)return;this.readyForMotion=true}))}))}connectedCallback(){this.el.addEventListener("transitionend",this.handleTransitionEnd)}openChanged(e,s){if(this.readyForMotion&&s!==undefined&&s!==e){this.motion=e?"opening":"closing";this.dsChromeTransitionStart.emit({source:"panel-tools"})}this.deferMotionEnable()}activeToolChanged(){this.deferMotionEnable()}componentDidLoad(){this.deferMotionEnable()}itemsChanged(){this.deferMotionEnable()}isRailSelected(e){return this.open&&this.activeTool===e}isDrawerPresent(){return this.open||this.motion==="closing"}isViewActive(e){return this.isDrawerPresent()&&this.activeTool===e}headerLabel(){if(!this.isDrawerPresent()||!this.activeTool)return"";return h[this.activeTool]??""}renderRailAction(e){return o("ds-bar-nav-action",{key:e.id,class:"panel-tools__rail-action",icon:e.icon,selected:this.isRailSelected(e.id),dot:e.dot??false,inactive:e.inactive,"aria-label":e.ariaLabel??h[e.id],onDsChange:()=>this.handleToolChange(e.id)})}render(){const e=this.headerLabel();const s=this.railItems;const t=s.find((e=>e.id===c));const i=s.filter((e=>e.id!==c));const n=this.isDrawerPresent();return o(a,{key:"d3c5373034a2b2ccc0a0709e2e61ec57a742b30a",class:{"panel-tools":true,"panel-tools--open":this.open,"panel-tools--ready":this.readyForMotion,"panel-tools--motion-opening":this.motion==="opening","panel-tools--motion-closing":this.motion==="closing"},role:"complementary","aria-label":"Tools"},o("div",{key:"d85c8c789ddee4feb74a4244fcfd935f728e5329",class:"panel-tools__layout"},o("div",{key:"6966b1d22836744f5cfde8e8162706090198dd62",class:{"panel-tools__drawer":true,"panel-tools__drawer--visible":n},"aria-hidden":n?null:"true"},o("div",{key:"c1dd1adb653161e86ec0bcb1bc5b4e077d352486",class:"panel-tools__drawer-surface"},o("header",{key:"44efbcbdf3997309713e187f0dfff228fd02875e",class:"panel-tools__header"},o("span",{key:"603b95f799170746a67fdfd5a210b8d10d3ee91c",class:"panel-tools__title text-body-medium-emphasis"},e)),o("div",{key:"3a14b81d263e122e8f7aca8620982c2c6e42f53c",class:"panel-tools__body"},o("div",{key:"e4d01235c9d0cda013d57d94bd60875dd0da3a8b",class:{"panel-tools__view":true,"panel-tools__view--active":this.isViewActive("search"),"text-body-medium":true},hidden:!this.isViewActive("search")},o("slot",{key:"3b9b957f9f94cc666dad45fd875a95420bea77f9",name:"search"})),o("div",{key:"be533e87563c79b78c91fec17a7120aa4439845e",class:{"panel-tools__view":true,"panel-tools__view--active":this.isViewActive("messages"),"text-body-medium":true},hidden:!this.isViewActive("messages")},o("slot",{key:"40529a7cf1af5fb679ac69decc58e3c7d06c3863",name:"messages"})),o("div",{key:"5f40d1977cbe43f128e491c18221470b793551f0",class:{"panel-tools__view":true,"panel-tools__view--active":this.isViewActive("stacks"),"text-body-medium":true},hidden:!this.isViewActive("stacks")},o("slot",{key:"57f8f0e5ad102a84c2084da78881576863eb3cb1",name:"stacks"})),o("div",{key:"6373116968b9b28a52a460c037f00ad7169c497a",class:{"panel-tools__view":true,"panel-tools__view--active":this.isViewActive("activity"),"text-body-medium":true},hidden:!this.isViewActive("activity")},o("slot",{key:"aef7ca5246031e7f523e7355d3a5b733d456ff45",name:"activity"})),o("div",{key:"78451a05e47f86a5121ace44aeb950671e0ecf07",class:{"panel-tools__view":true,"panel-tools__view--active":this.isViewActive("agents"),"text-body-medium":true},hidden:!this.isViewActive("agents")},o("slot",{key:"9bf0310b820e85f51d232e79b9ea2f7e427fb1fc",name:"agents"}))))),o("nav",{key:"0cc767857ce24c2a0c4e4b2cbd6faabb32699ced",class:"panel-tools__rail","aria-label":"Tool shortcuts"},t?o("div",{class:"panel-tools__rail-header"},this.renderRailAction(t)):null,o("div",{key:"7ce8b3a37209532611b2239b493a50216c6f3ccf",class:"panel-tools__rail-body"},i.map((e=>this.renderRailAction(e)))))))}get el(){return this}static get watchers(){return{open:[{openChanged:0}],activeTool:[{activeToolChanged:0}],items:[{itemsChanged:0}],itemsJson:[{itemsChanged:0}]}}static get style(){return f()}},[262,"ds-panel-tools",{open:[1540],activeTool:[1537,"active-tool"],items:[16],itemsJson:[1,"items-json"],motion:[32],readyForMotion:[32]},undefined,{open:[{openChanged:0}],activeTool:[{activeToolChanged:0}],items:[{itemsChanged:0}],itemsJson:[{itemsChanged:0}]}]);function b(){if(typeof customElements==="undefined"){return}const e=["ds-panel-tools","ds-badge","ds-bar-nav-action","ds-icon"];e.forEach((e=>{switch(e){case"ds-panel-tools":if(!customElements.get(i(e))){customElements.define(i(e),m)}break;case"ds-badge":if(!customElements.get(i(e))){l()}break;case"ds-bar-nav-action":if(!customElements.get(i(e))){r()}break;case"ds-icon":if(!customElements.get(i(e))){d()}break}}))}b();const g=m;const _=b;export{g as DsPanelTools,_ as defineCustomElement};
|
|
1
|
+
import{p as e,H as s,c as o,h as t,a,t as i}from"./index.js";import{p as l}from"./p-Dl1GvZQ2.js";import{d as n}from"./p-CiEc8Nwx.js";import{d as r}from"./p-CCZFMcLe.js";import{d}from"./p-DqBCQRRd.js";const c="search";const p={search:"Search",messages:"Messages",stacks:"Stacks",activity:"Activity",agents:"Agents"};function h(e,s){if(s){return l(s,[])}return e??[]}function f(e,s){return!e&&s==="idle"}const m=()=>`.sc-ds-panel-tools-h{display:block;flex:0 0 auto;box-sizing:border-box;height:100%;min-height:0;overflow:hidden;--_panel-tools-rail-width:var(--dimension-size-600);--_panel-tools-drawer-width:var(--dimension-panel-width-sm);--_panel-tools-border:var(--dimension-stroke-width-012, 1px) solid var(--color-border-tertiary);--_panel-tools-surface-bg:var(--color-background-secondary);--_panel-tools-expand-dur:var(--effect-animation-duration-medium-1, 300ms)}.panel-tools__layout.sc-ds-panel-tools{display:flex;flex-direction:row;align-items:stretch;height:100%;min-height:0;box-sizing:border-box}.panel-tools__drawer.sc-ds-panel-tools{flex:0 0 auto;max-width:0;min-width:0;height:100%;min-height:0;overflow:hidden;box-sizing:border-box;transition:none}.panel-tools--ready.panel-tools--motion-opening.sc-ds-panel-tools-h .panel-tools__drawer.sc-ds-panel-tools{transition:max-width var(--_panel-tools-expand-dur) var(--effect-animation-easing-ease-out, ease-out)}.panel-tools--ready.panel-tools--motion-closing.sc-ds-panel-tools-h .panel-tools__drawer.sc-ds-panel-tools{transition:max-width var(--_panel-tools-expand-dur) var(--effect-animation-easing-ease-in, ease-in)}.panel-tools--open.sc-ds-panel-tools-h .panel-tools__drawer.sc-ds-panel-tools{max-width:var(--_panel-tools-drawer-width)}.panel-tools__drawer--visible.sc-ds-panel-tools{border-left:var(--_panel-tools-border)}.panel-tools__drawer-surface.sc-ds-panel-tools{display:flex;flex-direction:column;width:var(--_panel-tools-drawer-width);height:100%;min-height:0;box-sizing:border-box;background-color:var(--_panel-tools-surface-bg)}ds-app-shell[gradient].sc-ds-panel-tools-h .panel-tools__drawer-surface.sc-ds-panel-tools,ds-app-shell[gradient] .sc-ds-panel-tools-h .panel-tools__drawer-surface.sc-ds-panel-tools,ds-app-shell[grid].sc-ds-panel-tools-h .panel-tools__drawer-surface.sc-ds-panel-tools,ds-app-shell[grid] .sc-ds-panel-tools-h .panel-tools__drawer-surface.sc-ds-panel-tools,ds-app-shell[gradient].sc-ds-panel-tools-h .panel-tools__rail.sc-ds-panel-tools,ds-app-shell[gradient] .sc-ds-panel-tools-h .panel-tools__rail.sc-ds-panel-tools,ds-app-shell[grid].sc-ds-panel-tools-h .panel-tools__rail.sc-ds-panel-tools,ds-app-shell[grid] .sc-ds-panel-tools-h .panel-tools__rail.sc-ds-panel-tools{background-color:transparent}.panel-tools__header.sc-ds-panel-tools{flex:0 0 auto;display:flex;align-items:center;height:var(--dimension-size-600);padding:var(--dimension-space-100);border-bottom:var(--_panel-tools-border);color:var(--color-foreground-primary);box-sizing:border-box;-webkit-user-select:none;user-select:none}.panel-tools__title.sc-ds-panel-tools{display:inline-flex;align-items:center;height:var(--dimension-size-400);padding-inline:var(--dimension-space-100);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.panel-tools__body.sc-ds-panel-tools{flex:1 1 auto;min-height:0;overflow:auto;position:relative}.panel-tools--drawer-resting.sc-ds-panel-tools-h .panel-tools__body.sc-ds-panel-tools{content-visibility:auto;contain-intrinsic-size:auto 200px}.panel-tools__view.sc-ds-panel-tools{display:none;height:100%;min-height:0;box-sizing:border-box;padding:var(--dimension-space-200);color:var(--color-foreground-secondary);font-family:var(--typography-font-family);font-size:var(--typography-fontsize-md);line-height:var(--typography-lineheight-md);font-weight:var(--typography-weight-regular);letter-spacing:var(--typography-letterspacing-negative-half)}.panel-tools__view.sc-ds-panel-tools-s>*,.panel-tools__view .sc-ds-panel-tools-s>*{margin:0;color:var(--color-foreground-secondary);font-family:var(--typography-font-family);font-size:var(--typography-fontsize-md);line-height:var(--typography-lineheight-md);font-weight:var(--typography-weight-regular);letter-spacing:var(--typography-letterspacing-negative-half)}.panel-tools__view--active.sc-ds-panel-tools{display:block}.panel-tools__rail.sc-ds-panel-tools{flex:0 0 var(--_panel-tools-rail-width);width:var(--_panel-tools-rail-width);min-width:var(--_panel-tools-rail-width);display:flex;flex-direction:column;box-sizing:border-box;height:100%;min-height:0;border-left:var(--_panel-tools-border);background-color:var(--_panel-tools-surface-bg)}.panel-tools__rail-header.sc-ds-panel-tools{display:flex;align-items:center;justify-content:center;height:var(--dimension-size-600);padding:var(--dimension-space-100);flex-shrink:0;box-sizing:border-box;border-bottom:var(--_panel-tools-border)}.panel-tools__rail-body.sc-ds-panel-tools{flex:1 1 auto;min-height:0;overflow-y:auto;overflow-x:hidden;display:flex;flex-direction:column;gap:var(--dimension-space-050);padding:var(--dimension-space-100);box-sizing:border-box;scrollbar-width:none}.panel-tools__rail-body.sc-ds-panel-tools::-webkit-scrollbar{display:none}.panel-tools__rail-action.sc-ds-panel-tools{display:flex;align-items:center;justify-content:center;width:100%;height:var(--dimension-size-400);flex-shrink:0}`;const g=e(class e extends s{constructor(e){super();if(e!==false){this.__registerHost()}this.dsToolChange=o(this,"dsToolChange");this.dsChromeTransitionStart=o(this,"dsChromeTransitionStart");this.dsChromeTransitionEnd=o(this,"dsChromeTransitionEnd");this.open=false;this.activeTool="";this.items=[];this.itemsJson="";this.motion="idle";this.readyForMotion=false;this.motionEnableGeneration=0;this.handleTransitionEnd=e=>{if(e.target!==this.el.querySelector(".panel-tools__drawer"))return;if(e.propertyName!=="max-width")return;this.motion="idle";this.dsChromeTransitionEnd.emit({source:"panel-tools"})};this.handleToolChange=e=>{const s=!this.isRailSelected(e);if(s){this.open=true;this.activeTool=e}else{this.open=false}this.dsToolChange.emit({id:e,selected:s})}}get railItems(){return h(this.items,this.itemsJson)}disconnectedCallback(){this.el.removeEventListener("transitionend",this.handleTransitionEnd);this.motionEnableGeneration+=1}deferMotionEnable(){if(this.readyForMotion)return;const e=++this.motionEnableGeneration;requestAnimationFrame((()=>{if(e!==this.motionEnableGeneration)return;requestAnimationFrame((()=>{if(e!==this.motionEnableGeneration)return;this.readyForMotion=true}))}))}connectedCallback(){this.el.addEventListener("transitionend",this.handleTransitionEnd)}openChanged(e,s){if(this.readyForMotion&&s!==undefined&&s!==e){this.motion=e?"opening":"closing";this.dsChromeTransitionStart.emit({source:"panel-tools"})}this.deferMotionEnable()}activeToolChanged(){this.deferMotionEnable()}componentDidLoad(){this.deferMotionEnable()}itemsChanged(){this.deferMotionEnable()}isRailSelected(e){return this.open&&this.activeTool===e}isDrawerPresent(){return this.open||this.motion==="closing"}isViewActive(e){return this.isDrawerPresent()&&this.activeTool===e}headerLabel(){if(!this.isDrawerPresent()||!this.activeTool)return"";return p[this.activeTool]??""}renderRailAction(e){return t("ds-bar-nav-action",{key:e.id,class:"panel-tools__rail-action",icon:e.icon,selected:this.isRailSelected(e.id),dot:e.dot??false,inactive:e.inactive,"aria-label":e.ariaLabel??p[e.id],onDsChange:()=>this.handleToolChange(e.id)})}render(){const e=this.headerLabel();const s=this.railItems;const o=s.find((e=>e.id===c));const i=s.filter((e=>e.id!==c));const l=this.isDrawerPresent();const n=f(this.open,this.motion);return t(a,{key:"3359add6059bfec442b6ff85cdcced1a8b2038d1",class:{"panel-tools":true,"panel-tools--open":this.open,"panel-tools--ready":this.readyForMotion,"panel-tools--motion-opening":this.motion==="opening","panel-tools--motion-closing":this.motion==="closing","panel-tools--drawer-resting":n},role:"complementary","aria-label":"Tools"},t("div",{key:"6c815a765578ca3d52d7818d3580cf38774446cc",class:"panel-tools__layout"},t("div",{key:"b0250a75f4ac645cc30b74d4b25d382719971b2f",class:{"panel-tools__drawer":true,"panel-tools__drawer--visible":l},"aria-hidden":l?null:"true"},t("div",{key:"5d958c0796273301fa0bac9dfe364ef8975f3c5b",class:"panel-tools__drawer-surface"},t("header",{key:"b18e7494c619b5f7212be9218023efca54c62ca7",class:"panel-tools__header"},t("span",{key:"957dfdd0dec696b3366e62d8d9f135f9d6f5f4a2",class:"panel-tools__title text-body-medium-emphasis"},e)),t("div",{key:"c173830d0226975cb95ecc22992dd0d3b17edc3d",class:"panel-tools__body"},t("div",{key:"3b5d3dfc7b96dd62578da34d233848edeaf473b3",class:{"panel-tools__view":true,"panel-tools__view--active":this.isViewActive("search"),"text-body-medium":true},hidden:!this.isViewActive("search")},t("slot",{key:"23cb69264669e69a5d31afeae9df08cf24dde050",name:"search"})),t("div",{key:"099ea6aade2d9647b6d1e3b3d370732320d9b10e",class:{"panel-tools__view":true,"panel-tools__view--active":this.isViewActive("messages"),"text-body-medium":true},hidden:!this.isViewActive("messages")},t("slot",{key:"05a9f57f047fa1effa6e300237c671aa3946cbda",name:"messages"})),t("div",{key:"1505c00a7f9d2cc4d058169f6b47586ffb4d7204",class:{"panel-tools__view":true,"panel-tools__view--active":this.isViewActive("stacks"),"text-body-medium":true},hidden:!this.isViewActive("stacks")},t("slot",{key:"a8f6826f5f47470cd910cdc0a03932d19b0e0e2b",name:"stacks"})),t("div",{key:"090111d7e451144bb13f916afdbb979ee43c36df",class:{"panel-tools__view":true,"panel-tools__view--active":this.isViewActive("activity"),"text-body-medium":true},hidden:!this.isViewActive("activity")},t("slot",{key:"3044e860002177150acb4389589d7a3234740a17",name:"activity"})),t("div",{key:"1951cfe74176b4a7db8c62a7045e32f75c98755d",class:{"panel-tools__view":true,"panel-tools__view--active":this.isViewActive("agents"),"text-body-medium":true},hidden:!this.isViewActive("agents")},t("slot",{key:"5c8eda79a06e0c2f3e06e380fc5b8dfc07ed68c1",name:"agents"}))))),t("nav",{key:"4b9286f275f7dadee02368d8b0db80253dedfc5f",class:"panel-tools__rail","aria-label":"Tool shortcuts"},o?t("div",{class:"panel-tools__rail-header"},this.renderRailAction(o)):null,t("div",{key:"7ce3ceb4221688687e77537d6fad3173f1eb0a57",class:"panel-tools__rail-body"},i.map((e=>this.renderRailAction(e)))))))}get el(){return this}static get watchers(){return{open:[{openChanged:0}],activeTool:[{activeToolChanged:0}],items:[{itemsChanged:0}],itemsJson:[{itemsChanged:0}]}}static get style(){return m()}},[262,"ds-panel-tools",{open:[1540],activeTool:[1537,"active-tool"],items:[16],itemsJson:[1,"items-json"],motion:[32],readyForMotion:[32]},undefined,{open:[{openChanged:0}],activeTool:[{activeToolChanged:0}],items:[{itemsChanged:0}],itemsJson:[{itemsChanged:0}]}]);function b(){if(typeof customElements==="undefined"){return}const e=["ds-panel-tools","ds-badge","ds-bar-nav-action","ds-icon"];e.forEach((e=>{switch(e){case"ds-panel-tools":if(!customElements.get(i(e))){customElements.define(i(e),g)}break;case"ds-badge":if(!customElements.get(i(e))){n()}break;case"ds-bar-nav-action":if(!customElements.get(i(e))){r()}break;case"ds-icon":if(!customElements.get(i(e))){d()}break}}))}b();const _=g;const v=b;export{_ as DsPanelTools,v as defineCustomElement};
|
|
2
2
|
//# sourceMappingURL=ds-panel-tools.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["PANEL_TOOLS_PRIMARY_TOOL_ID","PANEL_TOOLS_LABELS","search","messages","stacks","activity","agents","parsePanelToolsItems","items","itemsJson","parseJsonArrayProp","panelToolsCss","PanelTools","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","open","activeTool","motion","readyForMotion","motionEnableGeneration","handleTransitionEnd","event","target","el","querySelector","propertyName","dsChromeTransitionEnd","emit","source","handleToolChange","id","selected","isRailSelected","dsToolChange","railItems","disconnectedCallback","removeEventListener","deferMotionEnable","generation","requestAnimationFrame","connectedCallback","addEventListener","openChanged","isOpen","wasOpen","undefined","dsChromeTransitionStart","activeToolChanged","componentDidLoad","itemsChanged","isDrawerPresent","isViewActive","headerLabel","renderRailAction","item","h","key","class","icon","dot","inactive","ariaLabel","onDsChange","render","headerItem","find","bodyItems","filter","showDrawerChrome","Host","role","hidden","name","map"],"sources":["src/wc/components/PanelTools/panel-tools-types.ts","src/wc/components/PanelTools/panel-tools-utils.ts","src/wc/components/PanelTools/PanelTools.css?tag=ds-panel-tools&encapsulation=scoped","src/wc/components/PanelTools/PanelTools.tsx"],"sourcesContent":["/** Tool ids for the `ds-panel-tools` rail and drawer views. */\nexport type PanelToolsToolId = 'search' | 'agents' | 'messages' | 'stacks' | 'activity';\n\nexport const PANEL_TOOLS_TOOL_IDS: PanelToolsToolId[] = [\n 'search',\n 'agents',\n 'messages',\n 'stacks',\n 'activity',\n];\n\n/** Rail header slot — mirrors panel-nav M logo row. */\nexport const PANEL_TOOLS_PRIMARY_TOOL_ID: PanelToolsToolId = 'search';\n\nexport const PANEL_TOOLS_LABELS: Record<PanelToolsToolId, string> = {\n search: 'Search',\n messages: 'Messages',\n stacks: 'Stacks',\n activity: 'Activity',\n agents: 'Agents',\n};\n\nexport interface PanelToolsItem {\n id: PanelToolsToolId;\n /** Icon name for <ds-icon>. */\n icon: string;\n /** Whether this rail button is currently pressed/active. */\n selected?: boolean;\n /** Show a notification dot. */\n dot?: boolean;\n inactive?: boolean;\n ariaLabel?: string;\n}\n","import { parseJsonArrayProp } from '../BarNav/bar-nav-utils';\nimport type { PanelToolsItem } from './panel-tools-types';\n\nexport function parsePanelToolsItems(\n items: PanelToolsItem[],\n itemsJson: string,\n): PanelToolsItem[] {\n if (itemsJson) {\n return parseJsonArrayProp<PanelToolsItem>(itemsJson, []);\n }\n return items ?? [];\n}\n\nexport function shouldResyncPanelToolsItems(\n prev: PanelToolsItem[],\n next: PanelToolsItem[],\n): boolean {\n if (prev.length !== next.length) return true;\n return next.some((item, index) => {\n const prior = prev[index];\n if (!prior) return true;\n return (\n prior.id !== item.id ||\n prior.icon !== item.icon ||\n prior.selected !== item.selected ||\n prior.dot !== item.dot ||\n prior.inactive !== item.inactive ||\n prior.ariaLabel !== item.ariaLabel\n );\n });\n}\n",":host {\n display: block;\n flex: 0 0 auto;\n box-sizing: border-box;\n height: 100%;\n min-height: 0;\n overflow: hidden;\n --_panel-tools-rail-width: var(--dimension-size-600);\n --_panel-tools-drawer-width: var(--dimension-panel-width-sm);\n --_panel-tools-border: var(--dimension-stroke-width-012, 1px) solid var(--color-border-tertiary);\n /* Match panel-nav expand timing (medium-1); easing differs by direction. */\n --_panel-tools-expand-dur: var(--effect-animation-duration-medium-1, 300ms);\n}\n\n.panel-tools__layout {\n display: flex;\n flex-direction: row;\n align-items: stretch;\n height: 100%;\n min-height: 0;\n box-sizing: border-box;\n}\n\n/* Clip frame — only max-width animates (slide reveal, same as pre-rail :host). */\n.panel-tools__drawer {\n flex: 0 0 auto;\n max-width: 0;\n min-width: 0;\n height: 100%;\n min-height: 0;\n overflow: hidden;\n box-sizing: border-box;\n transition: none;\n}\n\n:host(.panel-tools--ready.panel-tools--motion-opening) .panel-tools__drawer {\n transition: max-width var(--_panel-tools-expand-dur)\n var(--effect-animation-easing-ease-out, ease-out);\n}\n\n:host(.panel-tools--ready.panel-tools--motion-closing) .panel-tools__drawer {\n transition: max-width var(--_panel-tools-expand-dur)\n var(--effect-animation-easing-ease-in, ease-in);\n}\n\n:host(.panel-tools--open) .panel-tools__drawer {\n max-width: var(--_panel-tools-drawer-width);\n}\n\n.panel-tools__drawer--visible {\n border-left: var(--_panel-tools-border);\n}\n\n/* Fixed-width surface — stays 400px while the clip frame opens/closes. */\n.panel-tools__drawer-surface {\n display: flex;\n flex-direction: column;\n width: var(--_panel-tools-drawer-width);\n height: 100%;\n min-height: 0;\n box-sizing: border-box;\n background-color: var(--color-background-primary);\n}\n\n/* Shell-owned chrome (bg + wash + grid) — drawer is a transparent frame. */\n:host-context(ds-app-shell[gradient]) .panel-tools__drawer-surface,\n:host-context(ds-app-shell[grid]) .panel-tools__drawer-surface {\n background-color: transparent;\n}\n\n/* Aligns with ds-bar-nav row — same height, inset, border, and title token. */\n.panel-tools__header {\n flex: 0 0 auto;\n display: flex;\n align-items: center;\n height: var(--dimension-size-600);\n padding: var(--dimension-space-100);\n border-bottom: var(--_panel-tools-border);\n color: var(--color-foreground-primary);\n box-sizing: border-box;\n -webkit-user-select: none;\n user-select: none;\n}\n\n.panel-tools__title {\n display: inline-flex;\n align-items: center;\n height: var(--dimension-size-400);\n padding-inline: var(--dimension-space-100);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.panel-tools__body {\n flex: 1 1 auto;\n min-height: 0;\n overflow: auto;\n position: relative;\n}\n\n.panel-tools__view {\n display: none;\n height: 100%;\n min-height: 0;\n box-sizing: border-box;\n padding: var(--dimension-space-200);\n color: var(--color-foreground-secondary);\n font-family: var(--typography-font-family);\n font-size: var(--typography-fontsize-md);\n line-height: var(--typography-lineheight-md);\n font-weight: var(--typography-weight-regular);\n letter-spacing: var(--typography-letterspacing-negative-half);\n}\n\n.panel-tools__view ::slotted(*) {\n margin: 0;\n color: var(--color-foreground-secondary);\n font-family: var(--typography-font-family);\n font-size: var(--typography-fontsize-md);\n line-height: var(--typography-lineheight-md);\n font-weight: var(--typography-weight-regular);\n letter-spacing: var(--typography-letterspacing-negative-half);\n}\n\n.panel-tools__view--active {\n display: block;\n}\n\n/* Rail — mirrors collapsed panel-nav width, padding, and item rhythm. */\n.panel-tools__rail {\n flex: 0 0 var(--_panel-tools-rail-width);\n width: var(--_panel-tools-rail-width);\n min-width: var(--_panel-tools-rail-width);\n display: flex;\n flex-direction: column;\n box-sizing: border-box;\n height: 100%;\n min-height: 0;\n border-left: var(--_panel-tools-border);\n}\n\n.panel-tools__rail-header {\n display: flex;\n align-items: center;\n justify-content: center;\n height: var(--dimension-size-600);\n padding: var(--dimension-space-100);\n flex-shrink: 0;\n box-sizing: border-box;\n border-bottom: var(--_panel-tools-border);\n}\n\n.panel-tools__rail-body {\n flex: 1 1 auto;\n min-height: 0;\n overflow-y: auto;\n overflow-x: hidden;\n display: flex;\n flex-direction: column;\n gap: var(--dimension-space-050);\n padding: var(--dimension-space-100);\n box-sizing: border-box;\n scrollbar-width: none;\n}\n\n.panel-tools__rail-body::-webkit-scrollbar {\n display: none;\n}\n\n.panel-tools__rail-action {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: var(--dimension-size-400);\n flex-shrink: 0;\n}\n","import { Component, Prop, Event, EventEmitter, Element, State, Watch, h, Host } from '@stencil/core';\nimport type { ChromeTransitionDetail } from '../../nav/chrome-transition';\nimport {\n PANEL_TOOLS_LABELS,\n PANEL_TOOLS_PRIMARY_TOOL_ID,\n type PanelToolsItem,\n type PanelToolsToolId,\n} from './panel-tools-types';\nimport { parsePanelToolsItems } from './panel-tools-utils';\n\n@Component({\n tag: 'ds-panel-tools',\n styleUrl: 'PanelTools.css',\n scoped: true,\n})\nexport class PanelTools {\n @Element() el!: HTMLElement;\n\n /** When false, only the icon rail is shown. */\n @Prop({ mutable: true, reflect: true }) open: boolean = false;\n\n /** Active tool view — `search`, `agents`, `messages`, `stacks`, or `activity`. */\n @Prop({ mutable: true, attribute: 'active-tool', reflect: true })\n activeTool: PanelToolsToolId | '' = '';\n\n /**\n * Rail items rendered in the right column.\n * Set via JS property: `el.items = [...]`. Replace the array reference to update.\n */\n @Prop() items: PanelToolsItem[] = [];\n\n /** JSON fallback for `items` — useful when framework bindings don't propagate arrays. */\n @Prop({ attribute: 'items-json' }) itemsJson: string = '';\n\n /** Emitted when a rail button is toggled. Detail = { id, selected }. */\n @Event({ bubbles: true, composed: true }) dsToolChange!: EventEmitter<{\n id: PanelToolsToolId;\n selected: boolean;\n }>;\n\n /** Bubbling lifecycle — `ds-bar-nav` defers overflow checks during drawer motion. */\n @Event({ bubbles: true, composed: true })\n dsChromeTransitionStart!: EventEmitter<ChromeTransitionDetail>;\n\n @Event({ bubbles: true, composed: true })\n dsChromeTransitionEnd!: EventEmitter<ChromeTransitionDetail>;\n\n /** Arms open vs close easing for the in-flight width transition. */\n @State() private motion: 'opening' | 'closing' | 'idle' = 'idle';\n\n /** Suppresses width transition until the host has painted its initial open state. */\n @State() private readyForMotion = false;\n\n private motionEnableGeneration = 0;\n\n private get railItems(): PanelToolsItem[] {\n return parsePanelToolsItems(this.items, this.itemsJson);\n }\n\n disconnectedCallback() {\n this.el.removeEventListener('transitionend', this.handleTransitionEnd);\n this.motionEnableGeneration += 1;\n }\n\n private deferMotionEnable() {\n if (this.readyForMotion) return;\n const generation = ++this.motionEnableGeneration;\n requestAnimationFrame(() => {\n if (generation !== this.motionEnableGeneration) return;\n requestAnimationFrame(() => {\n if (generation !== this.motionEnableGeneration) return;\n this.readyForMotion = true;\n });\n });\n }\n\n connectedCallback() {\n this.el.addEventListener('transitionend', this.handleTransitionEnd);\n }\n\n @Watch('open')\n openChanged(isOpen: boolean, wasOpen?: boolean) {\n if (this.readyForMotion && wasOpen !== undefined && wasOpen !== isOpen) {\n this.motion = isOpen ? 'opening' : 'closing';\n this.dsChromeTransitionStart.emit({ source: 'panel-tools' });\n }\n this.deferMotionEnable();\n }\n\n @Watch('activeTool')\n activeToolChanged() {\n this.deferMotionEnable();\n }\n\n componentDidLoad() {\n this.deferMotionEnable();\n }\n\n @Watch('items')\n @Watch('itemsJson')\n itemsChanged() {\n this.deferMotionEnable();\n }\n\n private handleTransitionEnd = (event: TransitionEvent) => {\n if (event.target !== this.el.querySelector('.panel-tools__drawer')) return;\n if (event.propertyName !== 'max-width') return;\n this.motion = 'idle';\n this.dsChromeTransitionEnd.emit({ source: 'panel-tools' });\n };\n\n /** Rail selection follows `open` immediately — independent of the slide animation. */\n private isRailSelected(id: PanelToolsToolId): boolean {\n return this.open && this.activeTool === id;\n }\n\n /** Drawer body stays mounted while the clip frame animates closed. */\n private isDrawerPresent(): boolean {\n return this.open || this.motion === 'closing';\n }\n\n private isViewActive(id: PanelToolsToolId): boolean {\n return this.isDrawerPresent() && this.activeTool === id;\n }\n\n private headerLabel(): string {\n if (!this.isDrawerPresent() || !this.activeTool) return '';\n return PANEL_TOOLS_LABELS[this.activeTool as PanelToolsToolId] ?? '';\n }\n\n private handleToolChange = (id: PanelToolsToolId) => {\n const selected = !this.isRailSelected(id);\n if (selected) {\n this.open = true;\n this.activeTool = id;\n } else {\n this.open = false;\n }\n this.dsToolChange.emit({ id, selected });\n };\n\n private renderRailAction(item: PanelToolsItem) {\n return (\n <ds-bar-nav-action\n key={item.id}\n class=\"panel-tools__rail-action\"\n icon={item.icon}\n selected={this.isRailSelected(item.id)}\n dot={item.dot ?? false}\n inactive={item.inactive}\n aria-label={item.ariaLabel ?? PANEL_TOOLS_LABELS[item.id]}\n onDsChange={() => this.handleToolChange(item.id)}\n />\n );\n }\n\n render() {\n const headerLabel = this.headerLabel();\n const railItems = this.railItems;\n const headerItem = railItems.find(item => item.id === PANEL_TOOLS_PRIMARY_TOOL_ID);\n const bodyItems = railItems.filter(item => item.id !== PANEL_TOOLS_PRIMARY_TOOL_ID);\n const showDrawerChrome = this.isDrawerPresent();\n\n return (\n <Host\n class={{\n 'panel-tools': true,\n 'panel-tools--open': this.open,\n 'panel-tools--ready': this.readyForMotion,\n 'panel-tools--motion-opening': this.motion === 'opening',\n 'panel-tools--motion-closing': this.motion === 'closing',\n }}\n role=\"complementary\"\n aria-label=\"Tools\"\n >\n <div class=\"panel-tools__layout\">\n <div\n class={{\n 'panel-tools__drawer': true,\n 'panel-tools__drawer--visible': showDrawerChrome,\n }}\n aria-hidden={showDrawerChrome ? null : 'true'}\n >\n <div class=\"panel-tools__drawer-surface\">\n <header class=\"panel-tools__header\">\n <span class=\"panel-tools__title text-body-medium-emphasis\">{headerLabel}</span>\n </header>\n <div class=\"panel-tools__body\">\n <div\n class={{\n 'panel-tools__view': true,\n 'panel-tools__view--active': this.isViewActive('search'),\n 'text-body-medium': true,\n }}\n hidden={!this.isViewActive('search')}\n >\n <slot name=\"search\" />\n </div>\n <div\n class={{\n 'panel-tools__view': true,\n 'panel-tools__view--active': this.isViewActive('messages'),\n 'text-body-medium': true,\n }}\n hidden={!this.isViewActive('messages')}\n >\n <slot name=\"messages\" />\n </div>\n <div\n class={{\n 'panel-tools__view': true,\n 'panel-tools__view--active': this.isViewActive('stacks'),\n 'text-body-medium': true,\n }}\n hidden={!this.isViewActive('stacks')}\n >\n <slot name=\"stacks\" />\n </div>\n <div\n class={{\n 'panel-tools__view': true,\n 'panel-tools__view--active': this.isViewActive('activity'),\n 'text-body-medium': true,\n }}\n hidden={!this.isViewActive('activity')}\n >\n <slot name=\"activity\" />\n </div>\n <div\n class={{\n 'panel-tools__view': true,\n 'panel-tools__view--active': this.isViewActive('agents'),\n 'text-body-medium': true,\n }}\n hidden={!this.isViewActive('agents')}\n >\n <slot name=\"agents\" />\n </div>\n </div>\n </div>\n </div>\n\n <nav class=\"panel-tools__rail\" aria-label=\"Tool shortcuts\">\n {headerItem ? (\n <div class=\"panel-tools__rail-header\">{this.renderRailAction(headerItem)}</div>\n ) : null}\n <div class=\"panel-tools__rail-body\">\n {bodyItems.map(item => this.renderRailAction(item))}\n </div>\n </nav>\n </div>\n </Host>\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["PANEL_TOOLS_PRIMARY_TOOL_ID","PANEL_TOOLS_LABELS","search","messages","stacks","activity","agents","parsePanelToolsItems","items","itemsJson","parseJsonArrayProp","panelToolsDrawerResting","open","motion","panelToolsCss","PanelTools","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","activeTool","readyForMotion","motionEnableGeneration","handleTransitionEnd","event","target","el","querySelector","propertyName","dsChromeTransitionEnd","emit","source","handleToolChange","id","selected","isRailSelected","dsToolChange","railItems","disconnectedCallback","removeEventListener","deferMotionEnable","generation","requestAnimationFrame","connectedCallback","addEventListener","openChanged","isOpen","wasOpen","undefined","dsChromeTransitionStart","activeToolChanged","componentDidLoad","itemsChanged","isDrawerPresent","isViewActive","headerLabel","renderRailAction","item","h","key","class","icon","dot","inactive","ariaLabel","onDsChange","render","headerItem","find","bodyItems","filter","showDrawerChrome","drawerResting","Host","role","hidden","name","map"],"sources":["src/wc/components/PanelTools/panel-tools-types.ts","src/wc/components/PanelTools/panel-tools-utils.ts","src/wc/components/PanelTools/PanelTools.css?tag=ds-panel-tools&encapsulation=scoped","src/wc/components/PanelTools/PanelTools.tsx"],"sourcesContent":["/** Tool ids for the `ds-panel-tools` rail and drawer views. */\nexport type PanelToolsToolId = 'search' | 'agents' | 'messages' | 'stacks' | 'activity';\n\nexport const PANEL_TOOLS_TOOL_IDS: PanelToolsToolId[] = [\n 'search',\n 'agents',\n 'messages',\n 'stacks',\n 'activity',\n];\n\n/** Rail header slot — mirrors panel-nav M logo row. */\nexport const PANEL_TOOLS_PRIMARY_TOOL_ID: PanelToolsToolId = 'search';\n\nexport const PANEL_TOOLS_LABELS: Record<PanelToolsToolId, string> = {\n search: 'Search',\n messages: 'Messages',\n stacks: 'Stacks',\n activity: 'Activity',\n agents: 'Agents',\n};\n\nexport interface PanelToolsItem {\n id: PanelToolsToolId;\n /** Icon name for <ds-icon>. */\n icon: string;\n /** Whether this rail button is currently pressed/active. */\n selected?: boolean;\n /** Show a notification dot. */\n dot?: boolean;\n inactive?: boolean;\n ariaLabel?: string;\n}\n","import { parseJsonArrayProp } from '../BarNav/bar-nav-utils';\nimport type { PanelToolsItem } from './panel-tools-types';\n\nexport function parsePanelToolsItems(\n items: PanelToolsItem[],\n itemsJson: string,\n): PanelToolsItem[] {\n if (itemsJson) {\n return parseJsonArrayProp<PanelToolsItem>(itemsJson, []);\n }\n return items ?? [];\n}\n\nexport function shouldResyncPanelToolsItems(\n prev: PanelToolsItem[],\n next: PanelToolsItem[],\n): boolean {\n if (prev.length !== next.length) return true;\n return next.some((item, index) => {\n const prior = prev[index];\n if (!prior) return true;\n return (\n prior.id !== item.id ||\n prior.icon !== item.icon ||\n prior.selected !== item.selected ||\n prior.dot !== item.dot ||\n prior.inactive !== item.inactive ||\n prior.ariaLabel !== item.ariaLabel\n );\n });\n}\n\nexport type PanelToolsMotion = 'opening' | 'closing' | 'idle';\n\n/** True when the drawer clip is fully closed — safe to skip painting slot content. */\nexport function panelToolsDrawerResting(open: boolean, motion: PanelToolsMotion): boolean {\n return !open && motion === 'idle';\n}\n",":host {\n display: block;\n flex: 0 0 auto;\n box-sizing: border-box;\n height: 100%;\n min-height: 0;\n overflow: hidden;\n --_panel-tools-rail-width: var(--dimension-size-600);\n --_panel-tools-drawer-width: var(--dimension-panel-width-sm);\n --_panel-tools-border: var(--dimension-stroke-width-012, 1px) solid var(--color-border-tertiary);\n --_panel-tools-surface-bg: var(--color-background-secondary);\n /* Match panel-nav expand timing (medium-1); easing differs by direction. */\n --_panel-tools-expand-dur: var(--effect-animation-duration-medium-1, 300ms);\n}\n\n.panel-tools__layout {\n display: flex;\n flex-direction: row;\n align-items: stretch;\n height: 100%;\n min-height: 0;\n box-sizing: border-box;\n}\n\n/* Clip frame — only max-width animates (slide reveal, same as pre-rail :host). */\n.panel-tools__drawer {\n flex: 0 0 auto;\n max-width: 0;\n min-width: 0;\n height: 100%;\n min-height: 0;\n overflow: hidden;\n box-sizing: border-box;\n transition: none;\n}\n\n:host(.panel-tools--ready.panel-tools--motion-opening) .panel-tools__drawer {\n transition: max-width var(--_panel-tools-expand-dur)\n var(--effect-animation-easing-ease-out, ease-out);\n}\n\n:host(.panel-tools--ready.panel-tools--motion-closing) .panel-tools__drawer {\n transition: max-width var(--_panel-tools-expand-dur)\n var(--effect-animation-easing-ease-in, ease-in);\n}\n\n:host(.panel-tools--open) .panel-tools__drawer {\n max-width: var(--_panel-tools-drawer-width);\n}\n\n.panel-tools__drawer--visible {\n border-left: var(--_panel-tools-border);\n}\n\n/* Fixed-width surface — stays 400px while the clip frame opens/closes. */\n.panel-tools__drawer-surface {\n display: flex;\n flex-direction: column;\n width: var(--_panel-tools-drawer-width);\n height: 100%;\n min-height: 0;\n box-sizing: border-box;\n background-color: var(--_panel-tools-surface-bg);\n}\n\n/* Shell-owned chrome (bg + wash +/or grid) — drawer + rail are transparent frames. */\n:host-context(ds-app-shell[gradient]) .panel-tools__drawer-surface,\n:host-context(ds-app-shell[grid]) .panel-tools__drawer-surface,\n:host-context(ds-app-shell[gradient]) .panel-tools__rail,\n:host-context(ds-app-shell[grid]) .panel-tools__rail {\n background-color: transparent;\n}\n\n/* Aligns with ds-bar-nav row — same height, inset, border, and title token. */\n.panel-tools__header {\n flex: 0 0 auto;\n display: flex;\n align-items: center;\n height: var(--dimension-size-600);\n padding: var(--dimension-space-100);\n border-bottom: var(--_panel-tools-border);\n color: var(--color-foreground-primary);\n box-sizing: border-box;\n -webkit-user-select: none;\n user-select: none;\n}\n\n.panel-tools__title {\n display: inline-flex;\n align-items: center;\n height: var(--dimension-size-400);\n padding-inline: var(--dimension-space-100);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.panel-tools__body {\n flex: 1 1 auto;\n min-height: 0;\n overflow: auto;\n position: relative;\n}\n\n/* Skip paint while fully closed; cleared during open/close motion for WYSIWYG slide. */\n:host(.panel-tools--drawer-resting) .panel-tools__body {\n content-visibility: auto;\n contain-intrinsic-size: auto 200px;\n}\n\n.panel-tools__view {\n display: none;\n height: 100%;\n min-height: 0;\n box-sizing: border-box;\n padding: var(--dimension-space-200);\n color: var(--color-foreground-secondary);\n font-family: var(--typography-font-family);\n font-size: var(--typography-fontsize-md);\n line-height: var(--typography-lineheight-md);\n font-weight: var(--typography-weight-regular);\n letter-spacing: var(--typography-letterspacing-negative-half);\n}\n\n.panel-tools__view ::slotted(*) {\n margin: 0;\n color: var(--color-foreground-secondary);\n font-family: var(--typography-font-family);\n font-size: var(--typography-fontsize-md);\n line-height: var(--typography-lineheight-md);\n font-weight: var(--typography-weight-regular);\n letter-spacing: var(--typography-letterspacing-negative-half);\n}\n\n.panel-tools__view--active {\n display: block;\n}\n\n/* Rail — mirrors collapsed panel-nav width, padding, and item rhythm. */\n.panel-tools__rail {\n flex: 0 0 var(--_panel-tools-rail-width);\n width: var(--_panel-tools-rail-width);\n min-width: var(--_panel-tools-rail-width);\n display: flex;\n flex-direction: column;\n box-sizing: border-box;\n height: 100%;\n min-height: 0;\n border-left: var(--_panel-tools-border);\n background-color: var(--_panel-tools-surface-bg);\n}\n\n.panel-tools__rail-header {\n display: flex;\n align-items: center;\n justify-content: center;\n height: var(--dimension-size-600);\n padding: var(--dimension-space-100);\n flex-shrink: 0;\n box-sizing: border-box;\n border-bottom: var(--_panel-tools-border);\n}\n\n.panel-tools__rail-body {\n flex: 1 1 auto;\n min-height: 0;\n overflow-y: auto;\n overflow-x: hidden;\n display: flex;\n flex-direction: column;\n gap: var(--dimension-space-050);\n padding: var(--dimension-space-100);\n box-sizing: border-box;\n scrollbar-width: none;\n}\n\n.panel-tools__rail-body::-webkit-scrollbar {\n display: none;\n}\n\n.panel-tools__rail-action {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: var(--dimension-size-400);\n flex-shrink: 0;\n}\n","import { Component, Prop, Event, EventEmitter, Element, State, Watch, h, Host } from '@stencil/core';\nimport type { ChromeTransitionDetail } from '../../nav/chrome-transition';\nimport {\n PANEL_TOOLS_LABELS,\n PANEL_TOOLS_PRIMARY_TOOL_ID,\n type PanelToolsItem,\n type PanelToolsToolId,\n} from './panel-tools-types';\nimport { parsePanelToolsItems, panelToolsDrawerResting } from './panel-tools-utils';\n\n@Component({\n tag: 'ds-panel-tools',\n styleUrl: 'PanelTools.css',\n scoped: true,\n})\nexport class PanelTools {\n @Element() el!: HTMLElement;\n\n /** When false, only the icon rail is shown. */\n @Prop({ mutable: true, reflect: true }) open: boolean = false;\n\n /** Active tool view — `search`, `agents`, `messages`, `stacks`, or `activity`. */\n @Prop({ mutable: true, attribute: 'active-tool', reflect: true })\n activeTool: PanelToolsToolId | '' = '';\n\n /**\n * Rail items rendered in the right column.\n * Set via JS property: `el.items = [...]`. Replace the array reference to update.\n */\n @Prop() items: PanelToolsItem[] = [];\n\n /** JSON fallback for `items` — useful when framework bindings don't propagate arrays. */\n @Prop({ attribute: 'items-json' }) itemsJson: string = '';\n\n /** Emitted when a rail button is toggled. Detail = { id, selected }. */\n @Event({ bubbles: true, composed: true }) dsToolChange!: EventEmitter<{\n id: PanelToolsToolId;\n selected: boolean;\n }>;\n\n /** Bubbling lifecycle — `ds-bar-nav` defers overflow checks during drawer motion. */\n @Event({ bubbles: true, composed: true })\n dsChromeTransitionStart!: EventEmitter<ChromeTransitionDetail>;\n\n @Event({ bubbles: true, composed: true })\n dsChromeTransitionEnd!: EventEmitter<ChromeTransitionDetail>;\n\n /** Arms open vs close easing for the in-flight width transition. */\n @State() private motion: 'opening' | 'closing' | 'idle' = 'idle';\n\n /** Suppresses width transition until the host has painted its initial open state. */\n @State() private readyForMotion = false;\n\n private motionEnableGeneration = 0;\n\n private get railItems(): PanelToolsItem[] {\n return parsePanelToolsItems(this.items, this.itemsJson);\n }\n\n disconnectedCallback() {\n this.el.removeEventListener('transitionend', this.handleTransitionEnd);\n this.motionEnableGeneration += 1;\n }\n\n private deferMotionEnable() {\n if (this.readyForMotion) return;\n const generation = ++this.motionEnableGeneration;\n requestAnimationFrame(() => {\n if (generation !== this.motionEnableGeneration) return;\n requestAnimationFrame(() => {\n if (generation !== this.motionEnableGeneration) return;\n this.readyForMotion = true;\n });\n });\n }\n\n connectedCallback() {\n this.el.addEventListener('transitionend', this.handleTransitionEnd);\n }\n\n @Watch('open')\n openChanged(isOpen: boolean, wasOpen?: boolean) {\n if (this.readyForMotion && wasOpen !== undefined && wasOpen !== isOpen) {\n this.motion = isOpen ? 'opening' : 'closing';\n this.dsChromeTransitionStart.emit({ source: 'panel-tools' });\n }\n this.deferMotionEnable();\n }\n\n @Watch('activeTool')\n activeToolChanged() {\n this.deferMotionEnable();\n }\n\n componentDidLoad() {\n this.deferMotionEnable();\n }\n\n @Watch('items')\n @Watch('itemsJson')\n itemsChanged() {\n this.deferMotionEnable();\n }\n\n private handleTransitionEnd = (event: TransitionEvent) => {\n if (event.target !== this.el.querySelector('.panel-tools__drawer')) return;\n if (event.propertyName !== 'max-width') return;\n this.motion = 'idle';\n this.dsChromeTransitionEnd.emit({ source: 'panel-tools' });\n };\n\n /** Rail selection follows `open` immediately — independent of the slide animation. */\n private isRailSelected(id: PanelToolsToolId): boolean {\n return this.open && this.activeTool === id;\n }\n\n /** Drawer body stays mounted while the clip frame animates closed. */\n private isDrawerPresent(): boolean {\n return this.open || this.motion === 'closing';\n }\n\n private isViewActive(id: PanelToolsToolId): boolean {\n return this.isDrawerPresent() && this.activeTool === id;\n }\n\n private headerLabel(): string {\n if (!this.isDrawerPresent() || !this.activeTool) return '';\n return PANEL_TOOLS_LABELS[this.activeTool as PanelToolsToolId] ?? '';\n }\n\n private handleToolChange = (id: PanelToolsToolId) => {\n const selected = !this.isRailSelected(id);\n if (selected) {\n this.open = true;\n this.activeTool = id;\n } else {\n this.open = false;\n }\n this.dsToolChange.emit({ id, selected });\n };\n\n private renderRailAction(item: PanelToolsItem) {\n return (\n <ds-bar-nav-action\n key={item.id}\n class=\"panel-tools__rail-action\"\n icon={item.icon}\n selected={this.isRailSelected(item.id)}\n dot={item.dot ?? false}\n inactive={item.inactive}\n aria-label={item.ariaLabel ?? PANEL_TOOLS_LABELS[item.id]}\n onDsChange={() => this.handleToolChange(item.id)}\n />\n );\n }\n\n render() {\n const headerLabel = this.headerLabel();\n const railItems = this.railItems;\n const headerItem = railItems.find(item => item.id === PANEL_TOOLS_PRIMARY_TOOL_ID);\n const bodyItems = railItems.filter(item => item.id !== PANEL_TOOLS_PRIMARY_TOOL_ID);\n const showDrawerChrome = this.isDrawerPresent();\n const drawerResting = panelToolsDrawerResting(this.open, this.motion);\n\n return (\n <Host\n class={{\n 'panel-tools': true,\n 'panel-tools--open': this.open,\n 'panel-tools--ready': this.readyForMotion,\n 'panel-tools--motion-opening': this.motion === 'opening',\n 'panel-tools--motion-closing': this.motion === 'closing',\n 'panel-tools--drawer-resting': drawerResting,\n }}\n role=\"complementary\"\n aria-label=\"Tools\"\n >\n <div class=\"panel-tools__layout\">\n <div\n class={{\n 'panel-tools__drawer': true,\n 'panel-tools__drawer--visible': showDrawerChrome,\n }}\n aria-hidden={showDrawerChrome ? null : 'true'}\n >\n <div class=\"panel-tools__drawer-surface\">\n <header class=\"panel-tools__header\">\n <span class=\"panel-tools__title text-body-medium-emphasis\">{headerLabel}</span>\n </header>\n <div class=\"panel-tools__body\">\n <div\n class={{\n 'panel-tools__view': true,\n 'panel-tools__view--active': this.isViewActive('search'),\n 'text-body-medium': true,\n }}\n hidden={!this.isViewActive('search')}\n >\n <slot name=\"search\" />\n </div>\n <div\n class={{\n 'panel-tools__view': true,\n 'panel-tools__view--active': this.isViewActive('messages'),\n 'text-body-medium': true,\n }}\n hidden={!this.isViewActive('messages')}\n >\n <slot name=\"messages\" />\n </div>\n <div\n class={{\n 'panel-tools__view': true,\n 'panel-tools__view--active': this.isViewActive('stacks'),\n 'text-body-medium': true,\n }}\n hidden={!this.isViewActive('stacks')}\n >\n <slot name=\"stacks\" />\n </div>\n <div\n class={{\n 'panel-tools__view': true,\n 'panel-tools__view--active': this.isViewActive('activity'),\n 'text-body-medium': true,\n }}\n hidden={!this.isViewActive('activity')}\n >\n <slot name=\"activity\" />\n </div>\n <div\n class={{\n 'panel-tools__view': true,\n 'panel-tools__view--active': this.isViewActive('agents'),\n 'text-body-medium': true,\n }}\n hidden={!this.isViewActive('agents')}\n >\n <slot name=\"agents\" />\n </div>\n </div>\n </div>\n </div>\n\n <nav class=\"panel-tools__rail\" aria-label=\"Tool shortcuts\">\n {headerItem ? (\n <div class=\"panel-tools__rail-header\">{this.renderRailAction(headerItem)}</div>\n ) : null}\n <div class=\"panel-tools__rail-body\">\n {bodyItems.map(item => this.renderRailAction(item))}\n </div>\n </nav>\n </div>\n </Host>\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const t="dsChromeTransitionStart";const n="dsChromeTransitionEnd";class e{constructor(){this.depth=0}enter(){this.depth+=1}exit(){this.depth=Math.max(0,this.depth-1)}get isActive(){return this.depth>0}}function i(t){let n=0;return{schedule(){if(n!==0)return;n=requestAnimationFrame((()=>{n=0;t()}))},cancel(){if(n!==0){cancelAnimationFrame(n);n=0}}}}function r(t){return t.detail?.source}function s(t,n){if(typeof document==="undefined")return 0;const e=document.createElement("div");e.style.cssText="position:absolute;visibility:hidden;pointer-events:none;height:0;width:var("+n+");";t.appendChild(e);const i=e.getBoundingClientRect().width;t.removeChild(e);return i}function a(t){return{expandedPx:s(t,"--_nav-width"),collapsedPx:s(t,"--_nav-width-collapsed")}}function o(t,n){if(n?.classList.contains("panel-nav--collapsed"))return true;const e=t?.collapsed;return e===true}function c(t,n){return n?t.collapsedPx:t.expandedPx}export{e as C,t as a,n as b,i as c,a as d,s as e,o as i,c as p,r};
|
|
2
|
+
//# sourceMappingURL=p-1HlgCxGN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["CHROME_TRANSITION_START","CHROME_TRANSITION_END","ChromeTransitionDepth","constructor","this","depth","enter","exit","Math","max","isActive","createRafCoalescer","onFrame","rafId","schedule","requestAnimationFrame","cancel","cancelAnimationFrame","readChromeTransitionSource","event","detail","source","readCssVarWidthPx","context","cssVarName","document","probe","createElement","style","cssText","appendChild","width","getBoundingClientRect","removeChild","readPanelNavWidthTokens","navRoot","expandedPx","collapsedPx","isPanelNavCollapsed","panelNavHost","classList","contains","collapsedProp","collapsed","panelWidthPxFromTokens","tokens"],"sources":["src/wc/nav/chrome-transition.ts","src/wc/nav/shell-chrome-metrics.ts"],"sourcesContent":["/** Bubbling/composed events — `ds-app-shell` and `ds-bar-nav` coordinate during width motion. */\n\nexport const CHROME_TRANSITION_START = 'dsChromeTransitionStart';\nexport const CHROME_TRANSITION_END = 'dsChromeTransitionEnd';\n\nexport type ChromeTransitionSource = 'panel-nav' | 'panel-tools';\n\nexport interface ChromeTransitionDetail {\n source: ChromeTransitionSource;\n}\n\n/** Reference-counted gate — used while panel-nav width is transitioning. */\nexport class ChromeTransitionDepth {\n private depth = 0;\n\n enter(): void {\n this.depth += 1;\n }\n\n exit(): void {\n this.depth = Math.max(0, this.depth - 1);\n }\n\n get isActive(): boolean {\n return this.depth > 0;\n }\n}\n\nexport interface RafCoalescer {\n schedule(): void;\n cancel(): void;\n}\n\n/** Coalesce bursty layout work (ResizeObserver, prop churn) to one callback per frame. */\nexport function createRafCoalescer(onFrame: () => void): RafCoalescer {\n let rafId = 0;\n return {\n schedule() {\n if (rafId !== 0) return;\n rafId = requestAnimationFrame(() => {\n rafId = 0;\n onFrame();\n });\n },\n cancel() {\n if (rafId !== 0) {\n cancelAnimationFrame(rafId);\n rafId = 0;\n }\n },\n };\n}\n\nexport function readChromeTransitionSource(event: Event): ChromeTransitionSource | undefined {\n return (event as CustomEvent<ChromeTransitionDetail>).detail?.source;\n}\n","import { shellGradientPositionBar } from './shell-gradient';\n\n/** Read a `var(--token)` width in px using a hidden probe (works with calc() tokens). */\nexport function readCssVarWidthPx(context: HTMLElement, cssVarName: string): number {\n if (typeof document === 'undefined') return 0;\n\n const probe = document.createElement('div');\n probe.style.cssText =\n 'position:absolute;visibility:hidden;pointer-events:none;height:0;width:var(' +\n cssVarName +\n ');';\n context.appendChild(probe);\n const width = probe.getBoundingClientRect().width;\n context.removeChild(probe);\n return width;\n}\n\nexport interface PanelNavWidthTokens {\n expandedPx: number;\n collapsedPx: number;\n}\n\n/** Resolve panel-nav expanded/collapsed widths from scoped CSS vars on `.panel-nav`. */\nexport function readPanelNavWidthTokens(navRoot: HTMLElement): PanelNavWidthTokens {\n return {\n expandedPx: readCssVarWidthPx(navRoot, '--_nav-width'),\n collapsedPx: readCssVarWidthPx(navRoot, '--_nav-width-collapsed'),\n };\n}\n\nexport function isPanelNavCollapsed(\n panelNavHost: HTMLElement | null,\n navRoot: HTMLElement | null,\n): boolean {\n if (navRoot?.classList.contains('panel-nav--collapsed')) return true;\n const collapsedProp = (panelNavHost as (HTMLElement & { collapsed?: boolean }) | null)?.collapsed;\n return collapsedProp === true;\n}\n\nexport function panelWidthPxFromTokens(\n tokens: PanelNavWidthTokens,\n collapsed: boolean,\n): number {\n return collapsed ? tokens.collapsedPx : tokens.expandedPx;\n}\n\nexport function barGradientPositionFromPanelWidth(panelWidthPx: number): string {\n return shellGradientPositionBar(panelWidthPx);\n}\n"],"mappings":"AAEO,MAAMA,EAA0B,0BAChC,MAAMC,EAAwB,wB,MASxBC,EAAb,WAAAC,GACUC,KAAAC,MAAQ,C,CAEhB,KAAAC,GACEF,KAAKC,OAAS,C,CAGhB,IAAAE,GACEH,KAAKC,MAAQG,KAAKC,IAAI,EAAGL,KAAKC,MAAQ,E,CAGxC,YAAIK,GACF,OAAON,KAAKC,MAAQ,C,EAUlB,SAAUM,EAAmBC,GACjC,IAAIC,EAAQ,EACZ,MAAO,CACL,QAAAC,GACE,GAAID,IAAU,EAAG,OACjBA,EAAQE,uBAAsB,KAC5BF,EAAQ,EACRD,GAAS,G,EAGb,MAAAI,GACE,GAAIH,IAAU,EAAG,CACfI,qBAAqBJ,GACrBA,EAAQ,C,GAIhB,CAEM,SAAUK,EAA2BC,GACzC,OAAQA,EAA8CC,QAAQC,MAChE,CCpDM,SAAUC,EAAkBC,EAAsBC,GACtD,UAAWC,WAAa,YAAa,OAAO,EAE5C,MAAMC,EAAQD,SAASE,cAAc,OACrCD,EAAME,MAAMC,QACV,8EACAL,EACA,KACFD,EAAQO,YAAYJ,GACpB,MAAMK,EAAQL,EAAMM,wBAAwBD,MAC5CR,EAAQU,YAAYP,GACpB,OAAOK,CACT,CAQM,SAAUG,EAAwBC,GACtC,MAAO,CACLC,WAAYd,EAAkBa,EAAS,gBACvCE,YAAaf,EAAkBa,EAAS,0BAE5C,CAEM,SAAUG,EACdC,EACAJ,GAEA,GAAIA,GAASK,UAAUC,SAAS,wBAAyB,OAAO,KAChE,MAAMC,EAAiBH,GAAiEI,UACxF,OAAOD,IAAkB,IAC3B,CAEM,SAAUE,EACdC,EACAF,GAEA,OAAOA,EAAYE,EAAOR,YAAcQ,EAAOT,UACjD,Q","ignoreList":[]}
|
|
@@ -13,8 +13,8 @@ export declare class AppShell {
|
|
|
13
13
|
gradientSrc: string;
|
|
14
14
|
el: HTMLElement;
|
|
15
15
|
private resizeObserver;
|
|
16
|
-
private
|
|
17
|
-
private
|
|
16
|
+
private readonly panelNavTransition;
|
|
17
|
+
private readonly chromeSyncCoalescer;
|
|
18
18
|
private panelWidthTokens;
|
|
19
19
|
private cachedShellWidth;
|
|
20
20
|
private cachedShellHeight;
|
|
@@ -57,9 +57,9 @@ export declare class BarNav {
|
|
|
57
57
|
private visibleTabGroupEl;
|
|
58
58
|
private probeTabGroupEl;
|
|
59
59
|
private resizeObserver;
|
|
60
|
-
private overflowCheckScheduled;
|
|
61
60
|
private intrinsicWidthRetryCount;
|
|
62
|
-
private
|
|
61
|
+
private readonly panelNavTransition;
|
|
62
|
+
private readonly overflowCoalescer;
|
|
63
63
|
private chromeTransitionShell;
|
|
64
64
|
private toolsDrawerOpening;
|
|
65
65
|
/** Matches `basePath` once tabs + URL are reconciled for the active section. */
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import type { PanelToolsItem } from './panel-tools-types';
|
|
2
2
|
export declare function parsePanelToolsItems(items: PanelToolsItem[], itemsJson: string): PanelToolsItem[];
|
|
3
3
|
export declare function shouldResyncPanelToolsItems(prev: PanelToolsItem[], next: PanelToolsItem[]): boolean;
|
|
4
|
+
export type PanelToolsMotion = 'opening' | 'closing' | 'idle';
|
|
5
|
+
/** True when the drawer clip is fully closed — safe to skip painting slot content. */
|
|
6
|
+
export declare function panelToolsDrawerResting(open: boolean, motion: PanelToolsMotion): boolean;
|
|
4
7
|
//# sourceMappingURL=panel-tools-utils.d.ts.map
|
|
@@ -5,4 +5,18 @@ export type ChromeTransitionSource = 'panel-nav' | 'panel-tools';
|
|
|
5
5
|
export interface ChromeTransitionDetail {
|
|
6
6
|
source: ChromeTransitionSource;
|
|
7
7
|
}
|
|
8
|
+
/** Reference-counted gate — used while panel-nav width is transitioning. */
|
|
9
|
+
export declare class ChromeTransitionDepth {
|
|
10
|
+
private depth;
|
|
11
|
+
enter(): void;
|
|
12
|
+
exit(): void;
|
|
13
|
+
get isActive(): boolean;
|
|
14
|
+
}
|
|
15
|
+
export interface RafCoalescer {
|
|
16
|
+
schedule(): void;
|
|
17
|
+
cancel(): void;
|
|
18
|
+
}
|
|
19
|
+
/** Coalesce bursty layout work (ResizeObserver, prop churn) to one callback per frame. */
|
|
20
|
+
export declare function createRafCoalescer(onFrame: () => void): RafCoalescer;
|
|
21
|
+
export declare function readChromeTransitionSource(event: Event): ChromeTransitionSource | undefined;
|
|
8
22
|
//# sourceMappingURL=chrome-transition.d.ts.map
|
|
@@ -5,7 +5,7 @@ export type { ShellNavRevealOrigin } from './shell-view-transition';
|
|
|
5
5
|
export { SHELL_GRADIENT_IMAGE_VAR, SHELL_GRADIENT_SIZE_VAR, SHELL_GRADIENT_POSITION_PANEL_VAR, SHELL_GRADIENT_POSITION_BAR_VAR, SHELL_GRADIENT_OPACITY_VAR, SHELL_CHROME_SURFACE_POSITION_VAR, SHELL_GRADIENT_OPACITY, buildShellRadialGradient, shellGradientImage, shellGradientSize, shellGradientPositionPanel, shellGradientPositionBar, shellChromeSurfacePosition, shellChromeLayerActive, } from './shell-gradient';
|
|
6
6
|
export type { ShellGradientLayout } from './shell-gradient';
|
|
7
7
|
export type { ChromeTransitionDetail, ChromeTransitionSource } from './chrome-transition';
|
|
8
|
-
export { CHROME_TRANSITION_END, CHROME_TRANSITION_START, } from './chrome-transition';
|
|
8
|
+
export { CHROME_TRANSITION_END, CHROME_TRANSITION_START, ChromeTransitionDepth, createRafCoalescer, readChromeTransitionSource, } from './chrome-transition';
|
|
9
9
|
export { barGradientPositionFromPanelWidth, isPanelNavCollapsed, panelWidthPxFromTokens, readCssVarWidthPx, readPanelNavWidthTokens, } from './shell-chrome-metrics';
|
|
10
10
|
export type { PanelNavWidthTokens } from './shell-chrome-metrics';
|
|
11
11
|
export { BADGE_GRADIENT_POSITION_VAR, badgeGradientPosition, findGradientSurface, isShellGradientActive, parseCssBackgroundPosition, readShellGradientPosition, syncBadgeGradientPosition, } from './badge-gradient-ring';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ds-mo/ui",
|
|
3
|
-
"version": "1.11.
|
|
3
|
+
"version": "1.11.1",
|
|
4
4
|
"description": "CompoMo — composable web components styled with TokoMo design tokens",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"web-components",
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"pretest": "node scripts/generate-icon-catalog.mjs",
|
|
70
70
|
"build": "stencil build && node scripts/patch-index-types.mjs && node scripts/verify-icons-externalized.mjs && node scripts/write-build-stamp.mjs",
|
|
71
71
|
"verify:pack": "node scripts/verify-npm-pack.mjs && node scripts/verify-nav-import.mjs",
|
|
72
|
-
"test": "node --import tsx/esm --test tests/panel-nav-utils.test.ts tests/panel-tools.test.ts tests/shell-view-transition.test.ts tests/shell-gradient.test.ts tests/shell-chrome-metrics.test.ts tests/shell-chrome-layer.test.ts tests/bar-nav-overflow-hysteresis.test.ts tests/badge-gradient-ring.test.ts tests/scroll-edge-fade.test.ts tests/resolve-css-length-px.test.ts tests/resolve-css-time-ms.test.ts tests/overlay-positioning.test.ts tests/menu-position.test.ts tests/bar-nav-utils.test.ts tests/bar-nav-tabs-menu-utils.test.ts tests/bar-nav-dom-utils.test.ts tests/icon-catalog.test.ts",
|
|
72
|
+
"test": "node --import tsx/esm --test tests/panel-nav-utils.test.ts tests/panel-tools.test.ts tests/shell-view-transition.test.ts tests/shell-gradient.test.ts tests/shell-chrome-metrics.test.ts tests/shell-chrome-layer.test.ts tests/chrome-transition.test.ts tests/bar-nav-overflow-hysteresis.test.ts tests/badge-gradient-ring.test.ts tests/scroll-edge-fade.test.ts tests/resolve-css-length-px.test.ts tests/resolve-css-time-ms.test.ts tests/overlay-positioning.test.ts tests/menu-position.test.ts tests/bar-nav-utils.test.ts tests/bar-nav-tabs-menu-utils.test.ts tests/bar-nav-dom-utils.test.ts tests/icon-catalog.test.ts",
|
|
73
73
|
"test:e2e": "npm run build && playwright test",
|
|
74
74
|
"test:e2e:install": "playwright install chromium",
|
|
75
75
|
"build:docs": "stencil build --docs",
|
|
@@ -3,7 +3,9 @@ import type { NavChromeStyle } from '../../nav/nav-chrome';
|
|
|
3
3
|
import {
|
|
4
4
|
CHROME_TRANSITION_END,
|
|
5
5
|
CHROME_TRANSITION_START,
|
|
6
|
-
|
|
6
|
+
ChromeTransitionDepth,
|
|
7
|
+
createRafCoalescer,
|
|
8
|
+
readChromeTransitionSource,
|
|
7
9
|
} from '../../nav/chrome-transition';
|
|
8
10
|
import {
|
|
9
11
|
isPanelNavCollapsed,
|
|
@@ -48,8 +50,8 @@ export class AppShell {
|
|
|
48
50
|
@Element() el!: HTMLElement;
|
|
49
51
|
|
|
50
52
|
private resizeObserver: ResizeObserver | null = null;
|
|
51
|
-
private
|
|
52
|
-
private
|
|
53
|
+
private readonly panelNavTransition = new ChromeTransitionDepth();
|
|
54
|
+
private readonly chromeSyncCoalescer = createRafCoalescer(() => this.syncChrome());
|
|
53
55
|
private panelWidthTokens: PanelNavWidthTokens = { expandedPx: 0, collapsedPx: 0 };
|
|
54
56
|
private cachedShellWidth = 0;
|
|
55
57
|
private cachedShellHeight = 0;
|
|
@@ -68,10 +70,7 @@ export class AppShell {
|
|
|
68
70
|
disconnectedCallback() {
|
|
69
71
|
this.resizeObserver?.disconnect();
|
|
70
72
|
this.resizeObserver = null;
|
|
71
|
-
|
|
72
|
-
cancelAnimationFrame(this.chromeSyncRafId);
|
|
73
|
-
this.chromeSyncRafId = 0;
|
|
74
|
-
}
|
|
73
|
+
this.chromeSyncCoalescer.cancel();
|
|
75
74
|
this.el.removeEventListener(CHROME_TRANSITION_START, this.onChromeTransitionStart);
|
|
76
75
|
this.el.removeEventListener(CHROME_TRANSITION_END, this.onChromeTransitionEnd);
|
|
77
76
|
}
|
|
@@ -86,32 +85,26 @@ export class AppShell {
|
|
|
86
85
|
}
|
|
87
86
|
|
|
88
87
|
private onChromeTransitionStart = (event: Event) => {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
}
|
|
88
|
+
if (readChromeTransitionSource(event) !== 'panel-nav') return;
|
|
89
|
+
|
|
90
|
+
this.panelNavTransition.enter();
|
|
91
|
+
this.cachedShellWidth = this.el.clientWidth;
|
|
92
|
+
this.cachedShellHeight = this.el.clientHeight;
|
|
93
|
+
this.syncChrome();
|
|
96
94
|
};
|
|
97
95
|
|
|
98
96
|
private onChromeTransitionEnd = (event: Event) => {
|
|
99
|
-
|
|
100
|
-
if (source !== 'panel-nav') return;
|
|
97
|
+
if (readChromeTransitionSource(event) !== 'panel-nav') return;
|
|
101
98
|
|
|
102
|
-
this.
|
|
103
|
-
if (this.
|
|
99
|
+
this.panelNavTransition.exit();
|
|
100
|
+
if (!this.panelNavTransition.isActive) {
|
|
104
101
|
this.scheduleChromeSync();
|
|
105
102
|
}
|
|
106
103
|
};
|
|
107
104
|
|
|
108
105
|
/** Coalesce ResizeObserver bursts to one layout read per frame. */
|
|
109
106
|
private scheduleChromeSync() {
|
|
110
|
-
|
|
111
|
-
this.chromeSyncRafId = requestAnimationFrame(() => {
|
|
112
|
-
this.chromeSyncRafId = 0;
|
|
113
|
-
this.syncChrome();
|
|
114
|
-
});
|
|
107
|
+
this.chromeSyncCoalescer.schedule();
|
|
115
108
|
}
|
|
116
109
|
|
|
117
110
|
private syncSlottedNavStyle() {
|
|
@@ -129,7 +122,7 @@ export class AppShell {
|
|
|
129
122
|
|
|
130
123
|
private connectMetricsObserver() {
|
|
131
124
|
this.resizeObserver = new ResizeObserver(() => {
|
|
132
|
-
if (this.
|
|
125
|
+
if (this.panelNavTransition.isActive) return;
|
|
133
126
|
this.scheduleChromeSync();
|
|
134
127
|
});
|
|
135
128
|
this.resizeObserver.observe(this.el);
|
|
@@ -180,7 +173,7 @@ export class AppShell {
|
|
|
180
173
|
private resolvePanelWidthPx(panelNav: HTMLElement | null): number {
|
|
181
174
|
const navRoot = panelNav?.querySelector('.panel-nav') as HTMLElement | null;
|
|
182
175
|
|
|
183
|
-
if (this.
|
|
176
|
+
if (this.panelNavTransition.isActive && this.panelWidthTokens.expandedPx > 0) {
|
|
184
177
|
const collapsed = isPanelNavCollapsed(panelNav, navRoot);
|
|
185
178
|
return panelWidthPxFromTokens(this.panelWidthTokens, collapsed);
|
|
186
179
|
}
|
|
@@ -198,7 +191,7 @@ export class AppShell {
|
|
|
198
191
|
}
|
|
199
192
|
|
|
200
193
|
private resolveShellDimensions(): { width: number; height: number } {
|
|
201
|
-
if (this.
|
|
194
|
+
if (this.panelNavTransition.isActive && this.cachedShellWidth > 0) {
|
|
202
195
|
return {
|
|
203
196
|
width: this.cachedShellWidth,
|
|
204
197
|
height: this.cachedShellHeight || this.el.clientHeight,
|
|
@@ -31,7 +31,9 @@ import {
|
|
|
31
31
|
import {
|
|
32
32
|
CHROME_TRANSITION_END,
|
|
33
33
|
CHROME_TRANSITION_START,
|
|
34
|
-
|
|
34
|
+
ChromeTransitionDepth,
|
|
35
|
+
createRafCoalescer,
|
|
36
|
+
readChromeTransitionSource,
|
|
35
37
|
} from '../../nav/chrome-transition';
|
|
36
38
|
import { readCssVarWidthPx } from '../../nav/shell-chrome-metrics';
|
|
37
39
|
|
|
@@ -107,9 +109,12 @@ export class BarNav {
|
|
|
107
109
|
private visibleTabGroupEl: QueryableHost | null = null;
|
|
108
110
|
private probeTabGroupEl: QueryableHost | null = null;
|
|
109
111
|
private resizeObserver: ResizeObserver | null = null;
|
|
110
|
-
private overflowCheckScheduled = false;
|
|
111
112
|
private intrinsicWidthRetryCount = 0;
|
|
112
|
-
private
|
|
113
|
+
private readonly panelNavTransition = new ChromeTransitionDepth();
|
|
114
|
+
private readonly overflowCoalescer = createRafCoalescer(() => {
|
|
115
|
+
this.updateTabsCollapsed();
|
|
116
|
+
this.updateTriggerLabelTruncation();
|
|
117
|
+
});
|
|
113
118
|
private chromeTransitionShell: HTMLElement | null = null;
|
|
114
119
|
private toolsDrawerOpening = false;
|
|
115
120
|
/** Matches `basePath` once tabs + URL are reconciled for the active section. */
|
|
@@ -189,7 +194,7 @@ export class BarNav {
|
|
|
189
194
|
}
|
|
190
195
|
|
|
191
196
|
componentDidRender() {
|
|
192
|
-
if (this.
|
|
197
|
+
if (this.panelNavTransition.isActive) {
|
|
193
198
|
this.syncMenuAnchor();
|
|
194
199
|
return;
|
|
195
200
|
}
|
|
@@ -203,6 +208,7 @@ export class BarNav {
|
|
|
203
208
|
disconnectedCallback() {
|
|
204
209
|
this.resizeObserver?.disconnect();
|
|
205
210
|
this.resizeObserver = null;
|
|
211
|
+
this.overflowCoalescer.cancel();
|
|
206
212
|
this.syncTriggerLabelObserver(true);
|
|
207
213
|
this.unbindChromeTransitionListeners();
|
|
208
214
|
}
|
|
@@ -229,9 +235,9 @@ export class BarNav {
|
|
|
229
235
|
}
|
|
230
236
|
|
|
231
237
|
private onChromeTransitionStart = (event: Event) => {
|
|
232
|
-
const source = (event
|
|
238
|
+
const source = readChromeTransitionSource(event);
|
|
233
239
|
if (source === 'panel-nav') {
|
|
234
|
-
this.
|
|
240
|
+
this.panelNavTransition.enter();
|
|
235
241
|
return;
|
|
236
242
|
}
|
|
237
243
|
if (source === 'panel-tools') {
|
|
@@ -246,10 +252,10 @@ export class BarNav {
|
|
|
246
252
|
};
|
|
247
253
|
|
|
248
254
|
private onChromeTransitionEnd = (event: Event) => {
|
|
249
|
-
const source = (event
|
|
255
|
+
const source = readChromeTransitionSource(event);
|
|
250
256
|
if (source === 'panel-nav') {
|
|
251
|
-
this.
|
|
252
|
-
if (this.
|
|
257
|
+
this.panelNavTransition.exit();
|
|
258
|
+
if (!this.panelNavTransition.isActive) {
|
|
253
259
|
this.scheduleOverflowCheck();
|
|
254
260
|
}
|
|
255
261
|
return;
|
|
@@ -295,22 +301,15 @@ export class BarNav {
|
|
|
295
301
|
if (typeof ResizeObserver === 'undefined' || !this.headerEl) return;
|
|
296
302
|
this.resizeObserver?.disconnect();
|
|
297
303
|
this.resizeObserver = new ResizeObserver(() => {
|
|
298
|
-
if (this.
|
|
304
|
+
if (this.panelNavTransition.isActive) return;
|
|
299
305
|
this.scheduleOverflowCheck();
|
|
300
306
|
});
|
|
301
307
|
this.resizeObserver.observe(this.headerEl);
|
|
302
308
|
}
|
|
303
309
|
|
|
304
310
|
private scheduleOverflowCheck() {
|
|
305
|
-
if (this.
|
|
306
|
-
|
|
307
|
-
this.overflowCheckScheduled = true;
|
|
308
|
-
requestAnimationFrame(() => {
|
|
309
|
-
this.overflowCheckScheduled = false;
|
|
310
|
-
if (this.chromeTransitionDepth > 0) return;
|
|
311
|
-
this.updateTabsCollapsed();
|
|
312
|
-
this.updateTriggerLabelTruncation();
|
|
313
|
-
});
|
|
311
|
+
if (this.panelNavTransition.isActive) return;
|
|
312
|
+
this.overflowCoalescer.schedule();
|
|
314
313
|
}
|
|
315
314
|
|
|
316
315
|
private syncTriggerLabelObserver(disconnectOnly = false) {
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
type PanelToolsItem,
|
|
7
7
|
type PanelToolsToolId,
|
|
8
8
|
} from './panel-tools-types';
|
|
9
|
-
import { parsePanelToolsItems } from './panel-tools-utils';
|
|
9
|
+
import { parsePanelToolsItems, panelToolsDrawerResting } from './panel-tools-utils';
|
|
10
10
|
|
|
11
11
|
@Component({
|
|
12
12
|
tag: 'ds-panel-tools',
|
|
@@ -160,6 +160,7 @@ export class PanelTools {
|
|
|
160
160
|
const headerItem = railItems.find(item => item.id === PANEL_TOOLS_PRIMARY_TOOL_ID);
|
|
161
161
|
const bodyItems = railItems.filter(item => item.id !== PANEL_TOOLS_PRIMARY_TOOL_ID);
|
|
162
162
|
const showDrawerChrome = this.isDrawerPresent();
|
|
163
|
+
const drawerResting = panelToolsDrawerResting(this.open, this.motion);
|
|
163
164
|
|
|
164
165
|
return (
|
|
165
166
|
<Host
|
|
@@ -169,6 +170,7 @@ export class PanelTools {
|
|
|
169
170
|
'panel-tools--ready': this.readyForMotion,
|
|
170
171
|
'panel-tools--motion-opening': this.motion === 'opening',
|
|
171
172
|
'panel-tools--motion-closing': this.motion === 'closing',
|
|
173
|
+
'panel-tools--drawer-resting': drawerResting,
|
|
172
174
|
}}
|
|
173
175
|
role="complementary"
|
|
174
176
|
aria-label="Tools"
|
|
@@ -29,3 +29,10 @@ export function shouldResyncPanelToolsItems(
|
|
|
29
29
|
);
|
|
30
30
|
});
|
|
31
31
|
}
|
|
32
|
+
|
|
33
|
+
export type PanelToolsMotion = 'opening' | 'closing' | 'idle';
|
|
34
|
+
|
|
35
|
+
/** True when the drawer clip is fully closed — safe to skip painting slot content. */
|
|
36
|
+
export function panelToolsDrawerResting(open: boolean, motion: PanelToolsMotion): boolean {
|
|
37
|
+
return !open && motion === 'idle';
|
|
38
|
+
}
|
|
@@ -8,3 +8,49 @@ export type ChromeTransitionSource = 'panel-nav' | 'panel-tools';
|
|
|
8
8
|
export interface ChromeTransitionDetail {
|
|
9
9
|
source: ChromeTransitionSource;
|
|
10
10
|
}
|
|
11
|
+
|
|
12
|
+
/** Reference-counted gate — used while panel-nav width is transitioning. */
|
|
13
|
+
export class ChromeTransitionDepth {
|
|
14
|
+
private depth = 0;
|
|
15
|
+
|
|
16
|
+
enter(): void {
|
|
17
|
+
this.depth += 1;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
exit(): void {
|
|
21
|
+
this.depth = Math.max(0, this.depth - 1);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
get isActive(): boolean {
|
|
25
|
+
return this.depth > 0;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface RafCoalescer {
|
|
30
|
+
schedule(): void;
|
|
31
|
+
cancel(): void;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Coalesce bursty layout work (ResizeObserver, prop churn) to one callback per frame. */
|
|
35
|
+
export function createRafCoalescer(onFrame: () => void): RafCoalescer {
|
|
36
|
+
let rafId = 0;
|
|
37
|
+
return {
|
|
38
|
+
schedule() {
|
|
39
|
+
if (rafId !== 0) return;
|
|
40
|
+
rafId = requestAnimationFrame(() => {
|
|
41
|
+
rafId = 0;
|
|
42
|
+
onFrame();
|
|
43
|
+
});
|
|
44
|
+
},
|
|
45
|
+
cancel() {
|
|
46
|
+
if (rafId !== 0) {
|
|
47
|
+
cancelAnimationFrame(rafId);
|
|
48
|
+
rafId = 0;
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function readChromeTransitionSource(event: Event): ChromeTransitionSource | undefined {
|
|
55
|
+
return (event as CustomEvent<ChromeTransitionDetail>).detail?.source;
|
|
56
|
+
}
|
package/src/wc/nav/index.ts
CHANGED
|
@@ -40,6 +40,9 @@ export type { ChromeTransitionDetail, ChromeTransitionSource } from './chrome-tr
|
|
|
40
40
|
export {
|
|
41
41
|
CHROME_TRANSITION_END,
|
|
42
42
|
CHROME_TRANSITION_START,
|
|
43
|
+
ChromeTransitionDepth,
|
|
44
|
+
createRafCoalescer,
|
|
45
|
+
readChromeTransitionSource,
|
|
43
46
|
} from './chrome-transition';
|
|
44
47
|
export {
|
|
45
48
|
barGradientPositionFromPanelWidth,
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
const n="dsChromeTransitionStart";const t="dsChromeTransitionEnd";function e(n,t){if(typeof document==="undefined")return 0;const e=document.createElement("div");e.style.cssText="position:absolute;visibility:hidden;pointer-events:none;height:0;width:var("+t+");";n.appendChild(e);const i=e.getBoundingClientRect().width;n.removeChild(e);return i}function i(n){return{expandedPx:e(n,"--_nav-width"),collapsedPx:e(n,"--_nav-width-collapsed")}}function o(n,t){if(t?.classList.contains("panel-nav--collapsed"))return true;const e=n?.collapsed;return e===true}function r(n,t){return t?n.collapsedPx:n.expandedPx}export{n as C,t as a,e as b,o as i,r as p,i as r};
|
|
2
|
-
//# sourceMappingURL=p-DN65lYYc.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["CHROME_TRANSITION_START","CHROME_TRANSITION_END","readCssVarWidthPx","context","cssVarName","document","probe","createElement","style","cssText","appendChild","width","getBoundingClientRect","removeChild","readPanelNavWidthTokens","navRoot","expandedPx","collapsedPx","isPanelNavCollapsed","panelNavHost","classList","contains","collapsedProp","collapsed","panelWidthPxFromTokens","tokens"],"sources":["src/wc/nav/chrome-transition.ts","src/wc/nav/shell-chrome-metrics.ts"],"sourcesContent":["/** Bubbling/composed events — `ds-app-shell` and `ds-bar-nav` coordinate during width motion. */\n\nexport const CHROME_TRANSITION_START = 'dsChromeTransitionStart';\nexport const CHROME_TRANSITION_END = 'dsChromeTransitionEnd';\n\nexport type ChromeTransitionSource = 'panel-nav' | 'panel-tools';\n\nexport interface ChromeTransitionDetail {\n source: ChromeTransitionSource;\n}\n","import { shellGradientPositionBar } from './shell-gradient';\n\n/** Read a `var(--token)` width in px using a hidden probe (works with calc() tokens). */\nexport function readCssVarWidthPx(context: HTMLElement, cssVarName: string): number {\n if (typeof document === 'undefined') return 0;\n\n const probe = document.createElement('div');\n probe.style.cssText =\n 'position:absolute;visibility:hidden;pointer-events:none;height:0;width:var(' +\n cssVarName +\n ');';\n context.appendChild(probe);\n const width = probe.getBoundingClientRect().width;\n context.removeChild(probe);\n return width;\n}\n\nexport interface PanelNavWidthTokens {\n expandedPx: number;\n collapsedPx: number;\n}\n\n/** Resolve panel-nav expanded/collapsed widths from scoped CSS vars on `.panel-nav`. */\nexport function readPanelNavWidthTokens(navRoot: HTMLElement): PanelNavWidthTokens {\n return {\n expandedPx: readCssVarWidthPx(navRoot, '--_nav-width'),\n collapsedPx: readCssVarWidthPx(navRoot, '--_nav-width-collapsed'),\n };\n}\n\nexport function isPanelNavCollapsed(\n panelNavHost: HTMLElement | null,\n navRoot: HTMLElement | null,\n): boolean {\n if (navRoot?.classList.contains('panel-nav--collapsed')) return true;\n const collapsedProp = (panelNavHost as (HTMLElement & { collapsed?: boolean }) | null)?.collapsed;\n return collapsedProp === true;\n}\n\nexport function panelWidthPxFromTokens(\n tokens: PanelNavWidthTokens,\n collapsed: boolean,\n): number {\n return collapsed ? tokens.collapsedPx : tokens.expandedPx;\n}\n\nexport function barGradientPositionFromPanelWidth(panelWidthPx: number): string {\n return shellGradientPositionBar(panelWidthPx);\n}\n"],"mappings":"AAEO,MAAMA,EAA0B,0BAChC,MAAMC,EAAwB,wBCA/B,SAAUC,EAAkBC,EAAsBC,GACtD,UAAWC,WAAa,YAAa,OAAO,EAE5C,MAAMC,EAAQD,SAASE,cAAc,OACrCD,EAAME,MAAMC,QACV,8EACAL,EACA,KACFD,EAAQO,YAAYJ,GACpB,MAAMK,EAAQL,EAAMM,wBAAwBD,MAC5CR,EAAQU,YAAYP,GACpB,OAAOK,CACT,CAQM,SAAUG,EAAwBC,GACtC,MAAO,CACLC,WAAYd,EAAkBa,EAAS,gBACvCE,YAAaf,EAAkBa,EAAS,0BAE5C,CAEM,SAAUG,EACdC,EACAJ,GAEA,GAAIA,GAASK,UAAUC,SAAS,wBAAyB,OAAO,KAChE,MAAMC,EAAiBH,GAAiEI,UACxF,OAAOD,IAAkB,IAC3B,CAEM,SAAUE,EACdC,EACAF,GAEA,OAAOA,EAAYE,EAAOR,YAAcQ,EAAOT,UACjD,Q","ignoreList":[]}
|