@pareto-engineering/design-system 5.0.0 → 5.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/a/{AreaChart → Charts/AreaChart}/AreaChart.js +89 -63
- package/dist/cjs/a/Charts/AreaChart/styles.scss +48 -0
- package/dist/cjs/a/Charts/BarChart/BarChart.js +135 -0
- package/dist/cjs/a/Charts/BarChart/index.js +13 -0
- package/dist/cjs/a/Charts/BarChart/styles.scss +48 -0
- package/dist/cjs/a/Charts/Common/CustomLegend/CustomLegend.js +69 -0
- package/dist/cjs/a/Charts/Common/CustomLegend/index.js +13 -0
- package/dist/cjs/a/Charts/Common/CustomLegend/styles.scss +40 -0
- package/dist/cjs/a/Charts/Common/CustomTooltipContent/CustomTooltipContent.js +86 -0
- package/dist/cjs/a/Charts/Common/CustomTooltipContent/index.js +13 -0
- package/dist/cjs/a/Charts/Common/CustomTooltipContent/styles.scss +22 -0
- package/dist/cjs/a/Charts/Common/YLabelsDropDown/YlabelsDropDown.js +98 -0
- package/dist/cjs/a/Charts/Common/YLabelsDropDown/index.js +13 -0
- package/dist/cjs/a/Charts/Common/YLabelsDropDown/styles.scss +88 -0
- package/dist/cjs/a/Charts/Common/index.js +26 -0
- package/dist/cjs/a/Charts/index.js +19 -0
- package/dist/cjs/a/Tooltip/styles.scss +1 -1
- package/dist/cjs/a/index.js +8 -2
- package/dist/cjs/f/FormInput/FormInput.js +6 -0
- package/dist/cjs/f/fields/FileUpload/FileUpload.js +18 -4
- package/dist/cjs/f/fields/LatexPreviewInput/LatexPreviewInput.js +78 -0
- package/dist/cjs/f/fields/LatexPreviewInput/convertLatexToHtml.js +46 -0
- package/dist/cjs/f/fields/LatexPreviewInput/index.js +20 -0
- package/dist/cjs/f/fields/LatexPreviewInput/styles.scss +24 -0
- package/dist/cjs/f/fields/index.js +13 -0
- package/dist/cjs/g/FormBuilder/FormBuilder.js +3 -6
- package/dist/cjs/g/FormBuilder/common/Builder/Builder.js +1 -3
- package/dist/cjs/g/FormBuilder/common/Builder/common/InputBuilder/InputBuilder.js +5 -7
- package/dist/cjs/g/FormBuilder/common/Builder/common/Section/Section.js +2 -4
- package/dist/cjs/g/FormBuilder/common/Renderer/Renderer.js +2 -4
- package/dist/cjs/g/FormBuilder/common/Renderer/common/Section/Section.js +2 -10
- package/dist/cjs/utils/formatting.js +111 -0
- package/dist/cjs/utils/index.js +20 -1
- package/dist/es/a/{AreaChart → Charts/AreaChart}/AreaChart.js +88 -59
- package/dist/es/a/Charts/AreaChart/styles.scss +48 -0
- package/dist/es/a/Charts/BarChart/BarChart.js +126 -0
- package/dist/es/a/Charts/BarChart/index.js +1 -0
- package/dist/es/a/Charts/BarChart/styles.scss +48 -0
- package/dist/es/a/Charts/Common/CustomLegend/CustomLegend.js +59 -0
- package/dist/es/a/Charts/Common/CustomLegend/index.js +1 -0
- package/dist/es/a/Charts/Common/CustomLegend/styles.scss +40 -0
- package/dist/es/a/Charts/Common/CustomTooltipContent/CustomTooltipContent.js +76 -0
- package/dist/es/a/Charts/Common/CustomTooltipContent/index.js +1 -0
- package/dist/es/a/Charts/Common/CustomTooltipContent/styles.scss +22 -0
- package/dist/es/a/Charts/Common/YLabelsDropDown/YlabelsDropDown.js +88 -0
- package/dist/es/a/Charts/Common/YLabelsDropDown/index.js +1 -0
- package/dist/es/a/Charts/Common/YLabelsDropDown/styles.scss +88 -0
- package/dist/es/a/Charts/Common/index.js +3 -0
- package/dist/es/a/Charts/index.js +2 -0
- package/dist/es/a/Tooltip/styles.scss +1 -1
- package/dist/es/a/index.js +1 -1
- package/dist/es/f/FormInput/FormInput.js +7 -1
- package/dist/es/f/fields/FileUpload/FileUpload.js +18 -4
- package/dist/es/f/fields/LatexPreviewInput/LatexPreviewInput.js +70 -0
- package/dist/es/f/fields/LatexPreviewInput/convertLatexToHtml.js +31 -0
- package/dist/es/f/fields/LatexPreviewInput/index.js +3 -0
- package/dist/es/f/fields/LatexPreviewInput/styles.scss +24 -0
- package/dist/es/f/fields/index.js +1 -0
- package/dist/es/g/FormBuilder/FormBuilder.js +3 -6
- package/dist/es/g/FormBuilder/common/Builder/Builder.js +1 -3
- package/dist/es/g/FormBuilder/common/Builder/common/InputBuilder/InputBuilder.js +5 -7
- package/dist/es/g/FormBuilder/common/Builder/common/Section/Section.js +2 -4
- package/dist/es/g/FormBuilder/common/Renderer/Renderer.js +2 -4
- package/dist/es/g/FormBuilder/common/Renderer/common/Section/Section.js +32 -42
- package/dist/es/utils/formatting.js +102 -0
- package/dist/es/utils/index.js +2 -1
- package/jest.config.js +3 -0
- package/package.json +7 -3
- package/src/stories/a/BarChart.stories.jsx +89 -0
- package/src/ui/a/{AreaChart → Charts/AreaChart}/AreaChart.jsx +109 -54
- package/src/ui/a/Charts/AreaChart/styles.scss +48 -0
- package/src/ui/a/Charts/BarChart/BarChart.jsx +165 -0
- package/src/ui/a/Charts/BarChart/index.js +1 -0
- package/src/ui/a/Charts/BarChart/styles.scss +48 -0
- package/src/ui/a/Charts/Common/CustomLegend/CustomLegend.jsx +84 -0
- package/src/ui/a/Charts/Common/CustomLegend/index.js +1 -0
- package/src/ui/a/Charts/Common/CustomLegend/styles.scss +40 -0
- package/src/ui/a/Charts/Common/CustomTooltipContent/CustomTooltipContent.jsx +105 -0
- package/src/ui/a/Charts/Common/CustomTooltipContent/index.js +1 -0
- package/src/ui/a/Charts/Common/CustomTooltipContent/styles.scss +22 -0
- package/src/ui/a/Charts/Common/YLabelsDropDown/YlabelsDropDown.jsx +121 -0
- package/src/ui/a/Charts/Common/YLabelsDropDown/index.js +1 -0
- package/src/ui/a/Charts/Common/YLabelsDropDown/styles.scss +88 -0
- package/src/ui/a/Charts/Common/index.js +3 -0
- package/src/ui/a/Charts/index.js +2 -0
- package/src/ui/a/Tooltip/styles.scss +1 -1
- package/src/ui/a/index.js +1 -1
- package/src/ui/f/FormInput/FormInput.jsx +11 -0
- package/src/ui/f/fields/FileUpload/FileUpload.jsx +24 -4
- package/src/ui/f/fields/LatexPreviewInput/LatexPreviewInput.jsx +91 -0
- package/src/ui/f/fields/LatexPreviewInput/convertLatexToHtml.jsx +38 -0
- package/src/ui/f/fields/LatexPreviewInput/index.js +3 -0
- package/src/ui/f/fields/LatexPreviewInput/styles.scss +24 -0
- package/src/ui/f/fields/index.js +4 -0
- package/src/ui/g/FormBuilder/FormBuilder.jsx +0 -3
- package/src/ui/g/FormBuilder/common/Builder/Builder.jsx +0 -2
- package/src/ui/g/FormBuilder/common/Builder/common/InputBuilder/InputBuilder.jsx +4 -7
- package/src/ui/g/FormBuilder/common/Builder/common/Section/Section.jsx +0 -2
- package/src/ui/g/FormBuilder/common/Renderer/Renderer.jsx +0 -2
- package/src/ui/g/FormBuilder/common/Renderer/common/Section/Section.jsx +49 -64
- package/src/ui/utils/formatting.js +125 -0
- package/src/ui/utils/index.js +1 -0
- package/tests/__snapshots__/Storyshots.test.js.snap +1257 -62
- package/tests/emptyMock.js +3 -0
- package/tests/mockTextEncoder.js +7 -0
- package/tests/test-setup.js +7 -0
- package/dist/cjs/a/AreaChart/styles.scss +0 -89
- package/dist/es/a/AreaChart/styles.scss +0 -89
- package/src/ui/a/AreaChart/styles.scss +0 -89
- /package/dist/cjs/a/{AreaChart → Charts/AreaChart}/index.js +0 -0
- /package/dist/es/a/{AreaChart → Charts/AreaChart}/index.js +0 -0
- /package/src/ui/a/{AreaChart → Charts/AreaChart}/index.js +0 -0
|
@@ -40,8 +40,7 @@ const FormBuilder = _ref => {
|
|
|
40
40
|
initialBuilderValues,
|
|
41
41
|
fileUploadStatus,
|
|
42
42
|
handleFileDelete,
|
|
43
|
-
taskData
|
|
44
|
-
customInputMap
|
|
43
|
+
taskData
|
|
45
44
|
// ...otherProps
|
|
46
45
|
} = _ref;
|
|
47
46
|
const formattedJson = JSON.stringify(taskData, null, 2);
|
|
@@ -57,8 +56,7 @@ const FormBuilder = _ref => {
|
|
|
57
56
|
formBuilderId: formBuilderId,
|
|
58
57
|
onSave: onBuilderFormSave,
|
|
59
58
|
onError: onBuilderError,
|
|
60
|
-
validate: onBuilderValidate
|
|
61
|
-
customInputMap: customInputMap
|
|
59
|
+
validate: onBuilderValidate
|
|
62
60
|
}), mode === 'render' && /*#__PURE__*/React.createElement(_common.Renderer, {
|
|
63
61
|
formData: formData,
|
|
64
62
|
onSave: onRendererFormSave,
|
|
@@ -66,8 +64,7 @@ const FormBuilder = _ref => {
|
|
|
66
64
|
shouldSubmit: shouldSubmit,
|
|
67
65
|
fileUploadStatus: fileUploadStatus,
|
|
68
66
|
handleFileDelete: handleFileDelete,
|
|
69
|
-
onFileUpload: onFileUpload
|
|
70
|
-
customInputMap: customInputMap
|
|
67
|
+
onFileUpload: onFileUpload
|
|
71
68
|
}));
|
|
72
69
|
};
|
|
73
70
|
FormBuilder.propTypes = {
|
|
@@ -42,7 +42,6 @@ const Builder = _ref => {
|
|
|
42
42
|
onError,
|
|
43
43
|
validate,
|
|
44
44
|
formBuilderId,
|
|
45
|
-
customInputMap,
|
|
46
45
|
initialValues = {}
|
|
47
46
|
// ...otherProps
|
|
48
47
|
} = _ref;
|
|
@@ -121,8 +120,7 @@ const Builder = _ref => {
|
|
|
121
120
|
remove,
|
|
122
121
|
values,
|
|
123
122
|
setFieldValue
|
|
124
|
-
})
|
|
125
|
-
customInputMap: customInputMap
|
|
123
|
+
})
|
|
126
124
|
})), /*#__PURE__*/React.createElement("div", {
|
|
127
125
|
className: "section-footer"
|
|
128
126
|
}, /*#__PURE__*/React.createElement("button", {
|
|
@@ -36,8 +36,7 @@ const InputBuilder = _ref => {
|
|
|
36
36
|
style,
|
|
37
37
|
sectionIndex,
|
|
38
38
|
inputIndex,
|
|
39
|
-
onDelete
|
|
40
|
-
customInputMap
|
|
39
|
+
onDelete
|
|
41
40
|
// ...otherProps
|
|
42
41
|
} = _ref;
|
|
43
42
|
const {
|
|
@@ -64,7 +63,6 @@ const InputBuilder = _ref => {
|
|
|
64
63
|
const handleToggleShowSpecificFileTypes = () => {
|
|
65
64
|
setFieldValue(`sections.${sectionIndex}.inputs.${inputIndex}.showSpecificFileTypes`, !input.showSpecificFileTypes);
|
|
66
65
|
};
|
|
67
|
-
const customInputTypes = customInputMap ? Object.keys(customInputMap) : [];
|
|
68
66
|
return /*#__PURE__*/React.createElement("div", {
|
|
69
67
|
id: id,
|
|
70
68
|
className: [baseClassName, componentClassName, userClassName].filter(e => e).join(' '),
|
|
@@ -104,10 +102,10 @@ const InputBuilder = _ref => {
|
|
|
104
102
|
}, {
|
|
105
103
|
value: 'file',
|
|
106
104
|
label: 'File upload'
|
|
107
|
-
},
|
|
108
|
-
value:
|
|
109
|
-
label:
|
|
110
|
-
}
|
|
105
|
+
}, {
|
|
106
|
+
value: 'latex-preview-input',
|
|
107
|
+
label: 'Textbox with LaTeX preview'
|
|
108
|
+
}]
|
|
111
109
|
}), /*#__PURE__*/React.createElement("div", {
|
|
112
110
|
className: "controls"
|
|
113
111
|
}, /*#__PURE__*/React.createElement("button", {
|
|
@@ -33,8 +33,7 @@ const Section = _ref => {
|
|
|
33
33
|
className: userClassName,
|
|
34
34
|
style,
|
|
35
35
|
index,
|
|
36
|
-
handleDeleteSection
|
|
37
|
-
customInputMap
|
|
36
|
+
handleDeleteSection
|
|
38
37
|
// ...otherProps
|
|
39
38
|
} = _ref;
|
|
40
39
|
const {
|
|
@@ -66,8 +65,7 @@ const Section = _ref => {
|
|
|
66
65
|
sectionIndex: index,
|
|
67
66
|
inputIndex: indx,
|
|
68
67
|
onDelete: handleDeleteInput,
|
|
69
|
-
onCopy: handleCopyInput
|
|
70
|
-
customInputMap: customInputMap
|
|
68
|
+
onCopy: handleCopyInput
|
|
71
69
|
}),
|
|
72
70
|
identifier: input.name
|
|
73
71
|
}));
|
|
@@ -71,8 +71,7 @@ const Renderer = _ref => {
|
|
|
71
71
|
fileUploadStatus,
|
|
72
72
|
handleFileDelete,
|
|
73
73
|
onFileUpload,
|
|
74
|
-
shouldUpdateInputStateInRealTime = true
|
|
75
|
-
customInputMap
|
|
74
|
+
shouldUpdateInputStateInRealTime = true
|
|
76
75
|
// ...otherProps
|
|
77
76
|
} = _ref;
|
|
78
77
|
const [currentSectionIndex, setCurrentSectionIndex] = (0, _react.useState)(0);
|
|
@@ -150,8 +149,7 @@ const Renderer = _ref => {
|
|
|
150
149
|
fileUploadStatus: fileUploadStatus,
|
|
151
150
|
handleFileDelete: handleFileDelete,
|
|
152
151
|
onFileUpload: onFileUpload,
|
|
153
|
-
sectionIndex: sectionIndex
|
|
154
|
-
customInputMap: customInputMap
|
|
152
|
+
sectionIndex: sectionIndex
|
|
155
153
|
}))), /*#__PURE__*/React.createElement("div", {
|
|
156
154
|
className: "navigator-container"
|
|
157
155
|
}, updatedFormData.sections.length > 1 && /*#__PURE__*/React.createElement(_b.Button, {
|
|
@@ -39,11 +39,9 @@ const Section = _ref => {
|
|
|
39
39
|
fileUploadStatus,
|
|
40
40
|
handleFileDelete,
|
|
41
41
|
onFileUpload,
|
|
42
|
-
sectionIndex
|
|
43
|
-
customInputMap
|
|
42
|
+
sectionIndex
|
|
44
43
|
// ...otherProps
|
|
45
44
|
} = _ref;
|
|
46
|
-
const customInputTypes = customInputMap ? Object.keys(customInputMap) : [];
|
|
47
45
|
return /*#__PURE__*/React.createElement("div", {
|
|
48
46
|
id: id,
|
|
49
47
|
className: [baseClassName, componentClassName, userClassName].filter(e => e).join(' '),
|
|
@@ -55,9 +53,7 @@ const Section = _ref => {
|
|
|
55
53
|
name: "instructions"
|
|
56
54
|
}), inputs?.map((input, inputIndex) => {
|
|
57
55
|
const isFileInput = input.type === 'file';
|
|
58
|
-
|
|
59
|
-
const CustomInputComponent = isCustomInput ? customInputMap[input.type].component : null;
|
|
60
|
-
return !isCustomInput ? /*#__PURE__*/React.createElement(_f.FormInput, _extends({
|
|
56
|
+
return /*#__PURE__*/React.createElement(_f.FormInput, _extends({
|
|
61
57
|
key: input.name
|
|
62
58
|
}, input, {
|
|
63
59
|
disabled: readOnly
|
|
@@ -76,10 +72,6 @@ const Section = _ref => {
|
|
|
76
72
|
}));
|
|
77
73
|
onFileUpload(filesToUpload);
|
|
78
74
|
}
|
|
79
|
-
})) : /*#__PURE__*/React.createElement(CustomInputComponent, _extends({
|
|
80
|
-
key: input.name
|
|
81
|
-
}, input, {
|
|
82
|
-
disabled: readOnly
|
|
83
75
|
}));
|
|
84
76
|
}));
|
|
85
77
|
};
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.formatTime = exports.formatDate = exports.DATE_FORMATS = void 0;
|
|
7
|
+
const DATE_FORMATS = exports.DATE_FORMATS = {
|
|
8
|
+
HUMAN_READABLE: 'human_readable',
|
|
9
|
+
TIME: 'time',
|
|
10
|
+
DATETIME: 'datetime',
|
|
11
|
+
CHART_DATE: 'chart_date',
|
|
12
|
+
CHART_TIME: 'chart_time',
|
|
13
|
+
WEEKDAY_DATE: 'weekday_date',
|
|
14
|
+
DAY_VIEW: 'day_view'
|
|
15
|
+
};
|
|
16
|
+
const isValidDate = date => date instanceof Date && !Number.isNaN(date);
|
|
17
|
+
const isTimeSliceFormat = input => {
|
|
18
|
+
const timeSliceRegex = /^([01]?[0-9]|2[0-3]):[0-5][0-9]$/;
|
|
19
|
+
return timeSliceRegex.test(input);
|
|
20
|
+
};
|
|
21
|
+
const createTimeFromSlice = timeSlice => {
|
|
22
|
+
const [hours, minutes] = timeSlice.split(':').map(Number);
|
|
23
|
+
const date = new Date();
|
|
24
|
+
date.setHours(hours, minutes, 0, 0);
|
|
25
|
+
return date;
|
|
26
|
+
};
|
|
27
|
+
const format12Hour = date => {
|
|
28
|
+
const hour = date.getHours();
|
|
29
|
+
const ampm = hour >= 12 ? 'PM' : 'AM';
|
|
30
|
+
const hour12 = hour % 12 || 12;
|
|
31
|
+
return `${hour12} ${ampm}`;
|
|
32
|
+
};
|
|
33
|
+
const shouldShowYear = date => {
|
|
34
|
+
const currentYear = new Date().getFullYear();
|
|
35
|
+
return date.getFullYear() !== currentYear;
|
|
36
|
+
};
|
|
37
|
+
const formatTime = seconds => {
|
|
38
|
+
if (!seconds) return '0s';
|
|
39
|
+
const hours = Math.floor(seconds / 3600);
|
|
40
|
+
const minutes = Math.floor(seconds % 3600 / 60);
|
|
41
|
+
const remainingSeconds = Math.floor(seconds % 60);
|
|
42
|
+
const parts = [];
|
|
43
|
+
if (hours > 0) parts.push(`${hours}h`);
|
|
44
|
+
if (minutes > 0 || hours > 0 && remainingSeconds > 0) parts.push(`${minutes}m`);
|
|
45
|
+
if (remainingSeconds > 0) parts.push(`${remainingSeconds}s`);
|
|
46
|
+
return parts.join(' ');
|
|
47
|
+
};
|
|
48
|
+
exports.formatTime = formatTime;
|
|
49
|
+
const parseDate = input => {
|
|
50
|
+
if (input instanceof Date) return input;
|
|
51
|
+
if (typeof input === 'number') return new Date(input);
|
|
52
|
+
if (typeof input === 'string') {
|
|
53
|
+
if (isTimeSliceFormat(input)) {
|
|
54
|
+
return createTimeFromSlice(input);
|
|
55
|
+
}
|
|
56
|
+
const parsed = new Date(input);
|
|
57
|
+
if (isValidDate(parsed)) return parsed;
|
|
58
|
+
const timestamp = parseInt(input, 10);
|
|
59
|
+
if (!Number.isNaN(timestamp)) {
|
|
60
|
+
const date = new Date(timestamp * 1000);
|
|
61
|
+
if (isValidDate(date)) return date;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return null;
|
|
65
|
+
};
|
|
66
|
+
const formatStrategies = {
|
|
67
|
+
[DATE_FORMATS.CHART_DATE]: date => {
|
|
68
|
+
const monthDay = date.toLocaleDateString('en-US', {
|
|
69
|
+
month: 'short',
|
|
70
|
+
day: 'numeric',
|
|
71
|
+
timeZone: 'UTC'
|
|
72
|
+
});
|
|
73
|
+
return shouldShowYear(date) ? `${monthDay} ${date.getFullYear()}` : monthDay;
|
|
74
|
+
},
|
|
75
|
+
[DATE_FORMATS.CHART_TIME]: date => format12Hour(date),
|
|
76
|
+
[DATE_FORMATS.HUMAN_READABLE]: date => date.toLocaleDateString('en-US', {
|
|
77
|
+
year: 'numeric',
|
|
78
|
+
month: 'short',
|
|
79
|
+
day: 'numeric',
|
|
80
|
+
timeZone: 'UTC'
|
|
81
|
+
}),
|
|
82
|
+
default: date => date.toISOString()
|
|
83
|
+
};
|
|
84
|
+
const formatDate = function (input) {
|
|
85
|
+
let format = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DATE_FORMATS.HUMAN_READABLE;
|
|
86
|
+
try {
|
|
87
|
+
if (typeof input === 'string' && isTimeSliceFormat(input)) {
|
|
88
|
+
if (format === DATE_FORMATS.CHART_TIME || format === DATE_FORMATS.TIME) {
|
|
89
|
+
const date = createTimeFromSlice(input);
|
|
90
|
+
if (format === DATE_FORMATS.CHART_TIME) {
|
|
91
|
+
return format12Hour(date);
|
|
92
|
+
}
|
|
93
|
+
return date.toLocaleTimeString('en-US', {
|
|
94
|
+
hour: '2-digit',
|
|
95
|
+
minute: '2-digit',
|
|
96
|
+
timeZone: 'UTC'
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
return input;
|
|
100
|
+
}
|
|
101
|
+
const date = parseDate(input);
|
|
102
|
+
if (!date && (typeof input === 'string' || typeof input === 'number')) {
|
|
103
|
+
return input.toString();
|
|
104
|
+
}
|
|
105
|
+
const formatStrategy = formatStrategies[format] || formatStrategies.default;
|
|
106
|
+
return formatStrategy(date);
|
|
107
|
+
} catch (error) {
|
|
108
|
+
return 'Invalid Date';
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
exports.formatDate = formatDate;
|
package/dist/cjs/utils/index.js
CHANGED
|
@@ -3,6 +3,24 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
+
Object.defineProperty(exports, "DATE_FORMATS", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _formatting.DATE_FORMATS;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "formatDate", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () {
|
|
15
|
+
return _formatting.formatDate;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
Object.defineProperty(exports, "formatTime", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function () {
|
|
21
|
+
return _formatting.formatTime;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
6
24
|
Object.defineProperty(exports, "useDynamicPosition", {
|
|
7
25
|
enumerable: true,
|
|
8
26
|
get: function () {
|
|
@@ -21,4 +39,5 @@ Object.defineProperty(exports, "useWindowSize", {
|
|
|
21
39
|
return _hooks.useWindowSize;
|
|
22
40
|
}
|
|
23
41
|
});
|
|
24
|
-
var _hooks = require("./hooks");
|
|
42
|
+
var _hooks = require("./hooks");
|
|
43
|
+
var _formatting = require("./formatting");
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
// front/packages/design-system/src/ui/a/AreaChart/AreaChart.jsx
|
|
2
|
-
|
|
3
1
|
import * as React from 'react';
|
|
2
|
+
import { useState } from 'react';
|
|
4
3
|
import PropTypes from 'prop-types';
|
|
5
4
|
import { AreaChart as RechartsAreaChart, Area, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts';
|
|
6
5
|
import styleNames from '@pareto-engineering/bem/exports';
|
|
6
|
+
import { formatTime, formatDate, DATE_FORMATS } from "../../../utils";
|
|
7
|
+
import { CustomLegend, CustomTooltipContent, YLabelsDropDown } from "../Common";
|
|
7
8
|
import "./styles.scss";
|
|
8
|
-
|
|
9
|
-
// Local Definitions
|
|
10
|
-
|
|
11
9
|
const baseClassName = styleNames.base;
|
|
12
10
|
const componentClassName = 'area-chart';
|
|
13
11
|
const AreaChart = ({
|
|
@@ -22,9 +20,16 @@ const AreaChart = ({
|
|
|
22
20
|
colors,
|
|
23
21
|
filled,
|
|
24
22
|
height,
|
|
25
|
-
width
|
|
26
|
-
|
|
23
|
+
width,
|
|
24
|
+
isTimeFormat,
|
|
25
|
+
dateFormat,
|
|
26
|
+
capitalizedLegend
|
|
27
27
|
}) => {
|
|
28
|
+
const allYLabels = yKeys.map(key => ({
|
|
29
|
+
label: key,
|
|
30
|
+
color: colors[yKeys.indexOf(key)]
|
|
31
|
+
}));
|
|
32
|
+
const [selectedYLabels, setSelectedYLabels] = useState(allYLabels);
|
|
28
33
|
const processedData = data.map(item => {
|
|
29
34
|
const yValues = yKeys.map(key => item[key]);
|
|
30
35
|
const lowerBound = Math.min(...yValues);
|
|
@@ -32,7 +37,8 @@ const AreaChart = ({
|
|
|
32
37
|
const margin = (upperBound - lowerBound) * 0.1;
|
|
33
38
|
return {
|
|
34
39
|
...item,
|
|
35
|
-
bounds: [lowerBound - margin, upperBound + margin]
|
|
40
|
+
bounds: [lowerBound - margin, upperBound + margin],
|
|
41
|
+
isTimeFormat
|
|
36
42
|
};
|
|
37
43
|
});
|
|
38
44
|
const yAxisBounds = () => {
|
|
@@ -42,49 +48,19 @@ const AreaChart = ({
|
|
|
42
48
|
const margin = (max - min) * 0.1;
|
|
43
49
|
return [min - margin, max + margin];
|
|
44
50
|
};
|
|
45
|
-
const CustomTooltipContent = ({
|
|
46
|
-
active,
|
|
47
|
-
payload,
|
|
48
|
-
label
|
|
49
|
-
}) => {
|
|
50
|
-
if (active && payload && payload.length) {
|
|
51
|
-
const newPayload = payload.filter(item => item.name !== 'bounds');
|
|
52
|
-
return /*#__PURE__*/React.createElement("div", {
|
|
53
|
-
className: "custom-tooltip"
|
|
54
|
-
}, /*#__PURE__*/React.createElement("p", {
|
|
55
|
-
className: "label"
|
|
56
|
-
}, `${xLabel}: ${label}`), newPayload.map(entry => /*#__PURE__*/React.createElement("p", {
|
|
57
|
-
className: "label",
|
|
58
|
-
key: `${entry.name}`,
|
|
59
|
-
style: {
|
|
60
|
-
color: entry.color
|
|
61
|
-
}
|
|
62
|
-
}, `${entry.name}: ${entry.value}`)));
|
|
63
|
-
}
|
|
64
|
-
return null;
|
|
65
|
-
};
|
|
66
|
-
const CustomLegend = ({
|
|
67
|
-
colorsArray,
|
|
68
|
-
yKeysArray
|
|
69
|
-
}) => /*#__PURE__*/React.createElement("div", {
|
|
70
|
-
className: "custom-legend"
|
|
71
|
-
}, yKeysArray.map((key, index) => /*#__PURE__*/React.createElement("div", {
|
|
72
|
-
key: key,
|
|
73
|
-
className: "item"
|
|
74
|
-
}, /*#__PURE__*/React.createElement("span", {
|
|
75
|
-
className: "line",
|
|
76
|
-
style: {
|
|
77
|
-
backgroundColor: colorsArray[index]
|
|
78
|
-
}
|
|
79
|
-
}), /*#__PURE__*/React.createElement("span", {
|
|
80
|
-
className: "text"
|
|
81
|
-
}, key))));
|
|
82
51
|
return /*#__PURE__*/React.createElement("div", {
|
|
83
52
|
id: id,
|
|
84
53
|
className: [baseClassName, componentClassName, userClassName].filter(e => e).join(' ')
|
|
85
|
-
}, /*#__PURE__*/React.createElement("
|
|
54
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
55
|
+
className: "chart-header"
|
|
56
|
+
}, /*#__PURE__*/React.createElement("h3", null, title), /*#__PURE__*/React.createElement(YLabelsDropDown, {
|
|
57
|
+
allYLabels: allYLabels,
|
|
58
|
+
selectedYLabels: selectedYLabels,
|
|
59
|
+
setSelectedYLabels: setSelectedYLabels
|
|
60
|
+
})), /*#__PURE__*/React.createElement(CustomLegend, {
|
|
86
61
|
colorsArray: colors,
|
|
87
|
-
yKeysArray: yKeys
|
|
62
|
+
yKeysArray: yKeys,
|
|
63
|
+
capitalizedLegend: capitalizedLegend
|
|
88
64
|
}), /*#__PURE__*/React.createElement(ResponsiveContainer, {
|
|
89
65
|
width: width,
|
|
90
66
|
height: height
|
|
@@ -101,7 +77,8 @@ const AreaChart = ({
|
|
|
101
77
|
},
|
|
102
78
|
axisLine: false,
|
|
103
79
|
tickLine: false,
|
|
104
|
-
tickCount: 3
|
|
80
|
+
tickCount: 3,
|
|
81
|
+
tickFormatter: value => formatDate(value, dateFormat)
|
|
105
82
|
}), /*#__PURE__*/React.createElement(YAxis, {
|
|
106
83
|
domain: yAxisBounds,
|
|
107
84
|
scale: "linear",
|
|
@@ -110,7 +87,7 @@ const AreaChart = ({
|
|
|
110
87
|
value: yLabel,
|
|
111
88
|
angle: -90,
|
|
112
89
|
position: 'left',
|
|
113
|
-
offset:
|
|
90
|
+
offset: -3,
|
|
114
91
|
style: {
|
|
115
92
|
textAnchor: 'middle'
|
|
116
93
|
}
|
|
@@ -120,10 +97,17 @@ const AreaChart = ({
|
|
|
120
97
|
bottom: 10
|
|
121
98
|
},
|
|
122
99
|
axisLine: false,
|
|
123
|
-
tickLine:
|
|
124
|
-
tickFormatter: value =>
|
|
100
|
+
tickLine: false,
|
|
101
|
+
tickFormatter: value => {
|
|
102
|
+
if (isTimeFormat) {
|
|
103
|
+
return formatTime(value);
|
|
104
|
+
}
|
|
105
|
+
return value.toFixed(2);
|
|
106
|
+
}
|
|
125
107
|
}), /*#__PURE__*/React.createElement(Tooltip, {
|
|
126
|
-
content: /*#__PURE__*/React.createElement(CustomTooltipContent,
|
|
108
|
+
content: /*#__PURE__*/React.createElement(CustomTooltipContent, {
|
|
109
|
+
xLabel: xLabel
|
|
110
|
+
})
|
|
127
111
|
}), filled && /*#__PURE__*/React.createElement(Area, {
|
|
128
112
|
id: "bounds",
|
|
129
113
|
type: "linear",
|
|
@@ -135,12 +119,12 @@ const AreaChart = ({
|
|
|
135
119
|
dot: false,
|
|
136
120
|
label: false,
|
|
137
121
|
isAnimationActive: false
|
|
138
|
-
}),
|
|
139
|
-
id: key,
|
|
140
|
-
key: key,
|
|
122
|
+
}), selectedYLabels.map(key => /*#__PURE__*/React.createElement(Area, {
|
|
123
|
+
id: key.label,
|
|
124
|
+
key: key.label,
|
|
141
125
|
type: "linear",
|
|
142
|
-
dataKey: key,
|
|
143
|
-
stroke:
|
|
126
|
+
dataKey: key.label,
|
|
127
|
+
stroke: key.color,
|
|
144
128
|
fill: "none",
|
|
145
129
|
connectNulls: true,
|
|
146
130
|
dot: false,
|
|
@@ -151,21 +135,66 @@ const AreaChart = ({
|
|
|
151
135
|
})))));
|
|
152
136
|
};
|
|
153
137
|
AreaChart.propTypes = {
|
|
138
|
+
/**
|
|
139
|
+
* Array of data objects to be displayed in the chart.
|
|
140
|
+
*/
|
|
154
141
|
// eslint-disable-next-line react/forbid-prop-types
|
|
155
142
|
data: PropTypes.arrayOf(PropTypes.object).isRequired,
|
|
143
|
+
/**
|
|
144
|
+
* Title of the chart.
|
|
145
|
+
*/
|
|
156
146
|
title: PropTypes.string.isRequired,
|
|
147
|
+
/**
|
|
148
|
+
* Key for the x-axis data.
|
|
149
|
+
*/
|
|
157
150
|
xKey: PropTypes.string.isRequired,
|
|
151
|
+
/**
|
|
152
|
+
* Array of keys for the y-axis data.
|
|
153
|
+
*/
|
|
158
154
|
yKeys: PropTypes.arrayOf(PropTypes.string).isRequired,
|
|
155
|
+
/**
|
|
156
|
+
* Label for the x-axis.
|
|
157
|
+
*/
|
|
159
158
|
xLabel: PropTypes.string,
|
|
159
|
+
/**
|
|
160
|
+
* Label for the y-axis.
|
|
161
|
+
*/
|
|
160
162
|
yLabel: PropTypes.string,
|
|
163
|
+
/**
|
|
164
|
+
* Array of colors corresponding to the y-axis data keys.
|
|
165
|
+
*/
|
|
161
166
|
colors: PropTypes.arrayOf(PropTypes.string).isRequired,
|
|
167
|
+
/**
|
|
168
|
+
* Boolean to determine if the area under the curve should be filled.
|
|
169
|
+
*/
|
|
162
170
|
filled: PropTypes.bool,
|
|
171
|
+
/**
|
|
172
|
+
* Height of the chart.
|
|
173
|
+
*/
|
|
163
174
|
height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
164
|
-
|
|
175
|
+
/**
|
|
176
|
+
* Width of the chart.
|
|
177
|
+
*/
|
|
178
|
+
width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
179
|
+
/**
|
|
180
|
+
* Flag on whether to capitalize legend keys
|
|
181
|
+
*/
|
|
182
|
+
capitalizedLegend: PropTypes.bool,
|
|
183
|
+
/**
|
|
184
|
+
* Flag on whether it is a timeformat or not
|
|
185
|
+
*/
|
|
186
|
+
isTimeFormat: PropTypes.bool,
|
|
187
|
+
/**
|
|
188
|
+
* The type of format for the datetime value
|
|
189
|
+
*/
|
|
190
|
+
dateFormat: PropTypes.oneOf(Object.values(DATE_FORMATS))
|
|
165
191
|
};
|
|
166
192
|
AreaChart.defaultProps = {
|
|
167
193
|
filled: false,
|
|
168
194
|
width: '100%',
|
|
169
|
-
height: 300
|
|
195
|
+
height: 300,
|
|
196
|
+
capitalizedLegend: false,
|
|
197
|
+
isTimeFormat: false,
|
|
198
|
+
dateFormat: DATE_FORMATS.HUMAN_READABLE
|
|
170
199
|
};
|
|
171
200
|
export default AreaChart;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
@use "@pareto-engineering/bem";
|
|
2
|
+
|
|
3
|
+
$default-margin: 1rem;
|
|
4
|
+
$default-padding: 1rem;
|
|
5
|
+
$default-box-shadow: 0 .25rem .75rem var(--ui-lines);
|
|
6
|
+
$default-text-font-size: calc(var(--s-1) * 1rem);
|
|
7
|
+
|
|
8
|
+
.#{bem.$base} {
|
|
9
|
+
&.area-chart {
|
|
10
|
+
background-color: var(--background-far);
|
|
11
|
+
border-radius: var(--theme-default-border-radius);
|
|
12
|
+
box-shadow: $default-box-shadow;
|
|
13
|
+
margin: $default-margin 0;
|
|
14
|
+
padding: $default-padding;
|
|
15
|
+
|
|
16
|
+
.chart-header {
|
|
17
|
+
align-items: center;
|
|
18
|
+
display: flex;
|
|
19
|
+
justify-content: space-between;
|
|
20
|
+
margin-bottom: $default-margin;
|
|
21
|
+
|
|
22
|
+
h3 {
|
|
23
|
+
color: var(--subtitle);
|
|
24
|
+
margin: calc($default-margin / 5);
|
|
25
|
+
text-align: left;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/* stylelint-disable selector-max-compound-selectors -- nested elements */
|
|
30
|
+
.recharts-wrapper {
|
|
31
|
+
.recharts-surface {
|
|
32
|
+
.recharts-cartesian-grid line {
|
|
33
|
+
stroke: var(--ui-lines);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.recharts-text {
|
|
37
|
+
fill: var(--soft-paragraph);
|
|
38
|
+
font-size: calc($default-text-font-size * .75);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.recharts-text.recharts-label {
|
|
42
|
+
fill: var(--paragraph);
|
|
43
|
+
font-size: $default-text-font-size;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|