@groupeactual/ui-kit 0.4.30 → 0.4.32
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/index.js +94 -1199
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +113 -57176
- package/dist/esm/index.js.map +1 -1
- package/package.json +8 -11
- package/src/DesignSystemProvider.tsx +0 -61
- package/src/components/Accordion/Accordion.tsx +0 -72
- package/src/components/Accordion/index.ts +0 -1
- package/src/components/Button/Button.tsx +0 -18
- package/src/components/Button/index.ts +0 -1
- package/src/components/Chip/Chip.tsx +0 -125
- package/src/components/Chip/index.ts +0 -1
- package/src/components/EmbbededNotification/EmbeddedNotification.tsx +0 -95
- package/src/components/EmbbededNotification/index.ts +0 -1
- package/src/components/Form/Checkbox/Checkbox.tsx +0 -86
- package/src/components/Form/Checkbox/index.ts +0 -1
- package/src/components/Form/MultiSelect/MultiSelect.tsx +0 -184
- package/src/components/Form/MultiSelect/index.ts +0 -1
- package/src/components/Form/Select/Select.tsx +0 -154
- package/src/components/Form/Select/index.ts +0 -1
- package/src/components/Form/TextField/TextField.tsx +0 -98
- package/src/components/Form/TextField/index.ts +0 -1
- package/src/components/Icon/Icon.tsx +0 -126
- package/src/components/Icon/index.ts +0 -1
- package/src/components/Link/Link.tsx +0 -11
- package/src/components/Link/index.ts +0 -1
- package/src/components/Pagination/Pagination.tsx +0 -116
- package/src/components/Pagination/index.ts +0 -1
- package/src/components/Text/Text.tsx +0 -26
- package/src/components/Text/index.ts +0 -1
- package/src/components/Tooltip/Tooltip.tsx +0 -33
- package/src/components/Tooltip/index.ts +0 -1
- package/src/components/index.ts +0 -13
- package/src/index.ts +0 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@groupeactual/ui-kit",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.32",
|
|
4
4
|
"description": "A simple template for a custom React component library",
|
|
5
5
|
"devDependencies": {
|
|
6
6
|
"@babel/core": "^7.20.5",
|
|
@@ -37,16 +37,7 @@
|
|
|
37
37
|
"sass": "^1.56.1",
|
|
38
38
|
"sass-loader": "^12.6.0",
|
|
39
39
|
"style-loader": "^3.3.1",
|
|
40
|
-
"typescript": "^4.9.3"
|
|
41
|
-
},
|
|
42
|
-
"main": "dist/cjs/index.js",
|
|
43
|
-
"module": "dist/esm/index.js",
|
|
44
|
-
"files": [
|
|
45
|
-
"dist",
|
|
46
|
-
"src"
|
|
47
|
-
],
|
|
48
|
-
"types": "dist/index.d.ts",
|
|
49
|
-
"dependencies": {
|
|
40
|
+
"typescript": "^4.9.3",
|
|
50
41
|
"@emotion/is-prop-valid": "^1.2.0",
|
|
51
42
|
"@emotion/react": "^11.10.5",
|
|
52
43
|
"@emotion/styled": "^11.10.5",
|
|
@@ -69,6 +60,12 @@
|
|
|
69
60
|
"tslib": "^2.4.1",
|
|
70
61
|
"webpack": "^5.75.0"
|
|
71
62
|
},
|
|
63
|
+
"main": "dist/cjs/index.js",
|
|
64
|
+
"module": "dist/esm/index.js",
|
|
65
|
+
"files": [
|
|
66
|
+
"dist"
|
|
67
|
+
],
|
|
68
|
+
"types": "dist/index.d.ts",
|
|
72
69
|
"peerDependencies": {
|
|
73
70
|
"react": "^18.2.0",
|
|
74
71
|
"react-dom": "^18.2.0"
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import React, {
|
|
2
|
-
PropsWithChildren,
|
|
3
|
-
useState,
|
|
4
|
-
createContext,
|
|
5
|
-
useContext
|
|
6
|
-
} from 'react';
|
|
7
|
-
import { useMaterialThemeTokens } from '@groupeactual/design-tokens';
|
|
8
|
-
import { createTheme, ThemeProvider } from '@mui/material';
|
|
9
|
-
|
|
10
|
-
// Deux themes pour le moment :
|
|
11
|
-
// Default = Theme backoffice Material
|
|
12
|
-
// Ep = Espace personnel
|
|
13
|
-
type Theme = 'Default' | 'Ep';
|
|
14
|
-
|
|
15
|
-
export interface DesignSystemContextValues {
|
|
16
|
-
isDarkTheme: boolean;
|
|
17
|
-
themeName: Theme;
|
|
18
|
-
toggleDarkTheme: () => void;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export const DesignSystemContext = createContext<DesignSystemContextValues>({
|
|
22
|
-
isDarkTheme: false,
|
|
23
|
-
themeName: 'Default',
|
|
24
|
-
toggleDarkTheme: () => {
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
interface Props {
|
|
30
|
-
name?: Theme;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const MaterialThemeProvider = ({ children }: PropsWithChildren<unknown>) => {
|
|
34
|
-
const { themeName } =
|
|
35
|
-
useContext<DesignSystemContextValues>(DesignSystemContext);
|
|
36
|
-
const { muiTokens } = useMaterialThemeTokens(themeName);
|
|
37
|
-
const theme = createTheme(muiTokens);
|
|
38
|
-
|
|
39
|
-
return <ThemeProvider theme={theme}>{children}</ThemeProvider>;
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
const DesignSystemProvider = ({
|
|
43
|
-
children,
|
|
44
|
-
name: themeName = 'Default'
|
|
45
|
-
}: PropsWithChildren<Props>) => {
|
|
46
|
-
const [isDarkTheme, setIsDarkTheme] = useState(false);
|
|
47
|
-
|
|
48
|
-
const toggleDarkTheme = (): void => {
|
|
49
|
-
setIsDarkTheme(!isDarkTheme);
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
return (
|
|
53
|
-
<DesignSystemContext.Provider
|
|
54
|
-
value={{ isDarkTheme, themeName, toggleDarkTheme }}
|
|
55
|
-
>
|
|
56
|
-
<MaterialThemeProvider>{children}</MaterialThemeProvider>
|
|
57
|
-
</DesignSystemContext.Provider>
|
|
58
|
-
);
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
export default DesignSystemProvider;
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import React, {
|
|
2
|
-
MouseEventHandler,
|
|
3
|
-
ReactNode,
|
|
4
|
-
useEffect,
|
|
5
|
-
useState
|
|
6
|
-
} from 'react';
|
|
7
|
-
import AccordionMui, { AccordionProps } from '@mui/material/Accordion';
|
|
8
|
-
import AccordionSummary from '@mui/material/AccordionSummary';
|
|
9
|
-
import AccordionDetails from '@mui/material/AccordionDetails';
|
|
10
|
-
|
|
11
|
-
interface Props extends AccordionProps {
|
|
12
|
-
icon: ReactNode;
|
|
13
|
-
title?: string;
|
|
14
|
-
summaryHeight?: number;
|
|
15
|
-
expanded?: boolean;
|
|
16
|
-
onClick?: MouseEventHandler;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const Accordion = ({
|
|
20
|
-
icon,
|
|
21
|
-
title,
|
|
22
|
-
summaryHeight,
|
|
23
|
-
expanded = false,
|
|
24
|
-
onClick,
|
|
25
|
-
children,
|
|
26
|
-
...props
|
|
27
|
-
}: Props) => {
|
|
28
|
-
const [internalExpanded, setInternalExpanded] = useState(expanded);
|
|
29
|
-
|
|
30
|
-
useEffect(() => {
|
|
31
|
-
if (expanded !== internalExpanded) {
|
|
32
|
-
setInternalExpanded(expanded);
|
|
33
|
-
}
|
|
34
|
-
}, [expanded]);
|
|
35
|
-
|
|
36
|
-
return (
|
|
37
|
-
<AccordionMui
|
|
38
|
-
sx={{ border: `1px solid`, borderColor: 'greyLightDefaultBorder' }}
|
|
39
|
-
expanded={internalExpanded}
|
|
40
|
-
onClick={(e) => {
|
|
41
|
-
if (!props.disabled) {
|
|
42
|
-
setInternalExpanded(!internalExpanded);
|
|
43
|
-
onClick && onClick(e);
|
|
44
|
-
}
|
|
45
|
-
}}
|
|
46
|
-
{...props}
|
|
47
|
-
>
|
|
48
|
-
<AccordionSummary
|
|
49
|
-
expandIcon={icon}
|
|
50
|
-
sx={{
|
|
51
|
-
fontWeight: 500,
|
|
52
|
-
fontSize: 18,
|
|
53
|
-
lineHeight: 21,
|
|
54
|
-
height: summaryHeight || 60
|
|
55
|
-
}}
|
|
56
|
-
>
|
|
57
|
-
{title}
|
|
58
|
-
</AccordionSummary>
|
|
59
|
-
<AccordionDetails
|
|
60
|
-
sx={{
|
|
61
|
-
backgroundColor: 'greyXLight',
|
|
62
|
-
borderTop: '1px solid',
|
|
63
|
-
borderColor: 'greyLightDefaultBorder'
|
|
64
|
-
}}
|
|
65
|
-
>
|
|
66
|
-
{children}
|
|
67
|
-
</AccordionDetails>
|
|
68
|
-
</AccordionMui>
|
|
69
|
-
);
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
export default Accordion;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './Accordion';
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import React, { ReactNode } from 'react';
|
|
2
|
-
import { ButtonProps } from '@mui/material/Button';
|
|
3
|
-
import { Button as ButtonMUI } from '@mui/material';
|
|
4
|
-
|
|
5
|
-
interface Props extends Omit<ButtonProps, 'variant' | 'children'> {
|
|
6
|
-
variant?: 'primary' | 'secondary';
|
|
7
|
-
children?: ReactNode;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
const Button = ({ variant, children, ...props }: Props) => {
|
|
11
|
-
return (
|
|
12
|
-
<ButtonMUI variant={variant as 'text'} {...props}>
|
|
13
|
-
{children}
|
|
14
|
-
</ButtonMUI>
|
|
15
|
-
);
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export default Button;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './Button';
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
import React, { useEffect, useRef, useState } from 'react';
|
|
2
|
-
import { ChipProps as ChipPropsMUI } from '@mui/material/Chip';
|
|
3
|
-
import { Chip as ChipMUI, Tooltip } from '@mui/material';
|
|
4
|
-
import { useTheme } from '@mui/system';
|
|
5
|
-
import { IconDefinition } from '@fortawesome/fontawesome-svg-core';
|
|
6
|
-
|
|
7
|
-
import IconProvider from '../Icon';
|
|
8
|
-
|
|
9
|
-
interface Props
|
|
10
|
-
extends Omit<
|
|
11
|
-
ChipPropsMUI,
|
|
12
|
-
'suffix' | 'prefix' | 'onDelete' | 'onDeleteIcon'
|
|
13
|
-
> {
|
|
14
|
-
label: string;
|
|
15
|
-
size?: 'small';
|
|
16
|
-
prefixIcon?: IconDefinition;
|
|
17
|
-
suffixIcon?: IconDefinition;
|
|
18
|
-
suffixAction?: (e: any) => void;
|
|
19
|
-
suffixTooltip?: string;
|
|
20
|
-
tooltip?: string;
|
|
21
|
-
maxWidth?: number;
|
|
22
|
-
maxLength?: number;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const Chip = ({
|
|
26
|
-
label,
|
|
27
|
-
prefixIcon,
|
|
28
|
-
suffixIcon,
|
|
29
|
-
suffixTooltip,
|
|
30
|
-
suffixAction,
|
|
31
|
-
tooltip,
|
|
32
|
-
size = 'small',
|
|
33
|
-
maxWidth = 300,
|
|
34
|
-
maxLength = 17,
|
|
35
|
-
...props
|
|
36
|
-
}: Props) => {
|
|
37
|
-
const theme = useTheme();
|
|
38
|
-
const [currentLabel, setCurrentLabel] = useState<string>(label);
|
|
39
|
-
const [isOpen, setIsOpen] = useState<boolean>(false);
|
|
40
|
-
|
|
41
|
-
const ref = useRef<HTMLDivElement>(null);
|
|
42
|
-
|
|
43
|
-
let backgroundColor: string =
|
|
44
|
-
props.color && theme.palette[props.color]
|
|
45
|
-
? typeof theme.palette[props.color] === 'object'
|
|
46
|
-
? theme.palette[props.color]['main']
|
|
47
|
-
: theme.palette[props.color]
|
|
48
|
-
: props.color ?? 'white';
|
|
49
|
-
|
|
50
|
-
if (props.variant === 'filled') {
|
|
51
|
-
// opacity 0.08
|
|
52
|
-
backgroundColor = `${backgroundColor}14`;
|
|
53
|
-
} else {
|
|
54
|
-
backgroundColor = 'white';
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const emptyOnDelete = () => {
|
|
58
|
-
return null;
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
// use maxwidth props to set the max width of the chip based on the column width
|
|
62
|
-
// if a chip is in a table, the width should match the width of the column.
|
|
63
|
-
useEffect(() => {
|
|
64
|
-
if (
|
|
65
|
-
ref?.current?.offsetWidth &&
|
|
66
|
-
ref?.current?.offsetWidth > maxWidth &&
|
|
67
|
-
`${label.substring(0, maxLength)}...` !== currentLabel
|
|
68
|
-
) {
|
|
69
|
-
setCurrentLabel(`${label.substring(0, maxLength)}...`);
|
|
70
|
-
} else if (
|
|
71
|
-
ref?.current?.offsetWidth &&
|
|
72
|
-
ref?.current?.offsetWidth <= maxWidth &&
|
|
73
|
-
label === `${label.substring(0, maxLength)}...`
|
|
74
|
-
) {
|
|
75
|
-
setCurrentLabel(label);
|
|
76
|
-
}
|
|
77
|
-
}, [ref?.current?.offsetWidth]);
|
|
78
|
-
|
|
79
|
-
return (
|
|
80
|
-
<Tooltip title={tooltip} placement="right-start">
|
|
81
|
-
<Tooltip
|
|
82
|
-
title={suffixTooltip}
|
|
83
|
-
open={isOpen}
|
|
84
|
-
placement="bottom-end"
|
|
85
|
-
sx={{ cursor: suffixAction ? 'pointer !important' : 'default' }}
|
|
86
|
-
>
|
|
87
|
-
<ChipMUI
|
|
88
|
-
label={currentLabel}
|
|
89
|
-
ref={ref}
|
|
90
|
-
size={size}
|
|
91
|
-
sx={{
|
|
92
|
-
backgroundColor: backgroundColor,
|
|
93
|
-
'&.MuiChip-colorSecondary:hover': suffixIcon &&
|
|
94
|
-
suffixAction && {
|
|
95
|
-
backgroundColor: '#004f88 !important'
|
|
96
|
-
},
|
|
97
|
-
'&.MuiChip-deleteIconColorPrimary:hover': suffixIcon &&
|
|
98
|
-
suffixAction && {
|
|
99
|
-
backgroundColor: '#004f88 !important'
|
|
100
|
-
}
|
|
101
|
-
}}
|
|
102
|
-
avatar={
|
|
103
|
-
prefixIcon ? <IconProvider icon={prefixIcon} size="sm" /> : <></>
|
|
104
|
-
}
|
|
105
|
-
deleteIcon={
|
|
106
|
-
suffixIcon ? (
|
|
107
|
-
<IconProvider
|
|
108
|
-
icon={suffixIcon}
|
|
109
|
-
onMouseEnter={() => suffixTooltip && setIsOpen(true)}
|
|
110
|
-
onMouseLeave={() => suffixTooltip && setIsOpen(false)}
|
|
111
|
-
size="sm"
|
|
112
|
-
/>
|
|
113
|
-
) : (
|
|
114
|
-
<></>
|
|
115
|
-
)
|
|
116
|
-
}
|
|
117
|
-
onDelete={suffixAction ?? emptyOnDelete}
|
|
118
|
-
{...props}
|
|
119
|
-
/>
|
|
120
|
-
</Tooltip>
|
|
121
|
-
</Tooltip>
|
|
122
|
-
);
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
export default Chip;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './Chip';
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import React, { ReactNode } from 'react';
|
|
2
|
-
import { Box, BoxProps } from '@mui/material';
|
|
3
|
-
import { IconDefinition } from '@fortawesome/fontawesome-svg-core';
|
|
4
|
-
import {
|
|
5
|
-
faCircleXmark,
|
|
6
|
-
faCircleInfo,
|
|
7
|
-
faCircleCheck,
|
|
8
|
-
faCircleExclamation
|
|
9
|
-
} from '@fortawesome/pro-solid-svg-icons';
|
|
10
|
-
|
|
11
|
-
import Text from '../Text';
|
|
12
|
-
import Icon from '../Icon/Icon';
|
|
13
|
-
|
|
14
|
-
interface Props extends BoxProps {
|
|
15
|
-
variant: 'warning' | 'error' | 'success' | 'infos';
|
|
16
|
-
title: string;
|
|
17
|
-
text?: ReactNode;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const EmbeddedNotification = ({
|
|
21
|
-
title,
|
|
22
|
-
text,
|
|
23
|
-
variant = 'infos',
|
|
24
|
-
...props
|
|
25
|
-
}: Props) => {
|
|
26
|
-
interface EmbeddedNotifVariant {
|
|
27
|
-
color: string;
|
|
28
|
-
icon: IconDefinition;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const variantNotification: Record<string, EmbeddedNotifVariant> = {
|
|
32
|
-
warning: {
|
|
33
|
-
color: 'orangeWarning',
|
|
34
|
-
icon: faCircleExclamation
|
|
35
|
-
},
|
|
36
|
-
error: {
|
|
37
|
-
color: 'redError',
|
|
38
|
-
icon: faCircleXmark
|
|
39
|
-
},
|
|
40
|
-
success: {
|
|
41
|
-
color: 'greenSuccess',
|
|
42
|
-
icon: faCircleCheck
|
|
43
|
-
},
|
|
44
|
-
infos: {
|
|
45
|
-
color: 'blueInfo',
|
|
46
|
-
icon: faCircleInfo
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
return (
|
|
51
|
-
<Box
|
|
52
|
-
border="1px solid"
|
|
53
|
-
borderColor={variantNotification[variant].color}
|
|
54
|
-
mt="4px"
|
|
55
|
-
p="4px"
|
|
56
|
-
borderRadius="5px"
|
|
57
|
-
{...props}
|
|
58
|
-
>
|
|
59
|
-
<Box display="flex" alignItems="center" pb="2px">
|
|
60
|
-
<Box sx={{ pl: '12px', pr: '16px', display: 'flex' }}>
|
|
61
|
-
<Icon
|
|
62
|
-
icon={variantNotification[variant].icon}
|
|
63
|
-
color={variantNotification[variant].color}
|
|
64
|
-
/>
|
|
65
|
-
</Box>
|
|
66
|
-
<Box>
|
|
67
|
-
<Box>
|
|
68
|
-
<Text
|
|
69
|
-
align="left"
|
|
70
|
-
variant="body1Bold"
|
|
71
|
-
color={variantNotification[variant].color}
|
|
72
|
-
display="inline-block"
|
|
73
|
-
>
|
|
74
|
-
{title}
|
|
75
|
-
</Text>
|
|
76
|
-
</Box>
|
|
77
|
-
{text && (
|
|
78
|
-
<Box>
|
|
79
|
-
<Text
|
|
80
|
-
align="left"
|
|
81
|
-
variant="body1Regular"
|
|
82
|
-
color="greyDark"
|
|
83
|
-
display="inline-block"
|
|
84
|
-
>
|
|
85
|
-
{text}
|
|
86
|
-
</Text>
|
|
87
|
-
</Box>
|
|
88
|
-
)}
|
|
89
|
-
</Box>
|
|
90
|
-
</Box>
|
|
91
|
-
</Box>
|
|
92
|
-
);
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
export default EmbeddedNotification;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './EmbeddedNotification';
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import React, { useEffect, useState } from 'react';
|
|
2
|
-
|
|
3
|
-
import CheckboxMUI, { CheckboxProps } from '@mui/material/Checkbox';
|
|
4
|
-
import FormControl from '@mui/material/FormControl';
|
|
5
|
-
import FormControlLabel from '@mui/material/FormControlLabel';
|
|
6
|
-
import Typography from '@mui/material/Typography';
|
|
7
|
-
import Box from '@mui/system/Box';
|
|
8
|
-
|
|
9
|
-
interface Props {
|
|
10
|
-
name: string;
|
|
11
|
-
value: boolean;
|
|
12
|
-
label: string;
|
|
13
|
-
onChange?: (
|
|
14
|
-
field: string,
|
|
15
|
-
value: any,
|
|
16
|
-
shouldValidate?: boolean | undefined
|
|
17
|
-
) => void;
|
|
18
|
-
error?: string;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const Checkbox = ({
|
|
22
|
-
name,
|
|
23
|
-
value,
|
|
24
|
-
error,
|
|
25
|
-
label,
|
|
26
|
-
onChange,
|
|
27
|
-
...props
|
|
28
|
-
}: CheckboxProps & Props): JSX.Element => {
|
|
29
|
-
const [internalValue, setInternalValue] = useState(value);
|
|
30
|
-
|
|
31
|
-
useEffect(() => {
|
|
32
|
-
if (value !== internalValue) {
|
|
33
|
-
setInternalValue(value);
|
|
34
|
-
}
|
|
35
|
-
}, [value]);
|
|
36
|
-
|
|
37
|
-
return (
|
|
38
|
-
<FormControl fullWidth>
|
|
39
|
-
<FormControlLabel
|
|
40
|
-
control={
|
|
41
|
-
<Box>
|
|
42
|
-
<CheckboxMUI
|
|
43
|
-
name={name}
|
|
44
|
-
sx={{ marginTop: '-2px' }}
|
|
45
|
-
checked={internalValue}
|
|
46
|
-
color="primary"
|
|
47
|
-
onChange={(e) => {
|
|
48
|
-
setInternalValue(e.target.checked);
|
|
49
|
-
onChange && onChange(name, e.target.checked, true);
|
|
50
|
-
}}
|
|
51
|
-
{...props}
|
|
52
|
-
/>
|
|
53
|
-
</Box>
|
|
54
|
-
}
|
|
55
|
-
label={
|
|
56
|
-
<Typography
|
|
57
|
-
component="span"
|
|
58
|
-
sx={{
|
|
59
|
-
fontSize: '14px',
|
|
60
|
-
marginLeft: '-3px',
|
|
61
|
-
marginTop: '2px',
|
|
62
|
-
fontWeight: 400,
|
|
63
|
-
color: error ? '#B80025' : '#000'
|
|
64
|
-
}}
|
|
65
|
-
>
|
|
66
|
-
{label}
|
|
67
|
-
</Typography>
|
|
68
|
-
}
|
|
69
|
-
/>
|
|
70
|
-
{error && (
|
|
71
|
-
<Typography
|
|
72
|
-
sx={{
|
|
73
|
-
marginTop: -0.5,
|
|
74
|
-
color: '#B80025',
|
|
75
|
-
fontWeight: 400,
|
|
76
|
-
fontSize: '10px'
|
|
77
|
-
}}
|
|
78
|
-
>
|
|
79
|
-
{error}
|
|
80
|
-
</Typography>
|
|
81
|
-
)}
|
|
82
|
-
</FormControl>
|
|
83
|
-
);
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
export default Checkbox;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './Checkbox';
|
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
import React, { useMemo, useState } from 'react';
|
|
2
|
-
import { FormHelperText, InputLabel, MenuItem } from '@mui/material';
|
|
3
|
-
import Box from '@mui/material/Box';
|
|
4
|
-
import FormControl from '@mui/material/FormControl';
|
|
5
|
-
import MuiSelect, {
|
|
6
|
-
SelectChangeEvent,
|
|
7
|
-
SelectProps
|
|
8
|
-
} from '@mui/material/Select';
|
|
9
|
-
import {
|
|
10
|
-
faChevronDown,
|
|
11
|
-
faCheck,
|
|
12
|
-
faTimesCircle
|
|
13
|
-
} from '@fortawesome/pro-solid-svg-icons';
|
|
14
|
-
import Icon from '../../Icon';
|
|
15
|
-
import Chip from '../../Chip/Chip';
|
|
16
|
-
|
|
17
|
-
interface Props<T>
|
|
18
|
-
extends Omit<
|
|
19
|
-
SelectProps<T[]>,
|
|
20
|
-
'value' | 'onChange' | 'defaultValue' | 'color'
|
|
21
|
-
> {
|
|
22
|
-
label: string;
|
|
23
|
-
options: T[];
|
|
24
|
-
helperText?: string;
|
|
25
|
-
color?: 'success';
|
|
26
|
-
getOptionLabel: (option: T) => string;
|
|
27
|
-
onChange: (value: T[]) => void;
|
|
28
|
-
defaultValue?: T[];
|
|
29
|
-
width?: number;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const MultiSelect = <T extends {}>({
|
|
33
|
-
label,
|
|
34
|
-
options,
|
|
35
|
-
color,
|
|
36
|
-
error,
|
|
37
|
-
placeholder,
|
|
38
|
-
width = 200,
|
|
39
|
-
defaultValue = [],
|
|
40
|
-
getOptionLabel,
|
|
41
|
-
helperText,
|
|
42
|
-
onChange,
|
|
43
|
-
onBlur,
|
|
44
|
-
...props
|
|
45
|
-
}: Props<T>) => {
|
|
46
|
-
const [values, setValues] = useState(defaultValue);
|
|
47
|
-
|
|
48
|
-
const handleChange = (event: SelectChangeEvent<typeof options>) => {
|
|
49
|
-
const newValue = event.target.value as T[];
|
|
50
|
-
onChange(newValue);
|
|
51
|
-
setValues(newValue);
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
const handleDeleteChip = (chipValue: T) => {
|
|
55
|
-
const newValue = values?.filter((val) => val !== chipValue);
|
|
56
|
-
setValues(newValue);
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
const getFormControlClassName = useMemo(() => {
|
|
60
|
-
const classNames: string[] = ['DsSelect'];
|
|
61
|
-
if (props.disabled) classNames.push('Mui-disabled');
|
|
62
|
-
if (values?.length > 0) classNames.push('Mui-filled');
|
|
63
|
-
|
|
64
|
-
return classNames;
|
|
65
|
-
}, [values, props.disabled]);
|
|
66
|
-
|
|
67
|
-
const getInputLabelClassName = useMemo(() => {
|
|
68
|
-
const classNames: string[] = [];
|
|
69
|
-
if (error) classNames.push('Mui-error');
|
|
70
|
-
if (props.disabled) classNames.push('Mui-disabled');
|
|
71
|
-
|
|
72
|
-
return classNames;
|
|
73
|
-
}, [error, props.disabled]);
|
|
74
|
-
|
|
75
|
-
return (
|
|
76
|
-
<Box sx={{ width }}>
|
|
77
|
-
<FormControl
|
|
78
|
-
id={label === placeholder ? 'select-mui' : 'select-ds'}
|
|
79
|
-
fullWidth
|
|
80
|
-
color={color}
|
|
81
|
-
className={getFormControlClassName.join(' ')}
|
|
82
|
-
sx={{
|
|
83
|
-
'.MuiOutlinedInput-input': {
|
|
84
|
-
marginTop: values?.length > 0 ? '-4px' : '2px'
|
|
85
|
-
}
|
|
86
|
-
}}
|
|
87
|
-
>
|
|
88
|
-
<InputLabel className={getInputLabelClassName.join(' ')}>
|
|
89
|
-
{label}
|
|
90
|
-
</InputLabel>
|
|
91
|
-
<MuiSelect
|
|
92
|
-
sx={{
|
|
93
|
-
color: color + '! important',
|
|
94
|
-
'& .MuiSelect-select .notranslate::after': placeholder
|
|
95
|
-
? {
|
|
96
|
-
content: `"${placeholder}"`,
|
|
97
|
-
opacity:
|
|
98
|
-
label === placeholder ? '0 !important' : '1 !important'
|
|
99
|
-
}
|
|
100
|
-
: {}
|
|
101
|
-
}}
|
|
102
|
-
multiple
|
|
103
|
-
label={label}
|
|
104
|
-
placeholder={label === placeholder ? '' : placeholder}
|
|
105
|
-
notched={
|
|
106
|
-
/* eslint-disable-next-line no-undefined */
|
|
107
|
-
label === placeholder ? undefined : true
|
|
108
|
-
}
|
|
109
|
-
value={values}
|
|
110
|
-
error={!!error}
|
|
111
|
-
onChange={handleChange}
|
|
112
|
-
onBlur={onBlur}
|
|
113
|
-
renderValue={(selected) => (
|
|
114
|
-
<Box sx={{ display: 'flex', flexWrap: 'nowrap', gap: 0.5 }}>
|
|
115
|
-
{selected?.map((selectedOption: T, i) => (
|
|
116
|
-
<Chip
|
|
117
|
-
key={i}
|
|
118
|
-
disabled={props.disabled}
|
|
119
|
-
variant="filled"
|
|
120
|
-
color="default"
|
|
121
|
-
label={getOptionLabel(selectedOption)}
|
|
122
|
-
suffixIcon={faTimesCircle}
|
|
123
|
-
suffixAction={() =>
|
|
124
|
-
!props.disabled && handleDeleteChip(selectedOption)
|
|
125
|
-
}
|
|
126
|
-
onMouseDown={(event) => {
|
|
127
|
-
event.stopPropagation();
|
|
128
|
-
}}
|
|
129
|
-
/>
|
|
130
|
-
))}
|
|
131
|
-
</Box>
|
|
132
|
-
)}
|
|
133
|
-
IconComponent={({ className }) => (
|
|
134
|
-
<Icon
|
|
135
|
-
className={
|
|
136
|
-
props.disabled ? 'Mui-disabled SelectIcon' : 'SelectIcon'
|
|
137
|
-
}
|
|
138
|
-
icon={color === 'success' ? faCheck : faChevronDown}
|
|
139
|
-
size={color === 'success' ? 'md' : 'sm'}
|
|
140
|
-
sx={{
|
|
141
|
-
marginRight: '12px',
|
|
142
|
-
marginTop: color === 'success' ? '2px' : '0px',
|
|
143
|
-
transform:
|
|
144
|
-
className.toString().includes('iconOpen') &&
|
|
145
|
-
color !== 'success'
|
|
146
|
-
? 'rotate(180deg)'
|
|
147
|
-
: 'none'
|
|
148
|
-
}}
|
|
149
|
-
/>
|
|
150
|
-
)}
|
|
151
|
-
MenuProps={{
|
|
152
|
-
PaperProps: {
|
|
153
|
-
style: {
|
|
154
|
-
width
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}}
|
|
158
|
-
{...props}
|
|
159
|
-
>
|
|
160
|
-
{options?.map((option, i) => (
|
|
161
|
-
<MenuItem
|
|
162
|
-
key={i}
|
|
163
|
-
value={option as any}
|
|
164
|
-
sx={{
|
|
165
|
-
fontWeight: values.indexOf(option) === -1 ? 400 : 500,
|
|
166
|
-
backgroundColor:
|
|
167
|
-
values.indexOf(option) === -1 ? '#ffffff' : '#D3E4F0'
|
|
168
|
-
}}
|
|
169
|
-
>
|
|
170
|
-
{getOptionLabel(option)}
|
|
171
|
-
</MenuItem>
|
|
172
|
-
))}
|
|
173
|
-
</MuiSelect>
|
|
174
|
-
{(error || helperText) && (
|
|
175
|
-
<FormHelperText component="span" className={error ? 'Mui-error' : ''}>
|
|
176
|
-
{error || helperText}
|
|
177
|
-
</FormHelperText>
|
|
178
|
-
)}
|
|
179
|
-
</FormControl>
|
|
180
|
-
</Box>
|
|
181
|
-
);
|
|
182
|
-
};
|
|
183
|
-
|
|
184
|
-
export default MultiSelect;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './MultiSelect';
|