@pareto-engineering/design-system 5.2.0 → 5.3.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.
Files changed (80) hide show
  1. package/dist/cjs/a/Charts/AreaChart/AreaChart.js +61 -5
  2. package/dist/cjs/a/Charts/AreaChart/styles.scss +22 -0
  3. package/dist/cjs/a/Charts/BarChart/BarChart.js +1 -0
  4. package/dist/cjs/a/Charts/Common/CustomLegend/CustomLegend.js +23 -5
  5. package/dist/cjs/a/Charts/Common/CustomLegend/styles.scss +10 -2
  6. package/dist/cjs/a/Charts/Common/CustomTooltipContent/CustomTooltipContent.js +139 -42
  7. package/dist/cjs/a/Charts/Common/CustomTooltipContent/styles.scss +4 -0
  8. package/dist/cjs/a/Charts/PieChart/PieChart.js +39 -8
  9. package/dist/cjs/a/Charts/PieChart/styles.scss +88 -0
  10. package/dist/cjs/a/HamburgerButton/styles.scss +151 -9
  11. package/dist/cjs/a/ThroughPutIndicator/ThroughPutIndicator.js +78 -0
  12. package/dist/cjs/a/ThroughPutIndicator/index.js +13 -0
  13. package/dist/cjs/a/ThroughPutIndicator/styles.scss +35 -0
  14. package/dist/cjs/a/ToggleSwitch/ToggleSwitch.js +2 -1
  15. package/dist/cjs/a/ToggleSwitch/styles.scss +9 -2
  16. package/dist/cjs/a/Tooltip/Tooltip.js +19 -2
  17. package/dist/cjs/a/Tooltip/styles.scss +32 -4
  18. package/dist/cjs/a/XMLEditor/XMLEditor.js +4 -1
  19. package/dist/cjs/a/index.js +8 -1
  20. package/dist/cjs/f/FormInput/FormInput.js +7 -1
  21. package/dist/cjs/f/fields/ToggleInput/ToggleInput.js +126 -0
  22. package/dist/cjs/f/fields/ToggleInput/index.js +13 -0
  23. package/dist/cjs/f/fields/ToggleInput/styles.scss +22 -0
  24. package/dist/cjs/f/fields/index.js +8 -1
  25. package/dist/cjs/utils/formatting.js +27 -18
  26. package/dist/cjs/utils/index.js +6 -0
  27. package/dist/es/a/Charts/AreaChart/AreaChart.js +62 -6
  28. package/dist/es/a/Charts/AreaChart/styles.scss +22 -0
  29. package/dist/es/a/Charts/BarChart/BarChart.js +1 -0
  30. package/dist/es/a/Charts/Common/CustomLegend/CustomLegend.js +23 -5
  31. package/dist/es/a/Charts/Common/CustomLegend/styles.scss +10 -2
  32. package/dist/es/a/Charts/Common/CustomTooltipContent/CustomTooltipContent.js +128 -40
  33. package/dist/es/a/Charts/Common/CustomTooltipContent/styles.scss +4 -0
  34. package/dist/es/a/Charts/PieChart/PieChart.js +39 -8
  35. package/dist/es/a/Charts/PieChart/styles.scss +88 -0
  36. package/dist/es/a/HamburgerButton/styles.scss +151 -9
  37. package/dist/es/a/ThroughPutIndicator/ThroughPutIndicator.js +66 -0
  38. package/dist/es/a/ThroughPutIndicator/index.js +2 -0
  39. package/dist/es/a/ThroughPutIndicator/styles.scss +35 -0
  40. package/dist/es/a/ToggleSwitch/ToggleSwitch.js +2 -1
  41. package/dist/es/a/ToggleSwitch/styles.scss +9 -2
  42. package/dist/es/a/Tooltip/Tooltip.js +31 -12
  43. package/dist/es/a/Tooltip/styles.scss +32 -4
  44. package/dist/es/a/XMLEditor/XMLEditor.js +6 -3
  45. package/dist/es/a/index.js +2 -1
  46. package/dist/es/f/FormInput/FormInput.js +8 -2
  47. package/dist/es/f/fields/ToggleInput/ToggleInput.js +116 -0
  48. package/dist/es/f/fields/ToggleInput/index.js +2 -0
  49. package/dist/es/f/fields/ToggleInput/styles.scss +22 -0
  50. package/dist/es/f/fields/index.js +2 -1
  51. package/dist/es/utils/formatting.js +25 -17
  52. package/dist/es/utils/index.js +1 -1
  53. package/package.json +7 -6
  54. package/src/ui/a/Charts/AreaChart/AreaChart.jsx +74 -9
  55. package/src/ui/a/Charts/AreaChart/styles.scss +22 -0
  56. package/src/ui/a/Charts/BarChart/BarChart.jsx +1 -0
  57. package/src/ui/a/Charts/Common/CustomLegend/CustomLegend.jsx +26 -3
  58. package/src/ui/a/Charts/Common/CustomLegend/styles.scss +10 -2
  59. package/src/ui/a/Charts/Common/CustomTooltipContent/CustomTooltipContent.jsx +132 -48
  60. package/src/ui/a/Charts/Common/CustomTooltipContent/styles.scss +4 -0
  61. package/src/ui/a/Charts/PieChart/PieChart.jsx +54 -16
  62. package/src/ui/a/Charts/PieChart/styles.scss +88 -0
  63. package/src/ui/a/HamburgerButton/styles.scss +151 -9
  64. package/src/ui/a/ThroughPutIndicator/ThroughPutIndicator.jsx +90 -0
  65. package/src/ui/a/ThroughPutIndicator/index.js +2 -0
  66. package/src/ui/a/ThroughPutIndicator/styles.scss +35 -0
  67. package/src/ui/a/ToggleSwitch/ToggleSwitch.jsx +1 -1
  68. package/src/ui/a/ToggleSwitch/styles.scss +9 -2
  69. package/src/ui/a/Tooltip/Tooltip.jsx +55 -26
  70. package/src/ui/a/Tooltip/styles.scss +32 -4
  71. package/src/ui/a/XMLEditor/XMLEditor.jsx +15 -2
  72. package/src/ui/a/index.js +1 -0
  73. package/src/ui/f/FormInput/FormInput.jsx +11 -0
  74. package/src/ui/f/fields/ToggleInput/ToggleInput.jsx +140 -0
  75. package/src/ui/f/fields/ToggleInput/index.js +2 -0
  76. package/src/ui/f/fields/ToggleInput/styles.scss +22 -0
  77. package/src/ui/f/fields/index.js +1 -0
  78. package/src/ui/utils/formatting.js +38 -29
  79. package/src/ui/utils/index.js +1 -1
  80. package/tests/__snapshots__/Storyshots.test.js.snap +433 -160
