sag_components 1.0.28 → 1.0.30
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/package.json +1 -1
- package/.babelrc.json +0 -15
- package/.storybook/YourTheme.js +0 -11
- package/.storybook/main.js +0 -30
- package/.storybook/manager.js +0 -8
- package/.storybook/preview.js +0 -14
- package/.storybook/webpack.config.js +0 -16
- package/azure-pipelines.yml +0 -50
- package/azure-static-web-apps-delightful-cliff-010f39003.yml +0 -32
- package/babel.config.js +0 -10
- package/public/favicon.ico +0 -0
- package/public/index.html +0 -52
- package/public/manifest.json +0 -25
- package/public/robots.txt +0 -3
- package/src/App.css +0 -6
- package/src/App.js +0 -149
- package/src/App.test.js +0 -8
- package/src/index.css +0 -13
- package/src/index.js +0 -22
- package/src/logo.svg +0 -1
- package/src/stories/Benchmark.stories.jsx +0 -111
- package/src/stories/Benchmark.style.js +0 -82
- package/src/stories/Button.stories.js +0 -114
- package/src/stories/Button.style.js +0 -9
- package/src/stories/Dropdown.stories.jsx +0 -238
- package/src/stories/Dropdown.style.js +0 -9
- package/src/stories/Introduction.mdx +0 -119
- package/src/stories/OneColumnContainer.stories.js +0 -20
- package/src/stories/OneColumnContainer.style.js +0 -41
- package/src/stories/SegmentedButton.stories.js +0 -205
- package/src/stories/SegmentedButton.style.js +0 -76
- package/src/stories/TotalDoughnutChart.stories.js +0 -112
- package/src/stories/TotalDoughnutChart.style.js +0 -143
- package/src/stories/assets/code-brackets.svg +0 -1
- package/src/stories/assets/colors.svg +0 -1
- package/src/stories/assets/comments.svg +0 -1
- package/src/stories/assets/direction.svg +0 -1
- package/src/stories/assets/flow.svg +0 -1
- package/src/stories/assets/info.svg +0 -1
- package/src/stories/assets/plugin.svg +0 -1
- package/src/stories/assets/repo.svg +0 -1
- package/src/stories/assets/stackalt.svg +0 -1
- package/src/stories/components/Benchmark.jsx +0 -75
- package/src/stories/components/Button.jsx +0 -54
- package/src/stories/components/Dropdown.jsx +0 -249
- package/src/stories/components/InfoIcon.jsx +0 -9
- package/src/stories/components/OneColumnContainer.jsx +0 -46
- package/src/stories/components/SegmentedButton.jsx +0 -110
- package/src/stories/components/TotalDoughnutChart.jsx +0 -178
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import MUIButton from "@mui/material/Button";
|
|
3
|
-
import Stack from "@mui/material/Stack";
|
|
4
|
-
|
|
5
|
-
export const Button = ({
|
|
6
|
-
text,
|
|
7
|
-
shape,
|
|
8
|
-
size,
|
|
9
|
-
disabled,
|
|
10
|
-
radius,
|
|
11
|
-
textColor,
|
|
12
|
-
backgroundColor,
|
|
13
|
-
onClick,
|
|
14
|
-
...props
|
|
15
|
-
}) => {
|
|
16
|
-
const getTextColor = () => {
|
|
17
|
-
|
|
18
|
-
if (!textColor || textColor == "" || textColor == "none") {
|
|
19
|
-
//default when parameter was not set
|
|
20
|
-
if (shape === "contained") {
|
|
21
|
-
return "white";
|
|
22
|
-
} else {
|
|
23
|
-
return "black";
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
else{
|
|
27
|
-
return textColor;
|
|
28
|
-
}
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
return (
|
|
32
|
-
<Stack direction="row" spacing={2}>
|
|
33
|
-
<MUIButton
|
|
34
|
-
sx={{
|
|
35
|
-
textTransform: "none",
|
|
36
|
-
borderRadius: radius * 0.05,
|
|
37
|
-
color: getTextColor(), // shape === "contained" ? "white" : "black",
|
|
38
|
-
backgroundColor: { backgroundColor },
|
|
39
|
-
}}
|
|
40
|
-
|
|
41
|
-
variant={shape}
|
|
42
|
-
size={size}
|
|
43
|
-
disabled={disabled ? true : false}
|
|
44
|
-
onClick={(event) => {
|
|
45
|
-
onClick(event);
|
|
46
|
-
}}
|
|
47
|
-
>
|
|
48
|
-
{text}
|
|
49
|
-
</MUIButton>
|
|
50
|
-
</Stack>
|
|
51
|
-
);
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
export default Button;
|
|
@@ -1,249 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { useState, useEffect } from "react";
|
|
3
|
-
import "../Dropdown.style.js";
|
|
4
|
-
//import PropTypes from "prop-types";
|
|
5
|
-
import { DropdownContainer } from "../Dropdown.style.js";
|
|
6
|
-
|
|
7
|
-
// import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
8
|
-
// import { faChevronDown, faAsterisk } from "@fortawesome/free-solid-svg-icons";
|
|
9
|
-
|
|
10
|
-
import Autocomplete from "@mui/material/Autocomplete";
|
|
11
|
-
import TextField from "@mui/material/TextField";
|
|
12
|
-
import Checkbox from "@mui/material/Checkbox";
|
|
13
|
-
import InputAdornment from "@mui/material/InputAdornment";
|
|
14
|
-
import Icon from "@mui/material/Icon";
|
|
15
|
-
|
|
16
|
-
import CheckBoxOutlineBlankIcon from "@mui/icons-material/CheckBoxOutlineBlank";
|
|
17
|
-
import CheckBoxIcon from "@mui/icons-material/CheckBox";
|
|
18
|
-
import SearchIcon from "@mui/icons-material/Search.js";
|
|
19
|
-
import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown.js";
|
|
20
|
-
|
|
21
|
-
const icon = <CheckBoxOutlineBlankIcon fontSize="small" />;
|
|
22
|
-
const checkedIcon = <CheckBoxIcon fontSize="small" />;
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* SAG Dropdown
|
|
26
|
-
*/
|
|
27
|
-
export const Dropdown = ({
|
|
28
|
-
width,
|
|
29
|
-
size,
|
|
30
|
-
text,
|
|
31
|
-
shape,
|
|
32
|
-
placeHolder,
|
|
33
|
-
multiSelect,
|
|
34
|
-
limitTagsOnMultiSelect,
|
|
35
|
-
showPopupIcon,
|
|
36
|
-
showSearchIcon,
|
|
37
|
-
options,
|
|
38
|
-
onChange,
|
|
39
|
-
onInputChange,
|
|
40
|
-
}) => {
|
|
41
|
-
/**
|
|
42
|
-
* SAG Dropdown
|
|
43
|
-
*/
|
|
44
|
-
const [currentInputValue, setCurrentInputValue] = useState(null);
|
|
45
|
-
const [currentOption, setCurrentOption] = useState(null);
|
|
46
|
-
|
|
47
|
-
useEffect(() => {
|
|
48
|
-
const delayDebounceFn = setTimeout(() => {
|
|
49
|
-
onInputChange(currentInputValue);
|
|
50
|
-
}, 1000);
|
|
51
|
-
|
|
52
|
-
return () => clearTimeout(delayDebounceFn);
|
|
53
|
-
}, [currentInputValue]);
|
|
54
|
-
|
|
55
|
-
//defines shape: squire or round
|
|
56
|
-
const getTextFieldStyle = () => {
|
|
57
|
-
if (shape === "round") {
|
|
58
|
-
// round
|
|
59
|
-
return {
|
|
60
|
-
"& .MuiOutlinedInput-root": {
|
|
61
|
-
borderRadius: "50px",
|
|
62
|
-
|
|
63
|
-
legend: {
|
|
64
|
-
marginLeft: "30px",
|
|
65
|
-
},
|
|
66
|
-
},
|
|
67
|
-
"& .MuiAutocomplete-inputRoot": {
|
|
68
|
-
paddingLeft: "20px !important",
|
|
69
|
-
borderRadius: "50px",
|
|
70
|
-
},
|
|
71
|
-
"& .MuiInputLabel-outlined": {
|
|
72
|
-
paddingLeft: "20px",
|
|
73
|
-
},
|
|
74
|
-
"& .MuiInputLabel-shrink": {
|
|
75
|
-
marginLeft: "20px",
|
|
76
|
-
paddingLeft: "10px",
|
|
77
|
-
paddingRight: 0,
|
|
78
|
-
background: "white",
|
|
79
|
-
},
|
|
80
|
-
};
|
|
81
|
-
} else {
|
|
82
|
-
//square
|
|
83
|
-
return null;
|
|
84
|
-
}
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
const onInputChangeHandler = (event, newInputValue) => {
|
|
88
|
-
setCurrentInputValue({
|
|
89
|
-
syntheticBaseEvent: event,
|
|
90
|
-
inputValue: newInputValue,
|
|
91
|
-
});
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
const onChangeHandler = (event, newValue) => {
|
|
95
|
-
setCurrentOption(newValue);
|
|
96
|
-
onChange(event, newValue);
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
const getAutocompleteSingle = () => {
|
|
100
|
-
return (
|
|
101
|
-
<Autocomplete
|
|
102
|
-
onChange={(event, newValue) => {
|
|
103
|
-
onChangeHandler(event, newValue);
|
|
104
|
-
}}
|
|
105
|
-
onInputChange={(event, newInputValue) => {
|
|
106
|
-
onInputChangeHandler(event, newInputValue);
|
|
107
|
-
}}
|
|
108
|
-
disablePortal
|
|
109
|
-
id="combo-box"
|
|
110
|
-
options={options}
|
|
111
|
-
sx={{ width: width }}
|
|
112
|
-
popupIcon={showPopupIcon ? <ArrowDropDownIcon /> : null}
|
|
113
|
-
forcePopupIcon={"auto"}
|
|
114
|
-
renderInput={(params) => (
|
|
115
|
-
<TextField
|
|
116
|
-
{...params}
|
|
117
|
-
label={text}
|
|
118
|
-
size={size}
|
|
119
|
-
sx={getTextFieldStyle()}
|
|
120
|
-
placeholder={placeHolder}
|
|
121
|
-
InputProps={{
|
|
122
|
-
...params.InputProps,
|
|
123
|
-
startAdornment: showSearchIcon ? (
|
|
124
|
-
<InputAdornment position="start">
|
|
125
|
-
<SearchIcon fontSize="medium" />
|
|
126
|
-
</InputAdornment>
|
|
127
|
-
) : null,
|
|
128
|
-
}}
|
|
129
|
-
/>
|
|
130
|
-
)}
|
|
131
|
-
/>
|
|
132
|
-
);
|
|
133
|
-
};
|
|
134
|
-
|
|
135
|
-
const getAutocompleteMulti = () => {
|
|
136
|
-
return (
|
|
137
|
-
<Autocomplete
|
|
138
|
-
onChange={(event, newValue) => {
|
|
139
|
-
onChangeHandler(event, newValue);
|
|
140
|
-
}}
|
|
141
|
-
onInputChange={(event, newInputValue) => {
|
|
142
|
-
onInputChangeHandler(event, newInputValue);
|
|
143
|
-
}}
|
|
144
|
-
multiple
|
|
145
|
-
limitTags={limitTagsOnMultiSelect}
|
|
146
|
-
size={size}
|
|
147
|
-
id="checkboxes-tags"
|
|
148
|
-
options={options}
|
|
149
|
-
disableCloseOnSelect
|
|
150
|
-
getOptionLabel={(option) => option.label}
|
|
151
|
-
popupIcon={showPopupIcon ? <ArrowDropDownIcon /> : null}
|
|
152
|
-
renderOption={(props, option, { selected }) => (
|
|
153
|
-
<li {...props}>
|
|
154
|
-
<Checkbox
|
|
155
|
-
icon={icon}
|
|
156
|
-
checkedIcon={checkedIcon}
|
|
157
|
-
style={{ marginRight: 8 }}
|
|
158
|
-
checked={selected}
|
|
159
|
-
/>
|
|
160
|
-
{option.label}
|
|
161
|
-
</li>
|
|
162
|
-
)}
|
|
163
|
-
style={{ width: width }}
|
|
164
|
-
renderInput={(params) =>
|
|
165
|
-
showSearchIcon && (!currentOption || (currentOption && currentOption.length === 0)) ? (
|
|
166
|
-
<TextField
|
|
167
|
-
{...params}
|
|
168
|
-
label={text}
|
|
169
|
-
size={size}
|
|
170
|
-
sx={getTextFieldStyle()}
|
|
171
|
-
placeholder={placeHolder}
|
|
172
|
-
InputProps={{
|
|
173
|
-
...params.InputProps,
|
|
174
|
-
startAdornment: (
|
|
175
|
-
<InputAdornment position="start">
|
|
176
|
-
<SearchIcon fontSize="medium" />
|
|
177
|
-
</InputAdornment>
|
|
178
|
-
),
|
|
179
|
-
}}
|
|
180
|
-
/>
|
|
181
|
-
) : (
|
|
182
|
-
<TextField
|
|
183
|
-
{...params}
|
|
184
|
-
label={text}
|
|
185
|
-
size={size}
|
|
186
|
-
sx={getTextFieldStyle()}
|
|
187
|
-
placeholder={placeHolder}
|
|
188
|
-
/>
|
|
189
|
-
)
|
|
190
|
-
}
|
|
191
|
-
/>
|
|
192
|
-
);
|
|
193
|
-
};
|
|
194
|
-
|
|
195
|
-
return (
|
|
196
|
-
<DropdownContainer width={width}>
|
|
197
|
-
{/* <TextField
|
|
198
|
-
label={"Retailer"}
|
|
199
|
-
size={"small"}
|
|
200
|
-
placeholder="Type..."
|
|
201
|
-
InputProps={{
|
|
202
|
-
startAdornment: (
|
|
203
|
-
<InputAdornment position="start">
|
|
204
|
-
<SearchIcon fontSize="small" />
|
|
205
|
-
</InputAdornment>
|
|
206
|
-
),
|
|
207
|
-
}}
|
|
208
|
-
/> */}
|
|
209
|
-
{multiSelect ? getAutocompleteMulti() : getAutocompleteSingle()}
|
|
210
|
-
</DropdownContainer>
|
|
211
|
-
);
|
|
212
|
-
};
|
|
213
|
-
|
|
214
|
-
// Dropdown.propTypes = {
|
|
215
|
-
// /**
|
|
216
|
-
// * dropdown width
|
|
217
|
-
// */
|
|
218
|
-
// width: PropTypes.string,
|
|
219
|
-
|
|
220
|
-
// /**
|
|
221
|
-
// * dropdown size: small/large
|
|
222
|
-
// */
|
|
223
|
-
// size: PropTypes.string,
|
|
224
|
-
|
|
225
|
-
// /**
|
|
226
|
-
// * dropdown initial input text
|
|
227
|
-
// */
|
|
228
|
-
// text: PropTypes.string,
|
|
229
|
-
|
|
230
|
-
// /**
|
|
231
|
-
// * arrayOf <T> - options array to load into dropdown
|
|
232
|
-
// */
|
|
233
|
-
// options: PropTypes.arrayOf,
|
|
234
|
-
|
|
235
|
-
// /**
|
|
236
|
-
// * shape: round/square
|
|
237
|
-
// */
|
|
238
|
-
// shape: PropTypes.string,
|
|
239
|
-
// };
|
|
240
|
-
|
|
241
|
-
// Dropdown.defaultProps = {
|
|
242
|
-
// width: 300,
|
|
243
|
-
// size: "small",
|
|
244
|
-
// text: "Select retailer...",
|
|
245
|
-
// options: [],
|
|
246
|
-
// shape: "round",
|
|
247
|
-
// };
|
|
248
|
-
|
|
249
|
-
export default Dropdown;
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
|
|
3
|
-
export const InfoIcon = ({clicked}) => {
|
|
4
|
-
return (
|
|
5
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke={clicked ? "white" : "black"} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="feather feather-info"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="16" x2="12" y2="12"></line><line x1="12" y1="8" x2="12" y2="8"></line></svg>
|
|
6
|
-
);
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
export default InfoIcon;
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { useState } from "react";
|
|
3
|
-
import { InfoTextLabel,InfoTextContainer,IconContainer, StyledContainer } from '../OneColumnContainer.style';
|
|
4
|
-
import { InfoIcon } from "./InfoIcon";
|
|
5
|
-
import { useDroppable, UniqueIdentifier } from "@dnd-kit/core";
|
|
6
|
-
import classNames from "classnames";
|
|
7
|
-
/**
|
|
8
|
-
* Primary UI component for user interaction
|
|
9
|
-
*/
|
|
10
|
-
export const OneColumnContainer = ({ children,nodeRef,itemClass,divStyle,overStyle,draggingStyle,droppedStyle,refId,width,height,infoText,...props }) => {
|
|
11
|
-
const [clicked, setClicked] = useState(false);
|
|
12
|
-
const onInfoClick = ()=>{
|
|
13
|
-
setClicked(!clicked)
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
return (
|
|
17
|
-
|
|
18
|
-
<StyledContainer className={classNames(
|
|
19
|
-
itemClass,
|
|
20
|
-
overStyle,
|
|
21
|
-
draggingStyle,
|
|
22
|
-
children && droppedStyle
|
|
23
|
-
)} width={width} height={height}>
|
|
24
|
-
<div className={classNames(divStyle)} ref={nodeRef} >
|
|
25
|
-
{children}
|
|
26
|
-
<InfoTextContainer clicked={clicked} width={width} height={height}>
|
|
27
|
-
<InfoTextLabel>{infoText}</InfoTextLabel>
|
|
28
|
-
</InfoTextContainer>
|
|
29
|
-
<IconContainer onClick={onInfoClick}>
|
|
30
|
-
<InfoIcon clicked={clicked} />
|
|
31
|
-
</IconContainer>
|
|
32
|
-
</div>
|
|
33
|
-
</StyledContainer>
|
|
34
|
-
|
|
35
|
-
);
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
OneColumnContainer.propTypes = {
|
|
39
|
-
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
OneColumnContainer.defaultProps = {
|
|
43
|
-
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
export default OneColumnContainer;
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { useState, useEffect, useRef } from "react";
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
ControlsContainer,
|
|
6
|
-
Controls,
|
|
7
|
-
ControlsInput,
|
|
8
|
-
Segment,
|
|
9
|
-
SegmentLabel,
|
|
10
|
-
} from "../SegmentedButton.style.js";
|
|
11
|
-
|
|
12
|
-
/*SegmentedButton*/
|
|
13
|
-
export const SegmentedButton = ({
|
|
14
|
-
name,
|
|
15
|
-
options,
|
|
16
|
-
segmentWidth = 120,
|
|
17
|
-
segmentHeigth = 41,
|
|
18
|
-
controlRadius = 8,
|
|
19
|
-
segmentRadius = 8,
|
|
20
|
-
fontSize = 14,
|
|
21
|
-
backgroundColor = "#ECF0FF",
|
|
22
|
-
selectedSegmentColor = "#3a9df9",
|
|
23
|
-
selectedTextColor = "white",
|
|
24
|
-
unselectedTextColor = "black",
|
|
25
|
-
defaultIndex = 0,
|
|
26
|
-
onClick,
|
|
27
|
-
...props
|
|
28
|
-
}) => {
|
|
29
|
-
const [activeIndex, setActiveIndex] = useState(defaultIndex);
|
|
30
|
-
|
|
31
|
-
const controlRef = useRef();
|
|
32
|
-
const componentReady = useRef();
|
|
33
|
-
|
|
34
|
-
const optionsRef = options.map((item, i) => {
|
|
35
|
-
return { ...item, id: i, ref: useRef() };
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
// Determine when the component is "ready"
|
|
39
|
-
useEffect(() => {
|
|
40
|
-
componentReady.current = true;
|
|
41
|
-
}, []);
|
|
42
|
-
|
|
43
|
-
useEffect(()=>{
|
|
44
|
-
if( defaultIndex >= 0 && defaultIndex < options?.length){
|
|
45
|
-
setActiveIndex(defaultIndex);
|
|
46
|
-
}
|
|
47
|
-
},[defaultIndex])
|
|
48
|
-
|
|
49
|
-
useEffect(() => {
|
|
50
|
-
const activeSegmentRef = optionsRef[activeIndex].ref;
|
|
51
|
-
const { offsetWidth, offsetLeft } = activeSegmentRef.current;
|
|
52
|
-
const { style } = controlRef.current;
|
|
53
|
-
|
|
54
|
-
style.setProperty("--highlight-width", `${offsetWidth}px`);
|
|
55
|
-
style.setProperty("--highlight-x-pos", `${offsetLeft}px`);
|
|
56
|
-
}, [activeIndex, controlRef, optionsRef]);
|
|
57
|
-
|
|
58
|
-
const onInputChangeHandler = (value, index) => {
|
|
59
|
-
setActiveIndex(index);
|
|
60
|
-
onClick({index: index, value: value} );
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
return (
|
|
64
|
-
<ControlsContainer
|
|
65
|
-
fontSize={fontSize}
|
|
66
|
-
ref={controlRef}>
|
|
67
|
-
<Controls
|
|
68
|
-
backgroundColor={backgroundColor}
|
|
69
|
-
selectedSegmentColor={selectedSegmentColor}
|
|
70
|
-
segmentRadius={segmentRadius}
|
|
71
|
-
controlRadius={controlRadius}
|
|
72
|
-
segmentWidth={segmentWidth}
|
|
73
|
-
className={`controls ${componentReady.current ? "ready" : "idle"}`}
|
|
74
|
-
>
|
|
75
|
-
{optionsRef?.map((item, i) => (
|
|
76
|
-
<Segment
|
|
77
|
-
key={item.id}
|
|
78
|
-
backgroundColor={backgroundColor}
|
|
79
|
-
selectedSegmentColor={selectedSegmentColor}
|
|
80
|
-
segmentRadius={segmentRadius}
|
|
81
|
-
controlRadius={controlRadius}
|
|
82
|
-
segmentWidth={segmentWidth}
|
|
83
|
-
className={`${activeIndex === i ? "active" : "inactive"}`}
|
|
84
|
-
ref={item.ref}
|
|
85
|
-
>
|
|
86
|
-
<ControlsInput
|
|
87
|
-
type="radio"
|
|
88
|
-
value={item.value}
|
|
89
|
-
id={item.id}
|
|
90
|
-
name={name}
|
|
91
|
-
onChange={() => onInputChangeHandler(item.value, item.id)}
|
|
92
|
-
checked={i === activeIndex}
|
|
93
|
-
/>
|
|
94
|
-
<SegmentLabel
|
|
95
|
-
selectedTextColor={selectedTextColor}
|
|
96
|
-
unselectedTextColor={unselectedTextColor}
|
|
97
|
-
segmentHeigth={segmentHeigth/5}
|
|
98
|
-
className={`${activeIndex === i ? "active" : "inactive"} `}
|
|
99
|
-
htmlFor={item.value}
|
|
100
|
-
>
|
|
101
|
-
{item.value}
|
|
102
|
-
</SegmentLabel>
|
|
103
|
-
</Segment>
|
|
104
|
-
))}
|
|
105
|
-
</Controls>
|
|
106
|
-
</ControlsContainer>
|
|
107
|
-
);
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
export default SegmentedButton;
|
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
|
|
3
|
-
import { PieChart as SourcePieChart, Pie, Cell, Tooltip } from "recharts";
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
ControlsContainer,
|
|
7
|
-
Title,
|
|
8
|
-
CurrencySign,
|
|
9
|
-
FormattedValue,
|
|
10
|
-
Controls,
|
|
11
|
-
DoughnutChart,
|
|
12
|
-
LegendControls,
|
|
13
|
-
LegendColorRectangle,
|
|
14
|
-
LegendTitle,
|
|
15
|
-
LegendCurrencySign,
|
|
16
|
-
LegendFormattedValue,
|
|
17
|
-
} from "../TotalDoughnutChart.style.js";
|
|
18
|
-
|
|
19
|
-
/*TotalDoughnutChart*/
|
|
20
|
-
export const TotalDoughnutChart = ({
|
|
21
|
-
title = "Total Cost",
|
|
22
|
-
value = 0,
|
|
23
|
-
dotCut = true,
|
|
24
|
-
currency = true,
|
|
25
|
-
currencyType = "USD",
|
|
26
|
-
legendData,
|
|
27
|
-
width = 260,
|
|
28
|
-
height = 350,
|
|
29
|
-
textColor = "black",
|
|
30
|
-
...props
|
|
31
|
-
}) => {
|
|
32
|
-
const MIN_WIDTH = 260;
|
|
33
|
-
const MIN_HEIGHT = 300;
|
|
34
|
-
|
|
35
|
-
const getCurrencySign = (currencyTypeToConvert) => {
|
|
36
|
-
if (!currencyTypeToConvert) return "";
|
|
37
|
-
let currencySign = "";
|
|
38
|
-
const currencyFormatter = new Intl.NumberFormat("en-US", {
|
|
39
|
-
style: "currency",
|
|
40
|
-
currency: currencyTypeToConvert,
|
|
41
|
-
});
|
|
42
|
-
currencySign = currencyFormatter.format(value).substring(0, 1);
|
|
43
|
-
return currencySign;
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
const getFormattedUnits = (num) => {
|
|
47
|
-
if (Math.abs(num) >= 1000000000) {
|
|
48
|
-
return "B";
|
|
49
|
-
}
|
|
50
|
-
if (Math.abs(num) >= 1000000) {
|
|
51
|
-
return "M";
|
|
52
|
-
}
|
|
53
|
-
if (Math.abs(num) >= 1000) {
|
|
54
|
-
return "K";
|
|
55
|
-
}
|
|
56
|
-
return "";
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
const getFormattedValue = (num) => {
|
|
60
|
-
if (Math.abs(num) >= 1000000000) {
|
|
61
|
-
return (num / 1000000000).toFixed(1).replace(/\.0$/, "");
|
|
62
|
-
}
|
|
63
|
-
if (Math.abs(num) >= 1000000) {
|
|
64
|
-
return (num / 1000000).toFixed(1).replace(/\.0$/, "");
|
|
65
|
-
}
|
|
66
|
-
if (Math.abs(num) >= 1000) {
|
|
67
|
-
return (num / 1000).toFixed(1).replace(/\.0$/, "");
|
|
68
|
-
}
|
|
69
|
-
return num;
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
const getNumberWithCommas = (x) => {
|
|
73
|
-
x = x.toString();
|
|
74
|
-
var pattern = /(-?\d+)(\d{3})/;
|
|
75
|
-
while (pattern.test(x)) x = x.replace(pattern, "$1,$2");
|
|
76
|
-
return x;
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
const getDoughnutChartLeft = () => {
|
|
80
|
-
if( width <= 260) { return 10};
|
|
81
|
-
if( width >= 290) { return 40};
|
|
82
|
-
return 10 + (width - MIN_WIDTH) ;
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
const getLegendControlsLeft = () => {
|
|
86
|
-
if( width <= 260) { return 100};
|
|
87
|
-
if( width >= 300) { return 140};
|
|
88
|
-
return 100 + (width - MIN_WIDTH) ;
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
const getDoughnutChartTop = () => {
|
|
92
|
-
if( height <= 300) { return 180};
|
|
93
|
-
if( height >= 340) { return 220};
|
|
94
|
-
return 180 + (height - MIN_HEIGHT) ;
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
const getLegendControlsTop = () => {
|
|
98
|
-
if( height <= 300) { return 180};
|
|
99
|
-
if( height >= 340) { return 220};
|
|
100
|
-
return 180 + (height - MIN_HEIGHT) ;
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const getControlsLeft = () => {
|
|
105
|
-
if( (width - MIN_WIDTH)<= 0) { return MIN_WIDTH};
|
|
106
|
-
return width ;
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
const getControlsTop = () => {
|
|
110
|
-
if( (height - MIN_HEIGHT)<= 0) { return MIN_HEIGHT};
|
|
111
|
-
return height ;
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
const onPieEnterHandler = () => {};
|
|
115
|
-
|
|
116
|
-
return (
|
|
117
|
-
<ControlsContainer height={getControlsTop()} width={getControlsLeft()} textColor={textColor}>
|
|
118
|
-
<Controls height={height} width={getControlsLeft}>
|
|
119
|
-
<Title>{title}</Title>
|
|
120
|
-
|
|
121
|
-
<CurrencySign>
|
|
122
|
-
{`${currency ? getCurrencySign(currencyType) : ""}`}
|
|
123
|
-
</CurrencySign>
|
|
124
|
-
<FormattedValue>
|
|
125
|
-
{`${dotCut ? getFormattedValue(value) : getNumberWithCommas(value)}`}
|
|
126
|
-
{`${dotCut ? getFormattedUnits(value) : ""}`}
|
|
127
|
-
</FormattedValue>
|
|
128
|
-
|
|
129
|
-
{legendData.map((row, index) => (
|
|
130
|
-
<LegendControls
|
|
131
|
-
left={getLegendControlsLeft()}
|
|
132
|
-
top={getLegendControlsTop()}
|
|
133
|
-
>
|
|
134
|
-
<LegendColorRectangle color={row.color}></LegendColorRectangle>
|
|
135
|
-
<LegendTitle>{row.name}</LegendTitle>
|
|
136
|
-
<LegendCurrencySign>
|
|
137
|
-
{`${currency ? getCurrencySign(currencyType) : ""}`}
|
|
138
|
-
</LegendCurrencySign>
|
|
139
|
-
<LegendFormattedValue>
|
|
140
|
-
{`${
|
|
141
|
-
dotCut
|
|
142
|
-
? getFormattedValue(row.value)
|
|
143
|
-
: getNumberWithCommas(row.value)
|
|
144
|
-
}`}
|
|
145
|
-
{`${dotCut ? getFormattedUnits(row.value) : ""}`}
|
|
146
|
-
</LegendFormattedValue>
|
|
147
|
-
</LegendControls>
|
|
148
|
-
))}
|
|
149
|
-
|
|
150
|
-
<DoughnutChart
|
|
151
|
-
left={getDoughnutChartLeft() }
|
|
152
|
-
top={getDoughnutChartTop()}>
|
|
153
|
-
<SourcePieChart
|
|
154
|
-
width={90}
|
|
155
|
-
height={90}
|
|
156
|
-
onMouseEnter={onPieEnterHandler}
|
|
157
|
-
>
|
|
158
|
-
<Pie
|
|
159
|
-
data={legendData}
|
|
160
|
-
innerRadius={30}
|
|
161
|
-
outerRadius={45}
|
|
162
|
-
fill="#8884d8"
|
|
163
|
-
dataKey="value"
|
|
164
|
-
>
|
|
165
|
-
{legendData.map((row, index) => (
|
|
166
|
-
<Cell key={`cell-${index}`} fill={row.color} />
|
|
167
|
-
))}
|
|
168
|
-
</Pie>
|
|
169
|
-
|
|
170
|
-
<Tooltip />
|
|
171
|
-
</SourcePieChart>
|
|
172
|
-
</DoughnutChart>
|
|
173
|
-
</Controls>
|
|
174
|
-
</ControlsContainer>
|
|
175
|
-
);
|
|
176
|
-
};
|
|
177
|
-
|
|
178
|
-
export default TotalDoughnutChart;
|