@pareto-engineering/design-system 4.9.2 → 4.10.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 (31) hide show
  1. package/dist/cjs/a/AreaChart/AreaChart.js +176 -0
  2. package/dist/cjs/a/AreaChart/index.js +13 -0
  3. package/dist/cjs/a/AreaChart/styles.scss +89 -0
  4. package/dist/cjs/a/XMLEditor/XMLEditor.js +1 -1
  5. package/dist/cjs/a/index.js +8 -1
  6. package/dist/cjs/b/Button/styles.scss +1 -0
  7. package/dist/cjs/g/FormBuilder/FormBuilder.js +3 -3
  8. package/dist/cjs/g/FormBuilder/common/Renderer/Renderer.js +38 -38
  9. package/dist/cjs/g/FormBuilder/common/Renderer/common/Section/Section.js +34 -8
  10. package/dist/es/a/AreaChart/AreaChart.js +163 -0
  11. package/dist/es/a/AreaChart/index.js +1 -0
  12. package/dist/es/a/AreaChart/styles.scss +89 -0
  13. package/dist/es/a/XMLEditor/XMLEditor.js +2 -2
  14. package/dist/es/a/index.js +2 -1
  15. package/dist/es/b/Button/styles.scss +1 -0
  16. package/dist/es/g/FormBuilder/FormBuilder.js +3 -3
  17. package/dist/es/g/FormBuilder/common/Renderer/Renderer.js +39 -39
  18. package/dist/es/g/FormBuilder/common/Renderer/common/Section/Section.js +35 -9
  19. package/package.json +4 -3
  20. package/src/stories/a/AreaChart.stories.jsx +118 -0
  21. package/src/ui/a/AreaChart/AreaChart.jsx +185 -0
  22. package/src/ui/a/AreaChart/index.js +1 -0
  23. package/src/ui/a/AreaChart/styles.scss +89 -0
  24. package/src/ui/a/XMLEditor/XMLEditor.jsx +4 -1
  25. package/src/ui/a/index.js +1 -0
  26. package/src/ui/b/Button/styles.scss +1 -0
  27. package/src/ui/g/FormBuilder/FormBuilder.jsx +2 -2
  28. package/src/ui/g/FormBuilder/common/Renderer/Renderer.jsx +40 -39
  29. package/src/ui/g/FormBuilder/common/Renderer/common/Section/Section.jsx +41 -10
  30. package/tests/__snapshots__/Storyshots.test.js.snap +501 -1
  31. package/tests/test-setup.js +11 -0
