@ds-mo/ui 13.6.0 → 13.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.package-ready.json +1 -1
- package/dist/agent-patterns.json +2 -2
- package/dist/agent.json +109 -371
- package/dist/angular/ds-card-chart.d.ts +18 -0
- package/dist/angular/{ds-card-data-viz.js → ds-card-chart.js} +10 -10
- package/dist/angular/ds-chart.d.ts +19 -0
- package/dist/angular/{ds-chart-donut.js → ds-chart.js} +15 -15
- package/dist/angular/ds-tooltip-chart.d.ts +12 -0
- package/dist/angular/{ds-chart-line.js → ds-tooltip-chart.js} +12 -12
- package/dist/angular/index.d.ts +1 -1
- package/dist/angular/index.js +3 -5
- package/dist/angular/proxies.d.ts +3 -5
- package/dist/angular/proxies.js +3 -5
- 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-banner.js +1 -1
- package/dist/components/ds-banner.js.map +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-workflow.js +1 -1
- package/dist/components/ds-breadcrumb.js +1 -1
- package/dist/components/ds-button-filled.js +1 -1
- package/dist/components/ds-button-unfilled.js +1 -1
- package/dist/components/{ds-chart-line.d.ts → ds-card-chart.d.ts} +4 -4
- package/dist/components/ds-card-chart.js +2 -0
- package/dist/components/ds-card-chart.js.map +1 -0
- package/dist/components/ds-card-overview.js +1 -1
- package/dist/components/ds-card-setting.js +1 -1
- package/dist/components/ds-card-setting.js.map +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-bar.d.ts → ds-chart.d.ts} +4 -4
- package/dist/components/ds-chart.js +2 -0
- package/dist/components/ds-chart.js.map +1 -0
- 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-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-actions.js +1 -1
- package/dist/components/ds-message-bubble.js +1 -1
- package/dist/components/ds-message-composer.js +1 -1
- package/dist/components/ds-message-composer.js.map +1 -1
- package/dist/components/ds-message-scroller.js +1 -1
- package/dist/components/ds-message.js +1 -1
- package/dist/components/ds-mobile-bar-nav.js +1 -1
- package/dist/components/ds-mobile-header.js +1 -1
- package/dist/components/ds-mobile-section-switcher.js +1 -1
- package/dist/components/ds-mobile-sheet-nav.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-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-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.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-page.js +1 -1
- package/dist/components/ds-shell-tools.js +1 -1
- package/dist/components/ds-skeleton.js +1 -1
- package/dist/components/ds-slider.js +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-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-card-data-viz.d.ts → ds-tooltip-chart.d.ts} +4 -4
- package/dist/components/ds-tooltip-chart.js +2 -0
- package/dist/components/ds-tooltip.js +1 -1
- package/dist/components/ds-typing-indicator.js +1 -1
- package/dist/components/{p-IYy-jODg.js → p-1Zbh1MRy.js} +2 -2
- package/dist/components/{p-wOOAzVMC.js → p-BVsLc3t5.js} +2 -2
- package/dist/components/p-BZCUFHYa.js +2 -0
- package/dist/components/{p-D0bM3cKj.js.map → p-BZCUFHYa.js.map} +1 -1
- package/dist/components/{p-BBtjABBS.js → p-BjiRqLtB.js} +2 -2
- package/dist/components/p-Bk1A9jLm.js +2 -0
- package/dist/components/p-Bk1A9jLm.js.map +1 -0
- package/dist/components/{p-Bsfpxto1.js → p-BsBw-w1q.js} +2 -2
- package/dist/components/p-ByfXC1wu.js +2 -0
- package/dist/components/{p-1S9AW2MA.js.map → p-ByfXC1wu.js.map} +1 -1
- package/dist/components/{p-B6RrZQqw.js → p-C-ENnZzq.js} +2 -2
- package/dist/components/{p-BPyymeuR.js → p-C2U48kDH.js} +2 -2
- package/dist/components/{p-CKRJX0Y0.js → p-C7mCjS2t.js} +2 -2
- package/dist/components/{p-6B411hQA.js → p-CL8XL1eh.js} +2 -2
- package/dist/components/{p-DfvDNcoq.js → p-CMZVPEZ_.js} +2 -2
- package/dist/components/{p-BtuYufL3.js → p-CWL61nKt.js} +2 -2
- package/dist/components/p-CWL61nKt.js.map +1 -0
- package/dist/components/p-CWLrXsDQ.js +2 -0
- package/dist/components/{p-D2cjoj2r.js.map → p-CWLrXsDQ.js.map} +1 -1
- package/dist/components/{p-Di81y9Q2.js → p-CX7QIytv.js} +2 -2
- package/dist/components/p-CXduurfd.js +2 -0
- package/dist/components/p-CXduurfd.js.map +1 -0
- package/dist/components/p-CbAfTqlb.js +2 -0
- package/dist/components/{p-CuJ3J6OJ.js.map → p-CbAfTqlb.js.map} +1 -1
- package/dist/components/{p-DVuxzrCC.js → p-CfTThRNX.js} +2 -2
- package/dist/components/{p-BmNpPyzf.js → p-CkLffZGn.js} +2 -2
- package/dist/components/{p-B4_0Ys4w.js → p-CkyXU1YX.js} +2 -2
- package/dist/components/{p-iCjUWcp7.js → p-CywKWfgD.js} +2 -2
- package/dist/components/{p-BR_oMaas.js → p-D3UKwTEo.js} +2 -2
- package/dist/components/{p-Bl6A5AJq.js → p-D7z9bJ6n.js} +2 -2
- package/dist/components/{p-DaqFuVKZ.js → p-DAftUxvL.js} +2 -2
- package/dist/components/{p-BFfHIu6y.js → p-DQ94PkZA.js} +2 -2
- package/dist/components/{p-B-kRByho.js → p-DSpq7xQF.js} +2 -2
- package/dist/components/{p-og48Kh2i.js → p-DzM3TcyQ.js} +2 -2
- package/dist/components/p-GbTasczF.js +2 -0
- package/dist/components/{p-Ca6s5fLR.js → p-Mmr9b1bB.js} +2 -2
- package/dist/components/p-UH2AGfR0.js +2 -0
- package/dist/components/{p-DX4c3kZ1.js.map → p-UH2AGfR0.js.map} +1 -1
- package/dist/components/{p-CxgMUvqg.js → p-Z2zfShlF.js} +2 -2
- package/dist/components/{p-Bmo4T96l.js → p-_mClULFL.js} +2 -2
- package/dist/components/{p-Bb4f5SuF.js → p-jf1zCsuw.js} +2 -2
- package/dist/components/{p-Eep5mxtv.js → p-oiR4IoH1.js} +2 -2
- package/dist/components/{p-DHF5cLzr.js → p-u2OZHaLY.js} +2 -2
- package/dist/docs/components.json +180 -662
- package/dist/lib/utils/chart-grammar.d.ts +359 -0
- package/dist/lib/utils/index.d.ts +2 -0
- package/dist/lib/utils/index.js +504 -0
- package/dist/lib/utils/index.js.map +4 -4
- package/dist/lib/utils/token-defaults.d.ts +3 -0
- package/dist/mcp-data/registry/banner.json +2 -2
- package/dist/mcp-data/registry/card-chart.json +238 -0
- package/dist/mcp-data/registry/card-overview.json +2 -2
- package/dist/mcp-data/registry/card-setting.json +2 -2
- package/dist/mcp-data/registry/chart-legend.json +11 -18
- package/dist/mcp-data/registry/chart.json +258 -0
- package/dist/mcp-data/registry/mobile-bar-nav.json +3 -3
- package/dist/mcp-data/registry/registry.json +108 -376
- package/dist/mcp-data/registry/tooltip-chart.json +253 -0
- package/dist/mcp-data/registry/tooltip.json +2 -2
- package/dist/react/components.d.ts +3 -5
- package/dist/react/components.js +3 -5
- package/dist/react/ds-card-chart.d.ts +12 -0
- package/dist/react/ds-card-chart.js +12 -0
- package/dist/react/ds-chart.d.ts +12 -0
- package/dist/react/ds-chart.js +12 -0
- package/dist/react/{ds-chart-bar.d.ts → ds-tooltip-chart.d.ts} +3 -3
- package/dist/react/ds-tooltip-chart.js +12 -0
- package/dist/types/components/{CardDataViz/CardDataViz.d.ts → CardChart/CardChart.d.ts} +9 -13
- package/dist/types/components/CardChart/index.d.ts +2 -0
- package/dist/types/components/Chart/Chart.d.ts +66 -0
- package/dist/types/components/Chart/index.d.ts +2 -0
- package/dist/types/components/ChartLegend/ChartLegend.d.ts +1 -1
- package/dist/types/components/{TooltipDataViz/TooltipDataViz.d.ts → TooltipChart/TooltipChart.d.ts} +15 -6
- package/dist/types/components/TooltipChart/index.d.ts +2 -0
- package/dist/types/components.d.ts +129 -294
- package/dist/types/utils/chart-grammar.d.ts +360 -0
- package/dist/types/utils/chart-scene.d.ts +128 -0
- package/dist/types/utils/chart-theme.d.ts +27 -0
- package/dist/types/utils/chart-types.d.ts +0 -13
- package/dist/types/utils/index.d.ts +2 -0
- package/dist/types/utils/token-defaults.d.ts +3 -0
- package/package.json +1 -1
- package/dist/angular/ds-card-data-viz.d.ts +0 -18
- package/dist/angular/ds-chart-bar.d.ts +0 -12
- package/dist/angular/ds-chart-bar.js +0 -38
- package/dist/angular/ds-chart-donut.d.ts +0 -19
- package/dist/angular/ds-chart-line.d.ts +0 -12
- package/dist/angular/ds-tooltip-data-viz.d.ts +0 -12
- package/dist/angular/ds-tooltip-data-viz.js +0 -38
- package/dist/components/ds-card-data-viz.js +0 -2
- package/dist/components/ds-card-data-viz.js.map +0 -1
- package/dist/components/ds-chart-bar.js +0 -2
- package/dist/components/ds-chart-bar.js.map +0 -1
- package/dist/components/ds-chart-donut.d.ts +0 -11
- package/dist/components/ds-chart-donut.js +0 -2
- package/dist/components/ds-chart-donut.js.map +0 -1
- package/dist/components/ds-chart-line.js +0 -2
- package/dist/components/ds-chart-line.js.map +0 -1
- package/dist/components/ds-tooltip-data-viz.d.ts +0 -11
- package/dist/components/ds-tooltip-data-viz.js +0 -2
- package/dist/components/p-1S9AW2MA.js +0 -2
- package/dist/components/p-B6Vuayt6.js +0 -2
- package/dist/components/p-B6Vuayt6.js.map +0 -1
- package/dist/components/p-BBpASejH.js +0 -2
- package/dist/components/p-BBpASejH.js.map +0 -1
- package/dist/components/p-BtuYufL3.js.map +0 -1
- package/dist/components/p-BybqPD8K.js +0 -2
- package/dist/components/p-BybqPD8K.js.map +0 -1
- package/dist/components/p-C4uYvyq6.js +0 -2
- package/dist/components/p-C4uYvyq6.js.map +0 -1
- package/dist/components/p-CbjFUpOj.js +0 -2
- package/dist/components/p-CbjFUpOj.js.map +0 -1
- package/dist/components/p-CrCGIx8s.js +0 -2
- package/dist/components/p-CrCGIx8s.js.map +0 -1
- package/dist/components/p-CuJ3J6OJ.js +0 -2
- package/dist/components/p-D0bM3cKj.js +0 -2
- package/dist/components/p-D2cjoj2r.js +0 -2
- package/dist/components/p-DX4c3kZ1.js +0 -2
- package/dist/components/p-DXewjzkM.js +0 -2
- package/dist/components/p-DXewjzkM.js.map +0 -1
- package/dist/components/p-yhj1lIPx.js +0 -2
- package/dist/mcp-data/registry/card-data-viz.json +0 -241
- package/dist/mcp-data/registry/chart-bar.json +0 -245
- package/dist/mcp-data/registry/chart-donut.json +0 -344
- package/dist/mcp-data/registry/chart-line.json +0 -223
- package/dist/mcp-data/registry/tooltip-data-viz.json +0 -224
- package/dist/react/ds-card-data-viz.d.ts +0 -12
- package/dist/react/ds-card-data-viz.js +0 -12
- package/dist/react/ds-chart-bar.js +0 -12
- package/dist/react/ds-chart-donut.d.ts +0 -12
- package/dist/react/ds-chart-donut.js +0 -12
- package/dist/react/ds-chart-line.d.ts +0 -9
- package/dist/react/ds-chart-line.js +0 -12
- package/dist/react/ds-tooltip-data-viz.d.ts +0 -9
- package/dist/react/ds-tooltip-data-viz.js +0 -12
- package/dist/types/components/CardDataViz/index.d.ts +0 -2
- package/dist/types/components/ChartBar/ChartBar.d.ts +0 -31
- package/dist/types/components/ChartBar/index.d.ts +0 -3
- package/dist/types/components/ChartDonut/ChartDonut.d.ts +0 -72
- package/dist/types/components/ChartDonut/index.d.ts +0 -2
- package/dist/types/components/ChartLine/ChartLine.d.ts +0 -23
- package/dist/types/components/ChartLine/index.d.ts +0 -2
- package/dist/types/components/TooltipDataViz/index.d.ts +0 -2
- /package/dist/components/{ds-tooltip-data-viz.js.map → ds-tooltip-chart.js.map} +0 -0
- /package/dist/components/{p-IYy-jODg.js.map → p-1Zbh1MRy.js.map} +0 -0
- /package/dist/components/{p-wOOAzVMC.js.map → p-BVsLc3t5.js.map} +0 -0
- /package/dist/components/{p-BBtjABBS.js.map → p-BjiRqLtB.js.map} +0 -0
- /package/dist/components/{p-Bsfpxto1.js.map → p-BsBw-w1q.js.map} +0 -0
- /package/dist/components/{p-B6RrZQqw.js.map → p-C-ENnZzq.js.map} +0 -0
- /package/dist/components/{p-BPyymeuR.js.map → p-C2U48kDH.js.map} +0 -0
- /package/dist/components/{p-CKRJX0Y0.js.map → p-C7mCjS2t.js.map} +0 -0
- /package/dist/components/{p-6B411hQA.js.map → p-CL8XL1eh.js.map} +0 -0
- /package/dist/components/{p-DfvDNcoq.js.map → p-CMZVPEZ_.js.map} +0 -0
- /package/dist/components/{p-Di81y9Q2.js.map → p-CX7QIytv.js.map} +0 -0
- /package/dist/components/{p-DVuxzrCC.js.map → p-CfTThRNX.js.map} +0 -0
- /package/dist/components/{p-BmNpPyzf.js.map → p-CkLffZGn.js.map} +0 -0
- /package/dist/components/{p-B4_0Ys4w.js.map → p-CkyXU1YX.js.map} +0 -0
- /package/dist/components/{p-iCjUWcp7.js.map → p-CywKWfgD.js.map} +0 -0
- /package/dist/components/{p-BR_oMaas.js.map → p-D3UKwTEo.js.map} +0 -0
- /package/dist/components/{p-Bl6A5AJq.js.map → p-D7z9bJ6n.js.map} +0 -0
- /package/dist/components/{p-DaqFuVKZ.js.map → p-DAftUxvL.js.map} +0 -0
- /package/dist/components/{p-BFfHIu6y.js.map → p-DQ94PkZA.js.map} +0 -0
- /package/dist/components/{p-B-kRByho.js.map → p-DSpq7xQF.js.map} +0 -0
- /package/dist/components/{p-og48Kh2i.js.map → p-DzM3TcyQ.js.map} +0 -0
- /package/dist/components/{p-yhj1lIPx.js.map → p-GbTasczF.js.map} +0 -0
- /package/dist/components/{p-Ca6s5fLR.js.map → p-Mmr9b1bB.js.map} +0 -0
- /package/dist/components/{p-CxgMUvqg.js.map → p-Z2zfShlF.js.map} +0 -0
- /package/dist/components/{p-Bmo4T96l.js.map → p-_mClULFL.js.map} +0 -0
- /package/dist/components/{p-Bb4f5SuF.js.map → p-jf1zCsuw.js.map} +0 -0
- /package/dist/components/{p-Eep5mxtv.js.map → p-oiR4IoH1.js.map} +0 -0
- /package/dist/components/{p-DHF5cLzr.js.map → p-u2OZHaLY.js.map} +0 -0
|
@@ -1,241 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
-
"name": "card-data-viz",
|
|
4
|
-
"title": "CardDataViz",
|
|
5
|
-
"description": "Standard data-visualization card chrome with variant-owned chart and legend composition.",
|
|
6
|
-
"type": "registry:ui",
|
|
7
|
-
"meta": {
|
|
8
|
-
"library": "@ds-mo/ui",
|
|
9
|
-
"distribution": "npm",
|
|
10
|
-
"storybook": "https://zainadeel.github.io/compomo/?path=/story/card-data-viz",
|
|
11
|
-
"source": "src/wc/components/CardDataViz/CardDataViz.tsx",
|
|
12
|
-
"intentStatus": "complete",
|
|
13
|
-
"intent": {
|
|
14
|
-
"audience": "specialized",
|
|
15
|
-
"status": "experimental",
|
|
16
|
-
"summary": "Standard data-visualization card chrome with variant-owned chart and legend composition.",
|
|
17
|
-
"useWhen": [
|
|
18
|
-
"A chart, legend, metric visualization, or custom data-viz composition needs standard card chrome.",
|
|
19
|
-
"Bar and line legends should remain static, or a donut and legend should cross-highlight without redundant donut tooltips.",
|
|
20
|
-
"A data-viz card needs a visible heading, optional filter action, and application-owned chart data."
|
|
21
|
-
],
|
|
22
|
-
"avoidWhen": [
|
|
23
|
-
"The card contains editable settings; use CardSetting.",
|
|
24
|
-
"The surface contains ordinary non-visualization content.",
|
|
25
|
-
"The application needs to replace the card chrome rather than compose its chart and actions."
|
|
26
|
-
],
|
|
27
|
-
"alternatives": [
|
|
28
|
-
{
|
|
29
|
-
"when": "The surface contains editable settings.",
|
|
30
|
-
"component": "component:ds-card-setting",
|
|
31
|
-
"reason": "CardSetting owns the controlled settings-section workflow."
|
|
32
|
-
}
|
|
33
|
-
],
|
|
34
|
-
"commonlyComposedWith": [
|
|
35
|
-
"component:ds-chart-bar",
|
|
36
|
-
"component:ds-chart-donut",
|
|
37
|
-
"component:ds-chart-line",
|
|
38
|
-
"component:ds-chart-legend",
|
|
39
|
-
"component:ds-button-unfilled"
|
|
40
|
-
],
|
|
41
|
-
"accessibility": [
|
|
42
|
-
"Provide a concise visible heading; the component renders it as a section heading.",
|
|
43
|
-
"Slotted actions must provide accessible names and controlled-state semantics.",
|
|
44
|
-
"Charts retain their own image names and data summaries.",
|
|
45
|
-
"A visible donut legend owns persistent labels and values, so donut mode suppresses the redundant slice tooltip."
|
|
46
|
-
],
|
|
47
|
-
"states": [
|
|
48
|
-
"Custom mode provides flexible body chrome and does not mutate chart or legend interaction.",
|
|
49
|
-
"Bar and line modes keep a slotted legend static by disabling hover emphasis.",
|
|
50
|
-
"Donut mode synchronizes active labels between chart and legend and shows chart tooltips only when no legend is present.",
|
|
51
|
-
"showFilter adds the standard filter action and emits dsFilterClick without owning filter state."
|
|
52
|
-
],
|
|
53
|
-
"responsiveBehavior": [
|
|
54
|
-
"The sm, md, or lg width sets a matching token-based minimum height and remains constrained by its parent.",
|
|
55
|
-
"The body allocates remaining height to the chart while legends retain content height.",
|
|
56
|
-
"Parent layouts own wrapping, stacking, and breakpoint-dependent card width."
|
|
57
|
-
],
|
|
58
|
-
"frameworkCaveats": {
|
|
59
|
-
"customElements": [
|
|
60
|
-
"Set variant to bar, line, or donut when the component should manage legend interaction; slot chart, legend, actions, and supporting content by name."
|
|
61
|
-
],
|
|
62
|
-
"react": [
|
|
63
|
-
"Keep chart data in React and pass chart, legend, and action elements through named slots."
|
|
64
|
-
],
|
|
65
|
-
"angular": [
|
|
66
|
-
"Keep chart data in Angular and project chart, legend, and action elements through named slots."
|
|
67
|
-
]
|
|
68
|
-
},
|
|
69
|
-
"references": [
|
|
70
|
-
{
|
|
71
|
-
"label": "Storybook examples",
|
|
72
|
-
"path": "src/wc/components/CardDataViz/CardDataViz.stories.ts"
|
|
73
|
-
}
|
|
74
|
-
]
|
|
75
|
-
},
|
|
76
|
-
"api": {
|
|
77
|
-
"props": {
|
|
78
|
-
"cardWidth": {
|
|
79
|
-
"type": "CardDataVizWidth",
|
|
80
|
-
"resolvedType": "\"lg\" | \"md\" | \"sm\"",
|
|
81
|
-
"attribute": "card-width",
|
|
82
|
-
"default": "'md'",
|
|
83
|
-
"required": false,
|
|
84
|
-
"mutable": false,
|
|
85
|
-
"description": "Width token with the matching data-visualization card min-height."
|
|
86
|
-
},
|
|
87
|
-
"filterLabel": {
|
|
88
|
-
"type": "string",
|
|
89
|
-
"resolvedType": "string",
|
|
90
|
-
"attribute": "filter-label",
|
|
91
|
-
"default": "'Filter'",
|
|
92
|
-
"required": false,
|
|
93
|
-
"mutable": false
|
|
94
|
-
},
|
|
95
|
-
"heading": {
|
|
96
|
-
"type": "string",
|
|
97
|
-
"resolvedType": "string",
|
|
98
|
-
"attribute": "heading",
|
|
99
|
-
"required": true,
|
|
100
|
-
"mutable": false,
|
|
101
|
-
"description": "Data-visualization heading shown in the card header."
|
|
102
|
-
},
|
|
103
|
-
"showFilter": {
|
|
104
|
-
"type": "boolean",
|
|
105
|
-
"resolvedType": "boolean",
|
|
106
|
-
"attribute": "show-filter",
|
|
107
|
-
"default": "false",
|
|
108
|
-
"required": false,
|
|
109
|
-
"mutable": false,
|
|
110
|
-
"description": "Renders the standard filter action before custom actions."
|
|
111
|
-
},
|
|
112
|
-
"variant": {
|
|
113
|
-
"type": "CardDataVizVariant",
|
|
114
|
-
"resolvedType": "\"bar\" | \"custom\" | \"donut\" | \"line\"",
|
|
115
|
-
"attribute": "variant",
|
|
116
|
-
"default": "'custom'",
|
|
117
|
-
"required": false,
|
|
118
|
-
"mutable": false,
|
|
119
|
-
"description": "Chart composition behavior."
|
|
120
|
-
}
|
|
121
|
-
},
|
|
122
|
-
"events": [
|
|
123
|
-
{
|
|
124
|
-
"name": "dsFilterClick",
|
|
125
|
-
"detail": "void",
|
|
126
|
-
"bubbles": true,
|
|
127
|
-
"cancelable": true,
|
|
128
|
-
"composed": true,
|
|
129
|
-
"description": "Emits when the standard header filter control is activated."
|
|
130
|
-
}
|
|
131
|
-
],
|
|
132
|
-
"methods": [],
|
|
133
|
-
"slots": []
|
|
134
|
-
},
|
|
135
|
-
"props": {
|
|
136
|
-
"cardWidth": {
|
|
137
|
-
"type": "CardDataVizWidth",
|
|
138
|
-
"resolvedType": "\"lg\" | \"md\" | \"sm\"",
|
|
139
|
-
"attribute": "card-width",
|
|
140
|
-
"default": "'md'",
|
|
141
|
-
"required": false,
|
|
142
|
-
"mutable": false,
|
|
143
|
-
"description": "Width token with the matching data-visualization card min-height."
|
|
144
|
-
},
|
|
145
|
-
"filterLabel": {
|
|
146
|
-
"type": "string",
|
|
147
|
-
"resolvedType": "string",
|
|
148
|
-
"attribute": "filter-label",
|
|
149
|
-
"default": "'Filter'",
|
|
150
|
-
"required": false,
|
|
151
|
-
"mutable": false
|
|
152
|
-
},
|
|
153
|
-
"heading": {
|
|
154
|
-
"type": "string",
|
|
155
|
-
"resolvedType": "string",
|
|
156
|
-
"attribute": "heading",
|
|
157
|
-
"required": true,
|
|
158
|
-
"mutable": false,
|
|
159
|
-
"description": "Data-visualization heading shown in the card header."
|
|
160
|
-
},
|
|
161
|
-
"showFilter": {
|
|
162
|
-
"type": "boolean",
|
|
163
|
-
"resolvedType": "boolean",
|
|
164
|
-
"attribute": "show-filter",
|
|
165
|
-
"default": "false",
|
|
166
|
-
"required": false,
|
|
167
|
-
"mutable": false,
|
|
168
|
-
"description": "Renders the standard filter action before custom actions."
|
|
169
|
-
},
|
|
170
|
-
"variant": {
|
|
171
|
-
"type": "CardDataVizVariant",
|
|
172
|
-
"resolvedType": "\"bar\" | \"custom\" | \"donut\" | \"line\"",
|
|
173
|
-
"attribute": "variant",
|
|
174
|
-
"default": "'custom'",
|
|
175
|
-
"required": false,
|
|
176
|
-
"mutable": false,
|
|
177
|
-
"description": "Chart composition behavior."
|
|
178
|
-
}
|
|
179
|
-
},
|
|
180
|
-
"events": [
|
|
181
|
-
{
|
|
182
|
-
"name": "dsFilterClick",
|
|
183
|
-
"detail": "void",
|
|
184
|
-
"bubbles": true,
|
|
185
|
-
"cancelable": true,
|
|
186
|
-
"composed": true,
|
|
187
|
-
"description": "Emits when the standard header filter control is activated."
|
|
188
|
-
}
|
|
189
|
-
],
|
|
190
|
-
"methods": [],
|
|
191
|
-
"slots": [],
|
|
192
|
-
"exports": {
|
|
193
|
-
"customElement": "ds-card-data-viz",
|
|
194
|
-
"react": "DsCardDataViz",
|
|
195
|
-
"angular": "DsCardDataViz"
|
|
196
|
-
},
|
|
197
|
-
"consumption": {
|
|
198
|
-
"install": "npm install @ds-mo/ui @ds-mo/tokens @ds-mo/icons",
|
|
199
|
-
"cssSetup": "import '@ds-mo/tokens';\nimport '@ds-mo/tokens/reset';\nimport '@ds-mo/tokens/globals';",
|
|
200
|
-
"customElements": {
|
|
201
|
-
"import": "import '@ds-mo/ui/dist/components/ds-card-data-viz.js';",
|
|
202
|
-
"example": "<ds-card-data-viz></ds-card-data-viz>"
|
|
203
|
-
},
|
|
204
|
-
"react": {
|
|
205
|
-
"import": "import { DsCardDataViz } from '@ds-mo/ui/react';",
|
|
206
|
-
"example": "<DsCardDataViz />"
|
|
207
|
-
},
|
|
208
|
-
"angular": {
|
|
209
|
-
"import": "import { DsCardDataViz } from '@ds-mo/ui/angular/ds-card-data-viz';",
|
|
210
|
-
"example": "<ds-card-data-viz></ds-card-data-viz>"
|
|
211
|
-
},
|
|
212
|
-
"peerDependencies": {
|
|
213
|
-
"required": [
|
|
214
|
-
"@ds-mo/tokens ^5.1.1",
|
|
215
|
-
"@ds-mo/icons ^6.4.0"
|
|
216
|
-
],
|
|
217
|
-
"frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
},
|
|
221
|
-
"dependencies": [
|
|
222
|
-
"@ds-mo/ui",
|
|
223
|
-
"@ds-mo/tokens"
|
|
224
|
-
],
|
|
225
|
-
"registryDependencies": [
|
|
226
|
-
"button-unfilled",
|
|
227
|
-
"text"
|
|
228
|
-
],
|
|
229
|
-
"files": [
|
|
230
|
-
{
|
|
231
|
-
"path": "src/wc/components/CardDataViz/CardDataViz.css",
|
|
232
|
-
"content": "@import '../../utils/chrome-layout.css';\n@import '../../utils/forced-colors.css';\n\n:host {\n display: flex;\n flex-direction: column;\n box-sizing: border-box;\n width: var(--_card-data-viz-width);\n min-height: var(--_card-data-viz-min-height);\n max-width: 100%;\n overflow: hidden;\n border: none;\n border-radius: var(--dimension-radius-025);\n background-color: var(--color-background-primary);\n box-shadow: 0 0 0 var(--dimension-stroke-width-012) var(--color-border-tertiary);\n}\n\n.card-data-viz__header {\n flex-shrink: 0;\n justify-content: space-between;\n height: var(--dimension-size-600);\n border-bottom: var(--dimension-stroke-width-012) solid var(--color-border-tertiary);\n background-color: var(--color-background-secondary);\n}\n\nds-text.card-data-viz__title {\n display: flex;\n flex: 1 1 auto;\n align-items: center;\n box-sizing: border-box;\n min-width: 0;\n padding: calc(var(--dimension-space-075) + var(--dimension-space-025));\n -webkit-user-select: none;\n user-select: none;\n}\n\n.card-data-viz__actions {\n display: flex;\n flex-shrink: 0;\n align-items: center;\n gap: var(--dimension-space-100);\n}\n\n.card-data-viz__actions:empty {\n display: none;\n}\n\n.card-data-viz__body,\n.card-data-viz__layout {\n display: flex;\n flex: 1 1 auto;\n flex-direction: column;\n box-sizing: border-box;\n min-height: 0;\n}\n\n.card-data-viz__body {\n border-radius: 0 0 var(--dimension-radius-025) var(--dimension-radius-025);\n background-color: var(--color-background-primary);\n}\n\n.card-data-viz__layout {\n height: 100%;\n gap: var(--dimension-space-200);\n}\n\n.card-data-viz__chart {\n display: grid;\n flex: 1 1 auto;\n align-items: center;\n box-sizing: border-box;\n min-height: 0;\n padding: var(--dimension-space-400) var(--dimension-space-400) 0\n var(--dimension-space-400);\n}\n\n.card-data-viz__chart > * {\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n max-width: 100%;\n max-height: 100%;\n}\n\n.card-data-viz__chart--fill > * {\n height: 100%;\n min-height: 0;\n max-height: 100%;\n}\n\n.card-data-viz__legend {\n flex: 0 0 auto;\n box-sizing: border-box;\n padding: 0 var(--dimension-space-100) var(--dimension-space-100)\n var(--dimension-space-100);\n}\n\n@media (forced-colors: active) {\n :host {\n box-shadow: none;\n outline: var(--dimension-stroke-width-012) solid var(--ds-forced-color-content);\n outline-offset: calc(-1 * var(--dimension-stroke-width-012));\n }\n}\n",
|
|
233
|
-
"type": "registry:ui"
|
|
234
|
-
},
|
|
235
|
-
{
|
|
236
|
-
"path": "src/wc/components/CardDataViz/CardDataViz.tsx",
|
|
237
|
-
"content": "import {\n Component,\n Element,\n Event,\n EventEmitter,\n h,\n Host,\n Prop,\n State,\n} from '@stencil/core';\n\nexport type CardDataVizWidth = 'sm' | 'md' | 'lg';\nexport type CardDataVizVariant = 'custom' | 'bar' | 'line' | 'donut';\n\ntype HoveredDatum = { label: string } | null;\n\ntype ChartSlot = HTMLElement & {\n activeLabel?: string | null;\n showTooltip?: boolean;\n};\n\ntype LegendSlot = HTMLElement & {\n activeLabel?: string | null;\n highlightOnHover?: boolean;\n};\n\nconst CARD_WIDTH_VARS: Record<CardDataVizWidth, string> = {\n sm: 'var(--dimension-card-width-sm)',\n md: 'var(--dimension-card-width-md)',\n lg: 'var(--dimension-card-width-lg)',\n};\n\nconst CARD_HEIGHT_VARS: Record<CardDataVizWidth, string> = {\n sm: 'var(--dimension-card-height-sm)',\n md: 'var(--dimension-card-height-md)',\n lg: 'var(--dimension-card-height-lg)',\n};\n\n/**\n * Standard data-visualization card chrome and composition. The variant owns\n * only the chart/legend relationship; applications continue to own data.\n */\n@Component({\n tag: 'ds-card-data-viz',\n styleUrl: 'CardDataViz.css',\n scoped: true,\n})\nexport class CardDataViz {\n @Element() el!: HTMLElement;\n\n /** Data-visualization heading shown in the card header. */\n @Prop() heading!: string;\n /** Chart composition behavior. */\n @Prop() variant: CardDataVizVariant = 'custom';\n /** Width token with the matching data-visualization card min-height. */\n @Prop() cardWidth: CardDataVizWidth = 'md';\n /** Renders the standard filter action before custom actions. */\n @Prop() showFilter: boolean = false;\n @Prop() filterLabel: string = 'Filter';\n\n /** Emits when the standard header filter control is activated. */\n @Event() dsFilterClick!: EventEmitter<void>;\n\n @State() private hasChartSlot = false;\n @State() private hasLegendSlot = false;\n\n componentWillRender() {\n this.hasChartSlot = !!this.el.querySelector('[slot=\"chart\"]');\n this.hasLegendSlot = !!this.el.querySelector('[slot=\"legend\"]');\n }\n\n componentDidLoad() {\n this.el.addEventListener('dsSliceHover', this.handleChartHover);\n this.el.addEventListener('dsItemHover', this.handleLegendHover);\n }\n\n componentDidRender() {\n const chart = this.el.querySelector('[slot=\"chart\"]') as ChartSlot | null;\n const legend = this.el.querySelector(\n 'ds-chart-legend[slot=\"legend\"]'\n ) as LegendSlot | null;\n\n if (this.variant === 'donut') {\n if (chart && 'showTooltip' in chart) {\n chart.showTooltip = !this.hasLegendSlot;\n }\n return;\n }\n\n if (\n (this.variant === 'bar' || this.variant === 'line') &&\n legend\n ) {\n legend.setAttribute('highlight-on-hover', 'false');\n if ('highlightOnHover' in legend) legend.highlightOnHover = false;\n }\n }\n\n disconnectedCallback() {\n this.el.removeEventListener('dsSliceHover', this.handleChartHover);\n this.el.removeEventListener('dsItemHover', this.handleLegendHover);\n }\n\n private handleChartHover = (event: Event) => {\n if (this.variant !== 'donut') return;\n const legend = this.el.querySelector('[slot=\"legend\"]') as LegendSlot | null;\n if (!legend || !('activeLabel' in legend)) return;\n legend.activeLabel =\n (event as CustomEvent<HoveredDatum>).detail?.label ?? null;\n };\n\n private handleLegendHover = (event: Event) => {\n if (this.variant !== 'donut') return;\n const chart = this.el.querySelector('[slot=\"chart\"]') as ChartSlot | null;\n if (!chart || !('activeLabel' in chart)) return;\n chart.activeLabel =\n (event as CustomEvent<HoveredDatum>).detail?.label ?? null;\n };\n\n private handleFilterClick = () => {\n this.dsFilterClick.emit();\n };\n\n render() {\n const usesChartLayout = this.variant !== 'custom' || this.hasChartSlot;\n return (\n <Host\n class={{\n 'card-data-viz': true,\n [`card-data-viz--${this.variant}`]: true,\n }}\n style={{\n '--_card-data-viz-width': CARD_WIDTH_VARS[this.cardWidth],\n '--_card-data-viz-min-height': CARD_HEIGHT_VARS[this.cardWidth],\n }}\n >\n <header class=\"card-data-viz__header ds-chrome-row ds-chrome-space--md\">\n <ds-text\n class=\"card-data-viz__title\"\n variant=\"text-title-small\"\n emphasis\n color=\"primary\"\n as=\"h2\"\n >\n {this.heading}\n </ds-text>\n <div class=\"card-data-viz__actions\">\n {this.showFilter ? (\n <ds-button-unfilled\n variant=\"icon\"\n type=\"button\"\n icon=\"Filters\"\n aria-label={this.filterLabel}\n onDsClick={this.handleFilterClick}\n />\n ) : null}\n <slot name=\"actions\" />\n </div>\n </header>\n <div class=\"card-data-viz__body\">\n {usesChartLayout ? (\n <div class=\"card-data-viz__layout\">\n {this.hasChartSlot ? (\n <div\n class={{\n 'card-data-viz__chart': true,\n 'card-data-viz__chart--fill': this.variant === 'donut',\n }}\n >\n <slot name=\"chart\" />\n </div>\n ) : null}\n {this.hasLegendSlot ? (\n <div class=\"card-data-viz__legend\">\n <slot name=\"legend\" />\n </div>\n ) : null}\n <slot />\n </div>\n ) : (\n <slot />\n )}\n </div>\n </Host>\n );\n }\n}\n",
|
|
238
|
-
"type": "registry:ui"
|
|
239
|
-
}
|
|
240
|
-
]
|
|
241
|
-
}
|
|
@@ -1,245 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
-
"name": "chart-bar",
|
|
4
|
-
"title": "ChartBar",
|
|
5
|
-
"description": "Bar chart for single-series magnitude, additive stacked totals, or normalized 0–100% composition across categories.",
|
|
6
|
-
"type": "registry:ui",
|
|
7
|
-
"meta": {
|
|
8
|
-
"library": "@ds-mo/ui",
|
|
9
|
-
"distribution": "npm",
|
|
10
|
-
"storybook": "https://zainadeel.github.io/compomo/?path=/story/chart-bar",
|
|
11
|
-
"source": "src/wc/components/ChartBar/ChartBar.tsx",
|
|
12
|
-
"intentStatus": "complete",
|
|
13
|
-
"intent": {
|
|
14
|
-
"audience": "specialized",
|
|
15
|
-
"status": "experimental",
|
|
16
|
-
"summary": "Bar chart for single-series magnitude, additive stacked totals, or normalized 0–100% composition across categories.",
|
|
17
|
-
"useWhen": [
|
|
18
|
-
"Users need to compare one numeric measure across a small set of categories.",
|
|
19
|
-
"Values are grouped into ordered time buckets such as hours, days, weeks, or months and equal visual spacing is appropriate.",
|
|
20
|
-
"A data-viz card needs a compact magnitude comparison rather than a continuous trend.",
|
|
21
|
-
"Several consistent series contribute to each category total or its normalized composition."
|
|
22
|
-
],
|
|
23
|
-
"avoidWhen": [
|
|
24
|
-
"Timestamp positions must reflect irregular elapsed time; pre-bucket the data or use a future continuous time-scale chart.",
|
|
25
|
-
"The visualization needs grouped bars or precise comparison of each individual series across categories.",
|
|
26
|
-
"The interaction requires selection, drill-down, brushing, or zoom.",
|
|
27
|
-
"The data communicates a part-to-whole relationship."
|
|
28
|
-
],
|
|
29
|
-
"alternatives": [
|
|
30
|
-
{
|
|
31
|
-
"when": "Users need to follow one or more trends across ordered categories.",
|
|
32
|
-
"component": "component:ds-chart-line",
|
|
33
|
-
"reason": "ChartLine connects ordered observations and supports multiple named series."
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
"when": "The data communicates parts of a total.",
|
|
37
|
-
"component": "component:ds-chart-donut",
|
|
38
|
-
"reason": "ChartDonut provides the part-to-whole composition and center aggregate."
|
|
39
|
-
}
|
|
40
|
-
],
|
|
41
|
-
"commonlyComposedWith": [
|
|
42
|
-
"component:ds-chart-legend",
|
|
43
|
-
"component:ds-card-data-viz",
|
|
44
|
-
"component:ds-tooltip-data-viz"
|
|
45
|
-
],
|
|
46
|
-
"accessibility": [
|
|
47
|
-
"Keep category labels concise and provide an adjacent textual summary when exact values are critical to completing a task.",
|
|
48
|
-
"Do not rely on bar color alone to communicate category meaning.",
|
|
49
|
-
"A future interactive tooltip must supplement rather than replace the chart's accessible value representation."
|
|
50
|
-
],
|
|
51
|
-
"states": [
|
|
52
|
-
"The chart is static without hover, selection, loading, or empty-state policy.",
|
|
53
|
-
"Single mode reads data. Stacked and percentage modes read aligned series and categories.",
|
|
54
|
-
"Stacked mode preserves raw totals; percentage mode normalizes every non-empty category to 100%.",
|
|
55
|
-
"An empty dataset renders no bars; the owning card or product supplies meaningful empty-state messaging.",
|
|
56
|
-
"Bars use 2px top corner radii while the lower corners touching the zero axis remain square.",
|
|
57
|
-
"Use one consistent bar color across time buckets when every bar is the same measure at a different interval; categorical color changes are for genuinely distinct categories.",
|
|
58
|
-
"Authored datum colors override the shared categorical palette."
|
|
59
|
-
],
|
|
60
|
-
"responsiveBehavior": [
|
|
61
|
-
"Width and height provide the standalone intrinsic viewport; container constraints are measured and reflow the plot across the available pixels.",
|
|
62
|
-
"Responsive layout changes bar positions and plot extents without scaling SVG text, strokes, corner radii, or margins.",
|
|
63
|
-
"Limit or pre-format long category labels so they remain legible at the chosen width.",
|
|
64
|
-
"Time labels remain ordered, pre-formatted buckets with equal spacing rather than raw continuous timestamps."
|
|
65
|
-
],
|
|
66
|
-
"frameworkCaveats": {
|
|
67
|
-
"customElements": [
|
|
68
|
-
"Assign data, series, and categories as JavaScript properties; arrays are not supported as HTML attributes."
|
|
69
|
-
],
|
|
70
|
-
"react": [
|
|
71
|
-
"Pass stable data or series/category arrays; width and height provide standalone intrinsic dimensions while constrained containers reflow automatically."
|
|
72
|
-
],
|
|
73
|
-
"angular": [
|
|
74
|
-
"Bind data or series/categories as properties; width and height provide standalone intrinsic dimensions while constrained containers reflow automatically."
|
|
75
|
-
]
|
|
76
|
-
},
|
|
77
|
-
"references": [
|
|
78
|
-
{
|
|
79
|
-
"label": "Storybook examples",
|
|
80
|
-
"path": "src/wc/components/ChartBar/ChartBar.stories.ts"
|
|
81
|
-
}
|
|
82
|
-
]
|
|
83
|
-
},
|
|
84
|
-
"api": {
|
|
85
|
-
"props": {
|
|
86
|
-
"categories": {
|
|
87
|
-
"type": "string[]",
|
|
88
|
-
"resolvedType": "string[]",
|
|
89
|
-
"default": "[]",
|
|
90
|
-
"required": false,
|
|
91
|
-
"mutable": false,
|
|
92
|
-
"description": "X-axis labels for stacked and percentage variants. Set as a JS property."
|
|
93
|
-
},
|
|
94
|
-
"data": {
|
|
95
|
-
"type": "ChartDatum[]",
|
|
96
|
-
"resolvedType": "ChartDatum[]",
|
|
97
|
-
"default": "[]",
|
|
98
|
-
"required": false,
|
|
99
|
-
"mutable": false,
|
|
100
|
-
"description": "Bars to render. Set as a JS property (not an HTML attribute)."
|
|
101
|
-
},
|
|
102
|
-
"height": {
|
|
103
|
-
"type": "number",
|
|
104
|
-
"resolvedType": "number",
|
|
105
|
-
"attribute": "height",
|
|
106
|
-
"default": "240",
|
|
107
|
-
"required": false,
|
|
108
|
-
"mutable": false,
|
|
109
|
-
"description": "Standalone intrinsic height. Container constraints reflow the plot at rendered pixel size."
|
|
110
|
-
},
|
|
111
|
-
"series": {
|
|
112
|
-
"type": "ChartSeries[]",
|
|
113
|
-
"resolvedType": "ChartSeries[]",
|
|
114
|
-
"default": "[]",
|
|
115
|
-
"required": false,
|
|
116
|
-
"mutable": false,
|
|
117
|
-
"description": "Ordered stack series for stacked and percentage variants. Set as a JS property."
|
|
118
|
-
},
|
|
119
|
-
"variant": {
|
|
120
|
-
"type": "ChartBarVariant",
|
|
121
|
-
"resolvedType": "\"percentage\" | \"single\" | \"stacked\"",
|
|
122
|
-
"attribute": "variant",
|
|
123
|
-
"default": "'single'",
|
|
124
|
-
"required": false,
|
|
125
|
-
"mutable": false,
|
|
126
|
-
"description": "Rendering model. Single uses `data`; stacked and percentage use `series` and `categories`."
|
|
127
|
-
},
|
|
128
|
-
"width": {
|
|
129
|
-
"type": "number",
|
|
130
|
-
"resolvedType": "number",
|
|
131
|
-
"attribute": "width",
|
|
132
|
-
"default": "480",
|
|
133
|
-
"required": false,
|
|
134
|
-
"mutable": false,
|
|
135
|
-
"description": "Standalone intrinsic width. Container constraints reflow the plot at rendered pixel size."
|
|
136
|
-
}
|
|
137
|
-
},
|
|
138
|
-
"events": [],
|
|
139
|
-
"methods": [],
|
|
140
|
-
"slots": []
|
|
141
|
-
},
|
|
142
|
-
"props": {
|
|
143
|
-
"categories": {
|
|
144
|
-
"type": "string[]",
|
|
145
|
-
"resolvedType": "string[]",
|
|
146
|
-
"default": "[]",
|
|
147
|
-
"required": false,
|
|
148
|
-
"mutable": false,
|
|
149
|
-
"description": "X-axis labels for stacked and percentage variants. Set as a JS property."
|
|
150
|
-
},
|
|
151
|
-
"data": {
|
|
152
|
-
"type": "ChartDatum[]",
|
|
153
|
-
"resolvedType": "ChartDatum[]",
|
|
154
|
-
"default": "[]",
|
|
155
|
-
"required": false,
|
|
156
|
-
"mutable": false,
|
|
157
|
-
"description": "Bars to render. Set as a JS property (not an HTML attribute)."
|
|
158
|
-
},
|
|
159
|
-
"height": {
|
|
160
|
-
"type": "number",
|
|
161
|
-
"resolvedType": "number",
|
|
162
|
-
"attribute": "height",
|
|
163
|
-
"default": "240",
|
|
164
|
-
"required": false,
|
|
165
|
-
"mutable": false,
|
|
166
|
-
"description": "Standalone intrinsic height. Container constraints reflow the plot at rendered pixel size."
|
|
167
|
-
},
|
|
168
|
-
"series": {
|
|
169
|
-
"type": "ChartSeries[]",
|
|
170
|
-
"resolvedType": "ChartSeries[]",
|
|
171
|
-
"default": "[]",
|
|
172
|
-
"required": false,
|
|
173
|
-
"mutable": false,
|
|
174
|
-
"description": "Ordered stack series for stacked and percentage variants. Set as a JS property."
|
|
175
|
-
},
|
|
176
|
-
"variant": {
|
|
177
|
-
"type": "ChartBarVariant",
|
|
178
|
-
"resolvedType": "\"percentage\" | \"single\" | \"stacked\"",
|
|
179
|
-
"attribute": "variant",
|
|
180
|
-
"default": "'single'",
|
|
181
|
-
"required": false,
|
|
182
|
-
"mutable": false,
|
|
183
|
-
"description": "Rendering model. Single uses `data`; stacked and percentage use `series` and `categories`."
|
|
184
|
-
},
|
|
185
|
-
"width": {
|
|
186
|
-
"type": "number",
|
|
187
|
-
"resolvedType": "number",
|
|
188
|
-
"attribute": "width",
|
|
189
|
-
"default": "480",
|
|
190
|
-
"required": false,
|
|
191
|
-
"mutable": false,
|
|
192
|
-
"description": "Standalone intrinsic width. Container constraints reflow the plot at rendered pixel size."
|
|
193
|
-
}
|
|
194
|
-
},
|
|
195
|
-
"events": [],
|
|
196
|
-
"methods": [],
|
|
197
|
-
"slots": [],
|
|
198
|
-
"exports": {
|
|
199
|
-
"customElement": "ds-chart-bar",
|
|
200
|
-
"react": "DsChartBar",
|
|
201
|
-
"angular": "DsChartBar"
|
|
202
|
-
},
|
|
203
|
-
"consumption": {
|
|
204
|
-
"install": "npm install @ds-mo/ui @ds-mo/tokens @ds-mo/icons",
|
|
205
|
-
"cssSetup": "import '@ds-mo/tokens';\nimport '@ds-mo/tokens/reset';\nimport '@ds-mo/tokens/globals';",
|
|
206
|
-
"customElements": {
|
|
207
|
-
"import": "import '@ds-mo/ui/dist/components/ds-chart-bar.js';",
|
|
208
|
-
"example": "<ds-chart-bar></ds-chart-bar>"
|
|
209
|
-
},
|
|
210
|
-
"react": {
|
|
211
|
-
"import": "import { DsChartBar } from '@ds-mo/ui/react';",
|
|
212
|
-
"example": "<DsChartBar />"
|
|
213
|
-
},
|
|
214
|
-
"angular": {
|
|
215
|
-
"import": "import { DsChartBar } from '@ds-mo/ui/angular/ds-chart-bar';",
|
|
216
|
-
"example": "<ds-chart-bar></ds-chart-bar>"
|
|
217
|
-
},
|
|
218
|
-
"complexPropertyNote": "Assign these non-primitive values as JavaScript properties: categories, data, series.",
|
|
219
|
-
"peerDependencies": {
|
|
220
|
-
"required": [
|
|
221
|
-
"@ds-mo/tokens ^5.1.1",
|
|
222
|
-
"@ds-mo/icons ^6.4.0"
|
|
223
|
-
],
|
|
224
|
-
"frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
},
|
|
228
|
-
"dependencies": [
|
|
229
|
-
"@ds-mo/ui",
|
|
230
|
-
"@ds-mo/tokens"
|
|
231
|
-
],
|
|
232
|
-
"registryDependencies": [],
|
|
233
|
-
"files": [
|
|
234
|
-
{
|
|
235
|
-
"path": "src/wc/components/ChartBar/ChartBar.css",
|
|
236
|
-
"content": "@import '../../utils/forced-colors.css';\n\n:host {\n display: inline-block;\n max-width: 100%;\n font-family: var(--typography-font-family);\n}\n\n.chart-bar__svg {\n display: block;\n width: 100%;\n height: 100%;\n}\n\n.chart-bar__gridline {\n stroke: var(--color-border-tertiary);\n stroke-width: var(--dimension-stroke-width-012);\n vector-effect: non-scaling-stroke;\n}\n\n/* Matches ds-text text-caption regular (SVG cannot host ds-text). */\n.chart-bar__axis-label {\n fill: var(--color-foreground-secondary);\n font-family: var(--typography-font-family);\n font-size: var(--typography-fontsize-xs);\n font-weight: var(--typography-weight-medium);\n letter-spacing: var(--typography-letterspacing-positive);\n text-transform: uppercase;\n}\n\n.chart-bar__bar--rounded {\n rx: var(--dimension-radius-025);\n}\n\n.chart-bar__segment-shape--rounded {\n rx: var(--dimension-radius-025);\n}\n\n.chart-bar__segment-separator {\n stroke: var(--color-background-primary);\n stroke-width: var(--dimension-stroke-width-012);\n stroke-linecap: butt;\n vector-effect: non-scaling-stroke;\n}\n\n@media (forced-colors: active) {\n .chart-bar__bar,\n .chart-bar__segment-shape,\n .chart-bar__segment-square-base {\n forced-color-adjust: none;\n }\n\n .chart-bar__segment-separator {\n stroke: var(--ds-forced-color-surface);\n }\n}\n",
|
|
237
|
-
"type": "registry:ui"
|
|
238
|
-
},
|
|
239
|
-
{
|
|
240
|
-
"path": "src/wc/components/ChartBar/ChartBar.tsx",
|
|
241
|
-
"content": "import { Component, Prop, State, Watch, h, Host } from '@stencil/core';\nimport { scaleBand, scaleLinear } from 'd3-scale';\nimport { max } from 'd3-array';\nimport { categoryColor } from '../../utils/chart-colors';\nimport { formatPercentage } from '../../utils';\nimport { resolveCartesianChartLayout } from '../../utils/cartesian-chart-layout';\nimport {\n ChartViewportController,\n type ChartViewportSize,\n} from '../../utils/chart-viewport-controller';\nimport type { ChartDatum, ChartSeries } from '../../utils/chart-types';\n\nexport type ChartBarVariant = 'single' | 'stacked' | 'percentage';\n\nconst PERCENTAGE_TICKS = [0, 25, 50, 75, 100];\n\n@Component({\n tag: 'ds-chart-bar',\n styleUrl: 'ChartBar.css',\n scoped: true,\n})\nexport class ChartBar {\n /** Rendering model. Single uses `data`; stacked and percentage use `series` and `categories`. */\n @Prop() variant: ChartBarVariant = 'single';\n /** Bars to render. Set as a JS property (not an HTML attribute). */\n @Prop() data: ChartDatum[] = [];\n /** Ordered stack series for stacked and percentage variants. Set as a JS property. */\n @Prop() series: ChartSeries[] = [];\n /** X-axis labels for stacked and percentage variants. Set as a JS property. */\n @Prop() categories: string[] = [];\n /** Standalone intrinsic width. Container constraints reflow the plot at rendered pixel size. */\n @Prop() width: number = 480;\n /** Standalone intrinsic height. Container constraints reflow the plot at rendered pixel size. */\n @Prop() height: number = 240;\n\n @State() private viewport: ChartViewportSize | undefined;\n\n private viewportController: ChartViewportController | null = null;\n private svgEl: SVGElement | null = null;\n\n componentDidLoad() {\n this.connectViewportController();\n }\n\n connectedCallback() {\n if (this.svgEl && !this.viewportController) this.connectViewportController();\n }\n\n componentDidRender() {\n if (!this.viewportController) this.connectViewportController();\n }\n\n private connectViewportController() {\n if (!this.svgEl) return;\n this.viewportController = new ChartViewportController(this.svgEl, viewport => {\n if (\n viewport.width !== this.viewport?.width ||\n viewport.height !== this.viewport?.height\n ) {\n this.viewport = viewport;\n }\n });\n this.viewportController.connect();\n }\n\n disconnectedCallback() {\n this.viewportController?.disconnect();\n this.viewportController = null;\n }\n\n @Watch('width')\n @Watch('height')\n handleIntrinsicSizeChange() {\n this.viewport = undefined;\n if (typeof requestAnimationFrame === 'function') {\n requestAnimationFrame(() => this.viewportController?.measure());\n }\n }\n\n private renderSingle(\n innerWidth: number,\n innerHeight: number,\n axisLabelGap: number,\n categoryLabelOffset: number\n ) {\n const yMax = max(this.data, d => d.value) ?? 0;\n const xScale = scaleBand()\n .domain(this.data.map(d => d.label))\n .range([0, innerWidth])\n .padding(0.35);\n const yScale = scaleLinear()\n .domain([0, yMax || 1])\n .range([innerHeight, 0])\n .nice();\n const yTicks = yScale.ticks(4);\n\n return (\n <g>\n {yTicks.map(tick => (\n <g key={`grid-${tick}`} transform={`translate(0, ${yScale(tick)})`}>\n <line class=\"chart-bar__gridline\" x1={0} x2={innerWidth} />\n <text\n class=\"chart-bar__axis-label\"\n x={-axisLabelGap}\n text-anchor=\"end\"\n dominant-baseline=\"middle\"\n >\n {tick}\n </text>\n </g>\n ))}\n\n {this.data.map((datum, index) => {\n const barWidth = xScale.bandwidth();\n const barX = xScale(datum.label) ?? 0;\n const barY = yScale(datum.value);\n const barHeight = innerHeight - barY;\n const squareBaseY = barY + barHeight / 2;\n const squareBaseHeight = barHeight / 2;\n const fill = datum.color ?? categoryColor(index);\n return (\n <g key={datum.label}>\n <rect\n class=\"chart-bar__bar chart-bar__bar--rounded\"\n x={barX}\n y={barY}\n width={barWidth}\n height={barHeight}\n fill={fill}\n />\n <rect\n class=\"chart-bar__bar chart-bar__bar--square-base\"\n x={barX}\n y={squareBaseY}\n width={barWidth}\n height={squareBaseHeight}\n fill={fill}\n />\n <text\n class=\"chart-bar__axis-label\"\n x={barX + barWidth / 2}\n y={innerHeight + categoryLabelOffset}\n text-anchor=\"middle\"\n >\n {datum.label}\n </text>\n </g>\n );\n })}\n </g>\n );\n }\n\n private valuesForCategory(categoryIndex: number) {\n return this.series.map(series => Math.max(0, series.data[categoryIndex] ?? 0));\n }\n\n private stackedAccessibleLabel() {\n return this.categories\n .map((category, categoryIndex) => {\n const values = this.valuesForCategory(categoryIndex);\n const total = values.reduce((sum, value) => sum + value, 0);\n const details = this.series\n .map((series, seriesIndex) => {\n const value = values[seriesIndex];\n const visibleValue =\n this.variant === 'percentage'\n ? formatPercentage(total ? value / total : 0, 1)\n : String(value);\n return `${series.name}: ${visibleValue}`;\n })\n .join(', ');\n return `${category}: ${details}`;\n })\n .join('; ');\n }\n\n private renderStacked(\n innerWidth: number,\n innerHeight: number,\n axisLabelGap: number,\n categoryLabelOffset: number\n ) {\n const categoryValues = this.categories.map((_, index) =>\n this.valuesForCategory(index)\n );\n const totals = categoryValues.map(values =>\n values.reduce((sum, value) => sum + value, 0)\n );\n const yMax = this.variant === 'percentage' ? 100 : Math.max(0, ...totals);\n const xScale = scaleBand()\n .domain(this.categories)\n .range([0, innerWidth])\n .padding(0.35);\n const yScale = scaleLinear()\n .domain([0, yMax || 1])\n .range([innerHeight, 0])\n .nice();\n const yTicks =\n this.variant === 'percentage' ? PERCENTAGE_TICKS : yScale.ticks(4);\n\n return (\n <g>\n {yTicks.map(tick => (\n <g key={`grid-${tick}`} transform={`translate(0, ${yScale(tick)})`}>\n <line class=\"chart-bar__gridline\" x1={0} x2={innerWidth} />\n <text\n class=\"chart-bar__axis-label\"\n x={-axisLabelGap}\n text-anchor=\"end\"\n dominant-baseline=\"middle\"\n >\n {this.variant === 'percentage' ? `${tick}%` : tick}\n </text>\n </g>\n ))}\n\n {this.categories.map((category, categoryIndex) => {\n const barWidth = xScale.bandwidth();\n const barX = xScale(category) ?? 0;\n const values = categoryValues[categoryIndex];\n const total = totals[categoryIndex];\n const topSeriesIndex = values.reduce(\n (topIndex, value, seriesIndex) =>\n value > 0 ? seriesIndex : topIndex,\n -1\n );\n let cumulativeValue = 0;\n\n return (\n <g class=\"chart-bar__stack\" data-category={category} key={category}>\n {this.series.map((series, seriesIndex) => {\n const rawValue = values[seriesIndex];\n const value =\n this.variant === 'percentage'\n ? total\n ? (rawValue / total) * 100\n : 0\n : rawValue;\n const segmentStart = cumulativeValue;\n const segmentEnd = cumulativeValue + value;\n cumulativeValue = segmentEnd;\n const segmentY = yScale(segmentEnd);\n const segmentBottom = yScale(segmentStart);\n const segmentHeight = Math.max(0, segmentBottom - segmentY);\n if (!segmentHeight) return null;\n\n const fill = series.color ?? categoryColor(seriesIndex);\n const hasRoundedTop =\n this.variant === 'stacked' && seriesIndex === topSeriesIndex;\n const squareBaseY = segmentY + segmentHeight / 2;\n const squareBaseHeight = segmentHeight / 2;\n\n return (\n <g\n class=\"chart-bar__segment\"\n data-series={series.name}\n key={series.name}\n >\n <rect\n class={{\n 'chart-bar__segment-shape': true,\n 'chart-bar__segment-shape--rounded': hasRoundedTop,\n }}\n x={barX}\n y={segmentY}\n width={barWidth}\n height={segmentHeight}\n fill={fill}\n />\n {hasRoundedTop ? (\n <rect\n class=\"chart-bar__segment-square-base\"\n x={barX}\n y={squareBaseY}\n width={barWidth}\n height={squareBaseHeight}\n fill={fill}\n />\n ) : null}\n {segmentStart > 0 ? (\n <line\n class=\"chart-bar__segment-separator\"\n x1={barX}\n x2={barX + barWidth}\n y1={segmentBottom}\n y2={segmentBottom}\n vector-effect=\"non-scaling-stroke\"\n />\n ) : null}\n </g>\n );\n })}\n <text\n class=\"chart-bar__axis-label\"\n x={barX + barWidth / 2}\n y={innerHeight + categoryLabelOffset}\n text-anchor=\"middle\"\n >\n {category}\n </text>\n </g>\n );\n })}\n </g>\n );\n }\n\n render() {\n const viewportWidth = this.viewport?.width ?? this.width;\n const viewportHeight = this.viewport?.height ?? this.height;\n const { margin, axisLabelGap, categoryLabelOffset } =\n resolveCartesianChartLayout();\n const innerWidth = Math.max(0, viewportWidth - margin.left - margin.right);\n const innerHeight = Math.max(0, viewportHeight - margin.top - margin.bottom);\n const isSingle = this.variant === 'single';\n const accessibleLabel = isSingle\n ? this.data.map(datum => `${datum.label}: ${datum.value}`).join(', ')\n : this.stackedAccessibleLabel();\n\n return (\n <Host\n class={{\n 'chart-bar': true,\n [`chart-bar--${this.variant}`]: true,\n }}\n >\n <svg\n class=\"chart-bar__svg\"\n ref={element => {\n this.svgEl = element ?? null;\n }}\n width={viewportWidth}\n height={viewportHeight}\n role=\"img\"\n aria-label={accessibleLabel}\n >\n <g transform={`translate(${margin.left}, ${margin.top})`}>\n {isSingle\n ? this.renderSingle(\n innerWidth,\n innerHeight,\n axisLabelGap,\n categoryLabelOffset\n )\n : this.renderStacked(\n innerWidth,\n innerHeight,\n axisLabelGap,\n categoryLabelOffset\n )}\n </g>\n </svg>\n </Host>\n );\n }\n}\n",
|
|
242
|
-
"type": "registry:ui"
|
|
243
|
-
}
|
|
244
|
-
]
|
|
245
|
-
}
|