@acronis-platform/ui-react 2.0.0 → 4.0.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/components/ui/accordion-container/accordion-container.js +144 -0
- package/dist/components/ui/accordion-container/accordion-container.js.map +1 -0
- package/dist/components/ui/app-shell-chat/app-shell-chat.js.map +1 -1
- package/dist/components/ui/area-chart/area-chart.js +141 -139
- package/dist/components/ui/area-chart/area-chart.js.map +1 -1
- package/dist/components/ui/avatar/avatar.js +33 -22
- package/dist/components/ui/avatar/avatar.js.map +1 -1
- package/dist/components/ui/bar-chart/bar-chart.js +295 -293
- package/dist/components/ui/bar-chart/bar-chart.js.map +1 -1
- package/dist/components/ui/card/card.js +150 -74
- package/dist/components/ui/card/card.js.map +1 -1
- package/dist/components/ui/card-section/card-section.js +111 -0
- package/dist/components/ui/card-section/card-section.js.map +1 -0
- package/dist/components/ui/category-bar/category-bar.js +109 -93
- package/dist/components/ui/category-bar/category-bar.js.map +1 -1
- package/dist/components/ui/chart/chart-palette.js +113 -0
- package/dist/components/ui/chart/chart-palette.js.map +1 -0
- package/dist/components/ui/chart/chart.js +176 -129
- package/dist/components/ui/chart/chart.js.map +1 -1
- package/dist/components/ui/chart-state/chart-state-illustrations.js +310 -0
- package/dist/components/ui/chart-state/chart-state-illustrations.js.map +1 -0
- package/dist/components/ui/chart-state/chart-state.js +48 -34
- package/dist/components/ui/chart-state/chart-state.js.map +1 -1
- package/dist/components/ui/chart-widget/chart-widget.js +87 -0
- package/dist/components/ui/chart-widget/chart-widget.js.map +1 -0
- package/dist/components/ui/composed-chart/composed-chart.js +117 -115
- package/dist/components/ui/composed-chart/composed-chart.js.map +1 -1
- package/dist/components/ui/confidence-cone/confidence-cone.js +166 -158
- package/dist/components/ui/confidence-cone/confidence-cone.js.map +1 -1
- package/dist/components/ui/data-table/data-table.js +4 -2
- package/dist/components/ui/data-table/data-table.js.map +1 -1
- package/dist/components/ui/empty-overlay/empty-overlay.js +49 -0
- package/dist/components/ui/empty-overlay/empty-overlay.js.map +1 -0
- package/dist/components/ui/funnel-chart/funnel-chart.js +162 -161
- package/dist/components/ui/funnel-chart/funnel-chart.js.map +1 -1
- package/dist/components/ui/histogram/histogram.js +94 -92
- package/dist/components/ui/histogram/histogram.js.map +1 -1
- package/dist/components/ui/input/input.js.map +1 -1
- package/dist/components/ui/label/label.js +2 -9
- package/dist/components/ui/label/label.js.map +1 -1
- package/dist/components/ui/line-chart/line-chart.js +143 -141
- package/dist/components/ui/line-chart/line-chart.js.map +1 -1
- package/dist/components/ui/metric/metric.js +74 -185
- package/dist/components/ui/metric/metric.js.map +1 -1
- package/dist/components/ui/page-content/page-content.js.map +1 -1
- package/dist/components/ui/pie-chart/pie-chart.js +201 -195
- package/dist/components/ui/pie-chart/pie-chart.js.map +1 -1
- package/dist/components/ui/radar-chart/radar-chart.js +133 -131
- package/dist/components/ui/radar-chart/radar-chart.js.map +1 -1
- package/dist/components/ui/radial-bar-chart/radial-bar-chart.js +297 -265
- package/dist/components/ui/radial-bar-chart/radial-bar-chart.js.map +1 -1
- package/dist/components/ui/sankey-chart/sankey-chart.js +123 -101
- package/dist/components/ui/sankey-chart/sankey-chart.js.map +1 -1
- package/dist/components/ui/scatter-chart/scatter-chart.js +76 -74
- package/dist/components/ui/scatter-chart/scatter-chart.js.map +1 -1
- package/dist/components/ui/section/section.js +157 -31
- package/dist/components/ui/section/section.js.map +1 -1
- package/dist/components/ui/stepper/stepper.js +24 -24
- package/dist/components/ui/stepper/stepper.js.map +1 -1
- package/dist/components/ui/stepper-item/stepper-item.js +43 -24
- package/dist/components/ui/stepper-item/stepper-item.js.map +1 -1
- package/dist/components/ui/table/table.js +27 -27
- package/dist/components/ui/table/table.js.map +1 -1
- package/dist/components/ui/treemap/treemap.js +133 -124
- package/dist/components/ui/treemap/treemap.js.map +1 -1
- package/dist/components/ui/trend-indicator/trend-indicator.js +34 -69
- package/dist/components/ui/trend-indicator/trend-indicator.js.map +1 -1
- package/dist/components/ui/wizard/wizard.js +59 -0
- package/dist/components/ui/wizard/wizard.js.map +1 -0
- package/dist/hooks/use-wizard.js +75 -0
- package/dist/hooks/use-wizard.js.map +1 -0
- package/dist/index.js +540 -525
- package/dist/index.js.map +1 -1
- package/dist/llms/accordion-container.md +181 -0
- package/dist/llms/accordion.md +124 -0
- package/dist/llms/alert.md +225 -0
- package/dist/llms/app-shell-chat.md +415 -0
- package/dist/llms/area-chart.md +355 -0
- package/dist/llms/avatar.md +208 -0
- package/dist/llms/bar-chart.md +406 -0
- package/dist/llms/breadcrumb.md +326 -0
- package/dist/llms/button-group.md +298 -0
- package/dist/llms/button-icon-input.md +142 -0
- package/dist/llms/button-icon-menu.md +209 -0
- package/dist/llms/button-icon.md +128 -0
- package/dist/llms/button-menu.md +172 -0
- package/dist/llms/button.md +185 -0
- package/dist/llms/calendar-panel.md +733 -0
- package/dist/llms/calendar.md +188 -0
- package/dist/llms/card-filter.md +214 -0
- package/dist/llms/card-section.md +293 -0
- package/dist/llms/card.md +447 -0
- package/dist/llms/carousel-dialog.md +156 -0
- package/dist/llms/category-bar.md +193 -0
- package/dist/llms/chart-state.md +190 -0
- package/dist/llms/chart-widget.md +209 -0
- package/dist/llms/chart.md +182 -0
- package/dist/llms/checkbox.md +257 -0
- package/dist/llms/chip.md +195 -0
- package/dist/llms/combobox.md +164 -0
- package/dist/llms/composed-chart.md +508 -0
- package/dist/llms/confidence-cone.md +277 -0
- package/dist/llms/data-table.md +474 -0
- package/dist/llms/date-range-picker.md +272 -0
- package/dist/llms/description-list.md +131 -0
- package/dist/llms/dialog-footer-carousel.md +147 -0
- package/dist/llms/dialog-footer-default.md +142 -0
- package/dist/llms/dialog-root.md +246 -0
- package/dist/llms/dialog-welcome.md +223 -0
- package/dist/llms/dialog.md +403 -0
- package/dist/llms/dropdown-menu.md +193 -0
- package/dist/llms/empty-overlay.md +146 -0
- package/dist/llms/empty.md +156 -0
- package/dist/llms/field.md +185 -0
- package/dist/llms/filter-cards.md +157 -0
- package/dist/llms/filter-chips.md +323 -0
- package/dist/llms/filter-search.md +512 -0
- package/dist/llms/form.md +154 -0
- package/dist/llms/funnel-chart.md +333 -0
- package/dist/llms/grid.md +80 -0
- package/dist/llms/histogram.md +190 -0
- package/dist/llms/input-date-picker.md +203 -0
- package/dist/llms/input-otp.md +173 -0
- package/dist/llms/input-password.md +197 -0
- package/dist/llms/input-search.md +170 -0
- package/dist/llms/input-select.md +278 -0
- package/dist/llms/input-text-area.md +271 -0
- package/dist/llms/input-text.md +192 -0
- package/dist/llms/line-chart.md +369 -0
- package/dist/llms/link.md +209 -0
- package/dist/llms/loading.md +130 -0
- package/dist/llms/meter.md +177 -0
- package/dist/llms/metric.md +204 -0
- package/dist/llms/number-field.md +122 -0
- package/dist/llms/page-content.md +69 -0
- package/dist/llms/page-header.md +182 -0
- package/dist/llms/pagination.md +133 -0
- package/dist/llms/pie-chart.md +307 -0
- package/dist/llms/popover.md +252 -0
- package/dist/llms/progress-circle.md +126 -0
- package/dist/llms/progress.md +111 -0
- package/dist/llms/radar-chart.md +316 -0
- package/dist/llms/radial-bar-chart.md +319 -0
- package/dist/llms/radio.md +255 -0
- package/dist/llms/resizable.md +195 -0
- package/dist/llms/sankey-chart.md +208 -0
- package/dist/llms/scatter-chart.md +239 -0
- package/dist/llms/scroll-area.md +183 -0
- package/dist/llms/section.md +401 -0
- package/dist/llms/select.md +210 -0
- package/dist/llms/separator.md +87 -0
- package/dist/llms/sheet.md +202 -0
- package/dist/llms/sidebar-primary.md +360 -0
- package/dist/llms/sidebar-secondary.md +417 -0
- package/dist/llms/skeleton.md +81 -0
- package/dist/llms/slider.md +97 -0
- package/dist/llms/spinner.md +100 -0
- package/dist/llms/stack.md +80 -0
- package/dist/llms/stepper-item.md +309 -0
- package/dist/llms/stepper.md +251 -0
- package/dist/llms/switch.md +140 -0
- package/dist/llms/table.md +436 -0
- package/dist/llms/tabs.md +197 -0
- package/dist/llms/tag.md +139 -0
- package/dist/llms/timeline.md +361 -0
- package/dist/llms/timer.md +259 -0
- package/dist/llms/toast.md +241 -0
- package/dist/llms/toggle-group.md +121 -0
- package/dist/llms/toolbar.md +453 -0
- package/dist/llms/tooltip.md +164 -0
- package/dist/llms/treemap.md +254 -0
- package/dist/llms/trend-indicator.md +132 -0
- package/dist/llms/widget-placeholder.md +169 -0
- package/dist/llms/wizard.md +412 -0
- package/dist/llms.txt +142 -0
- package/dist/react.js +540 -525
- package/dist/react.js.map +1 -1
- package/dist/src/components/ui/accordion-container/accordion-container.d.ts +44 -0
- package/dist/src/components/ui/accordion-container/index.d.ts +1 -0
- package/dist/src/components/ui/area-chart/area-chart.d.ts +9 -4
- package/dist/src/components/ui/avatar/avatar.d.ts +27 -8
- package/dist/src/components/ui/bar-chart/bar-chart.d.ts +9 -4
- package/dist/src/components/ui/button/button.d.ts +1 -1
- package/dist/src/components/ui/card/card.d.ts +69 -8
- package/dist/src/components/ui/card/index.d.ts +1 -1
- package/dist/src/components/ui/card-section/card-section.d.ts +50 -0
- package/dist/src/components/ui/card-section/index.d.ts +1 -0
- package/dist/src/components/ui/category-bar/category-bar.d.ts +10 -4
- package/dist/src/components/ui/chart/__stories__/palette-control.d.ts +48 -0
- package/dist/src/components/ui/chart/__tests__/chart-palette.test.d.ts +1 -0
- package/dist/src/components/ui/chart/chart-palette.d.ts +128 -0
- package/dist/src/components/ui/chart/chart.d.ts +66 -15
- package/dist/src/components/ui/chart/index.d.ts +4 -2
- package/dist/src/components/ui/chart-state/chart-state-illustrations.d.ts +6 -0
- package/dist/src/components/ui/chart-state/chart-state.d.ts +13 -2
- package/dist/src/components/ui/chart-state/index.d.ts +1 -0
- package/dist/src/components/ui/chart-widget/chart-widget.d.ts +64 -0
- package/dist/src/components/ui/chart-widget/index.d.ts +1 -0
- package/dist/src/components/ui/composed-chart/composed-chart.d.ts +12 -7
- package/dist/src/components/ui/confidence-cone/confidence-cone.d.ts +10 -5
- package/dist/src/components/ui/dialog/dialog.d.ts +1 -1
- package/dist/src/components/ui/empty-overlay/empty-overlay.d.ts +20 -0
- package/dist/src/components/ui/empty-overlay/index.d.ts +2 -0
- package/dist/src/components/ui/funnel-chart/funnel-chart.d.ts +11 -5
- package/dist/src/components/ui/grid/grid.d.ts +1 -1
- package/dist/src/components/ui/histogram/histogram.d.ts +10 -4
- package/dist/src/components/ui/label/index.d.ts +1 -1
- package/dist/src/components/ui/label/label.d.ts +1 -5
- package/dist/src/components/ui/line-chart/line-chart.d.ts +9 -4
- package/dist/src/components/ui/metric/metric.d.ts +13 -14
- package/dist/src/components/ui/pie-chart/pie-chart.d.ts +17 -8
- package/dist/src/components/ui/radar-chart/radar-chart.d.ts +10 -5
- package/dist/src/components/ui/radial-bar-chart/radial-bar-chart.d.ts +17 -6
- package/dist/src/components/ui/sankey-chart/sankey-chart.d.ts +10 -5
- package/dist/src/components/ui/scatter-chart/scatter-chart.d.ts +10 -5
- package/dist/src/components/ui/section/index.d.ts +1 -1
- package/dist/src/components/ui/section/section.d.ts +75 -6
- package/dist/src/components/ui/sheet/sheet.d.ts +1 -1
- package/dist/src/components/ui/stack/stack.d.ts +1 -1
- package/dist/src/components/ui/stepper-item/stepper-item.d.ts +6 -5
- package/dist/src/components/ui/tag/tag.d.ts +1 -1
- package/dist/src/components/ui/treemap/treemap.d.ts +11 -5
- package/dist/src/components/ui/trend-indicator/trend-indicator.d.ts +3 -7
- package/dist/src/components/ui/wizard/index.d.ts +1 -0
- package/dist/src/components/ui/wizard/wizard.d.ts +6 -0
- package/dist/src/hooks/index.d.ts +1 -0
- package/dist/src/hooks/use-wizard.d.ts +80 -0
- package/dist/src/index.d.ts +5 -3
- package/dist/ui-react.css +1 -1
- package/package.json +12 -6
- package/dist/components/ui/app-shell/app-shell.js +0 -75
- package/dist/components/ui/app-shell/app-shell.js.map +0 -1
- package/dist/components/ui/auth-layout/auth-layout.js +0 -56
- package/dist/components/ui/auth-layout/auth-layout.js.map +0 -1
- package/dist/components/ui/collapsible/collapsible.js +0 -22
- package/dist/components/ui/collapsible/collapsible.js.map +0 -1
- package/dist/src/components/ui/app-shell/app-shell.d.ts +0 -8
- package/dist/src/components/ui/app-shell/index.d.ts +0 -1
- package/dist/src/components/ui/auth-layout/auth-layout.d.ts +0 -6
- package/dist/src/components/ui/auth-layout/index.d.ts +0 -1
- package/dist/src/components/ui/collapsible/collapsible.d.ts +0 -5
- package/dist/src/components/ui/collapsible/index.d.ts +0 -1
- package/dist/src/components/ui/label/label.docs.d.ts +0 -10
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { jsxs as s, jsx as a, Fragment as C } from "react/jsx-runtime";
|
|
2
|
+
import * as B from "react";
|
|
3
|
+
import { mergeProps as V } from "@base-ui/react/merge-props";
|
|
4
|
+
import { useRender as j } from "@base-ui/react/use-render";
|
|
5
|
+
import { cva as n } from "../../../node_modules/.pnpm/class-variance-authority@0.7.1/node_modules/class-variance-authority/dist/index.js";
|
|
6
|
+
import { cn as m } from "../../../lib/utils.js";
|
|
7
|
+
import { Card as R } from "../card/card.js";
|
|
8
|
+
const S = n(
|
|
9
|
+
"flex w-full flex-col items-start justify-center gap-3",
|
|
10
|
+
{
|
|
11
|
+
variants: {
|
|
12
|
+
variant: {
|
|
13
|
+
slot: "px-4 pt-4",
|
|
14
|
+
tag: "px-4 pt-4",
|
|
15
|
+
list: "px-4 pt-4",
|
|
16
|
+
// Flush: the table's own rows own the horizontal inset.
|
|
17
|
+
"table-actions": "",
|
|
18
|
+
"card-primary": "px-4 pt-4",
|
|
19
|
+
"card-secondary": "px-4 pt-4"
|
|
20
|
+
},
|
|
21
|
+
hasBottomBorder: {
|
|
22
|
+
false: "",
|
|
23
|
+
true: "border-b border-[var(--ui-border-on-surface-divider)] pb-4"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
defaultVariants: {
|
|
27
|
+
variant: "slot",
|
|
28
|
+
hasBottomBorder: !1
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
), k = n("w-full", {
|
|
32
|
+
variants: {
|
|
33
|
+
surface: {
|
|
34
|
+
primary: "bg-[var(--ui-background-surface-primary)]",
|
|
35
|
+
secondary: "bg-[var(--ui-background-surface-secondary)]"
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
defaultVariants: {
|
|
39
|
+
surface: "primary"
|
|
40
|
+
}
|
|
41
|
+
}), F = B.forwardRef(
|
|
42
|
+
({
|
|
43
|
+
className: p,
|
|
44
|
+
variant: e = "slot",
|
|
45
|
+
hasBottomBorder: u = !1,
|
|
46
|
+
hasHeader: x = !1,
|
|
47
|
+
title: y,
|
|
48
|
+
extras: g,
|
|
49
|
+
actions: b,
|
|
50
|
+
content: l,
|
|
51
|
+
contentTag: t,
|
|
52
|
+
contentList: i,
|
|
53
|
+
contentTable: d,
|
|
54
|
+
render: h,
|
|
55
|
+
children: o,
|
|
56
|
+
...v
|
|
57
|
+
}, N) => {
|
|
58
|
+
const c = e === "table-actions", f = e === "card-primary" || e === "card-secondary", w = x ? /* @__PURE__ */ s(
|
|
59
|
+
"div",
|
|
60
|
+
{
|
|
61
|
+
className: m(
|
|
62
|
+
"flex w-full items-center gap-2",
|
|
63
|
+
// `table-actions` has no root inset, so the header re-applies it to
|
|
64
|
+
// stay aligned with the table cells below.
|
|
65
|
+
c && "px-4"
|
|
66
|
+
),
|
|
67
|
+
children: [
|
|
68
|
+
/* @__PURE__ */ s("div", { className: "flex min-w-0 flex-1 items-start gap-2", children: [
|
|
69
|
+
/* @__PURE__ */ a("p", { className: "truncate text-sm leading-6 font-medium text-[var(--ui-text-on-surface-primary)]", children: y }),
|
|
70
|
+
g
|
|
71
|
+
] }),
|
|
72
|
+
b
|
|
73
|
+
]
|
|
74
|
+
}
|
|
75
|
+
) : null;
|
|
76
|
+
let r = null;
|
|
77
|
+
return f ? r = /* @__PURE__ */ a(
|
|
78
|
+
R,
|
|
79
|
+
{
|
|
80
|
+
className: k({
|
|
81
|
+
surface: e === "card-secondary" ? "secondary" : "primary"
|
|
82
|
+
}),
|
|
83
|
+
children: o
|
|
84
|
+
}
|
|
85
|
+
) : e === "tag" ? r = t ? /* @__PURE__ */ a("div", { className: "flex w-full flex-wrap items-start gap-x-4 gap-y-2", children: t }) : null : e === "list" ? r = i ? /* @__PURE__ */ a("div", { className: "flex w-full flex-col", children: i }) : null : c ? r = d ? /* @__PURE__ */ a("div", { className: "flex w-full flex-col overflow-hidden rounded", children: d }) : null : r = l ? /* @__PURE__ */ a("div", { className: "w-full", children: l }) : null, j({
|
|
86
|
+
render: h,
|
|
87
|
+
ref: N,
|
|
88
|
+
defaultTagName: "div",
|
|
89
|
+
props: V(
|
|
90
|
+
{
|
|
91
|
+
className: m(
|
|
92
|
+
S({ variant: e, hasBottomBorder: u }),
|
|
93
|
+
p
|
|
94
|
+
),
|
|
95
|
+
children: /* @__PURE__ */ s(C, { children: [
|
|
96
|
+
w,
|
|
97
|
+
r,
|
|
98
|
+
!f && o
|
|
99
|
+
] })
|
|
100
|
+
},
|
|
101
|
+
v
|
|
102
|
+
)
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
);
|
|
106
|
+
F.displayName = "CardSection";
|
|
107
|
+
export {
|
|
108
|
+
F as CardSection,
|
|
109
|
+
S as cardSectionVariants
|
|
110
|
+
};
|
|
111
|
+
//# sourceMappingURL=card-section.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"card-section.js","sources":["../../../../src/components/ui/card-section/card-section.tsx"],"sourcesContent":["import * as React from 'react';\nimport { mergeProps } from '@base-ui/react/merge-props';\nimport { useRender } from '@base-ui/react/use-render';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nimport { cn } from '@/lib/utils';\nimport { Card } from '@/components/ui/card';\n\n// Figma node 7662:8727 (\"CardSection\"). A band of content that stacks inside a\n// `Card`'s body, below `CardHeader`. Figma's PascalCase variant names map to\n// this repo's kebab-case convention: `Slot` → `slot`, `Tag` → `tag`,\n// `List` → `list`, `Table + Actions` → `table-actions`,\n// `Card (primary)` → `card-primary`, `Card (secondary)` → `card-secondary`.\n//\n// Padding is variant-dependent, straight from the design: every variant except\n// `table-actions` insets its content (`px-4 pt-4`), while `table-actions` sits\n// flush so its table rows can run edge-to-edge inside the card — its own header\n// row re-applies the `px-4` instead. `hasBottomBorder` adds the divider plus the\n// matching bottom padding that separates this section from the next one below.\n//\n// `card-primary` / `card-secondary` differ in exactly one thing: the nested\n// `Card`'s surface token. Everything else — border, radius, composition — is\n// identical, so the two are a single cva branch pair rather than a separate\n// prop. Both branches set their surface token explicitly (rather than\n// relying on `Card`'s own primary default) so the pair stays correct even\n// if that default ever changes.\n//\n// No `--ui-card-*` component tier exists in tokens-pd, so — like `card.tsx` —\n// this stays on the shared semantic tier. Figma's default `contentList`\n// (a `ListItem` instance) references `components/Card/body/section/item/*`\n// variables that have no counterpart in `@acronis-platform/design-tokens`, so\n// `list` ships without a built-in fallback: the consumer supplies the rows.\n\nconst cardSectionVariants = cva(\n 'flex w-full flex-col items-start justify-center gap-3',\n {\n variants: {\n variant: {\n slot: 'px-4 pt-4',\n tag: 'px-4 pt-4',\n list: 'px-4 pt-4',\n // Flush: the table's own rows own the horizontal inset.\n 'table-actions': '',\n 'card-primary': 'px-4 pt-4',\n 'card-secondary': 'px-4 pt-4',\n },\n hasBottomBorder: {\n false: '',\n true: 'border-b border-[var(--ui-border-on-surface-divider)] pb-4',\n },\n },\n defaultVariants: {\n variant: 'slot',\n hasBottomBorder: false,\n },\n }\n);\n\nconst nestedCardVariants = cva('w-full', {\n variants: {\n surface: {\n primary: 'bg-[var(--ui-background-surface-primary)]',\n secondary: 'bg-[var(--ui-background-surface-secondary)]',\n },\n },\n defaultVariants: {\n surface: 'primary',\n },\n});\n\nexport interface CardSectionBaseProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'title' | 'content'>,\n VariantProps<typeof cardSectionVariants> {\n /** Extra content rendered inline next to the section title (e.g. a tag). */\n extras?: React.ReactNode;\n /** Actions rendered at the end of the section header row (e.g. a menu button). */\n actions?: React.ReactNode;\n /** Body of the `slot` variant — arbitrary passthrough content. */\n content?: React.ReactNode;\n /**\n * Body of the `tag` variant — a wrapping row of tags. Has no built-in\n * default: like `contentList`, the consumer supplies the tags.\n */\n contentTag?: React.ReactNode;\n /**\n * Body of the `list` variant — title/description key-value rows. Has no\n * built-in default: the `ListItem` tokens the design references\n * (`--ui-card-body-section-item-*`) do not exist in tokens-pd yet.\n */\n contentList?: React.ReactNode;\n /** Body of the `table-actions` variant — a table with row actions. */\n contentTable?: React.ReactNode;\n /**\n * Replace the rendered `<div>` with another element or component (Base UI\n * composition) — e.g. render the section as a `<section>`.\n */\n render?: useRender.RenderProp;\n}\n\n/**\n * A band of content stacked inside a `Card`'s body.\n *\n * `hasHeader` and `title` form a discriminated union: turning the section's own\n * mini-header on requires a title, because the header row always renders one.\n */\nexport type CardSectionProps = CardSectionBaseProps &\n (\n | {\n /** Shows the section's own mini-header row (14px, distinct from `CardHeader`). */\n hasHeader: true;\n /** The section header's title. Required whenever `hasHeader` is set. */\n title: string;\n }\n | { hasHeader?: false; title?: never }\n );\n\nconst CardSection = React.forwardRef<HTMLDivElement, CardSectionProps>(\n (\n {\n className,\n variant = 'slot',\n hasBottomBorder = false,\n hasHeader = false,\n title,\n extras,\n actions,\n content,\n contentTag,\n contentList,\n contentTable,\n render,\n children,\n ...props\n },\n ref\n ) => {\n const isTable = variant === 'table-actions';\n const isNestedCard =\n variant === 'card-primary' || variant === 'card-secondary';\n\n const header = hasHeader ? (\n <div\n className={cn(\n 'flex w-full items-center gap-2',\n // `table-actions` has no root inset, so the header re-applies it to\n // stay aligned with the table cells below.\n isTable && 'px-4'\n )}\n >\n <div className=\"flex min-w-0 flex-1 items-start gap-2\">\n <p className=\"truncate text-sm leading-6 font-medium text-[var(--ui-text-on-surface-primary)]\">\n {title}\n </p>\n {extras}\n </div>\n {actions}\n </div>\n ) : null;\n\n let body: React.ReactNode = null;\n if (isNestedCard) {\n body = (\n <Card\n className={nestedCardVariants({\n surface: variant === 'card-secondary' ? 'secondary' : 'primary',\n })}\n >\n {children}\n </Card>\n );\n } else if (variant === 'tag') {\n body = contentTag ? (\n <div className=\"flex w-full flex-wrap items-start gap-x-4 gap-y-2\">\n {contentTag}\n </div>\n ) : null;\n } else if (variant === 'list') {\n body = contentList ? (\n <div className=\"flex w-full flex-col\">{contentList}</div>\n ) : null;\n } else if (isTable) {\n body = contentTable ? (\n <div className=\"flex w-full flex-col overflow-hidden rounded\">\n {contentTable}\n </div>\n ) : null;\n } else {\n body = content ? <div className=\"w-full\">{content}</div> : null;\n }\n\n return useRender({\n render,\n ref,\n defaultTagName: 'div',\n props: mergeProps<'div'>(\n {\n className: cn(\n cardSectionVariants({ variant, hasBottomBorder }),\n className\n ),\n children: (\n <>\n {header}\n {body}\n {!isNestedCard && children}\n </>\n ),\n },\n props\n ),\n });\n }\n);\nCardSection.displayName = 'CardSection';\n\nexport { CardSection, cardSectionVariants };\n"],"names":["cardSectionVariants","cva","nestedCardVariants","CardSection","React","className","variant","hasBottomBorder","hasHeader","title","extras","actions","content","contentTag","contentList","contentTable","render","children","props","ref","isTable","isNestedCard","header","jsxs","cn","jsx","body","Card","useRender","mergeProps","Fragment"],"mappings":";;;;;;;AAiCA,MAAMA,IAAsBC;AAAA,EAC1B;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA,QACP,MAAM;AAAA,QACN,KAAK;AAAA,QACL,MAAM;AAAA;AAAA,QAEN,iBAAiB;AAAA,QACjB,gBAAgB;AAAA,QAChB,kBAAkB;AAAA,MAAA;AAAA,MAEpB,iBAAiB;AAAA,QACf,OAAO;AAAA,QACP,MAAM;AAAA,MAAA;AAAA,IACR;AAAA,IAEF,iBAAiB;AAAA,MACf,SAAS;AAAA,MACT,iBAAiB;AAAA,IAAA;AAAA,EACnB;AAEJ,GAEMC,IAAqBD,EAAI,UAAU;AAAA,EACvC,UAAU;AAAA,IACR,SAAS;AAAA,MACP,SAAS;AAAA,MACT,WAAW;AAAA,IAAA;AAAA,EACb;AAAA,EAEF,iBAAiB;AAAA,IACf,SAAS;AAAA,EAAA;AAEb,CAAC,GAiDKE,IAAcC,EAAM;AAAA,EACxB,CACE;AAAA,IACE,WAAAC;AAAA,IACA,SAAAC,IAAU;AAAA,IACV,iBAAAC,IAAkB;AAAA,IAClB,WAAAC,IAAY;AAAA,IACZ,OAAAC;AAAA,IACA,QAAAC;AAAA,IACA,SAAAC;AAAA,IACA,SAAAC;AAAA,IACA,YAAAC;AAAA,IACA,aAAAC;AAAA,IACA,cAAAC;AAAA,IACA,QAAAC;AAAA,IACA,UAAAC;AAAA,IACA,GAAGC;AAAA,EAAA,GAELC,MACG;AACH,UAAMC,IAAUd,MAAY,iBACtBe,IACJf,MAAY,kBAAkBA,MAAY,kBAEtCgB,IAASd,IACb,gBAAAe;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAWC;AAAA,UACT;AAAA;AAAA;AAAA,UAGAJ,KAAW;AAAA,QAAA;AAAA,QAGb,UAAA;AAAA,UAAA,gBAAAG,EAAC,OAAA,EAAI,WAAU,yCACb,UAAA;AAAA,YAAA,gBAAAE,EAAC,KAAA,EAAE,WAAU,mFACV,UAAAhB,GACH;AAAA,YACCC;AAAA,UAAA,GACH;AAAA,UACCC;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA,IAED;AAEJ,QAAIe,IAAwB;AAC5B,WAAIL,IACFK,IACE,gBAAAD;AAAA,MAACE;AAAA,MAAA;AAAA,QACC,WAAWzB,EAAmB;AAAA,UAC5B,SAASI,MAAY,mBAAmB,cAAc;AAAA,QAAA,CACvD;AAAA,QAEA,UAAAW;AAAA,MAAA;AAAA,IAAA,IAGIX,MAAY,QACrBoB,IAAOb,IACL,gBAAAY,EAAC,OAAA,EAAI,WAAU,qDACZ,aACH,IACE,OACKnB,MAAY,SACrBoB,IAAOZ,IACL,gBAAAW,EAAC,OAAA,EAAI,WAAU,wBAAwB,aAAY,IACjD,OACKL,IACTM,IAAOX,IACL,gBAAAU,EAAC,OAAA,EAAI,WAAU,gDACZ,aACH,IACE,OAEJC,IAAOd,IAAU,gBAAAa,EAAC,OAAA,EAAI,WAAU,UAAU,aAAQ,IAAS,MAGtDG,EAAU;AAAA,MACf,QAAAZ;AAAA,MACA,KAAAG;AAAA,MACA,gBAAgB;AAAA,MAChB,OAAOU;AAAA,QACL;AAAA,UACE,WAAWL;AAAA,YACTxB,EAAoB,EAAE,SAAAM,GAAS,iBAAAC,GAAiB;AAAA,YAChDF;AAAA,UAAA;AAAA,UAEF,UACE,gBAAAkB,EAAAO,GAAA,EACG,UAAA;AAAA,YAAAR;AAAA,YACAI;AAAA,YACA,CAACL,KAAgBJ;AAAA,UAAA,EAAA,CACpB;AAAA,QAAA;AAAA,QAGJC;AAAA,MAAA;AAAA,IACF,CACD;AAAA,EACH;AACF;AACAf,EAAY,cAAc;"}
|
|
@@ -1,55 +1,59 @@
|
|
|
1
|
-
import { jsxs as l, jsx as
|
|
2
|
-
import * as
|
|
3
|
-
import { cva as
|
|
4
|
-
import { cn as
|
|
5
|
-
import { ChartStyle as
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
import { jsxs as l, jsx as r, Fragment as S } from "react/jsx-runtime";
|
|
2
|
+
import * as h from "react";
|
|
3
|
+
import { cva as A } from "../../../node_modules/.pnpm/class-variance-authority@0.7.1/node_modules/class-variance-authority/dist/index.js";
|
|
4
|
+
import { cn as v } from "../../../lib/utils.js";
|
|
5
|
+
import { resolveChartColors as E, ChartStyle as C } from "../chart/chart.js";
|
|
6
|
+
import { CHART_DEFAULT_PALETTE as F } from "../chart/chart-palette.js";
|
|
7
|
+
import { Tooltip as I, TooltipTrigger as L, TooltipContent as O } from "../tooltip/tooltip.js";
|
|
8
|
+
const R = (n) => n.toLocaleString(), q = A(
|
|
9
|
+
"flex w-full overflow-hidden rounded-full bg-input",
|
|
10
|
+
{
|
|
11
|
+
variants: {
|
|
12
|
+
size: {
|
|
13
|
+
sm: "h-1.5",
|
|
14
|
+
md: "h-2.5",
|
|
15
|
+
lg: "h-4"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
defaultVariants: {
|
|
19
|
+
size: "md"
|
|
13
20
|
}
|
|
14
|
-
},
|
|
15
|
-
defaultVariants: {
|
|
16
|
-
size: "md"
|
|
17
21
|
}
|
|
18
|
-
|
|
19
|
-
function
|
|
20
|
-
chartId:
|
|
21
|
-
config:
|
|
22
|
-
color:
|
|
23
|
-
label:
|
|
24
|
-
percent:
|
|
25
|
-
segmentKey:
|
|
26
|
-
value:
|
|
27
|
-
valueFormatter:
|
|
28
|
-
renderContent:
|
|
22
|
+
);
|
|
23
|
+
function M({
|
|
24
|
+
chartId: n,
|
|
25
|
+
config: s,
|
|
26
|
+
color: o,
|
|
27
|
+
label: i,
|
|
28
|
+
percent: d,
|
|
29
|
+
segmentKey: u,
|
|
30
|
+
value: m,
|
|
31
|
+
valueFormatter: f,
|
|
32
|
+
renderContent: t
|
|
29
33
|
}) {
|
|
30
34
|
return /* @__PURE__ */ l(
|
|
31
35
|
O,
|
|
32
36
|
{
|
|
33
|
-
"data-chart":
|
|
34
|
-
className:
|
|
37
|
+
"data-chart": n,
|
|
38
|
+
className: v(
|
|
35
39
|
"border border-border bg-background text-foreground shadow-md",
|
|
36
|
-
!
|
|
40
|
+
!t && "flex items-center gap-2"
|
|
37
41
|
),
|
|
38
42
|
children: [
|
|
39
|
-
/* @__PURE__ */
|
|
40
|
-
|
|
41
|
-
/* @__PURE__ */
|
|
43
|
+
/* @__PURE__ */ r(C, { id: n, config: s }),
|
|
44
|
+
t ? t({ key: u, value: m, label: i, percent: d, color: o }) : /* @__PURE__ */ l(S, { children: [
|
|
45
|
+
/* @__PURE__ */ r(
|
|
42
46
|
"span",
|
|
43
47
|
{
|
|
44
48
|
className: "size-2.5 shrink-0 rounded-full",
|
|
45
|
-
style: { backgroundColor:
|
|
49
|
+
style: { backgroundColor: o }
|
|
46
50
|
}
|
|
47
51
|
),
|
|
48
|
-
/* @__PURE__ */
|
|
52
|
+
/* @__PURE__ */ r("span", { className: "font-semibold", children: i }),
|
|
49
53
|
/* @__PURE__ */ l("span", { className: "text-muted-foreground tabular-nums", children: [
|
|
50
|
-
|
|
54
|
+
f(m),
|
|
51
55
|
" · ",
|
|
52
|
-
|
|
56
|
+
d,
|
|
53
57
|
"%"
|
|
54
58
|
] })
|
|
55
59
|
] })
|
|
@@ -57,79 +61,91 @@ function R({
|
|
|
57
61
|
}
|
|
58
62
|
);
|
|
59
63
|
}
|
|
60
|
-
const V =
|
|
64
|
+
const V = h.forwardRef(
|
|
61
65
|
({
|
|
62
|
-
className:
|
|
63
|
-
data:
|
|
64
|
-
config:
|
|
66
|
+
className: n,
|
|
67
|
+
data: s,
|
|
68
|
+
config: o,
|
|
69
|
+
palette: i = F,
|
|
65
70
|
size: d,
|
|
66
|
-
showLegend:
|
|
67
|
-
showTooltip:
|
|
68
|
-
tooltipContent:
|
|
69
|
-
valueFormatter:
|
|
70
|
-
defaultOpenIndex:
|
|
71
|
+
showLegend: u = !1,
|
|
72
|
+
showTooltip: m = !0,
|
|
73
|
+
tooltipContent: f,
|
|
74
|
+
valueFormatter: t = R,
|
|
75
|
+
defaultOpenIndex: T,
|
|
71
76
|
"aria-label": w,
|
|
72
|
-
|
|
73
|
-
},
|
|
74
|
-
const p = `chart-${
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
var
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
77
|
+
...$
|
|
78
|
+
}, j) => {
|
|
79
|
+
const p = `chart-${h.useId().replace(/:/g, "")}`, b = h.useMemo(
|
|
80
|
+
() => E(o, i),
|
|
81
|
+
[o, i]
|
|
82
|
+
), g = s.reduce((e, a) => e + a.value, 0), x = (e) => {
|
|
83
|
+
var a;
|
|
84
|
+
return ((a = o[e]) == null ? void 0 : a.label) ?? e;
|
|
85
|
+
}, z = (e) => {
|
|
86
|
+
var c;
|
|
87
|
+
const a = (c = o[e]) == null ? void 0 : c.label;
|
|
88
|
+
return typeof a == "string" || typeof a == "number" ? String(a) : e;
|
|
89
|
+
}, y = (e) => `var(--color-${e})`, N = (e) => g > 0 ? Math.round(e / g * 100) : 0, B = w ?? s.map((e) => `${z(e.key)} ${t(e.value)}`).join(", ");
|
|
82
90
|
return /* @__PURE__ */ l(
|
|
83
91
|
"div",
|
|
84
92
|
{
|
|
85
|
-
ref:
|
|
93
|
+
ref: j,
|
|
86
94
|
"data-chart": p,
|
|
87
|
-
className:
|
|
88
|
-
|
|
95
|
+
className: v("flex w-full flex-col gap-3", n),
|
|
96
|
+
...$,
|
|
89
97
|
children: [
|
|
90
|
-
/* @__PURE__ */
|
|
91
|
-
/* @__PURE__ */
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
{
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
98
|
+
/* @__PURE__ */ r(C, { id: p, config: b }),
|
|
99
|
+
/* @__PURE__ */ r(
|
|
100
|
+
"div",
|
|
101
|
+
{
|
|
102
|
+
className: q({ size: d }),
|
|
103
|
+
role: "img",
|
|
104
|
+
"aria-label": B,
|
|
105
|
+
children: s.map((e, a) => {
|
|
106
|
+
const c = y(e.key), k = /* @__PURE__ */ r(
|
|
107
|
+
"div",
|
|
108
|
+
{
|
|
109
|
+
className: "h-full min-w-0",
|
|
110
|
+
style: { flex: `${e.value} 0 0%`, backgroundColor: c }
|
|
111
|
+
},
|
|
112
|
+
e.key
|
|
113
|
+
);
|
|
114
|
+
return m ? /* @__PURE__ */ l(I, { defaultOpen: a === T, children: [
|
|
115
|
+
/* @__PURE__ */ r(L, { render: k }),
|
|
116
|
+
/* @__PURE__ */ r(
|
|
117
|
+
M,
|
|
118
|
+
{
|
|
119
|
+
chartId: p,
|
|
120
|
+
config: b,
|
|
121
|
+
color: c,
|
|
122
|
+
label: x(e.key),
|
|
123
|
+
percent: N(e.value),
|
|
124
|
+
segmentKey: e.key,
|
|
125
|
+
value: e.value,
|
|
126
|
+
valueFormatter: t,
|
|
127
|
+
renderContent: f
|
|
128
|
+
}
|
|
129
|
+
)
|
|
130
|
+
] }, e.key) : k;
|
|
131
|
+
})
|
|
132
|
+
}
|
|
133
|
+
),
|
|
134
|
+
u && /* @__PURE__ */ r("ul", { className: "flex flex-wrap justify-between gap-x-6 gap-y-3", children: s.map((e) => /* @__PURE__ */ l("li", { className: "flex flex-col gap-1.5", children: [
|
|
119
135
|
/* @__PURE__ */ l("span", { className: "flex items-center gap-1.5 text-sm leading-none text-muted-foreground", children: [
|
|
120
|
-
/* @__PURE__ */
|
|
136
|
+
/* @__PURE__ */ r(
|
|
121
137
|
"span",
|
|
122
138
|
{
|
|
123
139
|
className: "size-2.5 shrink-0 rounded-sm",
|
|
124
|
-
style: { backgroundColor:
|
|
140
|
+
style: { backgroundColor: y(e.key) }
|
|
125
141
|
}
|
|
126
142
|
),
|
|
127
|
-
|
|
143
|
+
x(e.key)
|
|
128
144
|
] }),
|
|
129
145
|
/* @__PURE__ */ l("span", { className: "flex items-baseline gap-1.5 leading-none tabular-nums", children: [
|
|
130
|
-
/* @__PURE__ */
|
|
146
|
+
/* @__PURE__ */ r("span", { className: "text-base font-semibold text-foreground", children: t(e.value) }),
|
|
131
147
|
/* @__PURE__ */ l("span", { className: "text-sm text-muted-foreground", children: [
|
|
132
|
-
|
|
148
|
+
N(e.value),
|
|
133
149
|
"%"
|
|
134
150
|
] })
|
|
135
151
|
] })
|
|
@@ -142,6 +158,6 @@ const V = N.forwardRef(
|
|
|
142
158
|
V.displayName = "CategoryBar";
|
|
143
159
|
export {
|
|
144
160
|
V as CategoryBar,
|
|
145
|
-
|
|
161
|
+
q as categoryBarVariants
|
|
146
162
|
};
|
|
147
163
|
//# sourceMappingURL=category-bar.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"category-bar.js","sources":["../../../../src/components/ui/category-bar/category-bar.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nimport { cn } from '@/lib/utils';\nimport { ChartStyle, type ChartConfig } from '../chart';\nimport { Tooltip, TooltipContent, TooltipTrigger } from '../tooltip';\n\n// A category bar: a single horizontal bar split into proportional colored\n// segments — one part-to-whole across a handful of categories, in one row\n// (onboarding stages, certification status, a rating scale). Unlike `Meter`\n// (one value per row, stacked into a bar list), all segments share the same bar.\n// It's a plain flex composition, not a recharts chart: each segment's width is\n// `value / total`, so exact proportions and the count/% legend are direct DOM,\n// with no axes/grid to hide. Segment colors are caller-supplied via `config`\n// (existing semantic `--ui-*` tokens); there is no chart palette tier yet.\n//\n// Colors are consumed through the same `--color-<key>` bridge the recharts\n// charts use: `ChartStyle` emits one custom property per config entry, so a\n// `theme: { light, dark }` entry works as well as a flat `color` — reading\n// `config[key].color` directly would render a themed config colorless. The\n// tooltip is portaled out of the bar's DOM, so its popup carries its own\n// `data-chart` scope + `ChartStyle` to keep the bridge resolvable there.\n\nconst defaultFormat = (value: number) => value.toLocaleString();\n\n// Track height only — the flex/rounded/overflow chrome is static.\nconst categoryBarVariants = cva('flex w-full overflow-hidden rounded-full bg-input', {\n variants: {\n size: {\n sm: 'h-1.5',\n md: 'h-2.5',\n lg: 'h-4',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n});\n\nexport interface CategoryBarSegment {\n /** Key into `config` for this segment's label + color. */\n key: string;\n /** The segment's value — its width is this over the sum of all values. */\n value: number;\n}\n\n/** The resolved segment passed to a custom `tooltipContent` renderer. */\nexport interface CategoryBarTooltipContext extends CategoryBarSegment {\n /** Resolved `config` label (falls back to the key); may be any `ReactNode`. */\n label: React.ReactNode;\n /** Share of the total as a rounded percentage (0–100). */\n percent: number;\n /**\n * CSS color reference for the segment — the `var(--color-<key>)` bridge, which\n * resolves the config entry's `color` or its per-theme `theme` value. Usable\n * anywhere a CSS color is (e.g. a `style` background); not a literal value.\n */\n color: string;\n}\n\nexport interface CategoryBarProps\n extends Omit<React.ComponentProps<'div'>, 'children'>,\n VariantProps<typeof categoryBarVariants> {\n /** Ordered segments (left → right). Widths are proportional to `value`. */\n data: ReadonlyArray<CategoryBarSegment>;\n /** Maps each segment `key` to a `label` and `color` (an existing `--ui-*` token). */\n config: ChartConfig;\n /** Show the legend below the bar (color dot + label + value + %). */\n showLegend?: boolean;\n /** Show a hover tooltip per segment (dot + label + value + %). */\n showTooltip?: boolean;\n /**\n * Custom tooltip content per segment — replaces the default (dot + label +\n * `value · %`) inside the same card. Ignored when `showTooltip` is false.\n */\n tooltipContent?: (segment: CategoryBarTooltipContext) => React.ReactNode;\n /** Format the numeric value (legend + tooltip). Defaults to `toLocaleString()`. */\n valueFormatter?: (value: number) => string;\n /** Render the tooltip for this segment index initially open (VR/testing). */\n defaultOpenIndex?: number;\n /**\n * Accessible summary of the whole bar. Defaults to a `label value` list built\n * from the data; pass a fuller sentence for screen readers if you have one.\n */\n 'aria-label'?: string;\n}\n\n/**\n * One segment's hover card.\n *\n * It re-declares `data-chart` and re-renders `ChartStyle` because the popup is\n * portaled out of the bar: outside that subtree the `--color-*` bridge the\n * swatch reads has nothing to resolve against.\n */\nfunction CategoryBarSegmentTooltip({\n chartId,\n config,\n color,\n label,\n percent,\n segmentKey,\n value,\n valueFormatter,\n renderContent,\n}: {\n chartId: string;\n config: ChartConfig;\n color: string;\n label: React.ReactNode;\n percent: number;\n segmentKey: string;\n value: number;\n valueFormatter: (value: number) => string;\n // Not named `render`: in this package that name is reserved for Base UI's\n // polymorphic composition prop (see `<TooltipTrigger render={…} />` below).\n renderContent?: (segment: CategoryBarTooltipContext) => React.ReactNode;\n}) {\n return (\n <TooltipContent\n data-chart={chartId}\n className={cn(\n 'border border-border bg-background text-foreground shadow-md',\n !renderContent && 'flex items-center gap-2'\n )}\n >\n <ChartStyle id={chartId} config={config} />\n {renderContent ? (\n renderContent({ key: segmentKey, value, label, percent, color })\n ) : (\n <>\n <span\n className=\"size-2.5 shrink-0 rounded-full\"\n style={{ backgroundColor: color }}\n />\n <span className=\"font-semibold\">{label}</span>\n <span className=\"text-muted-foreground tabular-nums\">\n {valueFormatter(value)} · {percent}%\n </span>\n </>\n )}\n </TooltipContent>\n );\n}\n\nconst CategoryBar = React.forwardRef<HTMLDivElement, CategoryBarProps>(\n (\n {\n className,\n data,\n config,\n size,\n showLegend = false,\n showTooltip = true,\n tooltipContent,\n valueFormatter = defaultFormat,\n defaultOpenIndex,\n 'aria-label': ariaLabel,\n ...props\n },\n ref\n ) => {\n const uniqueId = React.useId();\n const chartId = `chart-${uniqueId.replace(/:/g, '')}`;\n\n const total = data.reduce((sum, seg) => sum + seg.value, 0);\n const labelFor = (key: string): React.ReactNode => config[key]?.label ?? key;\n // The aria-label has to be a plain string, so a rich (element) label can't\n // be used there — fall back to the key rather than stringifying it into\n // \"[object Object]\".\n const labelTextFor = (key: string) => {\n const label = config[key]?.label;\n return typeof label === 'string' || typeof label === 'number'\n ? String(label)\n : key;\n };\n const colorOf = (key: string) => `var(--color-${key})`;\n const pctOf = (value: number) =>\n total > 0 ? Math.round((value / total) * 100) : 0;\n\n // A locale-neutral fallback: \"<label> <value>\" pairs. Consumers can pass a\n // fuller `aria-label` sentence.\n const summary =\n ariaLabel ??\n data\n .map((seg) => `${labelTextFor(seg.key)} ${valueFormatter(seg.value)}`)\n .join(', ');\n\n return (\n <div\n ref={ref}\n data-chart={chartId}\n className={cn('flex w-full flex-col gap-3', className)}\n {...props}\n >\n <ChartStyle id={chartId} config={config} />\n <div className={categoryBarVariants({ size })} role=\"img\" aria-label={summary}>\n {data.map((seg, index) => {\n const color = colorOf(seg.key);\n // flex-grow proportional to value with a zero basis → widths are\n // exactly value/total; a zero-value segment collapses.\n const segment = (\n <div\n key={seg.key}\n className=\"h-full min-w-0\"\n style={{ flex: `${seg.value} 0 0%`, backgroundColor: color }}\n />\n );\n\n if (!showTooltip) return segment;\n\n return (\n <Tooltip key={seg.key} defaultOpen={index === defaultOpenIndex}>\n <TooltipTrigger render={segment} />\n <CategoryBarSegmentTooltip\n chartId={chartId}\n config={config}\n color={color}\n label={labelFor(seg.key)}\n percent={pctOf(seg.value)}\n segmentKey={seg.key}\n value={seg.value}\n valueFormatter={valueFormatter}\n renderContent={tooltipContent}\n />\n </Tooltip>\n );\n })}\n </div>\n\n {showLegend && (\n <ul className=\"flex flex-wrap justify-between gap-x-6 gap-y-3\">\n {data.map((seg) => (\n <li key={seg.key} className=\"flex flex-col gap-1.5\">\n <span className=\"flex items-center gap-1.5 text-sm leading-none text-muted-foreground\">\n <span\n className=\"size-2.5 shrink-0 rounded-sm\"\n style={{ backgroundColor: colorOf(seg.key) }}\n />\n {labelFor(seg.key)}\n </span>\n <span className=\"flex items-baseline gap-1.5 leading-none tabular-nums\">\n <span className=\"text-base font-semibold text-foreground\">\n {valueFormatter(seg.value)}\n </span>\n <span className=\"text-sm text-muted-foreground\">\n {pctOf(seg.value)}%\n </span>\n </span>\n </li>\n ))}\n </ul>\n )}\n </div>\n );\n }\n);\nCategoryBar.displayName = 'CategoryBar';\n\nexport { CategoryBar, categoryBarVariants };\n"],"names":["defaultFormat","value","categoryBarVariants","cva","CategoryBarSegmentTooltip","chartId","config","color","label","percent","segmentKey","valueFormatter","renderContent","jsxs","TooltipContent","cn","jsx","ChartStyle","Fragment","CategoryBar","React","className","data","size","showLegend","showTooltip","tooltipContent","defaultOpenIndex","ariaLabel","props","ref","total","sum","seg","labelFor","key","_a","labelTextFor","colorOf","pctOf","summary","index","segment","Tooltip","TooltipTrigger"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"category-bar.js","sources":["../../../../src/components/ui/category-bar/category-bar.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nimport { cn } from '@/lib/utils';\nimport {\n CHART_DEFAULT_PALETTE,\n ChartStyle,\n resolveChartColors,\n type ChartConfig,\n type ChartPalette,\n type ResolvedChartConfig,\n} from '../chart';\nimport { Tooltip, TooltipContent, TooltipTrigger } from '../tooltip';\n\n// A category bar: a single horizontal bar split into proportional colored\n// segments — one part-to-whole across a handful of categories, in one row\n// (onboarding stages, certification status, a rating scale). Unlike `Meter`\n// (one value per row, stacked into a bar list), all segments share the same bar.\n// It's a plain flex composition, not a recharts chart: each segment's width is\n// `value / total`, so exact proportions and the count/% legend are direct DOM,\n// with no axes/grid to hide. Segment colors come from the `palette` prop, the\n// same dataviz palettes the recharts charts use.\n//\n// Colors are consumed through the same `--color-<key>` bridge the recharts\n// charts use: `ChartStyle` emits one custom property per config entry, so a\n// `theme: { light, dark }` entry works as well as a flat `color` — reading\n// `config[key].color` directly would render a themed config colorless. The\n// tooltip is portaled out of the bar's DOM, so its popup carries its own\n// `data-chart` scope + `ChartStyle` to keep the bridge resolvable there.\n\nconst defaultFormat = (value: number) => value.toLocaleString();\n\n// Track height only — the flex/rounded/overflow chrome is static.\nconst categoryBarVariants = cva(\n 'flex w-full overflow-hidden rounded-full bg-input',\n {\n variants: {\n size: {\n sm: 'h-1.5',\n md: 'h-2.5',\n lg: 'h-4',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n }\n);\n\nexport interface CategoryBarSegment {\n /** Key into `config` for this segment's label + color. */\n key: string;\n /** The segment's value — its width is this over the sum of all values. */\n value: number;\n}\n\n/** The resolved segment passed to a custom `tooltipContent` renderer. */\nexport interface CategoryBarTooltipContext extends CategoryBarSegment {\n /** Resolved `config` label (falls back to the key); may be any `ReactNode`. */\n label: React.ReactNode;\n /** Share of the total as a rounded percentage (0–100). */\n percent: number;\n /**\n * CSS color reference for the segment — the `var(--color-<key>)` bridge, which\n * resolves the palette stop assigned to this segment. Usable anywhere a CSS\n * color is (e.g. a `style` background); not a literal value.\n */\n color: string;\n}\n\nexport interface CategoryBarProps\n extends\n Omit<React.ComponentProps<'div'>, 'children'>,\n VariantProps<typeof categoryBarVariants> {\n /** Ordered segments (left → right). Widths are proportional to `value`. */\n data: ReadonlyArray<CategoryBarSegment>;\n /** Maps each segment `key` to a `label` and, optionally, a palette `tone`. */\n config: ChartConfig;\n /**\n * The dataviz palette the segments are painted from. Segments take a stop of\n * it in the palette's defined order, or the one their `tone` names. Defaults\n * to `categorical`.\n */\n palette?: ChartPalette;\n /** Show the legend below the bar (color dot + label + value + %). */\n showLegend?: boolean;\n /** Show a hover tooltip per segment (dot + label + value + %). */\n showTooltip?: boolean;\n /**\n * Custom tooltip content per segment — replaces the default (dot + label +\n * `value · %`) inside the same card. Ignored when `showTooltip` is false.\n */\n tooltipContent?: (segment: CategoryBarTooltipContext) => React.ReactNode;\n /** Format the numeric value (legend + tooltip). Defaults to `toLocaleString()`. */\n valueFormatter?: (value: number) => string;\n /** Render the tooltip for this segment index initially open (VR/testing). */\n defaultOpenIndex?: number;\n /**\n * Accessible summary of the whole bar. Defaults to a `label value` list built\n * from the data; pass a fuller sentence for screen readers if you have one.\n */\n 'aria-label'?: string;\n}\n\n/**\n * One segment's hover card.\n *\n * It re-declares `data-chart` and re-renders `ChartStyle` because the popup is\n * portaled out of the bar: outside that subtree the `--color-*` bridge the\n * swatch reads has nothing to resolve against.\n */\nfunction CategoryBarSegmentTooltip({\n chartId,\n config,\n color,\n label,\n percent,\n segmentKey,\n value,\n valueFormatter,\n renderContent,\n}: {\n chartId: string;\n config: ResolvedChartConfig;\n color: string;\n label: React.ReactNode;\n percent: number;\n segmentKey: string;\n value: number;\n valueFormatter: (value: number) => string;\n // Not named `render`: in this package that name is reserved for Base UI's\n // polymorphic composition prop (see `<TooltipTrigger render={…} />` below).\n renderContent?: (segment: CategoryBarTooltipContext) => React.ReactNode;\n}) {\n return (\n <TooltipContent\n data-chart={chartId}\n className={cn(\n 'border border-border bg-background text-foreground shadow-md',\n !renderContent && 'flex items-center gap-2'\n )}\n >\n <ChartStyle id={chartId} config={config} />\n {renderContent ? (\n renderContent({ key: segmentKey, value, label, percent, color })\n ) : (\n <>\n <span\n className=\"size-2.5 shrink-0 rounded-full\"\n style={{ backgroundColor: color }}\n />\n <span className=\"font-semibold\">{label}</span>\n <span className=\"text-muted-foreground tabular-nums\">\n {valueFormatter(value)} · {percent}%\n </span>\n </>\n )}\n </TooltipContent>\n );\n}\n\nconst CategoryBar = React.forwardRef<HTMLDivElement, CategoryBarProps>(\n (\n {\n className,\n data,\n config,\n palette = CHART_DEFAULT_PALETTE,\n size,\n showLegend = false,\n showTooltip = true,\n tooltipContent,\n valueFormatter = defaultFormat,\n defaultOpenIndex,\n 'aria-label': ariaLabel,\n ...props\n },\n ref\n ) => {\n const uniqueId = React.useId();\n const chartId = `chart-${uniqueId.replace(/:/g, '')}`;\n // Resolved here rather than by a `ChartContainer`: this component paints\n // plain divs, not a recharts plot, so it owns the `--color-*` emission for\n // both the bar and its portaled per-segment tooltip.\n const resolvedConfig = React.useMemo(\n () => resolveChartColors(config, palette),\n [config, palette]\n );\n\n const total = data.reduce((sum, seg) => sum + seg.value, 0);\n const labelFor = (key: string): React.ReactNode =>\n config[key]?.label ?? key;\n // The aria-label has to be a plain string, so a rich (element) label can't\n // be used there — fall back to the key rather than stringifying it into\n // \"[object Object]\".\n const labelTextFor = (key: string) => {\n const label = config[key]?.label;\n return typeof label === 'string' || typeof label === 'number'\n ? String(label)\n : key;\n };\n const colorOf = (key: string) => `var(--color-${key})`;\n const pctOf = (value: number) =>\n total > 0 ? Math.round((value / total) * 100) : 0;\n\n // A locale-neutral fallback: \"<label> <value>\" pairs. Consumers can pass a\n // fuller `aria-label` sentence.\n const summary =\n ariaLabel ??\n data\n .map((seg) => `${labelTextFor(seg.key)} ${valueFormatter(seg.value)}`)\n .join(', ');\n\n return (\n <div\n ref={ref}\n data-chart={chartId}\n className={cn('flex w-full flex-col gap-3', className)}\n {...props}\n >\n <ChartStyle id={chartId} config={resolvedConfig} />\n <div\n className={categoryBarVariants({ size })}\n role=\"img\"\n aria-label={summary}\n >\n {data.map((seg, index) => {\n const color = colorOf(seg.key);\n // flex-grow proportional to value with a zero basis → widths are\n // exactly value/total; a zero-value segment collapses.\n const segment = (\n <div\n key={seg.key}\n className=\"h-full min-w-0\"\n style={{ flex: `${seg.value} 0 0%`, backgroundColor: color }}\n />\n );\n\n if (!showTooltip) return segment;\n\n return (\n <Tooltip key={seg.key} defaultOpen={index === defaultOpenIndex}>\n <TooltipTrigger render={segment} />\n <CategoryBarSegmentTooltip\n chartId={chartId}\n config={resolvedConfig}\n color={color}\n label={labelFor(seg.key)}\n percent={pctOf(seg.value)}\n segmentKey={seg.key}\n value={seg.value}\n valueFormatter={valueFormatter}\n renderContent={tooltipContent}\n />\n </Tooltip>\n );\n })}\n </div>\n\n {showLegend && (\n <ul className=\"flex flex-wrap justify-between gap-x-6 gap-y-3\">\n {data.map((seg) => (\n <li key={seg.key} className=\"flex flex-col gap-1.5\">\n <span className=\"flex items-center gap-1.5 text-sm leading-none text-muted-foreground\">\n <span\n className=\"size-2.5 shrink-0 rounded-sm\"\n style={{ backgroundColor: colorOf(seg.key) }}\n />\n {labelFor(seg.key)}\n </span>\n <span className=\"flex items-baseline gap-1.5 leading-none tabular-nums\">\n <span className=\"text-base font-semibold text-foreground\">\n {valueFormatter(seg.value)}\n </span>\n <span className=\"text-sm text-muted-foreground\">\n {pctOf(seg.value)}%\n </span>\n </span>\n </li>\n ))}\n </ul>\n )}\n </div>\n );\n }\n);\nCategoryBar.displayName = 'CategoryBar';\n\nexport { CategoryBar, categoryBarVariants };\n"],"names":["defaultFormat","value","categoryBarVariants","cva","CategoryBarSegmentTooltip","chartId","config","color","label","percent","segmentKey","valueFormatter","renderContent","jsxs","TooltipContent","cn","jsx","ChartStyle","Fragment","CategoryBar","React","className","data","palette","CHART_DEFAULT_PALETTE","size","showLegend","showTooltip","tooltipContent","defaultOpenIndex","ariaLabel","props","ref","resolvedConfig","resolveChartColors","total","sum","seg","labelFor","key","_a","labelTextFor","colorOf","pctOf","summary","index","segment","Tooltip","TooltipTrigger"],"mappings":"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"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
const s = (e) => `var(--ui-dataviz-${e})`, f = Object.freeze(
|
|
2
|
+
Array.from({ length: 16 }, (e, t) => s(`categorical-${t + 1}`))
|
|
3
|
+
), h = Object.freeze({
|
|
4
|
+
blue: Object.freeze(
|
|
5
|
+
Array.from({ length: 8 }, (e, t) => s(`sequential-blue-${t + 1}`))
|
|
6
|
+
),
|
|
7
|
+
teal: Object.freeze(
|
|
8
|
+
Array.from({ length: 8 }, (e, t) => s(`sequential-teal-${t + 1}`))
|
|
9
|
+
),
|
|
10
|
+
orange: Object.freeze(
|
|
11
|
+
Array.from({ length: 8 }, (e, t) => s(`sequential-orange-${t + 1}`))
|
|
12
|
+
),
|
|
13
|
+
violet: Object.freeze(
|
|
14
|
+
Array.from({ length: 8 }, (e, t) => s(`sequential-violet-${t + 1}`))
|
|
15
|
+
)
|
|
16
|
+
}), g = (e) => Object.freeze([
|
|
17
|
+
s(`diverging-${e}-a3`),
|
|
18
|
+
s(`diverging-${e}-a2`),
|
|
19
|
+
s(`diverging-${e}-a1`),
|
|
20
|
+
s(`diverging-${e}-b1`),
|
|
21
|
+
s(`diverging-${e}-b2`),
|
|
22
|
+
s(`diverging-${e}-b3`)
|
|
23
|
+
]), b = Object.freeze({
|
|
24
|
+
"blue-orange": g("blue-orange"),
|
|
25
|
+
"teal-violet": g("teal-violet")
|
|
26
|
+
}), u = Object.freeze({
|
|
27
|
+
danger: s("meaningful-status-danger"),
|
|
28
|
+
critical: s("meaningful-status-critical"),
|
|
29
|
+
warning: s("meaningful-status-warning"),
|
|
30
|
+
success: s("meaningful-status-success"),
|
|
31
|
+
info: s("meaningful-status-info"),
|
|
32
|
+
neutral: s("meaningful-status-neutral")
|
|
33
|
+
}), p = Object.freeze({
|
|
34
|
+
type: "categorical"
|
|
35
|
+
});
|
|
36
|
+
function d(e) {
|
|
37
|
+
switch (e.type) {
|
|
38
|
+
case "categorical":
|
|
39
|
+
return f;
|
|
40
|
+
case "sequential":
|
|
41
|
+
return h[e.ramp];
|
|
42
|
+
case "diverging":
|
|
43
|
+
return b[e.pair];
|
|
44
|
+
case "status":
|
|
45
|
+
return [];
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function A(e) {
|
|
49
|
+
switch (e.type) {
|
|
50
|
+
case "status":
|
|
51
|
+
return Object.keys(u).map(
|
|
52
|
+
(t) => ({ status: t })
|
|
53
|
+
);
|
|
54
|
+
case "categorical":
|
|
55
|
+
return f.map((t, r) => ({ slot: r + 1 }));
|
|
56
|
+
default:
|
|
57
|
+
return [];
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function i(e) {
|
|
61
|
+
process.env.NODE_ENV !== "production" && console.warn(`[ui-react] ${e}`);
|
|
62
|
+
}
|
|
63
|
+
function m(e, t, r) {
|
|
64
|
+
const a = Math.round(e);
|
|
65
|
+
return !Number.isFinite(e) || a < 1 || a > t ? (i(
|
|
66
|
+
`Chart series slot ${e} is outside the "${r.type}" palette (1–${t}). Clamping.`
|
|
67
|
+
), Math.min(
|
|
68
|
+
Math.max(Number.isFinite(a) ? a : 1, 1),
|
|
69
|
+
t
|
|
70
|
+
)) : a;
|
|
71
|
+
}
|
|
72
|
+
function $(e, { index: t, tone: r }) {
|
|
73
|
+
if (e.type === "status")
|
|
74
|
+
return r != null && r.status ? u[r.status] : (i(
|
|
75
|
+
'A chart series has no `status` under the "status" palette. Falling back to neutral.'
|
|
76
|
+
), u.neutral);
|
|
77
|
+
const a = d(e);
|
|
78
|
+
if (r != null && r.status)
|
|
79
|
+
i(
|
|
80
|
+
`A chart series names a status ("${r.status}") under the "${e.type}" palette, which has no status tones. Ignoring.`
|
|
81
|
+
);
|
|
82
|
+
else if (typeof (r == null ? void 0 : r.slot) == "number") {
|
|
83
|
+
if (e.type === "categorical")
|
|
84
|
+
return a[m(r.slot, a.length, e) - 1];
|
|
85
|
+
i(
|
|
86
|
+
`A chart series pins slot ${r.slot} under the "${e.type}" palette, whose stops are a ramp and are not individually selectable. Ignoring.`
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
return a[t % a.length];
|
|
90
|
+
}
|
|
91
|
+
function v(e, t) {
|
|
92
|
+
var a, c;
|
|
93
|
+
const r = /* @__PURE__ */ new Map();
|
|
94
|
+
for (const [n, l] of Object.entries(e)) {
|
|
95
|
+
if ((c = (a = t == null ? void 0 : t[n]) == null ? void 0 : a.tone) != null && c.sameAs)
|
|
96
|
+
continue;
|
|
97
|
+
const o = r.get(l);
|
|
98
|
+
o ? o.push(n) : r.set(l, [n]);
|
|
99
|
+
}
|
|
100
|
+
return [...r.values()].filter((n) => n.length > 1);
|
|
101
|
+
}
|
|
102
|
+
export {
|
|
103
|
+
f as CHART_CATEGORICAL_TOKENS,
|
|
104
|
+
p as CHART_DEFAULT_PALETTE,
|
|
105
|
+
b as CHART_DIVERGING_TOKENS,
|
|
106
|
+
h as CHART_SEQUENTIAL_TOKENS,
|
|
107
|
+
u as CHART_STATUS_TOKENS,
|
|
108
|
+
v as findDuplicateTones,
|
|
109
|
+
A as listPaletteChoices,
|
|
110
|
+
d as listPaletteStops,
|
|
111
|
+
$ as resolveSeriesColor
|
|
112
|
+
};
|
|
113
|
+
//# sourceMappingURL=chart-palette.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart-palette.js","sources":["../../../../src/components/ui/chart/chart-palette.ts"],"sourcesContent":["// The dataviz palettes a chart paints its series from.\n//\n// Every color here resolves to a `--ui-dataviz-*` token from\n// `@acronis-platform/tokens-pd`'s semantic tier (already imported by\n// `styles/index.css`), so light/dark and brand overrides come for free — the\n// tokens are `light-dark()` pairs. There is deliberately no `--ui-chart-*`\n// component tier: these tokens are already semantic and shared across every\n// chart type, and a 1:1 alias layer would be pure indirection (see\n// `context/conventions.md`, \"bridge what's reused\").\n//\n// The four palettes mirror the product's widget editor, which offers exactly\n// this choice — Categorical / Sequential / Diverging / Status — and then, for\n// Categorical and Status only, a per-series color picker. Sequential and\n// Diverging expose the ramp/pair and nothing else, so how N series spread\n// across a ramp's stops is this module's decision, not the user's.\n\n/** A sequential ramp: one hue, eight stops from lightest to darkest. */\nexport type ChartSequentialRamp = 'blue' | 'teal' | 'orange' | 'violet';\n\n/** A diverging pair: two hues meeting at a pale midpoint. */\nexport type ChartDivergingPair = 'blue-orange' | 'teal-violet';\n\n/**\n * A semantic status tone. Ordered by severity in the product's picker:\n * danger (red) · critical (orange) · warning (yellow) · success (green) ·\n * info (blue) · neutral (gray). Note that `critical` is orange and ranks\n * *below* `danger` — that is what the tokens say, across the whole semantic\n * tier, not a typo here.\n */\nexport type ChartStatusTone =\n | 'danger'\n | 'critical'\n | 'warning'\n | 'success'\n | 'info'\n | 'neutral';\n\n/** Which palette a chart's series are painted from. */\nexport type ChartPalette =\n | { type: 'categorical' }\n | { type: 'sequential'; ramp: ChartSequentialRamp }\n | { type: 'diverging'; pair: ChartDivergingPair }\n | { type: 'status' };\n\n/**\n * How one series picks its color out of the active palette.\n *\n * Only the two palettes whose colors are independent of each other accept an\n * override:\n *\n * - `categorical` — `{ slot }` picks one of the 16 hues.\n * - `status` — `{ status }` names a tone.\n *\n * `sequential` and `diverging` accept none. Their stops are a *ramp*: the\n * colors mean something only in relation to each other, so letting one series\n * jump to an arbitrary stop would break the reading order the ramp exists to\n * convey. The product's widget editor agrees — it offers a ramp/pair picker\n * and no per-series control. An override passed under those palettes is\n * ignored, with a dev warning.\n *\n * Neither form can express a color from outside the palette — that is the point.\n */\nexport type ChartSeriesTone =\n | { slot: number; status?: never; sameAs?: never }\n | { slot?: never; status: ChartStatusTone; sameAs?: never }\n /**\n * Paint whatever the series under this key paints, under any palette. For a\n * twin series that is the *same* metric drawn differently — a forecast tail\n * continuing its actuals, a projection band behind its bars — where two hues\n * would read as two metrics. Resolved by `resolveChartColors`, which is the\n * only place the whole config is in view.\n */\n | { slot?: never; status?: never; sameAs: string };\n\nconst token = (name: string) => `var(--ui-dataviz-${name})`;\n\n/** The 16 categorical hues, in the order the product's picker lists them. */\nexport const CHART_CATEGORICAL_TOKENS = Object.freeze(\n Array.from({ length: 16 }, (_, i) => token(`categorical-${i + 1}`))\n);\n\n/** Each sequential ramp's eight stops, lightest (1) to darkest (8). */\nexport const CHART_SEQUENTIAL_TOKENS: Readonly<\n Record<ChartSequentialRamp, readonly string[]>\n> = Object.freeze({\n blue: Object.freeze(\n Array.from({ length: 8 }, (_, i) => token(`sequential-blue-${i + 1}`))\n ),\n teal: Object.freeze(\n Array.from({ length: 8 }, (_, i) => token(`sequential-teal-${i + 1}`))\n ),\n orange: Object.freeze(\n Array.from({ length: 8 }, (_, i) => token(`sequential-orange-${i + 1}`))\n ),\n violet: Object.freeze(\n Array.from({ length: 8 }, (_, i) => token(`sequential-violet-${i + 1}`))\n ),\n});\n\n// Ordered `a3 → a1` then `b1 → b3`: strongest of the first hue, through the two\n// pale midpoints, out to the strongest of the second. That is the order the\n// ChartTreeMap mockup paints its tiles in (Figma node 8999:72012), and it is\n// what makes a diverging palette read as a single gradient rather than two\n// unrelated ramps.\nconst divergingStops = (pair: string) =>\n Object.freeze([\n token(`diverging-${pair}-a3`),\n token(`diverging-${pair}-a2`),\n token(`diverging-${pair}-a1`),\n token(`diverging-${pair}-b1`),\n token(`diverging-${pair}-b2`),\n token(`diverging-${pair}-b3`),\n ]);\n\n/** Each diverging pair's six stops, one hue's strongest through to the other's. */\nexport const CHART_DIVERGING_TOKENS: Readonly<\n Record<ChartDivergingPair, readonly string[]>\n> = Object.freeze({\n 'blue-orange': divergingStops('blue-orange'),\n 'teal-violet': divergingStops('teal-violet'),\n});\n\n/** The six semantic status tones. */\nexport const CHART_STATUS_TOKENS: Readonly<Record<ChartStatusTone, string>> =\n Object.freeze({\n danger: token('meaningful-status-danger'),\n critical: token('meaningful-status-critical'),\n warning: token('meaningful-status-warning'),\n success: token('meaningful-status-success'),\n info: token('meaningful-status-info'),\n neutral: token('meaningful-status-neutral'),\n });\n\n/** The default palette — what a chart paints with when none is chosen. */\nexport const CHART_DEFAULT_PALETTE: ChartPalette = Object.freeze({\n type: 'categorical',\n});\n\n/**\n * The stops a palette offers, in picker order. `status` has named tones rather\n * than positional stops, so it returns an empty list — use\n * `CHART_STATUS_TOKENS` for those.\n */\nexport function listPaletteStops(palette: ChartPalette): readonly string[] {\n switch (palette.type) {\n case 'categorical':\n return CHART_CATEGORICAL_TOKENS;\n case 'sequential':\n return CHART_SEQUENTIAL_TOKENS[palette.ramp];\n case 'diverging':\n return CHART_DIVERGING_TOKENS[palette.pair];\n case 'status':\n return [];\n }\n}\n\n/**\n * Every choice a per-series picker may offer for this palette — what the\n * product's widget editor renders in its dropdown. Pure, so the form can build\n * its UI without re-deriving the palette.\n *\n * Empty for `sequential` and `diverging`: those have no per-series control, so\n * a form driven by this function renders no picker for them, which is exactly\n * the design.\n */\nexport function listPaletteChoices(\n palette: ChartPalette\n): readonly ChartSeriesTone[] {\n switch (palette.type) {\n case 'status':\n return (Object.keys(CHART_STATUS_TOKENS) as ChartStatusTone[]).map(\n (status) => ({ status })\n );\n case 'categorical':\n return CHART_CATEGORICAL_TOKENS.map((_, i) => ({ slot: i + 1 }));\n default:\n return [];\n }\n}\n\nfunction warn(message: string) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(`[ui-react] ${message}`);\n }\n}\n\nfunction clampSlot(slot: number, length: number, palette: ChartPalette) {\n const rounded = Math.round(slot);\n\n if (!Number.isFinite(slot) || rounded < 1 || rounded > length) {\n warn(\n `Chart series slot ${slot} is outside the \"${palette.type}\" palette (1–${length}). Clamping.`\n );\n return Math.min(\n Math.max(Number.isFinite(rounded) ? rounded : 1, 1),\n length\n );\n }\n\n return rounded;\n}\n\nexport interface ResolveSeriesColorOptions {\n /** This series' position among the chart's series. */\n index: number;\n /** This series' explicit choice within the palette, if it may make one. */\n tone?: ChartSeriesTone;\n}\n\n/**\n * The color one series paints with.\n *\n * Series walk the palette **in its defined order** — series 1 takes stop 1,\n * series 2 takes stop 2, and so on, wrapping once the stops run out. The order\n * is the design's, not something derived here: no re-ordering, no spreading\n * across a ramp, no skipping stops.\n *\n * On top of that, `categorical` and `status` honour a per-series override\n * (see `ChartSeriesTone`); `sequential` and `diverging` do not.\n *\n * Always returns a token from the active palette. A `slot` out of range is\n * clamped (with a dev warning) rather than passed through, so switching\n * palettes can never leave a series painting off-palette.\n */\nexport function resolveSeriesColor(\n palette: ChartPalette,\n { index, tone }: ResolveSeriesColorOptions\n): string {\n if (palette.type === 'status') {\n if (tone?.status) {\n return CHART_STATUS_TOKENS[tone.status];\n }\n\n // Unlike the ordered palettes there is no meaningful \"next\" tone to fall\n // back to — status colors carry meaning, and inventing one would be worse\n // than reading gray.\n warn(\n 'A chart series has no `status` under the \"status\" palette. Falling back to neutral.'\n );\n return CHART_STATUS_TOKENS.neutral;\n }\n\n const stops = listPaletteStops(palette);\n\n if (tone?.status) {\n warn(\n `A chart series names a status (\"${tone.status}\") under the \"${palette.type}\" palette, which has no status tones. Ignoring.`\n );\n } else if (typeof tone?.slot === 'number') {\n if (palette.type === 'categorical') {\n return stops[clampSlot(tone.slot, stops.length, palette) - 1];\n }\n\n warn(\n `A chart series pins slot ${tone.slot} under the \"${palette.type}\" palette, whose stops are a ramp and are not individually selectable. Ignoring.`\n );\n }\n\n // Wraps rather than clamps once the stops run out: a chart with more series\n // than the palette has colors is unreadable either way, but wrapping keeps\n // each series distinguishable from its immediate neighbours.\n return stops[index % stops.length];\n}\n\n/**\n * Series that would paint the same color — what the widget editor's \"duplicate\n * color\" warning is keyed to. Returns one group per collision, each holding the\n * colliding series' keys in input order.\n *\n * Only series that named a `tone` can collide: automatic assignment is\n * injective by construction (up to `categorical`'s 16-series wrap).\n *\n * Pass the chart's `config` to exclude intentional aliases: a series with\n * `tone: { sameAs }` shares its target's colour on purpose, so it is not a\n * collision. Without the config every alias reads as a duplicate.\n */\nexport function findDuplicateTones(\n colors: Readonly<Record<string, string>>,\n config?: Readonly<Record<string, { tone?: { sameAs?: string } }>>\n): string[][] {\n const byColor = new Map<string, string[]>();\n\n for (const [key, color] of Object.entries(colors)) {\n if (config?.[key]?.tone?.sameAs) {\n continue;\n }\n const group = byColor.get(color);\n if (group) {\n group.push(key);\n } else {\n byColor.set(color, [key]);\n }\n }\n\n return [...byColor.values()].filter((group) => group.length > 1);\n}\n"],"names":["token","name","CHART_CATEGORICAL_TOKENS","_","i","CHART_SEQUENTIAL_TOKENS","divergingStops","pair","CHART_DIVERGING_TOKENS","CHART_STATUS_TOKENS","CHART_DEFAULT_PALETTE","listPaletteStops","palette","listPaletteChoices","status","warn","message","clampSlot","slot","length","rounded","resolveSeriesColor","index","tone","stops","findDuplicateTones","colors","config","_a","_b","byColor","key","color","group"],"mappings":"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"}
|