@@ -0,0 +1,163 @@
1
+ // front/packages/design-system/src/ui/a/AreaChart/AreaChart.jsx
2
+
3
+ import * as React from 'react';
4
+ import PropTypes from 'prop-types';
5
+ import { AreaChart as RechartsAreaChart, Area, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts';
6
+ import styleNames from '@pareto-engineering/bem/exports';
7
+ import "./styles.scss";
8
+
9
+ // Local Definitions
10
+
11
+ const baseClassName = styleNames.base;
12
+ const componentClassName = 'area-chart';
13
+ const AreaChart = ({
14
+ id,
15
+ className: userClassName,
16
+ data,
17
+ title,
18
+ xKey,
19
+ yKeys,
20
+ xLabel,
21
+ yLabel,
22
+ colors,
23
+ filled,
24
+ height,
25
+ width
26
+ // ...otherProps
27
+ }) => {
28
+ const processedData = data.map(item => {
29
+ const yValues = yKeys.map(key => item[key]);
30
+ const lowerBound = Math.min(...yValues);
31
+ const upperBound = Math.max(...yValues);
32
+ const margin = (upperBound - lowerBound) * 0.1;
33
+ return {
34
+ ...item,
35
+ bounds: [lowerBound - margin, upperBound + margin]
36
+ };
37
+ });
38
+ const yAxisBounds = () => {
39
+ const yValues = data.map(item => yKeys.map(key => item[key]));
40
+ const min = Math.min(...yValues.flat());
41
+ const max = Math.max(...yValues.flat());
42
+ const margin = (max - min) * 0.1;
43
+ return [min - margin, max + margin];
44
+ };
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
+ return /*#__PURE__*/React.createElement("div", {
83
+ id: id,
84
+ className: [baseClassName, componentClassName, userClassName].filter(e => e).join(' ')
85
+ }, /*#__PURE__*/React.createElement("h3", null, title), /*#__PURE__*/React.createElement(CustomLegend, {
86
+ colorsArray: colors,
87
+ yKeysArray: yKeys
88
+ }), /*#__PURE__*/React.createElement(ResponsiveContainer, {
89
+ width: width,
90
+ height: height
91
+ }, /*#__PURE__*/React.createElement(RechartsAreaChart, {
92
+ data: processedData
93
+ }, /*#__PURE__*/React.createElement(CartesianGrid, {
94
+ strokeDasharray: "3 3"
95
+ }), /*#__PURE__*/React.createElement(XAxis, {
96
+ dataKey: xKey,
97
+ label: {
98
+ value: xLabel,
99
+ position: 'insideBottom',
100
+ offset: -5
101
+ } // Adjusted offset for padding
102
+ ,
103
+ axisLine: false,
104
+ tickLine: false,
105
+ tickCount: 3
106
+ }), /*#__PURE__*/React.createElement(YAxis, {
107
+ domain: yAxisBounds,
108
+ label: {
109
+ value: yLabel,
110
+ angle: -90,
111
+ position: 'insideLeft',
112
+ offset: 15
113
+ },
114
+ axisLine: false,
115
+ tickLine: false,
116
+ tickFormatter: value => value.toFixed(2)
117
+ }), /*#__PURE__*/React.createElement(Tooltip, {
118
+ content: /*#__PURE__*/React.createElement(CustomTooltipContent, null)
119
+ }), filled && /*#__PURE__*/React.createElement(Area, {
120
+ id: "bounds",
121
+ type: "linear",
122
+ dataKey: "bounds",
123
+ stroke: "none",
124
+ fill: "var(--hard-ui-main-2)",
125
+ fillOpacity: 0.4,
126
+ activeDot: false,
127
+ dot: false,
128
+ label: false,
129
+ isAnimationActive: false
130
+ }), yKeys.map((key, index) => /*#__PURE__*/React.createElement(Area, {
131
+ id: key,
132
+ key: key,
133
+ type: "linear",
134
+ dataKey: key,
135
+ stroke: colors[index],
136
+ fill: "none",
137
+ connectNulls: true,
138
+ dot: false,
139
+ activeDot: {
140
+ r: 4
141
+ },
142
+ isAnimationActive: false
143
+ })))));
144
+ };
145
+ AreaChart.propTypes = {
146
+ // eslint-disable-next-line react/forbid-prop-types
147
+ data: PropTypes.arrayOf(PropTypes.object).isRequired,
148
+ title: PropTypes.string.isRequired,
149
+ xKey: PropTypes.string.isRequired,
150
+ yKeys: PropTypes.arrayOf(PropTypes.string).isRequired,
151
+ xLabel: PropTypes.string,
152
+ yLabel: PropTypes.string,
153
+ colors: PropTypes.arrayOf(PropTypes.string).isRequired,
154
+ filled: PropTypes.bool,
155
+ height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
156
+ width: PropTypes.oneOfType([PropTypes.string, PropTypes.number])
157
+ };
158
+ AreaChart.defaultProps = {
159
+ filled: false,
160
+ width: '100%',
161
+ height: 300
162
+ };
163
+ export default AreaChart;
@@ -0,0 +1 @@
1
+ export { default as AreaChart } from "./AreaChart";
@@ -0,0 +1,89 @@
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
+ $default-border-radius: .25rem;
8
+ $default-legend-gap: .625rem;
9
+ $default-legend-padding: calc($default-padding * .125) calc($default-padding * .625);
10
+ $default-legend-line-width: 1.25rem;
11
+ $default-legend-line-height: .125rem;
12
+ $default-legend-line-margin-right: .3125rem;
13
+ $default-border-line-width: .0625rem;
14
+
15
+ .#{bem.$base} {
16
+ &.area-chart {
17
+ background-color: var(--background-far);
18
+ border-radius: var(--theme-default-border-radius);
19
+ box-shadow: $default-box-shadow;
20
+ margin: $default-margin 0;
21
+ padding: $default-padding;
22
+
23
+ h3 {
24
+ color: var(--subtitle);
25
+ margin: calc($default-margin / 5);
26
+ text-align: left;
27
+ }
28
+
29
+ .custom-legend {
30
+ display: flex;
31
+ gap: $default-legend-gap;
32
+ justify-content: flex-end;
33
+ padding-bottom: $default-padding;
34
+ padding-right: calc($default-padding * .25);
35
+
36
+ .item {
37
+ align-items: center;
38
+ border: $default-border-line-width solid var(--ui-lines);
39
+ border-radius: $default-border-radius;
40
+ display: flex;
41
+ padding: $default-legend-padding;
42
+ }
43
+
44
+ .line {
45
+ display: inline-block;
46
+ height: $default-legend-line-height;
47
+ margin-right: $default-legend-line-margin-right;
48
+ width: $default-legend-line-width;
49
+ }
50
+
51
+ .text {
52
+ color: var(--paragraph);
53
+ font-size: calc($default-text-font-size * .75);
54
+ }
55
+ }
56
+
57
+ .custom-tooltip {
58
+ background-color: var(--background-far);
59
+ border: $default-border-line-width solid var(--ui-lines);
60
+ border-radius: $default-border-radius;
61
+ padding: calc($default-padding * .25);
62
+
63
+ .label {
64
+ color: var(--hard-paragraph);
65
+ font-size: $default-text-font-size;
66
+ margin: calc($default-margin * .25);
67
+ }
68
+ }
69
+
70
+ /* stylelint-disable selector-max-compound-selectors -- nested elements */
71
+ .recharts-wrapper {
72
+ .recharts-surface {
73
+ .recharts-cartesian-grid line {
74
+ stroke: var(--ui-lines);
75
+ }
76
+
77
+ .recharts-text {
78
+ fill: var(--soft-paragraph);
79
+ font-size: calc($default-text-font-size * .75);
80
+ }
81
+
82
+ .recharts-text.recharts-label {
83
+ fill: var(--paragraph);
84
+ font-size: $default-text-font-size;
85
+ }
86
+ }
87
+ }
88
+ }
89
+ }
@@ -4,7 +4,7 @@ import { useEffect, useRef } from 'react';
4
4
  import PropTypes from 'prop-types';
