@ds-mo/ui 1.10.0 → 1.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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-nav.js +1 -1
- package/dist/components/ds-panel-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-DN65lYYc.js +2 -0
- package/dist/components/p-DN65lYYc.js.map +1 -0
- package/dist/types/components/AppShell/AppShell.d.ts +16 -2
- package/dist/types/components/BarNav/BarNav.d.ts +10 -0
- package/dist/types/components/PanelNav/PanelNav.d.ts +4 -0
- package/dist/types/components/PanelTools/PanelTools.d.ts +4 -0
- package/dist/types/components.d.ts +29 -2
- package/dist/types/nav/chrome-transition.d.ts +8 -0
- package/dist/types/nav/index.d.ts +5 -1
- package/dist/types/nav/shell-chrome-metrics.d.ts +12 -0
- package/dist/types/nav/shell-gradient.d.ts +2 -0
- package/package.json +2 -2
- package/src/angular/proxies.ts +22 -4
- package/src/react/ds-panel-nav.ts +5 -1
- package/src/react/ds-panel-tools.ts +11 -3
- package/src/wc/components/AppShell/AppShell.tsx +133 -21
- package/src/wc/components/BarNav/BarNav.tsx +91 -2
- package/src/wc/components/PanelNav/PanelNav.tsx +10 -0
- package/src/wc/components/PanelTools/PanelTools.tsx +10 -0
- package/src/wc/components.d.ts +29 -2
- package/src/wc/nav/chrome-transition.ts +10 -0
- package/src/wc/nav/index.ts +14 -0
- package/src/wc/nav/shell-chrome-metrics.ts +49 -0
- package/src/wc/nav/shell-gradient.ts +5 -0
|
@@ -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","handleToolChange","id","selected","isRailSelected","dsToolChange","emit","railItems","disconnectedCallback","removeEventListener","deferMotionEnable","generation","requestAnimationFrame","connectedCallback","addEventListener","openChanged","isOpen","wasOpen","undefined","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 --_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 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 {\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 /** 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 }\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 };\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":"wMAYO,MAAMA,EAAgD,SAEtD,MAAMC,EAAuD,CAClEC,OAAQ,SACRC,SAAU,WACVC,OAAQ,SACRC,SAAU,WACVC,OAAQ,UChBJ,SAAUC,EACdC,EACAC,GAEA,GAAIA,EAAW,CACb,OAAOC,EAAmCD,EAAW,G,CAEvD,OAAOD,GAAS,EAClB,CCXA,MAAMG,EAAgB,IAAM,kkI,MCcfC,EAAUC,EAAA,MAAAD,UAAAE,EALvB,WAAAC,CAAAC,G,qFAS0CC,KAAAC,KAAgB,MAIxDD,KAAAE,WAAoC,GAM5BF,KAAAT,MAA0B,GAGCS,KAAAR,UAAoB,GAStCQ,KAAAG,OAAyC,OAGzCH,KAAAI,eAAiB,MAE1BJ,KAAAK,uBAAyB,EAkDzBL,KAAAM,oBAAuBC,IAC7B,GAAIA,EAAMC,SAAWR,KAAKS,GAAGC,cAAc,wBAAyB,OACpE,GAAIH,EAAMI,eAAiB,YAAa,OACxCX,KAAKG,OAAS,MAAM,EAsBdH,KAAAY,iBAAoBC,IAC1B,MAAMC,GAAYd,KAAKe,eAAeF,GACtC,GAAIC,EAAU,CACZd,KAAKC,KAAO,KACZD,KAAKE,WAAaW,C,KACb,CACLb,KAAKC,KAAO,K,CAEdD,KAAKgB,aAAaC,KAAK,CAAEJ,KAAIC,YAAW,CAoH3C,CArMC,aAAYI,GACV,OAAO5B,EAAqBU,KAAKT,MAAOS,KAAKR,U,CAG/C,oBAAA2B,GACEnB,KAAKS,GAAGW,oBAAoB,gBAAiBpB,KAAKM,qBAClDN,KAAKK,wBAA0B,C,CAGzB,iBAAAgB,GACN,GAAIrB,KAAKI,eAAgB,OACzB,MAAMkB,IAAetB,KAAKK,uBAC1BkB,uBAAsB,KACpB,GAAID,IAAetB,KAAKK,uBAAwB,OAChDkB,uBAAsB,KACpB,GAAID,IAAetB,KAAKK,uBAAwB,OAChDL,KAAKI,eAAiB,IAAI,GAC1B,G,CAIN,iBAAAoB,GACExB,KAAKS,GAAGgB,iBAAiB,gBAAiBzB,KAAKM,oB,CAIjD,WAAAoB,CAAYC,EAAiBC,GAC3B,GAAI5B,KAAKI,gBAAkBwB,IAAYC,WAAaD,IAAYD,EAAQ,CACtE3B,KAAKG,OAASwB,EAAS,UAAY,S,CAErC3B,KAAKqB,mB,CAIP,iBAAAS,GACE9B,KAAKqB,mB,CAGP,gBAAAU,GACE/B,KAAKqB,mB,CAKP,YAAAW,GACEhC,KAAKqB,mB,CAUC,cAAAN,CAAeF,GACrB,OAAOb,KAAKC,MAAQD,KAAKE,aAAeW,C,CAIlC,eAAAoB,GACN,OAAOjC,KAAKC,MAAQD,KAAKG,SAAW,S,CAG9B,YAAA+B,CAAarB,GACnB,OAAOb,KAAKiC,mBAAqBjC,KAAKE,aAAeW,C,CAG/C,WAAAsB,GACN,IAAKnC,KAAKiC,oBAAsBjC,KAAKE,WAAY,MAAO,GACxD,OAAOlB,EAAmBgB,KAAKE,aAAmC,E,CAc5D,gBAAAkC,CAAiBC,GACvB,OACEC,EAAA,qBACEC,IAAKF,EAAKxB,GACV2B,MAAM,2BACNC,KAAMJ,EAAKI,KACX3B,SAAUd,KAAKe,eAAesB,EAAKxB,IACnC6B,IAAKL,EAAKK,KAAO,MACjBC,SAAUN,EAAKM,SAAQ,aACXN,EAAKO,WAAa5D,EAAmBqD,EAAKxB,IACtDgC,WAAY,IAAM7C,KAAKY,iBAAiByB,EAAKxB,K,CAKnD,MAAAiC,GACE,MAAMX,EAAcnC,KAAKmC,cACzB,MAAMjB,EAAYlB,KAAKkB,UACvB,MAAM6B,EAAa7B,EAAU8B,MAAKX,GAAQA,EAAKxB,KAAO9B,IACtD,MAAMkE,EAAY/B,EAAUgC,QAAOb,GAAQA,EAAKxB,KAAO9B,IACvD,MAAMoE,EAAmBnD,KAAKiC,kBAE9B,OACEK,EAACc,EAAI,CAAAb,IAAA,2CACHC,MAAO,CACL,cAAe,KACf,oBAAqBxC,KAAKC,KAC1B,qBAAsBD,KAAKI,eAC3B,8BAA+BJ,KAAKG,SAAW,UAC/C,8BAA+BH,KAAKG,SAAW,WAEjDkD,KAAK,gBAAe,aACT,SAEXf,EAAA,OAAAC,IAAA,2CAAKC,MAAM,uBACTF,EAAA,OAAAC,IAAA,2CACEC,MAAO,CACL,sBAAuB,KACvB,+BAAgCW,GACjC,cACYA,EAAmB,KAAO,QAEvCb,EAAA,OAAAC,IAAA,2CAAKC,MAAM,+BACTF,EAAA,UAAAC,IAAA,2CAAQC,MAAM,uBACZF,EAAA,QAAAC,IAAA,2CAAMC,MAAM,gDAAgDL,IAE9DG,EAAA,OAAAC,IAAA,2CAAKC,MAAM,qBACTF,EAAA,OAAAC,IAAA,2CACEC,MAAO,CACL,oBAAqB,KACrB,4BAA6BxC,KAAKkC,aAAa,UAC/C,mBAAoB,MAEtBoB,QAAStD,KAAKkC,aAAa,WAE3BI,EAAA,QAAAC,IAAA,2CAAMgB,KAAK,YAEbjB,EAAA,OAAAC,IAAA,2CACEC,MAAO,CACL,oBAAqB,KACrB,4BAA6BxC,KAAKkC,aAAa,YAC/C,mBAAoB,MAEtBoB,QAAStD,KAAKkC,aAAa,aAE3BI,EAAA,QAAAC,IAAA,2CAAMgB,KAAK,cAEbjB,EAAA,OAAAC,IAAA,2CACEC,MAAO,CACL,oBAAqB,KACrB,4BAA6BxC,KAAKkC,aAAa,UAC/C,mBAAoB,MAEtBoB,QAAStD,KAAKkC,aAAa,WAE3BI,EAAA,QAAAC,IAAA,2CAAMgB,KAAK,YAEbjB,EAAA,OAAAC,IAAA,2CACEC,MAAO,CACL,oBAAqB,KACrB,4BAA6BxC,KAAKkC,aAAa,YAC/C,mBAAoB,MAEtBoB,QAAStD,KAAKkC,aAAa,aAE3BI,EAAA,QAAAC,IAAA,2CAAMgB,KAAK,cAEbjB,EAAA,OAAAC,IAAA,2CACEC,MAAO,CACL,oBAAqB,KACrB,4BAA6BxC,KAAKkC,aAAa,UAC/C,mBAAoB,MAEtBoB,QAAStD,KAAKkC,aAAa,WAE3BI,EAAA,QAAAC,IAAA,2CAAMgB,KAAK,eAMnBjB,EAAA,OAAAC,IAAA,2CAAKC,MAAM,oBAAmB,aAAY,kBACvCO,EACCT,EAAA,OAAKE,MAAM,4BAA4BxC,KAAKoC,iBAAiBW,IAC3D,KACJT,EAAA,OAAAC,IAAA,2CAAKC,MAAM,0BACRS,EAAUO,KAAInB,GAAQrC,KAAKoC,iBAAiBC,Q","ignoreList":[]}
|
|
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":[]}
|
|
@@ -0,0 +1,2 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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":[]}
|
|
@@ -2,8 +2,10 @@ import type { NavChromeStyle } from '../../nav/nav-chrome';
|
|
|
2
2
|
export declare class AppShell {
|
|
3
3
|
/** Chrome style propagated to slotted `ds-panel-nav` and `ds-bar-nav`. */
|
|
4
4
|
navStyle: NavChromeStyle;
|
|
5
|
-
/** When `true`, paints the
|
|
5
|
+
/** When `true`, paints the radial wash behind panel, bar, and tools (synced to shell layout). */
|
|
6
6
|
gradient: boolean;
|
|
7
|
+
/** When `true`, paints the diagonal grid overlay on the shared chrome layer. Independent of `gradient`. */
|
|
8
|
+
grid: boolean;
|
|
7
9
|
/**
|
|
8
10
|
* Optional custom gradient for `background-image` (e.g. SVG URL).
|
|
9
11
|
* When set, overrides the built-in radial wash.
|
|
@@ -11,16 +13,28 @@ export declare class AppShell {
|
|
|
11
13
|
gradientSrc: string;
|
|
12
14
|
el: HTMLElement;
|
|
13
15
|
private resizeObserver;
|
|
16
|
+
private chromeSyncRafId;
|
|
17
|
+
private chromeTransitionDepth;
|
|
18
|
+
private panelWidthTokens;
|
|
19
|
+
private cachedShellWidth;
|
|
20
|
+
private cachedShellHeight;
|
|
14
21
|
componentDidLoad(): void;
|
|
15
|
-
private scheduleChromeSync;
|
|
16
22
|
disconnectedCallback(): void;
|
|
17
23
|
onShellPropsChange(): void;
|
|
24
|
+
private onChromeTransitionStart;
|
|
25
|
+
private onChromeTransitionEnd;
|
|
26
|
+
/** Coalesce ResizeObserver bursts to one layout read per frame. */
|
|
27
|
+
private scheduleChromeSync;
|
|
18
28
|
private syncSlottedNavStyle;
|
|
19
29
|
private connectMetricsObserver;
|
|
30
|
+
private cachePanelWidthTokens;
|
|
20
31
|
private applyGradientVars;
|
|
21
32
|
private clearGradientPaintVars;
|
|
22
33
|
/** Panel/bar wash offsets for scroll fades and badge rings. */
|
|
23
34
|
private syncChromeLayoutVars;
|
|
35
|
+
private resolvePanelWidthPx;
|
|
36
|
+
private resolveShellDimensions;
|
|
37
|
+
private chromeLayerActive;
|
|
24
38
|
private syncChrome;
|
|
25
39
|
render(): any;
|
|
26
40
|
}
|
|
@@ -48,6 +48,7 @@ export declare class BarNav {
|
|
|
48
48
|
private triggerLabelTruncated;
|
|
49
49
|
private static readonly HOST_PROP_SYNC_BUDGET;
|
|
50
50
|
private static readonly INTRINSIC_WIDTH_RETRY_MAX;
|
|
51
|
+
private static readonly OVERFLOW_HYSTERESIS_PX;
|
|
51
52
|
private headerEl;
|
|
52
53
|
private triggerEl;
|
|
53
54
|
private triggerLabelTextEl;
|
|
@@ -58,6 +59,9 @@ export declare class BarNav {
|
|
|
58
59
|
private resizeObserver;
|
|
59
60
|
private overflowCheckScheduled;
|
|
60
61
|
private intrinsicWidthRetryCount;
|
|
62
|
+
private chromeTransitionDepth;
|
|
63
|
+
private chromeTransitionShell;
|
|
64
|
+
private toolsDrawerOpening;
|
|
61
65
|
/** Matches `basePath` once tabs + URL are reconciled for the active section. */
|
|
62
66
|
private committedSection;
|
|
63
67
|
/** Section waiting for URL + tabs to catch up after a cross-area navigation. */
|
|
@@ -73,6 +77,10 @@ export declare class BarNav {
|
|
|
73
77
|
componentDidLoad(): void;
|
|
74
78
|
componentDidRender(): void;
|
|
75
79
|
disconnectedCallback(): void;
|
|
80
|
+
private bindChromeTransitionListeners;
|
|
81
|
+
private unbindChromeTransitionListeners;
|
|
82
|
+
private onChromeTransitionStart;
|
|
83
|
+
private onChromeTransitionEnd;
|
|
76
84
|
/** Re-resolve props assigned by the host after componentWillLoad (Angular ngAfterViewInit). */
|
|
77
85
|
private syncHostPropsIfNeeded;
|
|
78
86
|
/** Poll across animation frames — host props may land without triggering @Watch. */
|
|
@@ -83,6 +91,8 @@ export declare class BarNav {
|
|
|
83
91
|
private updateTriggerLabelTruncation;
|
|
84
92
|
/** Width left for tabs after actions. */
|
|
85
93
|
private getLeftZoneAvailableWidth;
|
|
94
|
+
/** While the tools drawer is opening, reserve width not yet claimed by flex shrink. */
|
|
95
|
+
private toolsDrawerOpeningReservePx;
|
|
86
96
|
private getTabsIntrinsicWidth;
|
|
87
97
|
private scheduleIntrinsicWidthRetry;
|
|
88
98
|
private updateTabsCollapsed;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { EventEmitter } from '../../stencil-public-runtime';
|
|
2
|
+
import type { ChromeTransitionDetail } from '../../nav/chrome-transition';
|
|
2
3
|
import type { NavChromeStyle } from '../../nav/nav-chrome';
|
|
3
4
|
import { type PanelNavGroup, type PanelNavRouterMode, type PanelNavUserActionDetail } from './panel-nav-types';
|
|
4
5
|
export declare class PanelNav {
|
|
@@ -35,6 +36,9 @@ export declare class PanelNav {
|
|
|
35
36
|
dsNavSelect: EventEmitter<string>;
|
|
36
37
|
/** Emitted when the collapse toggle is clicked. Detail = new collapsed state. */
|
|
37
38
|
dsNavToggle: EventEmitter<boolean>;
|
|
39
|
+
/** Bubbling lifecycle — `ds-app-shell` pauses chrome metrics during width motion. */
|
|
40
|
+
dsChromeTransitionStart: EventEmitter<ChromeTransitionDetail>;
|
|
41
|
+
dsChromeTransitionEnd: EventEmitter<ChromeTransitionDetail>;
|
|
38
42
|
/** Emitted when the footer left button (gear / dashboard) is clicked. */
|
|
39
43
|
dsNavFooterAction: EventEmitter<void>;
|
|
40
44
|
/** Emitted when the footer user button is clicked. Detail includes the anchor for `ds-menu`. */
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { EventEmitter } from '../../stencil-public-runtime';
|
|
2
|
+
import type { ChromeTransitionDetail } from '../../nav/chrome-transition';
|
|
2
3
|
import { type PanelToolsItem, type PanelToolsToolId } from './panel-tools-types';
|
|
3
4
|
export declare class PanelTools {
|
|
4
5
|
el: HTMLElement;
|
|
@@ -18,6 +19,9 @@ export declare class PanelTools {
|
|
|
18
19
|
id: PanelToolsToolId;
|
|
19
20
|
selected: boolean;
|
|
20
21
|
}>;
|
|
22
|
+
/** Bubbling lifecycle — `ds-bar-nav` defers overflow checks during drawer motion. */
|
|
23
|
+
dsChromeTransitionStart: EventEmitter<ChromeTransitionDetail>;
|
|
24
|
+
dsChromeTransitionEnd: EventEmitter<ChromeTransitionDetail>;
|
|
21
25
|
/** Arms open vs close easing for the in-flight width transition. */
|
|
22
26
|
private motion;
|
|
23
27
|
/** Suppresses width transition until the host has painted its initial open state. */
|
|
@@ -26,6 +26,7 @@ import { MenuItemData, MenuSection } from "./components/Menu/menu-types";
|
|
|
26
26
|
import { MenuAlign, MenuSide } from "./components/Menu/menu-position";
|
|
27
27
|
import { ModalWidth } from "./components/Modal/Modal";
|
|
28
28
|
import { PanelNavGroup, PanelNavRouterMode, PanelNavUserActionDetail } from "./components/PanelNav/panel-nav-types";
|
|
29
|
+
import { ChromeTransitionDetail } from "./nav/chrome-transition";
|
|
29
30
|
import { PanelToolsItem, PanelToolsToolId } from "./components/PanelTools/panel-tools-types";
|
|
30
31
|
import { RadioOption } from "./components/RadioGroup/RadioGroup";
|
|
31
32
|
import { ScrollbarVariant } from "./components/Scrollbar/Scrollbar";
|
|
@@ -63,6 +64,7 @@ export { MenuItemData, MenuSection } from "./components/Menu/menu-types";
|
|
|
63
64
|
export { MenuAlign, MenuSide } from "./components/Menu/menu-position";
|
|
64
65
|
export { ModalWidth } from "./components/Modal/Modal";
|
|
65
66
|
export { PanelNavGroup, PanelNavRouterMode, PanelNavUserActionDetail } from "./components/PanelNav/panel-nav-types";
|
|
67
|
+
export { ChromeTransitionDetail } from "./nav/chrome-transition";
|
|
66
68
|
export { PanelToolsItem, PanelToolsToolId } from "./components/PanelTools/panel-tools-types";
|
|
67
69
|
export { RadioOption } from "./components/RadioGroup/RadioGroup";
|
|
68
70
|
export { ScrollbarVariant } from "./components/Scrollbar/Scrollbar";
|
|
@@ -97,7 +99,7 @@ export namespace Components {
|
|
|
97
99
|
}
|
|
98
100
|
interface DsAppShell {
|
|
99
101
|
/**
|
|
100
|
-
* When `true`, paints the
|
|
102
|
+
* When `true`, paints the radial wash behind panel, bar, and tools (synced to shell layout).
|
|
101
103
|
* @default false
|
|
102
104
|
*/
|
|
103
105
|
"gradient": boolean;
|
|
@@ -106,6 +108,11 @@ export namespace Components {
|
|
|
106
108
|
* @default ''
|
|
107
109
|
*/
|
|
108
110
|
"gradientSrc": string;
|
|
111
|
+
/**
|
|
112
|
+
* When `true`, paints the diagonal grid overlay on the shared chrome layer. Independent of `gradient`.
|
|
113
|
+
* @default false
|
|
114
|
+
*/
|
|
115
|
+
"grid": boolean;
|
|
109
116
|
/**
|
|
110
117
|
* Chrome style propagated to slotted `ds-panel-nav` and `ds-bar-nav`.
|
|
111
118
|
* @default 'dashboard'
|
|
@@ -1476,6 +1483,8 @@ declare global {
|
|
|
1476
1483
|
interface HTMLDsPanelNavElementEventMap {
|
|
1477
1484
|
"dsNavSelect": string;
|
|
1478
1485
|
"dsNavToggle": boolean;
|
|
1486
|
+
"dsChromeTransitionStart": ChromeTransitionDetail;
|
|
1487
|
+
"dsChromeTransitionEnd": ChromeTransitionDetail;
|
|
1479
1488
|
"dsNavFooterAction": void;
|
|
1480
1489
|
"dsNavUserAction": PanelNavUserActionDetail;
|
|
1481
1490
|
}
|
|
@@ -1498,6 +1507,8 @@ declare global {
|
|
|
1498
1507
|
id: PanelToolsToolId;
|
|
1499
1508
|
selected: boolean;
|
|
1500
1509
|
};
|
|
1510
|
+
"dsChromeTransitionStart": ChromeTransitionDetail;
|
|
1511
|
+
"dsChromeTransitionEnd": ChromeTransitionDetail;
|
|
1501
1512
|
}
|
|
1502
1513
|
interface HTMLDsPanelToolsElement extends Components.DsPanelTools, HTMLStencilElement {
|
|
1503
1514
|
addEventListener<K extends keyof HTMLDsPanelToolsElementEventMap>(type: K, listener: (this: HTMLDsPanelToolsElement, ev: DsPanelToolsCustomEvent<HTMLDsPanelToolsElementEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
|
|
@@ -1775,7 +1786,7 @@ declare namespace LocalJSX {
|
|
|
1775
1786
|
}
|
|
1776
1787
|
interface DsAppShell {
|
|
1777
1788
|
/**
|
|
1778
|
-
* When `true`, paints the
|
|
1789
|
+
* When `true`, paints the radial wash behind panel, bar, and tools (synced to shell layout).
|
|
1779
1790
|
* @default false
|
|
1780
1791
|
*/
|
|
1781
1792
|
"gradient"?: boolean;
|
|
@@ -1784,6 +1795,11 @@ declare namespace LocalJSX {
|
|
|
1784
1795
|
* @default ''
|
|
1785
1796
|
*/
|
|
1786
1797
|
"gradientSrc"?: string;
|
|
1798
|
+
/**
|
|
1799
|
+
* When `true`, paints the diagonal grid overlay on the shared chrome layer. Independent of `gradient`.
|
|
1800
|
+
* @default false
|
|
1801
|
+
*/
|
|
1802
|
+
"grid"?: boolean;
|
|
1787
1803
|
/**
|
|
1788
1804
|
* Chrome style propagated to slotted `ds-panel-nav` and `ds-bar-nav`.
|
|
1789
1805
|
* @default 'dashboard'
|
|
@@ -2378,6 +2394,11 @@ declare namespace LocalJSX {
|
|
|
2378
2394
|
* @default 'dashboard'
|
|
2379
2395
|
*/
|
|
2380
2396
|
"navStyle"?: NavChromeStyle;
|
|
2397
|
+
"onDsChromeTransitionEnd"?: (event: DsPanelNavCustomEvent<ChromeTransitionDetail>) => void;
|
|
2398
|
+
/**
|
|
2399
|
+
* Bubbling lifecycle — `ds-app-shell` pauses chrome metrics during width motion.
|
|
2400
|
+
*/
|
|
2401
|
+
"onDsChromeTransitionStart"?: (event: DsPanelNavCustomEvent<ChromeTransitionDetail>) => void;
|
|
2381
2402
|
/**
|
|
2382
2403
|
* Emitted when the footer left button (gear / dashboard) is clicked.
|
|
2383
2404
|
*/
|
|
@@ -2431,6 +2452,11 @@ declare namespace LocalJSX {
|
|
|
2431
2452
|
* @default ''
|
|
2432
2453
|
*/
|
|
2433
2454
|
"itemsJson"?: string;
|
|
2455
|
+
"onDsChromeTransitionEnd"?: (event: DsPanelToolsCustomEvent<ChromeTransitionDetail>) => void;
|
|
2456
|
+
/**
|
|
2457
|
+
* Bubbling lifecycle — `ds-bar-nav` defers overflow checks during drawer motion.
|
|
2458
|
+
*/
|
|
2459
|
+
"onDsChromeTransitionStart"?: (event: DsPanelToolsCustomEvent<ChromeTransitionDetail>) => void;
|
|
2434
2460
|
/**
|
|
2435
2461
|
* Emitted when a rail button is toggled. Detail = { id, selected }.
|
|
2436
2462
|
*/
|
|
@@ -2855,6 +2881,7 @@ declare namespace LocalJSX {
|
|
|
2855
2881
|
interface DsAppShellAttributes {
|
|
2856
2882
|
"navStyle": NavChromeStyle;
|
|
2857
2883
|
"gradient": boolean;
|
|
2884
|
+
"grid": boolean;
|
|
2858
2885
|
"gradientSrc": string;
|
|
2859
2886
|
}
|
|
2860
2887
|
interface DsBadgeAttributes {
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Bubbling/composed events — `ds-app-shell` and `ds-bar-nav` coordinate during width motion. */
|
|
2
|
+
export declare const CHROME_TRANSITION_START = "dsChromeTransitionStart";
|
|
3
|
+
export declare const CHROME_TRANSITION_END = "dsChromeTransitionEnd";
|
|
4
|
+
export type ChromeTransitionSource = 'panel-nav' | 'panel-tools';
|
|
5
|
+
export interface ChromeTransitionDetail {
|
|
6
|
+
source: ChromeTransitionSource;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=chrome-transition.d.ts.map
|
|
@@ -2,8 +2,12 @@ export type { NavChromeStyle } from './nav-chrome';
|
|
|
2
2
|
export { NAV_STYLE_HINT_ATTR, readNavStyleAttr, setNavStyleHint, clearNavStyleHint, resolveNavChromeStyle, shouldResyncNavChromeStyle, } from './nav-chrome';
|
|
3
3
|
export { SHELL_BAR_NAV_VT_NAME, SHELL_NAV_REVEAL_DURATION_VAR, SHELL_NAV_REVEAL_EASING_VAR, parseCssTimeMs, ensureShellNavVtStyle, resolveShellNavRevealOrigin, setShellNavRevealOriginVars, animateShellNavRadialReveal, runShellNavStyleRevealOnReady, } from './shell-view-transition';
|
|
4
4
|
export type { ShellNavRevealOrigin } from './shell-view-transition';
|
|
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, } from './shell-gradient';
|
|
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
|
+
export type { ChromeTransitionDetail, ChromeTransitionSource } from './chrome-transition';
|
|
8
|
+
export { CHROME_TRANSITION_END, CHROME_TRANSITION_START, } from './chrome-transition';
|
|
9
|
+
export { barGradientPositionFromPanelWidth, isPanelNavCollapsed, panelWidthPxFromTokens, readCssVarWidthPx, readPanelNavWidthTokens, } from './shell-chrome-metrics';
|
|
10
|
+
export type { PanelNavWidthTokens } from './shell-chrome-metrics';
|
|
7
11
|
export { BADGE_GRADIENT_POSITION_VAR, badgeGradientPosition, findGradientSurface, isShellGradientActive, parseCssBackgroundPosition, readShellGradientPosition, syncBadgeGradientPosition, } from './badge-gradient-ring';
|
|
8
12
|
export type { GradientSurface } from './badge-gradient-ring';
|
|
9
13
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** Read a `var(--token)` width in px using a hidden probe (works with calc() tokens). */
|
|
2
|
+
export declare function readCssVarWidthPx(context: HTMLElement, cssVarName: string): number;
|
|
3
|
+
export interface PanelNavWidthTokens {
|
|
4
|
+
expandedPx: number;
|
|
5
|
+
collapsedPx: number;
|
|
6
|
+
}
|
|
7
|
+
/** Resolve panel-nav expanded/collapsed widths from scoped CSS vars on `.panel-nav`. */
|
|
8
|
+
export declare function readPanelNavWidthTokens(navRoot: HTMLElement): PanelNavWidthTokens;
|
|
9
|
+
export declare function isPanelNavCollapsed(panelNavHost: HTMLElement | null, navRoot: HTMLElement | null): boolean;
|
|
10
|
+
export declare function panelWidthPxFromTokens(tokens: PanelNavWidthTokens, collapsed: boolean): number;
|
|
11
|
+
export declare function barGradientPositionFromPanelWidth(panelWidthPx: number): string;
|
|
12
|
+
//# sourceMappingURL=shell-chrome-metrics.d.ts.map
|
|
@@ -8,6 +8,8 @@ export declare const SHELL_GRADIENT_OPACITY_VAR = "--ds-shell-gradient-opacity";
|
|
|
8
8
|
export declare const SHELL_CHROME_SURFACE_POSITION_VAR = "--ds-shell-chrome-surface-position";
|
|
9
9
|
/** Layer opacity for the nav gradient wash. */
|
|
10
10
|
export declare const SHELL_GRADIENT_OPACITY = "0.1";
|
|
11
|
+
/** Whether the shared chrome layer (bg + optional wash/grid) should mount. */
|
|
12
|
+
export declare function shellChromeLayerActive(gradient: boolean, grid: boolean): boolean;
|
|
11
13
|
/**
|
|
12
14
|
* Shell radial wash — same for panel and bar nav.
|
|
13
15
|
* Tokens follow `data-theme` (light/dark blue intent).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ds-mo/ui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.11.0",
|
|
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/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/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",
|
package/src/angular/proxies.ts
CHANGED
|
@@ -36,14 +36,14 @@ export declare interface DsAccordion extends Components.DsAccordion {
|
|
|
36
36
|
|
|
37
37
|
|
|
38
38
|
@ProxyCmp({
|
|
39
|
-
inputs: ['gradient', 'gradientSrc', 'navStyle']
|
|
39
|
+
inputs: ['gradient', 'gradientSrc', 'grid', 'navStyle']
|
|
40
40
|
})
|
|
41
41
|
@Component({
|
|
42
42
|
selector: 'ds-app-shell',
|
|
43
43
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
44
44
|
template: '<ng-content></ng-content>',
|
|
45
45
|
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
|
|
46
|
-
inputs: ['gradient', 'gradientSrc', 'navStyle'],
|
|
46
|
+
inputs: ['gradient', 'gradientSrc', 'grid', 'navStyle'],
|
|
47
47
|
standalone: false
|
|
48
48
|
})
|
|
49
49
|
export class DsAppShell {
|
|
@@ -650,13 +650,15 @@ export declare interface DsPagination extends Components.DsPagination {
|
|
|
650
650
|
template: '<ng-content></ng-content>',
|
|
651
651
|
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
|
|
652
652
|
inputs: ['activeId', 'breakpoint', 'collapsed', 'currentUrl', 'disableViewTransition', 'groups', 'navStyle', 'routerMode', 'storageKey', 'userInitial', 'userName'],
|
|
653
|
-
outputs: ['dsNavSelect', 'dsNavToggle', 'dsNavFooterAction', 'dsNavUserAction'],
|
|
653
|
+
outputs: ['dsNavSelect', 'dsNavToggle', 'dsChromeTransitionStart', 'dsChromeTransitionEnd', 'dsNavFooterAction', 'dsNavUserAction'],
|
|
654
654
|
standalone: false
|
|
655
655
|
})
|
|
656
656
|
export class DsPanelNav {
|
|
657
657
|
protected el: HTMLDsPanelNavElement;
|
|
658
658
|
@Output() dsNavSelect = new EventEmitter<CustomEvent<string>>();
|
|
659
659
|
@Output() dsNavToggle = new EventEmitter<CustomEvent<boolean>>();
|
|
660
|
+
@Output() dsChromeTransitionStart = new EventEmitter<CustomEvent<IDsPanelNavChromeTransitionDetail>>();
|
|
661
|
+
@Output() dsChromeTransitionEnd = new EventEmitter<CustomEvent<IDsPanelNavChromeTransitionDetail>>();
|
|
660
662
|
@Output() dsNavFooterAction = new EventEmitter<CustomEvent<void>>();
|
|
661
663
|
@Output() dsNavUserAction = new EventEmitter<CustomEvent<IDsPanelNavPanelNavUserActionDetail>>();
|
|
662
664
|
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
|
@@ -666,6 +668,7 @@ export class DsPanelNav {
|
|
|
666
668
|
}
|
|
667
669
|
|
|
668
670
|
|
|
671
|
+
import type { ChromeTransitionDetail as IDsPanelNavChromeTransitionDetail } from '@ds-mo/ui';
|
|
669
672
|
import type { PanelNavUserActionDetail as IDsPanelNavPanelNavUserActionDetail } from '@ds-mo/ui';
|
|
670
673
|
|
|
671
674
|
export declare interface DsPanelNav extends Components.DsPanelNav {
|
|
@@ -677,6 +680,12 @@ export declare interface DsPanelNav extends Components.DsPanelNav {
|
|
|
677
680
|
* Emitted when the collapse toggle is clicked. Detail = new collapsed state.
|
|
678
681
|
*/
|
|
679
682
|
dsNavToggle: EventEmitter<CustomEvent<boolean>>;
|
|
683
|
+
/**
|
|
684
|
+
* Bubbling lifecycle — `ds-app-shell` pauses chrome metrics during width motion.
|
|
685
|
+
*/
|
|
686
|
+
dsChromeTransitionStart: EventEmitter<CustomEvent<IDsPanelNavChromeTransitionDetail>>;
|
|
687
|
+
|
|
688
|
+
dsChromeTransitionEnd: EventEmitter<CustomEvent<IDsPanelNavChromeTransitionDetail>>;
|
|
680
689
|
/**
|
|
681
690
|
* Emitted when the footer left button (gear / dashboard) is clicked.
|
|
682
691
|
*/
|
|
@@ -697,12 +706,14 @@ export declare interface DsPanelNav extends Components.DsPanelNav {
|
|
|
697
706
|
template: '<ng-content></ng-content>',
|
|
698
707
|
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
|
|
699
708
|
inputs: ['activeTool', 'items', 'itemsJson', 'open'],
|
|
700
|
-
outputs: ['dsToolChange'],
|
|
709
|
+
outputs: ['dsToolChange', 'dsChromeTransitionStart', 'dsChromeTransitionEnd'],
|
|
701
710
|
standalone: false
|
|
702
711
|
})
|
|
703
712
|
export class DsPanelTools {
|
|
704
713
|
protected el: HTMLDsPanelToolsElement;
|
|
705
714
|
@Output() dsToolChange = new EventEmitter<CustomEvent<{ id: IDsPanelToolsPanelToolsToolId; selected: boolean; }>>();
|
|
715
|
+
@Output() dsChromeTransitionStart = new EventEmitter<CustomEvent<IDsPanelToolsChromeTransitionDetail>>();
|
|
716
|
+
@Output() dsChromeTransitionEnd = new EventEmitter<CustomEvent<IDsPanelToolsChromeTransitionDetail>>();
|
|
706
717
|
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
|
|
707
718
|
c.detach();
|
|
708
719
|
this.el = r.nativeElement;
|
|
@@ -711,12 +722,19 @@ export class DsPanelTools {
|
|
|
711
722
|
|
|
712
723
|
|
|
713
724
|
import type { PanelToolsToolId as IDsPanelToolsPanelToolsToolId } from '@ds-mo/ui';
|
|
725
|
+
import type { ChromeTransitionDetail as IDsPanelToolsChromeTransitionDetail } from '@ds-mo/ui';
|
|
714
726
|
|
|
715
727
|
export declare interface DsPanelTools extends Components.DsPanelTools {
|
|
716
728
|
/**
|
|
717
729
|
* Emitted when a rail button is toggled. Detail = { id, selected }.
|
|
718
730
|
*/
|
|
719
731
|
dsToolChange: EventEmitter<CustomEvent<{ id: IDsPanelToolsPanelToolsToolId; selected: boolean; }>>;
|
|
732
|
+
/**
|
|
733
|
+
* Bubbling lifecycle — `ds-bar-nav` defers overflow checks during drawer motion.
|
|
734
|
+
*/
|
|
735
|
+
dsChromeTransitionStart: EventEmitter<CustomEvent<IDsPanelToolsChromeTransitionDetail>>;
|
|
736
|
+
|
|
737
|
+
dsChromeTransitionEnd: EventEmitter<CustomEvent<IDsPanelToolsChromeTransitionDetail>>;
|
|
720
738
|
}
|
|
721
739
|
|
|
722
740
|
|
|
@@ -11,13 +11,15 @@ import type { EventName, StencilReactComponent } from '@stencil/react-output-tar
|
|
|
11
11
|
import { createComponent } from '@stencil/react-output-target/runtime';
|
|
12
12
|
import React from 'react';
|
|
13
13
|
|
|
14
|
-
import { type DsPanelNavCustomEvent, type PanelNavUserActionDetail } from "@ds-mo/ui";
|
|
14
|
+
import { type ChromeTransitionDetail, type DsPanelNavCustomEvent, type PanelNavUserActionDetail } from "@ds-mo/ui";
|
|
15
15
|
import type { Components } from "@ds-mo/ui/dist/components";
|
|
16
16
|
import { DsPanelNav as DsPanelNavElement, defineCustomElement as defineDsPanelNav } from "@ds-mo/ui/dist/components/ds-panel-nav.js";
|
|
17
17
|
|
|
18
18
|
export type DsPanelNavEvents = {
|
|
19
19
|
onDsNavSelect: EventName<DsPanelNavCustomEvent<string>>,
|
|
20
20
|
onDsNavToggle: EventName<DsPanelNavCustomEvent<boolean>>,
|
|
21
|
+
onDsChromeTransitionStart: EventName<DsPanelNavCustomEvent<ChromeTransitionDetail>>,
|
|
22
|
+
onDsChromeTransitionEnd: EventName<DsPanelNavCustomEvent<ChromeTransitionDetail>>,
|
|
21
23
|
onDsNavFooterAction: EventName<DsPanelNavCustomEvent<void>>,
|
|
22
24
|
onDsNavUserAction: EventName<DsPanelNavCustomEvent<PanelNavUserActionDetail>>
|
|
23
25
|
};
|
|
@@ -30,6 +32,8 @@ export const DsPanelNav: StencilReactComponent<DsPanelNavElement, DsPanelNavEven
|
|
|
30
32
|
events: {
|
|
31
33
|
onDsNavSelect: 'dsNavSelect',
|
|
32
34
|
onDsNavToggle: 'dsNavToggle',
|
|
35
|
+
onDsChromeTransitionStart: 'dsChromeTransitionStart',
|
|
36
|
+
onDsChromeTransitionEnd: 'dsChromeTransitionEnd',
|
|
33
37
|
onDsNavFooterAction: 'dsNavFooterAction',
|
|
34
38
|
onDsNavUserAction: 'dsNavUserAction'
|
|
35
39
|
} as DsPanelNavEvents,
|
|
@@ -11,17 +11,25 @@ import type { EventName, StencilReactComponent } from '@stencil/react-output-tar
|
|
|
11
11
|
import { createComponent } from '@stencil/react-output-target/runtime';
|
|
12
12
|
import React from 'react';
|
|
13
13
|
|
|
14
|
-
import { type DsPanelToolsCustomEvent, type PanelToolsToolId } from "@ds-mo/ui";
|
|
14
|
+
import { type ChromeTransitionDetail, type DsPanelToolsCustomEvent, type PanelToolsToolId } from "@ds-mo/ui";
|
|
15
15
|
import type { Components } from "@ds-mo/ui/dist/components";
|
|
16
16
|
import { DsPanelTools as DsPanelToolsElement, defineCustomElement as defineDsPanelTools } from "@ds-mo/ui/dist/components/ds-panel-tools.js";
|
|
17
17
|
|
|
18
|
-
export type DsPanelToolsEvents = {
|
|
18
|
+
export type DsPanelToolsEvents = {
|
|
19
|
+
onDsToolChange: EventName<DsPanelToolsCustomEvent<{ id: PanelToolsToolId; selected: boolean; }>>,
|
|
20
|
+
onDsChromeTransitionStart: EventName<DsPanelToolsCustomEvent<ChromeTransitionDetail>>,
|
|
21
|
+
onDsChromeTransitionEnd: EventName<DsPanelToolsCustomEvent<ChromeTransitionDetail>>
|
|
22
|
+
};
|
|
19
23
|
|
|
20
24
|
export const DsPanelTools: StencilReactComponent<DsPanelToolsElement, DsPanelToolsEvents, Components.DsPanelTools> = /*@__PURE__*/ createComponent<DsPanelToolsElement, DsPanelToolsEvents, Components.DsPanelTools>({
|
|
21
25
|
tagName: 'ds-panel-tools',
|
|
22
26
|
elementClass: DsPanelToolsElement,
|
|
23
27
|
// @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.
|
|
24
28
|
react: React,
|
|
25
|
-
events: {
|
|
29
|
+
events: {
|
|
30
|
+
onDsToolChange: 'dsToolChange',
|
|
31
|
+
onDsChromeTransitionStart: 'dsChromeTransitionStart',
|
|
32
|
+
onDsChromeTransitionEnd: 'dsChromeTransitionEnd'
|
|
33
|
+
} as DsPanelToolsEvents,
|
|
26
34
|
defineCustomElement: defineDsPanelTools
|
|
27
35
|
});
|