@auth0/quantum-charts 1.3.6 → 1.3.8

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.
@@ -64,7 +64,7 @@ var chart_card_1 = require("../chart-card");
64
64
  var chart_1 = require("../common/chart");
65
65
  var custom_legend_1 = require("../common/custom-legend");
66
66
  function BarChart(props) {
67
- var _a = props, data = _a.data, leftAxis = _a.leftAxis, bottomAxis = _a.bottomAxis, _b = _a.height, height = _b === void 0 ? 300 : _b, title = _a.title, value = _a.value, label = _a.label, helperText = _a.helperText, _c = _a.layout, layout = _c === void 0 ? 'vertical' : _c, _d = _a.isStacked, isStacked = _d === void 0 ? false : _d, _e = _a.color, color = _e === void 0 ? 'categorical' : _e, additionalMenuItems = _a.additionalMenuItems, tooltipProp = _a.tooltipProp, _f = _a.showTotalValueInTooltip, showTotalValueInTooltip = _f === void 0 ? false : _f, _g = _a.allowDownload, allowDownload = _g === void 0 ? true : _g, _h = _a.showChartTable, showChartTable = _h === void 0 ? true : _h, headerAction = _a.headerAction, customViewChartTable = _a.customViewChartTable, barSize = _a.barSize;
67
+ var _a = props, data = _a.data, leftAxis = _a.leftAxis, bottomAxis = _a.bottomAxis, _b = _a.height, height = _b === void 0 ? 300 : _b, title = _a.title, value = _a.value, label = _a.label, helperText = _a.helperText, _c = _a.layout, layout = _c === void 0 ? 'vertical' : _c, _d = _a.isStacked, isStacked = _d === void 0 ? false : _d, _e = _a.color, color = _e === void 0 ? 'categorical' : _e, statusColorMapping = _a.statusColorMapping, additionalMenuItems = _a.additionalMenuItems, tooltipProp = _a.tooltipProp, _f = _a.showTotalValueInTooltip, showTotalValueInTooltip = _f === void 0 ? false : _f, _g = _a.allowDownload, allowDownload = _g === void 0 ? true : _g, _h = _a.showChartTable, showChartTable = _h === void 0 ? true : _h, headerAction = _a.headerAction, customViewChartTable = _a.customViewChartTable, barSize = _a.barSize;
68
68
  var theme = (0, quantum_product_1.useTheme)();
69
69
  // Function to know how many bars we need based of how much different group values are.
70
70
  var groups = lodash_1.default.uniqBy(data, 'group').map(function (item) { return item.group; });
@@ -119,9 +119,17 @@ function BarChart(props) {
119
119
  React.createElement(recharts_1.Tooltip, { wrapperStyle: { outline: 'none' }, content: React.createElement(custom_tooltip_1.default, { scaleType: bottomAxis.scaleType, tooltipProp: tooltipProp, showTotalValue: showTotalValueInTooltip }) }),
120
120
  React.createElement(recharts_1.Legend, { align: "center", content: React.createElement(custom_legend_1.CustomLegend, { selectData: selectBar, handleLegendMouseEnter: handleLegendMouseEnter, handleLegendMouseLeave: handleLegendMouseLeave, dataVisibility: barVisibility }) }),
121
121
  groups.map(function (group, index) {
122
- return (React.createElement(recharts_1.Bar, __assign({ key: group, dataKey: group, barSize: barSize }, (isStacked && { stackId: 'stack' }), { name: group, hide: barVisibility[group] === true, fill: barVisibility.hover === group || !barVisibility.hover
123
- ? (0, theme_1.getColorScale)(theme)[color]['base'][index]
124
- : (0, theme_1.getColorScale)(theme)[color]['muted'][index] })));
122
+ var isMuted = barVisibility.hover !== group && barVisibility.hover;
123
+ var fillColor;
124
+ if (color === 'status') {
125
+ fillColor = (0, theme_1.getStatusColorForGroup)(group, groups, theme, statusColorMapping, isMuted);
126
+ }
127
+ else {
128
+ fillColor = isMuted
129
+ ? (0, theme_1.getColorScale)(theme)[color]['muted'][index]
130
+ : (0, theme_1.getColorScale)(theme)[color]['base'][index];
131
+ }
132
+ return (React.createElement(recharts_1.Bar, __assign({ key: group, dataKey: group, barSize: barSize }, (isStacked && { stackId: 'stack' }), { name: group, hide: barVisibility[group] === true, fill: fillColor })));
125
133
  }))) : (React.createElement("div", { style: {
126
134
  display: 'grid',
127
135
  placeItems: 'center',
@@ -29,7 +29,7 @@ var React = __importStar(require("react"));
29
29
  var chart_summary_1 = require("../chart-summary");
30
30
  function ChartCard(props) {
31
31
  var children = props.children, title = props.title, chartStatus = props.chartStatus, titleIcon = props.titleIcon, value = props.value, dataTable = props.dataTable, helperText = props.helperText, label = props.label, height = props.height, headerAction = props.headerAction, additionalMenuItems = props.additionalMenuItems, showChartTable = props.showChartTable, allowDownload = props.allowDownload, customViewChartTable = props.customViewChartTable, triggerButtonSize = props.triggerButtonSize, isVertical = props.isVertical, finalMenuItem = props.finalMenuItem;
32
- return (React.createElement(quantum_product_1.Card, { sx: { height: height, padding: 3, paddingBottom: isVertical ? 0.5 : 3 } },
32
+ return (React.createElement(quantum_product_1.Card, { sx: { height: height, padding: isVertical ? 2 : 3, paddingBottom: isVertical ? 2 : 3 } },
33
33
  React.createElement(chart_summary_1.ChartSummary, { title: title, value: value, dataTable: dataTable, helperText: helperText, label: label, headerAction: headerAction, showChartTable: showChartTable, allowDownload: allowDownload, additionalMenuItems: additionalMenuItems, customViewChartTable: customViewChartTable, triggerButtonSize: triggerButtonSize, chartStatus: chartStatus, titleIcon: titleIcon, finalMenuItem: finalMenuItem, isVertical: isVertical }),
34
34
  children));
35
35
  }
@@ -75,9 +75,22 @@ var Aggregate = (0, quantum_product_1.styled)('h4')(templateObject_1 || (templat
75
75
  var theme = _a.theme;
76
76
  return theme.typography.h4.fontSize;
77
77
  });
78
- var TitleIconWrapper = (0, quantum_product_1.styled)('div')(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n display: flex;\n align-items: center;\n & > svg {\n font-size: ", ";\n width: 1em;\n height: 1em;\n }\n"], ["\n display: flex;\n align-items: center;\n & > svg {\n font-size: ", ";\n width: 1em;\n height: 1em;\n }\n"])), function (_a) {
78
+ var TitleIconWrapper = (0, quantum_product_1.styled)('div')(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n display: flex;\n align-items: center;\n & > svg {\n font-size: ", ";\n color: ", ";\n width: 1em;\n height: 1em;\n }\n"], ["\n display: flex;\n align-items: center;\n & > svg {\n font-size: ", ";\n color: ", ";\n width: 1em;\n height: 1em;\n }\n"])), function (_a) {
79
79
  var theme = _a.theme;
80
80
  return theme.tokens.type_preset_section_subtitle.fontSize;
81
+ }, function (_a) {
82
+ var theme = _a.theme;
83
+ return theme.tokens.color_fg_bold;
84
+ });
85
+ var TitleWrapper = (0, quantum_product_1.styled)(quantum_product_1.Text)(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n font-size: ", ";\n color: ", ";\n font-weight: ", ";\n}"], ["\n font-size: ", ";\n color: ", ";\n font-weight: ", ";\n}"])), function (_a) {
86
+ var theme = _a.theme;
87
+ return theme.tokens.type_preset_section_subtitle.fontSize;
88
+ }, function (_a) {
89
+ var theme = _a.theme;
90
+ return theme.tokens.color_fg_bold;
91
+ }, function (_a) {
92
+ var theme = _a.theme;
93
+ return theme.tokens.type_preset_section_subtitle.fontWeight;
81
94
  });
82
95
  function ChartSummary(props) {
83
96
  var title = props.title, chartStatus = props.chartStatus, value = props.value, helperText = props.helperText, label = props.label, dataTable = props.dataTable, headerAction = props.headerAction, additionalMenuItems = props.additionalMenuItems, showChartTable = props.showChartTable, allowDownload = props.allowDownload, customViewChartTable = props.customViewChartTable, _a = props.triggerButtonSize, triggerButtonSize = _a === void 0 ? 'small' : _a, titleIcon = props.titleIcon, finalMenuItem = props.finalMenuItem, isVertical = props.isVertical;
@@ -137,12 +150,11 @@ function ChartSummary(props) {
137
150
  });
138
151
  }, [showChartTable, allowDownload, additionalMenuItems, dataTable, title, menuProps, finalMenuItem]);
139
152
  return (React.createElement("div", null,
140
- React.createElement(quantum_product_1.DescriptionBlock, { label: React.createElement("div", { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center' } },
153
+ React.createElement(quantum_product_1.DescriptionBlock, { sx: __assign({}, (isVertical && { gap: '16px' })), label: React.createElement("div", { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center' } },
141
154
  React.createElement(quantum_product_1.StackLayout, { gutter: 1 },
142
155
  titleIcon && (React.createElement(quantum_product_1.StackLayoutItem, null,
143
156
  React.createElement(TitleIconWrapper, null, titleIcon))),
144
- React.createElement(quantum_product_1.StackLayoutItem, null,
145
- React.createElement(quantum_product_1.Text, { fontWeight: 500 }, title)),
157
+ React.createElement(quantum_product_1.StackLayoutItem, null, titleIcon ? React.createElement(TitleWrapper, null, title) : React.createElement(quantum_product_1.Text, { fontWeight: 500 }, title)),
146
158
  chartStatus && (React.createElement(quantum_product_1.StackLayoutItem, { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center' } },
147
159
  React.createElement(quantum_product_1.Label, { color: chartStatus.color },
148
160
  React.createElement(quantum_product_1.StatusDot, __assign({}, chartStatus, { label: "", details: "" })),
@@ -166,4 +178,4 @@ function ChartSummary(props) {
166
178
  showChartTable && (React.createElement(data_table_chart_1.DataTableChart, { title: title, isOpen: isOpen, toggleIsOpen: toggleIsOpen, data: dataTable, customViewChartTable: customViewChartTable, allowDownload: allowDownload }))));
167
179
  }
168
180
  exports.ChartSummary = ChartSummary;
169
- var templateObject_1, templateObject_2;
181
+ var templateObject_1, templateObject_2, templateObject_3;
package/common/chart.d.ts CHANGED
@@ -14,6 +14,12 @@ export interface ICustomTooltipProps extends TooltipProps<number, string> {
14
14
  export interface ILegendOptions {
15
15
  enabled?: boolean;
16
16
  }
17
+ export type StatusType = 'success' | 'failed' | 'total';
18
+ export interface IStatusColorMapping {
19
+ success?: string;
20
+ failed?: string;
21
+ total?: string;
22
+ }
17
23
  export type IChartDataPoint<DataType = unknown> = {
18
24
  group: string;
19
25
  value?: number;
@@ -32,7 +38,8 @@ export interface IBaseChartProps<DataType = unknown> extends IChartCardProps {
32
38
  bottomAxis: IAxisOptions<DataType>;
33
39
  leftAxis: IAxisOptions<DataType>;
34
40
  legend?: ILegendOptions;
35
- color?: 'categorical' | 'sequential';
41
+ color?: 'categorical' | 'sequential' | 'status';
42
+ statusColorMapping?: IStatusColorMapping;
36
43
  additionalMenuItems?: DropdownMenuListItemValue[];
37
44
  headerAction?: React.ReactElement;
38
45
  }
@@ -1,10 +1,11 @@
1
1
  import * as React from 'react';
2
- import { IDonutChartDataPoint } from '../common/chart';
2
+ import { IDonutChartDataPoint, IStatusColorMapping } from '../common/chart';
3
3
  export type IDecoupledLegendProps<DataType = unknown> = {
4
4
  data: IDonutChartDataPoint<DataType>[];
5
5
  activeIndex?: number;
6
6
  setActiveIndex: (index: number | undefined) => void;
7
- color?: 'categorical' | 'sequential';
7
+ color?: 'categorical' | 'sequential' | 'status';
8
+ statusColorMapping?: IStatusColorMapping;
8
9
  isStacked?: boolean;
9
10
  };
10
11
  declare function DecoupledLegend<DataType = unknown>(props: IDecoupledLegendProps<DataType>): React.JSX.Element;
@@ -38,14 +38,23 @@ var LegendText = (0, quantum_product_1.styled)('span')({
38
38
  cursor: 'default',
39
39
  });
40
40
  function DecoupledLegend(props) {
41
- var data = props.data, activeIndex = props.activeIndex, setActiveIndex = props.setActiveIndex, _a = props.color, color = _a === void 0 ? 'categorical' : _a, isStacked = props.isStacked;
41
+ var data = props.data, activeIndex = props.activeIndex, setActiveIndex = props.setActiveIndex, _a = props.color, color = _a === void 0 ? 'categorical' : _a, statusColorMapping = props.statusColorMapping, isStacked = props.isStacked;
42
42
  var theme = (0, quantum_product_1.useTheme)();
43
43
  var BASE_COLORS = (0, theme_1.getColorScale)(theme)[color]['base'];
44
44
  var MUTED_COLORS = (0, theme_1.getColorScale)(theme)[color]['muted'];
45
+ var groups = data.map(function (item) { return item.name; });
45
46
  var content = data.map(function (datum, index) {
46
47
  var isActive = activeIndex !== undefined && activeIndex === index;
47
- var color = BASE_COLORS[index % BASE_COLORS.length];
48
- var mutedColor = MUTED_COLORS[index % MUTED_COLORS.length];
48
+ var itemColor;
49
+ var mutedColor;
50
+ if (color === 'status') {
51
+ itemColor = (0, theme_1.getStatusColorForGroup)(datum.name, groups, theme, statusColorMapping, false);
52
+ mutedColor = (0, theme_1.getStatusColorForGroup)(datum.name, groups, theme, statusColorMapping, true);
53
+ }
54
+ else {
55
+ itemColor = BASE_COLORS[index % BASE_COLORS.length];
56
+ mutedColor = MUTED_COLORS[index % MUTED_COLORS.length];
57
+ }
49
58
  return (React.createElement(React.Fragment, { key: index },
50
59
  React.createElement(quantum_product_1.StackLayout, { gutter: 1, onMouseEnter: function () {
51
60
  setActiveIndex(index);
@@ -57,7 +66,7 @@ function DecoupledLegend(props) {
57
66
  React.createElement(quantum_product_1.StackLayoutItem, { sx: {
58
67
  alignSelf: 'center',
59
68
  } },
60
- React.createElement(LegendDot, { style: { backgroundColor: activeIndex === undefined ? color : isActive ? color : mutedColor } })),
69
+ React.createElement(LegendDot, { style: { backgroundColor: activeIndex === undefined ? itemColor : isActive ? itemColor : mutedColor } })),
61
70
  React.createElement(quantum_product_1.StackLayoutItem, { sx: {
62
71
  alignSelf: 'center',
63
72
  } },
@@ -1,11 +1,12 @@
1
1
  import * as React from 'react';
2
2
  import { IChartCardProps } from '../chart-card';
3
- import { IDonutChartDataPoint } from '../common/chart';
3
+ import { IDonutChartDataPoint, IStatusColorMapping } from '../common/chart';
4
4
  interface IDonutChartProps<DataType = unknown> extends IChartCardProps {
5
5
  data: IDonutChartDataPoint<DataType>[];
6
6
  displayType: 'absolute' | 'percent';
7
7
  layout?: 'horizontal' | 'vertical';
8
- color?: 'categorical' | 'sequential';
8
+ color?: 'categorical' | 'sequential' | 'status';
9
+ statusColorMapping?: IStatusColorMapping;
9
10
  height?: number | string;
10
11
  isStacked?: boolean;
11
12
  centerLabel?: string;
@@ -71,11 +71,12 @@ var ResponsiveChartCard = (0, quantum_product_1.styled)(quantum_product_1.StackL
71
71
  })));
72
72
  });
73
73
  function DonutChart(props) {
74
- var data = props.data, displayType = props.displayType, title = props.title, value = props.value, label = props.label, helperText = props.helperText, _a = props.layout, layout = _a === void 0 ? 'horizontal' : _a, _b = props.color, color = _b === void 0 ? 'categorical' : _b, _c = props.height, height = _c === void 0 ? '100%' : _c, additionalMenuItems = props.additionalMenuItems, isStacked = props.isStacked, centerLabel = props.centerLabel;
74
+ var data = props.data, displayType = props.displayType, title = props.title, value = props.value, label = props.label, helperText = props.helperText, _a = props.layout, layout = _a === void 0 ? 'horizontal' : _a, _b = props.color, color = _b === void 0 ? 'categorical' : _b, statusColorMapping = props.statusColorMapping, _c = props.height, height = _c === void 0 ? '100%' : _c, additionalMenuItems = props.additionalMenuItems, isStacked = props.isStacked, centerLabel = props.centerLabel;
75
75
  var _d = __read(React.useState(undefined), 2), activeIndex = _d[0], setActiveIndex = _d[1];
76
76
  var donutHeight = isStacked ? 196 : 150;
77
77
  var theme = (0, quantum_product_1.useTheme)();
78
78
  var BASE_COLORS = (0, theme_1.getColorScale)(theme)[color]['base'];
79
+ var groups = data.map(function (item) { return item.name; });
79
80
  return (React.createElement(chart_card_1.ChartCard, { title: title, value: value, dataTable: data, label: label, helperText: helperText, height: height, additionalMenuItems: additionalMenuItems },
80
81
  React.createElement(ResponsiveChartCard, { ownerState: { layout: layout } },
81
82
  React.createElement(quantum_product_1.StackLayoutItem, { sx: {
@@ -90,10 +91,17 @@ function DonutChart(props) {
90
91
  setActiveIndex(index);
91
92
  }, onMouseLeave: function () {
92
93
  setActiveIndex(undefined);
93
- } }, data.map(function (_, index) {
94
- return (React.createElement(recharts_1.Cell, { key: "cell-".concat(index), fill: BASE_COLORS[index % BASE_COLORS.length], opacity: activeIndex === undefined ? 1 : activeIndex === index ? 1 : 0.5 }));
94
+ } }, data.map(function (item, index) {
95
+ var fillColor;
96
+ if (color === 'status') {
97
+ fillColor = (0, theme_1.getStatusColorForGroup)(item.name, groups, theme, statusColorMapping, false);
98
+ }
99
+ else {
100
+ fillColor = BASE_COLORS[index % BASE_COLORS.length];
101
+ }
102
+ return (React.createElement(recharts_1.Cell, { key: "cell-".concat(index), fill: fillColor, opacity: activeIndex === undefined ? 1 : activeIndex === index ? 1 : 0.5 }));
95
103
  }))))),
96
104
  React.createElement(quantum_product_1.StackLayoutItem, null,
97
- React.createElement(decoupled_legend_1.default, { activeIndex: activeIndex, setActiveIndex: setActiveIndex, data: data, color: color, isStacked: isStacked })))));
105
+ React.createElement(decoupled_legend_1.default, { activeIndex: activeIndex, setActiveIndex: setActiveIndex, data: data, color: color, statusColorMapping: statusColorMapping, isStacked: isStacked })))));
98
106
  }
99
107
  exports.DonutChart = DonutChart;
@@ -29,13 +29,13 @@ import _ from 'lodash';
29
29
  import * as React from 'react';
30
30
  import { BarChart as RechartsBarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer, } from 'recharts';
31
31
  import { useTheme, Text } from '@auth0/quantum-product';
32
- import { getColorScale } from '../theme';
32
+ import { getColorScale, getStatusColorForGroup } from '../theme';
33
33
  import CustomTooltip from '../common/custom-tooltip';
34
34
  import { ChartCard } from '../chart-card';
35
35
  import { tickFormatter } from '../common/chart';
36
36
  import { CustomLegend } from '../common/custom-legend';
37
37
  export function BarChart(props) {
38
- var _a = props, data = _a.data, leftAxis = _a.leftAxis, bottomAxis = _a.bottomAxis, _b = _a.height, height = _b === void 0 ? 300 : _b, title = _a.title, value = _a.value, label = _a.label, helperText = _a.helperText, _c = _a.layout, layout = _c === void 0 ? 'vertical' : _c, _d = _a.isStacked, isStacked = _d === void 0 ? false : _d, _e = _a.color, color = _e === void 0 ? 'categorical' : _e, additionalMenuItems = _a.additionalMenuItems, tooltipProp = _a.tooltipProp, _f = _a.showTotalValueInTooltip, showTotalValueInTooltip = _f === void 0 ? false : _f, _g = _a.allowDownload, allowDownload = _g === void 0 ? true : _g, _h = _a.showChartTable, showChartTable = _h === void 0 ? true : _h, headerAction = _a.headerAction, customViewChartTable = _a.customViewChartTable, barSize = _a.barSize;
38
+ var _a = props, data = _a.data, leftAxis = _a.leftAxis, bottomAxis = _a.bottomAxis, _b = _a.height, height = _b === void 0 ? 300 : _b, title = _a.title, value = _a.value, label = _a.label, helperText = _a.helperText, _c = _a.layout, layout = _c === void 0 ? 'vertical' : _c, _d = _a.isStacked, isStacked = _d === void 0 ? false : _d, _e = _a.color, color = _e === void 0 ? 'categorical' : _e, statusColorMapping = _a.statusColorMapping, additionalMenuItems = _a.additionalMenuItems, tooltipProp = _a.tooltipProp, _f = _a.showTotalValueInTooltip, showTotalValueInTooltip = _f === void 0 ? false : _f, _g = _a.allowDownload, allowDownload = _g === void 0 ? true : _g, _h = _a.showChartTable, showChartTable = _h === void 0 ? true : _h, headerAction = _a.headerAction, customViewChartTable = _a.customViewChartTable, barSize = _a.barSize;
39
39
  var theme = useTheme();
40
40
  // Function to know how many bars we need based of how much different group values are.
41
41
  var groups = _.uniqBy(data, 'group').map(function (item) { return item.group; });
@@ -90,9 +90,17 @@ export function BarChart(props) {
90
90
  React.createElement(Tooltip, { wrapperStyle: { outline: 'none' }, content: React.createElement(CustomTooltip, { scaleType: bottomAxis.scaleType, tooltipProp: tooltipProp, showTotalValue: showTotalValueInTooltip }) }),
91
91
  React.createElement(Legend, { align: "center", content: React.createElement(CustomLegend, { selectData: selectBar, handleLegendMouseEnter: handleLegendMouseEnter, handleLegendMouseLeave: handleLegendMouseLeave, dataVisibility: barVisibility }) }),
92
92
  groups.map(function (group, index) {
93
- return (React.createElement(Bar, __assign({ key: group, dataKey: group, barSize: barSize }, (isStacked && { stackId: 'stack' }), { name: group, hide: barVisibility[group] === true, fill: barVisibility.hover === group || !barVisibility.hover
94
- ? getColorScale(theme)[color]['base'][index]
95
- : getColorScale(theme)[color]['muted'][index] })));
93
+ var isMuted = barVisibility.hover !== group && barVisibility.hover;
94
+ var fillColor;
95
+ if (color === 'status') {
96
+ fillColor = getStatusColorForGroup(group, groups, theme, statusColorMapping, isMuted);
97
+ }
98
+ else {
99
+ fillColor = isMuted
100
+ ? getColorScale(theme)[color]['muted'][index]
101
+ : getColorScale(theme)[color]['base'][index];
102
+ }
103
+ return (React.createElement(Bar, __assign({ key: group, dataKey: group, barSize: barSize }, (isStacked && { stackId: 'stack' }), { name: group, hide: barVisibility[group] === true, fill: fillColor })));
96
104
  }))) : (React.createElement("div", { style: {
97
105
  display: 'grid',
98
106
  placeItems: 'center',
@@ -3,7 +3,7 @@ import * as React from 'react';
3
3
  import { ChartSummary } from '../chart-summary';
4
4
  export function ChartCard(props) {
5
5
  var children = props.children, title = props.title, chartStatus = props.chartStatus, titleIcon = props.titleIcon, value = props.value, dataTable = props.dataTable, helperText = props.helperText, label = props.label, height = props.height, headerAction = props.headerAction, additionalMenuItems = props.additionalMenuItems, showChartTable = props.showChartTable, allowDownload = props.allowDownload, customViewChartTable = props.customViewChartTable, triggerButtonSize = props.triggerButtonSize, isVertical = props.isVertical, finalMenuItem = props.finalMenuItem;
6
- return (React.createElement(Card, { sx: { height: height, padding: 3, paddingBottom: isVertical ? 0.5 : 3 } },
6
+ return (React.createElement(Card, { sx: { height: height, padding: isVertical ? 2 : 3, paddingBottom: isVertical ? 2 : 3 } },
7
7
  React.createElement(ChartSummary, { title: title, value: value, dataTable: dataTable, helperText: helperText, label: label, headerAction: headerAction, showChartTable: showChartTable, allowDownload: allowDownload, additionalMenuItems: additionalMenuItems, customViewChartTable: customViewChartTable, triggerButtonSize: triggerButtonSize, chartStatus: chartStatus, titleIcon: titleIcon, finalMenuItem: finalMenuItem, isVertical: isVertical }),
8
8
  children));
9
9
  }
@@ -49,9 +49,22 @@ var Aggregate = styled('h4')(templateObject_1 || (templateObject_1 = __makeTempl
49
49
  var theme = _a.theme;
50
50
  return theme.typography.h4.fontSize;
51
51
  });
52
- var TitleIconWrapper = styled('div')(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n display: flex;\n align-items: center;\n & > svg {\n font-size: ", ";\n width: 1em;\n height: 1em;\n }\n"], ["\n display: flex;\n align-items: center;\n & > svg {\n font-size: ", ";\n width: 1em;\n height: 1em;\n }\n"])), function (_a) {
52
+ var TitleIconWrapper = styled('div')(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n display: flex;\n align-items: center;\n & > svg {\n font-size: ", ";\n color: ", ";\n width: 1em;\n height: 1em;\n }\n"], ["\n display: flex;\n align-items: center;\n & > svg {\n font-size: ", ";\n color: ", ";\n width: 1em;\n height: 1em;\n }\n"])), function (_a) {
53
53
  var theme = _a.theme;
54
54
  return theme.tokens.type_preset_section_subtitle.fontSize;
55
+ }, function (_a) {
56
+ var theme = _a.theme;
57
+ return theme.tokens.color_fg_bold;
58
+ });
59
+ var TitleWrapper = styled(Text)(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n font-size: ", ";\n color: ", ";\n font-weight: ", ";\n}"], ["\n font-size: ", ";\n color: ", ";\n font-weight: ", ";\n}"])), function (_a) {
60
+ var theme = _a.theme;
61
+ return theme.tokens.type_preset_section_subtitle.fontSize;
62
+ }, function (_a) {
63
+ var theme = _a.theme;
64
+ return theme.tokens.color_fg_bold;
65
+ }, function (_a) {
66
+ var theme = _a.theme;
67
+ return theme.tokens.type_preset_section_subtitle.fontWeight;
55
68
  });
56
69
  export function ChartSummary(props) {
57
70
  var title = props.title, chartStatus = props.chartStatus, value = props.value, helperText = props.helperText, label = props.label, dataTable = props.dataTable, headerAction = props.headerAction, additionalMenuItems = props.additionalMenuItems, showChartTable = props.showChartTable, allowDownload = props.allowDownload, customViewChartTable = props.customViewChartTable, _a = props.triggerButtonSize, triggerButtonSize = _a === void 0 ? 'small' : _a, titleIcon = props.titleIcon, finalMenuItem = props.finalMenuItem, isVertical = props.isVertical;
@@ -111,12 +124,11 @@ export function ChartSummary(props) {
111
124
  });
112
125
  }, [showChartTable, allowDownload, additionalMenuItems, dataTable, title, menuProps, finalMenuItem]);
113
126
  return (React.createElement("div", null,
114
- React.createElement(DescriptionBlock, { label: React.createElement("div", { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center' } },
127
+ React.createElement(DescriptionBlock, { sx: __assign({}, (isVertical && { gap: '16px' })), label: React.createElement("div", { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center' } },
115
128
  React.createElement(StackLayout, { gutter: 1 },
116
129
  titleIcon && (React.createElement(StackLayoutItem, null,
117
130
  React.createElement(TitleIconWrapper, null, titleIcon))),
118
- React.createElement(StackLayoutItem, null,
119
- React.createElement(Text, { fontWeight: 500 }, title)),
131
+ React.createElement(StackLayoutItem, null, titleIcon ? React.createElement(TitleWrapper, null, title) : React.createElement(Text, { fontWeight: 500 }, title)),
120
132
  chartStatus && (React.createElement(StackLayoutItem, { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center' } },
121
133
  React.createElement(Label, { color: chartStatus.color },
122
134
  React.createElement(StatusDot, __assign({}, chartStatus, { label: "", details: "" })),
@@ -139,4 +151,4 @@ export function ChartSummary(props) {
139
151
  label) }),
140
152
  showChartTable && (React.createElement(DataTableChart, { title: title, isOpen: isOpen, toggleIsOpen: toggleIsOpen, data: dataTable, customViewChartTable: customViewChartTable, allowDownload: allowDownload }))));
141
153
  }
142
- var templateObject_1, templateObject_2;
154
+ var templateObject_1, templateObject_2, templateObject_3;
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { StackLayout, StackLayoutItem, RowLayout, styled, useTheme } from '@auth0/quantum-product';
3
- import { getColorScale } from '../theme';
3
+ import { getColorScale, getStatusColorForGroup } from '../theme';
4
4
  var LegendDot = styled('div')({
5
5
  height: '14px',
6
6
  width: '14px',
@@ -13,14 +13,23 @@ var LegendText = styled('span')({
13
13
  cursor: 'default',
14
14
  });
15
15
  function DecoupledLegend(props) {
16
- var data = props.data, activeIndex = props.activeIndex, setActiveIndex = props.setActiveIndex, _a = props.color, color = _a === void 0 ? 'categorical' : _a, isStacked = props.isStacked;
16
+ var data = props.data, activeIndex = props.activeIndex, setActiveIndex = props.setActiveIndex, _a = props.color, color = _a === void 0 ? 'categorical' : _a, statusColorMapping = props.statusColorMapping, isStacked = props.isStacked;
17
17
  var theme = useTheme();
18
18
  var BASE_COLORS = getColorScale(theme)[color]['base'];
19
19
  var MUTED_COLORS = getColorScale(theme)[color]['muted'];
20
+ var groups = data.map(function (item) { return item.name; });
20
21
  var content = data.map(function (datum, index) {
21
22
  var isActive = activeIndex !== undefined && activeIndex === index;
22
- var color = BASE_COLORS[index % BASE_COLORS.length];
23
- var mutedColor = MUTED_COLORS[index % MUTED_COLORS.length];
23
+ var itemColor;
24
+ var mutedColor;
25
+ if (color === 'status') {
26
+ itemColor = getStatusColorForGroup(datum.name, groups, theme, statusColorMapping, false);
27
+ mutedColor = getStatusColorForGroup(datum.name, groups, theme, statusColorMapping, true);
28
+ }
29
+ else {
30
+ itemColor = BASE_COLORS[index % BASE_COLORS.length];
31
+ mutedColor = MUTED_COLORS[index % MUTED_COLORS.length];
32
+ }
24
33
  return (React.createElement(React.Fragment, { key: index },
25
34
  React.createElement(StackLayout, { gutter: 1, onMouseEnter: function () {
26
35
  setActiveIndex(index);
@@ -32,7 +41,7 @@ function DecoupledLegend(props) {
32
41
  React.createElement(StackLayoutItem, { sx: {
33
42
  alignSelf: 'center',
34
43
  } },
35
- React.createElement(LegendDot, { style: { backgroundColor: activeIndex === undefined ? color : isActive ? color : mutedColor } })),
44
+ React.createElement(LegendDot, { style: { backgroundColor: activeIndex === undefined ? itemColor : isActive ? itemColor : mutedColor } })),
36
45
  React.createElement(StackLayoutItem, { sx: {
37
46
  alignSelf: 'center',
38
47
  } },
@@ -28,7 +28,7 @@ var __read = (this && this.__read) || function (o, n) {
28
28
  import * as React from 'react';
29
29
  import { Cell, Pie, PieChart as RechartsPieChart, ResponsiveContainer } from 'recharts';
30
30
  import { StackLayout, StackLayoutItem, styled, useTheme } from '@auth0/quantum-product';
31
- import { getColorScale } from '../theme';
31
+ import { getColorScale, getStatusColorForGroup } from '../theme';
32
32
  import Center from './center';
33
33
  import DecoupledLegend from './decoupled-legend';
34
34
  import { ChartCard } from '../chart-card';
@@ -42,11 +42,12 @@ var ResponsiveChartCard = styled(StackLayout)(function (_a) {
42
42
  })));
43
43
  });
44
44
  export function DonutChart(props) {
45
- var data = props.data, displayType = props.displayType, title = props.title, value = props.value, label = props.label, helperText = props.helperText, _a = props.layout, layout = _a === void 0 ? 'horizontal' : _a, _b = props.color, color = _b === void 0 ? 'categorical' : _b, _c = props.height, height = _c === void 0 ? '100%' : _c, additionalMenuItems = props.additionalMenuItems, isStacked = props.isStacked, centerLabel = props.centerLabel;
45
+ var data = props.data, displayType = props.displayType, title = props.title, value = props.value, label = props.label, helperText = props.helperText, _a = props.layout, layout = _a === void 0 ? 'horizontal' : _a, _b = props.color, color = _b === void 0 ? 'categorical' : _b, statusColorMapping = props.statusColorMapping, _c = props.height, height = _c === void 0 ? '100%' : _c, additionalMenuItems = props.additionalMenuItems, isStacked = props.isStacked, centerLabel = props.centerLabel;
46
46
  var _d = __read(React.useState(undefined), 2), activeIndex = _d[0], setActiveIndex = _d[1];
47
47
  var donutHeight = isStacked ? 196 : 150;
48
48
  var theme = useTheme();
49
49
  var BASE_COLORS = getColorScale(theme)[color]['base'];
50
+ var groups = data.map(function (item) { return item.name; });
50
51
  return (React.createElement(ChartCard, { title: title, value: value, dataTable: data, label: label, helperText: helperText, height: height, additionalMenuItems: additionalMenuItems },
51
52
  React.createElement(ResponsiveChartCard, { ownerState: { layout: layout } },
52
53
  React.createElement(StackLayoutItem, { sx: {
@@ -61,9 +62,16 @@ export function DonutChart(props) {
61
62
  setActiveIndex(index);
62
63
  }, onMouseLeave: function () {
63
64
  setActiveIndex(undefined);
64
- } }, data.map(function (_, index) {
65
- return (React.createElement(Cell, { key: "cell-".concat(index), fill: BASE_COLORS[index % BASE_COLORS.length], opacity: activeIndex === undefined ? 1 : activeIndex === index ? 1 : 0.5 }));
65
+ } }, data.map(function (item, index) {
66
+ var fillColor;
67
+ if (color === 'status') {
68
+ fillColor = getStatusColorForGroup(item.name, groups, theme, statusColorMapping, false);
69
+ }
70
+ else {
71
+ fillColor = BASE_COLORS[index % BASE_COLORS.length];
72
+ }
73
+ return (React.createElement(Cell, { key: "cell-".concat(index), fill: fillColor, opacity: activeIndex === undefined ? 1 : activeIndex === index ? 1 : 0.5 }));
66
74
  }))))),
67
75
  React.createElement(StackLayoutItem, null,
68
- React.createElement(DecoupledLegend, { activeIndex: activeIndex, setActiveIndex: setActiveIndex, data: data, color: color, isStacked: isStacked })))));
76
+ React.createElement(DecoupledLegend, { activeIndex: activeIndex, setActiveIndex: setActiveIndex, data: data, color: color, statusColorMapping: statusColorMapping, isStacked: isStacked })))));
69
77
  }
@@ -29,7 +29,7 @@ import _ from 'lodash';
29
29
  import * as React from 'react';
30
30
  import { Area, CartesianGrid, ComposedChart, Legend, Line, ReferenceArea, ReferenceLine, ResponsiveContainer, Tooltip, XAxis, YAxis, } from 'recharts';
31
31
  import { useTheme, Text, DropdownMenu, useDropdownMenuState, Button, StackLayout, Divider, ChevronDownIcon, AlertDiamondIcon, IconButton, TableIcon, alpha, } from '@auth0/quantum-product';
32
- import { getColorScale } from '../theme';
32
+ import { getColorScale, getStatusColorForGroup } from '../theme';
33
33
  import CustomActiveDot from './custom-active-dot';
34
34
  import CustomTooltip from '../common/custom-tooltip';
35
35
  import { ChartCard } from '../chart-card';
@@ -40,7 +40,7 @@ var getThresholdColor = function (data, baseColor) {
40
40
  return data.hover === 'thresholdControl' || !data.hover ? baseColor : alpha(baseColor, 0.35);
41
41
  };
42
42
  export function LineChart(props) {
43
- var _a = props, data = _a.data, leftAxis = _a.leftAxis, bottomAxis = _a.bottomAxis, _b = _a.height, height = _b === void 0 ? 300 : _b, title = _a.title, titleIcon = _a.titleIcon, chartStatus = _a.chartStatus, value = _a.value, label = _a.label, helperText = _a.helperText, _c = _a.legend, legend = _c === void 0 ? true : _c, syncId = _a.syncId, _d = _a.color, color = _d === void 0 ? 'categorical' : _d, headerAction = _a.headerAction, additionalMenuItems = _a.additionalMenuItems, finalMenuItem = _a.finalMenuItem, thresholds = _a.thresholds, breaches = _a.breaches, disableThresholdMenu = _a.disableThresholdMenu, _e = _a.allowDownload, allowDownload = _e === void 0 ? true : _e, _f = _a.showChartTable, showChartTable = _f === void 0 ? true : _f, _g = _a.showChartTableButtonInHeader, showChartTableButtonInHeader = _g === void 0 ? true : _g, _h = _a.showDividerInHeader, showDividerInHeader = _h === void 0 ? true : _h, _j = _a.headerButtonsSize, headerButtonsSize = _j === void 0 ? 'medium' : _j, _k = _a.isVertical, isVertical = _k === void 0 ? false : _k;
43
+ var _a = props, data = _a.data, leftAxis = _a.leftAxis, bottomAxis = _a.bottomAxis, _b = _a.height, height = _b === void 0 ? 300 : _b, title = _a.title, titleIcon = _a.titleIcon, chartStatus = _a.chartStatus, value = _a.value, label = _a.label, helperText = _a.helperText, _c = _a.legend, legend = _c === void 0 ? true : _c, syncId = _a.syncId, _d = _a.color, color = _d === void 0 ? 'categorical' : _d, statusColorMapping = _a.statusColorMapping, headerAction = _a.headerAction, additionalMenuItems = _a.additionalMenuItems, finalMenuItem = _a.finalMenuItem, thresholds = _a.thresholds, breaches = _a.breaches, disableThresholdMenu = _a.disableThresholdMenu, _e = _a.allowDownload, allowDownload = _e === void 0 ? true : _e, _f = _a.showChartTable, showChartTable = _f === void 0 ? true : _f, _g = _a.showChartTableButtonInHeader, showChartTableButtonInHeader = _g === void 0 ? true : _g, _h = _a.showDividerInHeader, showDividerInHeader = _h === void 0 ? true : _h, _j = _a.headerButtonsSize, headerButtonsSize = _j === void 0 ? 'medium' : _j, _k = _a.isVertical, isVertical = _k === void 0 ? false : _k;
44
44
  var theme = useTheme();
45
45
  var _l = useDropdownMenuState({ baseId: 'threshold-menu' }), triggerProps = _l.triggerProps, menuProps = _l.menuProps;
46
46
  // Function to know how many lines we need based of how much different group values are.
@@ -164,9 +164,17 @@ export function LineChart(props) {
164
164
  top: '15px',
165
165
  }, content: React.createElement(CustomLegend, { title: title, helperText: helperText, selectData: selectLine, handleLegendMouseEnter: handleLegendMouseEnter, handleLegendMouseLeave: handleLegendMouseLeave, dataVisibility: lineVisibility, isVertical: isVertical, theme: theme }) })) : (React.createElement(Legend, { align: "center", iconSize: 14, wrapperStyle: { paddingTop: 16 }, content: React.createElement(CustomLegend, { selectData: selectLine, handleLegendMouseEnter: handleLegendMouseEnter, handleLegendMouseLeave: handleLegendMouseLeave, dataVisibility: lineVisibility, theme: theme }) })),
166
166
  groups.map(function (group, index) {
167
- return (React.createElement(Line, { key: group, dataKey: group, name: group, strokeWidth: 3, hide: lineVisibility[group] === true, stroke: lineVisibility.hover === group || !lineVisibility.hover
168
- ? getColorScale(theme)[color]['base'][index]
169
- : getColorScale(theme)[color]['muted'][index], dot: false, activeDot: CustomActiveDot() }));
167
+ var isMuted = lineVisibility.hover !== group && lineVisibility.hover;
168
+ var strokeColor;
169
+ if (color === 'status') {
170
+ strokeColor = getStatusColorForGroup(group, groups, theme, statusColorMapping, isMuted);
171
+ }
172
+ else {
173
+ strokeColor = isMuted
174
+ ? getColorScale(theme)[color]['muted'][index]
175
+ : getColorScale(theme)[color]['base'][index];
176
+ }
177
+ return (React.createElement(Line, { key: group, dataKey: group, name: group, strokeWidth: 3, hide: lineVisibility[group] === true, stroke: strokeColor, dot: false, activeDot: CustomActiveDot() }));
170
178
  }),
171
179
  threshold && (React.createElement(React.Fragment, null,
172
180
  React.createElement(Area, { type: "monotone", dataKey: 'thresholdControl', name: "".concat(threshold.threshold_label), stroke: "none", fillOpacity: 0, fill: getThresholdColor(lineVisibility, theme.tokens.color_bg_state_info), isAnimationActive: false, dot: false, activeDot: false }),
package/esm/theme.js CHANGED
@@ -34,5 +34,71 @@ export var getColorScale = function (_a) {
34
34
  alpha(tokens.color_chart_sequential_4, 0.35),
35
35
  ],
36
36
  },
37
+ status: {
38
+ base: [tokens.color_fg_state_success, tokens.color_fg_state_danger, tokens.color_fg_state_neutral],
39
+ muted: [
40
+ alpha(tokens.color_fg_state_success, 0.35),
41
+ alpha(tokens.color_fg_state_danger, 0.35),
42
+ alpha(tokens.color_fg_state_neutral, 0.35),
43
+ ],
44
+ },
37
45
  };
38
46
  };
47
+ /**
48
+ * Auto-detects status type based on common group names
49
+ */
50
+ var autoDetectStatusType = function (groupName) {
51
+ var name = groupName.toLowerCase();
52
+ if (name.includes('success') ||
53
+ name.includes('passed') ||
54
+ name.includes('completed') ||
55
+ name.includes('ok') ||
56
+ name.includes('approved')) {
57
+ return 'success';
58
+ }
59
+ if (name.includes('fail') ||
60
+ name.includes('error') ||
61
+ name.includes('reject') ||
62
+ name.includes('denied') ||
63
+ name.includes('blocked')) {
64
+ return 'failed';
65
+ }
66
+ if (name.includes('total') || name.includes('all') || name.includes('overall')) {
67
+ return 'total';
68
+ }
69
+ return null;
70
+ };
71
+ /**
72
+ * Maps groups to status colors with explicit mapping support and auto-detection fallback
73
+ */
74
+ export var getStatusColorForGroup = function (group, groups, theme, statusColorMapping, isMuted) {
75
+ if (isMuted === void 0) { isMuted = false; }
76
+ var colorScale = getColorScale(theme);
77
+ var statusColors = isMuted ? colorScale.status.muted : colorScale.status.base;
78
+ // First, try explicit mapping if provided
79
+ if (statusColorMapping) {
80
+ if (statusColorMapping.success === group) {
81
+ return statusColors[0];
82
+ }
83
+ if (statusColorMapping.failed === group) {
84
+ return statusColors[1];
85
+ }
86
+ if (statusColorMapping.total === group) {
87
+ return statusColors[2];
88
+ }
89
+ }
90
+ // Second, try auto-detection based on group name
91
+ var detectedType = autoDetectStatusType(group);
92
+ if (detectedType === 'success') {
93
+ return statusColors[0];
94
+ }
95
+ if (detectedType === 'failed') {
96
+ return statusColors[1];
97
+ }
98
+ if (detectedType === 'total') {
99
+ return statusColors[2];
100
+ }
101
+ // Fallback to positional mapping (current behavior)
102
+ var groupIndex = groups.indexOf(group);
103
+ return statusColors[groupIndex % statusColors.length];
104
+ };
@@ -69,7 +69,7 @@ var getThresholdColor = function (data, baseColor) {
69
69
  return data.hover === 'thresholdControl' || !data.hover ? baseColor : (0, quantum_product_1.alpha)(baseColor, 0.35);
70
70
  };
71
71
  function LineChart(props) {
72
- var _a = props, data = _a.data, leftAxis = _a.leftAxis, bottomAxis = _a.bottomAxis, _b = _a.height, height = _b === void 0 ? 300 : _b, title = _a.title, titleIcon = _a.titleIcon, chartStatus = _a.chartStatus, value = _a.value, label = _a.label, helperText = _a.helperText, _c = _a.legend, legend = _c === void 0 ? true : _c, syncId = _a.syncId, _d = _a.color, color = _d === void 0 ? 'categorical' : _d, headerAction = _a.headerAction, additionalMenuItems = _a.additionalMenuItems, finalMenuItem = _a.finalMenuItem, thresholds = _a.thresholds, breaches = _a.breaches, disableThresholdMenu = _a.disableThresholdMenu, _e = _a.allowDownload, allowDownload = _e === void 0 ? true : _e, _f = _a.showChartTable, showChartTable = _f === void 0 ? true : _f, _g = _a.showChartTableButtonInHeader, showChartTableButtonInHeader = _g === void 0 ? true : _g, _h = _a.showDividerInHeader, showDividerInHeader = _h === void 0 ? true : _h, _j = _a.headerButtonsSize, headerButtonsSize = _j === void 0 ? 'medium' : _j, _k = _a.isVertical, isVertical = _k === void 0 ? false : _k;
72
+ var _a = props, data = _a.data, leftAxis = _a.leftAxis, bottomAxis = _a.bottomAxis, _b = _a.height, height = _b === void 0 ? 300 : _b, title = _a.title, titleIcon = _a.titleIcon, chartStatus = _a.chartStatus, value = _a.value, label = _a.label, helperText = _a.helperText, _c = _a.legend, legend = _c === void 0 ? true : _c, syncId = _a.syncId, _d = _a.color, color = _d === void 0 ? 'categorical' : _d, statusColorMapping = _a.statusColorMapping, headerAction = _a.headerAction, additionalMenuItems = _a.additionalMenuItems, finalMenuItem = _a.finalMenuItem, thresholds = _a.thresholds, breaches = _a.breaches, disableThresholdMenu = _a.disableThresholdMenu, _e = _a.allowDownload, allowDownload = _e === void 0 ? true : _e, _f = _a.showChartTable, showChartTable = _f === void 0 ? true : _f, _g = _a.showChartTableButtonInHeader, showChartTableButtonInHeader = _g === void 0 ? true : _g, _h = _a.showDividerInHeader, showDividerInHeader = _h === void 0 ? true : _h, _j = _a.headerButtonsSize, headerButtonsSize = _j === void 0 ? 'medium' : _j, _k = _a.isVertical, isVertical = _k === void 0 ? false : _k;
73
73
  var theme = (0, quantum_product_1.useTheme)();
74
74
  var _l = (0, quantum_product_1.useDropdownMenuState)({ baseId: 'threshold-menu' }), triggerProps = _l.triggerProps, menuProps = _l.menuProps;
75
75
  // Function to know how many lines we need based of how much different group values are.
@@ -193,9 +193,17 @@ function LineChart(props) {
193
193
  top: '15px',
194
194
  }, content: React.createElement(custom_legend_1.CustomLegend, { title: title, helperText: helperText, selectData: selectLine, handleLegendMouseEnter: handleLegendMouseEnter, handleLegendMouseLeave: handleLegendMouseLeave, dataVisibility: lineVisibility, isVertical: isVertical, theme: theme }) })) : (React.createElement(recharts_1.Legend, { align: "center", iconSize: 14, wrapperStyle: { paddingTop: 16 }, content: React.createElement(custom_legend_1.CustomLegend, { selectData: selectLine, handleLegendMouseEnter: handleLegendMouseEnter, handleLegendMouseLeave: handleLegendMouseLeave, dataVisibility: lineVisibility, theme: theme }) })),
195
195
  groups.map(function (group, index) {
196
- return (React.createElement(recharts_1.Line, { key: group, dataKey: group, name: group, strokeWidth: 3, hide: lineVisibility[group] === true, stroke: lineVisibility.hover === group || !lineVisibility.hover
197
- ? (0, theme_1.getColorScale)(theme)[color]['base'][index]
198
- : (0, theme_1.getColorScale)(theme)[color]['muted'][index], dot: false, activeDot: (0, custom_active_dot_1.default)() }));
196
+ var isMuted = lineVisibility.hover !== group && lineVisibility.hover;
197
+ var strokeColor;
198
+ if (color === 'status') {
199
+ strokeColor = (0, theme_1.getStatusColorForGroup)(group, groups, theme, statusColorMapping, isMuted);
200
+ }
201
+ else {
202
+ strokeColor = isMuted
203
+ ? (0, theme_1.getColorScale)(theme)[color]['muted'][index]
204
+ : (0, theme_1.getColorScale)(theme)[color]['base'][index];
205
+ }
206
+ return (React.createElement(recharts_1.Line, { key: group, dataKey: group, name: group, strokeWidth: 3, hide: lineVisibility[group] === true, stroke: strokeColor, dot: false, activeDot: (0, custom_active_dot_1.default)() }));
199
207
  }),
200
208
  threshold && (React.createElement(React.Fragment, null,
201
209
  React.createElement(recharts_1.Area, { type: "monotone", dataKey: 'thresholdControl', name: "".concat(threshold.threshold_label), stroke: "none", fillOpacity: 0, fill: getThresholdColor(lineVisibility, theme.tokens.color_bg_state_info), isAnimationActive: false, dot: false, activeDot: false }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@auth0/quantum-charts",
3
- "version": "1.3.6",
3
+ "version": "1.3.8",
4
4
  "sideEffects": false,
5
5
  "main": "./index.js",
6
6
  "types": "./index.d.ts",
package/theme.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { ITheme } from '@auth0/quantum-product';
2
+ import { IStatusColorMapping } from './common/chart';
2
3
  export declare const getColorScale: ({ tokens }: ITheme) => {
3
4
  categorical: {
4
5
  base: string[];
@@ -8,4 +9,12 @@ export declare const getColorScale: ({ tokens }: ITheme) => {
8
9
  base: string[];
9
10
  muted: string[];
10
11
  };
12
+ status: {
13
+ base: string[];
14
+ muted: string[];
15
+ };
11
16
  };
17
+ /**
18
+ * Maps groups to status colors with explicit mapping support and auto-detection fallback
19
+ */
20
+ export declare const getStatusColorForGroup: (group: string, groups: string[], theme: ITheme, statusColorMapping?: IStatusColorMapping, isMuted?: boolean) => string;
package/theme.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getColorScale = void 0;
3
+ exports.getStatusColorForGroup = exports.getColorScale = void 0;
4
4
  var quantum_product_1 = require("@auth0/quantum-product");
5
5
  var getColorScale = function (_a) {
6
6
  var tokens = _a.tokens;
@@ -37,6 +37,73 @@ var getColorScale = function (_a) {
37
37
  (0, quantum_product_1.alpha)(tokens.color_chart_sequential_4, 0.35),
38
38
  ],
39
39
  },
40
+ status: {
41
+ base: [tokens.color_fg_state_success, tokens.color_fg_state_danger, tokens.color_fg_state_neutral],
42
+ muted: [
43
+ (0, quantum_product_1.alpha)(tokens.color_fg_state_success, 0.35),
44
+ (0, quantum_product_1.alpha)(tokens.color_fg_state_danger, 0.35),
45
+ (0, quantum_product_1.alpha)(tokens.color_fg_state_neutral, 0.35),
46
+ ],
47
+ },
40
48
  };
41
49
  };
42
50
  exports.getColorScale = getColorScale;
51
+ /**
52
+ * Auto-detects status type based on common group names
53
+ */
54
+ var autoDetectStatusType = function (groupName) {
55
+ var name = groupName.toLowerCase();
56
+ if (name.includes('success') ||
57
+ name.includes('passed') ||
58
+ name.includes('completed') ||
59
+ name.includes('ok') ||
60
+ name.includes('approved')) {
61
+ return 'success';
62
+ }
63
+ if (name.includes('fail') ||
64
+ name.includes('error') ||
65
+ name.includes('reject') ||
66
+ name.includes('denied') ||
67
+ name.includes('blocked')) {
68
+ return 'failed';
69
+ }
70
+ if (name.includes('total') || name.includes('all') || name.includes('overall')) {
71
+ return 'total';
72
+ }
73
+ return null;
74
+ };
75
+ /**
76
+ * Maps groups to status colors with explicit mapping support and auto-detection fallback
77
+ */
78
+ var getStatusColorForGroup = function (group, groups, theme, statusColorMapping, isMuted) {
79
+ if (isMuted === void 0) { isMuted = false; }
80
+ var colorScale = (0, exports.getColorScale)(theme);
81
+ var statusColors = isMuted ? colorScale.status.muted : colorScale.status.base;
82
+ // First, try explicit mapping if provided
83
+ if (statusColorMapping) {
84
+ if (statusColorMapping.success === group) {
85
+ return statusColors[0];
86
+ }
87
+ if (statusColorMapping.failed === group) {
88
+ return statusColors[1];
89
+ }
90
+ if (statusColorMapping.total === group) {
91
+ return statusColors[2];
92
+ }
93
+ }
94
+ // Second, try auto-detection based on group name
95
+ var detectedType = autoDetectStatusType(group);
96
+ if (detectedType === 'success') {
97
+ return statusColors[0];
98
+ }
99
+ if (detectedType === 'failed') {
100
+ return statusColors[1];
101
+ }
102
+ if (detectedType === 'total') {
103
+ return statusColors[2];
104
+ }
105
+ // Fallback to positional mapping (current behavior)
106
+ var groupIndex = groups.indexOf(group);
107
+ return statusColors[groupIndex % statusColors.length];
108
+ };
109
+ exports.getStatusColorForGroup = getStatusColorForGroup;