5
5
  import { EditorState } from '@codemirror/state';
6
6
  import { EditorView, keymap, lineNumbers, drawSelection, dropCursor, highlightActiveLine, highlightActiveLineGutter, highlightSpecialChars, crosshairCursor, rectangularSelection } from '@codemirror/view';
7
- import { defaultKeymap, indentWithTab } from '@codemirror/commands';
7
+ import { defaultKeymap, indentWithTab, history, historyKeymap } from '@codemirror/commands';
8
8
  import { indentOnInput, bracketMatching, foldGutter } from '@codemirror/language';
9
9
  import { xml } from '@codemirror/lang-xml';
10
10
  import styleNames from '@pareto-engineering/bem/exports';
@@ -33,7 +33,7 @@ const XMLEditor = ({
33
33
  useEffect(() => {
34
34
  const startState = EditorState.create({
35
35
  doc: config,
36
- extensions: [keymap.of([defaultKeymap, indentWithTab]), indentOnInput(), lineNumbers(), bracketMatching(), foldGutter(), drawSelection(), highlightActiveLine(), highlightActiveLineGutter(), highlightSpecialChars(), dropCursor(), rectangularSelection(), crosshairCursor(), xml(), theme, EditorState.readOnly.of(readOnly), EditorView.updateListener.of(view => {
36
+ extensions: [keymap.of([defaultKeymap, indentWithTab, ...historyKeymap]), indentOnInput(), lineNumbers(), bracketMatching(), foldGutter(), drawSelection(), highlightActiveLine(), highlightActiveLineGutter(), highlightSpecialChars(), dropCursor(), rectangularSelection(), crosshairCursor(), xml(), history(), theme, EditorState.readOnly.of(readOnly), EditorView.updateListener.of(view => {
37
37
  onChange(view);
38
38
  // view.state.doc.toString() to receive the current content in the editor.
39
39
  }), EditorView.focusChangeEffect.of((state, focused) => {
@@ -27,4 +27,5 @@ export { Removable } from "./Removable";
27
27
  export { ToggleSwitch } from "./ToggleSwitch";
28
28
  export { XMLEditor } from "./XMLEditor";
29
29
  export { DatePicker } from "./DatePicker";
30
- export { Tooltip } from "./Tooltip";
30
+ export { Tooltip } from "./Tooltip";
31
+ export { AreaChart } from "./AreaChart";
@@ -124,6 +124,7 @@ $default-animation-time: .31s;
124
124
  }
125
125
 
126
126
  &.#{bem.$modifier-simple} {
127
+ --stroke-color: var(--x, var(--#{$default-color}));
127
128
  background: transparent;
128
129
  border: 1px solid transparent;
129
130
  color: var(--x, var(--#{$default-color}));
@@ -24,8 +24,8 @@ const FormBuilder = ({
24
24
  formBuilderId,
25
25
  onBuilderFormSave,
26
26
  onBuilderError,
27
- onRendererError,
28
27
  onRendererFormSave,
28
+ onFileUpload,
29
29
  onBuilderValidate,
30
30
  initialBuilderValues,
31
31
  fileUploadStatus,
@@ -52,9 +52,9 @@ const FormBuilder = ({
52
52
  onSave: onRendererFormSave,
53
53
  readOnly: readOnly,
54
54
  shouldSubmit: shouldSubmit,
55
- onError: onRendererError,
56
55
  fileUploadStatus: fileUploadStatus,
57
- handleFileDelete: handleFileDelete
56
+ handleFileDelete: handleFileDelete,
57
+ onFileUpload: onFileUpload
58
58
  }));
59
59
  };
60
60
  FormBuilder.propTypes = {
@@ -1,7 +1,7 @@
1
1
  function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
2
2
  /* @pareto-engineering/generator-front 1.1.1-alpha.2 */
3
3
  import * as React from 'react';
4
- import { useState, useEffect } from 'react';
4
+ import { useState, useEffect, useRef } from 'react';
5
5
  import { Formik, Form } from 'formik';
6
6
  import PropTypes from 'prop-types';
7
7
  import styleNames from '@pareto-engineering/bem/exports';
@@ -13,28 +13,6 @@ import "./styles.scss";
13
13
  import { Section } from "./common";
14
14
  const baseClassName = styleNames.base;
15
15
  const componentClassName = 'renderer';
16
- const reconstructFormDataWithValues = (formData, values) => {
17
- const valuesMap = {};
18
- Object.keys(values).forEach(async key => {
19
- if (key.includes('files')) {
20
- const files = values[key].map(file => file instanceof File ? URL.createObjectURL(file) : file);
21
- valuesMap[key] = files;
22
- } else {
23
- valuesMap[key] = values[key];
24
- }
25
- });
26
- const newData = {
27
- ...formData,
28
- sections: formData.sections.map(section => ({
29
- ...section,
30
- inputs: section.inputs.map(input => ({
31
- ...input,
32
- value: valuesMap[input.name] !== undefined ? valuesMap[input.name] : input.value
33
- }))
34
- }))
35
- };
36
- return newData;
37
- };
38
16
  const validate = (currentSectionIndex, formData, values) => {
39
17
  const errors = {};
40
18
  const hasAtLeastOneValue = Object.keys(values).some(valueKey => {
@@ -53,6 +31,25 @@ const validate = (currentSectionIndex, formData, values) => {
53
31
  });
54
32
  return errors;
55
33
  };
34
+ const reconstructFormDataWithValues = (formData, values) => {
35
+ const valuesMap = {};
36
+ Object.keys(values).forEach(async key => {
37
+ if (!key.includes('files')) {
38
+ valuesMap[key] = values[key];
39
+ }
40
+ });
41
+ const newData = {
42
+ ...formData,
43
+ sections: formData.sections.map(section => ({
44
+ ...section,
45
+ inputs: section.inputs.map(input => ({
46
+ ...input,
47
+ value: valuesMap[input.name] !== undefined ? valuesMap[input.name] : input.value
48
+ }))
49
+ }))
50
+ };
51
+ return newData;
52
+ };
56
53
 
57
54
  /**
58
55
  * This is the component description.
@@ -64,15 +61,18 @@ const Renderer = ({
64
61
  formData,
65
62
  readOnly,
66
63
  onSave,
67
- onError,
68
64
  shouldSubmit,
69
65
  fileUploadStatus,
70
- handleFileDelete
66
+ handleFileDelete,
67
+ onFileUpload,
68
+ shouldUpdateInputStateInRealTime = true
71
69
  // ...otherProps
72
70
  }) => {
73
71
  const [currentSectionIndex, setCurrentSectionIndex] = useState(0);
74
72
  const [sectionHistory, setSectionHistory] = useState([]);
75
- const [updatedFormData, setUpdatedFormData] = useState(formData);
73
+ const [updatedFormData, setUpdatedFormData] = useState({
74
+ ...formData
75
+ });
76
76
  useEffect(() => {
77
77
  setUpdatedFormData(formData);
78
78
  }, [formData]);
@@ -112,6 +112,9 @@ const Renderer = ({
112
112
  }
113
113
  };
114
114
  const isSubmit = currentSectionIndex === updatedFormData.sections.length - 1 || updatedFormData.sections[currentSectionIndex].navigation.nextSection === 'submit';
115
+ const ref = useRef(null);
116
+ const currentSectionInputs = updatedFormData.sections[currentSectionIndex].inputs;
117
+ const hasErrorsOnInitialRender = currentSectionInputs.some(input => input.required && !ref.current?.values[input.name] || ref.current?.errors[input.name]);
115
118
  return /*#__PURE__*/React.createElement("div", {
116
119
  id: id,
117
120
  className: [baseClassName, componentClassName, userClassName].filter(e => e).join(' '),
@@ -119,30 +122,27 @@ const Renderer = ({
119
122
  }, /*#__PURE__*/React.createElement(Formik, {
120
123
  initialValues: initialValues,
121
124
  onSubmit: handleSubmit,
122
- validate: values => validate(currentSectionIndex, formData, values)
125
+ validate: values => validate(currentSectionIndex, updatedFormData, values),
126
+ innerRef: ref
123
127
  }, ({
124
128
  values,
125
129
  errors
126
130
  }) => {
127
131
  useEffect(() => {
128
- const formDataWithValues = reconstructFormDataWithValues(updatedFormData, values);
129
- setUpdatedFormData(formDataWithValues);
130
- onSave?.(formDataWithValues);
132
+ if (shouldUpdateInputStateInRealTime) {
133
+ const formDataWithValues = reconstructFormDataWithValues(updatedFormData, values);
134
+ onSave?.(formDataWithValues);
135
+ }
131
136
  }, [values]);
132
- useEffect(() => {
133
- onError?.({
134
- errors,
135
- values
136
- });
137
- }, [errors, values]);
138
137
  const hasErrors = Object.keys(errors).length > 0;
139
138
  return /*#__PURE__*/React.createElement(Form, null, updatedFormData.sections.map((section, sectionIndex) => sectionIndex === currentSectionIndex && /*#__PURE__*/React.createElement(Section, _extends({
140
139
  key: `${section.title}`
141
140
  }, section, {
142
141
  readOnly: readOnly,
143
- setUpdatedFormData: setUpdatedFormData,
144
142
  fileUploadStatus: fileUploadStatus,
145
- handleFileDelete: handleFileDelete
143
+ handleFileDelete: handleFileDelete,
144
+ onFileUpload: onFileUpload,
145
+ sectionIndex: sectionIndex
146
146
  }))), /*#__PURE__*/React.createElement("div", {
147
147
  className: "navigator-container"
148
148
  }, updatedFormData.sections.length > 1 && /*#__PURE__*/React.createElement(Button, {
@@ -157,7 +157,7 @@ const Renderer = ({
157
157
  color: "interactive",
158
158
  isGradient: true,
159
159
  type: "submit",
160
- disabled: hasErrors
160
+ disabled: hasErrors || hasErrorsOnInitialRender
161
161
  }, isSubmit ? 'Submit' : 'Next')));
162
162
  }));
163
163
  };
@@ -6,11 +6,19 @@ import PropTypes from 'prop-types';
6
6
 
7
7
  // Local Definitions
8
8
 
9
- import { FormInput } from "../../../../../../f";
9
+ import { FormInput, getFileType } from "../../../../../../f";
10
10
  import { ExpandableLexicalPreview } from "../../../../..";
11
11
  import styleNames from '@pareto-engineering/bem/exports';
12
12
  const baseClassName = styleNames.base;
13
13
  const componentClassName = 'section';
14
+ const fileTypeMapper = {
15
+ VID: 'Video',
16
+ TXT: 'Text',
17
+ IMG: 'Image',
18
+ PDF: 'PDF',
19
+ AUD: 'Audio',
20
+ FILE: 'Generic'
21
+ };
14
22
 
15
23
  /**
16
24
  * This is the component description.
@@ -24,7 +32,9 @@ const Section = ({
24
32
  inputs,
25
33
  readOnly,
26
34
  fileUploadStatus,
27
- handleFileDelete
35
+ handleFileDelete,
36
+ onFileUpload,
37
+ sectionIndex
28
38
  // ...otherProps
29
39
  }) => /*#__PURE__*/React.createElement("div", {
30
40
  id: id,
@@ -35,13 +45,29 @@ const Section = ({
35
45
  }, title), /*#__PURE__*/React.createElement(ExpandableLexicalPreview, {
36
46
  nodes: description,
37
47
  name: "instructions"
38
- }), inputs?.map(input => /*#__PURE__*/React.createElement(FormInput, _extends({
39
- key: input.name
40
- }, input, {
41
- disabled: readOnly,
42
- uploadStatus: fileUploadStatus,
43
- handleFileDelete: handleFileDelete
44
- }))));
48
+ }), inputs?.map((input, inputIndex) => {
49
+ const isFileInput = input.type === 'file';
50
+ return /*#__PURE__*/React.createElement(FormInput, _extends({
51
+ key: input.name
52
+ }, input, {
53
+ disabled: readOnly
54
+ }, isFileInput && {
55
+ uploadStatus: fileUploadStatus,
56
+ handleFileDelete,
57
+ onChange: files => {
58
+ const filesToUpload = files?.filter(file => file instanceof File).map(file => ({
59
+ file,
60
+ name: file.name,
61
+ mimeType: file.type,
62
+ type: fileTypeMapper[getFileType(file)] || 'Generic',
63
+ title: file.name,
64
+ sectionIndex,
65
+ inputIndex
66
+ }));
67
+ onFileUpload(filesToUpload);
68
+ }
69
+ }));
70
+ }));
45
71
  Section.propTypes = {
46
72
  /**
47
73
  * The HTML id for this element
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pareto-engineering/design-system",
3
- "version": "4.9.2",
3
+ "version": "4.10.0",
4
4
  "description": "",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/es/index.js",
@@ -59,7 +59,7 @@
59
59
  "@lexical/selection": "0.12.2",
60
60
  "@lexical/table": "0.12.2",
61
61
  "@lexical/utils": "0.12.2",
62
- "@pareto-engineering/assets": "^4.9.0",
62
+ "@pareto-engineering/assets": "^4.9.3",
63
63
  "@pareto-engineering/bem": "^4.8.1",
64
64
  "@pareto-engineering/styles": "^4.2.0",
65
65
  "@pareto-engineering/utils": "^4.0.0",
@@ -79,8 +79,9 @@
79
79
  "react-helmet-async": "^1.3.0",
80
80
  "react-relay": "^15.0.0",
81
81
  "react-router-dom": "^5.3.4",
82
+ "recharts": "^2.13.3",
82
83
  "relay-test-utils": "^15.0.0"
83
84
  },
84
85
  "browserslist": "> 2%",
85
- "gitHead": "d7034652bbfb7fa7362d9cedaa04ae23fc8323ad"
86
+ "gitHead": "a7230fcb13b180d33c831ed413f8fc039e95fc89"
86
87
  }
@@ -0,0 +1,118 @@
1
+ // front/packages/design-system/src/ui/a/AreaChart/AreaChart.stories.jsx
2
+
3
+ import React from 'react'
4
+ import { AreaChart } from 'ui'
5
+
6
+ export default {
7
+ title :'a/AreaChart',
8
+ component:AreaChart,
9
+ }
10
+
11
+ const data = [
12
+ {
13
+ date:'2023-01-01', Average:0.49, Best:0.50, Worst:0.48,
14
+ },
15
+ {
16
+ date:'2023-01-02', Average:0.48, Best:0.49, Worst:0.47,
17
+ },
18
+ {
19
+ date:'2023-01-03', Average:0.47, Best:0.48, Worst:0.46,
20
+ },
21
+ {
22
+ date:'2023-01-04', Average:0.50, Best:0.51, Worst:0.49,
23
+ },
24
+ {
25
+ date:'2023-01-05', Average:0.52, Best:0.53, Worst:0.51,
26
+ },
27
+ {
28
+ date:'2023-01-06', Average:0.51, Best:0.52, Worst:0.50,
29
+ },
30
+ {
31
+ date:'2023-01-07', Average:0.49, Best:0.50, Worst:0.48,
32
+ },
33
+ ]
34
+
35
+ const data2 = [
36
+ {
37
+ date:'2023-01-01', Average:0.60, Best:0.62, Worst:0.58,
38
+ },
39
+ {
40
+ date:'2023-01-02', Average:0.59, Best:0.61, Worst:0.57,
41
+ },
42
+ {
43
+ date:'2023-01-03', Average:0.58, Best:0.60, Worst:0.56,
44
+ },
45
+ {
46
+ date:'2023-01-04', Average:0.61, Best:0.63, Worst:0.59,
47
+ },
48
+ {
49
+ date:'2023-01-05', Average:0.63, Best:0.65, Worst:0.61,
50
+ },
51
+ {
52
+ date:'2023-01-06', Average:0.62, Best:0.64, Worst:0.60,
53
+ },
54
+ {
55
+ date:'2023-01-07', Average:0.60, Best:0.62, Worst:0.58,
56
+ },
57
+ ]
58
+
59
+ const Template = (args) => (
60
+ <div style={{ height: '100%', width: '100%' }}>
61
+ <AreaChart {...args} />
62
+ </div>
63
+ )
64
+
65
+ export const Default = Template.bind({})
66
+ Default.args = {
67
+ data,
68
+ title :'Approval rate over time',
69
+ xKey :'date',
70
+ yKeys :['Average', 'Best', 'Worst'],
71
+ xLabel:'Date',
72
+ yLabel:'Approval rate',
73
+ colors:['purple', 'green', 'orange'],
74
+ height:400,
75
+ }
76
+
77
+ export const Filled = Template.bind({})
78
+ Filled.args = {
79
+ ...Default.args,
80
+ filled:true,
81
+ }
82
+
83
+ const TemplateSideBySide = (args) => (
84
+ <div style={{ display: 'flex', gap: '20px' }}>
85
+ <div style={{ flex: 1 }}>
86
+ {/* eslint-disable-next-line react/destructuring-assignment */}
87
+ <AreaChart {...args[0]} />
88
+ </div>
89
+ <div style={{ flex: 1 }}>
90
+ {/* eslint-disable-next-line react/destructuring-assignment */}
91
+ <AreaChart {...args[1]} />
92
+ </div>
93
+ </div>
94
+ )
95
+
96
+ export const SideBySide = TemplateSideBySide.bind({})
97
+ SideBySide.args = [
98
+ {
99
+ ...Default.args,
100
+ },
101
+ {
102
+ ...Default.args,
103
+ title:'Submission rate over time',
104
+ data :data2,
105
+ },
106
+ ]
107
+
108
+ export const SideBySideFilled = TemplateSideBySide.bind({})
109
+ SideBySideFilled.args = [
110
+ {
111
+ ...Filled.args,
112
+ },
113
+ {
114
+ ...Filled.args,
115
+ data :data2,
116
+ title:'Submission rate over time',
117
+ },
118
+ ]