@lunit/oui 1.0.1-alpha.14 → 1.0.1-alpha.2
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/components/MuiCssBaseline.js +0 -17
- package/dist/index.js +0 -1
- package/dist/types/index.d.ts +0 -1
- package/package.json +7 -20
- package/src/assets/ic-bell-noti-outlined-20px.tsx +21 -0
- package/src/assets/ic-close-large-outlined-20px.tsx +17 -0
- package/src/assets/ic-close-small-outlined-20px.tsx +17 -0
- package/src/assets/ic-download-pdf-outlined-20px.tsx +18 -0
- package/src/assets/ic-ellipse-outlined-20px.tsx +17 -0
- package/src/assets/ic-filter-noti-outlined-20px.tsx +21 -0
- package/src/assets/ic-hide-large-outlined-20px.tsx +13 -0
- package/src/assets/ic-hide-small-outlined-20px.tsx +17 -0
- package/src/assets/ic-information-large-outlined-20px.tsx +17 -0
- package/src/assets/ic-information-small-outlined-20px.tsx +17 -0
- package/src/assets/ic-manufacturer-outlined-20px.tsx +19 -0
- package/src/assets/ic-rectangle-outlined-20px.tsx +17 -0
- package/src/assets/ic-refresh-left-outlined-20px.tsx +17 -0
- package/src/assets/ic-refresh-right-outlined-20px.tsx +13 -0
- package/src/assets/ic-show-large-outlined-20px.tsx +17 -0
- package/src/assets/ic-show-small-outlined-20px.tsx +17 -0
- package/src/assets/ic_bell_noti=outlined_20px.svg +5 -0
- package/src/assets/ic_close_large=outlined_20px.svg +4 -0
- package/src/assets/ic_close_small=outlined_20px.svg +4 -0
- package/src/assets/ic_download_pdf=outlined_20px.svg +7 -0
- package/src/assets/ic_ellipse=outlined_20px.svg +4 -0
- package/src/assets/ic_filter_noti=outlined_20px.svg +5 -0
- package/src/assets/ic_hide_large=outlined_20px.svg +4 -0
- package/src/assets/ic_hide_small=outlined_20px.svg +4 -0
- package/src/assets/ic_information_large=outlined_20px.svg +4 -0
- package/src/assets/ic_information_small=outlined_20px.svg +4 -0
- package/src/assets/ic_manufacturer=outlined_20px.svg +3 -0
- package/src/assets/ic_rectangle=outlined_20px.svg +4 -0
- package/src/assets/ic_refresh_left=outlined_20px.svg +4 -0
- package/src/assets/ic_refresh_right=outlined_20px.svg +4 -0
- package/src/assets/ic_show_large=outlined_20px.svg +4 -0
- package/src/assets/ic_show_small=outlined_20px.svg +4 -0
- package/src/assets/index.ts +16 -0
- package/src/components/Alert/Alert.styled.ts +44 -0
- package/src/components/Alert/Alert.tsx +39 -0
- package/src/components/Alert/Alert.types.ts +5 -0
- package/src/components/Alert/Alert.utils.tsx +43 -0
- package/src/components/Alert/index.ts +5 -0
- package/src/components/BaseTextField/BaseTextField.styled.ts +110 -0
- package/src/components/BaseTextField/BaseTextField.types.ts +25 -0
- package/src/components/BaseTextField/BaseTextField.utils.ts +10 -0
- package/src/components/Button/BaseButton.tsx +19 -0
- package/src/components/Button/Button.tsx +117 -0
- package/src/components/Button/Button.types.ts +36 -0
- package/src/components/Button/Button.utils.ts +13 -0
- package/src/components/Button/index.ts +6 -0
- package/src/components/Button/styleds/BaseButton.styled.ts +57 -0
- package/src/components/Button/styleds/ContainedButton.styled.ts +123 -0
- package/src/components/Button/styleds/GhostButton.styled.ts +139 -0
- package/src/components/Button/styleds/IconButton.styled.ts +25 -0
- package/src/components/Button/styleds/OutlinedButton.styled.ts +144 -0
- package/src/components/Card/Card.styled.tsx +18 -0
- package/src/components/Card/Card.tsx +18 -0
- package/src/components/Card/Card.types.ts +10 -0
- package/src/components/Card/index.ts +5 -0
- package/src/components/Checkbox/Checkbox.styled.tsx +27 -0
- package/src/components/Checkbox/Checkbox.tsx +64 -0
- package/src/components/Checkbox/Checkbox.types.ts +16 -0
- package/src/components/Checkbox/Checkbox.utils.tsx +42 -0
- package/src/components/Checkbox/index.ts +5 -0
- package/src/components/Chip/Chip.styled.ts +120 -0
- package/src/components/Chip/Chip.tsx +33 -0
- package/src/components/Chip/Chip.types.ts +18 -0
- package/src/components/Chip/Chip.utils.tsx +50 -0
- package/src/components/Chip/index.ts +4 -0
- package/src/components/DataTable/DataTable.styled.ts +66 -0
- package/src/components/DataTable/DataTable.tsx +29 -0
- package/src/components/DataTable/index.ts +1 -0
- package/src/components/DatePicker/DatePicker.styled.ts +19 -0
- package/src/components/DatePicker/DatePicker.tsx +194 -0
- package/src/components/DatePicker/DatePicker.types.ts +8 -0
- package/src/components/DatePicker/index.ts +4 -0
- package/src/components/Dialog/Dialog.styled.ts +87 -0
- package/src/components/Dialog/Dialog.tsx +111 -0
- package/src/components/Dialog/Dialog.types.ts +19 -0
- package/src/components/Dialog/index.ts +5 -0
- package/src/components/Divider/Divider.styled.ts +24 -0
- package/src/components/Divider/Divider.tsx +13 -0
- package/src/components/Divider/Divider.types.ts +7 -0
- package/src/components/Divider/index.ts +5 -0
- package/src/components/Dropdown/Dropdown.styled.tsx +127 -0
- package/src/components/Dropdown/Dropdown.tsx +116 -0
- package/src/components/Dropdown/Dropdown.types.ts +31 -0
- package/src/components/Dropdown/Dropdown.utils.ts +13 -0
- package/src/components/Dropdown/DropdownItem.styled.tsx +66 -0
- package/src/components/Dropdown/DropdownItem.tsx +45 -0
- package/src/components/Dropdown/DropdownItem.types.ts +14 -0
- package/src/components/Dropdown/DropdownItem.utils.ts +14 -0
- package/src/components/Dropdown/DropdownSubtitle.styled.ts +13 -0
- package/src/components/Dropdown/DropdownSubtitle.tsx +9 -0
- package/src/components/Dropdown/DropdownSubtitle.types.ts +6 -0
- package/src/components/Dropdown/IconDropdown.styled.tsx +82 -0
- package/src/components/Dropdown/IconDropdown.tsx +56 -0
- package/src/components/Dropdown/IconDropdown.types.ts +22 -0
- package/src/components/Dropdown/index.ts +22 -0
- package/src/components/FileDnDZone/FileDnDZone.styled.ts +43 -0
- package/src/components/FileDnDZone/FileDnDZone.tsx +81 -0
- package/src/components/FileDnDZone/FileDnDZone.types.ts +14 -0
- package/src/components/FileDnDZone/FileDnDZone.utils.ts +3 -0
- package/src/components/FileDnDZone/index.ts +5 -0
- package/src/components/List/List.styled.ts +31 -0
- package/src/components/List/List.tsx +71 -0
- package/src/components/List/List.types.ts +24 -0
- package/src/components/List/List.utils.ts +14 -0
- package/src/components/List/ListItem.styled.tsx +61 -0
- package/src/components/List/ListItem.tsx +66 -0
- package/src/components/List/ListItem.types.ts +40 -0
- package/src/components/List/ListItemCaption.styled.tsx +7 -0
- package/src/components/List/ListItemCaption.tsx +18 -0
- package/src/components/List/ListItemCaption.types.ts +2 -0
- package/src/components/List/index.ts +8 -0
- package/src/components/LoadingIndicator/LoadingIndicator.styled.tsx +40 -0
- package/src/components/LoadingIndicator/LoadingIndicator.tsx +44 -0
- package/src/components/LoadingIndicator/LoadingIndicator.types.ts +7 -0
- package/src/components/LoadingIndicator/assets/DnaLoadingAnimation.json +769 -0
- package/src/components/LoadingIndicator/assets/DotLoadingAnimation.json +426 -0
- package/src/components/LoadingIndicator/index.ts +5 -0
- package/src/components/Menu/Menu.styled.tsx +42 -0
- package/src/components/Menu/Menu.tsx +28 -0
- package/src/components/Menu/Menu.types.ts +18 -0
- package/src/components/Menu/MenuItem.styled.ts +62 -0
- package/src/components/Menu/MenuItem.tsx +45 -0
- package/src/components/Menu/MenuItem.types.ts +14 -0
- package/src/components/Menu/index.ts +5 -0
- package/src/components/MuiCssBaseline.ts +78 -0
- package/src/components/MuiInputBase.ts +25 -0
- package/src/components/MuiOutlinedInput.ts +57 -0
- package/src/components/MuiTextField.ts +17 -0
- package/src/components/Pagination/Pagination.styled.tsx +71 -0
- package/src/components/Pagination/Pagination.tsx +182 -0
- package/src/components/Pagination/Pagination.types.ts +39 -0
- package/src/components/Pagination/index.ts +2 -0
- package/src/components/ProductLabel/ProductLabel.styled.ts +61 -0
- package/src/components/ProductLabel/ProductLabel.tsx +57 -0
- package/src/components/ProductLabel/ProductLabel.types.ts +10 -0
- package/src/components/ProductLabel/index.ts +5 -0
- package/src/components/Progress/CircularProgress.styled.ts +10 -0
- package/src/components/Progress/CircularProgress.tsx +15 -0
- package/src/components/Progress/CircularProgress.types.ts +6 -0
- package/src/components/Progress/LinearProgress.styled.ts +15 -0
- package/src/components/Progress/LinearProgress.tsx +16 -0
- package/src/components/Progress/LinearProgress.types.ts +7 -0
- package/src/components/Progress/index.ts +4 -0
- package/src/components/Radio/Radio.styled.ts +35 -0
- package/src/components/Radio/Radio.tsx +60 -0
- package/src/components/Radio/Radio.types.ts +15 -0
- package/src/components/Radio/RadioGroup.styled.ts +6 -0
- package/src/components/Radio/RadioGroup.tsx +23 -0
- package/src/components/Radio/RadioGroup.types.ts +10 -0
- package/src/components/Radio/index.ts +7 -0
- package/src/components/Stepper/Stepper.styled.ts +38 -0
- package/src/components/Stepper/Stepper.tsx +24 -0
- package/src/components/Stepper/Stepper.types.ts +13 -0
- package/src/components/Stepper/index.ts +5 -0
- package/src/components/TabbedPanel/TabbedPanel.styled.ts +129 -0
- package/src/components/TabbedPanel/TabbedPanel.tsx +70 -0
- package/src/components/TabbedPanel/TabbedPanel.types.ts +36 -0
- package/src/components/TabbedPanel/TabbedPanel.utils.ts +21 -0
- package/src/components/TabbedPanel/index.ts +5 -0
- package/src/components/TextField/TextArea.styled.tsx +36 -0
- package/src/components/TextField/TextArea.tsx +35 -0
- package/src/components/TextField/TextArea.types.ts +28 -0
- package/src/components/TextField/TextInput.styled.tsx +115 -0
- package/src/components/TextField/TextInput.tsx +27 -0
- package/src/components/TextField/TextInput.types.ts +46 -0
- package/src/components/TextField/TextInput.utils.ts +7 -0
- package/src/components/TextField/components/Buttons.tsx +26 -0
- package/src/components/TextField/components/NormalTextInput.tsx +95 -0
- package/src/components/TextField/components/PasswordInput.tsx +92 -0
- package/src/components/TextField/index.ts +7 -0
- package/src/components/Tooltip/Tooltip.styled.tsx +36 -0
- package/src/components/Tooltip/Tooltip.tsx +58 -0
- package/src/components/Tooltip/Tooltip.types.ts +24 -0
- package/src/components/Tooltip/Tooltip.utils.ts +46 -0
- package/src/components/Tooltip/index.ts +5 -0
- package/src/components/UploadManager/UploadManager.styled.ts +49 -0
- package/src/components/UploadManager/UploadManager.tsx +271 -0
- package/src/components/UploadManager/UploadManager.types.ts +16 -0
- package/src/components/UploadManager/index.ts +5 -0
- package/src/components/index.ts +23 -0
- package/src/foundations/index.ts +4 -0
- package/src/foundations/palette.ts +418 -0
- package/src/foundations/spacing.ts +5 -0
- package/src/foundations/styles.ts +9 -0
- package/src/foundations/typography.ts +492 -0
- package/src/icons/BellNoti/index.tsx +28 -0
- package/src/icons/CloseLarge/index.tsx +28 -0
- package/src/icons/CloseSmall/index.tsx +28 -0
- package/src/icons/DownloadPdf/index.tsx +28 -0
- package/src/icons/Ellipse/index.tsx +28 -0
- package/src/icons/FilterNoti/index.tsx +28 -0
- package/src/icons/HideLarge/index.tsx +28 -0
- package/src/icons/HideSmall/index.tsx +28 -0
- package/src/icons/InformationLarge/index.tsx +28 -0
- package/src/icons/InformationSmall/index.tsx +28 -0
- package/src/icons/Manufacturer/index.tsx +28 -0
- package/src/icons/Rectangle/index.tsx +28 -0
- package/src/icons/RefreshLeft/index.tsx +28 -0
- package/src/icons/RefreshRight/index.tsx +28 -0
- package/src/icons/ShowLarge/index.tsx +28 -0
- package/src/icons/ShowSmall/index.tsx +28 -0
- package/src/icons/index.ts +180 -0
- package/src/index.ts +4 -0
- package/src/react-app-env.d.ts +71 -0
- package/src/reportWebVitals.ts +15 -0
- package/src/setupTests.ts +5 -0
- package/src/systems/drawer.ts +27 -0
- package/src/systems/index.ts +7 -0
- package/src/theme.ts +22 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { AlertColor } from '@mui/material';
|
|
3
|
+
import { Success, Error, Information } from '../../icons';
|
|
4
|
+
import theme from '../../theme';
|
|
5
|
+
|
|
6
|
+
export const getIcons = (severity: AlertColor | undefined) => {
|
|
7
|
+
switch (severity) {
|
|
8
|
+
case 'info':
|
|
9
|
+
return <Information />;
|
|
10
|
+
case 'success':
|
|
11
|
+
return <Success />;
|
|
12
|
+
case 'error':
|
|
13
|
+
return <Error />;
|
|
14
|
+
default:
|
|
15
|
+
return <Error />;
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const getBackgroundColor = (severity: AlertColor | undefined) => {
|
|
20
|
+
switch (severity) {
|
|
21
|
+
case 'info':
|
|
22
|
+
return theme.palette.alert.InfoBG;
|
|
23
|
+
case 'success':
|
|
24
|
+
return theme.palette.alert.SuccessBG;
|
|
25
|
+
case 'error':
|
|
26
|
+
return theme.palette.alert.ErrorBG;
|
|
27
|
+
default:
|
|
28
|
+
return theme.palette.alert.WarningBG;
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const getAccentColor = (severity: AlertColor | undefined) => {
|
|
33
|
+
switch (severity) {
|
|
34
|
+
case 'info':
|
|
35
|
+
return theme.palette.blue[25];
|
|
36
|
+
case 'success':
|
|
37
|
+
return theme.palette.lunitTeal[40];
|
|
38
|
+
case 'error':
|
|
39
|
+
return theme.palette.red[5];
|
|
40
|
+
default:
|
|
41
|
+
return theme.palette.yellow[20];
|
|
42
|
+
}
|
|
43
|
+
};
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
// This file facilitates style sharing between text input and text area
|
|
2
|
+
import { Box, Theme, Typography } from '@mui/material';
|
|
3
|
+
import { styled } from '@mui/material/styles';
|
|
4
|
+
import type { BaseTextFieldContainerProps, HelperMsgProps } from './BaseTextField.types';
|
|
5
|
+
import { formatCSSSize } from './BaseTextField.utils';
|
|
6
|
+
|
|
7
|
+
const baseTextFieldStyle = (theme: Theme) => {
|
|
8
|
+
return {
|
|
9
|
+
backgroundColor: theme.palette.neutralGrey[75],
|
|
10
|
+
borderRadius: '8px',
|
|
11
|
+
border: '1px solid',
|
|
12
|
+
borderColor: 'transparent',
|
|
13
|
+
color: theme.palette.neutralGrey[5],
|
|
14
|
+
fontWeight: '400',
|
|
15
|
+
fontSize: '14px',
|
|
16
|
+
fontFamily:
|
|
17
|
+
'Pretendard,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"',
|
|
18
|
+
lineHeight: '20px',
|
|
19
|
+
padding: '7px 16px',
|
|
20
|
+
|
|
21
|
+
'&::placeholder': {
|
|
22
|
+
color: theme.palette.neutralGrey[45],
|
|
23
|
+
},
|
|
24
|
+
'&:focus': {
|
|
25
|
+
outline: 'none',
|
|
26
|
+
border: '1px solid',
|
|
27
|
+
borderColor: theme.palette.lunitTeal[10],
|
|
28
|
+
},
|
|
29
|
+
'&:hover': {
|
|
30
|
+
borderColor: theme.palette.neutralGrey[45],
|
|
31
|
+
},
|
|
32
|
+
'&:disabled': {
|
|
33
|
+
opacity: '0.8',
|
|
34
|
+
pointerEvents: 'none',
|
|
35
|
+
},
|
|
36
|
+
'&:read-only': {
|
|
37
|
+
border: `1px solid ${theme.palette.neutralGrey[70]}`,
|
|
38
|
+
backgroundColor: 'transparent',
|
|
39
|
+
color: theme.palette.neutralGrey[45],
|
|
40
|
+
pointerEvents: 'none',
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const baseTextFieldErrorStyle = (theme: Theme) => {
|
|
46
|
+
return {
|
|
47
|
+
borderColor: theme.palette.red[5],
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const baseTextFieldMsgStyle = (theme: Theme) => {
|
|
52
|
+
return {
|
|
53
|
+
width: '312px',
|
|
54
|
+
maxWidth: '312px',
|
|
55
|
+
minHeight: '20px',
|
|
56
|
+
color: theme.palette.neutralGrey[45],
|
|
57
|
+
padding: '4px',
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const baseTextFieldMsgErrorStyle = (theme: Theme) => {
|
|
62
|
+
return {
|
|
63
|
+
color: theme.palette.red[5],
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const BaseTextFieldBox = styled(Box, {
|
|
68
|
+
shouldForwardProp: (prop) => prop !== 'width',
|
|
69
|
+
})<BaseTextFieldContainerProps>(({ width }) => {
|
|
70
|
+
return {
|
|
71
|
+
width: formatCSSSize(width),
|
|
72
|
+
minWidth: formatCSSSize(width) ? 'unset' : '208px',
|
|
73
|
+
};
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
const BaseTextFieldContainer = styled(Box, {
|
|
77
|
+
shouldForwardProp: (prop) => !['width'].includes(prop.toString()),
|
|
78
|
+
})<BaseTextFieldContainerProps>(({ width }) => {
|
|
79
|
+
return {
|
|
80
|
+
position: 'relative',
|
|
81
|
+
display: 'flex',
|
|
82
|
+
flexDirection: 'column',
|
|
83
|
+
width: formatCSSSize(width),
|
|
84
|
+
minWidth: formatCSSSize(width) ? 'unset' : '208px',
|
|
85
|
+
};
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
const InputMsg = styled(Typography, {
|
|
89
|
+
shouldForwardProp: (prop) => prop !== 'error',
|
|
90
|
+
})<HelperMsgProps>(({ theme, error }) => {
|
|
91
|
+
let resultStyle = baseTextFieldMsgStyle(theme);
|
|
92
|
+
|
|
93
|
+
if (error) {
|
|
94
|
+
resultStyle = {
|
|
95
|
+
...resultStyle,
|
|
96
|
+
...baseTextFieldMsgErrorStyle(theme),
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return resultStyle;
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
const styles = {
|
|
104
|
+
baseTextFieldStyle,
|
|
105
|
+
baseTextFieldErrorStyle,
|
|
106
|
+
baseTextFieldMsgStyle,
|
|
107
|
+
baseTextFieldMsgErrorStyle,
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
export { styles, BaseTextFieldContainer, BaseTextFieldBox, InputMsg };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Props for all text fields
|
|
2
|
+
|
|
3
|
+
import type { BoxProps } from '@mui/material';
|
|
4
|
+
|
|
5
|
+
// It redefines certain intrinsic properties because of MUI interference
|
|
6
|
+
interface BaseTextFieldContainerProps {
|
|
7
|
+
width?: string | number;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface RootTextFieldProps extends BaseTextFieldContainerProps {
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
readOnly?: boolean;
|
|
13
|
+
value?: string;
|
|
14
|
+
defaultValue?: string;
|
|
15
|
+
error?: boolean;
|
|
16
|
+
BoxProps?: BoxProps;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Props for helper message specifically
|
|
20
|
+
interface HelperMsgProps {
|
|
21
|
+
error?: boolean;
|
|
22
|
+
helperMsg?: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export { RootTextFieldProps, BaseTextFieldContainerProps, HelperMsgProps };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { BaseButtonProps } from './Button.types';
|
|
3
|
+
import { BaseContainedButton } from './styleds/ContainedButton.styled';
|
|
4
|
+
import { BaseGhostButton } from './styleds/GhostButton.styled';
|
|
5
|
+
import { BaseOutlinedButton } from './styleds/OutlinedButton.styled';
|
|
6
|
+
|
|
7
|
+
const BaseButton = ({ variant, ...otherProps }: BaseButtonProps) => {
|
|
8
|
+
if (variant === 'ghost') {
|
|
9
|
+
return <BaseGhostButton {...otherProps} />;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
if (variant === 'outlined') {
|
|
13
|
+
return <BaseOutlinedButton {...otherProps} />;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return <BaseContainedButton {...otherProps} />;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export default BaseButton;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Box } from '@mui/system';
|
|
3
|
+
import BaseButton from './BaseButton';
|
|
4
|
+
import { CircularProgress } from '../Progress';
|
|
5
|
+
import theme from '../../theme';
|
|
6
|
+
|
|
7
|
+
import { isIconButton } from './Button.utils';
|
|
8
|
+
import type { ButtonProps } from './Button.types';
|
|
9
|
+
|
|
10
|
+
function Button(props: ButtonProps) {
|
|
11
|
+
if (isIconButton(props)) {
|
|
12
|
+
const {
|
|
13
|
+
icon,
|
|
14
|
+
loading,
|
|
15
|
+
onClick,
|
|
16
|
+
disableRipple = true,
|
|
17
|
+
focusOutline = false,
|
|
18
|
+
...otherProps
|
|
19
|
+
} = props;
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<BaseButton
|
|
23
|
+
{...otherProps}
|
|
24
|
+
isIconOnly
|
|
25
|
+
disableRipple={disableRipple}
|
|
26
|
+
focusOutline={focusOutline}
|
|
27
|
+
onClick={
|
|
28
|
+
loading
|
|
29
|
+
? (e) => {
|
|
30
|
+
e.preventDefault();
|
|
31
|
+
}
|
|
32
|
+
: onClick
|
|
33
|
+
}
|
|
34
|
+
>
|
|
35
|
+
{loading ? (
|
|
36
|
+
<CircularProgress
|
|
37
|
+
circleColor={theme.palette.neutralGrey[0]}
|
|
38
|
+
size={20}
|
|
39
|
+
sx={{
|
|
40
|
+
display: 'flex',
|
|
41
|
+
justifyContent: 'center',
|
|
42
|
+
alignItems: 'center',
|
|
43
|
+
}}
|
|
44
|
+
/>
|
|
45
|
+
) : (
|
|
46
|
+
icon
|
|
47
|
+
)}
|
|
48
|
+
</BaseButton>
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const {
|
|
53
|
+
icon,
|
|
54
|
+
label,
|
|
55
|
+
size,
|
|
56
|
+
focusOutline = false,
|
|
57
|
+
disableRipple = true,
|
|
58
|
+
loading,
|
|
59
|
+
onClick,
|
|
60
|
+
...otherProps
|
|
61
|
+
} = props;
|
|
62
|
+
return (
|
|
63
|
+
<BaseButton
|
|
64
|
+
isIconOnly={false}
|
|
65
|
+
variant={otherProps.variant ?? 'contained'}
|
|
66
|
+
disableRipple={disableRipple}
|
|
67
|
+
size={size}
|
|
68
|
+
color={otherProps.color}
|
|
69
|
+
focusOutline={focusOutline}
|
|
70
|
+
onClick={
|
|
71
|
+
loading
|
|
72
|
+
? (e) => {
|
|
73
|
+
e.preventDefault();
|
|
74
|
+
}
|
|
75
|
+
: onClick
|
|
76
|
+
}
|
|
77
|
+
sx={
|
|
78
|
+
loading
|
|
79
|
+
? {
|
|
80
|
+
'&:not(.loadingCircle)': {
|
|
81
|
+
color: 'transparent',
|
|
82
|
+
},
|
|
83
|
+
}
|
|
84
|
+
: {}
|
|
85
|
+
}
|
|
86
|
+
{...otherProps}
|
|
87
|
+
>
|
|
88
|
+
<>
|
|
89
|
+
{icon}
|
|
90
|
+
{label}
|
|
91
|
+
|
|
92
|
+
{loading && (
|
|
93
|
+
<Box
|
|
94
|
+
className="loadingCircle"
|
|
95
|
+
sx={{
|
|
96
|
+
position: 'absolute',
|
|
97
|
+
top: '50%',
|
|
98
|
+
left: '50%',
|
|
99
|
+
transform: 'translate3d(-50%, -50%, 0)',
|
|
100
|
+
}}
|
|
101
|
+
>
|
|
102
|
+
<CircularProgress
|
|
103
|
+
circleColor={theme.palette.neutralGrey[0]}
|
|
104
|
+
size={20}
|
|
105
|
+
sx={{
|
|
106
|
+
display: 'flex',
|
|
107
|
+
justifyContent: 'center',
|
|
108
|
+
alignItems: 'center',
|
|
109
|
+
}}
|
|
110
|
+
/>
|
|
111
|
+
</Box>
|
|
112
|
+
)}
|
|
113
|
+
</>
|
|
114
|
+
</BaseButton>
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
export default Button;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { ButtonProps as MuiButtonProps } from '@mui/material';
|
|
2
|
+
|
|
3
|
+
type ButtonVariant = 'contained' | 'ghost' | 'outlined';
|
|
4
|
+
type ButtonColor = 'primary' | 'secondary' | 'error';
|
|
5
|
+
type ButtonSize = 'small' | 'medium' | 'large';
|
|
6
|
+
|
|
7
|
+
interface BaseButtonProps extends Omit<MuiButtonProps, 'variant' | 'color'> {
|
|
8
|
+
variant?: ButtonVariant;
|
|
9
|
+
color?: ButtonColor;
|
|
10
|
+
size?: ButtonSize;
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
focusOutline?: boolean;
|
|
13
|
+
isIconOnly: boolean;
|
|
14
|
+
loading?: boolean;
|
|
15
|
+
label?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface IconButtonProps extends Omit<BaseButtonProps, 'isIconOnly'> {
|
|
19
|
+
icon: React.ReactNode;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface NormalButtonProps extends Omit<BaseButtonProps, 'isIconOnly'> {
|
|
23
|
+
label: string;
|
|
24
|
+
icon?: React.ReactNode;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
type ButtonProps = IconButtonProps | NormalButtonProps;
|
|
28
|
+
|
|
29
|
+
export type {
|
|
30
|
+
ButtonVariant,
|
|
31
|
+
ButtonColor,
|
|
32
|
+
BaseButtonProps,
|
|
33
|
+
IconButtonProps,
|
|
34
|
+
NormalButtonProps,
|
|
35
|
+
ButtonProps,
|
|
36
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ButtonProps, IconButtonProps, NormalButtonProps } from './Button.types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @param props
|
|
5
|
+
* @returns boolean
|
|
6
|
+
* @description checks for presence of `label` prop to assert between Icon and Normal Button
|
|
7
|
+
*/
|
|
8
|
+
function isIconButton(props: ButtonProps): props is IconButtonProps {
|
|
9
|
+
const p = props as NormalButtonProps;
|
|
10
|
+
return !p.label;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export { isIconButton };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Theme } from '@mui/material';
|
|
2
|
+
import { typography } from '../../../foundations';
|
|
3
|
+
|
|
4
|
+
const baseButtonStyle = (theme: Theme, focusOutline: boolean | undefined) => {
|
|
5
|
+
const mainColor = theme.palette.lunitTeal[40];
|
|
6
|
+
|
|
7
|
+
return {
|
|
8
|
+
alignItems: 'center',
|
|
9
|
+
display: 'flex',
|
|
10
|
+
gap: '4px',
|
|
11
|
+
borderRadius: '8px',
|
|
12
|
+
border: '1px solid transparent',
|
|
13
|
+
textTransform: 'none' as const,
|
|
14
|
+
minWidth: '36px',
|
|
15
|
+
width: 'max-content',
|
|
16
|
+
height: '36px',
|
|
17
|
+
padding: '8px 12px',
|
|
18
|
+
...typography.body4,
|
|
19
|
+
backgroundColor: mainColor,
|
|
20
|
+
color: theme.palette.neutralGrey[97],
|
|
21
|
+
'&:hover': {
|
|
22
|
+
backgroundColor: mainColor,
|
|
23
|
+
opacity: 0.8,
|
|
24
|
+
},
|
|
25
|
+
'&:disabled': {
|
|
26
|
+
color: theme.palette.neutralGrey[97],
|
|
27
|
+
backgroundColor: mainColor,
|
|
28
|
+
opacity: 0.4,
|
|
29
|
+
},
|
|
30
|
+
'&:focus': {
|
|
31
|
+
border: focusOutline ? `1px solid ${theme.palette.lunitTeal[10]}` : '1px solid transparent',
|
|
32
|
+
outline: 'none' as const,
|
|
33
|
+
},
|
|
34
|
+
'&:focus-visible': {
|
|
35
|
+
border: focusOutline ? `1px solid ${theme.palette.lunitTeal[10]}` : '1px solid transparent',
|
|
36
|
+
outline: 'none' as const,
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const baseSmallStyle = {
|
|
42
|
+
height: '28px',
|
|
43
|
+
minWidth: '28px',
|
|
44
|
+
padding: '4px 8px',
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const baseLargeStyle = {
|
|
48
|
+
fontWeight: 600,
|
|
49
|
+
fontSize: '16px',
|
|
50
|
+
lineHeight: '22px',
|
|
51
|
+
// textTransform: 'capitalize', // This causes a type error in BaseOutlinedButton :S
|
|
52
|
+
height: '44px',
|
|
53
|
+
minWidth: '44px',
|
|
54
|
+
padding: '12px',
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export { baseButtonStyle, baseSmallStyle, baseLargeStyle };
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { ButtonBase, styled } from '@mui/material';
|
|
2
|
+
import type { Theme } from '@mui/material';
|
|
3
|
+
import { baseButtonStyle, baseLargeStyle, baseSmallStyle } from './BaseButton.styled';
|
|
4
|
+
import { baseLargeIconStyle, baseMediumIconStyle, baseSmallIconStyle } from './IconButton.styled';
|
|
5
|
+
import type { BaseButtonProps } from '../Button.types';
|
|
6
|
+
|
|
7
|
+
const containedPrimaryStyle = (theme: Theme, focusOutline: boolean | undefined) => {
|
|
8
|
+
return baseButtonStyle(theme, focusOutline);
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const containedSecondaryStyle = (theme: Theme, focusOutline: boolean | undefined) => {
|
|
12
|
+
const mainColor = theme.palette.lunitTeal[40];
|
|
13
|
+
|
|
14
|
+
return {
|
|
15
|
+
backgroundColor: theme.palette.neutralGrey[85],
|
|
16
|
+
color: mainColor,
|
|
17
|
+
'&:hover': {
|
|
18
|
+
color: mainColor,
|
|
19
|
+
backgroundColor: theme.palette.neutralGrey[75],
|
|
20
|
+
opacity: 1,
|
|
21
|
+
},
|
|
22
|
+
'&:disabled': {
|
|
23
|
+
color: mainColor,
|
|
24
|
+
backgroundColor: theme.palette.neutralGrey[85],
|
|
25
|
+
opacity: 0.4,
|
|
26
|
+
},
|
|
27
|
+
'&:focus': {
|
|
28
|
+
outline: 'none' as const,
|
|
29
|
+
border: focusOutline ? `1px solid ${mainColor}` : '1px solid transparent',
|
|
30
|
+
},
|
|
31
|
+
'&:focus-visible': {
|
|
32
|
+
outline: 'none' as const,
|
|
33
|
+
border: focusOutline ? `1px solid ${mainColor}` : '1px solid transparent',
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const containedErrorStyle = (theme: Theme, focusOutline: boolean | undefined) => {
|
|
39
|
+
const mainColor = theme.palette.red[5];
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
backgroundColor: mainColor,
|
|
43
|
+
color: theme.palette.neutralGrey[0],
|
|
44
|
+
'&:hover': {
|
|
45
|
+
backgroundColor: mainColor,
|
|
46
|
+
opacity: 0.8,
|
|
47
|
+
},
|
|
48
|
+
'&:disabled': {
|
|
49
|
+
color: theme.palette.neutralGrey[0],
|
|
50
|
+
backgroundColor: mainColor,
|
|
51
|
+
opacity: 0.4,
|
|
52
|
+
},
|
|
53
|
+
'&:focus': {
|
|
54
|
+
outline: 'none' as const,
|
|
55
|
+
border: focusOutline ? `1px solid ${mainColor}` : '1px solid transparent',
|
|
56
|
+
},
|
|
57
|
+
'&:focus-visible': {
|
|
58
|
+
outline: 'none' as const,
|
|
59
|
+
border: focusOutline ? `1px solid ${mainColor}` : '1px solid transparent',
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const BaseContainedButton = styled(ButtonBase, {
|
|
65
|
+
shouldForwardProp: (prop) =>
|
|
66
|
+
!['color', 'variant', 'size', 'focusOutline', 'isIconOnly'].includes(prop.toString()),
|
|
67
|
+
})<BaseButtonProps>(({ theme, color, size, focusOutline, isIconOnly }) => {
|
|
68
|
+
let resultStyle = containedPrimaryStyle(theme, focusOutline);
|
|
69
|
+
|
|
70
|
+
// Apply icon sizing if icon only
|
|
71
|
+
if (isIconOnly) {
|
|
72
|
+
if (size === 'small') {
|
|
73
|
+
resultStyle = {
|
|
74
|
+
...resultStyle,
|
|
75
|
+
...baseSmallIconStyle,
|
|
76
|
+
};
|
|
77
|
+
} else if (size === 'large') {
|
|
78
|
+
resultStyle = {
|
|
79
|
+
...resultStyle,
|
|
80
|
+
...baseLargeIconStyle,
|
|
81
|
+
};
|
|
82
|
+
} else {
|
|
83
|
+
resultStyle = {
|
|
84
|
+
...resultStyle,
|
|
85
|
+
...baseMediumIconStyle,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
} else {
|
|
89
|
+
// Apply label or icon-label
|
|
90
|
+
if (size === 'small') {
|
|
91
|
+
resultStyle = {
|
|
92
|
+
...resultStyle,
|
|
93
|
+
...baseSmallStyle,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (size === 'large') {
|
|
98
|
+
resultStyle = {
|
|
99
|
+
...resultStyle,
|
|
100
|
+
...baseLargeStyle,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Apply color
|
|
106
|
+
if (color === 'error') {
|
|
107
|
+
resultStyle = {
|
|
108
|
+
...resultStyle,
|
|
109
|
+
...containedErrorStyle(theme, focusOutline),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (color === 'secondary') {
|
|
114
|
+
resultStyle = {
|
|
115
|
+
...resultStyle,
|
|
116
|
+
...containedSecondaryStyle(theme, focusOutline),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return resultStyle;
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
export { containedPrimaryStyle, containedSecondaryStyle, containedErrorStyle, BaseContainedButton };
|