@ds-mo/ui 12.2.0 → 12.4.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/README.md +8 -2
- package/dist/.build-stamp +1 -1
- package/dist/agent-patterns.json +94 -16
- package/dist/agent.json +1092 -53
- package/dist/angular/ds-bar-title.d.ts +7 -1
- package/dist/angular/ds-bar-title.js +7 -4
- package/dist/angular/ds-breadcrumb.d.ts +19 -0
- package/dist/angular/ds-breadcrumb.js +42 -0
- package/dist/angular/ds-card-data-viz-bar.d.ts +18 -0
- package/dist/angular/ds-card-data-viz-bar.js +42 -0
- package/dist/angular/ds-card-data-viz-line.d.ts +18 -0
- package/dist/angular/ds-card-data-viz-line.js +42 -0
- package/dist/angular/ds-chart-bar-stacked.d.ts +12 -0
- package/dist/angular/ds-chart-bar-stacked.js +38 -0
- package/dist/angular/ds-chart-legend.d.ts +1 -1
- package/dist/angular/ds-chart-legend.js +3 -3
- package/dist/angular/ds-shell-app.d.ts +13 -2
- package/dist/angular/ds-shell-app.js +9 -5
- package/dist/angular/ds-shell-mobile-bar.d.ts +18 -0
- package/dist/angular/ds-shell-mobile-bar.js +46 -0
- package/dist/angular/ds-shell-mobile-nav.d.ts +23 -0
- package/dist/angular/ds-shell-mobile-nav.js +51 -0
- package/dist/angular/ds-shell-mobile-section-nav.d.ts +18 -0
- package/dist/angular/ds-shell-mobile-section-nav.js +42 -0
- package/dist/angular/ds-shell-page.d.ts +1 -1
- package/dist/angular/ds-shell-page.js +3 -3
- package/dist/angular/ds-shell-tools.d.ts +42 -0
- package/dist/angular/ds-shell-tools.js +52 -0
- package/dist/angular/index.d.ts +1 -1
- package/dist/angular/index.js +8 -0
- package/dist/angular/proxies.d.ts +8 -0
- package/dist/angular/proxies.js +8 -0
- package/dist/components/ds-agent-activity.js +1 -1
- package/dist/components/ds-agent-response.js +1 -1
- package/dist/components/ds-agent-source-list.js +1 -1
- package/dist/components/ds-agent-tool-call.js +1 -1
- package/dist/components/ds-attachment-list.js +1 -1
- package/dist/components/ds-badge.js +1 -1
- package/dist/components/ds-bar-nav.js +1 -1
- package/dist/components/ds-bar-title.js +1 -1
- package/dist/components/ds-bar-title.js.map +1 -1
- package/dist/components/ds-bar-workflow.js +1 -1
- package/dist/components/ds-breadcrumb.d.ts +11 -0
- package/dist/components/ds-breadcrumb.js +2 -0
- package/dist/components/ds-breadcrumb.js.map +1 -0
- package/dist/components/ds-button-filled.js +1 -1
- package/dist/components/ds-button-unfilled.js +1 -1
- package/dist/components/ds-card-data-viz-bar.d.ts +11 -0
- package/dist/components/ds-card-data-viz-bar.js +2 -0
- package/dist/components/ds-card-data-viz-bar.js.map +1 -0
- package/dist/components/ds-card-data-viz-donut.js +1 -1
- package/dist/components/ds-card-data-viz-donut.js.map +1 -1
- package/dist/components/ds-card-data-viz-line.d.ts +11 -0
- package/dist/components/ds-card-data-viz-line.js +2 -0
- package/dist/components/ds-card-data-viz-line.js.map +1 -0
- package/dist/components/ds-card-setting.js +1 -1
- package/dist/components/ds-card-setting.js.map +1 -1
- package/dist/components/ds-card-shell-data-viz.js +1 -1
- package/dist/components/ds-chart-bar-stacked.d.ts +11 -0
- package/dist/components/ds-chart-bar-stacked.js +2 -0
- package/dist/components/ds-chart-bar-stacked.js.map +1 -0
- package/dist/components/ds-chart-bar.js +1 -1
- package/dist/components/ds-chart-bar.js.map +1 -1
- package/dist/components/ds-chart-donut.js +1 -1
- package/dist/components/ds-chart-legend.js +1 -1
- package/dist/components/ds-chart-legend.js.map +1 -1
- package/dist/components/ds-chart-line.js +1 -1
- package/dist/components/ds-chart-line.js.map +1 -1
- package/dist/components/ds-checkbox.js +1 -1
- package/dist/components/ds-chip.js +1 -1
- package/dist/components/ds-code-block.js +1 -1
- package/dist/components/ds-conversation-list-item.js +1 -1
- package/dist/components/ds-conversation-list-item.js.map +1 -1
- package/dist/components/ds-conversation-list-section.js +1 -1
- package/dist/components/ds-conversation-list.js +1 -1
- package/dist/components/ds-divider.js +1 -1
- package/dist/components/ds-empty-state.js +1 -1
- package/dist/components/ds-field.js +1 -1
- package/dist/components/ds-input.js +1 -1
- package/dist/components/ds-markdown.js +1 -1
- package/dist/components/ds-menu.js +1 -1
- package/dist/components/ds-message-bubble.js +1 -1
- package/dist/components/ds-message-bubble.js.map +1 -1
- package/dist/components/ds-message-composer.js +1 -1
- package/dist/components/ds-message-scroller.js +1 -1
- package/dist/components/ds-message-scroller.js.map +1 -1
- package/dist/components/ds-message.js +1 -1
- package/dist/components/ds-modal.js +1 -1
- package/dist/components/ds-modal.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-sub-nav.js +1 -1
- package/dist/components/ds-panel-tool-header.js +1 -1
- package/dist/components/ds-panel-tool-search.js +1 -1
- package/dist/components/ds-panel-tools.js +1 -1
- package/dist/components/ds-panel-tools.js.map +1 -1
- package/dist/components/ds-radio.js +1 -1
- package/dist/components/ds-scroll-overlay.js +1 -1
- package/dist/components/ds-scroll-overlay.js.map +1 -1
- package/dist/components/ds-select-multi.js +1 -1
- package/dist/components/ds-select-multi.js.map +1 -1
- package/dist/components/ds-select.js +1 -1
- package/dist/components/ds-select.js.map +1 -1
- package/dist/components/ds-shell-app.js +1 -1
- package/dist/components/ds-shell-app.js.map +1 -1
- package/dist/components/ds-shell-gradient-picker.js +1 -1
- package/dist/components/ds-shell-gradient-picker.js.map +1 -1
- package/dist/components/ds-shell-gradient-swatch.js +1 -1
- package/dist/components/ds-shell-mobile-bar.d.ts +11 -0
- package/dist/components/ds-shell-mobile-bar.js +2 -0
- package/dist/components/ds-shell-mobile-bar.js.map +1 -0
- package/dist/components/ds-shell-mobile-nav.d.ts +11 -0
- package/dist/components/ds-shell-mobile-nav.js +2 -0
- package/dist/components/ds-shell-mobile-nav.js.map +1 -0
- package/dist/components/ds-shell-mobile-section-nav.d.ts +11 -0
- package/dist/components/ds-shell-mobile-section-nav.js +2 -0
- package/dist/components/ds-shell-mobile-section-nav.js.map +1 -0
- package/dist/components/ds-shell-page.js +1 -1
- package/dist/components/ds-shell-page.js.map +1 -1
- package/dist/components/ds-shell-tools.d.ts +11 -0
- package/dist/components/ds-shell-tools.js +2 -0
- package/dist/components/ds-shell-tools.js.map +1 -0
- package/dist/components/ds-skeleton.js +1 -1
- package/dist/components/ds-slider.js +1 -1
- package/dist/components/ds-slider.js.map +1 -1
- package/dist/components/ds-swatch-picker.js +1 -1
- package/dist/components/ds-switch.js +1 -1
- package/dist/components/ds-tab-group.js +1 -1
- package/dist/components/ds-tab-group.js.map +1 -1
- package/dist/components/ds-tag.js +1 -1
- package/dist/components/ds-text.js +1 -1
- package/dist/components/ds-toast.js +1 -1
- package/dist/components/ds-toast.js.map +1 -1
- package/dist/components/ds-tooltip-data-viz.js +1 -1
- package/dist/components/ds-tooltip.js +1 -1
- package/dist/components/ds-typing-indicator.js +1 -1
- package/dist/components/ds-typing-indicator.js.map +1 -1
- package/dist/components/{p-DcGpdIlT.js → p-9dQQSgwT.js} +2 -2
- package/dist/components/p-B3rbhRAk.js +2 -0
- package/dist/components/p-B3rbhRAk.js.map +1 -0
- package/dist/components/p-B6Vuayt6.js +2 -0
- package/dist/components/p-B6Vuayt6.js.map +1 -0
- package/dist/components/{p-BWUTr_XN.js → p-BJMRBHKW.js} +2 -2
- package/dist/components/p-BJMRBHKW.js.map +1 -0
- package/dist/components/p-BPS9VExm.js +2 -0
- package/dist/components/{p-CCHqsF_H.js.map → p-BPS9VExm.js.map} +1 -1
- package/dist/components/p-BVV_rlIP.js +2 -0
- package/dist/components/p-BVV_rlIP.js.map +1 -0
- package/dist/components/{p-GMDGgtY8.js → p-BhxwpOH8.js} +2 -2
- package/dist/components/{p-2W-ZjZCR.js → p-Biz6xo-z.js} +2 -2
- package/dist/components/p-BrusnEYP.js +2 -0
- package/dist/components/p-BrusnEYP.js.map +1 -0
- package/dist/components/{p-CG5EX4NW.js → p-BtEjlcB9.js} +2 -2
- package/dist/components/{p-C0_8K4y7.js → p-BwGnhInj.js} +2 -2
- package/dist/components/p-BwGnhInj.js.map +1 -0
- package/dist/components/{p-D6jK2Hyi.js → p-C7bZ-jiU.js} +2 -2
- package/dist/components/p-CH3w-P2H.js +2 -0
- package/dist/components/p-CH3w-P2H.js.map +1 -0
- package/dist/components/{p-DOCKtrS4.js → p-CH6cNXXF.js} +2 -2
- package/dist/components/{p-BE_CDJeL.js → p-CY19gMiz.js} +2 -2
- package/dist/components/p-C_0Q8Cnp.js +2 -0
- package/dist/components/{p-Dg3xLna0.js.map → p-C_0Q8Cnp.js.map} +1 -1
- package/dist/components/p-C_ewSXTT.js +2 -0
- package/dist/components/p-C_ewSXTT.js.map +1 -0
- package/dist/components/{p-CHkI3oIS.js → p-Ce52yVXF.js} +2 -2
- package/dist/components/p-CgHTNfC1.js +2 -0
- package/dist/components/p-CgHTNfC1.js.map +1 -0
- package/dist/components/p-Co8hD3P-.js +2 -0
- package/dist/components/{p-Cxpl-rzP.js.map → p-Co8hD3P-.js.map} +1 -1
- package/dist/components/{p-xY3TjBF5.js → p-CoYFJD-w.js} +2 -2
- package/dist/components/{p-DBi1bmOL.js → p-CtD24EyI.js} +2 -2
- package/dist/components/{p-BRLDJmkh.js → p-D-xttdpn.js} +2 -2
- package/dist/components/{p-CNffejay.js → p-DSa0Hnd3.js} +2 -2
- package/dist/components/p-DXewjzkM.js +2 -0
- package/dist/components/p-DXewjzkM.js.map +1 -0
- package/dist/components/p-DXnFhmZF.js +2 -0
- package/dist/components/{p-BpA9uYKX.js.map → p-DXnFhmZF.js.map} +1 -1
- package/dist/components/{p-DyGB97Oy.js → p-DYqReipj.js} +2 -2
- package/dist/components/{p-ky1msbJ8.js → p-DjPZxzIG.js} +2 -2
- package/dist/components/{p-ky1msbJ8.js.map → p-DjPZxzIG.js.map} +1 -1
- package/dist/components/p-NUNsefU1.js +2 -0
- package/dist/components/{p-8OOCLGph.js.map → p-NUNsefU1.js.map} +1 -1
- package/dist/components/p-PZ6R_nGI.js +2 -0
- package/dist/components/p-PZ6R_nGI.js.map +1 -0
- package/dist/components/{p-B8CubPgQ.js → p-g40DTeV8.js} +2 -2
- package/dist/components/p-jCWtxthA.js +2 -0
- package/dist/components/{p-XgIQ3oI_.js.map → p-jCWtxthA.js.map} +1 -1
- package/dist/components/p-yhj1lIPx.js +2 -0
- package/dist/components/p-yhj1lIPx.js.map +1 -0
- package/dist/docs/components.json +8860 -6021
- package/dist/lib/components/BarNav/bar-nav-types.d.ts +2 -0
- package/dist/lib/components/PanelNav/panel-nav-types.d.ts +29 -0
- package/dist/lib/components/PanelTools/panel-tools-types.d.ts +40 -0
- package/dist/lib/components/TabGroup/tab-item-utils.d.ts +31 -0
- package/dist/lib/shell/index.d.ts +5 -0
- package/dist/lib/shell/index.js +36 -0
- package/dist/lib/shell/index.js.map +3 -3
- package/dist/lib/shell/shell-responsive.d.ts +13 -0
- package/dist/lib/utils/index.js +3 -1
- package/dist/lib/utils/index.js.map +2 -2
- package/dist/mcp/cli.js +142 -18
- package/dist/mcp-data/registry/agent-source-list.json +1 -1
- package/dist/mcp-data/registry/bar-title.json +68 -14
- package/dist/mcp-data/registry/breadcrumb.json +205 -0
- package/dist/mcp-data/registry/card-data-viz-bar.json +212 -0
- package/dist/mcp-data/registry/card-data-viz-line.json +206 -0
- package/dist/mcp-data/registry/card-shell-data-viz.json +7 -0
- package/dist/mcp-data/registry/chart-bar-stacked.json +225 -0
- package/dist/mcp-data/registry/chart-bar.json +9 -2
- package/dist/mcp-data/registry/chart-legend.json +29 -3
- package/dist/mcp-data/registry/chart-line.json +4 -2
- package/dist/mcp-data/registry/conversation-list-item.json +3 -3
- package/dist/mcp-data/registry/message-scroller.json +4 -2
- package/dist/mcp-data/registry/message.json +3 -2
- package/dist/mcp-data/registry/modal.json +1 -1
- package/dist/mcp-data/registry/registry.json +1107 -44
- package/dist/mcp-data/registry/shell-app.json +71 -11
- package/dist/mcp-data/registry/shell-mobile-bar.json +314 -0
- package/dist/mcp-data/registry/shell-mobile-nav.json +348 -0
- package/dist/mcp-data/registry/shell-mobile-section-nav.json +267 -0
- package/dist/mcp-data/registry/shell-page.json +31 -13
- package/dist/mcp-data/registry/shell-tools.json +450 -0
- package/dist/mcp-data/registry/text.json +1 -1
- package/dist/mcp-data/registry/typing-indicator.json +7 -7
- package/dist/react/components.d.ts +8 -0
- package/dist/react/components.js +8 -0
- package/dist/react/ds-bar-title.d.ts +2 -1
- package/dist/react/ds-bar-title.js +1 -0
- package/dist/react/ds-breadcrumb.d.ts +12 -0
- package/dist/react/ds-breadcrumb.js +12 -0
- package/dist/react/ds-card-data-viz-bar.d.ts +12 -0
- package/dist/react/ds-card-data-viz-bar.js +12 -0
- package/dist/react/ds-card-data-viz-line.d.ts +12 -0
- package/dist/react/ds-card-data-viz-line.js +12 -0
- package/dist/react/ds-chart-bar-stacked.d.ts +9 -0
- package/dist/react/ds-chart-bar-stacked.js +12 -0
- package/dist/react/ds-shell-app.d.ts +7 -2
- package/dist/react/ds-shell-app.js +1 -1
- package/dist/react/ds-shell-mobile-bar.d.ts +13 -0
- package/dist/react/ds-shell-mobile-bar.js +15 -0
- package/dist/react/ds-shell-mobile-nav.d.ts +15 -0
- package/dist/react/ds-shell-mobile-nav.js +17 -0
- package/dist/react/ds-shell-mobile-section-nav.d.ts +12 -0
- package/dist/react/ds-shell-mobile-section-nav.js +12 -0
- package/dist/react/ds-shell-tools.d.ts +25 -0
- package/dist/react/ds-shell-tools.js +17 -0
- package/dist/styles/prose.css +1 -0
- package/dist/types/components/BarTitle/BarTitle.d.ts +13 -1
- package/dist/types/components/Breadcrumb/Breadcrumb.d.ts +31 -0
- package/dist/types/components/Breadcrumb/breadcrumb-types.d.ts +17 -0
- package/dist/types/components/CardDataVizBar/CardDataVizBar.d.ts +24 -0
- package/dist/types/components/CardDataVizBar/index.d.ts +2 -0
- package/dist/types/components/CardDataVizLine/CardDataVizLine.d.ts +24 -0
- package/dist/types/components/CardDataVizLine/index.d.ts +2 -0
- package/dist/types/components/ChartBarStacked/ChartBarStacked.d.ts +15 -0
- package/dist/types/components/ChartBarStacked/index.d.ts +3 -0
- package/dist/types/components/ChartLegend/ChartLegend.d.ts +3 -0
- package/dist/types/components/ShellApp/ShellApp.d.ts +16 -0
- package/dist/types/components/ShellMobileBar/ShellMobileBar.d.ts +25 -0
- package/dist/types/components/ShellMobileBar/index.d.ts +4 -0
- package/dist/types/components/ShellMobileBar/shell-mobile-bar-types.d.ts +5 -0
- package/dist/types/components/ShellMobileNav/ShellMobileNav.d.ts +32 -0
- package/dist/types/components/ShellMobileNav/index.d.ts +2 -0
- package/dist/types/components/ShellMobileNav/shell-mobile-nav-types.d.ts +6 -0
- package/dist/types/components/ShellMobileSectionNav/ShellMobileSectionNav.d.ts +30 -0
- package/dist/types/components/ShellMobileSectionNav/index.d.ts +2 -0
- package/dist/types/components/ShellPage/ShellPage.d.ts +19 -7
- package/dist/types/components/ShellPage/shell-page-responsive.d.ts +0 -8
- package/dist/types/components/ShellTools/ShellTools.d.ts +61 -0
- package/dist/types/components/ShellTools/index.d.ts +3 -0
- package/dist/types/components/TypingIndicator/TypingIndicator.d.ts +1 -1
- package/dist/types/components.d.ts +953 -19
- package/dist/types/shell/index.d.ts +5 -0
- package/dist/types/shell/shell-responsive.d.ts +14 -0
- package/package.json +1 -1
- package/dist/components/p-8OOCLGph.js +0 -2
- package/dist/components/p-BWUTr_XN.js.map +0 -1
- package/dist/components/p-BpA9uYKX.js +0 -2
- package/dist/components/p-C0_8K4y7.js.map +0 -1
- package/dist/components/p-CA3kLO7K.js +0 -2
- package/dist/components/p-CA3kLO7K.js.map +0 -1
- package/dist/components/p-CCHqsF_H.js +0 -2
- package/dist/components/p-Cxpl-rzP.js +0 -2
- package/dist/components/p-CzBnvtcz.js +0 -2
- package/dist/components/p-CzBnvtcz.js.map +0 -1
- package/dist/components/p-Dg3xLna0.js +0 -2
- package/dist/components/p-XgIQ3oI_.js +0 -2
- /package/dist/components/{p-DcGpdIlT.js.map → p-9dQQSgwT.js.map} +0 -0
- /package/dist/components/{p-GMDGgtY8.js.map → p-BhxwpOH8.js.map} +0 -0
- /package/dist/components/{p-2W-ZjZCR.js.map → p-Biz6xo-z.js.map} +0 -0
- /package/dist/components/{p-CG5EX4NW.js.map → p-BtEjlcB9.js.map} +0 -0
- /package/dist/components/{p-D6jK2Hyi.js.map → p-C7bZ-jiU.js.map} +0 -0
- /package/dist/components/{p-DOCKtrS4.js.map → p-CH6cNXXF.js.map} +0 -0
- /package/dist/components/{p-BE_CDJeL.js.map → p-CY19gMiz.js.map} +0 -0
- /package/dist/components/{p-CHkI3oIS.js.map → p-Ce52yVXF.js.map} +0 -0
- /package/dist/components/{p-xY3TjBF5.js.map → p-CoYFJD-w.js.map} +0 -0
- /package/dist/components/{p-DBi1bmOL.js.map → p-CtD24EyI.js.map} +0 -0
- /package/dist/components/{p-BRLDJmkh.js.map → p-D-xttdpn.js.map} +0 -0
- /package/dist/components/{p-CNffejay.js.map → p-DSa0Hnd3.js.map} +0 -0
- /package/dist/components/{p-DyGB97Oy.js.map → p-DYqReipj.js.map} +0 -0
- /package/dist/components/{p-B8CubPgQ.js.map → p-g40DTeV8.js.map} +0 -0
package/dist/mcp/cli.js
CHANGED
|
@@ -31121,6 +31121,54 @@ var IS_SOURCE_CHECKOUT = fs.existsSync(path.join(SOURCE_ROOT, "scripts", "build-
|
|
|
31121
31121
|
var REGISTRY_DIR = IS_SOURCE_CHECKOUT ? path.resolve(SOURCE_ROOT, "public", "r") : path.resolve(__dirname, "..", "mcp-data", "registry");
|
|
31122
31122
|
var PATTERN_DIR = path.resolve(SOURCE_ROOT, "agent", "patterns");
|
|
31123
31123
|
var PATTERN_MANIFEST = path.resolve(__dirname, "..", "agent-patterns.json");
|
|
31124
|
+
var PACKAGE_ROOT = IS_SOURCE_CHECKOUT ? SOURCE_ROOT : path.resolve(__dirname, "..", "..");
|
|
31125
|
+
var PACKAGE_VERSION = JSON.parse(
|
|
31126
|
+
fs.readFileSync(path.join(PACKAGE_ROOT, "package.json"), "utf8")
|
|
31127
|
+
).version;
|
|
31128
|
+
var READ_ONLY_TOOL_ANNOTATIONS = {
|
|
31129
|
+
readOnlyHint: true,
|
|
31130
|
+
destructiveHint: false,
|
|
31131
|
+
idempotentHint: true,
|
|
31132
|
+
openWorldHint: false
|
|
31133
|
+
};
|
|
31134
|
+
var JSON_OBJECT_SCHEMA = external_exports.record(external_exports.string(), external_exports.unknown());
|
|
31135
|
+
var COMPONENT_SUMMARY_SCHEMA = external_exports.object({
|
|
31136
|
+
name: external_exports.string(),
|
|
31137
|
+
title: external_exports.string(),
|
|
31138
|
+
description: external_exports.string(),
|
|
31139
|
+
type: external_exports.string(),
|
|
31140
|
+
status: external_exports.string(),
|
|
31141
|
+
audience: external_exports.string(),
|
|
31142
|
+
dependencies: external_exports.array(external_exports.string()),
|
|
31143
|
+
registryDependencies: external_exports.array(external_exports.string()),
|
|
31144
|
+
patterns: external_exports.array(external_exports.string())
|
|
31145
|
+
});
|
|
31146
|
+
var COMPONENT_LIST_OUTPUT_SCHEMA = external_exports.object({
|
|
31147
|
+
count: external_exports.number().int().nonnegative(),
|
|
31148
|
+
query: external_exports.string().nullable(),
|
|
31149
|
+
components: external_exports.array(COMPONENT_SUMMARY_SCHEMA)
|
|
31150
|
+
});
|
|
31151
|
+
var COMPONENT_OUTPUT_SCHEMA = external_exports.object({
|
|
31152
|
+
component: JSON_OBJECT_SCHEMA
|
|
31153
|
+
});
|
|
31154
|
+
var PATTERN_SUMMARY_SCHEMA = external_exports.object({
|
|
31155
|
+
id: external_exports.string(),
|
|
31156
|
+
status: external_exports.string(),
|
|
31157
|
+
summary: external_exports.string(),
|
|
31158
|
+
useWhen: external_exports.array(external_exports.string()),
|
|
31159
|
+
avoidWhen: external_exports.array(external_exports.string()),
|
|
31160
|
+
components: external_exports.array(external_exports.string()),
|
|
31161
|
+
frameworks: external_exports.array(external_exports.string())
|
|
31162
|
+
});
|
|
31163
|
+
var PATTERN_LIST_OUTPUT_SCHEMA = external_exports.object({
|
|
31164
|
+
count: external_exports.number().int().nonnegative(),
|
|
31165
|
+
query: external_exports.string().nullable(),
|
|
31166
|
+
patterns: external_exports.array(PATTERN_SUMMARY_SCHEMA)
|
|
31167
|
+
});
|
|
31168
|
+
var PATTERN_OUTPUT_SCHEMA = external_exports.object({
|
|
31169
|
+
framework: external_exports.enum(["customElements", "react", "angular"]).nullable(),
|
|
31170
|
+
pattern: JSON_OBJECT_SCHEMA
|
|
31171
|
+
});
|
|
31124
31172
|
function ensureRegistry() {
|
|
31125
31173
|
const registryPath = path.join(REGISTRY_DIR, "registry.json");
|
|
31126
31174
|
if (!fs.existsSync(registryPath)) {
|
|
@@ -31168,6 +31216,41 @@ function loadPattern(name) {
|
|
|
31168
31216
|
const normalized = name.replace(/^pattern:/, "").toLowerCase();
|
|
31169
31217
|
return loadPatterns().find((pattern) => pattern.id === `pattern:${normalized}`) ?? null;
|
|
31170
31218
|
}
|
|
31219
|
+
function componentSummary(component) {
|
|
31220
|
+
return {
|
|
31221
|
+
name: component.name,
|
|
31222
|
+
title: component.title,
|
|
31223
|
+
description: component.description,
|
|
31224
|
+
type: component.type,
|
|
31225
|
+
status: component.meta?.intent?.status ?? "unknown",
|
|
31226
|
+
audience: component.meta?.intent?.audience ?? "unknown",
|
|
31227
|
+
dependencies: component.dependencies ?? [],
|
|
31228
|
+
registryDependencies: component.registryDependencies ?? [],
|
|
31229
|
+
patterns: component.meta?.intent?.patterns ?? []
|
|
31230
|
+
};
|
|
31231
|
+
}
|
|
31232
|
+
function componentDetail(component) {
|
|
31233
|
+
const { files: _files, ...detail } = component;
|
|
31234
|
+
return detail;
|
|
31235
|
+
}
|
|
31236
|
+
function patternSummary(pattern) {
|
|
31237
|
+
return {
|
|
31238
|
+
id: pattern.id,
|
|
31239
|
+
status: pattern.status,
|
|
31240
|
+
summary: pattern.summary,
|
|
31241
|
+
useWhen: pattern.useWhen ?? [],
|
|
31242
|
+
avoidWhen: pattern.avoidWhen ?? [],
|
|
31243
|
+
components: (pattern.components ?? []).map((entry) => entry.component),
|
|
31244
|
+
frameworks: Object.entries(pattern.implementations ?? {}).filter(([, implementation]) => implementation.recipes?.length).map(([framework]) => framework)
|
|
31245
|
+
};
|
|
31246
|
+
}
|
|
31247
|
+
function patternDetail(pattern, framework) {
|
|
31248
|
+
if (!framework) return pattern;
|
|
31249
|
+
return {
|
|
31250
|
+
...pattern,
|
|
31251
|
+
implementations: pattern.implementations?.[framework] ? { [framework]: pattern.implementations[framework] } : {}
|
|
31252
|
+
};
|
|
31253
|
+
}
|
|
31171
31254
|
function formatSetupGuide() {
|
|
31172
31255
|
const m = loadRegistry().meta;
|
|
31173
31256
|
return `# @ds-mo/ui \u2014 Project Setup Guide
|
|
@@ -31247,16 +31330,18 @@ Never hardcode these values. The tokens support light/dark theming automatically
|
|
|
31247
31330
|
}
|
|
31248
31331
|
var server = new McpServer({
|
|
31249
31332
|
name: "compomo",
|
|
31250
|
-
version:
|
|
31333
|
+
version: PACKAGE_VERSION
|
|
31251
31334
|
});
|
|
31252
31335
|
server.registerTool(
|
|
31253
31336
|
"list_components",
|
|
31254
31337
|
{
|
|
31255
31338
|
title: "List Components",
|
|
31256
31339
|
description: "List all available components in the @ds-mo/ui design system library. Returns component names, descriptions, and required packages.",
|
|
31257
|
-
inputSchema: {
|
|
31340
|
+
inputSchema: external_exports.object({
|
|
31258
31341
|
search: external_exports.string().optional().describe("Optional text to filter components by name or description.")
|
|
31259
|
-
}
|
|
31342
|
+
}),
|
|
31343
|
+
outputSchema: COMPONENT_LIST_OUTPUT_SCHEMA,
|
|
31344
|
+
annotations: READ_ONLY_TOOL_ANNOTATIONS
|
|
31260
31345
|
},
|
|
31261
31346
|
async ({ search }) => {
|
|
31262
31347
|
let items = loadRegistry().items;
|
|
@@ -31268,13 +31353,25 @@ server.registerTool(
|
|
|
31268
31353
|
}
|
|
31269
31354
|
if (items.length === 0) {
|
|
31270
31355
|
return {
|
|
31271
|
-
content: [{ type: "text", text: `No components found${search ? ` matching "${search}"` : ""}.` }]
|
|
31356
|
+
content: [{ type: "text", text: `No components found${search ? ` matching "${search}"` : ""}.` }],
|
|
31357
|
+
structuredContent: {
|
|
31358
|
+
count: 0,
|
|
31359
|
+
query: search ?? null,
|
|
31360
|
+
components: []
|
|
31361
|
+
}
|
|
31272
31362
|
};
|
|
31273
31363
|
}
|
|
31274
31364
|
const text = `# @ds-mo/ui \u2014 ${items.length} component${items.length === 1 ? "" : "s"}${search ? ` matching "${search}"` : ""}
|
|
31275
31365
|
|
|
31276
31366
|
${formatComponentList(items)}`;
|
|
31277
|
-
return {
|
|
31367
|
+
return {
|
|
31368
|
+
content: [{ type: "text", text }],
|
|
31369
|
+
structuredContent: {
|
|
31370
|
+
count: items.length,
|
|
31371
|
+
query: search ?? null,
|
|
31372
|
+
components: items.map(componentSummary)
|
|
31373
|
+
}
|
|
31374
|
+
};
|
|
31278
31375
|
}
|
|
31279
31376
|
);
|
|
31280
31377
|
server.registerTool(
|
|
@@ -31282,9 +31379,11 @@ server.registerTool(
|
|
|
31282
31379
|
{
|
|
31283
31380
|
title: "Get Component",
|
|
31284
31381
|
description: "Get detailed information about a specific @ds-mo/ui component including props API, import statements, setup instructions, peer dependencies, and full source code for reference.",
|
|
31285
|
-
inputSchema: {
|
|
31382
|
+
inputSchema: external_exports.object({
|
|
31286
31383
|
name: external_exports.string().describe('Component name in kebab-case (e.g., "button", "tab-group", "toggle-button") or PascalCase (e.g., "Button", "TabGroup").')
|
|
31287
|
-
}
|
|
31384
|
+
}),
|
|
31385
|
+
outputSchema: COMPONENT_OUTPUT_SCHEMA,
|
|
31386
|
+
annotations: READ_ONLY_TOOL_ANNOTATIONS
|
|
31288
31387
|
},
|
|
31289
31388
|
async ({ name }) => {
|
|
31290
31389
|
const kebab = name.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/([A-Z])([A-Z][a-z])/g, "$1-$2").toLowerCase();
|
|
@@ -31302,14 +31401,18 @@ Available: ${allNames.join(", ")}`;
|
|
|
31302
31401
|
isError: true
|
|
31303
31402
|
};
|
|
31304
31403
|
}
|
|
31305
|
-
return {
|
|
31404
|
+
return {
|
|
31405
|
+
content: [{ type: "text", text: formatComponentDetail(comp) }],
|
|
31406
|
+
structuredContent: { component: componentDetail(comp) }
|
|
31407
|
+
};
|
|
31306
31408
|
}
|
|
31307
31409
|
);
|
|
31308
31410
|
server.registerTool(
|
|
31309
31411
|
"get_setup_guide",
|
|
31310
31412
|
{
|
|
31311
31413
|
title: "Get Setup Guide",
|
|
31312
|
-
description: "Get the full project setup guide for @ds-mo/ui \u2014 install commands, CSS imports, theme configuration, and design token architecture."
|
|
31414
|
+
description: "Get the full project setup guide for @ds-mo/ui \u2014 install commands, CSS imports, theme configuration, and design token architecture.",
|
|
31415
|
+
annotations: READ_ONLY_TOOL_ANNOTATIONS
|
|
31313
31416
|
},
|
|
31314
31417
|
async () => {
|
|
31315
31418
|
return { content: [{ type: "text", text: formatSetupGuide() }] };
|
|
@@ -31320,9 +31423,10 @@ server.registerTool(
|
|
|
31320
31423
|
{
|
|
31321
31424
|
title: "Get Component Source",
|
|
31322
31425
|
description: "Get the full source code of a @ds-mo/ui component for reference. Use this to understand implementation patterns, not to copy the code into a project.",
|
|
31323
|
-
inputSchema: {
|
|
31426
|
+
inputSchema: external_exports.object({
|
|
31324
31427
|
name: external_exports.string().describe('Component name in kebab-case (e.g., "button", "modal").')
|
|
31325
|
-
}
|
|
31428
|
+
}),
|
|
31429
|
+
annotations: READ_ONLY_TOOL_ANNOTATIONS
|
|
31326
31430
|
},
|
|
31327
31431
|
async ({ name }) => {
|
|
31328
31432
|
const kebab = name.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/([A-Z])([A-Z][a-z])/g, "$1-$2").toLowerCase();
|
|
@@ -31352,9 +31456,11 @@ server.registerTool(
|
|
|
31352
31456
|
{
|
|
31353
31457
|
title: "List Patterns",
|
|
31354
31458
|
description: "List supported @ds-mo/ui multi-component composition patterns with executable framework recipes.",
|
|
31355
|
-
inputSchema: {
|
|
31459
|
+
inputSchema: external_exports.object({
|
|
31356
31460
|
search: external_exports.string().optional().describe("Optional text to filter patterns by id, summary, or use case.")
|
|
31357
|
-
}
|
|
31461
|
+
}),
|
|
31462
|
+
outputSchema: PATTERN_LIST_OUTPUT_SCHEMA,
|
|
31463
|
+
annotations: READ_ONLY_TOOL_ANNOTATIONS
|
|
31358
31464
|
},
|
|
31359
31465
|
async ({ search }) => {
|
|
31360
31466
|
let patterns = loadPatterns();
|
|
@@ -31369,13 +31475,23 @@ server.registerTool(
|
|
|
31369
31475
|
}
|
|
31370
31476
|
if (!patterns.length) {
|
|
31371
31477
|
return {
|
|
31372
|
-
content: [{ type: "text", text: `No composition patterns found${search ? ` matching "${search}"` : ""}.` }]
|
|
31478
|
+
content: [{ type: "text", text: `No composition patterns found${search ? ` matching "${search}"` : ""}.` }],
|
|
31479
|
+
structuredContent: {
|
|
31480
|
+
count: 0,
|
|
31481
|
+
query: search ?? null,
|
|
31482
|
+
patterns: []
|
|
31483
|
+
}
|
|
31373
31484
|
};
|
|
31374
31485
|
}
|
|
31375
31486
|
return {
|
|
31376
31487
|
content: [{ type: "text", text: `# @ds-mo/ui \u2014 ${patterns.length} composition pattern${patterns.length === 1 ? "" : "s"}
|
|
31377
31488
|
|
|
31378
|
-
${formatPatternList(patterns)}` }]
|
|
31489
|
+
${formatPatternList(patterns)}` }],
|
|
31490
|
+
structuredContent: {
|
|
31491
|
+
count: patterns.length,
|
|
31492
|
+
query: search ?? null,
|
|
31493
|
+
patterns: patterns.map(patternSummary)
|
|
31494
|
+
}
|
|
31379
31495
|
};
|
|
31380
31496
|
}
|
|
31381
31497
|
);
|
|
@@ -31384,10 +31500,12 @@ server.registerTool(
|
|
|
31384
31500
|
{
|
|
31385
31501
|
title: "Get Pattern",
|
|
31386
31502
|
description: "Get design intent, state ownership, accessibility requirements, and executable Custom Elements, React, or Angular recipes for an @ds-mo/ui composition.",
|
|
31387
|
-
inputSchema: {
|
|
31503
|
+
inputSchema: external_exports.object({
|
|
31388
31504
|
name: external_exports.string().describe('Pattern id or name, for example "menu-trigger" or "pattern:menu-trigger".'),
|
|
31389
31505
|
framework: external_exports.enum(["customElements", "react", "angular"]).optional().describe("Return recipes only for this framework. Omit to return every implementation.")
|
|
31390
|
-
}
|
|
31506
|
+
}),
|
|
31507
|
+
outputSchema: PATTERN_OUTPUT_SCHEMA,
|
|
31508
|
+
annotations: READ_ONLY_TOOL_ANNOTATIONS
|
|
31391
31509
|
},
|
|
31392
31510
|
async ({ name, framework }) => {
|
|
31393
31511
|
const pattern = loadPattern(name);
|
|
@@ -31398,7 +31516,13 @@ server.registerTool(
|
|
|
31398
31516
|
isError: true
|
|
31399
31517
|
};
|
|
31400
31518
|
}
|
|
31401
|
-
return {
|
|
31519
|
+
return {
|
|
31520
|
+
content: [{ type: "text", text: formatPatternDetail(pattern, framework) }],
|
|
31521
|
+
structuredContent: {
|
|
31522
|
+
framework: framework ?? null,
|
|
31523
|
+
pattern: patternDetail(pattern, framework)
|
|
31524
|
+
}
|
|
31525
|
+
};
|
|
31402
31526
|
}
|
|
31403
31527
|
);
|
|
31404
31528
|
var transport = new StdioServerTransport();
|
|
@@ -141,7 +141,7 @@
|
|
|
141
141
|
"files": [
|
|
142
142
|
{
|
|
143
143
|
"path": "src/wc/components/AgentSourceList/AgentSourceList.css",
|
|
144
|
-
"content": ":host { display: block; }\n.agent-sources { border-block-start: var(--dimension-stroke-width-012) solid var(--color-border-tertiary); }\nsummary { align-items: center; cursor: pointer; display: flex; gap: var(--dimension-space-050); list-style: none; padding-block: var(--dimension-space-075); }\nsummary::-webkit-details-marker { display: none; }\ndetails[open] summary ds-icon { transform: rotate(90deg); }\nol { display: grid; gap: var(--dimension-space-075); margin: 0; padding: 0 0 var(--dimension-space-075) var(--dimension-space-150); }\nli { display: grid; gap: var(--dimension-space-025); }\na { align-items: center; color: inherit; display: inline-flex; gap: var(--dimension-space-025); width: fit-content; }\n\n@media (prefers-reduced-motion: no-preference) { summary ds-icon { transition: transform var(--effect-motion-short-2); } }\n",
|
|
144
|
+
"content": ":host { display: block; }\n.agent-sources { border-block-start: var(--dimension-stroke-width-012) solid var(--color-border-tertiary); }\nsummary { align-items: center; cursor: pointer; display: flex; gap: var(--dimension-space-050); list-style: none; padding-block: var(--dimension-space-075); }\nsummary::-webkit-details-marker { display: none; }\ndetails[open] summary ds-icon { transform: rotate(90deg); }\nol { display: grid; gap: var(--dimension-space-075); margin: 0; padding: 0 0 var(--dimension-space-075) var(--dimension-space-150); }\nli { display: grid; gap: var(--dimension-space-025); }\na { align-items: center; color: inherit; display: inline-flex; gap: var(--dimension-space-025); text-decoration-color: var(--color-foreground-tertiary); width: fit-content; }\n\n@media (prefers-reduced-motion: no-preference) { summary ds-icon { transition: transform var(--effect-motion-short-2); } }\n",
|
|
145
145
|
"type": "registry:ui"
|
|
146
146
|
},
|
|
147
147
|
{
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
3
|
"name": "bar-title",
|
|
4
4
|
"title": "BarTitle",
|
|
5
|
-
"description": "Page-level title chrome with optional route
|
|
5
|
+
"description": "Page-level title chrome with an optional expanded route breadcrumb, compact Back action, supporting description, inline active-section menu, one primary action, grouped overflow actions, and explicit expanded, compact, or constrained variants.",
|
|
6
6
|
"type": "registry:ui",
|
|
7
7
|
"meta": {
|
|
8
8
|
"library": "@ds-mo/ui",
|
|
@@ -13,11 +13,11 @@
|
|
|
13
13
|
"intent": {
|
|
14
14
|
"audience": "general",
|
|
15
15
|
"status": "stable",
|
|
16
|
-
"summary": "Page-level title chrome with optional route
|
|
16
|
+
"summary": "Page-level title chrome with an optional expanded route breadcrumb, compact Back action, supporting description, inline active-section menu, one primary action, grouped overflow actions, and explicit expanded, compact, or constrained variants.",
|
|
17
17
|
"useWhen": [
|
|
18
18
|
"A top-level page needs one h1 above its content.",
|
|
19
19
|
"A list or detail page has multiple route-level sections that belong in the inline active-section menu.",
|
|
20
|
-
"A detail page needs a page-level Back action.",
|
|
20
|
+
"A detail page needs route ancestors in expanded presentation and a page-level Back action in compact chrome.",
|
|
21
21
|
"A page needs one primary action plus optional secondary or destructive overflow commands."
|
|
22
22
|
],
|
|
23
23
|
"avoidWhen": [
|
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
"component:ds-shell-page",
|
|
49
49
|
"component:ds-button-filled",
|
|
50
50
|
"component:ds-button-unfilled",
|
|
51
|
+
"component:ds-breadcrumb",
|
|
51
52
|
"component:ds-menu",
|
|
52
53
|
"component:ds-text"
|
|
53
54
|
],
|
|
@@ -56,7 +57,8 @@
|
|
|
56
57
|
],
|
|
57
58
|
"accessibility": [
|
|
58
59
|
"Provide one concise heading; BarTitle renders exactly one h1 and changes only its visual recipe between variants.",
|
|
59
|
-
"Give Back a destination-specific accessible name such as Back to Drivers
|
|
60
|
+
"Give compact Back a destination-specific accessible name such as Back to Drivers and handle dsBack in the route owner.",
|
|
61
|
+
"Provide ordered breadcrumb items for deeper expanded paths and handle dsBreadcrumbSelect when native href navigation is not used; backLabel remains the single-parent expanded fallback.",
|
|
60
62
|
"Keep value synchronized with the current child route; dsSectionChange returns the selected section id.",
|
|
61
63
|
"Section and overflow triggers expose menu relationships and restore focus after selection or dismissal.",
|
|
62
64
|
"Use one filled primary action in the page decision area and mark destructive overflow actions explicitly."
|
|
@@ -65,7 +67,8 @@
|
|
|
65
67
|
"Omitting Back, sections, primaryAction, and actions produces the top-level title-only header.",
|
|
66
68
|
"Two or more selectable sections add the inline section trigger; one section does not render a redundant menu.",
|
|
67
69
|
"Dividers in sections or actions create separate Menu groups without becoming selectable rows.",
|
|
68
|
-
"
|
|
70
|
+
"The overflow trigger uses its bordered treatment whenever the primary action is visible beside it; overflow-only and auto-collapsed-primary presentations keep the trigger borderless.",
|
|
71
|
+
"expanded renders the larger heading, optional description, inset divider, and a full-width caption breadcrumb row above the title. The breadcrumb begins after 32px top padding; the following title and right-side actions share one top alignment. Compact renders 48px chrome with the existing icon Back action; constrained uses compact chrome and moves an auto-collapse primary action into overflow.",
|
|
69
72
|
"primaryAction collapse defaults to auto. Use never for exceptional actions whose hierarchy must remain visible in constrained layouts."
|
|
70
73
|
],
|
|
71
74
|
"responsiveBehavior": [
|
|
@@ -76,15 +79,15 @@
|
|
|
76
79
|
],
|
|
77
80
|
"frameworkCaveats": {
|
|
78
81
|
"customElements": [
|
|
79
|
-
"Assign sections, primaryAction, and actions as JavaScript properties and replace array or object identities when controlled state changes.",
|
|
80
|
-
"Handle dsBack
|
|
82
|
+
"Assign breadcrumbs, sections, primaryAction, and actions as JavaScript properties and replace array or object identities when controlled state changes.",
|
|
83
|
+
"Handle dsBack for compact navigation and dsBreadcrumbSelect for application-owned expanded breadcrumb navigation, update value after dsSectionChange, and execute product commands from dsAction."
|
|
81
84
|
],
|
|
82
85
|
"react": [
|
|
83
|
-
"Pass
|
|
86
|
+
"Pass breadcrumb, section, and action arrays directly to DsBarTitle and keep value controlled from route state.",
|
|
84
87
|
"Place DsBarTitle in DsShellPage with slot=header when automatic page behavior is required."
|
|
85
88
|
],
|
|
86
89
|
"angular": [
|
|
87
|
-
"Bind complex values on the standalone DsBarTitle adapter and handle
|
|
90
|
+
"Bind complex values on the standalone DsBarTitle adapter and handle Back, breadcrumb, section, and action intent events in the route shell.",
|
|
88
91
|
"Place ds-bar-title in ds-shell-page with slot=header; do not render router-outlet inside BarTitle."
|
|
89
92
|
]
|
|
90
93
|
},
|
|
@@ -138,7 +141,24 @@
|
|
|
138
141
|
"default": "'Back'",
|
|
139
142
|
"required": false,
|
|
140
143
|
"mutable": false,
|
|
141
|
-
"description": "Visible parent-page label used by the expanded
|
|
144
|
+
"description": "Visible parent-page label used by the expanded breadcrumb when breadcrumbs is empty."
|
|
145
|
+
},
|
|
146
|
+
"breadcrumbAriaLabel": {
|
|
147
|
+
"type": "string",
|
|
148
|
+
"resolvedType": "string",
|
|
149
|
+
"attribute": "breadcrumb-aria-label",
|
|
150
|
+
"default": "'Breadcrumb'",
|
|
151
|
+
"required": false,
|
|
152
|
+
"mutable": false,
|
|
153
|
+
"description": "Accessible name for the expanded breadcrumb navigation landmark."
|
|
154
|
+
},
|
|
155
|
+
"breadcrumbs": {
|
|
156
|
+
"type": "BreadcrumbItem[]",
|
|
157
|
+
"resolvedType": "BreadcrumbItem[]",
|
|
158
|
+
"default": "[]",
|
|
159
|
+
"required": false,
|
|
160
|
+
"mutable": false,
|
|
161
|
+
"description": "Optional expanded ancestor path. Compact variants continue to use the Back action."
|
|
142
162
|
},
|
|
143
163
|
"description": {
|
|
144
164
|
"type": "string",
|
|
@@ -227,6 +247,14 @@
|
|
|
227
247
|
"composed": true,
|
|
228
248
|
"description": "Emitted when the leading Back action is activated."
|
|
229
249
|
},
|
|
250
|
+
{
|
|
251
|
+
"name": "dsBreadcrumbSelect",
|
|
252
|
+
"detail": "BreadcrumbSelectDetail",
|
|
253
|
+
"bubbles": true,
|
|
254
|
+
"cancelable": true,
|
|
255
|
+
"composed": true,
|
|
256
|
+
"description": "Emitted when an authored expanded breadcrumb item is activated."
|
|
257
|
+
},
|
|
230
258
|
{
|
|
231
259
|
"name": "dsSectionChange",
|
|
232
260
|
"detail": "string",
|
|
@@ -273,7 +301,24 @@
|
|
|
273
301
|
"default": "'Back'",
|
|
274
302
|
"required": false,
|
|
275
303
|
"mutable": false,
|
|
276
|
-
"description": "Visible parent-page label used by the expanded
|
|
304
|
+
"description": "Visible parent-page label used by the expanded breadcrumb when breadcrumbs is empty."
|
|
305
|
+
},
|
|
306
|
+
"breadcrumbAriaLabel": {
|
|
307
|
+
"type": "string",
|
|
308
|
+
"resolvedType": "string",
|
|
309
|
+
"attribute": "breadcrumb-aria-label",
|
|
310
|
+
"default": "'Breadcrumb'",
|
|
311
|
+
"required": false,
|
|
312
|
+
"mutable": false,
|
|
313
|
+
"description": "Accessible name for the expanded breadcrumb navigation landmark."
|
|
314
|
+
},
|
|
315
|
+
"breadcrumbs": {
|
|
316
|
+
"type": "BreadcrumbItem[]",
|
|
317
|
+
"resolvedType": "BreadcrumbItem[]",
|
|
318
|
+
"default": "[]",
|
|
319
|
+
"required": false,
|
|
320
|
+
"mutable": false,
|
|
321
|
+
"description": "Optional expanded ancestor path. Compact variants continue to use the Back action."
|
|
277
322
|
},
|
|
278
323
|
"description": {
|
|
279
324
|
"type": "string",
|
|
@@ -362,6 +407,14 @@
|
|
|
362
407
|
"composed": true,
|
|
363
408
|
"description": "Emitted when the leading Back action is activated."
|
|
364
409
|
},
|
|
410
|
+
{
|
|
411
|
+
"name": "dsBreadcrumbSelect",
|
|
412
|
+
"detail": "BreadcrumbSelectDetail",
|
|
413
|
+
"bubbles": true,
|
|
414
|
+
"cancelable": true,
|
|
415
|
+
"composed": true,
|
|
416
|
+
"description": "Emitted when an authored expanded breadcrumb item is activated."
|
|
417
|
+
},
|
|
365
418
|
{
|
|
366
419
|
"name": "dsSectionChange",
|
|
367
420
|
"detail": "string",
|
|
@@ -393,7 +446,7 @@
|
|
|
393
446
|
"import": "import { DsBarTitle } from '@ds-mo/ui/angular/ds-bar-title';",
|
|
394
447
|
"example": "<ds-bar-title></ds-bar-title>"
|
|
395
448
|
},
|
|
396
|
-
"complexPropertyNote": "Assign these non-primitive values as JavaScript properties: actions, primaryAction, sections.",
|
|
449
|
+
"complexPropertyNote": "Assign these non-primitive values as JavaScript properties: actions, breadcrumbs, primaryAction, sections.",
|
|
397
450
|
"peerDependencies": {
|
|
398
451
|
"required": [
|
|
399
452
|
"@ds-mo/tokens ^3.1.1",
|
|
@@ -409,6 +462,7 @@
|
|
|
409
462
|
"@ds-mo/icons"
|
|
410
463
|
],
|
|
411
464
|
"registryDependencies": [
|
|
465
|
+
"breadcrumb",
|
|
412
466
|
"button-filled",
|
|
413
467
|
"button-unfilled",
|
|
414
468
|
"icon",
|
|
@@ -419,12 +473,12 @@
|
|
|
419
473
|
"files": [
|
|
420
474
|
{
|
|
421
475
|
"path": "src/wc/components/BarTitle/BarTitle.css",
|
|
422
|
-
"content": "@import '../../utils/control-density.css';\n@import '../../utils/focus-ring.css';\n@import '../../utils/interaction-fill.css';\n\n:host {\n display: block;\n min-width: 0;\n box-sizing: border-box;\n background: var(--color-background-primary);\n}\n\n:host([data-shell-page-syncing]) {\n visibility: hidden;\n}\n\n.bar-title {\n position: relative;\n min-width: 0;\n padding: 0;\n box-sizing: border-box;\n background: var(--color-background-primary);\n}\n\n.bar-title::after {\n content: '';\n position: absolute;\n inset: auto var(--dimension-space-400) 0;\n height: var(--dimension-stroke-width-012);\n background: var(--color-border-tertiary);\n pointer-events: none;\n}\n\n.bar-title__inner {\n position: relative;\n display: flex;\n flex-direction: column;\n align-items: stretch;\n gap: var(--dimension-space-100);\n padding: var(--dimension-space-400);\n box-sizing: border-box;\n}\n\n.bar-title__row {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: var(--dimension-space-100);\n min-height: var(--dimension-size-400);\n min-width: 0;\n}\n\n:host(.bar-title-host--expanded) .bar-title__row {\n gap: var(--dimension-space-400);\n}\n\n.bar-title__leading {\n display: flex;\n flex: 1 1 auto;\n flex-direction: column;\n gap: var(--dimension-space-
|
|
476
|
+
"content": "@import '../../utils/control-density.css';\n@import '../../utils/focus-ring.css';\n@import '../../utils/interaction-fill.css';\n\n:host {\n display: block;\n min-width: 0;\n box-sizing: border-box;\n background: var(--color-background-primary);\n}\n\n:host([data-shell-page-syncing]) {\n visibility: hidden;\n}\n\n.bar-title {\n position: relative;\n min-width: 0;\n padding: 0;\n box-sizing: border-box;\n background: var(--color-background-primary);\n}\n\n.bar-title::after {\n content: '';\n position: absolute;\n inset: auto var(--dimension-space-400) 0;\n height: var(--dimension-stroke-width-012);\n background: var(--color-border-tertiary);\n pointer-events: none;\n}\n\n.bar-title__inner {\n position: relative;\n display: flex;\n flex-direction: column;\n align-items: stretch;\n gap: var(--dimension-space-100);\n padding: var(--dimension-space-400);\n box-sizing: border-box;\n}\n\n.bar-title__row {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: var(--dimension-space-100);\n min-height: var(--dimension-size-400);\n min-width: 0;\n}\n\n:host(.bar-title-host--expanded) .bar-title__row {\n gap: var(--dimension-space-400);\n}\n\n.bar-title__leading {\n display: flex;\n flex: 1 1 auto;\n flex-direction: column;\n gap: var(--dimension-space-100);\n min-width: 0;\n}\n\n.bar-title__title-row {\n display: flex;\n align-items: center;\n gap: var(--dimension-space-100);\n min-width: 0;\n min-height: var(--dimension-size-400);\n}\n\n.bar-title__identity {\n display: flex;\n flex: 0 1 auto;\n align-items: center;\n gap: var(--dimension-space-050);\n min-width: 0;\n}\n\n.bar-title__back,\n.bar-title__section-chevron {\n flex: 0 0 auto;\n}\n\n.bar-title__breadcrumb {\n display: block;\n width: 100%;\n min-width: 0;\n}\n\n.bar-title__heading {\n display: block;\n width: auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n user-select: none;\n}\n\n.bar-title__divider {\n width: var(--dimension-stroke-width-012);\n height: var(--dimension-size-250);\n margin-inline-start: var(--dimension-space-100);\n flex: 0 0 var(--dimension-stroke-width-012);\n background: var(--color-border-tertiary);\n}\n\n.bar-title__section-selector {\n display: flex;\n flex: 0 1 auto;\n min-width: 0;\n max-width: var(--dimension-panel-width-sm);\n}\n\n.bar-title__section-trigger {\n --ds-control-radius: var(--dimension-radius-half);\n\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--ds-control-gap);\n height: var(--ds-control-height);\n min-width: 0;\n max-width: 100%;\n padding-inline: var(--ds-control-padding-inline);\n border: none;\n border-radius: var(--ds-control-radius);\n box-sizing: border-box;\n background: transparent;\n color: var(--color-foreground-secondary);\n cursor: pointer;\n font-family: inherit;\n user-select: none;\n transition: color var(--effect-motion-short-2);\n}\n\n.bar-title__section-trigger--expanded {\n color: var(--color-foreground-primary);\n}\n\n.bar-title__section-trigger--expanded::after,\n.bar-title__section-trigger--expanded:hover::after {\n background: var(--ds-interaction-pressed);\n}\n\n.bar-title__section-label {\n min-width: 0;\n padding-inline: var(--ds-control-label-inset);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.bar-title__actions {\n display: flex;\n align-items: center;\n gap: var(--dimension-space-100);\n flex: 0 0 auto;\n}\n\n.bar-title__description {\n display: block;\n min-width: 0;\n max-width: 100%;\n}\n\n:host(.bar-title-host--compact) .bar-title {\n height: var(--dimension-size-600);\n padding: var(--dimension-space-100);\n}\n\n:host(.bar-title-host--compact) .bar-title::after {\n inset-inline: 0;\n}\n\n:host(.bar-title-host--compact) .bar-title__inner {\n height: 100%;\n padding: 0;\n gap: 0;\n}\n\n:host(.bar-title-host--compact) .bar-title__row {\n height: 100%;\n align-items: center;\n}\n\n:host(.bar-title-host--compact) .bar-title__identity {\n height: var(--dimension-size-400);\n}\n\n:host(.bar-title-host--compact) .bar-title__divider {\n margin-inline-start: 0;\n}\n\n:host(.bar-title-host--compact) .bar-title__heading {\n display: inline-flex;\n flex: 1 1 auto;\n align-items: center;\n height: var(--dimension-size-400);\n padding-inline: calc(var(--ds-control-padding-inline) + var(--ds-control-label-inset));\n box-sizing: border-box;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .bar-title__section-trigger {\n transition: none;\n }\n}\n",
|
|
423
477
|
"type": "registry:ui"
|
|
424
478
|
},
|
|
425
479
|
{
|
|
426
480
|
"path": "src/wc/components/BarTitle/BarTitle.tsx",
|
|
427
|
-
"content": "import { Component, Event, EventEmitter, h, Host, Prop, State, Watch } from '@stencil/core';\nimport type { MenuItemData, MenuSection } from '../Menu/menu-types';\nimport {\n isBarTitleDivider,\n type BarTitleAction,\n type BarTitleActionItem,\n type BarTitlePrimaryAction,\n type BarTitleSection,\n type BarTitleSectionItem,\n type BarTitleVariant,\n} from './bar-title-types';\n\nlet nextBarTitleId = 0;\n\ntype FocusableButton = HTMLElement & { setFocus?: () => Promise<void> };\n\n@Component({\n tag: 'ds-bar-title',\n styleUrl: 'BarTitle.css',\n scoped: true,\n})\nexport class BarTitle {\n /** The page's single visible h1. */\n @Prop() heading!: string;\n\n /** Optional supporting copy shown in the expanded presentation. */\n @Prop() description: string = '';\n\n /** Show the leading page-level Back action. */\n @Prop({ attribute: 'show-back' }) showBack: boolean = false;\n\n /** Accessible name for the leading Back action. */\n @Prop() backAriaLabel: string = 'Back';\n\n /** Visible parent-page label used by the expanded Back breadcrumb. */\n @Prop() backLabel: string = 'Back';\n\n /** Optional page sections exposed through the active-section menu. */\n @Prop() sections: BarTitleSectionItem[] = [];\n\n /** Id of the active page section. */\n @Prop() value: string = '';\n\n /** Accessible name for the page-section menu. */\n @Prop() sectionsAriaLabel: string = 'Change page section';\n\n /** The one highest-emphasis page action. */\n @Prop() primaryAction: BarTitlePrimaryAction | null = null;\n\n /** Secondary page actions shown in the overflow menu. Dividers create groups. */\n @Prop() actions: BarTitleActionItem[] = [];\n\n /** Accessible name for the page-actions menu. */\n @Prop() actionsAriaLabel: string = 'More page actions';\n\n /** Explicit visual/capacity variant. ShellPage owns automatic selection. */\n @Prop() variant: BarTitleVariant = 'expanded';\n\n /** Emitted when the leading Back action is activated. */\n @Event() dsBack!: EventEmitter<MouseEvent>;\n\n /** Emitted with the newly selected page-section id. */\n @Event() dsSectionChange!: EventEmitter<string>;\n\n /** Emitted with the activated primary or overflow action id. */\n @Event() dsAction!: EventEmitter<string>;\n\n @State() private sectionMenuOpen = false;\n @State() private actionMenuOpen = false;\n @State() private sectionMenuInitialFocusVisible = false;\n @State() private actionMenuInitialFocusVisible = false;\n\n private readonly instanceId = nextBarTitleId++;\n private readonly sectionMenuTriggerId = `bar-title-section-trigger-${this.instanceId}`;\n private readonly sectionMenuId = `bar-title-section-menu-${this.instanceId}`;\n private readonly actionMenuTriggerId = `bar-title-action-trigger-${this.instanceId}`;\n private readonly actionMenuId = `bar-title-action-menu-${this.instanceId}`;\n private sectionTriggerEl: HTMLButtonElement | null = null;\n private actionTriggerEl: FocusableButton | null = null;\n\n @Watch('sections')\n handleSectionsChange() {\n if (!this.hasSectionSelector) this.closeSectionMenu();\n }\n\n @Watch('actions')\n @Watch('primaryAction')\n handleActionsChange() {\n if (!this.showActionMenuTrigger) this.closeActionMenu();\n }\n\n private get compact(): boolean {\n return this.variant !== 'expanded';\n }\n\n /** Tooltip copy is fixed and generic; backAriaLabel/actionsAriaLabel stay page-specific. */\n private get backTooltipLabel(): string {\n return 'Go back';\n }\n\n private get primaryCollapsed(): boolean {\n return (\n this.variant === 'constrained' &&\n this.primaryAction !== null &&\n (this.primaryAction.collapse ?? 'auto') === 'auto'\n );\n }\n\n private get selectableSections(): BarTitleSection[] {\n return this.sections.filter((item): item is BarTitleSection => !isBarTitleDivider(item));\n }\n\n private get hasSectionSelector(): boolean {\n return this.selectableSections.length > 1;\n }\n\n private get effectiveValue(): string {\n return this.selectableSections.some(section => section.id === this.value)\n ? this.value\n : (this.selectableSections[0]?.id ?? '');\n }\n\n private get selectedSectionLabel(): string {\n return this.selectableSections.find(section => section.id === this.effectiveValue)?.label ?? '';\n }\n\n private get sectionTriggerAriaLabel(): string {\n return `${this.sectionsAriaLabel}. Current section: ${this.selectedSectionLabel}`;\n }\n\n private groupsFromItems<T extends BarTitleSection | BarTitleAction>(\n source: Array<T | { type: 'divider' }>,\n map: (item: T) => MenuItemData\n ): MenuSection[] {\n const groups: MenuSection[] = [];\n let items: MenuItemData[] = [];\n const commit = () => {\n if (items.length > 0) groups.push({ items });\n items = [];\n };\n\n for (const item of source) {\n if (isBarTitleDivider(item)) {\n commit();\n } else {\n items.push(map(item));\n }\n }\n commit();\n return groups;\n }\n\n private get sectionMenuSections(): MenuSection[] {\n return this.groupsFromItems(this.sections, section => ({\n label: section.label,\n value: section.id,\n isSelected: section.id === this.effectiveValue,\n isInactive: section.isInactive,\n }));\n }\n\n private get selectableActions(): BarTitleAction[] {\n return this.actions.filter((item): item is BarTitleAction => !isBarTitleDivider(item));\n }\n\n private get showActionMenuTrigger(): boolean {\n return (\n this.selectableActions.length > 0 || (this.primaryCollapsed && this.primaryAction !== null)\n );\n }\n\n private actionMenuItem(action: BarTitleAction | BarTitlePrimaryAction): MenuItemData {\n const primary = action as BarTitlePrimaryAction;\n return {\n label: action.label,\n value: action.id,\n isInactive: action.isInactive || primary.isLoading,\n isDestructive: action.isDestructive || primary.intent === 'negative',\n };\n }\n\n private get actionMenuSections(): MenuSection[] {\n const groups = this.groupsFromItems(this.actions, action => this.actionMenuItem(action));\n if (!this.primaryCollapsed || !this.primaryAction) return groups;\n return [{ items: [this.actionMenuItem(this.primaryAction)] }, ...groups];\n }\n\n private toggleSectionMenu = (event: MouseEvent) => {\n this.sectionMenuInitialFocusVisible = event.detail === 0;\n this.actionMenuOpen = false;\n this.sectionMenuOpen = !this.sectionMenuOpen;\n };\n\n private closeSectionMenu = () => {\n this.sectionMenuOpen = false;\n };\n\n private handleSectionSelect = (event: CustomEvent<MenuItemData>) => {\n const id = String(event.detail?.value ?? '');\n const selected = this.selectableSections.find(section => section.id === id);\n if (!selected || selected.isInactive) return;\n this.closeSectionMenu();\n this.dsSectionChange.emit(id);\n requestAnimationFrame(() => this.sectionTriggerEl?.focus());\n };\n\n private toggleActionMenu = (event: MouseEvent) => {\n this.actionMenuInitialFocusVisible = event.detail === 0;\n this.sectionMenuOpen = false;\n this.actionMenuOpen = !this.actionMenuOpen;\n };\n\n private closeActionMenu = () => {\n this.actionMenuOpen = false;\n };\n\n private handleActionSelect = (event: CustomEvent<MenuItemData>) => {\n const id = String(event.detail?.value ?? '');\n const primaryMatches = this.primaryCollapsed && this.primaryAction?.id === id;\n const action = this.selectableActions.find(candidate => candidate.id === id);\n if (!primaryMatches && !action) return;\n if (\n (primaryMatches && (this.primaryAction?.isInactive || this.primaryAction?.isLoading)) ||\n action?.isInactive\n ) {\n return;\n }\n this.closeActionMenu();\n this.dsAction.emit(id);\n requestAnimationFrame(() => void this.actionTriggerEl?.setFocus?.());\n };\n\n private renderSectionSelector() {\n if (!this.hasSectionSelector) return null;\n return [\n <div class=\"bar-title__divider\" aria-hidden=\"true\" />,\n <div class=\"bar-title__section-selector\">\n <button\n ref={el => {\n this.sectionTriggerEl = el ?? null;\n }}\n id={this.sectionMenuTriggerId}\n class={{\n 'bar-title__section-trigger': true,\n 'bar-title__section-trigger--expanded': this.sectionMenuOpen,\n 'ds-control--md': true,\n 'ds-focus-ring-inset': true,\n 'ds-interaction-fill': true,\n }}\n type=\"button\"\n aria-haspopup=\"menu\"\n aria-controls={this.sectionMenuId}\n aria-expanded={String(this.sectionMenuOpen)}\n aria-label={this.sectionTriggerAriaLabel}\n onClick={this.toggleSectionMenu}\n >\n <ds-text\n class=\"bar-title__section-label ds-interaction-fill__content\"\n as=\"span\"\n variant=\"text-body-medium\"\n emphasis\n color=\"primary\"\n >\n {this.selectedSectionLabel}\n </ds-text>\n <ds-icon\n class=\"bar-title__section-chevron ds-interaction-fill__content\"\n name=\"ChevronUpDown\"\n size=\"md\"\n color=\"inherit\"\n aria-hidden=\"true\"\n />\n </button>\n </div>,\n ];\n }\n\n private renderActions() {\n const primary = this.primaryAction;\n if (!primary && !this.showActionMenuTrigger) return null;\n\n return (\n <div class=\"bar-title__actions\">\n {primary && !this.primaryCollapsed ? (\n <ds-button-filled\n class=\"bar-title__primary-action\"\n variant={primary.icon ? 'icon-label' : 'label'}\n icon={primary.icon ?? ''}\n label={primary.label}\n intent={primary.intent ?? 'brand'}\n contrast={primary.contrast ?? 'bold'}\n size=\"md\"\n type={primary.type ?? 'button'}\n isInactive={primary.isInactive}\n isLoading={primary.isLoading}\n onDsClick={() => this.dsAction.emit(primary.id)}\n />\n ) : null}\n {this.showActionMenuTrigger ? (\n <ds-tooltip label=\"Page options\" side=\"bottom\" size=\"sm\">\n <ds-button-unfilled\n ref={el => {\n this.actionTriggerEl = el ?? null;\n }}\n id={this.actionMenuTriggerId}\n class=\"bar-title__more-actions\"\n variant=\"icon\"\n icon=\"Ellipses\"\n aria-label={this.actionsAriaLabel}\n size=\"md\"\n activeFill={!this.compact}\n hasBorder={!this.compact && !this.primaryCollapsed}\n haspopup=\"menu\"\n controls={this.actionMenuId}\n expanded={this.actionMenuOpen}\n onDsClick={(event: CustomEvent<MouseEvent>) => this.toggleActionMenu(event.detail)}\n />\n </ds-tooltip>\n ) : null}\n </div>\n );\n }\n\n private renderBack(compact: boolean) {\n if (!this.showBack) return null;\n\n if (!compact) {\n return (\n <div class=\"bar-title__breadcrumb\">\n <ds-button-unfilled\n class=\"bar-title__breadcrumb-back\"\n variant=\"icon-label\"\n icon=\"ChevronLeft\"\n label={this.backLabel}\n aria-label={this.backAriaLabel}\n size=\"xs\"\n hasBorder={false}\n onDsClick={(event: CustomEvent<MouseEvent>) => this.dsBack.emit(event.detail)}\n />\n </div>\n );\n }\n\n return (\n <ds-tooltip label={this.backTooltipLabel} side=\"bottom\" size=\"sm\">\n <ds-button-unfilled\n class=\"bar-title__back\"\n variant=\"icon\"\n icon=\"ChevronLeft\"\n aria-label={this.backAriaLabel}\n size=\"md\"\n activeFill={false}\n hasBorder={false}\n onDsClick={(event: CustomEvent<MouseEvent>) => this.dsBack.emit(event.detail)}\n />\n </ds-tooltip>\n );\n }\n\n render() {\n const compact = this.compact;\n return (\n <Host\n class={{\n 'bar-title-host--compact': compact,\n 'bar-title-host--expanded': this.variant === 'expanded',\n 'bar-title-host--constrained': this.variant === 'constrained',\n 'bar-title-host--has-description': !!this.description,\n 'bar-title-host--has-back': this.showBack,\n }}\n >\n <div class=\"bar-title\">\n <div class=\"bar-title__inner\">\n <div class=\"bar-title__row\">\n <div class=\"bar-title__leading\">\n {!compact ? this.renderBack(false) : null}\n <div class=\"bar-title__title-row\">\n <div class=\"bar-title__identity\">\n {compact ? this.renderBack(true) : null}\n <ds-text\n class=\"bar-title__heading ds-control--md\"\n variant={compact ? 'text-title-small' : 'text-title-medium'}\n emphasis\n color=\"primary\"\n as=\"h1\"\n lineTruncation={1}\n >\n {this.heading}\n </ds-text>\n </div>\n {this.renderSectionSelector()}\n </div>\n {this.description && !compact ? (\n <ds-text\n class=\"bar-title__description\"\n variant=\"text-body-small\"\n color=\"secondary\"\n lineTruncation={2}\n wrap=\"wrap\"\n as=\"p\"\n >\n {this.description}\n </ds-text>\n ) : null}\n </div>\n {this.renderActions()}\n </div>\n </div>\n </div>\n\n {this.hasSectionSelector ? (\n <ds-menu\n id={this.sectionMenuId}\n class=\"bar-title__section-menu\"\n anchorId={this.sectionMenuTriggerId}\n menuLabel={this.sectionsAriaLabel}\n open={this.sectionMenuOpen}\n initialFocusVisible={this.sectionMenuInitialFocusVisible}\n sections={this.sectionMenuSections}\n onDsClose={this.closeSectionMenu}\n onDsSelect={this.handleSectionSelect}\n />\n ) : null}\n\n {this.showActionMenuTrigger ? (\n <ds-menu\n id={this.actionMenuId}\n class=\"bar-title__action-menu\"\n anchorId={this.actionMenuTriggerId}\n align=\"end\"\n menuLabel={this.actionsAriaLabel}\n open={this.actionMenuOpen}\n initialFocusVisible={this.actionMenuInitialFocusVisible}\n sections={this.actionMenuSections}\n onDsClose={this.closeActionMenu}\n onDsSelect={this.handleActionSelect}\n />\n ) : null}\n </Host>\n );\n }\n}\n",
|
|
481
|
+
"content": "import {\n Component,\n Element,\n Event,\n EventEmitter,\n h,\n Host,\n Prop,\n State,\n Watch,\n} from '@stencil/core';\nimport type { BreadcrumbItem, BreadcrumbSelectDetail } from '../Breadcrumb/breadcrumb-types';\nimport type { MenuItemData, MenuSection } from '../Menu/menu-types';\nimport {\n isBarTitleDivider,\n type BarTitleAction,\n type BarTitleActionItem,\n type BarTitlePrimaryAction,\n type BarTitleSection,\n type BarTitleSectionItem,\n type BarTitleVariant,\n} from './bar-title-types';\n\nlet nextBarTitleId = 0;\n\ntype FocusableButton = HTMLElement & { setFocus?: () => Promise<void> };\n\n@Component({\n tag: 'ds-bar-title',\n styleUrl: 'BarTitle.css',\n scoped: true,\n})\nexport class BarTitle {\n @Element() el!: HTMLElement;\n\n /** The page's single visible h1. */\n @Prop() heading!: string;\n\n /** Optional supporting copy shown in the expanded presentation. */\n @Prop() description: string = '';\n\n /** Show the leading page-level Back action. */\n @Prop({ attribute: 'show-back' }) showBack: boolean = false;\n\n /** Accessible name for the leading Back action. */\n @Prop() backAriaLabel: string = 'Back';\n\n /** Visible parent-page label used by the expanded breadcrumb when breadcrumbs is empty. */\n @Prop() backLabel: string = 'Back';\n\n /** Optional expanded ancestor path. Compact variants continue to use the Back action. */\n @Prop() breadcrumbs: BreadcrumbItem[] = [];\n\n /** Accessible name for the expanded breadcrumb navigation landmark. */\n @Prop() breadcrumbAriaLabel: string = 'Breadcrumb';\n\n /** Optional page sections exposed through the active-section menu. */\n @Prop() sections: BarTitleSectionItem[] = [];\n\n /** Id of the active page section. */\n @Prop() value: string = '';\n\n /** Accessible name for the page-section menu. */\n @Prop() sectionsAriaLabel: string = 'Change page section';\n\n /** The one highest-emphasis page action. */\n @Prop() primaryAction: BarTitlePrimaryAction | null = null;\n\n /** Secondary page actions shown in the overflow menu. Dividers create groups. */\n @Prop() actions: BarTitleActionItem[] = [];\n\n /** Accessible name for the page-actions menu. */\n @Prop() actionsAriaLabel: string = 'More page actions';\n\n /** Explicit visual/capacity variant. ShellPage owns automatic selection. */\n @Prop() variant: BarTitleVariant = 'expanded';\n\n /** Emitted when the leading Back action is activated. */\n @Event() dsBack!: EventEmitter<MouseEvent>;\n\n /** Emitted when an authored expanded breadcrumb item is activated. */\n @Event({ cancelable: true }) dsBreadcrumbSelect!: EventEmitter<BreadcrumbSelectDetail>;\n\n /** Emitted with the newly selected page-section id. */\n @Event() dsSectionChange!: EventEmitter<string>;\n\n /** Emitted with the activated primary or overflow action id. */\n @Event() dsAction!: EventEmitter<string>;\n\n @State() private sectionMenuOpen = false;\n @State() private actionMenuOpen = false;\n @State() private sectionMenuInitialFocusVisible = false;\n @State() private actionMenuInitialFocusVisible = false;\n\n private readonly instanceId = nextBarTitleId++;\n private readonly sectionMenuTriggerId = `bar-title-section-trigger-${this.instanceId}`;\n private readonly sectionMenuId = `bar-title-section-menu-${this.instanceId}`;\n private readonly actionMenuTriggerId = `bar-title-action-trigger-${this.instanceId}`;\n private readonly actionMenuId = `bar-title-action-menu-${this.instanceId}`;\n private sectionTriggerEl: HTMLButtonElement | null = null;\n private actionTriggerEl: FocusableButton | null = null;\n\n componentWillLoad() {\n if (this.el.closest('ds-shell-page')) {\n this.el.setAttribute('data-shell-page-syncing', '');\n }\n }\n\n @Watch('sections')\n handleSectionsChange() {\n if (!this.hasSectionSelector) this.closeSectionMenu();\n }\n\n @Watch('actions')\n @Watch('primaryAction')\n handleActionsChange() {\n if (!this.showActionMenuTrigger) this.closeActionMenu();\n }\n\n private get compact(): boolean {\n return this.variant !== 'expanded';\n }\n\n private get expandedBreadcrumbItems(): BreadcrumbItem[] {\n if (this.breadcrumbs.length > 0) return this.breadcrumbs;\n if (!this.showBack) return [];\n return [\n {\n id: 'back',\n label: this.backLabel,\n ariaLabel: this.backAriaLabel,\n },\n ];\n }\n\n /** Tooltip copy is fixed and generic; backAriaLabel/actionsAriaLabel stay page-specific. */\n private get backTooltipLabel(): string {\n return 'Go back';\n }\n\n private get primaryCollapsed(): boolean {\n return (\n this.variant === 'constrained' &&\n this.primaryAction !== null &&\n (this.primaryAction.collapse ?? 'auto') === 'auto'\n );\n }\n\n private get selectableSections(): BarTitleSection[] {\n return this.sections.filter((item): item is BarTitleSection => !isBarTitleDivider(item));\n }\n\n private get hasSectionSelector(): boolean {\n return this.selectableSections.length > 1;\n }\n\n private get effectiveValue(): string {\n return this.selectableSections.some(section => section.id === this.value)\n ? this.value\n : (this.selectableSections[0]?.id ?? '');\n }\n\n private get selectedSectionLabel(): string {\n return this.selectableSections.find(section => section.id === this.effectiveValue)?.label ?? '';\n }\n\n private get sectionTriggerAriaLabel(): string {\n return `${this.sectionsAriaLabel}. Current section: ${this.selectedSectionLabel}`;\n }\n\n private groupsFromItems<T extends BarTitleSection | BarTitleAction>(\n source: Array<T | { type: 'divider' }>,\n map: (item: T) => MenuItemData\n ): MenuSection[] {\n const groups: MenuSection[] = [];\n let items: MenuItemData[] = [];\n const commit = () => {\n if (items.length > 0) groups.push({ items });\n items = [];\n };\n\n for (const item of source) {\n if (isBarTitleDivider(item)) {\n commit();\n } else {\n items.push(map(item));\n }\n }\n commit();\n return groups;\n }\n\n private get sectionMenuSections(): MenuSection[] {\n return this.groupsFromItems(this.sections, section => ({\n label: section.label,\n value: section.id,\n isSelected: section.id === this.effectiveValue,\n isInactive: section.isInactive,\n }));\n }\n\n private get selectableActions(): BarTitleAction[] {\n return this.actions.filter((item): item is BarTitleAction => !isBarTitleDivider(item));\n }\n\n private get showActionMenuTrigger(): boolean {\n return (\n this.selectableActions.length > 0 || (this.primaryCollapsed && this.primaryAction !== null)\n );\n }\n\n private actionMenuItem(action: BarTitleAction | BarTitlePrimaryAction): MenuItemData {\n const primary = action as BarTitlePrimaryAction;\n return {\n label: action.label,\n value: action.id,\n isInactive: action.isInactive || primary.isLoading,\n isDestructive: action.isDestructive || primary.intent === 'negative',\n };\n }\n\n private get actionMenuSections(): MenuSection[] {\n const groups = this.groupsFromItems(this.actions, action => this.actionMenuItem(action));\n if (!this.primaryCollapsed || !this.primaryAction) return groups;\n return [{ items: [this.actionMenuItem(this.primaryAction)] }, ...groups];\n }\n\n private toggleSectionMenu = (event: MouseEvent) => {\n this.sectionMenuInitialFocusVisible = event.detail === 0;\n this.actionMenuOpen = false;\n this.sectionMenuOpen = !this.sectionMenuOpen;\n };\n\n private closeSectionMenu = () => {\n this.sectionMenuOpen = false;\n };\n\n private handleSectionSelect = (event: CustomEvent<MenuItemData>) => {\n const id = String(event.detail?.value ?? '');\n const selected = this.selectableSections.find(section => section.id === id);\n if (!selected || selected.isInactive) return;\n this.closeSectionMenu();\n this.dsSectionChange.emit(id);\n requestAnimationFrame(() => this.sectionTriggerEl?.focus());\n };\n\n private toggleActionMenu = (event: MouseEvent) => {\n this.actionMenuInitialFocusVisible = event.detail === 0;\n this.sectionMenuOpen = false;\n this.actionMenuOpen = !this.actionMenuOpen;\n };\n\n private closeActionMenu = () => {\n this.actionMenuOpen = false;\n };\n\n private handleActionSelect = (event: CustomEvent<MenuItemData>) => {\n const id = String(event.detail?.value ?? '');\n const primaryMatches = this.primaryCollapsed && this.primaryAction?.id === id;\n const action = this.selectableActions.find(candidate => candidate.id === id);\n if (!primaryMatches && !action) return;\n if (\n (primaryMatches && (this.primaryAction?.isInactive || this.primaryAction?.isLoading)) ||\n action?.isInactive\n ) {\n return;\n }\n this.closeActionMenu();\n this.dsAction.emit(id);\n requestAnimationFrame(() => void this.actionTriggerEl?.setFocus?.());\n };\n\n private renderSectionSelector() {\n if (!this.hasSectionSelector) return null;\n return [\n <div class=\"bar-title__divider\" aria-hidden=\"true\" />,\n <div class=\"bar-title__section-selector\">\n <button\n ref={el => {\n this.sectionTriggerEl = el ?? null;\n }}\n id={this.sectionMenuTriggerId}\n class={{\n 'bar-title__section-trigger': true,\n 'bar-title__section-trigger--expanded': this.sectionMenuOpen,\n 'ds-control--md': true,\n 'ds-focus-ring-inset': true,\n 'ds-interaction-fill': true,\n }}\n type=\"button\"\n aria-haspopup=\"menu\"\n aria-controls={this.sectionMenuId}\n aria-expanded={String(this.sectionMenuOpen)}\n aria-label={this.sectionTriggerAriaLabel}\n onClick={this.toggleSectionMenu}\n >\n <ds-text\n class=\"bar-title__section-label ds-interaction-fill__content\"\n as=\"span\"\n variant=\"text-body-medium\"\n emphasis\n color=\"primary\"\n >\n {this.selectedSectionLabel}\n </ds-text>\n <ds-icon\n class=\"bar-title__section-chevron ds-interaction-fill__content\"\n name=\"ChevronUpDown\"\n size=\"md\"\n color=\"inherit\"\n aria-hidden=\"true\"\n />\n </button>\n </div>,\n ];\n }\n\n private renderActions() {\n const primary = this.primaryAction;\n if (!primary && !this.showActionMenuTrigger) return null;\n\n return (\n <div class=\"bar-title__actions\">\n {primary && !this.primaryCollapsed ? (\n <ds-button-filled\n class=\"bar-title__primary-action\"\n variant={primary.icon ? 'icon-label' : 'label'}\n icon={primary.icon ?? ''}\n label={primary.label}\n intent={primary.intent ?? 'brand'}\n contrast={primary.contrast ?? 'bold'}\n size=\"md\"\n type={primary.type ?? 'button'}\n isInactive={primary.isInactive}\n isLoading={primary.isLoading}\n onDsClick={() => this.dsAction.emit(primary.id)}\n />\n ) : null}\n {this.showActionMenuTrigger ? (\n <ds-tooltip label=\"Page options\" side=\"bottom\" size=\"sm\">\n <ds-button-unfilled\n ref={el => {\n this.actionTriggerEl = el ?? null;\n }}\n id={this.actionMenuTriggerId}\n class=\"bar-title__more-actions\"\n variant=\"icon\"\n icon=\"Ellipses\"\n aria-label={this.actionsAriaLabel}\n size=\"md\"\n activeFill={!this.compact}\n hasBorder={primary !== null && !this.primaryCollapsed}\n haspopup=\"menu\"\n controls={this.actionMenuId}\n expanded={this.actionMenuOpen}\n onDsClick={(event: CustomEvent<MouseEvent>) => this.toggleActionMenu(event.detail)}\n />\n </ds-tooltip>\n ) : null}\n </div>\n );\n }\n\n private handleBreadcrumbSelect = (event: CustomEvent<BreadcrumbSelectDetail>) => {\n if (this.breadcrumbs.length === 0) {\n this.dsBack.emit(event.detail.originalEvent);\n return;\n }\n const forwarded = this.dsBreadcrumbSelect.emit(event.detail);\n if (forwarded.defaultPrevented) event.preventDefault();\n };\n\n private renderBreadcrumb() {\n const items = this.expandedBreadcrumbItems;\n if (items.length === 0) return null;\n return (\n <ds-breadcrumb\n class=\"bar-title__breadcrumb\"\n items={items}\n ariaLabel={this.breadcrumbAriaLabel}\n onDsSelect={this.handleBreadcrumbSelect}\n />\n );\n }\n\n private renderBack() {\n if (!this.showBack) return null;\n return (\n <ds-tooltip label={this.backTooltipLabel} side=\"bottom\" size=\"sm\">\n <ds-button-unfilled\n class=\"bar-title__back\"\n variant=\"icon\"\n icon=\"ChevronLeft\"\n aria-label={this.backAriaLabel}\n size=\"md\"\n activeFill={false}\n hasBorder={false}\n onDsClick={(event: CustomEvent<MouseEvent>) => this.dsBack.emit(event.detail)}\n />\n </ds-tooltip>\n );\n }\n\n render() {\n const compact = this.compact;\n return (\n <Host\n class={{\n 'bar-title-host--compact': compact,\n 'bar-title-host--expanded': this.variant === 'expanded',\n 'bar-title-host--constrained': this.variant === 'constrained',\n 'bar-title-host--has-description': !!this.description,\n 'bar-title-host--has-back': this.showBack,\n 'bar-title-host--has-breadcrumb': !compact && this.expandedBreadcrumbItems.length > 0,\n }}\n >\n <div class=\"bar-title\">\n <div class=\"bar-title__inner\">\n {!compact ? this.renderBreadcrumb() : null}\n <div class=\"bar-title__row\">\n <div class=\"bar-title__leading\">\n <div class=\"bar-title__title-row\" data-shell-page-header-anchor>\n <div class=\"bar-title__identity\">\n {compact ? this.renderBack() : null}\n <ds-text\n class=\"bar-title__heading ds-control--md\"\n variant={compact ? 'text-title-small' : 'text-title-medium'}\n emphasis\n color=\"primary\"\n as=\"h1\"\n lineTruncation={1}\n >\n {this.heading}\n </ds-text>\n </div>\n {this.renderSectionSelector()}\n </div>\n {this.description && !compact ? (\n <ds-text\n class=\"bar-title__description\"\n variant=\"text-body-small\"\n color=\"secondary\"\n lineTruncation={2}\n wrap=\"wrap\"\n as=\"p\"\n >\n {this.description}\n </ds-text>\n ) : null}\n </div>\n {this.renderActions()}\n </div>\n </div>\n </div>\n\n {this.hasSectionSelector ? (\n <ds-menu\n id={this.sectionMenuId}\n class=\"bar-title__section-menu\"\n anchorId={this.sectionMenuTriggerId}\n menuLabel={this.sectionsAriaLabel}\n open={this.sectionMenuOpen}\n initialFocusVisible={this.sectionMenuInitialFocusVisible}\n sections={this.sectionMenuSections}\n onDsClose={this.closeSectionMenu}\n onDsSelect={this.handleSectionSelect}\n />\n ) : null}\n\n {this.showActionMenuTrigger ? (\n <ds-menu\n id={this.actionMenuId}\n class=\"bar-title__action-menu\"\n anchorId={this.actionMenuTriggerId}\n align=\"end\"\n menuLabel={this.actionsAriaLabel}\n open={this.actionMenuOpen}\n initialFocusVisible={this.actionMenuInitialFocusVisible}\n sections={this.actionMenuSections}\n onDsClose={this.closeActionMenu}\n onDsSelect={this.handleActionSelect}\n />\n ) : null}\n </Host>\n );\n }\n}\n",
|
|
428
482
|
"type": "registry:ui"
|
|
429
483
|
},
|
|
430
484
|
{
|