@@ -81,6 +81,12 @@ Object.defineProperty(exports, "TextareaInput", {
81
81
  return _TextareaInput.TextareaInput;
82
82
  }
83
83
  });
84
+ Object.defineProperty(exports, "ToggleInput", {
85
+ enumerable: true,
86
+ get: function () {
87
+ return _ToggleInput.ToggleInput;
88
+ }
89
+ });
84
90
  Object.defineProperty(exports, "convertLatexToHtml", {
85
91
  enumerable: true,
86
92
  get: function () {
@@ -117,4 +123,5 @@ var _QueryChoices = require("./QueryChoices");
117
123
  var _LinkInput = require("./LinkInput");
118
124
  var _EditorInput = require("./EditorInput");
119
125
  var _LatexPreviewInput = require("./LatexPreviewInput");
120
- var _FileUpload = require("./FileUpload");
126
+ var _FileUpload = require("./FileUpload");
127
+ var _ToggleInput = require("./ToggleInput");
@@ -3,9 +3,10 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.snakeCaseToTitleCase = exports.formatTime = exports.formatDate = exports.DATE_FORMATS = void 0;
6
+ exports.snakeCaseToTitleCase = exports.parseDate = exports.formatTime = exports.formatDate = exports.DATE_FORMATS = void 0;
7
7
  const DATE_FORMATS = exports.DATE_FORMATS = {
8
8
  HUMAN_READABLE: 'human_readable',
9
+ HUMAN_READABLE_WITH_TIME: 'human_readable_with_time',
9
10
  TIME: 'time',
10
11
  DATETIME: 'datetime',
11
12
  CHART_DATE: 'chart_date',
@@ -49,23 +50,6 @@ const formatTime = seconds => {
49
50
  return parts.join(' ');
50
51
  };
51
52
  exports.formatTime = formatTime;
52
- const parseDate = input => {
53
- if (input instanceof Date) return input;
54
- if (typeof input === 'number') return new Date(input);
55
- if (typeof input === 'string') {
56
- if (isTimeSliceFormat(input)) {
57
- return createTimeFromSlice(input);
58
- }
59
- const parsed = new Date(input);
60
- if (isValidDate(parsed)) return parsed;
61
- const timestamp = parseInt(input, 10);
62
- if (!Number.isNaN(timestamp)) {
63
- const date = new Date(timestamp * 1000);
64
- if (isValidDate(date)) return date;
65
- }
66
- }
67
- return null;
68
- };
69
53
  const formatStrategies = {
70
54
  [DATE_FORMATS.CHART_DATE]: date => {
71
55
  const monthDay = date.toLocaleDateString('en-US', {
@@ -82,8 +66,33 @@ const formatStrategies = {
82
66
  day: 'numeric',
83
67
  timeZone: 'UTC'
84
68
  }),
69
+ [DATE_FORMATS.HUMAN_READABLE_WITH_TIME]: date => date.toLocaleString('en-US', {
70
+ year: 'numeric',
71
+ month: 'short',
72
+ day: 'numeric',
73
+ hour: '2-digit',
74
+ timeZone: 'UTC'
75
+ }),
85
76
  default: date => date.toISOString()
86
77
  };
78
+ const parseDate = input => {
79
+ if (input instanceof Date) return input;
80
+ if (typeof input === 'number') return new Date(input);
81
+ if (typeof input === 'string') {
82
+ if (isTimeSliceFormat(input)) {
83
+ return createTimeFromSlice(input);
84
+ }
85
+ const parsed = new Date(input);
86
+ if (isValidDate(parsed)) return parsed;
87
+ const timestamp = parseInt(input, 10);
88
+ if (!Number.isNaN(timestamp)) {
89
+ const date = new Date(timestamp * 1000);
90
+ if (isValidDate(date)) return date;
91
+ }
92
+ }
93
+ return null;
94
+ };
95
+ exports.parseDate = parseDate;
87
96
  const formatDate = function (input) {
88
97
  let format = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DATE_FORMATS.HUMAN_READABLE;
89
98
  try {
@@ -27,6 +27,12 @@ Object.defineProperty(exports, "formatTime", {
27
27
  return _formatting.formatTime;
28
28
  }
29
29
  });
30
+ Object.defineProperty(exports, "parseDate", {
31
+ enumerable: true,
32
+ get: function () {
33
+ return _formatting.parseDate;
34
+ }
35
+ });
30
36
  Object.defineProperty(exports, "snakeCaseToTitleCase", {
31
37
  enumerable: true,
32
38
  get: function () {
@@ -3,11 +3,39 @@ import { useState } from 'react';
3
3
  import PropTypes from 'prop-types';
4
4
  import { AreaChart as RechartsAreaChart, Area, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts';
5
5
  import styleNames from '@pareto-engineering/bem/exports';
6
- import { formatTime, formatDate, DATE_FORMATS } from "../../../utils";
6
+ import { formatTime, formatDate, DATE_FORMATS, parseDate } from "../../../utils";
7
+ import { ThroughPutIndicator } from "../../ThroughPutIndicator";
7
8
  import { CustomLegend, CustomTooltipContent, YLabelsDropDown } from "../Common";
8
9
  import "./styles.scss";
9
10
  const baseClassName = styleNames.base;
10
11
  const componentClassName = 'area-chart';
12
+
13
+ /**
14
+ * Determines whether to show only date or date with time based on the data range
15
+ *
16
+ * @param {Array} data - The chart data array
17
+ * @param {string} xKey - The key for the x-axis values (dates)
18
+ * @returns {boolean} - True if only date should be shown, false if date and time should be shown
19
+ */
20
+ const shouldShowOnlyDate = (data, xKey) => {
21
+ if (!data || data.length < 2 || !xKey) return true;
22
+
23
+ // Extract dates from the data
24
+ const dates = data.map(item => parseDate(item[xKey])).filter(date => date !== null);
25
+ if (dates.length < 2) return true;
26
+
27
+ // Sort dates chronologically
28
+ dates.sort((a, b) => a.getTime() - b.getTime());
29
+
30
+ // Calculate the difference in days between the first and last date
31
+ const firstDate = dates[0];
32
+ const lastDate = dates[dates.length - 1];
33
+ const diffInMs = lastDate.getTime() - firstDate.getTime();
34
+ const diffInDays = diffInMs / (1000 * 60 * 60 * 24);
35
+
36
+ // If the data spans less than 4 days, show only date
37
+ return diffInDays > 4;
38
+ };
11
39
  const AreaChart = ({
12
40
  id,
13
41
  className: userClassName,
@@ -23,7 +51,9 @@ const AreaChart = ({
23
51
  width,
24
52
  isTimeFormat,
25
53
  dateFormat,
26
- capitalizedLegend
54
+ capitalizedLegend,
55
+ isWorkerSubmissionChart,
56
+ totalSubmissions
27
57
  }) => {
28
58
  const allYLabels = yKeys.map(key => ({
29
59
  label: key,
@@ -35,8 +65,9 @@ const AreaChart = ({
35
65
  const min = Math.min(...yValues.flat());
36
66
  const max = Math.max(...yValues.flat());
37
67
  const margin = (max - min) * 0.1;
38
- return [min - margin, max + margin];
68
+ return [Math.max(min - margin, 0), max + margin];
39
69
  };
70
+ const showOnlyDate = shouldShowOnlyDate(data, xKey);
40
71
  return /*#__PURE__*/React.createElement("div", {
41
72
  id: id,
42
73
  className: [baseClassName, componentClassName, userClassName].filter(e => e).join(' ')
@@ -46,7 +77,15 @@ const AreaChart = ({
46
77
  allYLabels: allYLabels,
47
78
  selectedYLabels: selectedYLabels,
48
79
  setSelectedYLabels: setSelectedYLabels
80
+ })), isWorkerSubmissionChart && /*#__PURE__*/React.createElement("div", {
81
+ className: "worker-submissions-total-percentage-container"
82
+ }, /*#__PURE__*/React.createElement("p", {
83
+ className: "total-submissions-text"
84
+ }, totalSubmissions), /*#__PURE__*/React.createElement(ThroughPutIndicator, {
85
+ data: data,
86
+ keyName: "reserved"
49
87
  })), /*#__PURE__*/React.createElement(CustomLegend, {
88
+ key: id,
50
89
  colorsArray: colors,
51
90
  yKeysArray: yKeys,
52
91
  capitalizedLegend: capitalizedLegend
@@ -67,7 +106,12 @@ const AreaChart = ({
67
106
  axisLine: false,
68
107
  tickLine: false,
69
108
  tickCount: 3,
70
- tickFormatter: value => formatDate(value, dateFormat)
109
+ tickFormatter: value => {
110
+ if (showOnlyDate) {
111
+ return formatDate(value, dateFormat);
112
+ }
113
+ return formatDate(value, DATE_FORMATS.HUMAN_READABLE_WITH_TIME);
114
+ }
71
115
  }), /*#__PURE__*/React.createElement(YAxis, {
72
116
  domain: yAxisBounds,
73
117
  scale: "linear",
@@ -91,6 +135,9 @@ const AreaChart = ({
91
135
  if (isTimeFormat) {
92
136
  return formatTime(value);
93
137
  }
138
+ if (isWorkerSubmissionChart) {
139
+ return Math.round(value);
140
+ }
94
141
  return value.toFixed(2);
95
142
  }
96
143
  }), /*#__PURE__*/React.createElement(Tooltip, {
@@ -177,7 +224,15 @@ AreaChart.propTypes = {
177
224
  /**
178
225
  * The type of format for the datetime value
179
226
  */
180
- dateFormat: PropTypes.oneOf(Object.values(DATE_FORMATS))
227
+ dateFormat: PropTypes.oneOf(Object.values(DATE_FORMATS)),
228
+ /**
229
+ * Flag on whether the chart is a worker submission chart or not
230
+ */
231
+ isWorkerSubmissionChart: PropTypes.bool,
232
+ /**
233
+ * Total submissions
234
+ */
235
+ totalSubmissions: PropTypes.number
181
236
  };
182
237
  AreaChart.defaultProps = {
183
238
  filled: false,
@@ -185,6 +240,7 @@ AreaChart.defaultProps = {
185
240
  height: 300,
186
241
  capitalizedLegend: false,
187
242
  isTimeFormat: false,
188
- dateFormat: DATE_FORMATS.HUMAN_READABLE
243
+ dateFormat: DATE_FORMATS.HUMAN_READABLE,
244
+ isWorkerSubmissionChart: false
189
245
  };
190
246
  export default AreaChart;
@@ -26,6 +26,17 @@ $default-text-font-size: calc(var(--s-1) * 1rem);
26
26
  }
27
27
  }
28
28
 
29
+ .worker-submissions-total-percentage-container {
30
+ align-items: center;
31
+ display: flex;
32
+ gap: 1rem;
33
+ justify-content: flex-start;
34
+
35
+ .total-submissions-text {
36
+ font-size: calc($default-text-font-size * 2);
37
+ }
38
+ }
39
+
29
40
  /* stylelint-disable selector-max-compound-selectors -- nested elements */
30
41
  .recharts-wrapper {
31
42
  .recharts-surface {
@@ -46,3 +57,14 @@ $default-text-font-size: calc(var(--s-1) * 1rem);
46
57
  }
47
58
  }
48
59
  }
60
+
61
+ .worker-submissions-total-percentage-container {
62
+ align-items: center;
63
+ display: flex;
64
+ gap: 1rem;
65
+ justify-content: flex-start;
66
+
67
+ .total-submissions-text {
68
+ font-size: calc($default-text-font-size * 2);
69
+ }
70
+ }
@@ -40,6 +40,7 @@ const BarChart = ({
40
40
  selectedYLabels: selectedYLabels,
41
41
  setSelectedYLabels: setSelectedYLabels
42
42
  })), /*#__PURE__*/React.createElement(CustomLegend, {
43
+ key: id,
43
44
  colorsArray: selectedYLabels.map(item => item.color),
44
45
  yKeysArray: selectedYLabels.map(item => item.label),
45
46
  capitalizedLegend: capitalizedLegend
@@ -5,6 +5,13 @@ import { snakeCaseToTitleCase } from "../../../../utils";
5
5
  import "./styles.scss";
6
6
  const baseClassName = styleNames.base;
7
7
  const componentClassName = 'custom-legend';
8
+ const toCurrency = value => {
9
+ const formatter = new Intl.NumberFormat('en-US', {
10
+ style: 'currency',
11
+ currency: 'USD'
12
+ });
13
+ return formatter.format(value);
14
+ };
8
15
  const CustomLegend = ({
9
16
  id,
10
17
  className: userClassName,
@@ -13,7 +20,9 @@ const CustomLegend = ({
13
20
  orientation,
14
21
  getLegendItemTitle,
15
22
  getLegendItemSubtitle,
16
- capitalizedLegend
23
+ capitalizedLegend,
24
+ subtitleToCurrency,
25
+ isPayOutChart
17
26
  }) => /*#__PURE__*/React.createElement("div", {
18
27
  id: id,
19
28
  className: [baseClassName, componentClassName, userClassName, orientation].filter(e => e).join(' ')
@@ -29,9 +38,13 @@ const CustomLegend = ({
29
38
  }
30
39
  }), /*#__PURE__*/React.createElement("span", {
31
40
  className: "text"
32
- }, capitalizedLegend ? snakeCaseToTitleCase(getLegendItemTitle(key)) : getLegendItemTitle(key))), /*#__PURE__*/React.createElement("span", {
41
+ }, capitalizedLegend ? snakeCaseToTitleCase(getLegendItemTitle(key)) : getLegendItemTitle(key))), /*#__PURE__*/React.createElement("div", {
42
+ className: "sub-title-percentage-container"
43
+ }, /*#__PURE__*/React.createElement("span", {
33
44
  className: "sub-title"
34
- }, getLegendItemSubtitle(key)))));
45
+ }, subtitleToCurrency ? toCurrency(getLegendItemSubtitle(key)) : getLegendItemSubtitle(key)), Object.prototype.hasOwnProperty.call(key, 'percentage') && !isPayOutChart && /*#__PURE__*/React.createElement("span", {
46
+ className: "percentage-title"
47
+ }, `${key?.percentage}%`)))));
35
48
  CustomLegend.propTypes = {
36
49
  /**
37
50
  * The id of the dropdown component.
@@ -64,13 +77,18 @@ CustomLegend.propTypes = {
64
77
  /**
65
78
  * Flag on whether to capitalize legend keys
66
79
  */
67
- capitalizedLegend: PropTypes.bool
80
+ capitalizedLegend: PropTypes.bool,
81
+ /**
82
+ * Flag on whether to convert the subtitle to currency
83
+ */
84
+ subtitleToCurrency: PropTypes.bool
68
85
  };
69
86
  CustomLegend.defaultProps = {
70
87
  orientation: 'horizontal',
71
88
  getLegendItemTitle: key => key,
72
89
  /* eslint-disable no-unused-vars */
73
90
  getLegendItemSubtitle: () => {},
74
- capitalizedLegend: false
91
+ capitalizedLegend: false,
92
+ subtitleToCurrency: false
75
93
  };
76
94
  export default CustomLegend;
@@ -24,7 +24,6 @@ $default-box-shadow: 0 4px 16px 0 var(--soft-shadow);
24
24
  min-width: fit-content;
25
25
 
26
26
  .item {
27
- box-shadow: $default-box-shadow;
28
27
  padding-top: $default-padding;
29
28
  }
30
29
  }
@@ -55,12 +54,21 @@ $default-box-shadow: 0 4px 16px 0 var(--soft-shadow);
55
54
  }
56
55
  }
57
56
 
57
+
58
+
58
59
  .sub-title {
59
60
  color: var(--heading);
60
61
  display: flex;
61
62
  font-size: calc($default-text-font-size * 1.2);
62
63
  font-weight: 500;
63
- justify-content: flex-end;
64
+ justify-content: flex-start;
65
+ margin-left: 1rem;
66
+ }
67
+
68
+ .percentage-title {
69
+ color: var(--paragraph);
70
+ font-size: calc($default-text-font-size * .75);
71
+ justify-content: flex-start;
64
72
  }
65
73
  }
66
74
  }
@@ -5,6 +5,72 @@ import { formatTime, formatDate, DATE_FORMATS, snakeCaseToTitleCase } from "../.
5
5
  import "./styles.scss";
6
6
  const baseClassName = styleNames.base;
7
7
  const componentClassName = 'custom-tooltip-content';
8
+ const formatValue = (value, isTimeFormat) => {
9
+ if (isTimeFormat) {
10
+ return formatTime(value);
11
+ }
12
+ if (typeof value === 'number') {
13
+ return Number.isInteger(value) ? value : value.toFixed(2);
14
+ }
15
+ return value;
16
+ };
17
+ const PayoutPieChartLabel = ({
18
+ entry,
19
+ formatLabelValue
20
+ }) => /*#__PURE__*/React.createElement("div", {
21
+ className: "pie-chart-label"
22
+ }, /*#__PURE__*/React.createElement("div", {
23
+ className: "status"
24
+ }, /*#__PURE__*/React.createElement("span", {
25
+ className: "dot",
26
+ style: {
27
+ backgroundColor: entry?.payload?.color
28
+ }
29
+ }), /*#__PURE__*/React.createElement("p", {
30
+ className: "label",
31
+ key: `${entry.name}`,
32
+ style: {
33
+ color: entry.color,
34
+ textTransform: 'capitalize'
35
+ }
36
+ }, `${snakeCaseToTitleCase(entry.name)} `)), /*#__PURE__*/React.createElement("p", {
37
+ className: "value"
38
+ }, `${formatLabelValue(entry.value)}`));
39
+ const StandardPieChartLabel = ({
40
+ entry,
41
+ formatLabelValue
42
+ }) => /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("p", null, "Submissions"), /*#__PURE__*/React.createElement("div", {
43
+ className: "pie-chart-label"
44
+ }, /*#__PURE__*/React.createElement("div", {
45
+ className: "status"
46
+ }, /*#__PURE__*/React.createElement("span", {
47
+ className: "dot",
48
+ style: {
49
+ backgroundColor: entry?.payload?.color
50
+ }
51
+ }), /*#__PURE__*/React.createElement("p", {
52
+ className: "label",
53
+ key: `${entry.name}`,
54
+ style: {
55
+ color: entry.color,
56
+ textTransform: 'capitalize'
57
+ }
58
+ }, `${snakeCaseToTitleCase(entry.name)} `)), /*#__PURE__*/React.createElement("p", {
59
+ className: "value"
60
+ }, `${formatLabelValue(entry.value)}`), /*#__PURE__*/React.createElement("p", {
61
+ className: "percentage-title"
62
+ }, `${entry?.payload?.percentage}%`)));
63
+ const StandardChartLabel = ({
64
+ entry,
65
+ formatLabelValue
66
+ }) => /*#__PURE__*/React.createElement("p", {
67
+ className: "label",
68
+ key: `${entry.name}`,
69
+ style: {
70
+ color: entry.color,
71
+ textTransform: 'capitalize'
72
+ }
73
+ }, `${snakeCaseToTitleCase(entry.name)}: ${formatLabelValue(entry.value)}`);
8
74
  const CustomTooltipContent = ({
9
75
  id,
10
76
  className: userClassName,
@@ -13,75 +79,97 @@ const CustomTooltipContent = ({
13
79
  isDateValue,
14
80
  active,
15
81
  payload,
16
- label
82
+ label,
83
+ isPieChart,
84
+ isPayOutChart
17
85
  }) => {
18
- const formatLabelValue = value => {
19
- if (isTimeFormat) {
20
- return formatTime(value);
86
+ const formatLabelValue = React.useCallback(value => formatValue(value, isTimeFormat), [isTimeFormat]);
87
+ const renderContent = React.useCallback(entry => {
88
+ if (isPieChart && isPayOutChart) {
89
+ return /*#__PURE__*/React.createElement(PayoutPieChartLabel, {
90
+ entry: entry,
91
+ formatLabelValue: formatLabelValue
92
+ });
21
93
  }
22
- if (typeof value === 'number') {
23
- if (Number.isInteger(value)) return value;
24
- return value.toFixed(2);
94
+ if (isPieChart) {
95
+ return /*#__PURE__*/React.createElement(StandardPieChartLabel, {
96
+ entry: entry,
97
+ formatLabelValue: formatLabelValue
98
+ });
25
99
  }
26
- return value;
27
- };
28
- if (active && payload && payload.length) {
29
- const newPayload = payload.filter(item => item.name !== 'bounds');
30
- return /*#__PURE__*/React.createElement("div", {
31
- id: id,
32
- className: [baseClassName, componentClassName, userClassName].filter(e => e).join(' ')
33
- }, /*#__PURE__*/React.createElement("p", {
34
- className: "label"
35
- }, isDateValue ? formatDate(label, dateFormat) : label), newPayload.map(entry => /*#__PURE__*/React.createElement("p", {
36
- className: "label",
37
- key: `${entry.name}`,
38
- style: {
39
- color: entry.color,
40
- textTransform: 'capitalize'
41
- }
42
- }, `${snakeCaseToTitleCase(entry.name)}: ${formatLabelValue(entry.value)}`)));
100
+ return /*#__PURE__*/React.createElement(StandardChartLabel, {
101
+ entry: entry,
102
+ formatLabelValue: formatLabelValue
103
+ });
104
+ }, [isPieChart, isPayOutChart, formatLabelValue]);
105
+ if (!active || !payload || !payload.length) {
106
+ return null;
43
107
  }
44
- return null;
108
+ const filteredPayload = payload.filter(item => item?.name !== 'bounds');
109
+ return /*#__PURE__*/React.createElement("div", {
110
+ id: id,
111
+ className: [baseClassName, componentClassName, userClassName].filter(Boolean).join(' ')
112
+ }, /*#__PURE__*/React.createElement("p", {
113
+ className: "label"
114
+ }, isDateValue ? formatDate(label, dateFormat) : label), filteredPayload.map(entry => /*#__PURE__*/React.createElement(React.Fragment, {
115
+ key: entry.name || entry.dataKey
116
+ }, renderContent(entry))));
45
117
  };
46
118
  CustomTooltipContent.propTypes = {
47
119
  /**
48
- * The id of the dropdown component.
49
- */
120
+ * The id of the tooltip component
121
+ */
50
122
  id: PropTypes.string,
51
123
  /**
52
- * Additional class names for the dropdown component.
124
+ * Additional class names for the tooltip component
53
125
  */
54
126
  className: PropTypes.string,
55
127
  /**
56
- * Flag on whether it is a timeformat or not
128
+ * Flag indicating whether values should be formatted as time
57
129
  */
58
130
  isTimeFormat: PropTypes.bool,
59
131
  /**
60
- * The type of format for the datetime value
132
+ * The format to use for date values
61
133
  */
62
134
  dateFormat: PropTypes.oneOf(Object.values(DATE_FORMATS)),
63
135
  /**
64
- * Flag on whether the label is a date value or not
136
+ * Flag indicating whether the label is a date value
65
137
  */
66
138
  isDateValue: PropTypes.bool,
67
139
  /**
68
- * If set true, the tooltip is displayed.
69
- * If set false, the tooltip is hidden, usually calculated internally.
140
+ * If true, the tooltip is displayed
70
141
  */
71
142
  active: PropTypes.bool.isRequired,
72
143
  /**
73
- * The source data of the content to be displayed in the tooltip,
74
- * always calculated internally and cannot be user set.
144
+ * The source data to be displayed in the tooltip
145
+ */
146
+ payload: PropTypes.arrayOf(PropTypes.shape({
147
+ name: PropTypes.string,
148
+ value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
149
+ payload: PropTypes.shape({}),
150
+ dataKey: PropTypes.string,
151
+ color: PropTypes.string
152
+ })).isRequired,
153
+ /**
154
+ * The label value which is active
155
+ */
156
+ label: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
157
+ /**
158
+ * Flag indicating whether the chart is a pie chart
75
159
  */
76
- payload: PropTypes.arrayOf(PropTypes.string).isRequired,
160
+ isPieChart: PropTypes.bool,
77
161
  /**
78
- *The label value which is active now, usually calculated internally.
162
+ * Flag indicating whether the chart is a payout chart
79
163
  */
80
- label: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired
164
+ isPayOutChart: PropTypes.bool
81
165
  };
82
166
  CustomTooltipContent.defaultProps = {
167
+ id: undefined,
168
+ className: undefined,
83
169
  isTimeFormat: false,
84
170
  isDateValue: true,
85
- dateFormat: DATE_FORMATS.HUMAN_READABLE
171
+ dateFormat: DATE_FORMATS.HUMAN_READABLE,
172
+ isPieChart: false,
173
+ isPayOutChart: false
86
174
  };
87
- export default CustomTooltipContent;
175
+ export default /*#__PURE__*/React.memo(CustomTooltipContent);
@@ -5,6 +5,9 @@ $default-padding: 1rem;
5
5
  $default-text-font-size: calc(var(--s-1) * 1rem);
6
6
  $default-border-radius: .25rem;
7
7
  $default-border-line-width: .0625rem;
8
+ $default-legend-dot-width: .5rem;
9
+ $default-legend-dot-height: .5rem;
10
+ $default-legend-dot-margin-right: .3125rem;
8
11
 
9
12
  .#{bem.$base} {
10
13
  &.custom-tooltip-content {
@@ -20,3 +23,4 @@ $default-border-line-width: .0625rem;
20
23
  }
21
24
  }
22
25
  }
26
+
@@ -17,14 +17,18 @@ const PieChart = ({
17
17
  height,
18
18
  width,
19
19
  innerRadius,
20
- outerRadius
20
+ outerRadius,
21
+ formatTotal,
22
+ subtitleToCurrency,
23
+ isPayOutChart
21
24
  }) => {
22
25
  const total = data.reduce((sum, item) => sum + item[valueKey], 0);
26
+ const displayTotal = formatTotal ? formatTotal(total) : `${total}`;
23
27
  const formattedData = data.map(item => ({
24
28
  ...item,
25
29
  label: item[labelKey],
26
30
  color: colors[data.indexOf(item)],
27
- percentage: (item[valueKey] / total * 100).toFixed(0)
31
+ percentage: total === 0 ? 0.0 : (item[valueKey] / total * 100).toFixed(0)
28
32
  }));
29
33
  return /*#__PURE__*/React.createElement("div", {
30
34
  id: id,
@@ -52,15 +56,36 @@ const PieChart = ({
52
56
  strokeWidth: 0
53
57
  }))), /*#__PURE__*/React.createElement(Tooltip, {
54
58
  content: /*#__PURE__*/React.createElement(CustomTooltipContent, {
55
- isDateValue: false
59
+ isDateValue: false,
60
+ isPieChart: true,
61
+ isPayOutChart: isPayOutChart
56
62
  })
57
- }))), /*#__PURE__*/React.createElement(CustomLegend, {
63
+ }), /*#__PURE__*/React.createElement("text", {
64
+ x: "50%",
65
+ y: "50%",
66
+ textAnchor: "middle",
67
+ dominantBaseline: "middle",
68
+ style: {}
69
+ }, /*#__PURE__*/React.createElement("tspan", {
70
+ x: "50%",
71
+ dy: "-1.2em",
72
+ fontSize: "14",
73
+ fill: "grey"
74
+ }, "Total"), /*#__PURE__*/React.createElement("tspan", {
75
+ x: "50%",
76
+ dy: "1.2em",
77
+ fill: "var(--heading)",
78
+ fontSize: "22"
79
+ }, displayTotal)))), /*#__PURE__*/React.createElement(CustomLegend, {
80
+ key: id,
58
81
  colorsArray: colors,
59
82
  yKeysArray: formattedData,
60
83
  capitalizedLegend: true,
61
84
  orientation: "vertical",
62
85
  getLegendItemTitle: entry => entry[labelKey],
63
- getLegendItemSubtitle: entry => entry[valueKey]
86
+ getLegendItemSubtitle: entry => entry[valueKey],
87
+ subtitleToCurrency: subtitleToCurrency,
88
+ isPayOutChart: isPayOutChart
64
89
  })));
65
90
  };
66
91
  PieChart.propTypes = {
@@ -76,14 +101,20 @@ PieChart.propTypes = {
76
101
  height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
77
102
  width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
78
103
  innerRadius: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
79
- outerRadius: PropTypes.oneOfType([PropTypes.string, PropTypes.number])
104
+ outerRadius: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
105
+ formatTotal: PropTypes.func,
106
+ subtitleToCurrency: PropTypes.bool,
107
+ isPayOutChart: PropTypes.bool
80
108
  };
81
109
  PieChart.defaultProps = {
82
110
  id: undefined,
83
111
  className: undefined,
84
112
  width: '100%',
85
113
  height: 300,
86
- innerRadius: '0%',
87
- outerRadius: '100%'
114
+ innerRadius: '50%',
115
+ outerRadius: '100%',
116
+ formatTotal: null,
117
+ subtitleToCurrency: false,
118
+ isPayOutChart: false
88
119
  };
89
120
  export default PieChart;