@pareto-engineering/design-system 5.0.5 → 5.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/a/Charts/AreaChart/AreaChart.js +3 -13
- package/dist/cjs/a/Charts/BarChart/BarChart.js +6 -4
- package/dist/cjs/a/Charts/Common/CustomLegend/CustomLegend.js +26 -7
- package/dist/cjs/a/Charts/Common/CustomLegend/styles.scss +41 -14
- package/dist/cjs/a/Charts/Common/CustomTooltipContent/CustomTooltipContent.js +18 -7
- package/dist/cjs/a/Charts/Common/YLabelsDropDown/YlabelsDropDown.js +3 -4
- package/dist/cjs/a/Charts/Common/YLabelsDropDown/styles.scss +7 -6
- package/dist/cjs/a/Charts/PieChart/PieChart.js +99 -0
- package/dist/cjs/a/Charts/PieChart/index.js +13 -0
- package/dist/cjs/a/Charts/PieChart/styles.scss +48 -0
- package/dist/cjs/a/Charts/index.js +8 -1
- package/dist/cjs/a/Notification/styles.scss +17 -5
- package/dist/cjs/a/index.js +6 -0
- package/dist/cjs/f/FormInput/FormInput.js +1 -1
- package/dist/cjs/f/fields/LatexPreviewInput/LatexPreviewInput.js +1 -1
- package/dist/cjs/f/fields/LatexPreviewInput/styles.scss +1 -0
- package/dist/cjs/f/fields/TextareaInput/TextareaInput.js +4 -2
- package/dist/cjs/g/FormBuilder/common/Builder/common/InputBuilder/InputBuilder.js +27 -1
- package/dist/cjs/g/FormBuilder/common/Builder/common/InputBuilder/styles.scss +15 -0
- package/dist/cjs/g/FormBuilder/common/Builder/common/Section/Section.js +6 -2
- package/dist/cjs/g/FormBuilder/common/Renderer/Renderer.js +6 -0
- package/dist/cjs/utils/applyCharacterLimit.js +75 -0
- package/dist/cjs/utils/formatting.js +10 -2
- package/dist/cjs/utils/index.js +14 -1
- package/dist/es/a/Charts/AreaChart/AreaChart.js +3 -13
- package/dist/es/a/Charts/BarChart/BarChart.js +6 -4
- package/dist/es/a/Charts/Common/CustomLegend/CustomLegend.js +38 -21
- package/dist/es/a/Charts/Common/CustomLegend/styles.scss +41 -14
- package/dist/es/a/Charts/Common/CustomTooltipContent/CustomTooltipContent.js +19 -8
- package/dist/es/a/Charts/Common/YLabelsDropDown/YlabelsDropDown.js +3 -5
- package/dist/es/a/Charts/Common/YLabelsDropDown/styles.scss +7 -6
- package/dist/es/a/Charts/PieChart/PieChart.js +89 -0
- package/dist/es/a/Charts/PieChart/index.js +1 -0
- package/dist/es/a/Charts/PieChart/styles.scss +48 -0
- package/dist/es/a/Charts/index.js +2 -1
- package/dist/es/a/Notification/styles.scss +17 -5
- package/dist/es/a/index.js +1 -1
- package/dist/es/f/FormInput/FormInput.js +1 -1
- package/dist/es/f/fields/LatexPreviewInput/LatexPreviewInput.js +1 -1
- package/dist/es/f/fields/LatexPreviewInput/styles.scss +1 -0
- package/dist/es/f/fields/TextareaInput/TextareaInput.js +4 -2
- package/dist/es/g/FormBuilder/common/Builder/common/InputBuilder/InputBuilder.js +27 -1
- package/dist/es/g/FormBuilder/common/Builder/common/InputBuilder/styles.scss +15 -0
- package/dist/es/g/FormBuilder/common/Builder/common/Section/Section.js +6 -2
- package/dist/es/g/FormBuilder/common/Renderer/Renderer.js +6 -0
- package/dist/es/utils/applyCharacterLimit.js +67 -0
- package/dist/es/utils/formatting.js +7 -0
- package/dist/es/utils/index.js +2 -1
- package/package.json +3 -3
- package/src/stories/a/AreaChart.stories.jsx +1 -1
- package/src/stories/a/BarChart.stories.jsx +1 -1
- package/src/stories/a/PieChart.stories.jsx +53 -0
- package/src/ui/a/Charts/AreaChart/AreaChart.jsx +8 -14
- package/src/ui/a/Charts/BarChart/BarChart.jsx +4 -2
- package/src/ui/a/Charts/Common/CustomLegend/CustomLegend.jsx +54 -29
- package/src/ui/a/Charts/Common/CustomLegend/styles.scss +41 -14
- package/src/ui/a/Charts/Common/CustomTooltipContent/CustomTooltipContent.jsx +25 -13
- package/src/ui/a/Charts/Common/YLabelsDropDown/YlabelsDropDown.jsx +4 -4
- package/src/ui/a/Charts/Common/YLabelsDropDown/styles.scss +7 -6
- package/src/ui/a/Charts/PieChart/PieChart.jsx +125 -0
- package/src/ui/a/Charts/PieChart/index.js +1 -0
- package/src/ui/a/Charts/PieChart/styles.scss +48 -0
- package/src/ui/a/Charts/index.js +1 -0
- package/src/ui/a/Notification/styles.scss +17 -5
- package/src/ui/a/index.js +1 -1
- package/src/ui/f/FormInput/FormInput.jsx +1 -0
- package/src/ui/f/fields/LatexPreviewInput/LatexPreviewInput.jsx +1 -0
- package/src/ui/f/fields/LatexPreviewInput/styles.scss +1 -0
- package/src/ui/f/fields/TextareaInput/TextareaInput.jsx +2 -0
- package/src/ui/g/FormBuilder/common/Builder/common/InputBuilder/InputBuilder.jsx +34 -0
- package/src/ui/g/FormBuilder/common/Builder/common/InputBuilder/styles.scss +15 -0
- package/src/ui/g/FormBuilder/common/Builder/common/Section/Section.jsx +10 -2
- package/src/ui/g/FormBuilder/common/Renderer/Renderer.jsx +5 -0
- package/src/ui/g/FormBuilder/common/Renderer/common/Section/Section.jsx +0 -1
- package/src/ui/utils/applyCharacterLimit.js +80 -0
- package/src/ui/utils/formatting.js +8 -0
- package/src/ui/utils/index.js +4 -1
- package/tests/__snapshots__/Storyshots.test.js.snap +1165 -429
|
@@ -63,6 +63,7 @@ const InputBuilder = _ref => {
|
|
|
63
63
|
const handleToggleShowSpecificFileTypes = () => {
|
|
64
64
|
setFieldValue(`sections.${sectionIndex}.inputs.${inputIndex}.showSpecificFileTypes`, !input.showSpecificFileTypes);
|
|
65
65
|
};
|
|
66
|
+
const textChoices = ['text', 'number', 'textarea', 'latex-preview-input'];
|
|
66
67
|
return /*#__PURE__*/React.createElement("div", {
|
|
67
68
|
id: id,
|
|
68
69
|
className: [baseClassName, componentClassName, userClassName].filter(e => e).join(' '),
|
|
@@ -139,7 +140,32 @@ const InputBuilder = _ref => {
|
|
|
139
140
|
label: "Description (optional)",
|
|
140
141
|
name: `sections.${sectionIndex}.inputs.${inputIndex}.description`,
|
|
141
142
|
placeholder: "Describe details for the question"
|
|
142
|
-
})),
|
|
143
|
+
})), textChoices.includes(input?.type) && /*#__PURE__*/React.createElement("div", {
|
|
144
|
+
className: "character-limit-container"
|
|
145
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
146
|
+
className: "is-required"
|
|
147
|
+
}, /*#__PURE__*/React.createElement("span", {
|
|
148
|
+
className: "s0"
|
|
149
|
+
}, "Limit number of characters permitted for this input"), /*#__PURE__*/React.createElement(_a.ToggleSwitch, {
|
|
150
|
+
handleOnChange: () => {
|
|
151
|
+
setFieldValue(`sections.${sectionIndex}.inputs.${inputIndex}.hasCharacterLimit`, !input?.hasCharacterLimit);
|
|
152
|
+
if (!input?.hasCharacterLimit) {
|
|
153
|
+
setFieldValue(`sections.${sectionIndex}.inputs.${inputIndex}.maxLength`, '');
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
checked: input?.hasCharacterLimit,
|
|
157
|
+
style: getToggleSwitchStyles(!input?.hasCharacterLimit),
|
|
158
|
+
inputId: `sections_${sectionIndex}_inputs.${inputIndex}_character_limit_toggle`
|
|
159
|
+
})), /*#__PURE__*/React.createElement("div", {
|
|
160
|
+
className: "character-limit-input"
|
|
161
|
+
}, input?.hasCharacterLimit && /*#__PURE__*/React.createElement(_f.TextInput, {
|
|
162
|
+
label: "Enter the maximum number of characters permitted.",
|
|
163
|
+
name: `sections.${sectionIndex}.inputs.${inputIndex}.maxLength`,
|
|
164
|
+
placeholder: "",
|
|
165
|
+
type: "number",
|
|
166
|
+
validate: _f.integerAndGreaterThanZero,
|
|
167
|
+
value: input?.maxLength
|
|
168
|
+
}))), shouldRenderOptions && /*#__PURE__*/React.createElement(_formik.FieldArray, {
|
|
143
169
|
name: `sections.${sectionIndex}.inputs.${inputIndex}.options`
|
|
144
170
|
}, _ref2 => {
|
|
145
171
|
let {
|
|
@@ -64,6 +64,21 @@ $default-list-width: var(--action-button-width, 18rem);
|
|
|
64
64
|
margin-bottom: $default-margin;
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
+
> .character-limit-container {
|
|
68
|
+
display: flex;
|
|
69
|
+
flex-direction: column;
|
|
70
|
+
gap: var(--gap);
|
|
71
|
+
|
|
72
|
+
> .is-required {
|
|
73
|
+
display: flex;
|
|
74
|
+
flex-direction: row;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
> .character-limit-input {
|
|
78
|
+
flex-direction: column;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
67
82
|
> .input-options {
|
|
68
83
|
display: flex;
|
|
69
84
|
flex-direction: column;
|
|
@@ -59,7 +59,10 @@ const Section = _ref => {
|
|
|
59
59
|
inputs
|
|
60
60
|
} = section;
|
|
61
61
|
(0, _react.useEffect)(() => {
|
|
62
|
-
const
|
|
62
|
+
const orderMap = new Map();
|
|
63
|
+
section.orderedInputDragIds.forEach((identifier, indx) => orderMap.set(identifier, indx));
|
|
64
|
+
const orderedInputs = inputs.sort((a, b) => orderMap.get(a.name) - orderMap.get(b.name));
|
|
65
|
+
const items = orderedInputs.map((input, indx) => ({
|
|
63
66
|
Content: /*#__PURE__*/React.createElement(_InputBuilder.InputBuilder, {
|
|
64
67
|
key: input.name,
|
|
65
68
|
sectionIndex: index,
|
|
@@ -71,6 +74,7 @@ const Section = _ref => {
|
|
|
71
74
|
}));
|
|
72
75
|
setDraggableInputs(items);
|
|
73
76
|
}, [inputs.length, index]);
|
|
77
|
+
const dragAndDropKey = draggableInputs.map(e => e.identifier).join(',');
|
|
74
78
|
return /*#__PURE__*/React.createElement("div", {
|
|
75
79
|
id: id,
|
|
76
80
|
className: [baseClassName, componentClassName, userClassName].filter(e => e).join(' '),
|
|
@@ -104,7 +108,7 @@ const Section = _ref => {
|
|
|
104
108
|
const ids = reOrderedItems.map(e => e.identifier);
|
|
105
109
|
setFieldValue(`sections.${index}.orderedInputDragIds`, ids);
|
|
106
110
|
},
|
|
107
|
-
key:
|
|
111
|
+
key: dragAndDropKey
|
|
108
112
|
}), /*#__PURE__*/React.createElement("button", {
|
|
109
113
|
type: "button",
|
|
110
114
|
className: "add-question-cta",
|
|
@@ -11,6 +11,7 @@ var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
|
11
11
|
var _exports = _interopRequireDefault(require("@pareto-engineering/bem/exports"));
|
|
12
12
|
var _b = require("../../../../b");
|
|
13
13
|
require("./styles.scss");
|
|
14
|
+
var _utils = require("../../../../utils");
|
|
14
15
|
var _common = require("./common");
|
|
15
16
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
16
17
|
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
@@ -141,6 +142,11 @@ const Renderer = _ref => {
|
|
|
141
142
|
onSave?.(formDataWithValues);
|
|
142
143
|
}
|
|
143
144
|
}, [values]);
|
|
145
|
+
(0, _react.useEffect)(() => {
|
|
146
|
+
(0, _utils.applyCharacterLimit)({
|
|
147
|
+
setMaxLength: false
|
|
148
|
+
});
|
|
149
|
+
}, [values]);
|
|
144
150
|
const hasErrors = Object.keys(errors).length > 0;
|
|
145
151
|
return /*#__PURE__*/React.createElement(_formik.Form, null, updatedFormData.sections.map((section, sectionIndex) => sectionIndex === currentSectionIndex && /*#__PURE__*/React.createElement(_common.Section, _extends({
|
|
146
152
|
key: `${section.title}`
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.applyCharacterLimit = void 0;
|
|
7
|
+
const applyCharacterLimit = function () {
|
|
8
|
+
let setMaxLength = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
|
|
9
|
+
setTimeout(() => {
|
|
10
|
+
document.querySelectorAll("[class*='limit-character-count-']").forEach(parent => {
|
|
11
|
+
const match = parent.className.match(/limit-character-count-(\d+)/);
|
|
12
|
+
if (!match) return;
|
|
13
|
+
const maxLength = parseInt(match[1], 10);
|
|
14
|
+
const fields = parent.matches("input[type='text'], input[type='email'], input[type='password'], input[type='search'], textarea") ? [parent] : Array.from(parent.querySelectorAll("input[type='text'], input[type='email'], input[type='password'], input[type='search'], textarea"));
|
|
15
|
+
if (!fields.length) return;
|
|
16
|
+
const characterCounterBaseClassName = 's-2 character-counter';
|
|
17
|
+
const characterCounterClassName = `${characterCounterBaseClassName} x-paragraph c-x`;
|
|
18
|
+
const characterCounterWarningClassName = `${characterCounterBaseClassName} x-orange c-x`;
|
|
19
|
+
const characterCounterErrorClassName = `${characterCounterBaseClassName} x-error c-x`;
|
|
20
|
+
fields.forEach(field => {
|
|
21
|
+
if (field.parentNode.querySelector('.character-counter')) return;
|
|
22
|
+
if (setMaxLength) {
|
|
23
|
+
field.setAttribute('maxlength', maxLength);
|
|
24
|
+
}
|
|
25
|
+
const counter = document.createElement('span');
|
|
26
|
+
counter.className = characterCounterClassName;
|
|
27
|
+
counter.style.position = 'absolute';
|
|
28
|
+
counter.style.right = '10px';
|
|
29
|
+
counter.style.bottom = '-20px';
|
|
30
|
+
counter.style.pointerEvents = 'none';
|
|
31
|
+
let wrapper;
|
|
32
|
+
const {
|
|
33
|
+
parentNode
|
|
34
|
+
} = field;
|
|
35
|
+
const computedStyle = window.getComputedStyle(parentNode);
|
|
36
|
+
if (parentNode.style && parentNode.style.position === 'relative' || computedStyle.getPropertyValue('position') === 'relative') {
|
|
37
|
+
wrapper = parentNode;
|
|
38
|
+
} else {
|
|
39
|
+
wrapper = document.createElement('div');
|
|
40
|
+
wrapper.style.position = 'relative';
|
|
41
|
+
wrapper.style.display = 'inline-block';
|
|
42
|
+
wrapper.style.width = '100%';
|
|
43
|
+
field.parentNode.insertBefore(wrapper, field);
|
|
44
|
+
wrapper.appendChild(field);
|
|
45
|
+
}
|
|
46
|
+
wrapper.appendChild(counter);
|
|
47
|
+
function updateCounter() {
|
|
48
|
+
if (field.value.length > maxLength) {
|
|
49
|
+
// eslint-disable-next-line no-param-reassign
|
|
50
|
+
field.value = field.value.substring(0, maxLength);
|
|
51
|
+
}
|
|
52
|
+
const {
|
|
53
|
+
length
|
|
54
|
+
} = field.value;
|
|
55
|
+
counter.textContent = `${length}/${maxLength}`;
|
|
56
|
+
if (length >= maxLength) {
|
|
57
|
+
counter.className = characterCounterErrorClassName;
|
|
58
|
+
} else if (length >= maxLength * 0.9) {
|
|
59
|
+
counter.className = characterCounterWarningClassName;
|
|
60
|
+
} else {
|
|
61
|
+
counter.className = characterCounterClassName;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
field.removeEventListener('input', updateCounter);
|
|
65
|
+
field.removeEventListener('paste', updateCounter);
|
|
66
|
+
field.addEventListener('input', updateCounter);
|
|
67
|
+
field.addEventListener('paste', () => {
|
|
68
|
+
setTimeout(updateCounter, 0);
|
|
69
|
+
});
|
|
70
|
+
updateCounter();
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
}, 100); // Small delay to ensure DOM is ready
|
|
74
|
+
};
|
|
75
|
+
exports.applyCharacterLimit = applyCharacterLimit;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.formatTime = exports.formatDate = exports.DATE_FORMATS = void 0;
|
|
6
|
+
exports.snakeCaseToTitleCase = exports.formatTime = exports.formatDate = exports.DATE_FORMATS = void 0;
|
|
7
7
|
const DATE_FORMATS = exports.DATE_FORMATS = {
|
|
8
8
|
HUMAN_READABLE: 'human_readable',
|
|
9
9
|
TIME: 'time',
|
|
@@ -43,6 +43,9 @@ const formatTime = seconds => {
|
|
|
43
43
|
if (hours > 0) parts.push(`${hours}h`);
|
|
44
44
|
if (minutes > 0 || hours > 0 && remainingSeconds > 0) parts.push(`${minutes}m`);
|
|
45
45
|
if (remainingSeconds > 0) parts.push(`${remainingSeconds}s`);
|
|
46
|
+
|
|
47
|
+
// Cater for decimal seconds
|
|
48
|
+
if (parts.length === 0) return '0s';
|
|
46
49
|
return parts.join(' ');
|
|
47
50
|
};
|
|
48
51
|
exports.formatTime = formatTime;
|
|
@@ -108,4 +111,9 @@ const formatDate = function (input) {
|
|
|
108
111
|
return 'Invalid Date';
|
|
109
112
|
}
|
|
110
113
|
};
|
|
111
|
-
exports.formatDate = formatDate;
|
|
114
|
+
exports.formatDate = formatDate;
|
|
115
|
+
const snakeCaseToTitleCase = word => {
|
|
116
|
+
const result = word.replace(/([A-Z])/g, ' $1');
|
|
117
|
+
return result.charAt(0).toUpperCase() + result.slice(1);
|
|
118
|
+
};
|
|
119
|
+
exports.snakeCaseToTitleCase = snakeCaseToTitleCase;
|
package/dist/cjs/utils/index.js
CHANGED
|
@@ -9,6 +9,12 @@ Object.defineProperty(exports, "DATE_FORMATS", {
|
|
|
9
9
|
return _formatting.DATE_FORMATS;
|
|
10
10
|
}
|
|
11
11
|
});
|
|
12
|
+
Object.defineProperty(exports, "applyCharacterLimit", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () {
|
|
15
|
+
return _applyCharacterLimit.applyCharacterLimit;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
12
18
|
Object.defineProperty(exports, "formatDate", {
|
|
13
19
|
enumerable: true,
|
|
14
20
|
get: function () {
|
|
@@ -21,6 +27,12 @@ Object.defineProperty(exports, "formatTime", {
|
|
|
21
27
|
return _formatting.formatTime;
|
|
22
28
|
}
|
|
23
29
|
});
|
|
30
|
+
Object.defineProperty(exports, "snakeCaseToTitleCase", {
|
|
31
|
+
enumerable: true,
|
|
32
|
+
get: function () {
|
|
33
|
+
return _formatting.snakeCaseToTitleCase;
|
|
34
|
+
}
|
|
35
|
+
});
|
|
24
36
|
Object.defineProperty(exports, "useDynamicPosition", {
|
|
25
37
|
enumerable: true,
|
|
26
38
|
get: function () {
|
|
@@ -40,4 +52,5 @@ Object.defineProperty(exports, "useWindowSize", {
|
|
|
40
52
|
}
|
|
41
53
|
});
|
|
42
54
|
var _hooks = require("./hooks");
|
|
43
|
-
var _formatting = require("./formatting");
|
|
55
|
+
var _formatting = require("./formatting");
|
|
56
|
+
var _applyCharacterLimit = require("./applyCharacterLimit");
|
|
@@ -30,17 +30,6 @@ const AreaChart = ({
|
|
|
30
30
|
color: colors[yKeys.indexOf(key)]
|
|
31
31
|
}));
|
|
32
32
|
const [selectedYLabels, setSelectedYLabels] = useState(allYLabels);
|
|
33
|
-
const processedData = data.map(item => {
|
|
34
|
-
const yValues = yKeys.map(key => item[key]);
|
|
35
|
-
const lowerBound = Math.min(...yValues);
|
|
36
|
-
const upperBound = Math.max(...yValues);
|
|
37
|
-
const margin = (upperBound - lowerBound) * 0.1;
|
|
38
|
-
return {
|
|
39
|
-
...item,
|
|
40
|
-
bounds: [lowerBound - margin, upperBound + margin],
|
|
41
|
-
isTimeFormat
|
|
42
|
-
};
|
|
43
|
-
});
|
|
44
33
|
const yAxisBounds = () => {
|
|
45
34
|
const yValues = data.map(item => yKeys.map(key => item[key]));
|
|
46
35
|
const min = Math.min(...yValues.flat());
|
|
@@ -65,7 +54,7 @@ const AreaChart = ({
|
|
|
65
54
|
width: width,
|
|
66
55
|
height: height
|
|
67
56
|
}, /*#__PURE__*/React.createElement(RechartsAreaChart, {
|
|
68
|
-
data:
|
|
57
|
+
data: data
|
|
69
58
|
}, /*#__PURE__*/React.createElement(CartesianGrid, {
|
|
70
59
|
strokeDasharray: "3 3"
|
|
71
60
|
}), /*#__PURE__*/React.createElement(XAxis, {
|
|
@@ -106,7 +95,8 @@ const AreaChart = ({
|
|
|
106
95
|
}
|
|
107
96
|
}), /*#__PURE__*/React.createElement(Tooltip, {
|
|
108
97
|
content: /*#__PURE__*/React.createElement(CustomTooltipContent, {
|
|
109
|
-
|
|
98
|
+
dateFormat: dateFormat,
|
|
99
|
+
isTimeFormat: isTimeFormat
|
|
110
100
|
})
|
|
111
101
|
}), filled && /*#__PURE__*/React.createElement(Area, {
|
|
112
102
|
id: "bounds",
|
|
@@ -21,8 +21,9 @@ const BarChart = ({
|
|
|
21
21
|
yLabel,
|
|
22
22
|
colors,
|
|
23
23
|
height,
|
|
24
|
-
width
|
|
25
|
-
|
|
24
|
+
width,
|
|
25
|
+
isTimeFormat,
|
|
26
|
+
capitalizedLegend
|
|
26
27
|
}) => {
|
|
27
28
|
const allYLabels = yKeys.map(key => ({
|
|
28
29
|
label: key,
|
|
@@ -40,7 +41,8 @@ const BarChart = ({
|
|
|
40
41
|
setSelectedYLabels: setSelectedYLabels
|
|
41
42
|
})), /*#__PURE__*/React.createElement(CustomLegend, {
|
|
42
43
|
colorsArray: selectedYLabels.map(item => item.color),
|
|
43
|
-
yKeysArray: selectedYLabels.map(item => item.label)
|
|
44
|
+
yKeysArray: selectedYLabels.map(item => item.label),
|
|
45
|
+
capitalizedLegend: capitalizedLegend
|
|
44
46
|
}), /*#__PURE__*/React.createElement(ResponsiveContainer, {
|
|
45
47
|
width: width,
|
|
46
48
|
height: height
|
|
@@ -70,7 +72,7 @@ const BarChart = ({
|
|
|
70
72
|
tickLine: false
|
|
71
73
|
}), /*#__PURE__*/React.createElement(Tooltip, {
|
|
72
74
|
content: /*#__PURE__*/React.createElement(CustomTooltipContent, {
|
|
73
|
-
|
|
75
|
+
isTimeFormat: isTimeFormat
|
|
74
76
|
})
|
|
75
77
|
}), selectedYLabels.map(key => /*#__PURE__*/React.createElement(Bar, {
|
|
76
78
|
stackId: "a",
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import styleNames from '@pareto-engineering/bem/exports';
|
|
4
|
+
import { snakeCaseToTitleCase } from "../../../../utils";
|
|
4
5
|
import "./styles.scss";
|
|
5
6
|
const baseClassName = styleNames.base;
|
|
6
7
|
const componentClassName = 'custom-legend';
|
|
@@ -9,28 +10,28 @@ const CustomLegend = ({
|
|
|
9
10
|
className: userClassName,
|
|
10
11
|
colorsArray,
|
|
11
12
|
yKeysArray,
|
|
13
|
+
orientation,
|
|
14
|
+
getLegendItemTitle,
|
|
15
|
+
getLegendItemSubtitle,
|
|
12
16
|
capitalizedLegend
|
|
13
|
-
}) => {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
className: "text"
|
|
32
|
-
}, capitalizeWord(key)))));
|
|
33
|
-
};
|
|
17
|
+
}) => /*#__PURE__*/React.createElement("div", {
|
|
18
|
+
id: id,
|
|
19
|
+
className: [baseClassName, componentClassName, userClassName, orientation].filter(e => e).join(' ')
|
|
20
|
+
}, yKeysArray.map((key, index) => /*#__PURE__*/React.createElement("div", {
|
|
21
|
+
key: key,
|
|
22
|
+
className: "item"
|
|
23
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
24
|
+
className: "title"
|
|
25
|
+
}, /*#__PURE__*/React.createElement("span", {
|
|
26
|
+
className: "dot",
|
|
27
|
+
style: {
|
|
28
|
+
backgroundColor: colorsArray[index]
|
|
29
|
+
}
|
|
30
|
+
}), /*#__PURE__*/React.createElement("span", {
|
|
31
|
+
className: "text"
|
|
32
|
+
}, capitalizedLegend ? snakeCaseToTitleCase(getLegendItemTitle(key)) : getLegendItemTitle(key))), /*#__PURE__*/React.createElement("span", {
|
|
33
|
+
className: "sub-title"
|
|
34
|
+
}, getLegendItemSubtitle(key)))));
|
|
34
35
|
CustomLegend.propTypes = {
|
|
35
36
|
/**
|
|
36
37
|
* The id of the dropdown component.
|
|
@@ -48,12 +49,28 @@ CustomLegend.propTypes = {
|
|
|
48
49
|
* Array of keys for the y-axis data.
|
|
49
50
|
*/
|
|
50
51
|
yKeysArray: PropTypes.arrayOf(PropTypes.string).isRequired,
|
|
52
|
+
/**
|
|
53
|
+
* The orientation of the Legend
|
|
54
|
+
*/
|
|
55
|
+
orientation: PropTypes.oneOf(['vertical', 'horizontal']),
|
|
56
|
+
/**
|
|
57
|
+
* The function to get the legendItemKey
|
|
58
|
+
*/
|
|
59
|
+
getLegendItemTitle: PropTypes.func,
|
|
60
|
+
/**
|
|
61
|
+
* The function to get legend children
|
|
62
|
+
*/
|
|
63
|
+
getLegendItemSubtitle: PropTypes.func,
|
|
51
64
|
/**
|
|
52
65
|
* Flag on whether to capitalize legend keys
|
|
53
66
|
*/
|
|
54
67
|
capitalizedLegend: PropTypes.bool
|
|
55
68
|
};
|
|
56
69
|
CustomLegend.defaultProps = {
|
|
70
|
+
orientation: 'horizontal',
|
|
71
|
+
getLegendItemTitle: key => key,
|
|
72
|
+
/* eslint-disable no-unused-vars */
|
|
73
|
+
getLegendItemSubtitle: () => {},
|
|
57
74
|
capitalizedLegend: false
|
|
58
75
|
};
|
|
59
76
|
export default CustomLegend;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
@use "@pareto-engineering/bem";
|
|
2
2
|
|
|
3
3
|
$default-padding: 1rem;
|
|
4
|
+
$default-margin: 1rem;
|
|
4
5
|
$default-text-font-size: calc(var(--s-1) * 1rem);
|
|
5
6
|
$default-border-radius: .25rem;
|
|
6
7
|
$default-legend-gap: .625rem;
|
|
@@ -8,33 +9,59 @@ $default-legend-padding: calc($default-padding * .125) calc($default-padding * .
|
|
|
8
9
|
$default-legend-dot-width: .5rem;
|
|
9
10
|
$default-legend-dot-height: .5rem;
|
|
10
11
|
$default-legend-dot-margin-right: .3125rem;
|
|
12
|
+
$default-box-shadow: 0 4px 16px 0 var(--soft-shadow);
|
|
11
13
|
|
|
12
14
|
.#{bem.$base} {
|
|
13
15
|
&.custom-legend {
|
|
14
|
-
display: flex;
|
|
15
16
|
gap: $default-legend-gap;
|
|
16
17
|
justify-content: flex-end;
|
|
17
18
|
padding-bottom: $default-padding;
|
|
18
19
|
padding-right: calc($default-padding * .25);
|
|
19
20
|
|
|
21
|
+
&.vertical {
|
|
22
|
+
display: block;
|
|
23
|
+
margin-right: calc($default-margin * 2);
|
|
24
|
+
min-width: fit-content;
|
|
25
|
+
|
|
26
|
+
.item {
|
|
27
|
+
box-shadow: $default-box-shadow;
|
|
28
|
+
padding-top: $default-padding;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
&.horizontal {
|
|
33
|
+
display: flex;
|
|
34
|
+
}
|
|
35
|
+
|
|
20
36
|
.item {
|
|
21
|
-
align-items: center;
|
|
22
37
|
border-radius: $default-border-radius;
|
|
23
|
-
display: flex;
|
|
24
38
|
padding: $default-legend-padding;
|
|
25
|
-
}
|
|
26
39
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
40
|
+
.title {
|
|
41
|
+
align-items: center;
|
|
42
|
+
display: flex;
|
|
43
|
+
|
|
44
|
+
.dot {
|
|
45
|
+
border-radius: 50%;
|
|
46
|
+
display: inline-block;
|
|
47
|
+
height: $default-legend-dot-height;
|
|
48
|
+
margin-right: $default-legend-dot-margin-right;
|
|
49
|
+
width: $default-legend-dot-width;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.text {
|
|
53
|
+
color: var(--paragraph);
|
|
54
|
+
font-size: calc($default-text-font-size * .75);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
34
57
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
58
|
+
.sub-title {
|
|
59
|
+
color: var(--heading);
|
|
60
|
+
display: flex;
|
|
61
|
+
font-size: calc($default-text-font-size * 1.2);
|
|
62
|
+
font-weight: 500;
|
|
63
|
+
justify-content: flex-end;
|
|
64
|
+
}
|
|
38
65
|
}
|
|
39
66
|
}
|
|
40
67
|
}
|
|
@@ -1,20 +1,30 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import styleNames from '@pareto-engineering/bem/exports';
|
|
4
|
-
import { formatTime, formatDate, DATE_FORMATS } from "../../../../utils";
|
|
4
|
+
import { formatTime, formatDate, DATE_FORMATS, snakeCaseToTitleCase } from "../../../../utils";
|
|
5
5
|
import "./styles.scss";
|
|
6
6
|
const baseClassName = styleNames.base;
|
|
7
7
|
const componentClassName = 'custom-tooltip-content';
|
|
8
8
|
const CustomTooltipContent = ({
|
|
9
9
|
id,
|
|
10
10
|
className: userClassName,
|
|
11
|
-
xLabel,
|
|
12
11
|
dateFormat,
|
|
13
12
|
isTimeFormat,
|
|
13
|
+
isDateValue,
|
|
14
14
|
active,
|
|
15
15
|
payload,
|
|
16
16
|
label
|
|
17
17
|
}) => {
|
|
18
|
+
const formatLabelValue = value => {
|
|
19
|
+
if (isTimeFormat) {
|
|
20
|
+
return formatTime(value);
|
|
21
|
+
}
|
|
22
|
+
if (typeof value === 'number') {
|
|
23
|
+
if (Number.isInteger(value)) return value;
|
|
24
|
+
return value.toFixed(2);
|
|
25
|
+
}
|
|
26
|
+
return value;
|
|
27
|
+
};
|
|
18
28
|
if (active && payload && payload.length) {
|
|
19
29
|
const newPayload = payload.filter(item => item.name !== 'bounds');
|
|
20
30
|
return /*#__PURE__*/React.createElement("div", {
|
|
@@ -22,14 +32,14 @@ const CustomTooltipContent = ({
|
|
|
22
32
|
className: [baseClassName, componentClassName, userClassName].filter(e => e).join(' ')
|
|
23
33
|
}, /*#__PURE__*/React.createElement("p", {
|
|
24
34
|
className: "label"
|
|
25
|
-
},
|
|
35
|
+
}, isDateValue ? formatDate(label, dateFormat) : label), newPayload.map(entry => /*#__PURE__*/React.createElement("p", {
|
|
26
36
|
className: "label",
|
|
27
37
|
key: `${entry.name}`,
|
|
28
38
|
style: {
|
|
29
39
|
color: entry.color,
|
|
30
40
|
textTransform: 'capitalize'
|
|
31
41
|
}
|
|
32
|
-
}, `${entry.name}: ${
|
|
42
|
+
}, `${snakeCaseToTitleCase(entry.name)}: ${formatLabelValue(entry.value)}`)));
|
|
33
43
|
}
|
|
34
44
|
return null;
|
|
35
45
|
};
|
|
@@ -42,10 +52,6 @@ CustomTooltipContent.propTypes = {
|
|
|
42
52
|
* Additional class names for the dropdown component.
|
|
43
53
|
*/
|
|
44
54
|
className: PropTypes.string,
|
|
45
|
-
/**
|
|
46
|
-
* The label for the x-axis.
|
|
47
|
-
*/
|
|
48
|
-
xLabel: PropTypes.string,
|
|
49
55
|
/**
|
|
50
56
|
* Flag on whether it is a timeformat or not
|
|
51
57
|
*/
|
|
@@ -54,6 +60,10 @@ CustomTooltipContent.propTypes = {
|
|
|
54
60
|
* The type of format for the datetime value
|
|
55
61
|
*/
|
|
56
62
|
dateFormat: PropTypes.oneOf(Object.values(DATE_FORMATS)),
|
|
63
|
+
/**
|
|
64
|
+
* Flag on whether the label is a date value or not
|
|
65
|
+
*/
|
|
66
|
+
isDateValue: PropTypes.bool,
|
|
57
67
|
/**
|
|
58
68
|
* If set true, the tooltip is displayed.
|
|
59
69
|
* If set false, the tooltip is hidden, usually calculated internally.
|
|
@@ -71,6 +81,7 @@ CustomTooltipContent.propTypes = {
|
|
|
71
81
|
};
|
|
72
82
|
CustomTooltipContent.defaultProps = {
|
|
73
83
|
isTimeFormat: false,
|
|
84
|
+
isDateValue: true,
|
|
74
85
|
dateFormat: DATE_FORMATS.HUMAN_READABLE
|
|
75
86
|
};
|
|
76
87
|
export default CustomTooltipContent;
|
|
@@ -2,10 +2,8 @@
|
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import PropTypes from 'prop-types';
|
|
4
4
|
import styleNames from '@pareto-engineering/bem/exports';
|
|
5
|
+
import { snakeCaseToTitleCase } from "../../../../utils";
|
|
5
6
|
import "./styles.scss";
|
|
6
|
-
|
|
7
|
-
// Local Definitions
|
|
8
|
-
|
|
9
7
|
const baseClassName = styleNames.base;
|
|
10
8
|
const componentClassName = 'y-labels-dropdown';
|
|
11
9
|
const YLabelsDropDown = ({
|
|
@@ -46,7 +44,7 @@ const YLabelsDropDown = ({
|
|
|
46
44
|
style: {
|
|
47
45
|
backgroundColor: item.color
|
|
48
46
|
}
|
|
49
|
-
}), item.label, selectedYLabels.some(label => label.label === item.label) && /*#__PURE__*/React.createElement("span", {
|
|
47
|
+
}), snakeCaseToTitleCase(item.label), selectedYLabels.some(label => label.label === item.label) && /*#__PURE__*/React.createElement("span", {
|
|
50
48
|
className: "icon checkmark"
|
|
51
49
|
}, "I")))));
|
|
52
50
|
};
|
|
@@ -83,6 +81,6 @@ YLabelsDropDown.propTypes = {
|
|
|
83
81
|
}))
|
|
84
82
|
};
|
|
85
83
|
YLabelsDropDown.defaultProps = {
|
|
86
|
-
placeholder: '
|
|
84
|
+
placeholder: 'Select Item'
|
|
87
85
|
};
|
|
88
86
|
export default YLabelsDropDown;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
@use "@pareto-engineering/bem";
|
|
2
2
|
|
|
3
3
|
$default-margin: 1rem;
|
|
4
|
-
$default-border
|
|
4
|
+
$default-border: var(--theme-default-input-border);
|
|
5
|
+
$default-border-radius: var(--theme-default-input-border-radius);
|
|
5
6
|
$default-padding: 1rem;
|
|
6
7
|
$default-width: 15rem;
|
|
7
8
|
$default-box-shadow: 0 .25rem .75rem var(--ui-lines);
|
|
@@ -16,9 +17,9 @@ $default-checkmark-font-size: calc(var(--s-1) * .75rem);
|
|
|
16
17
|
|
|
17
18
|
.dropdown-button {
|
|
18
19
|
align-items: center;
|
|
19
|
-
background-color: var(--
|
|
20
|
-
border:
|
|
21
|
-
border-radius: $default-border-radius;
|
|
20
|
+
background-color: var(--background-far);
|
|
21
|
+
border: $default-border;
|
|
22
|
+
border-radius: calc($default-border-radius / 2);
|
|
22
23
|
color: var(--hard-paragraph);
|
|
23
24
|
cursor: pointer;
|
|
24
25
|
display: flex;
|
|
@@ -53,8 +54,8 @@ $default-checkmark-font-size: calc(var(--s-1) * .75rem);
|
|
|
53
54
|
|
|
54
55
|
.dropdown-item {
|
|
55
56
|
align-items: center;
|
|
56
|
-
border-radius: $default-border-radius;
|
|
57
|
-
color: var(--
|
|
57
|
+
border-radius: calc($default-border-radius / 2);
|
|
58
|
+
color: var(--paragraph);
|
|
58
59
|
cursor: pointer;
|
|
59
60
|
display: flex;
|
|
60
61
|
margin: calc($default-margin * .125);
|