@ds-mo/ui 14.22.1 → 14.23.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.
Files changed (133) hide show
  1. package/dist/.package-ready.json +1 -1
  2. package/dist/agent-patterns.json +5 -1
  3. package/dist/agent.json +56 -13
  4. package/dist/angular/ds-panel-tools.d.ts +7 -1
  5. package/dist/angular/ds-panel-tools.js +7 -4
  6. package/dist/angular/ds-shell-app.d.ts +7 -1
  7. package/dist/angular/ds-shell-app.js +5 -2
  8. package/dist/angular/ds-shell-tools.d.ts +4 -1
  9. package/dist/angular/ds-shell-tools.js +7 -4
  10. package/dist/components/ds-message-scroller.js +1 -1
  11. package/dist/components/ds-message-scroller.js.map +1 -1
  12. package/dist/components/ds-panel-nav.js +1 -1
  13. package/dist/components/ds-panel-tools.js +1 -1
  14. package/dist/components/ds-shell-app.js +1 -1
  15. package/dist/components/ds-shell-app.js.map +1 -1
  16. package/dist/components/ds-shell-tools.js +1 -1
  17. package/dist/components/p-Bd-Kpekh.js +2 -0
  18. package/dist/components/p-Bd-Kpekh.js.map +1 -0
  19. package/dist/components/{p-DrVA5L25.js → p-BmqnrfTf.js} +2 -2
  20. package/dist/components/p-BmqnrfTf.js.map +1 -0
  21. package/dist/components/p-C13fWp2x.js +2 -0
  22. package/dist/components/p-C13fWp2x.js.map +1 -0
  23. package/dist/docs/components.json +178 -3
  24. package/dist/lib/components/PanelTools/panel-tools-types.d.ts +76 -1
  25. package/dist/lib/components/ShellApp/shell-app-types.d.ts +3 -1
  26. package/dist/lib/shell/index.d.ts +1 -1
  27. package/dist/lib/shell/index.js.map +2 -2
  28. package/dist/mcp-data/registry/agent-activity.json +1 -1
  29. package/dist/mcp-data/registry/agent-questionnaire.json +1 -1
  30. package/dist/mcp-data/registry/agent-response.json +1 -1
  31. package/dist/mcp-data/registry/agent-source-list.json +1 -1
  32. package/dist/mcp-data/registry/agent-tool-call.json +1 -1
  33. package/dist/mcp-data/registry/attachment-list.json +1 -1
  34. package/dist/mcp-data/registry/avatar.json +1 -1
  35. package/dist/mcp-data/registry/badge.json +1 -1
  36. package/dist/mcp-data/registry/banner.json +1 -1
  37. package/dist/mcp-data/registry/bar-action.json +1 -1
  38. package/dist/mcp-data/registry/bar-nav.json +1 -1
  39. package/dist/mcp-data/registry/bar-title.json +1 -1
  40. package/dist/mcp-data/registry/bar-workflow.json +1 -1
  41. package/dist/mcp-data/registry/breadcrumb.json +1 -1
  42. package/dist/mcp-data/registry/button-filled.json +1 -1
  43. package/dist/mcp-data/registry/button-unfilled.json +1 -1
  44. package/dist/mcp-data/registry/card-chart.json +1 -1
  45. package/dist/mcp-data/registry/card-overview.json +1 -1
  46. package/dist/mcp-data/registry/card-setting.json +1 -1
  47. package/dist/mcp-data/registry/chart-legend.json +1 -1
  48. package/dist/mcp-data/registry/chart.json +1 -1
  49. package/dist/mcp-data/registry/checkbox.json +1 -1
  50. package/dist/mcp-data/registry/chip.json +1 -1
  51. package/dist/mcp-data/registry/code-block.json +1 -1
  52. package/dist/mcp-data/registry/conversation-list-item.json +1 -1
  53. package/dist/mcp-data/registry/conversation-list-section.json +1 -1
  54. package/dist/mcp-data/registry/conversation-list.json +1 -1
  55. package/dist/mcp-data/registry/divider.json +1 -1
  56. package/dist/mcp-data/registry/empty-state.json +1 -1
  57. package/dist/mcp-data/registry/field.json +1 -1
  58. package/dist/mcp-data/registry/filter-menu.json +1 -1
  59. package/dist/mcp-data/registry/icon.json +1 -1
  60. package/dist/mcp-data/registry/input.json +1 -1
  61. package/dist/mcp-data/registry/loader.json +1 -1
  62. package/dist/mcp-data/registry/markdown.json +1 -1
  63. package/dist/mcp-data/registry/menu.json +1 -1
  64. package/dist/mcp-data/registry/message-actions.json +1 -1
  65. package/dist/mcp-data/registry/message-bubble.json +1 -1
  66. package/dist/mcp-data/registry/message-composer.json +1 -1
  67. package/dist/mcp-data/registry/message-scroller.json +9 -2
  68. package/dist/mcp-data/registry/message.json +1 -1
  69. package/dist/mcp-data/registry/mobile-bar-nav.json +1 -1
  70. package/dist/mcp-data/registry/mobile-header.json +1 -1
  71. package/dist/mcp-data/registry/mobile-section-switcher.json +1 -1
  72. package/dist/mcp-data/registry/mobile-sheet-nav.json +1 -1
  73. package/dist/mcp-data/registry/modal.json +1 -1
  74. package/dist/mcp-data/registry/pagination.json +1 -1
  75. package/dist/mcp-data/registry/panel-nav.json +2 -2
  76. package/dist/mcp-data/registry/panel-sub-nav.json +1 -1
  77. package/dist/mcp-data/registry/panel-tool-header.json +1 -1
  78. package/dist/mcp-data/registry/panel-tool-search.json +1 -1
  79. package/dist/mcp-data/registry/panel-tools.json +62 -15
  80. package/dist/mcp-data/registry/paper-texture.json +1 -1
  81. package/dist/mcp-data/registry/radio.json +1 -1
  82. package/dist/mcp-data/registry/registry.json +56 -13
  83. package/dist/mcp-data/registry/scroll-overlay.json +1 -1
  84. package/dist/mcp-data/registry/select.json +1 -1
  85. package/dist/mcp-data/registry/shell-app.json +22 -3
  86. package/dist/mcp-data/registry/shell-page.json +1 -1
  87. package/dist/mcp-data/registry/shell-tools.json +39 -6
  88. package/dist/mcp-data/registry/skeleton.json +1 -1
  89. package/dist/mcp-data/registry/slider.json +1 -1
  90. package/dist/mcp-data/registry/swatch-picker.json +1 -1
  91. package/dist/mcp-data/registry/switch.json +1 -1
  92. package/dist/mcp-data/registry/tab-group.json +1 -1
  93. package/dist/mcp-data/registry/table-filter.json +1 -1
  94. package/dist/mcp-data/registry/table-group.json +1 -1
  95. package/dist/mcp-data/registry/table-saved-views.json +1 -1
  96. package/dist/mcp-data/registry/table-search.json +1 -1
  97. package/dist/mcp-data/registry/table-sort.json +1 -1
  98. package/dist/mcp-data/registry/table-toolbar.json +1 -1
  99. package/dist/mcp-data/registry/table.json +1 -1
  100. package/dist/mcp-data/registry/tag.json +1 -1
  101. package/dist/mcp-data/registry/text.json +1 -1
  102. package/dist/mcp-data/registry/toast.json +1 -1
  103. package/dist/mcp-data/registry/tooltip-chart.json +1 -1
  104. package/dist/mcp-data/registry/tooltip.json +1 -1
  105. package/dist/mcp-data/registry/typing-indicator.json +1 -1
  106. package/dist/react/ds-panel-tools.d.ts +2 -1
  107. package/dist/react/ds-panel-tools.js +1 -0
  108. package/dist/react/ds-shell-app.d.ts +2 -1
  109. package/dist/react/ds-shell-app.js +1 -0
  110. package/dist/react/ds-shell-tools.d.ts +2 -1
  111. package/dist/react/ds-shell-tools.js +2 -1
  112. package/dist/types/components/MessageScroller/MessageScroller.d.ts +14 -0
  113. package/dist/types/components/MessageScroller/message-scroller-transcript.d.ts +9 -0
  114. package/dist/types/components/PanelNav/PanelNav.d.ts +6 -1
  115. package/dist/types/components/PanelTools/PanelTools.d.ts +17 -1
  116. package/dist/types/components/PanelTools/index.d.ts +1 -1
  117. package/dist/types/components/PanelTools/panel-tools-types.d.ts +76 -1
  118. package/dist/types/components/PanelTools/panel-tools-utils.d.ts +17 -1
  119. package/dist/types/components/ShellApp/ShellApp.d.ts +4 -1
  120. package/dist/types/components/ShellApp/shell-app-types.d.ts +3 -1
  121. package/dist/types/components/ShellTools/ShellTools.d.ts +5 -1
  122. package/dist/types/components/ShellTools/index.d.ts +1 -1
  123. package/dist/types/components.d.ts +34 -2
  124. package/dist/types/shell/index.d.ts +1 -1
  125. package/dist/vue/ds-panel-tools.js +3 -0
  126. package/dist/vue/ds-shell-app.js +2 -0
  127. package/dist/vue/ds-shell-tools.js +5 -2
  128. package/package.json +3 -3
  129. package/dist/components/p-COFw_fcj.js +0 -2
  130. package/dist/components/p-COFw_fcj.js.map +0 -1
  131. package/dist/components/p-CvHrCyuz.js +0 -2
  132. package/dist/components/p-CvHrCyuz.js.map +0 -1
  133. package/dist/components/p-DrVA5L25.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"names":["PANEL_TOOLS_TOOL_IDS","PANEL_TOOLS_PRIMARY_TOOL_ID","PANEL_TOOLS_LABELS","search","messages","stacks","activity","agents","help","PANEL_TOOLS_SHORTCUTS","PANEL_TOOLS_DEFAULT_ITEMS","id","icon","label","railPlacement","order","shortcutKey","mobileDestination","PANEL_TOOLS_REGION_ORDER","header","body","footer","panelToolsItemOrder","item","canonical","findIndex","Number","MAX_SAFE_INTEGER","orderPanelToolsItems","items","firstById","Map","trim","has","set","Array","from","values","sort","left","right","leftRegion","panelToolsRailPlacement","rightRegion","regionDelta","orderPanelToolsRailEntries","accessories","toolEntries","map","type","firstAccessoryById","accessory","accessoryEntries","leftPlacement","rightPlacement","leftOrder","rightOrder","panelToolsRailFocusKeys","entries","flatMap","entry","action","isInactive","keys","primaryAction","secondaryAction","push","reconcilePanelToolsRovingIndex","previousKeys","nextKeys","currentIndex","length","currentKey","preservedIndex","indexOf","index","nextIndex","Math","min","max","panelToolsRailAccessoryActionDetail","accessoryId","actionId","anchor","isPanelToolsToolId","value","reconcilePanelToolsAvailability","open","activeTool","some","removedTool","panelToolsDrawerTransitionMs","style","properties","transitionProperty","split","durations","transitionDuration","parseCssTimeMs","delays","transitionDelay","reduce","property","duration","delay","panelToolsDrawerResting","motion","panelToolsDrawerAtTerminal","width","targetWidth","resolvePanelToolActivation","selected","panelToolsCss","PanelTools","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","presentation","fullscreenHeaderMode","toolsLabel","toolShortcutsLabel","headers","storageKey","drawerSurfaceRetained","readyForMotion","presentationMotionSuppressed","rovingIndex","fullViewToolIds","railBodyScrollable","motionEnableGeneration","presentationMotionGeneration","transitionGeneration","transitionFallbackTimer","ignoreReplacementTerminal","focusBeforeFullscreen","fullViewObserver","handleComposedHeaderAction","event","detail","stopPropagation","dsHeaderAction","emit","tool","handleTransitionEnd","drawer","renderRoot","querySelector","target","propertyName","drawerTransitionAtTerminal","finishDrawerTransition","handleToolChange","next","dsToolChange","handleRailKeyDown","e","activate","orderedRailEntries","key","preventDefault","focusRailAt","railItems","orderedRailItems","railAccessories","disconnectedCallback","el","removeEventListener","clearTransitionCompletion","disconnect","disconnectRailBodyObserver","presentationChanged","previous","getAttribute","setAttribute","presentationGeneration","requestAnimationFrame","document","activeElement","fallbackActionId","activeHeader","actions","async","isConnected","focus","preventScroll","focusRestored","contains","focusHeaderAction","dsPresentationChange","handleFullscreenEscape","deferMotionEnable","generation","connectedCallback","addEventListener","componentWillLoad","restoreLastActiveTool","openChanged","isOpen","wasOpen","undefined","startDrawerTransition","activeToolChanged","persistLastActiveTool","storageKeyChanged","componentDidLoad","connectRailBodyObserver","updateRailBodyScrollable","syncFullViewTools","MutationObserver","observe","childList","attributes","attributeFilter","componentDidRender","railBodyEl","ResizeObserver","railBodyObserver","Boolean","scrollHeight","clientHeight","itemsChanged","reconcileActiveTool","accessoriesChanged","focusedKey","closest","dataset","railFocusKey","focusedIndex","restoreFocus","includes","stored","localStorage","getItem","setItem","clearPersistedTool","removeItem","phase","dsChromeTransitionStart","source","fallbackMs","getComputedStyle","window","setTimeout","getBoundingClientRect","surface","completedPhase","wasTransitioning","dsChromeTransitionEnd","clearTimeout","isRailSelected","isDrawerPresent","isViewActive","hasFullView","ids","filter","join","shadowRoot","headerLabel","find","candidate","resolvedHeaders","activateTool","closeDrawer","CSS","escape","setFocus","bounded","renderRailAction","focusKey","ariaLabel","h","side","size","boundary","variant","class","isActive","activeFill","hasBorder","pressScale","dot","focusTabIndex","pressed","onFocusin","onKeyDown","onDsClick","accessoryPrimaryLabel","actionLabel","status","statusText","emitAccessoryAction","dsRailAccessoryAction","renderAccessoryVisual","visual","src","alt","initial","slice","as","emphasis","color","name","renderRailShortcut","focusIndexes","focusIndex","get","initials","disabled","tabIndex","onFocus","onClick","currentTarget","background","renderRailAccessory","primaryKey","primaryIndex","primaryLabel","secondary","secondaryKey","secondaryIndex","statusTone","rounded","renderRailEntry","render","headerTitle","title","headerActions","entryPlacement","headerEntries","bodyEntries","footerEntries","showDrawerChrome","drawerResting","activeFullView","toolIds","Host","role","ref","element","inert","heading","showBack","backIcon","backAriaLabel","showMenu","toolHeader","onDsBack","dsHeaderBack","hidden","active"],"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=shadow","src/wc/components/PanelTools/PanelTools.tsx"],"sourcesContent":["/** Application-owned tool id for the shell rail and responsive tool views. */\nexport type PanelToolsToolId = string;\n\n/** Canonical Motive shell recipe used when item metadata is omitted. */\nexport type CanonicalPanelToolsToolId =\n | 'search'\n | 'messages'\n | 'agents'\n | 'stacks'\n | 'activity'\n | 'help';\n\nexport const PANEL_TOOLS_TOOL_IDS: CanonicalPanelToolsToolId[] = [\n 'agents',\n 'messages',\n 'activity',\n 'search',\n 'stacks',\n 'help',\n];\n\n/** Rail header slot — mirrors panel-nav M logo row. */\nexport const PANEL_TOOLS_PRIMARY_TOOL_ID: CanonicalPanelToolsToolId = 'agents';\n\n/** Rail footer slot — flush to the bottom of the tools column. */\nexport const PANEL_TOOLS_FOOTER_TOOL_ID: CanonicalPanelToolsToolId = 'help';\n\nexport const PANEL_TOOLS_LABELS: Record<CanonicalPanelToolsToolId, string> = {\n search: 'Search',\n messages: 'Messages',\n stacks: 'Stacks',\n activity: 'Activity',\n agents: 'Agents',\n help: 'Help & Support',\n};\n\nexport const PANEL_TOOLS_SHORTCUTS: Partial<Record<CanonicalPanelToolsToolId, string>> = {\n search: 'K',\n agents: 'A',\n messages: 'M',\n stacks: 'S',\n activity: 'N',\n help: '/',\n};\n\nexport type PanelToolsRailPlacement = 'header' | 'body' | 'footer';\n\nexport interface PanelToolsItem {\n id: PanelToolsToolId;\n /** Icon name for <ds-icon>. */\n icon: string;\n /** Visible and accessible fallback label for custom tool ids. */\n label?: string;\n /** Explicit rail region; canonical Agents/Help placement is the fallback. */\n railPlacement?: PanelToolsRailPlacement;\n /** Stable ordering within the selected rail region. */\n order?: number;\n /** Optional shortcut label displayed by the tooltip. */\n shortcutKey?: string;\n /** Mobile destination recipe; canonical ids retain their explicit defaults. */\n mobileDestination?: 'search' | 'inbox' | 'activity' | 'messages' | 'agents' | 'help';\n /** Whether this rail button is currently pressed/active. */\n selected?: boolean;\n /** Show a notification dot. */\n dot?: boolean;\n isInactive?: boolean;\n ariaLabel?: string;\n}\n\nexport type PanelToolsRailAccessoryVisual =\n | { type: 'icon'; icon: string }\n | { type: 'initial'; initial: string }\n | { type: 'image'; src: string };\n\nexport interface PanelToolsRailAccessoryAction {\n /** Stable application-owned action id emitted with the accessory id. */\n id: string;\n /** Overrides the accessory label for the primary action. */\n ariaLabel?: string;\n isInactive?: boolean;\n}\n\nexport interface PanelToolsRailAccessorySecondaryAction {\n id: string;\n icon: string;\n ariaLabel: string;\n isInactive?: boolean;\n}\n\nexport type PanelToolsRailTransientTone = 'active' | 'positive';\n\ninterface PanelToolsRailAccessoryBase {\n /** Stable application-owned identity. Duplicate or blank ids are omitted. */\n id: string;\n /** Explicit rail region; accessories never infer placement from their id. */\n railPlacement: PanelToolsRailPlacement;\n /** Stable ordering within the selected rail region. */\n order: number;\n}\n\n/** Decorative boundary between application-owned rail accessory groups. */\nexport interface PanelToolsRailDividerAccessory extends PanelToolsRailAccessoryBase {\n type: 'divider';\n}\n\n/**\n * A compact one-action shortcut that matches standard tool-button geometry.\n * PanelTools owns its initial orb, notification dot, and transient interaction paint.\n */\nexport interface PanelToolsRailShortcutAccessory extends PanelToolsRailAccessoryBase {\n type: 'shortcut';\n /** Accessible shortcut name and action-label fallback. */\n ariaLabel: string;\n /** One or two displayed graphemes. Longer values are truncated visually. */\n initials: string;\n /** Supplemental notification dot. Include its meaning in the accessible label when needed. */\n dot?: boolean;\n action: PanelToolsRailAccessoryAction;\n}\n\n/**\n * A direct application intent that never selects a tool or changes drawer state.\n * PanelTools owns the two-control-height surface and its focus behavior.\n */\nexport interface PanelToolsRailTransientAccessory extends PanelToolsRailAccessoryBase {\n type: 'transient';\n /** Accessible accessory name and primary-action fallback label. */\n ariaLabel: string;\n visual: PanelToolsRailAccessoryVisual;\n /** State announced with the primary action and shown in its tooltip. */\n statusText: string;\n /** Bold surface treatment. Active uses brand; positive uses positive semantic color. */\n statusTone: PanelToolsRailTransientTone;\n primaryAction: PanelToolsRailAccessoryAction;\n secondaryAction?: PanelToolsRailAccessorySecondaryAction;\n}\n\nexport type PanelToolsRailAccessory =\n | PanelToolsRailDividerAccessory\n | PanelToolsRailShortcutAccessory\n | PanelToolsRailTransientAccessory;\n\nexport interface PanelToolsRailAccessoryActionDetail {\n accessoryId: string;\n actionId: string;\n /** Rendered action control, suitable for anchoring an application-owned overlay. */\n anchor: HTMLElement;\n}\n\n/** Canonical shell recipe used by Lab and by managed ShellApp examples. */\nexport const PANEL_TOOLS_DEFAULT_ITEMS: PanelToolsItem[] = [\n {\n id: 'agents',\n icon: 'AI',\n label: PANEL_TOOLS_LABELS.agents,\n railPlacement: 'header',\n order: 0,\n shortcutKey: PANEL_TOOLS_SHORTCUTS.agents,\n mobileDestination: 'agents',\n },\n {\n id: 'messages',\n icon: 'MessageBubbleStack',\n label: PANEL_TOOLS_LABELS.messages,\n order: 0,\n shortcutKey: PANEL_TOOLS_SHORTCUTS.messages,\n mobileDestination: 'messages',\n },\n {\n id: 'activity',\n icon: 'Bell',\n label: PANEL_TOOLS_LABELS.activity,\n order: 1,\n shortcutKey: PANEL_TOOLS_SHORTCUTS.activity,\n mobileDestination: 'activity',\n },\n {\n id: 'search',\n icon: 'MagnifyingGlass',\n label: PANEL_TOOLS_LABELS.search,\n order: 2,\n shortcutKey: PANEL_TOOLS_SHORTCUTS.search,\n mobileDestination: 'search',\n },\n {\n id: 'help',\n icon: 'CircleQuestion',\n label: PANEL_TOOLS_LABELS.help,\n railPlacement: 'footer',\n order: 0,\n shortcutKey: PANEL_TOOLS_SHORTCUTS.help,\n mobileDestination: 'help',\n },\n];\n\nexport interface PanelToolsHeaderAction {\n id: string;\n icon: string;\n ariaLabel: string;\n triggerId?: string;\n controls?: string;\n expanded?: boolean;\n haspopup?: 'menu' | 'dialog' | 'listbox' | 'tree' | 'grid';\n pressed?: boolean;\n isInactive?: boolean;\n}\n\nexport interface PanelToolsHeaderActionDetail {\n tool: PanelToolsToolId;\n id: string;\n /** Rendered header action host. Pass this to an external overlay's element anchor prop. */\n anchor?: HTMLElement;\n}\n\nexport interface PanelToolHeaderActionDetail {\n id: string;\n originalEvent: MouseEvent;\n /** Rendered action host, suitable for anchoring an external overlay across a shadow boundary. */\n anchor: HTMLElement;\n}\n\nexport interface PanelToolsHeaderConfig {\n title?: string;\n showBack?: boolean;\n backIcon?: string;\n backAriaLabel?: string;\n actions?: PanelToolsHeaderAction[];\n}\n\n/** Per-tool header state. The application replaces the object when a tool changes depth or actions. */\nexport type PanelToolsHeaders = Partial<Record<PanelToolsToolId, PanelToolsHeaderConfig>>;\n","import { parseCssTimeMs } from '../../utils/resolve-css-time-ms';\nimport {\n PANEL_TOOLS_PRIMARY_TOOL_ID,\n PANEL_TOOLS_TOOL_IDS,\n type PanelToolsItem,\n type PanelToolsRailAccessory,\n type PanelToolsRailAccessoryActionDetail,\n type PanelToolsRailPlacement,\n type PanelToolsToolId,\n} from './panel-tools-types';\n\nconst PANEL_TOOLS_REGION_ORDER: Record<PanelToolsRailPlacement, number> = {\n header: 0,\n body: 1,\n footer: 2,\n};\n\nfunction panelToolsItemOrder(item: PanelToolsItem): number {\n const canonical = PANEL_TOOLS_TOOL_IDS.findIndex(id => id === item.id);\n return item.order ?? (canonical < 0 ? Number.MAX_SAFE_INTEGER : canonical);\n}\n\nexport function orderPanelToolsItems(items: PanelToolsItem[]): PanelToolsItem[] {\n const firstById = new Map<PanelToolsToolId, PanelToolsItem>();\n for (const item of items) {\n if (item.id.trim() && !firstById.has(item.id)) firstById.set(item.id, item);\n }\n return Array.from(firstById.values()).sort((left, right) => {\n const leftRegion = panelToolsRailPlacement(left);\n const rightRegion = panelToolsRailPlacement(right);\n const regionDelta =\n PANEL_TOOLS_REGION_ORDER[leftRegion] - PANEL_TOOLS_REGION_ORDER[rightRegion];\n if (regionDelta !== 0) return regionDelta;\n\n return panelToolsItemOrder(left) - panelToolsItemOrder(right);\n });\n}\n\nexport type PanelToolsRailEntry =\n | { type: 'tool'; id: string; item: PanelToolsItem }\n | { type: 'accessory'; id: string; accessory: PanelToolsRailAccessory };\n\n/** Merge tools and governed accessories into one visual and keyboard order. */\nexport function orderPanelToolsRailEntries(\n items: PanelToolsItem[],\n accessories: PanelToolsRailAccessory[]\n): PanelToolsRailEntry[] {\n const toolEntries: PanelToolsRailEntry[] = orderPanelToolsItems(items).map(item => ({\n type: 'tool',\n id: item.id,\n item,\n }));\n const firstAccessoryById = new Map<string, PanelToolsRailAccessory>();\n for (const accessory of accessories) {\n if (accessory.id.trim() && !firstAccessoryById.has(accessory.id)) {\n firstAccessoryById.set(accessory.id, accessory);\n }\n }\n const accessoryEntries: PanelToolsRailEntry[] = Array.from(firstAccessoryById.values()).map(\n accessory => ({\n type: 'accessory',\n id: accessory.id,\n accessory,\n })\n );\n\n return [...toolEntries, ...accessoryEntries].sort((left, right) => {\n const leftPlacement =\n left.type === 'tool' ? panelToolsRailPlacement(left.item) : left.accessory.railPlacement;\n const rightPlacement =\n right.type === 'tool' ? panelToolsRailPlacement(right.item) : right.accessory.railPlacement;\n const regionDelta =\n PANEL_TOOLS_REGION_ORDER[leftPlacement] - PANEL_TOOLS_REGION_ORDER[rightPlacement];\n if (regionDelta !== 0) return regionDelta;\n\n const leftOrder = left.type === 'tool' ? panelToolsItemOrder(left.item) : left.accessory.order;\n const rightOrder =\n right.type === 'tool' ? panelToolsItemOrder(right.item) : right.accessory.order;\n return leftOrder - rightOrder;\n });\n}\n\n/** Flatten interactive entries while leaving decorative boundaries out of focus order. */\nexport function panelToolsRailFocusKeys(entries: PanelToolsRailEntry[]): string[] {\n return entries.flatMap(entry => {\n if (entry.type === 'tool') return [`tool:${entry.id}`];\n if (entry.accessory.type === 'divider') return [];\n if (entry.accessory.type === 'shortcut') {\n return entry.accessory.action.isInactive\n ? []\n : [`accessory:${entry.id}:${entry.accessory.action.id}`];\n }\n const keys = entry.accessory.primaryAction.isInactive\n ? []\n : [`accessory:${entry.id}:${entry.accessory.primaryAction.id}`];\n if (entry.accessory.secondaryAction && !entry.accessory.secondaryAction.isInactive) {\n keys.push(`accessory:${entry.id}:${entry.accessory.secondaryAction.id}`);\n }\n return keys;\n });\n}\n\n/** Preserve the current target across collection changes, or choose its nearest survivor. */\nexport function reconcilePanelToolsRovingIndex(\n previousKeys: string[],\n nextKeys: string[],\n currentIndex: number\n): number {\n if (!nextKeys.length) return 0;\n const currentKey = previousKeys[currentIndex];\n const preservedIndex = currentKey ? nextKeys.indexOf(currentKey) : -1;\n if (preservedIndex >= 0) return preservedIndex;\n for (let index = currentIndex + 1; index < previousKeys.length; index += 1) {\n const nextIndex = nextKeys.indexOf(previousKeys[index]);\n if (nextIndex >= 0) return nextIndex;\n }\n for (let index = currentIndex - 1; index >= 0; index -= 1) {\n const nextIndex = nextKeys.indexOf(previousKeys[index]);\n if (nextIndex >= 0) return nextIndex;\n }\n return Math.min(Math.max(currentIndex, 0), nextKeys.length - 1);\n}\n\nexport function panelToolsRailAccessoryActionDetail(\n accessoryId: string,\n actionId: string,\n anchor: HTMLElement\n): PanelToolsRailAccessoryActionDetail {\n return { accessoryId, actionId, anchor };\n}\n\nexport function isPanelToolsToolId(value: string | null): value is PanelToolsToolId {\n return typeof value === 'string' && value.trim().length > 0;\n}\n\nexport function panelToolsRailPlacement(item: PanelToolsItem): 'header' | 'body' | 'footer' {\n if (item.railPlacement) return item.railPlacement;\n if (item.id === PANEL_TOOLS_PRIMARY_TOOL_ID) return 'header';\n if (item.id === 'help') return 'footer';\n return 'body';\n}\n\nexport function reconcilePanelToolsAvailability(\n items: PanelToolsItem[],\n open: boolean,\n activeTool: PanelToolsToolId | ''\n): { open: boolean; activeTool: PanelToolsToolId | ''; removedTool: PanelToolsToolId | '' } {\n if (!activeTool || items.some(item => item.id === activeTool)) {\n return { open, activeTool, removedTool: '' };\n }\n return { open: false, activeTool: '', removedTool: activeTool };\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.label !== item.label ||\n prior.railPlacement !== item.railPlacement ||\n prior.order !== item.order ||\n prior.shortcutKey !== item.shortcutKey ||\n prior.mobileDestination !== item.mobileDestination ||\n prior.selected !== item.selected ||\n prior.dot !== item.dot ||\n prior.isInactive !== item.isInactive ||\n prior.ariaLabel !== item.ariaLabel\n );\n });\n}\n\nexport type PanelToolsMotion = 'opening' | 'closing' | 'idle';\n\nexport interface PanelToolsTransitionStyle {\n transitionProperty: string;\n transitionDuration: string;\n transitionDelay: string;\n}\n\n/** Maximum computed time for the drawer's max-width transition, including delay. */\nexport function panelToolsDrawerTransitionMs(style: PanelToolsTransitionStyle): number {\n const properties = style.transitionProperty.split(',').map(item => item.trim());\n const durations = style.transitionDuration.split(',').map(item => parseCssTimeMs(item.trim(), 0));\n const delays = style.transitionDelay.split(',').map(item => parseCssTimeMs(item.trim(), 0));\n\n return properties.reduce((max, property, index) => {\n if (property !== 'all' && property !== 'max-width') return max;\n const duration = durations[index % durations.length] ?? 0;\n const delay = delays[index % delays.length] ?? 0;\n return Math.max(max, duration + delay, 0);\n }, 0);\n}\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\n/** True only when the animated clip has reached the terminal width for its motion phase. */\nexport function panelToolsDrawerAtTerminal(\n width: number,\n targetWidth: number,\n motion: PanelToolsMotion\n): boolean {\n if (motion === 'closing') return width <= 0.5;\n if (motion === 'opening') return targetWidth > 0 && width >= targetWidth - 0.5;\n return true;\n}\n\n/** Toggle or switch rail tool selection — repeat activation closes the active tool. */\nexport function resolvePanelToolActivation(\n open: boolean,\n activeTool: PanelToolsToolId | '',\n id: PanelToolsToolId\n): { open: boolean; activeTool: PanelToolsToolId; selected: boolean } {\n if (open && activeTool === id) {\n return { open: false, activeTool: id, selected: false };\n }\n return { open: true, activeTool: id, selected: true };\n}\n","@import '../../utils/control-density.css';\n@import '../../utils/chrome-layout.css';\n@import '../../utils/focus-ring.css';\n@import '../../utils/interaction-fill.css';\n@import '../../utils/scrollbar-hidden.css';\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(--ds-shell-panel-tools-width, var(--dimension-panel-width-xs));\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-reverse;\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__drawer {\n transition: max-width var(--_panel-tools-expand-dur)\n var(--effect-animation-easing-ease-in-out, ease);\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 — ShellApp supplies the standard 300px tools width. */\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: transparent;\n}\n\n.panel-tools__full-views,\n.panel-tools__full-view {\n flex: 1 1 auto;\n min-height: 0;\n overflow: hidden;\n}\n\n.panel-tools__full-view {\n height: 100%;\n}\n\n.panel-tools__full-view {\n display: none;\n}\n.panel-tools__full-view--active {\n display: block;\n}\n\n:host([presentation='fullscreen']) {\n height: 100vh;\n inset: 0;\n position: fixed;\n width: 100vw;\n z-index: var(--dimension-z-index-modal);\n}\n\n:host([presentation='fullscreen']) .panel-tools__rail {\n display: none;\n}\n:host([presentation='fullscreen']) .panel-tools__drawer {\n max-width: 100vw;\n transition: none;\n width: 100vw;\n}\n:host([presentation='fullscreen']) .panel-tools__drawer--visible {\n border-left: none;\n}\n:host([presentation='fullscreen']) .panel-tools__drawer-surface {\n background-color: transparent;\n width: 100vw;\n}\n\n/*\n * A framework can update the reflected presentation attribute before Stencil\n * commits the matching render class. Conceal that single inconsistent frame so\n * slotted master/detail content never paints against the previous geometry.\n */\n:host([presentation='fullscreen']:not(.panel-tools--fullscreen)) .panel-tools__drawer-surface,\n:host(.panel-tools--fullscreen:not([presentation='fullscreen'])) .panel-tools__drawer-surface {\n visibility: hidden;\n}\n\n:host(.panel-tools--presentation-snap) .panel-tools__drawer {\n transition: none;\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-ui);\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-ui);\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: transparent;\n}\n\n.panel-tools__rail-header {\n justify-content: center;\n height: var(--dimension-size-600);\n flex-shrink: 0;\n border-bottom: var(--_panel-tools-border);\n}\n\n.panel-tools__rail-header.panel-tools__rail-section--stacked {\n height: auto;\n min-height: var(--dimension-size-600);\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}\n\n.panel-tools__rail-actions {\n display: flex;\n flex-direction: column;\n gap: var(--dimension-space-050);\n width: 100%;\n}\n\n/* Flush to the bottom of the rail — mirrors Search header pin. */\n.panel-tools__rail-footer {\n justify-content: center;\n flex-shrink: 0;\n margin-top: auto;\n}\n\n.panel-tools__rail-section--stacked {\n align-items: stretch;\n}\n\n.panel-tools__rail-action {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: var(--ds-control-height);\n flex-shrink: 0;\n}\n\n.panel-tools__accessory {\n display: flex;\n flex-direction: column;\n flex: 0 0 calc(var(--dimension-size-400) * 2);\n box-sizing: border-box;\n width: 100%;\n min-height: calc(var(--dimension-size-400) * 2);\n}\n\n.panel-tools__accessory--shortcut {\n flex-basis: var(--dimension-size-400);\n min-width: var(--dimension-size-400);\n min-height: var(--dimension-size-400);\n}\n\n.panel-tools__accessory--shortcut > ds-tooltip {\n display: flex;\n flex: 1 1 auto;\n width: 100%;\n min-height: 0;\n}\n\n.panel-tools__accessory--transient {\n align-items: center;\n gap: var(--dimension-space-100);\n width: var(--dimension-size-400);\n height: calc(var(--dimension-size-400) * 2);\n min-height: calc(var(--dimension-size-400) * 2);\n padding: var(--dimension-space-050);\n border-radius: var(--dimension-radius-half);\n}\n\n.panel-tools__accessory--transient-active {\n background-color: var(--color-background-bold-brand);\n}\n\n.panel-tools__accessory--transient-positive {\n background-color: var(--color-background-bold-positive);\n}\n\n.panel-tools__accessory--transient > ds-tooltip {\n display: flex;\n flex: 0 0 var(--dimension-size-300);\n width: var(--dimension-size-300);\n height: var(--dimension-size-300);\n min-height: var(--dimension-size-300);\n}\n\n.panel-tools__shortcut {\n display: flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n width: 100%;\n height: 100%;\n margin: 0;\n padding: 0;\n border: 0;\n border-radius: var(--dimension-radius-half);\n color: var(--color-foreground-secondary);\n background: transparent;\n font: inherit;\n}\n\n.panel-tools__shortcut:disabled {\n color: var(--color-foreground-disabled);\n cursor: not-allowed;\n}\n\n.panel-tools__shortcut-content {\n display: flex;\n align-items: center;\n justify-content: center;\n width: var(--dimension-size-400);\n height: var(--dimension-size-400);\n}\n\n.panel-tools__shortcut-orb {\n display: flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n width: var(--dimension-size-300);\n height: var(--dimension-size-300);\n border: var(--dimension-stroke-width-012) solid var(--color-border-secondary);\n border-radius: var(--dimension-radius-half);\n background: transparent;\n}\n\n.panel-tools__shortcut-dot {\n position: absolute;\n inset-block-start: calc((var(--dimension-size-400) - var(--dimension-iconography-md)) / 2);\n inset-inline-end: calc((var(--dimension-size-400) - var(--dimension-iconography-md)) / 2);\n z-index: 2;\n pointer-events: none;\n}\n\n.panel-tools__accessory-primary {\n display: flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n width: var(--dimension-size-300);\n height: var(--dimension-size-300);\n margin: 0;\n padding: 0;\n border: 0;\n border-radius: var(--dimension-radius-half);\n color: var(--color-foreground-on-bold-background-secondary);\n background: transparent;\n font: inherit;\n --ds-interaction-border-width: var(--dimension-stroke-width-012);\n --ds-interaction-border-color: var(--color-border-on-bold-background-secondary);\n}\n\n.panel-tools__accessory-primary:disabled {\n color: var(--color-foreground-on-bold-background-quaternary);\n cursor: not-allowed;\n}\n\n.panel-tools__accessory-primary-content {\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n width: 100%;\n height: 100%;\n}\n\n.panel-tools__accessory-image,\n.panel-tools__accessory-initial {\n display: flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n width: 100%;\n height: 100%;\n border-radius: var(--dimension-radius-half);\n}\n\n.panel-tools__accessory-image {\n object-fit: cover;\n}\n\n.panel-tools__accessory-initial {\n color: inherit;\n background: transparent;\n}\n\n.panel-tools__accessory-secondary {\n display: inline-flex;\n flex: 0 0 var(--dimension-size-300);\n width: var(--dimension-size-300);\n height: var(--dimension-size-300);\n}\n\n.panel-tools__accessory-divider {\n flex: 0 0 auto;\n box-sizing: border-box;\n width: 100%;\n padding-block: var(--dimension-space-050);\n}\n\n.panel-tools__accessory-divider ds-divider {\n display: block;\n}\n\n@media (prefers-reduced-motion: reduce) {\n :host(.panel-tools--ready.panel-tools--motion-opening) .panel-tools__drawer,\n :host(.panel-tools--ready.panel-tools--motion-closing) .panel-tools__drawer {\n transition: none;\n }\n}\n","import {\n Component,\n Prop,\n Event,\n EventEmitter,\n Element,\n State,\n Watch,\n Method,\n Listen,\n h,\n Host,\n} from '@stencil/core';\nimport type { ChromeTransitionDetail } from '../../shell/chrome-transition';\nimport {\n PANEL_TOOLS_LABELS,\n PANEL_TOOLS_SHORTCUTS,\n type PanelToolsHeaderAction,\n type PanelToolsHeaderActionDetail,\n type PanelToolsHeaderConfig,\n type PanelToolsHeaders,\n type PanelToolsItem,\n type PanelToolsRailAccessory,\n type PanelToolsRailAccessoryAction,\n type PanelToolsRailAccessoryActionDetail,\n type PanelToolsRailShortcutAccessory,\n type PanelToolsRailTransientAccessory,\n type PanelToolsToolId,\n} from './panel-tools-types';\nimport {\n isPanelToolsToolId,\n orderPanelToolsRailEntries,\n orderPanelToolsItems,\n panelToolsRailAccessoryActionDetail,\n panelToolsRailFocusKeys,\n panelToolsDrawerAtTerminal,\n panelToolsDrawerResting,\n panelToolsDrawerTransitionMs,\n panelToolsRailPlacement,\n reconcilePanelToolsAvailability,\n reconcilePanelToolsRovingIndex,\n resolvePanelToolActivation,\n type PanelToolsRailEntry,\n} from './panel-tools-utils';\n\n@Component({\n tag: 'ds-panel-tools',\n styleUrl: 'PanelTools.css',\n shadow: 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 /** Drawer presentation or viewport-covering presentation for the active tool. */\n @Prop({ mutable: true, reflect: true }) presentation: 'drawer' | 'fullscreen' = 'drawer';\n\n /** Let a fullscreen product supply independent master/detail headers inside its view. */\n @Prop({ attribute: 'fullscreen-header-mode', reflect: true })\n fullscreenHeaderMode: 'shared' | 'split' = 'shared';\n\n /** Active tool view — `search`, `agents`, `messages`, `stacks`, `activity`, or `help`. */\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 /**\n * Desktop/tablet-only application-owned rail boundaries and direct intents.\n * Set via JS property and replace the array reference to update.\n */\n @Prop() accessories: PanelToolsRailAccessory[] = [];\n\n @Prop() toolsLabel: string = 'Tools';\n @Prop() toolShortcutsLabel: string = 'Tool shortcuts';\n\n /** Active header state per tool. Replace the object when title, depth, or actions change. */\n @Prop() headers: PanelToolsHeaders = {};\n\n /**\n * Optional localStorage key for the last active tool. The drawer always starts\n * closed; only the tool identity is restored for continuity within this browser.\n */\n @Prop({ attribute: 'storage-key' }) storageKey: 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 /** Emitted when fullscreen changes, including Escape-initiated exits. */\n @Event({ bubbles: true, composed: true }) dsPresentationChange!: EventEmitter<{\n presentation: 'drawer' | 'fullscreen';\n }>;\n\n /** Requests navigation to the active tool's parent view. */\n @Event({ bubbles: true, composed: true }) dsHeaderBack!: EventEmitter<{\n tool: PanelToolsToolId;\n }>;\n\n /** Requests one application-owned action from the active tool header. */\n @Event({ bubbles: true, composed: true })\n dsHeaderAction!: EventEmitter<PanelToolsHeaderActionDetail>;\n\n /** Direct accessory intent. Emitting this event never changes the active tool or drawer. */\n @Event({ bubbles: true, composed: true })\n dsRailAccessoryAction!: EventEmitter<PanelToolsRailAccessoryActionDetail>;\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 /** Keeps header and slotted content painted until the closing clip transition completes. */\n @State() private drawerSurfaceRetained = false;\n\n /** Suppresses width transition until the host has painted its initial open state. */\n @State() private readyForMotion = false;\n\n /** Fullscreen presentation changes snap without borrowing drawer width motion. */\n @State() private presentationMotionSuppressed = false;\n\n @State() private rovingIndex = 0;\n @State() private fullViewToolIds: PanelToolsToolId[] = [];\n @State() private railBodyScrollable = false;\n\n private motionEnableGeneration = 0;\n private presentationMotionGeneration = 0;\n private transitionGeneration = 0;\n private transitionFallbackTimer: number | null = null;\n /** Ignores the old transition's terminal event when reversing direction. */\n private ignoreReplacementTerminal = false;\n private focusBeforeFullscreen: HTMLElement | null = null;\n private fullViewObserver: MutationObserver | null = null;\n private railBodyEl?: HTMLElement;\n private railBodyObserver?: ResizeObserver;\n\n private get railItems(): PanelToolsItem[] {\n return this.items ?? [];\n }\n\n private get orderedRailItems(): PanelToolsItem[] {\n return orderPanelToolsItems(this.railItems);\n }\n\n private get railAccessories(): PanelToolsRailAccessory[] {\n return this.accessories ?? [];\n }\n\n private get orderedRailEntries(): PanelToolsRailEntry[] {\n return orderPanelToolsRailEntries(this.railItems, this.railAccessories);\n }\n\n disconnectedCallback() {\n this.el.removeEventListener('transitionend', this.handleTransitionEnd);\n this.el.removeEventListener('transitioncancel', this.handleTransitionEnd);\n this.el.removeEventListener('dsAction', this.handleComposedHeaderAction);\n this.clearTransitionCompletion();\n this.motionEnableGeneration += 1;\n this.fullViewObserver?.disconnect();\n this.fullViewObserver = null;\n this.disconnectRailBodyObserver();\n }\n\n @Watch('presentation')\n presentationChanged(next: 'drawer' | 'fullscreen', previous?: 'drawer' | 'fullscreen') {\n if (next === previous) return;\n // Framework property bindings can update slotted master/detail content in\n // the same render that requests fullscreen. Reflect the host selector\n // immediately so that content cannot paint once in the drawer geometry\n // while Stencil waits to commit its next render.\n if (this.el.getAttribute('presentation') !== next) {\n this.el.setAttribute('presentation', next);\n }\n const presentationGeneration = ++this.presentationMotionGeneration;\n this.presentationMotionSuppressed = true;\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n if (presentationGeneration !== this.presentationMotionGeneration) return;\n this.presentationMotionSuppressed = false;\n });\n });\n if (next === 'fullscreen') {\n this.focusBeforeFullscreen =\n document.activeElement instanceof HTMLElement ? document.activeElement : null;\n this.open = true;\n } else if (previous === 'fullscreen') {\n const focusBeforeFullscreen = this.focusBeforeFullscreen;\n const fallbackActionId = this.activeHeader().actions?.[0]?.id;\n requestAnimationFrame(async () => {\n if (focusBeforeFullscreen?.isConnected) {\n focusBeforeFullscreen.focus({ preventScroll: true });\n }\n const focusRestored = focusBeforeFullscreen\n ? document.activeElement === focusBeforeFullscreen ||\n focusBeforeFullscreen.contains(document.activeElement)\n : false;\n if (!focusRestored && fallbackActionId) await this.focusHeaderAction(fallbackActionId);\n this.focusBeforeFullscreen = null;\n });\n }\n this.dsPresentationChange.emit({ presentation: next });\n }\n\n @Listen('keydown', { target: 'window', capture: true })\n handleFullscreenEscape(event: KeyboardEvent) {\n if (this.presentation !== 'fullscreen' || event.key !== 'Escape') return;\n event.preventDefault();\n event.stopPropagation();\n this.presentation = 'drawer';\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 this.el.addEventListener('transitioncancel', this.handleTransitionEnd);\n this.el.addEventListener('dsAction', this.handleComposedHeaderAction);\n }\n\n private handleComposedHeaderAction = (event: Event) => {\n const detail = (event as CustomEvent<{ id?: string; anchor?: HTMLElement }>).detail;\n if (!this.activeTool || !detail?.id) return;\n event.stopPropagation();\n this.dsHeaderAction.emit({\n tool: this.activeTool,\n id: detail.id,\n anchor: detail.anchor,\n });\n };\n\n componentWillLoad() {\n this.restoreLastActiveTool();\n this.drawerSurfaceRetained = this.open;\n }\n\n @Watch('open')\n openChanged(isOpen: boolean, wasOpen?: boolean) {\n if (isOpen) this.drawerSurfaceRetained = true;\n if (this.readyForMotion && wasOpen !== undefined && wasOpen !== isOpen) {\n this.startDrawerTransition(isOpen ? 'opening' : 'closing');\n } else if (!isOpen) {\n this.drawerSurfaceRetained = false;\n }\n this.deferMotionEnable();\n }\n\n @Watch('activeTool')\n activeToolChanged() {\n this.persistLastActiveTool();\n this.deferMotionEnable();\n }\n\n @Watch('storageKey')\n storageKeyChanged() {\n this.restoreLastActiveTool();\n }\n\n componentDidLoad() {\n this.deferMotionEnable();\n this.connectRailBodyObserver();\n this.updateRailBodyScrollable();\n this.syncFullViewTools();\n this.fullViewObserver = new MutationObserver(() => this.syncFullViewTools());\n this.fullViewObserver.observe(this.el, {\n childList: true,\n attributes: true,\n attributeFilter: ['slot'],\n });\n }\n\n componentDidRender() {\n this.updateRailBodyScrollable();\n }\n\n private connectRailBodyObserver() {\n this.disconnectRailBodyObserver();\n if (!this.railBodyEl || typeof ResizeObserver === 'undefined') return;\n this.railBodyObserver = new ResizeObserver(() => this.updateRailBodyScrollable());\n this.railBodyObserver.observe(this.railBodyEl);\n }\n\n private disconnectRailBodyObserver() {\n this.railBodyObserver?.disconnect();\n this.railBodyObserver = undefined;\n }\n\n private updateRailBodyScrollable() {\n const next = Boolean(\n this.railBodyEl && this.railBodyEl.scrollHeight > this.railBodyEl.clientHeight + 1\n );\n if (next !== this.railBodyScrollable) this.railBodyScrollable = next;\n }\n\n @Watch('items')\n itemsChanged() {\n this.rovingIndex = 0;\n this.reconcileActiveTool();\n this.deferMotionEnable();\n }\n\n @Watch('accessories')\n accessoriesChanged(\n next: PanelToolsRailAccessory[] = [],\n previous: PanelToolsRailAccessory[] = []\n ) {\n const previousKeys = panelToolsRailFocusKeys(\n orderPanelToolsRailEntries(this.railItems, previous)\n );\n const nextKeys = panelToolsRailFocusKeys(orderPanelToolsRailEntries(this.railItems, next));\n const activeElement = (this.renderRoot as ShadowRoot).activeElement as HTMLElement | null;\n const focusedKey =\n activeElement?.closest<HTMLElement>('[data-rail-focus-key]')?.dataset.railFocusKey;\n const focusedIndex = focusedKey ? previousKeys.indexOf(focusedKey) : -1;\n const currentIndex = focusedIndex >= 0 ? focusedIndex : this.rovingIndex;\n const nextIndex = reconcilePanelToolsRovingIndex(previousKeys, nextKeys, currentIndex);\n const restoreFocus = focusedIndex >= 0 && !nextKeys.includes(focusedKey ?? '');\n this.rovingIndex = nextIndex;\n if (restoreFocus && nextKeys.length) {\n requestAnimationFrame(() => this.focusRailAt(nextIndex));\n }\n }\n\n private restoreLastActiveTool() {\n if (!this.storageKey || this.activeTool) return;\n try {\n const stored = localStorage.getItem(this.storageKey);\n if (isPanelToolsToolId(stored)) this.activeTool = stored;\n } catch {\n /* localStorage unavailable */\n }\n }\n\n private persistLastActiveTool() {\n if (!this.storageKey || !this.activeTool) return;\n try {\n localStorage.setItem(this.storageKey, this.activeTool);\n } catch {\n /* unavailable */\n }\n }\n\n private clearPersistedTool() {\n if (!this.storageKey) return;\n try {\n localStorage.removeItem(this.storageKey);\n } catch {\n /* unavailable */\n }\n }\n\n private reconcileActiveTool() {\n const next = reconcilePanelToolsAvailability(this.railItems, this.open, this.activeTool);\n if (!next.removedTool) return;\n this.clearPersistedTool();\n this.open = next.open;\n this.activeTool = next.activeTool;\n this.dsToolChange.emit({ id: next.removedTool, selected: false });\n }\n\n private startDrawerTransition(phase: 'opening' | 'closing') {\n const drawer = this.renderRoot.querySelector('.panel-tools__drawer') as HTMLElement | null;\n if (this.motion !== 'idle') {\n this.finishDrawerTransition();\n this.ignoreReplacementTerminal = true;\n }\n this.motion = phase;\n this.dsChromeTransitionStart.emit({ source: 'panel-tools', phase });\n const generation = ++this.transitionGeneration;\n\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n if (generation !== this.transitionGeneration || this.motion !== phase) return;\n if (!drawer) {\n this.finishDrawerTransition();\n return;\n }\n\n if (this.drawerTransitionAtTerminal(drawer, phase)) {\n this.finishDrawerTransition();\n return;\n }\n\n const fallbackMs = panelToolsDrawerTransitionMs(getComputedStyle(drawer));\n if (fallbackMs <= 0) {\n this.finishDrawerTransition();\n return;\n }\n this.transitionFallbackTimer = window.setTimeout(() => {\n this.finishDrawerTransition();\n }, fallbackMs);\n });\n });\n }\n\n private handleTransitionEnd = (event: TransitionEvent) => {\n const drawer = this.renderRoot.querySelector('.panel-tools__drawer') as HTMLElement | null;\n if (event.target !== drawer) return;\n if (event.propertyName !== 'max-width') return;\n if (this.ignoreReplacementTerminal) {\n this.ignoreReplacementTerminal = false;\n return;\n }\n // Changing from the neutral transition recipe to the direction-specific\n // easing can cancel the transition that the reflected `open` class began.\n // The replacement transition and its watchdog still own completion; ending\n // motion here would hide the fixed-width tool surface while it is visible.\n if (event.type === 'transitioncancel') return;\n if (drawer && !this.drawerTransitionAtTerminal(drawer, this.motion)) return;\n this.finishDrawerTransition();\n };\n\n private drawerTransitionAtTerminal(\n drawer: HTMLElement,\n phase: 'opening' | 'closing' | 'idle'\n ): boolean {\n const width = drawer.getBoundingClientRect().width;\n const surface = drawer.querySelector('.panel-tools__drawer-surface') as HTMLElement | null;\n const targetWidth = surface?.getBoundingClientRect().width ?? 0;\n return panelToolsDrawerAtTerminal(width, targetWidth, phase);\n }\n\n private finishDrawerTransition() {\n const completedPhase = this.motion;\n const wasTransitioning = completedPhase !== 'idle';\n this.clearTransitionCompletion();\n if (!wasTransitioning) return;\n this.ignoreReplacementTerminal = false;\n this.motion = 'idle';\n if (completedPhase === 'closing' && !this.open) {\n this.drawerSurfaceRetained = false;\n }\n this.dsChromeTransitionEnd.emit({ source: 'panel-tools' });\n }\n\n private clearTransitionCompletion() {\n this.transitionGeneration += 1;\n if (this.transitionFallbackTimer !== null) {\n window.clearTimeout(this.transitionFallbackTimer);\n this.transitionFallbackTimer = null;\n }\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.drawerSurfaceRetained;\n }\n\n private isViewActive(id: PanelToolsToolId): boolean {\n return this.isDrawerPresent() && this.activeTool === id;\n }\n\n private hasFullView(id: PanelToolsToolId): boolean {\n return this.fullViewToolIds.includes(id);\n }\n\n private syncFullViewTools() {\n const ids = this.orderedRailItems.map(item => item.id);\n const next = ids.filter(id => Boolean(this.el.querySelector(`[slot=\"${id}-view\"]`)));\n if (next.join('|') !== this.fullViewToolIds.join('|')) this.fullViewToolIds = next;\n }\n\n private get renderRoot(): ParentNode {\n return this.el.shadowRoot ?? this.el;\n }\n\n private headerLabel(): string {\n if (!this.isDrawerPresent() || !this.activeTool) return '';\n const item = this.railItems.find(candidate => candidate.id === this.activeTool);\n return (\n item?.label ??\n PANEL_TOOLS_LABELS[this.activeTool as keyof typeof PANEL_TOOLS_LABELS] ??\n this.activeTool\n );\n }\n\n private resolvedHeaders(): PanelToolsHeaders {\n return this.headers ?? {};\n }\n\n private activeHeader(): PanelToolsHeaderConfig {\n if (!this.activeTool) return {};\n return this.resolvedHeaders()[this.activeTool] ?? {};\n }\n\n private handleToolChange = (id: PanelToolsToolId) => {\n const next = resolvePanelToolActivation(this.open, this.activeTool, id);\n this.open = next.open;\n this.activeTool = next.activeTool;\n this.dsToolChange.emit({ id, selected: next.selected });\n };\n\n /** Toggle any rail tool open/closed — shell shortcuts K/A/S/M/N call this. */\n @Method()\n async activateTool(id: PanelToolsToolId) {\n const item = this.railItems.find(entry => entry.id === id);\n if (!item || item.isInactive) return;\n this.handleToolChange(id);\n }\n\n /** Close the tools drawer when open — used by shell keyboard shortcuts. */\n @Method()\n async closeDrawer() {\n if (!this.open) return;\n const id = this.activeTool;\n this.open = false;\n if (id) {\n this.dsToolChange.emit({ id, selected: false });\n }\n }\n\n /** Focus an active tool-header action by its application-owned id. */\n @Method()\n async focusHeaderAction(id: string) {\n const action = this.renderRoot.querySelector(`[data-header-action-id=\"${CSS.escape(id)}\"]`) as\n | (HTMLElement & { setFocus?: () => Promise<void> })\n | null;\n await action?.setFocus?.();\n }\n\n private focusRailAt(index: number) {\n const keys = panelToolsRailFocusKeys(this.orderedRailEntries);\n if (!keys.length) return;\n const bounded = Math.max(0, Math.min(index, keys.length - 1));\n this.rovingIndex = bounded;\n const action = this.renderRoot.querySelector(\n `[data-rail-focus-key=\"${CSS.escape(keys[bounded])}\"]`\n ) as (HTMLElement & { setFocus?: () => Promise<void> }) | null;\n if (action?.setFocus) {\n void action.setFocus();\n } else {\n action?.focus({ preventScroll: true });\n }\n }\n\n private handleRailKeyDown = (e: KeyboardEvent, index: number, activate?: () => void) => {\n const keys = panelToolsRailFocusKeys(this.orderedRailEntries);\n if (!keys.length) return;\n\n if ((e.key === 'Enter' || e.key === ' ') && activate) {\n e.preventDefault();\n activate();\n return;\n }\n\n if (e.key === 'ArrowDown') {\n if (index >= keys.length - 1) return;\n e.preventDefault();\n this.focusRailAt(index + 1);\n return;\n }\n\n if (e.key === 'ArrowUp') {\n if (index <= 0) return;\n e.preventDefault();\n this.focusRailAt(index - 1);\n }\n };\n\n private renderRailAction(item: PanelToolsItem, index: number) {\n const focusKey = `tool:${item.id}`;\n const label =\n item.ariaLabel ??\n item.label ??\n PANEL_TOOLS_LABELS[item.id as keyof typeof PANEL_TOOLS_LABELS] ??\n item.id;\n return (\n <ds-tooltip\n key={item.id}\n label={label}\n shortcutKey={\n item.shortcutKey ?? PANEL_TOOLS_SHORTCUTS[item.id as keyof typeof PANEL_TOOLS_SHORTCUTS]\n }\n side=\"left\"\n size=\"sm\"\n boundary=\"viewport\"\n >\n <ds-button-unfilled\n variant=\"icon\"\n class=\"panel-tools__rail-action\"\n icon={item.icon}\n isActive={this.isRailSelected(item.id)}\n activeFill={false}\n hasBorder={false}\n pressScale={false}\n dot={item.dot ?? false}\n isInactive={item.isInactive}\n focusTabIndex={index === this.rovingIndex ? 0 : -1}\n data-rail-focus-key={focusKey}\n aria-label={label}\n pressed={this.isRailSelected(item.id)}\n onFocusin={() => {\n this.rovingIndex = index;\n }}\n onKeyDown={(e: KeyboardEvent) =>\n this.handleRailKeyDown(e, index, () => this.handleToolChange(item.id))\n }\n onDsClick={() => this.handleToolChange(item.id)}\n />\n </ds-tooltip>\n );\n }\n\n private accessoryPrimaryLabel(accessory: PanelToolsRailTransientAccessory): string {\n const actionLabel = accessory.primaryAction.ariaLabel?.trim() || accessory.ariaLabel;\n const status = accessory.statusText.trim();\n return status ? `${actionLabel}. ${status}` : actionLabel;\n }\n\n private emitAccessoryAction(\n accessoryId: string,\n action: PanelToolsRailAccessoryAction,\n anchor: HTMLElement\n ) {\n if (action.isInactive) return;\n this.dsRailAccessoryAction.emit(\n panelToolsRailAccessoryActionDetail(accessoryId, action.id, anchor)\n );\n }\n\n private renderAccessoryVisual(accessory: PanelToolsRailTransientAccessory) {\n if (accessory.visual.type === 'image') {\n return (\n <img\n class=\"panel-tools__accessory-image\"\n src={accessory.visual.src}\n alt=\"\"\n aria-hidden=\"true\"\n />\n );\n }\n if (accessory.visual.type === 'initial') {\n const initial = [...accessory.visual.initial.trim()].slice(0, 2).join('');\n return (\n <ds-text\n class=\"panel-tools__accessory-initial\"\n as=\"span\"\n variant=\"text-caption\"\n emphasis\n color=\"inherit\"\n aria-hidden=\"true\"\n >\n {initial}\n </ds-text>\n );\n }\n return <ds-icon name={accessory.visual.icon} size=\"sm\" aria-hidden=\"true\" />;\n }\n\n private renderRailShortcut(\n accessory: PanelToolsRailShortcutAccessory,\n focusIndexes: Map<string, number>\n ) {\n const focusKey = `accessory:${accessory.id}:${accessory.action.id}`;\n const focusIndex = focusIndexes.get(focusKey);\n const label = accessory.action.ariaLabel?.trim() || accessory.ariaLabel;\n const initials = [...accessory.initials.trim()].slice(0, 2).join('');\n\n return (\n <div\n key={`accessory:${accessory.id}`}\n class=\"panel-tools__accessory panel-tools__accessory--shortcut\"\n >\n <ds-tooltip label={label} side=\"left\" size=\"sm\" boundary=\"viewport\">\n <button\n type=\"button\"\n class=\"panel-tools__shortcut ds-focus-ring-inset ds-interaction-fill\"\n disabled={accessory.action.isInactive}\n tabIndex={focusIndex === this.rovingIndex ? 0 : -1}\n data-rail-focus-key={focusKey}\n aria-label={label}\n onFocus={() => {\n if (focusIndex !== undefined) this.rovingIndex = focusIndex;\n }}\n onKeyDown={(event: KeyboardEvent) =>\n focusIndex === undefined ? undefined : this.handleRailKeyDown(event, focusIndex)\n }\n onClick={(event: MouseEvent) =>\n this.emitAccessoryAction(\n accessory.id,\n accessory.action,\n event.currentTarget as HTMLElement\n )\n }\n >\n <span class=\"panel-tools__shortcut-content ds-interaction-fill__content\">\n <ds-text\n class=\"panel-tools__shortcut-orb\"\n as=\"span\"\n variant=\"text-caption\"\n emphasis\n color=\"inherit\"\n >\n {initials}\n </ds-text>\n {accessory.dot ? (\n <ds-badge\n class=\"panel-tools__shortcut-dot\"\n variant=\"dot\"\n background=\"var(--color-background-secondary)\"\n aria-hidden=\"true\"\n />\n ) : null}\n </span>\n </button>\n </ds-tooltip>\n </div>\n );\n }\n\n private renderRailAccessory(\n accessory: PanelToolsRailAccessory,\n focusIndexes: Map<string, number>\n ) {\n if (accessory.type === 'divider') {\n return (\n <div\n key={`accessory:${accessory.id}`}\n class=\"panel-tools__accessory-divider\"\n aria-hidden=\"true\"\n >\n <ds-divider />\n </div>\n );\n }\n\n if (accessory.type === 'shortcut') {\n return this.renderRailShortcut(accessory, focusIndexes);\n }\n\n const primaryKey = `accessory:${accessory.id}:${accessory.primaryAction.id}`;\n const primaryIndex = focusIndexes.get(primaryKey);\n const primaryLabel = this.accessoryPrimaryLabel(accessory);\n const secondary = accessory.secondaryAction;\n const secondaryKey = secondary ? `accessory:${accessory.id}:${secondary.id}` : '';\n const secondaryIndex = secondary ? focusIndexes.get(secondaryKey) : undefined;\n\n return (\n <div\n key={`accessory:${accessory.id}`}\n class={{\n 'panel-tools__accessory': true,\n 'panel-tools__accessory--transient': true,\n 'panel-tools__accessory--transient-active': accessory.statusTone === 'active',\n 'panel-tools__accessory--transient-positive': accessory.statusTone === 'positive',\n }}\n >\n <ds-tooltip label={primaryLabel} side=\"left\" size=\"sm\" boundary=\"viewport\">\n <button\n type=\"button\"\n class=\"panel-tools__accessory-primary ds-focus-ring-inset ds-interaction-fill ds-interaction-fill--on-bold\"\n disabled={accessory.primaryAction.isInactive}\n tabIndex={primaryIndex === this.rovingIndex ? 0 : -1}\n data-rail-focus-key={primaryKey}\n aria-label={primaryLabel}\n onFocus={() => {\n if (primaryIndex !== undefined) this.rovingIndex = primaryIndex;\n }}\n onKeyDown={(event: KeyboardEvent) =>\n primaryIndex === undefined ? undefined : this.handleRailKeyDown(event, primaryIndex)\n }\n onClick={(event: MouseEvent) =>\n this.emitAccessoryAction(\n accessory.id,\n accessory.primaryAction,\n event.currentTarget as HTMLElement\n )\n }\n >\n <span class=\"panel-tools__accessory-primary-content ds-interaction-fill__content\">\n {this.renderAccessoryVisual(accessory)}\n </span>\n </button>\n </ds-tooltip>\n {secondary ? (\n <ds-tooltip label={secondary.ariaLabel} side=\"left\" size=\"sm\" boundary=\"viewport\">\n <ds-button-unfilled\n class=\"panel-tools__accessory-secondary\"\n variant=\"icon\"\n size=\"sm\"\n rounded\n background=\"bold\"\n hasBorder={false}\n icon={secondary.icon}\n isInactive={secondary.isInactive}\n focusTabIndex={secondaryIndex === this.rovingIndex ? 0 : -1}\n data-rail-focus-key={secondaryKey}\n aria-label={secondary.ariaLabel}\n onFocusin={() => {\n if (secondaryIndex !== undefined) this.rovingIndex = secondaryIndex;\n }}\n onKeyDown={(event: KeyboardEvent) =>\n secondaryIndex === undefined\n ? undefined\n : this.handleRailKeyDown(event, secondaryIndex)\n }\n onDsClick={(event: CustomEvent<MouseEvent>) =>\n this.emitAccessoryAction(\n accessory.id,\n secondary,\n event.currentTarget as HTMLElement\n )\n }\n />\n </ds-tooltip>\n ) : null}\n </div>\n );\n }\n\n private renderRailEntry(entry: PanelToolsRailEntry, focusIndexes: Map<string, number>) {\n if (entry.type === 'tool') {\n return this.renderRailAction(entry.item, focusIndexes.get(`tool:${entry.id}`) ?? 0);\n }\n return this.renderRailAccessory(entry.accessory, focusIndexes);\n }\n\n render() {\n const headerLabel = this.headerLabel();\n const header = this.activeHeader();\n const headerTitle = header.title?.trim() || headerLabel;\n const headerActions = header.actions ?? [];\n const orderedRailItems = this.orderedRailItems;\n const orderedRailEntries = this.orderedRailEntries;\n const entryPlacement = (entry: PanelToolsRailEntry) =>\n entry.type === 'tool' ? panelToolsRailPlacement(entry.item) : entry.accessory.railPlacement;\n const headerEntries = orderedRailEntries.filter(entry => entryPlacement(entry) === 'header');\n const bodyEntries = orderedRailEntries.filter(entry => entryPlacement(entry) === 'body');\n const footerEntries = orderedRailEntries.filter(entry => entryPlacement(entry) === 'footer');\n const focusIndexes = new Map(\n panelToolsRailFocusKeys(orderedRailEntries).map((key, index) => [key, index])\n );\n const showDrawerChrome = this.isDrawerPresent();\n const drawerResting = panelToolsDrawerResting(this.open, this.motion);\n const activeFullView = Boolean(\n showDrawerChrome && this.activeTool && this.hasFullView(this.activeTool)\n );\n const toolIds = orderedRailItems.map(item => item.id);\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 'panel-tools--fullscreen': this.presentation === 'fullscreen',\n 'panel-tools--presentation-snap': this.presentationMotionSuppressed,\n }}\n role={this.presentation === 'fullscreen' ? 'dialog' : 'complementary'}\n aria-modal={this.presentation === 'fullscreen' ? 'true' : undefined}\n aria-label={this.toolsLabel}\n >\n <div class=\"panel-tools__layout\">\n <nav class=\"panel-tools__rail\" aria-label={this.toolShortcutsLabel}>\n {headerEntries.length ? (\n <div\n class={{\n 'panel-tools__rail-header': true,\n 'panel-tools__rail-section--stacked': headerEntries.length > 1,\n 'ds-chrome-row': headerEntries.length === 1,\n 'ds-chrome-column': headerEntries.length > 1,\n 'ds-chrome-space--md': true,\n }}\n >\n {headerEntries.map(entry => this.renderRailEntry(entry, focusIndexes))}\n </div>\n ) : null}\n <div\n class={{\n 'panel-tools__rail-body': true,\n 'ds-chrome-column': true,\n 'ds-chrome-space--md': true,\n 'ds-scrollbar-hidden': true,\n 'ds-focus-ring': this.railBodyScrollable,\n }}\n ref={element => {\n const next = (element as HTMLElement) ?? undefined;\n if (next === this.railBodyEl) return;\n this.railBodyEl = next;\n this.connectRailBodyObserver();\n }}\n role={this.railBodyScrollable ? 'region' : undefined}\n aria-label={this.railBodyScrollable ? this.toolShortcutsLabel : undefined}\n tabIndex={this.railBodyScrollable ? 0 : undefined}\n >\n <div class=\"panel-tools__rail-actions\">\n {bodyEntries.map(entry => this.renderRailEntry(entry, focusIndexes))}\n </div>\n </div>\n {footerEntries.length ? (\n <div\n class={{\n 'panel-tools__rail-footer': true,\n 'panel-tools__rail-section--stacked': footerEntries.length > 1,\n 'ds-chrome-row': footerEntries.length === 1,\n 'ds-chrome-column': footerEntries.length > 1,\n 'ds-chrome-space--md': true,\n }}\n >\n {footerEntries.map(entry => this.renderRailEntry(entry, focusIndexes))}\n </div>\n ) : null}\n </nav>\n\n <div\n class={{\n 'panel-tools__drawer': true,\n 'panel-tools__drawer--visible': showDrawerChrome,\n }}\n aria-hidden={showDrawerChrome ? null : 'true'}\n inert={showDrawerChrome ? undefined : true}\n >\n <div class=\"panel-tools__drawer-surface\">\n {this.presentation !== 'fullscreen' || this.fullscreenHeaderMode === 'shared' ? (\n <ds-panel-tool-header\n class=\"panel-tools__header\"\n heading={headerTitle}\n showBack={header.showBack ?? false}\n backIcon={header.backIcon || 'ChevronLeft'}\n backAriaLabel={header.backAriaLabel || 'Back'}\n showMenu={false}\n ref={element => {\n const toolHeader = element as\n | (HTMLDsPanelToolHeaderElement & {\n actions: PanelToolsHeaderAction[];\n })\n | undefined;\n if (toolHeader) toolHeader.actions = headerActions;\n }}\n onDsBack={() => {\n if (this.activeTool) this.dsHeaderBack.emit({ tool: this.activeTool });\n }}\n />\n ) : null}\n <div class=\"panel-tools__body\" hidden={activeFullView}>\n {toolIds.map(id => {\n const active = this.isViewActive(id);\n return (\n <div\n class={{\n 'panel-tools__view': true,\n 'panel-tools__view--active': active,\n }}\n hidden={!active}\n >\n <slot name={id} />\n </div>\n );\n })}\n </div>\n <div class=\"panel-tools__full-views\" hidden={!activeFullView}>\n {toolIds.map(id => (\n <div\n class={{\n 'panel-tools__full-view': true,\n 'panel-tools__full-view--active':\n this.isViewActive(id) && this.hasFullView(id),\n }}\n hidden={!(this.isViewActive(id) && this.hasFullView(id))}\n >\n <slot name={`${id}-view`} />\n </div>\n ))}\n </div>\n </div>\n </div>\n </div>\n </Host>\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1,5 +1,5 @@
1
1
  {
2
- "timestamp": "2026-08-30T01:47:17",
2
+ "timestamp": "2026-08-31T23:08:34",
3
3
  "compiler": {
4
4
  "name": "@stencil/core",
5
5
  "version": "4.43.5",
@@ -2041,6 +2041,7 @@
2041
2041
  "ds-mobile-bar-nav",
2042
2042
  "ds-mobile-sheet-nav",
2043
2043
  "ds-panel-nav",
2044
+ "ds-panel-tools",
2044
2045
  "ds-select",
2045
2046
  "ds-tab-group"
2046
2047
  ],
@@ -2078,6 +2079,9 @@
2078
2079
  "ds-panel-nav": [
2079
2080
  "ds-badge"
2080
2081
  ],
2082
+ "ds-panel-tools": [
2083
+ "ds-badge"
2084
+ ],
2081
2085
  "ds-select": [
2082
2086
  "ds-badge"
2083
2087
  ],
@@ -9251,6 +9255,7 @@
9251
9255
  "dependents": [
9252
9256
  "ds-pagination",
9253
9257
  "ds-panel-tool-search",
9258
+ "ds-panel-tools",
9254
9259
  "ds-table",
9255
9260
  "ds-table-search",
9256
9261
  "ds-table-toolbar"
@@ -9263,6 +9268,9 @@
9263
9268
  "ds-panel-tool-search": [
9264
9269
  "ds-divider"
9265
9270
  ],
9271
+ "ds-panel-tools": [
9272
+ "ds-divider"
9273
+ ],
9266
9274
  "ds-table": [
9267
9275
  "ds-divider"
9268
9276
  ],
@@ -11095,6 +11103,7 @@
11095
11103
  "ds-mobile-bar-nav",
11096
11104
  "ds-mobile-sheet-nav",
11097
11105
  "ds-panel-nav",
11106
+ "ds-panel-tools",
11098
11107
  "ds-select",
11099
11108
  "ds-tab-group",
11100
11109
  "ds-table",
@@ -11157,6 +11166,9 @@
11157
11166
  "ds-panel-nav": [
11158
11167
  "ds-icon"
11159
11168
  ],
11169
+ "ds-panel-tools": [
11170
+ "ds-icon"
11171
+ ],
11160
11172
  "ds-select": [
11161
11173
  "ds-icon"
11162
11174
  ],
@@ -19319,6 +19331,41 @@
19319
19331
  "docsTags": [],
19320
19332
  "usage": {},
19321
19333
  "props": [
19334
+ {
19335
+ "name": "accessories",
19336
+ "type": "PanelToolsRailAccessory[]",
19337
+ "complexType": {
19338
+ "original": "PanelToolsRailAccessory[]",
19339
+ "resolved": "PanelToolsRailAccessory[]",
19340
+ "references": {
19341
+ "PanelToolsRailAccessory": {
19342
+ "location": "import",
19343
+ "path": "./panel-tools-types",
19344
+ "id": "src/wc/components/PanelTools/panel-tools-types.ts::PanelToolsRailAccessory",
19345
+ "referenceLocation": "PanelToolsRailAccessory"
19346
+ }
19347
+ }
19348
+ },
19349
+ "mutable": false,
19350
+ "reflectToAttr": false,
19351
+ "docs": "Desktop/tablet-only application-owned rail boundaries and direct intents.\nSet via JS property and replace the array reference to update.",
19352
+ "docsTags": [
19353
+ {
19354
+ "name": "default",
19355
+ "text": "[]"
19356
+ }
19357
+ ],
19358
+ "default": "[]",
19359
+ "values": [
19360
+ {
19361
+ "type": "PanelToolsRailAccessory[]"
19362
+ }
19363
+ ],
19364
+ "optional": false,
19365
+ "required": false,
19366
+ "getter": false,
19367
+ "setter": false
19368
+ },
19322
19369
  {
19323
19370
  "name": "activeTool",
19324
19371
  "type": "string",
@@ -19814,6 +19861,27 @@
19814
19861
  "docs": "Emitted when fullscreen changes, including Escape-initiated exits.",
19815
19862
  "docsTags": []
19816
19863
  },
19864
+ {
19865
+ "event": "dsRailAccessoryAction",
19866
+ "detail": "PanelToolsRailAccessoryActionDetail",
19867
+ "bubbles": true,
19868
+ "complexType": {
19869
+ "original": "PanelToolsRailAccessoryActionDetail",
19870
+ "resolved": "PanelToolsRailAccessoryActionDetail",
19871
+ "references": {
19872
+ "PanelToolsRailAccessoryActionDetail": {
19873
+ "location": "import",
19874
+ "path": "./panel-tools-types",
19875
+ "id": "src/wc/components/PanelTools/panel-tools-types.ts::PanelToolsRailAccessoryActionDetail",
19876
+ "referenceLocation": "PanelToolsRailAccessoryActionDetail"
19877
+ }
19878
+ }
19879
+ },
19880
+ "cancelable": true,
19881
+ "composed": true,
19882
+ "docs": "Direct accessory intent. Emitting this event never changes the active tool or drawer.",
19883
+ "docsTags": []
19884
+ },
19817
19885
  {
19818
19886
  "event": "dsToolChange",
19819
19887
  "detail": "{ id: string; selected: boolean; }",
@@ -19854,12 +19922,20 @@
19854
19922
  "dependencies": [
19855
19923
  "ds-tooltip",
19856
19924
  "ds-button-unfilled",
19925
+ "ds-text",
19926
+ "ds-icon",
19927
+ "ds-badge",
19928
+ "ds-divider",
19857
19929
  "ds-panel-tool-header"
19858
19930
  ],
19859
19931
  "dependencyGraph": {
19860
19932
  "ds-panel-tools": [
19861
19933
  "ds-tooltip",
19862
19934
  "ds-button-unfilled",
19935
+ "ds-text",
19936
+ "ds-icon",
19937
+ "ds-badge",
19938
+ "ds-divider",
19863
19939
  "ds-panel-tool-header"
19864
19940
  ],
19865
19941
  "ds-tooltip": [
@@ -22691,6 +22767,27 @@
22691
22767
  "docs": "Managed drawer/fullscreen presentation state.",
22692
22768
  "docsTags": []
22693
22769
  },
22770
+ {
22771
+ "event": "dsRailAccessoryAction",
22772
+ "detail": "PanelToolsRailAccessoryActionDetail",
22773
+ "bubbles": true,
22774
+ "complexType": {
22775
+ "original": "PanelToolsRailAccessoryActionDetail",
22776
+ "resolved": "PanelToolsRailAccessoryActionDetail",
22777
+ "references": {
22778
+ "PanelToolsRailAccessoryActionDetail": {
22779
+ "location": "import",
22780
+ "path": "../PanelTools/panel-tools-types",
22781
+ "id": "src/wc/components/PanelTools/panel-tools-types.ts::PanelToolsRailAccessoryActionDetail",
22782
+ "referenceLocation": "PanelToolsRailAccessoryActionDetail"
22783
+ }
22784
+ }
22785
+ },
22786
+ "cancelable": true,
22787
+ "composed": true,
22788
+ "docs": "Managed desktop/tablet rail accessory intent.",
22789
+ "docsTags": []
22790
+ },
22694
22791
  {
22695
22792
  "event": "dsResponsiveModeChange",
22696
22793
  "detail": "{ mode: ShellResponsiveMode; }",
@@ -22855,6 +22952,10 @@
22855
22952
  "ds-panel-tools": [
22856
22953
  "ds-tooltip",
22857
22954
  "ds-button-unfilled",
22955
+ "ds-text",
22956
+ "ds-icon",
22957
+ "ds-badge",
22958
+ "ds-divider",
22858
22959
  "ds-panel-tool-header"
22859
22960
  ],
22860
22961
  "ds-panel-tool-header": [
@@ -23323,6 +23424,41 @@
23323
23424
  "docsTags": [],
23324
23425
  "usage": {},
23325
23426
  "props": [
23427
+ {
23428
+ "name": "accessories",
23429
+ "type": "PanelToolsRailAccessory[]",
23430
+ "complexType": {
23431
+ "original": "PanelToolsRailAccessory[]",
23432
+ "resolved": "PanelToolsRailAccessory[]",
23433
+ "references": {
23434
+ "PanelToolsRailAccessory": {
23435
+ "location": "import",
23436
+ "path": "../PanelTools/panel-tools-types",
23437
+ "id": "src/wc/components/PanelTools/panel-tools-types.ts::PanelToolsRailAccessory",
23438
+ "referenceLocation": "PanelToolsRailAccessory"
23439
+ }
23440
+ }
23441
+ },
23442
+ "mutable": false,
23443
+ "reflectToAttr": false,
23444
+ "docs": "Desktop/tablet rail accessories. Intentionally omitted from the mobile tool stage.",
23445
+ "docsTags": [
23446
+ {
23447
+ "name": "default",
23448
+ "text": "[]"
23449
+ }
23450
+ ],
23451
+ "default": "[]",
23452
+ "values": [
23453
+ {
23454
+ "type": "PanelToolsRailAccessory[]"
23455
+ }
23456
+ ],
23457
+ "optional": false,
23458
+ "required": false,
23459
+ "getter": false,
23460
+ "setter": false
23461
+ },
23326
23462
  {
23327
23463
  "name": "activeTool",
23328
23464
  "type": "string",
@@ -23879,6 +24015,27 @@
23879
24015
  "docs": "",
23880
24016
  "docsTags": []
23881
24017
  },
24018
+ {
24019
+ "event": "dsRailAccessoryAction",
24020
+ "detail": "PanelToolsRailAccessoryActionDetail",
24021
+ "bubbles": true,
24022
+ "complexType": {
24023
+ "original": "PanelToolsRailAccessoryActionDetail",
24024
+ "resolved": "PanelToolsRailAccessoryActionDetail",
24025
+ "references": {
24026
+ "PanelToolsRailAccessoryActionDetail": {
24027
+ "location": "import",
24028
+ "path": "../PanelTools/panel-tools-types",
24029
+ "id": "src/wc/components/PanelTools/panel-tools-types.ts::PanelToolsRailAccessoryActionDetail",
24030
+ "referenceLocation": "PanelToolsRailAccessoryActionDetail"
24031
+ }
24032
+ }
24033
+ },
24034
+ "cancelable": true,
24035
+ "composed": true,
24036
+ "docs": "",
24037
+ "docsTags": []
24038
+ },
23882
24039
  {
23883
24040
  "event": "dsToolChange",
23884
24041
  "detail": "{ id: string; selected: boolean; }",
@@ -23925,6 +24082,10 @@
23925
24082
  "ds-panel-tools": [
23926
24083
  "ds-tooltip",
23927
24084
  "ds-button-unfilled",
24085
+ "ds-text",
24086
+ "ds-icon",
24087
+ "ds-badge",
24088
+ "ds-divider",
23928
24089
  "ds-panel-tool-header"
23929
24090
  ],
23930
24091
  "ds-tooltip": [
@@ -31531,6 +31692,7 @@
31531
31692
  "ds-panel-sub-nav",
31532
31693
  "ds-panel-tool-header",
31533
31694
  "ds-panel-tool-search",
31695
+ "ds-panel-tools",
31534
31696
  "ds-radio",
31535
31697
  "ds-select",
31536
31698
  "ds-slider",
@@ -31663,6 +31825,9 @@
31663
31825
  "ds-panel-tool-search": [
31664
31826
  "ds-text"
31665
31827
  ],
31828
+ "ds-panel-tools": [
31829
+ "ds-text"
31830
+ ],
31666
31831
  "ds-radio": [
31667
31832
  "ds-text"
31668
31833
  ],
@@ -33753,7 +33918,12 @@
33753
33918
  "path": "src/wc/components/PanelTools/panel-tools-types.ts"
33754
33919
  },
33755
33920
  "src/wc/components/PanelTools/panel-tools-types.ts::PanelToolsItem": {
33756
- "declaration": "export interface PanelToolsItem {\n id: PanelToolsToolId;\n /** Icon name for <ds-icon>. */\n icon: string;\n /** Visible and accessible fallback label for custom tool ids. */\n label?: string;\n /** Explicit rail region; canonical Agents/Help placement is the fallback. */\n railPlacement?: 'header' | 'body' | 'footer';\n /** Stable ordering within the selected rail region. */\n order?: number;\n /** Optional shortcut label displayed by the tooltip. */\n shortcutKey?: string;\n /** Mobile destination recipe; canonical ids retain their explicit defaults. */\n mobileDestination?: 'search' | 'inbox' | 'activity' | 'messages' | 'agents' | 'help';\n /** Whether this rail button is currently pressed/active. */\n selected?: boolean;\n /** Show a notification dot. */\n dot?: boolean;\n isInactive?: boolean;\n ariaLabel?: string;\n}",
33921
+ "declaration": "export interface PanelToolsItem {\n id: PanelToolsToolId;\n /** Icon name for <ds-icon>. */\n icon: string;\n /** Visible and accessible fallback label for custom tool ids. */\n label?: string;\n /** Explicit rail region; canonical Agents/Help placement is the fallback. */\n railPlacement?: PanelToolsRailPlacement;\n /** Stable ordering within the selected rail region. */\n order?: number;\n /** Optional shortcut label displayed by the tooltip. */\n shortcutKey?: string;\n /** Mobile destination recipe; canonical ids retain their explicit defaults. */\n mobileDestination?: 'search' | 'inbox' | 'activity' | 'messages' | 'agents' | 'help';\n /** Whether this rail button is currently pressed/active. */\n selected?: boolean;\n /** Show a notification dot. */\n dot?: boolean;\n isInactive?: boolean;\n ariaLabel?: string;\n}",
33922
+ "docstring": "",
33923
+ "path": "src/wc/components/PanelTools/panel-tools-types.ts"
33924
+ },
33925
+ "src/wc/components/PanelTools/panel-tools-types.ts::PanelToolsRailAccessory": {
33926
+ "declaration": "export type PanelToolsRailAccessory =\n | PanelToolsRailDividerAccessory\n | PanelToolsRailShortcutAccessory\n | PanelToolsRailTransientAccessory;",
33757
33927
  "docstring": "",
33758
33928
  "path": "src/wc/components/PanelTools/panel-tools-types.ts"
33759
33929
  },
@@ -33767,6 +33937,11 @@
33767
33937
  "docstring": "",
33768
33938
  "path": "src/wc/components/PanelTools/panel-tools-types.ts"
33769
33939
  },
33940
+ "src/wc/components/PanelTools/panel-tools-types.ts::PanelToolsRailAccessoryActionDetail": {
33941
+ "declaration": "export interface PanelToolsRailAccessoryActionDetail {\n accessoryId: string;\n actionId: string;\n /** Rendered action control, suitable for anchoring an application-owned overlay. */\n anchor: HTMLElement;\n}",
33942
+ "docstring": "",
33943
+ "path": "src/wc/components/PanelTools/panel-tools-types.ts"
33944
+ },
33770
33945
  "src/wc/components/PaperTexture/paper-texture-types.ts::PaperTextureConfig": {
33771
33946
  "declaration": "export interface PaperTextureConfig {\n image?: HTMLImageElement | string;\n colorFront?: string;\n colorBack?: string;\n contrast?: number;\n roughness?: number;\n fiber?: number;\n fiberSize?: number;\n crumples?: number;\n crumpleSize?: number;\n folds?: number;\n foldCount?: number;\n fade?: number;\n drops?: number;\n seed?: number;\n fit?: PaperTextureFit;\n scale?: number;\n rotation?: number;\n originX?: number;\n originY?: number;\n offsetX?: number;\n offsetY?: number;\n worldWidth?: number;\n worldHeight?: number;\n speed?: number;\n frame?: number;\n minPixelRatio?: number;\n maxPixelCount?: number;\n /** CSS opacity applied after the shader has rendered. */\n opacity?: number;\n}",
33772
33947
  "docstring": "Literal parameters forwarded to Paper Design's paper texture shader.\nColors intentionally remain ordinary CSS color strings; they are not token\nreferences and are parsed once into shader RGBA uniforms.",
@@ -33793,7 +33968,7 @@
33793
33968
  "path": "src/wc/components/ShellApp/shell-app-types.ts"
33794
33969
  },
33795
33970
  "src/wc/components/ShellApp/shell-app-types.ts::ShellToolsConfig": {
33796
- "declaration": "export interface ShellToolsConfig {\n items?: PanelToolsItem[];\n headers?: PanelToolsHeaders;\n storageKey?: string;\n fullscreenHeaderMode?: 'shared' | 'split';\n toolsLabel?: string;\n toolShortcutsLabel?: string;\n inboxLabel?: string;\n inboxNavigationLabel?: string;\n /** Temporarily conceal the mobile bar while a tool-owned keyboard interaction needs the space. */\n mobileBarHidden?: boolean;\n}",
33971
+ "declaration": "export interface ShellToolsConfig {\n items?: PanelToolsItem[];\n /** Desktop/tablet-only direct rail intents and decorative group boundaries. */\n accessories?: PanelToolsRailAccessory[];\n headers?: PanelToolsHeaders;\n storageKey?: string;\n fullscreenHeaderMode?: 'shared' | 'split';\n toolsLabel?: string;\n toolShortcutsLabel?: string;\n inboxLabel?: string;\n inboxNavigationLabel?: string;\n /** Temporarily conceal the mobile bar while a tool-owned keyboard interaction needs the space. */\n mobileBarHidden?: boolean;\n}",
33797
33972
  "docstring": "Product-owned global tools supplied to managed ShellApp. Tool view content\nremains mounted in the corresponding named `*-view` slots.",
33798
33973
  "path": "src/wc/components/ShellApp/shell-app-types.ts"
33799
33974
  },
@@ -9,6 +9,7 @@ export declare const PANEL_TOOLS_PRIMARY_TOOL_ID: CanonicalPanelToolsToolId;
9
9
  export declare const PANEL_TOOLS_FOOTER_TOOL_ID: CanonicalPanelToolsToolId;
10
10
  export declare const PANEL_TOOLS_LABELS: Record<CanonicalPanelToolsToolId, string>;
11
11
  export declare const PANEL_TOOLS_SHORTCUTS: Partial<Record<CanonicalPanelToolsToolId, string>>;
12
+ export type PanelToolsRailPlacement = 'header' | 'body' | 'footer';
12
13
  export interface PanelToolsItem {
13
14
  id: PanelToolsToolId;
14
15
  /** Icon name for <ds-icon>. */
@@ -16,7 +17,7 @@ export interface PanelToolsItem {
16
17
  /** Visible and accessible fallback label for custom tool ids. */
17
18
  label?: string;
18
19
  /** Explicit rail region; canonical Agents/Help placement is the fallback. */
19
- railPlacement?: 'header' | 'body' | 'footer';
20
+ railPlacement?: PanelToolsRailPlacement;
20
21
  /** Stable ordering within the selected rail region. */
21
22
  order?: number;
22
23
  /** Optional shortcut label displayed by the tooltip. */
@@ -30,6 +31,79 @@ export interface PanelToolsItem {
30
31
  isInactive?: boolean;
31
32
  ariaLabel?: string;
32
33
  }
34
+ export type PanelToolsRailAccessoryVisual = {
35
+ type: 'icon';
36
+ icon: string;
37
+ } | {
38
+ type: 'initial';
39
+ initial: string;
40
+ } | {
41
+ type: 'image';
42
+ src: string;
43
+ };
44
+ export interface PanelToolsRailAccessoryAction {
45
+ /** Stable application-owned action id emitted with the accessory id. */
46
+ id: string;
47
+ /** Overrides the accessory label for the primary action. */
48
+ ariaLabel?: string;
49
+ isInactive?: boolean;
50
+ }
51
+ export interface PanelToolsRailAccessorySecondaryAction {
52
+ id: string;
53
+ icon: string;
54
+ ariaLabel: string;
55
+ isInactive?: boolean;
56
+ }
57
+ export type PanelToolsRailTransientTone = 'active' | 'positive';
58
+ interface PanelToolsRailAccessoryBase {
59
+ /** Stable application-owned identity. Duplicate or blank ids are omitted. */
60
+ id: string;
61
+ /** Explicit rail region; accessories never infer placement from their id. */
62
+ railPlacement: PanelToolsRailPlacement;
63
+ /** Stable ordering within the selected rail region. */
64
+ order: number;
65
+ }
66
+ /** Decorative boundary between application-owned rail accessory groups. */
67
+ export interface PanelToolsRailDividerAccessory extends PanelToolsRailAccessoryBase {
68
+ type: 'divider';
69
+ }
70
+ /**
71
+ * A compact one-action shortcut that matches standard tool-button geometry.
72
+ * PanelTools owns its initial orb, notification dot, and transient interaction paint.
73
+ */
74
+ export interface PanelToolsRailShortcutAccessory extends PanelToolsRailAccessoryBase {
75
+ type: 'shortcut';
76
+ /** Accessible shortcut name and action-label fallback. */
77
+ ariaLabel: string;
78
+ /** One or two displayed graphemes. Longer values are truncated visually. */
79
+ initials: string;
80
+ /** Supplemental notification dot. Include its meaning in the accessible label when needed. */
81
+ dot?: boolean;
82
+ action: PanelToolsRailAccessoryAction;
83
+ }
84
+ /**
85
+ * A direct application intent that never selects a tool or changes drawer state.
86
+ * PanelTools owns the two-control-height surface and its focus behavior.
87
+ */
88
+ export interface PanelToolsRailTransientAccessory extends PanelToolsRailAccessoryBase {
89
+ type: 'transient';
90
+ /** Accessible accessory name and primary-action fallback label. */
91
+ ariaLabel: string;
92
+ visual: PanelToolsRailAccessoryVisual;
93
+ /** State announced with the primary action and shown in its tooltip. */
94
+ statusText: string;
95
+ /** Bold surface treatment. Active uses brand; positive uses positive semantic color. */
96
+ statusTone: PanelToolsRailTransientTone;
97
+ primaryAction: PanelToolsRailAccessoryAction;
98
+ secondaryAction?: PanelToolsRailAccessorySecondaryAction;
99
+ }
100
+ export type PanelToolsRailAccessory = PanelToolsRailDividerAccessory | PanelToolsRailShortcutAccessory | PanelToolsRailTransientAccessory;
101
+ export interface PanelToolsRailAccessoryActionDetail {
102
+ accessoryId: string;
103
+ actionId: string;
104
+ /** Rendered action control, suitable for anchoring an application-owned overlay. */
105
+ anchor: HTMLElement;
106
+ }
33
107
  /** Canonical shell recipe used by Lab and by managed ShellApp examples. */
34
108
  export declare const PANEL_TOOLS_DEFAULT_ITEMS: PanelToolsItem[];
35
109
  export interface PanelToolsHeaderAction {
@@ -64,3 +138,4 @@ export interface PanelToolsHeaderConfig {
64
138
  }
65
139
  /** Per-tool header state. The application replaces the object when a tool changes depth or actions. */
66
140
  export type PanelToolsHeaders = Partial<Record<PanelToolsToolId, PanelToolsHeaderConfig>>;
141
+ export {};