@spaced-out/ui-design-system 0.6.23 → 0.6.25
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/CHANGELOG.md +14 -0
- package/lib/components/Charts/ChartWrapper/ChartWrapper.js +1 -1
- package/lib/components/Charts/DonutChart/DonutChart.d.ts +4 -1
- package/lib/components/Charts/DonutChart/DonutChart.d.ts.map +1 -1
- package/lib/components/Charts/DonutChart/DonutChart.js +58 -5
- package/lib/components/Charts/DonutChart/DonutChart.module.css +25 -0
- package/lib/components/Chip/Chip.module.css +6 -1
- package/lib/components/Chip/Pill.d.ts +32 -0
- package/lib/components/Chip/Pill.d.ts.map +1 -0
- package/lib/components/Chip/Pill.js +72 -0
- package/lib/components/Chip/index.d.ts +2 -0
- package/lib/components/Chip/index.d.ts.map +1 -1
- package/lib/components/Chip/index.js +14 -1
- package/lib/utils/charts/donutChart.d.ts +21 -1
- package/lib/utils/charts/donutChart.d.ts.map +1 -1
- package/lib/utils/charts/donutChart.js +57 -5
- package/lib/utils/charts/helpers.d.ts +7 -0
- package/lib/utils/charts/helpers.d.ts.map +1 -1
- package/lib/utils/charts/helpers.js +13 -1
- package/mcp/package.json +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
### [0.6.25](https://github.com/spaced-out/ui-design-system/compare/v0.6.24...v0.6.25) (2026-07-01)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* add total and legend value/percent support to donut chart ([#494](https://github.com/spaced-out/ui-design-system/issues/494)) ([23b07df](https://github.com/spaced-out/ui-design-system/commit/23b07df5f5cb870be2df66dda2603fe6b4e1a1b1))
|
|
11
|
+
|
|
12
|
+
### [0.6.24](https://github.com/spaced-out/ui-design-system/compare/v0.6.23...v0.6.24) (2026-06-25)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
|
|
17
|
+
* pill component ([#492](https://github.com/spaced-out/ui-design-system/issues/492)) ([001a9ef](https://github.com/spaced-out/ui-design-system/commit/001a9ef9c132642ffd17cfde9fe990dabac3cb8f))
|
|
18
|
+
|
|
5
19
|
### [0.6.23](https://github.com/spaced-out/ui-design-system/compare/v0.6.22...v0.6.23) (2026-06-25)
|
|
6
20
|
|
|
7
21
|
|
|
@@ -83,7 +83,7 @@ const CustomExportButton = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
83
83
|
size: 'medium',
|
|
84
84
|
width: _size.size180
|
|
85
85
|
},
|
|
86
|
-
iconLeftName: "
|
|
86
|
+
iconLeftName: "cloud-arrow-down",
|
|
87
87
|
onOptionSelect: option => handleDownload(option.key),
|
|
88
88
|
size: "small",
|
|
89
89
|
type: "ghost",
|
|
@@ -18,6 +18,9 @@ export interface DonutChartProps extends Omit<ChartOptions, 'isLoading' | 'class
|
|
|
18
18
|
headerActions?: React.ReactNode;
|
|
19
19
|
centerText?: string;
|
|
20
20
|
centerSubtext?: string;
|
|
21
|
+
showTotal?: boolean;
|
|
22
|
+
showLegendValues?: boolean;
|
|
23
|
+
formatValue?: (value: number) => string;
|
|
21
24
|
series: Array<PieSeriesOptions>;
|
|
22
25
|
drilldown?: Drilldown;
|
|
23
26
|
legend?: LegendOptionsType;
|
|
@@ -25,6 +28,6 @@ export interface DonutChartProps extends Omit<ChartOptions, 'isLoading' | 'class
|
|
|
25
28
|
emptyText?: React.ReactNode;
|
|
26
29
|
testId?: string;
|
|
27
30
|
}
|
|
28
|
-
export declare const DonutChart: ({ isLoading, classNames, cardTitle, customExportOptions, headerActions, series, drilldown, legend, centerText, centerSubtext, hasEmptyData, emptyText, testId, ...userOptions }: DonutChartProps) => React.JSX.Element;
|
|
31
|
+
export declare const DonutChart: ({ isLoading, classNames, cardTitle, customExportOptions, headerActions, series, drilldown, legend, centerText, centerSubtext, showTotal, showLegendValues, formatValue, hasEmptyData, emptyText, testId, ...userOptions }: DonutChartProps) => React.JSX.Element;
|
|
29
32
|
export {};
|
|
30
33
|
//# sourceMappingURL=DonutChart.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DonutChart.d.ts","sourceRoot":"","sources":["../../../../src/components/Charts/DonutChart/DonutChart.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,OAAO,KAAK,EACV,YAAY,EAGZ,SAAS,EACT,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"DonutChart.d.ts","sourceRoot":"","sources":["../../../../src/components/Charts/DonutChart/DonutChart.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,OAAO,KAAK,EACV,YAAY,EAGZ,SAAS,EACT,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,kBAAkB,CAAC;AAU1B,OAAO,KAAK,EACV,sBAAsB,EACtB,gBAAgB,EACjB,MAAM,oCAAoC,CAAC;AAO5C,KAAK,UAAU,GAAG,QAAQ,CACxB,sBAAsB,GAAG;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;CACzC,CACF,CAAC;AAEF,UAAU,kBAAkB;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eACf,SAAQ,IAAI,CACV,YAAY,EACV,WAAW,GACX,YAAY,GACZ,WAAW,GACX,qBAAqB,GACrB,eAAe,GACf,YAAY,GACZ,eAAe,GACf,QAAQ,GACR,WAAW,GACX,QAAQ,GACR,cAAc,GACd,WAAW,CACd;IACD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC5B,mBAAmB,CAAC,EAAE,KAAK,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAAC;IACrD,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACxC,MAAM,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAChC,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAgCD,eAAO,MAAM,UAAU,GAAI,2NAkBxB,eAAe,sBA8IjB,CAAC"}
|
|
@@ -15,6 +15,24 @@ var _typographyModule = _interopRequireDefault(require("../../../styles/typograp
|
|
|
15
15
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
16
16
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
17
17
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
18
|
+
// Coerce to a usable number, treating null/undefined/NaN/Infinity as 0 so a
|
|
19
|
+
// single bad data point can't render the total (or a legend value) as "NaN".
|
|
20
|
+
const toFiniteNumber = value => typeof value === 'number' && Number.isFinite(value) ? value : 0;
|
|
21
|
+
const getPointValue = point => {
|
|
22
|
+
if (typeof point === 'number') {
|
|
23
|
+
return toFiniteNumber(point);
|
|
24
|
+
}
|
|
25
|
+
if (Array.isArray(point)) {
|
|
26
|
+
return toFiniteNumber(point[1]);
|
|
27
|
+
}
|
|
28
|
+
if (point && typeof point === 'object' && 'y' in point) {
|
|
29
|
+
return toFiniteNumber(point.y);
|
|
30
|
+
}
|
|
31
|
+
return 0;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/** Sums every data-point value across all series to derive the donut total. */
|
|
35
|
+
const getDonutSeriesTotal = series => series.reduce((seriesSum, seriesItem) => seriesSum + (seriesItem.data ?? []).reduce((pointSum, point) => pointSum + getPointValue(point), 0), 0);
|
|
18
36
|
const DonutChart = _ref => {
|
|
19
37
|
let {
|
|
20
38
|
isLoading,
|
|
@@ -27,6 +45,9 @@ const DonutChart = _ref => {
|
|
|
27
45
|
legend,
|
|
28
46
|
centerText,
|
|
29
47
|
centerSubtext,
|
|
48
|
+
showTotal,
|
|
49
|
+
showLegendValues,
|
|
50
|
+
formatValue,
|
|
30
51
|
hasEmptyData,
|
|
31
52
|
emptyText,
|
|
32
53
|
testId,
|
|
@@ -38,14 +59,44 @@ const DonutChart = _ref => {
|
|
|
38
59
|
subtitleClassNames,
|
|
39
60
|
...wrapperClassNames
|
|
40
61
|
} = classNames || {};
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
62
|
+
const resolveFormatValue = formatValue ?? _charts.formatCompactNumber;
|
|
63
|
+
const buildCenterHTML = mainText => `<span class="${(0, _classify.default)(_DonutChartModule.default.subtitleWrap, subtitleClassNames?.wrapper)}">
|
|
64
|
+
<span class="${(0, _classify.default)(_typographyModule.default.jumboMedium, _DonutChartModule.default.subtitleText, subtitleClassNames?.text, _charts.CENTER_TOTAL_CLASS)}">
|
|
65
|
+
${mainText}
|
|
44
66
|
</span>
|
|
45
67
|
<span class="${(0, _classify.default)(_typographyModule.default.bodySmall, _DonutChartModule.default.subtitleSubtext, subtitleClassNames?.subtext)}">
|
|
46
68
|
${centerSubtext ? centerSubtext : ''}
|
|
47
69
|
</span>
|
|
48
|
-
|
|
70
|
+
</span>`;
|
|
71
|
+
|
|
72
|
+
// `centerText` always wins; otherwise fall back to the computed total.
|
|
73
|
+
let resolvedCenterText = centerText;
|
|
74
|
+
if (resolvedCenterText == null && showTotal) {
|
|
75
|
+
resolvedCenterText = resolveFormatValue(getDonutSeriesTotal(series));
|
|
76
|
+
}
|
|
77
|
+
const defaultCenterHTML = buildCenterHTML(resolvedCenterText ?? '');
|
|
78
|
+
|
|
79
|
+
// When the total is auto-computed (not an explicit `centerText`), let the
|
|
80
|
+
// center recompute from the *visible* points so it stays consistent with the
|
|
81
|
+
// legend percentages after a slice is toggled off in the legend. Returns just
|
|
82
|
+
// the formatted number so it can be applied via textContent (no innerHTML).
|
|
83
|
+
const getCenterTextForVisibleTotal = showTotal && centerText == null ? visibleTotal => resolveFormatValue(visibleTotal) : undefined;
|
|
84
|
+
|
|
85
|
+
// When enabled, each legend item shows the point value and percentage,
|
|
86
|
+
// right-aligned against the item name (rendered as HTML by Highcharts).
|
|
87
|
+
const legendLabelFormatter = showLegendValues ? function () {
|
|
88
|
+
// Pie legends bind `this` to a Point; narrow via `percentage` so a
|
|
89
|
+
// Series (any non-pie reuse) degrades gracefully to just its name.
|
|
90
|
+
if (!('percentage' in this)) {
|
|
91
|
+
return this.name ?? '';
|
|
92
|
+
}
|
|
93
|
+
const value = resolveFormatValue(toFiniteNumber(this.y));
|
|
94
|
+
const percent = Math.round(toFiniteNumber(this.percentage));
|
|
95
|
+
return `<span class="${(0, _classify.default)(_DonutChartModule.default.legendRow)}">
|
|
96
|
+
<span class="${(0, _classify.default)(_typographyModule.default.formLabelSmall, _DonutChartModule.default.legendName)}">${this.name}</span>
|
|
97
|
+
<span class="${(0, _classify.default)(_typographyModule.default.formLabelSmall, _DonutChartModule.default.legendValue)}">${value} (${percent}%)</span>
|
|
98
|
+
</span>`;
|
|
99
|
+
} : undefined;
|
|
49
100
|
const donutChartSeries = series.map(seriesItem => ({
|
|
50
101
|
...seriesItem,
|
|
51
102
|
type: 'pie',
|
|
@@ -71,7 +122,9 @@ const DonutChart = _ref => {
|
|
|
71
122
|
} : {};
|
|
72
123
|
const defaultLineChartOptions = (0, _charts.getDonutChartOptions)({
|
|
73
124
|
legend,
|
|
74
|
-
defaultCenterHTML
|
|
125
|
+
defaultCenterHTML,
|
|
126
|
+
legendLabelFormatter,
|
|
127
|
+
getCenterTextForVisibleTotal
|
|
75
128
|
});
|
|
76
129
|
const chartOptions = (0, _charts.mergeChartUserOptions)(defaultLineChartOptions, {
|
|
77
130
|
series: donutChartSeries,
|
|
@@ -63,3 +63,28 @@
|
|
|
63
63
|
white-space: nowrap;
|
|
64
64
|
text-overflow: ellipsis;
|
|
65
65
|
}
|
|
66
|
+
|
|
67
|
+
.legendRow {
|
|
68
|
+
display: flex;
|
|
69
|
+
align-items: center;
|
|
70
|
+
justify-content: space-between;
|
|
71
|
+
gap: spaceXSmall;
|
|
72
|
+
/* Width set at runtime so the value/percentage can hug the right edge;
|
|
73
|
+
falls back to full width if the custom property is unavailable. */
|
|
74
|
+
width: var(--donut-legend-item-width, sizeFluid);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.legendName {
|
|
78
|
+
overflow: hidden;
|
|
79
|
+
color: colorTextPrimary;
|
|
80
|
+
font-weight: fontWeightBook;
|
|
81
|
+
white-space: nowrap;
|
|
82
|
+
text-overflow: ellipsis;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.legendValue {
|
|
86
|
+
flex-shrink: 0;
|
|
87
|
+
color: colorTextPrimary;
|
|
88
|
+
font-weight: fontWeightMedium;
|
|
89
|
+
white-space: nowrap;
|
|
90
|
+
}
|
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
spaceSmall
|
|
22
22
|
) from '../../styles/variables/_space.css';
|
|
23
23
|
@value (
|
|
24
|
-
borderRadiusXSmall
|
|
24
|
+
borderRadiusXSmall,
|
|
25
|
+
borderRadiusXLarge
|
|
25
26
|
) from '../../styles/variables/_border.css';
|
|
26
27
|
@value (
|
|
27
28
|
size18,
|
|
@@ -72,6 +73,10 @@
|
|
|
72
73
|
background-color: colorNeutralLightest;
|
|
73
74
|
}
|
|
74
75
|
|
|
76
|
+
.pill {
|
|
77
|
+
border-radius: borderRadiusXLarge;
|
|
78
|
+
}
|
|
79
|
+
|
|
75
80
|
.noHoverState {
|
|
76
81
|
cursor: initial;
|
|
77
82
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { Flow } from 'flow-to-typescript-codemod';
|
|
3
|
+
import type { ChipSemanticType } from '../../components/Chip/Chip';
|
|
4
|
+
import type { IconType } from '../../components/Icon';
|
|
5
|
+
type ClassNames = Readonly<{
|
|
6
|
+
wrapper?: string;
|
|
7
|
+
icon?: string;
|
|
8
|
+
}>;
|
|
9
|
+
export declare const PILL_SEMANTIC: Readonly<{
|
|
10
|
+
primary: "primary";
|
|
11
|
+
information: "information";
|
|
12
|
+
success: "success";
|
|
13
|
+
warning: "warning";
|
|
14
|
+
danger: "danger";
|
|
15
|
+
secondary: "secondary";
|
|
16
|
+
}>;
|
|
17
|
+
export type PillSemanticType = ChipSemanticType;
|
|
18
|
+
export interface PillProps {
|
|
19
|
+
classNames?: ClassNames;
|
|
20
|
+
semantic?: PillSemanticType;
|
|
21
|
+
size?: 'large' | 'medium' | 'small';
|
|
22
|
+
children: React.ReactNode;
|
|
23
|
+
disabled?: boolean;
|
|
24
|
+
line?: number;
|
|
25
|
+
wordBreak?: string;
|
|
26
|
+
iconName?: string;
|
|
27
|
+
iconType?: IconType;
|
|
28
|
+
testId?: string;
|
|
29
|
+
}
|
|
30
|
+
export declare const Pill: Flow.AbstractComponent<PillProps, HTMLDivElement>;
|
|
31
|
+
export {};
|
|
32
|
+
//# sourceMappingURL=Pill.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Pill.d.ts","sourceRoot":"","sources":["../../../src/components/Chip/Pill.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,4BAA4B,CAAC;AAKrD,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,0BAA0B,CAAC;AAE/D,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,qBAAqB,CAAC;AAOlD,KAAK,UAAU,GAAG,QAAQ,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC,CAAC;AAEH,eAAO,MAAM,aAAa;;;;;;;EAAgB,CAAC;AAE3C,MAAM,MAAM,gBAAgB,GAAG,gBAAgB,CAAC;AAEhD,MAAM,WAAW,SAAS;IACxB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IACpC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,IAAI,EAAE,IAAI,CAAC,iBAAiB,CAAC,SAAS,EAAE,cAAc,CA8DhE,CAAC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.Pill = exports.PILL_SEMANTIC = void 0;
|
|
7
|
+
var React = _interopRequireWildcard(require("react"));
|
|
8
|
+
var _classify = require("../../utils/classify");
|
|
9
|
+
var _qa = require("../../utils/qa");
|
|
10
|
+
var _Chip = require("./Chip");
|
|
11
|
+
var _Icon = require("../Icon");
|
|
12
|
+
var _Truncate = require("../Truncate");
|
|
13
|
+
var _ChipModule = _interopRequireDefault(require("./Chip.module.css"));
|
|
14
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
15
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
16
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
17
|
+
const PILL_SEMANTIC = exports.PILL_SEMANTIC = _Chip.CHIP_SEMANTIC;
|
|
18
|
+
const Pill = exports.Pill = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
19
|
+
let {
|
|
20
|
+
classNames,
|
|
21
|
+
semantic = 'primary',
|
|
22
|
+
size = 'medium',
|
|
23
|
+
children,
|
|
24
|
+
disabled,
|
|
25
|
+
line = 1,
|
|
26
|
+
wordBreak,
|
|
27
|
+
iconName,
|
|
28
|
+
iconType = 'regular',
|
|
29
|
+
testId
|
|
30
|
+
} = _ref;
|
|
31
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
|
|
32
|
+
"data-testid": (0, _qa.generateTestId)({
|
|
33
|
+
base: testId,
|
|
34
|
+
slot: 'root'
|
|
35
|
+
}),
|
|
36
|
+
ref: ref,
|
|
37
|
+
className: (0, _classify.classify)(_ChipModule.default.chipWrapper, _ChipModule.default.pill, _ChipModule.default.noHoverState, {
|
|
38
|
+
[_ChipModule.default.primary]: semantic === _Chip.CHIP_SEMANTIC.primary,
|
|
39
|
+
[_ChipModule.default.information]: semantic === _Chip.CHIP_SEMANTIC.information,
|
|
40
|
+
[_ChipModule.default.success]: semantic === _Chip.CHIP_SEMANTIC.success,
|
|
41
|
+
[_ChipModule.default.warning]: semantic === _Chip.CHIP_SEMANTIC.warning,
|
|
42
|
+
[_ChipModule.default.danger]: semantic === _Chip.CHIP_SEMANTIC.danger,
|
|
43
|
+
[_ChipModule.default.secondary]: semantic === _Chip.CHIP_SEMANTIC.secondary,
|
|
44
|
+
[_ChipModule.default.large]: size === 'large',
|
|
45
|
+
[_ChipModule.default.medium]: size === 'medium',
|
|
46
|
+
[_ChipModule.default.small]: size === 'small',
|
|
47
|
+
[_ChipModule.default.withIcon]: !!iconName && size !== 'small',
|
|
48
|
+
[_ChipModule.default.disabled]: disabled
|
|
49
|
+
}, classNames?.wrapper),
|
|
50
|
+
children: [iconName && size !== 'small' && /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.Icon, {
|
|
51
|
+
className: (0, _classify.classify)(_ChipModule.default.chipIcon, {
|
|
52
|
+
[_ChipModule.default.alignTop]: line > 1
|
|
53
|
+
}, classNames?.icon),
|
|
54
|
+
name: iconName,
|
|
55
|
+
type: iconType,
|
|
56
|
+
size: "small",
|
|
57
|
+
testId: (0, _qa.generateTestId)({
|
|
58
|
+
base: testId,
|
|
59
|
+
slot: 'icon'
|
|
60
|
+
})
|
|
61
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Truncate.Truncate, {
|
|
62
|
+
line: line,
|
|
63
|
+
wordBreak: wordBreak,
|
|
64
|
+
testId: (0, _qa.generateTestId)({
|
|
65
|
+
base: testId,
|
|
66
|
+
slot: 'text'
|
|
67
|
+
}),
|
|
68
|
+
children: children
|
|
69
|
+
})]
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
Pill.displayName = 'Pill';
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
export type { ChipProps, ChipSemanticType } from '../../components/Chip/Chip';
|
|
2
2
|
export { Chip, CHIP_SEMANTIC } from '../../components/Chip/Chip';
|
|
3
|
+
export type { PillProps, PillSemanticType } from '../../components/Chip/Pill';
|
|
4
|
+
export { Pill, PILL_SEMANTIC } from '../../components/Chip/Pill';
|
|
3
5
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Chip/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAC,SAAS,EAAE,gBAAgB,EAAC,MAAM,0BAA0B,CAAC;AAC1E,OAAO,EAAC,IAAI,EAAE,aAAa,EAAC,MAAM,0BAA0B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Chip/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAC,SAAS,EAAE,gBAAgB,EAAC,MAAM,0BAA0B,CAAC;AAC1E,OAAO,EAAC,IAAI,EAAE,aAAa,EAAC,MAAM,0BAA0B,CAAC;AAC7D,YAAY,EAAC,SAAS,EAAE,gBAAgB,EAAC,MAAM,0BAA0B,CAAC;AAC1E,OAAO,EAAC,IAAI,EAAE,aAAa,EAAC,MAAM,0BAA0B,CAAC"}
|
|
@@ -15,4 +15,17 @@ Object.defineProperty(exports, "Chip", {
|
|
|
15
15
|
return _Chip.Chip;
|
|
16
16
|
}
|
|
17
17
|
});
|
|
18
|
-
|
|
18
|
+
Object.defineProperty(exports, "PILL_SEMANTIC", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function () {
|
|
21
|
+
return _Pill.PILL_SEMANTIC;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
Object.defineProperty(exports, "Pill", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
get: function () {
|
|
27
|
+
return _Pill.Pill;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
var _Chip = require("./Chip");
|
|
31
|
+
var _Pill = require("./Pill");
|
|
@@ -2,7 +2,27 @@ import type { ChartOptions, LegendOptionsType } from '../../types/charts';
|
|
|
2
2
|
interface DonutChartPropsType {
|
|
3
3
|
legend?: LegendOptionsType;
|
|
4
4
|
defaultCenterHTML?: string;
|
|
5
|
+
/**
|
|
6
|
+
* Formatter for each legend item. When provided, the legend renders as HTML
|
|
7
|
+
* so items can show the point value and percentage alongside the name.
|
|
8
|
+
*/
|
|
9
|
+
legendLabelFormatter?: LegendOptionsType['labelFormatter'];
|
|
10
|
+
/**
|
|
11
|
+
* Formats the center total for a given value. When provided, the center is
|
|
12
|
+
* recomputed from the visible points on every render (applied via
|
|
13
|
+
* textContent) so an auto-computed total stays in sync with the
|
|
14
|
+
* (redistributed) legend percentages after a slice is toggled off.
|
|
15
|
+
*/
|
|
16
|
+
getCenterTextForVisibleTotal?: (visibleTotal: number) => string;
|
|
5
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* Marker class on the center total element. The auto-total's text is updated
|
|
20
|
+
* in place (via textContent) as slices are toggled, so it must be locatable
|
|
21
|
+
* without rebuilding the subtitle HTML. A class is used (not a data-attribute)
|
|
22
|
+
* because Highcharts' useHTML sanitizer keeps the class attribute but strips
|
|
23
|
+
* unknown data-* attributes.
|
|
24
|
+
*/
|
|
25
|
+
export declare const CENTER_TOTAL_CLASS = "donut-center-total";
|
|
6
26
|
export declare const rightLegendColumn: {
|
|
7
27
|
readonly layout: "vertical";
|
|
8
28
|
readonly align: "right";
|
|
@@ -16,6 +36,6 @@ export declare const rightLegendColumn: {
|
|
|
16
36
|
* This function modifies the the common chart behavior to donut chart default behavior.
|
|
17
37
|
* It will not take userPassed option into account.
|
|
18
38
|
*/
|
|
19
|
-
export declare const getDonutChartOptions: ({ legend, defaultCenterHTML, }: DonutChartPropsType) => ChartOptions;
|
|
39
|
+
export declare const getDonutChartOptions: ({ legend, defaultCenterHTML, legendLabelFormatter, getCenterTextForVisibleTotal, }: DonutChartPropsType) => ChartOptions;
|
|
20
40
|
export {};
|
|
21
41
|
//# sourceMappingURL=donutChart.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"donutChart.d.ts","sourceRoot":"","sources":["../../../src/utils/charts/donutChart.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,YAAY,EAAE,iBAAiB,EAAC,MAAM,kBAAkB,CAAC;AAKtE,UAAU,mBAAmB;IAC3B,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"donutChart.d.ts","sourceRoot":"","sources":["../../../src/utils/charts/donutChart.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,YAAY,EAAE,iBAAiB,EAAC,MAAM,kBAAkB,CAAC;AAKtE,UAAU,mBAAmB;IAC3B,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;OAGG;IACH,oBAAoB,CAAC,EAAE,iBAAiB,CAAC,gBAAgB,CAAC,CAAC;IAC3D;;;;;OAKG;IACH,4BAA4B,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,MAAM,CAAC;CACjE;AA0BD;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,uBAAuB,CAAC;AAEvD,eAAO,MAAM,iBAAiB;;;;;;;;CASpB,CAAC;AAEX;;;GAGG;AAEH,eAAO,MAAM,oBAAoB,GAAI,oFAKlC,mBAAmB,KAAG,YAwHxB,CAAC"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.rightLegendColumn = exports.getDonutChartOptions = void 0;
|
|
6
|
+
exports.rightLegendColumn = exports.getDonutChartOptions = exports.CENTER_TOTAL_CLASS = void 0;
|
|
7
7
|
var _charts = require("./charts");
|
|
8
8
|
var _helpers = require("./helpers");
|
|
9
9
|
/**
|
|
@@ -15,13 +15,35 @@ const CHART_WIDTH = 1 - LEGEND_WIDTH;
|
|
|
15
15
|
const CHART_CENTER = (1 - LEGEND_WIDTH) / 2;
|
|
16
16
|
const CHART_SIZE = 0.8; // chart size w.r.t area allocated to chart drawing;
|
|
17
17
|
|
|
18
|
+
const LEGEND_SYMBOL_WIDTH = 8;
|
|
19
|
+
const LEGEND_SYMBOL_PADDING = 8;
|
|
20
|
+
const LEGEND_BOX_PADDING = 8; // Highcharts default legend.padding, applied on each side.
|
|
21
|
+
/**
|
|
22
|
+
* Horizontal space each legend item spends on chrome (box padding + symbol +
|
|
23
|
+
* symbol padding) before the label text. Subtracted from the legend box width
|
|
24
|
+
* to derive the width available to the HTML label so the value can be
|
|
25
|
+
* right-aligned against the name.
|
|
26
|
+
*/
|
|
27
|
+
const LEGEND_ITEM_CHROME_WIDTH = LEGEND_BOX_PADDING * 2 + LEGEND_SYMBOL_WIDTH + LEGEND_SYMBOL_PADDING;
|
|
28
|
+
|
|
29
|
+
/** CSS custom property consumed by the HTML legend label to right-align values. */
|
|
30
|
+
const LEGEND_ITEM_WIDTH_VAR = '--donut-legend-item-width';
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Marker class on the center total element. The auto-total's text is updated
|
|
34
|
+
* in place (via textContent) as slices are toggled, so it must be locatable
|
|
35
|
+
* without rebuilding the subtitle HTML. A class is used (not a data-attribute)
|
|
36
|
+
* because Highcharts' useHTML sanitizer keeps the class attribute but strips
|
|
37
|
+
* unknown data-* attributes.
|
|
38
|
+
*/
|
|
39
|
+
const CENTER_TOTAL_CLASS = exports.CENTER_TOTAL_CLASS = 'donut-center-total';
|
|
18
40
|
const rightLegendColumn = exports.rightLegendColumn = {
|
|
19
41
|
layout: 'vertical',
|
|
20
42
|
align: 'right',
|
|
21
43
|
verticalAlign: 'middle',
|
|
22
44
|
itemMarginBottom: 12,
|
|
23
|
-
symbolPadding:
|
|
24
|
-
symbolWidth:
|
|
45
|
+
symbolPadding: LEGEND_SYMBOL_PADDING,
|
|
46
|
+
symbolWidth: LEGEND_SYMBOL_WIDTH,
|
|
25
47
|
// take it as 10% of width as left margin
|
|
26
48
|
width: `${LEGEND_WIDTH * 90}%`
|
|
27
49
|
};
|
|
@@ -34,10 +56,13 @@ const rightLegendColumn = exports.rightLegendColumn = {
|
|
|
34
56
|
const getDonutChartOptions = _ref => {
|
|
35
57
|
let {
|
|
36
58
|
legend,
|
|
37
|
-
defaultCenterHTML
|
|
59
|
+
defaultCenterHTML,
|
|
60
|
+
legendLabelFormatter,
|
|
61
|
+
getCenterTextForVisibleTotal
|
|
38
62
|
} = _ref;
|
|
39
63
|
const legendOption = (0, _helpers.deepMerge)(_charts.commonChartOptions.legend, legend);
|
|
40
64
|
const isLegendEnabled = legendOption.enabled;
|
|
65
|
+
const hasLegendValues = Boolean(legendLabelFormatter);
|
|
41
66
|
return {
|
|
42
67
|
..._charts.commonChartOptions,
|
|
43
68
|
chart: {
|
|
@@ -52,6 +77,29 @@ const getDonutChartOptions = _ref => {
|
|
|
52
77
|
const desiredHeight = CHART_WIDTH * containerWidth;
|
|
53
78
|
// 5px adjustment required due to borderWidth mostly.
|
|
54
79
|
const centerTextX = isLegendEnabled ? chart.plotWidth * CHART_CENTER + 5 : 0;
|
|
80
|
+
// Expose the label width to the HTML legend so the value/percentage
|
|
81
|
+
// can be right-aligned against the item name. Prefer the measured
|
|
82
|
+
// legend box, falling back to an estimate from the container width.
|
|
83
|
+
if (isLegendEnabled && hasLegendValues) {
|
|
84
|
+
const measuredWidth = chart.legend?.box?.getBBox().width;
|
|
85
|
+
const legendBoxWidth = measuredWidth || containerWidth * (LEGEND_WIDTH * 0.9);
|
|
86
|
+
const legendItemWidth = Math.max(0, legendBoxWidth - LEGEND_ITEM_CHROME_WIDTH);
|
|
87
|
+
chart.container.style.setProperty(LEGEND_ITEM_WIDTH_VAR, `${legendItemWidth}px`);
|
|
88
|
+
} else {
|
|
89
|
+
// Clear it so a stale width can't linger if the feature is toggled off.
|
|
90
|
+
chart.container.style.removeProperty(LEGEND_ITEM_WIDTH_VAR);
|
|
91
|
+
}
|
|
92
|
+
// Recompute the auto-total from the visible points so it tracks the
|
|
93
|
+
// legend as slices are toggled on/off. Applied via textContent (not
|
|
94
|
+
// innerHTML) on the marked element to avoid an HTML-injection sink.
|
|
95
|
+
if (getCenterTextForVisibleTotal) {
|
|
96
|
+
const points = chart.series[0]?.points ?? [];
|
|
97
|
+
const visibleTotal = points.reduce((sum, point) => sum + (point.visible && typeof point.y === 'number' ? point.y : 0), 0);
|
|
98
|
+
const totalEl = chart.container.querySelector(`.${CENTER_TOTAL_CLASS}`);
|
|
99
|
+
if (totalEl) {
|
|
100
|
+
totalEl.textContent = getCenterTextForVisibleTotal(visibleTotal);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
55
103
|
chart.update({
|
|
56
104
|
chart: {
|
|
57
105
|
height: desiredHeight // Set the height dynamically based on the container's width
|
|
@@ -65,7 +113,11 @@ const getDonutChartOptions = _ref => {
|
|
|
65
113
|
},
|
|
66
114
|
legend: {
|
|
67
115
|
...legendOption,
|
|
68
|
-
...rightLegendColumn
|
|
116
|
+
...rightLegendColumn,
|
|
117
|
+
...(hasLegendValues ? {
|
|
118
|
+
useHTML: true,
|
|
119
|
+
labelFormatter: legendLabelFormatter
|
|
120
|
+
} : {})
|
|
69
121
|
},
|
|
70
122
|
plotOptions: {
|
|
71
123
|
pie: {
|
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
export declare const deepMerge: <T extends object>(obj1: Partial<T> | null | undefined, obj2: Partial<T> | null | undefined, ...args: Array<Partial<T> | null | undefined>) => T;
|
|
2
|
+
/**
|
|
3
|
+
* Default number formatter used by charts for center totals and legend values.
|
|
4
|
+
* Abbreviates large numbers into a compact, locale-aware form, keeping up to
|
|
5
|
+
* two decimal places (e.g. 1460 -> "1.46K", 1260 -> "1.26K", 1200 -> "1.2K",
|
|
6
|
+
* 200 -> "200").
|
|
7
|
+
*/
|
|
8
|
+
export declare const formatCompactNumber: (value: number) => string;
|
|
2
9
|
export declare const rightLineLegendColumn: {
|
|
3
10
|
readonly layout: "vertical";
|
|
4
11
|
readonly align: "right";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/utils/charts/helpers.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,SAAS,GAAI,CAAC,SAAS,MAAM,EACxC,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,EACnC,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,EACnC,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,KAC5C,CAAmC,CAAC;AAEvC,eAAO,MAAM,qBAAqB;;;;;;;;CAQxB,CAAC;AAEX,eAAO,MAAM,eAAe;;;;;;;CAOlB,CAAC;AAEX,eAAO,MAAM,eAAe;;;;;;;;;;CAGlB,CAAC;AAEX,eAAO,MAAM,eAAe;;;;;;;;;;CAGlB,CAAC;AAEX,eAAO,MAAM,eAAe;;;;;;;;;;CAElB,CAAC;AAEX,eAAO,MAAM,eAAe;;;;;;;;;;CAElB,CAAC;AAEX,eAAO,MAAM,gBAAgB;;;;;;;;;;;;CAKnB,CAAC"}
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/utils/charts/helpers.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,SAAS,GAAI,CAAC,SAAS,MAAM,EACxC,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,EACnC,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,EACnC,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,KAC5C,CAAmC,CAAC;AAEvC;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,GAAI,OAAO,MAAM,KAAG,MAIlC,CAAC;AAEnB,eAAO,MAAM,qBAAqB;;;;;;;;CAQxB,CAAC;AAEX,eAAO,MAAM,eAAe;;;;;;;CAOlB,CAAC;AAEX,eAAO,MAAM,eAAe;;;;;;;;;;CAGlB,CAAC;AAEX,eAAO,MAAM,eAAe;;;;;;;;;;CAGlB,CAAC;AAEX,eAAO,MAAM,eAAe;;;;;;;;;;CAElB,CAAC;AAEX,eAAO,MAAM,eAAe;;;;;;;;;;CAElB,CAAC;AAEX,eAAO,MAAM,gBAAgB;;;;;;;;;;;;CAKnB,CAAC"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.yAxisTitleStyle = exports.yAxisLabelStyle = exports.xAxisTitleStyle = exports.xAxisLabelStyle = exports.rightLineLegendColumn = exports.deepMerge = exports.bottomLegendRow = exports.activeLabelStyle = void 0;
|
|
6
|
+
exports.yAxisTitleStyle = exports.yAxisLabelStyle = exports.xAxisTitleStyle = exports.xAxisLabelStyle = exports.rightLineLegendColumn = exports.formatCompactNumber = exports.deepMerge = exports.bottomLegendRow = exports.activeLabelStyle = void 0;
|
|
7
7
|
var _merge = _interopRequireDefault(require("lodash/merge"));
|
|
8
8
|
var _color = require("../../styles/variables/_color");
|
|
9
9
|
var _typography = require("./typography");
|
|
@@ -14,7 +14,19 @@ const deepMerge = function (obj1, obj2) {
|
|
|
14
14
|
}
|
|
15
15
|
return (0, _merge.default)({}, obj1, obj2, ...args);
|
|
16
16
|
}; // {} is used here to ensure obj1 is not modified
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Default number formatter used by charts for center totals and legend values.
|
|
20
|
+
* Abbreviates large numbers into a compact, locale-aware form, keeping up to
|
|
21
|
+
* two decimal places (e.g. 1460 -> "1.46K", 1260 -> "1.26K", 1200 -> "1.2K",
|
|
22
|
+
* 200 -> "200").
|
|
23
|
+
*/
|
|
17
24
|
exports.deepMerge = deepMerge;
|
|
25
|
+
const formatCompactNumber = value => new Intl.NumberFormat('en', {
|
|
26
|
+
notation: 'compact',
|
|
27
|
+
maximumFractionDigits: 2
|
|
28
|
+
}).format(value);
|
|
29
|
+
exports.formatCompactNumber = formatCompactNumber;
|
|
18
30
|
const rightLineLegendColumn = exports.rightLineLegendColumn = {
|
|
19
31
|
layout: 'vertical',
|
|
20
32
|
align: 'right',
|
package/mcp/package.json
CHANGED