@lunit/oui 1.0.1-alpha.13 → 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.
Files changed (212) hide show
  1. package/dist/index.js +0 -1
  2. package/dist/types/index.d.ts +0 -1
  3. package/package.json +7 -20
  4. package/src/assets/ic-bell-noti-outlined-20px.tsx +21 -0
  5. package/src/assets/ic-close-large-outlined-20px.tsx +17 -0
  6. package/src/assets/ic-close-small-outlined-20px.tsx +17 -0
  7. package/src/assets/ic-download-pdf-outlined-20px.tsx +18 -0
  8. package/src/assets/ic-ellipse-outlined-20px.tsx +17 -0
  9. package/src/assets/ic-filter-noti-outlined-20px.tsx +21 -0
  10. package/src/assets/ic-hide-large-outlined-20px.tsx +13 -0
  11. package/src/assets/ic-hide-small-outlined-20px.tsx +17 -0
  12. package/src/assets/ic-information-large-outlined-20px.tsx +17 -0
  13. package/src/assets/ic-information-small-outlined-20px.tsx +17 -0
  14. package/src/assets/ic-manufacturer-outlined-20px.tsx +19 -0
  15. package/src/assets/ic-rectangle-outlined-20px.tsx +17 -0
  16. package/src/assets/ic-refresh-left-outlined-20px.tsx +17 -0
  17. package/src/assets/ic-refresh-right-outlined-20px.tsx +13 -0
  18. package/src/assets/ic-show-large-outlined-20px.tsx +17 -0
  19. package/src/assets/ic-show-small-outlined-20px.tsx +17 -0
  20. package/src/assets/ic_bell_noti=outlined_20px.svg +5 -0
  21. package/src/assets/ic_close_large=outlined_20px.svg +4 -0
  22. package/src/assets/ic_close_small=outlined_20px.svg +4 -0
  23. package/src/assets/ic_download_pdf=outlined_20px.svg +7 -0
  24. package/src/assets/ic_ellipse=outlined_20px.svg +4 -0
  25. package/src/assets/ic_filter_noti=outlined_20px.svg +5 -0
  26. package/src/assets/ic_hide_large=outlined_20px.svg +4 -0
  27. package/src/assets/ic_hide_small=outlined_20px.svg +4 -0
  28. package/src/assets/ic_information_large=outlined_20px.svg +4 -0
  29. package/src/assets/ic_information_small=outlined_20px.svg +4 -0
  30. package/src/assets/ic_manufacturer=outlined_20px.svg +3 -0
  31. package/src/assets/ic_rectangle=outlined_20px.svg +4 -0
  32. package/src/assets/ic_refresh_left=outlined_20px.svg +4 -0
  33. package/src/assets/ic_refresh_right=outlined_20px.svg +4 -0
  34. package/src/assets/ic_show_large=outlined_20px.svg +4 -0
  35. package/src/assets/ic_show_small=outlined_20px.svg +4 -0
  36. package/src/assets/index.ts +16 -0
  37. package/src/components/Alert/Alert.styled.ts +44 -0
  38. package/src/components/Alert/Alert.tsx +39 -0
  39. package/src/components/Alert/Alert.types.ts +5 -0
  40. package/src/components/Alert/Alert.utils.tsx +43 -0
  41. package/src/components/Alert/index.ts +5 -0
  42. package/src/components/BaseTextField/BaseTextField.styled.ts +110 -0
  43. package/src/components/BaseTextField/BaseTextField.types.ts +25 -0
  44. package/src/components/BaseTextField/BaseTextField.utils.ts +10 -0
  45. package/src/components/Button/BaseButton.tsx +19 -0
  46. package/src/components/Button/Button.tsx +117 -0
  47. package/src/components/Button/Button.types.ts +36 -0
  48. package/src/components/Button/Button.utils.ts +13 -0
  49. package/src/components/Button/index.ts +6 -0
  50. package/src/components/Button/styleds/BaseButton.styled.ts +57 -0
  51. package/src/components/Button/styleds/ContainedButton.styled.ts +123 -0
  52. package/src/components/Button/styleds/GhostButton.styled.ts +139 -0
  53. package/src/components/Button/styleds/IconButton.styled.ts +25 -0
  54. package/src/components/Button/styleds/OutlinedButton.styled.ts +144 -0
  55. package/src/components/Card/Card.styled.tsx +18 -0
  56. package/src/components/Card/Card.tsx +18 -0
  57. package/src/components/Card/Card.types.ts +10 -0
  58. package/src/components/Card/index.ts +5 -0
  59. package/src/components/Checkbox/Checkbox.styled.tsx +27 -0
  60. package/src/components/Checkbox/Checkbox.tsx +64 -0
  61. package/src/components/Checkbox/Checkbox.types.ts +16 -0
  62. package/src/components/Checkbox/Checkbox.utils.tsx +42 -0
  63. package/src/components/Checkbox/index.ts +5 -0
  64. package/src/components/Chip/Chip.styled.ts +120 -0
  65. package/src/components/Chip/Chip.tsx +33 -0
  66. package/src/components/Chip/Chip.types.ts +18 -0
  67. package/src/components/Chip/Chip.utils.tsx +50 -0
  68. package/src/components/Chip/index.ts +4 -0
  69. package/src/components/DataTable/DataTable.styled.ts +66 -0
  70. package/src/components/DataTable/DataTable.tsx +29 -0
  71. package/src/components/DataTable/index.ts +1 -0
  72. package/src/components/DatePicker/DatePicker.styled.ts +19 -0
  73. package/src/components/DatePicker/DatePicker.tsx +194 -0
  74. package/src/components/DatePicker/DatePicker.types.ts +8 -0
  75. package/src/components/DatePicker/index.ts +4 -0
  76. package/src/components/Dialog/Dialog.styled.ts +87 -0
  77. package/src/components/Dialog/Dialog.tsx +111 -0
  78. package/src/components/Dialog/Dialog.types.ts +19 -0
  79. package/src/components/Dialog/index.ts +5 -0
  80. package/src/components/Divider/Divider.styled.ts +24 -0
  81. package/src/components/Divider/Divider.tsx +13 -0
  82. package/src/components/Divider/Divider.types.ts +7 -0
  83. package/src/components/Divider/index.ts +5 -0
  84. package/src/components/Dropdown/Dropdown.styled.tsx +127 -0
  85. package/src/components/Dropdown/Dropdown.tsx +116 -0
  86. package/src/components/Dropdown/Dropdown.types.ts +31 -0
  87. package/src/components/Dropdown/Dropdown.utils.ts +13 -0
  88. package/src/components/Dropdown/DropdownItem.styled.tsx +66 -0
  89. package/src/components/Dropdown/DropdownItem.tsx +45 -0
  90. package/src/components/Dropdown/DropdownItem.types.ts +14 -0
  91. package/src/components/Dropdown/DropdownItem.utils.ts +14 -0
  92. package/src/components/Dropdown/DropdownSubtitle.styled.ts +13 -0
  93. package/src/components/Dropdown/DropdownSubtitle.tsx +9 -0
  94. package/src/components/Dropdown/DropdownSubtitle.types.ts +6 -0
  95. package/src/components/Dropdown/IconDropdown.styled.tsx +82 -0
  96. package/src/components/Dropdown/IconDropdown.tsx +56 -0
  97. package/src/components/Dropdown/IconDropdown.types.ts +22 -0
  98. package/src/components/Dropdown/index.ts +22 -0
  99. package/src/components/FileDnDZone/FileDnDZone.styled.ts +43 -0
  100. package/src/components/FileDnDZone/FileDnDZone.tsx +81 -0
  101. package/src/components/FileDnDZone/FileDnDZone.types.ts +14 -0
  102. package/src/components/FileDnDZone/FileDnDZone.utils.ts +3 -0
  103. package/src/components/FileDnDZone/index.ts +5 -0
  104. package/src/components/List/List.styled.ts +31 -0
  105. package/src/components/List/List.tsx +71 -0
  106. package/src/components/List/List.types.ts +24 -0
  107. package/src/components/List/List.utils.ts +14 -0
  108. package/src/components/List/ListItem.styled.tsx +61 -0
  109. package/src/components/List/ListItem.tsx +66 -0
  110. package/src/components/List/ListItem.types.ts +40 -0
  111. package/src/components/List/ListItemCaption.styled.tsx +7 -0
  112. package/src/components/List/ListItemCaption.tsx +18 -0
  113. package/src/components/List/ListItemCaption.types.ts +2 -0
  114. package/src/components/List/index.ts +8 -0
  115. package/src/components/LoadingIndicator/LoadingIndicator.styled.tsx +40 -0
  116. package/src/components/LoadingIndicator/LoadingIndicator.tsx +44 -0
  117. package/src/components/LoadingIndicator/LoadingIndicator.types.ts +7 -0
  118. package/src/components/LoadingIndicator/assets/DnaLoadingAnimation.json +769 -0
  119. package/src/components/LoadingIndicator/assets/DotLoadingAnimation.json +426 -0
  120. package/src/components/LoadingIndicator/index.ts +5 -0
  121. package/src/components/Menu/Menu.styled.tsx +42 -0
  122. package/src/components/Menu/Menu.tsx +28 -0
  123. package/src/components/Menu/Menu.types.ts +18 -0
  124. package/src/components/Menu/MenuItem.styled.ts +62 -0
  125. package/src/components/Menu/MenuItem.tsx +45 -0
  126. package/src/components/Menu/MenuItem.types.ts +14 -0
  127. package/src/components/Menu/index.ts +5 -0
  128. package/src/components/MuiCssBaseline.ts +78 -0
  129. package/src/components/MuiInputBase.ts +25 -0
  130. package/src/components/MuiOutlinedInput.ts +57 -0
  131. package/src/components/MuiTextField.ts +17 -0
  132. package/src/components/Pagination/Pagination.styled.tsx +71 -0
  133. package/src/components/Pagination/Pagination.tsx +182 -0
  134. package/src/components/Pagination/Pagination.types.ts +39 -0
  135. package/src/components/Pagination/index.ts +2 -0
  136. package/src/components/ProductLabel/ProductLabel.styled.ts +61 -0
  137. package/src/components/ProductLabel/ProductLabel.tsx +57 -0
  138. package/src/components/ProductLabel/ProductLabel.types.ts +10 -0
  139. package/src/components/ProductLabel/index.ts +5 -0
  140. package/src/components/Progress/CircularProgress.styled.ts +10 -0
  141. package/src/components/Progress/CircularProgress.tsx +15 -0
  142. package/src/components/Progress/CircularProgress.types.ts +6 -0
  143. package/src/components/Progress/LinearProgress.styled.ts +15 -0
  144. package/src/components/Progress/LinearProgress.tsx +16 -0
  145. package/src/components/Progress/LinearProgress.types.ts +7 -0
  146. package/src/components/Progress/index.ts +4 -0
  147. package/src/components/Radio/Radio.styled.ts +35 -0
  148. package/src/components/Radio/Radio.tsx +60 -0
  149. package/src/components/Radio/Radio.types.ts +15 -0
  150. package/src/components/Radio/RadioGroup.styled.ts +6 -0
  151. package/src/components/Radio/RadioGroup.tsx +23 -0
  152. package/src/components/Radio/RadioGroup.types.ts +10 -0
  153. package/src/components/Radio/index.ts +7 -0
  154. package/src/components/Stepper/Stepper.styled.ts +38 -0
  155. package/src/components/Stepper/Stepper.tsx +24 -0
  156. package/src/components/Stepper/Stepper.types.ts +13 -0
  157. package/src/components/Stepper/index.ts +5 -0
  158. package/src/components/TabbedPanel/TabbedPanel.styled.ts +129 -0
  159. package/src/components/TabbedPanel/TabbedPanel.tsx +70 -0
  160. package/src/components/TabbedPanel/TabbedPanel.types.ts +36 -0
  161. package/src/components/TabbedPanel/TabbedPanel.utils.ts +21 -0
  162. package/src/components/TabbedPanel/index.ts +5 -0
  163. package/src/components/TextField/TextArea.styled.tsx +36 -0
  164. package/src/components/TextField/TextArea.tsx +35 -0
  165. package/src/components/TextField/TextArea.types.ts +28 -0
  166. package/src/components/TextField/TextInput.styled.tsx +115 -0
  167. package/src/components/TextField/TextInput.tsx +27 -0
  168. package/src/components/TextField/TextInput.types.ts +46 -0
  169. package/src/components/TextField/TextInput.utils.ts +7 -0
  170. package/src/components/TextField/components/Buttons.tsx +26 -0
  171. package/src/components/TextField/components/NormalTextInput.tsx +95 -0
  172. package/src/components/TextField/components/PasswordInput.tsx +92 -0
  173. package/src/components/TextField/index.ts +7 -0
  174. package/src/components/Tooltip/Tooltip.styled.tsx +36 -0
  175. package/src/components/Tooltip/Tooltip.tsx +58 -0
  176. package/src/components/Tooltip/Tooltip.types.ts +24 -0
  177. package/src/components/Tooltip/Tooltip.utils.ts +46 -0
  178. package/src/components/Tooltip/index.ts +5 -0
  179. package/src/components/UploadManager/UploadManager.styled.ts +49 -0
  180. package/src/components/UploadManager/UploadManager.tsx +271 -0
  181. package/src/components/UploadManager/UploadManager.types.ts +16 -0
  182. package/src/components/UploadManager/index.ts +5 -0
  183. package/src/components/index.ts +23 -0
  184. package/src/foundations/index.ts +4 -0
  185. package/src/foundations/palette.ts +418 -0
  186. package/src/foundations/spacing.ts +5 -0
  187. package/src/foundations/styles.ts +9 -0
  188. package/src/foundations/typography.ts +492 -0
  189. package/src/icons/BellNoti/index.tsx +28 -0
  190. package/src/icons/CloseLarge/index.tsx +28 -0
  191. package/src/icons/CloseSmall/index.tsx +28 -0
  192. package/src/icons/DownloadPdf/index.tsx +28 -0
  193. package/src/icons/Ellipse/index.tsx +28 -0
  194. package/src/icons/FilterNoti/index.tsx +28 -0
  195. package/src/icons/HideLarge/index.tsx +28 -0
  196. package/src/icons/HideSmall/index.tsx +28 -0
  197. package/src/icons/InformationLarge/index.tsx +28 -0
  198. package/src/icons/InformationSmall/index.tsx +28 -0
  199. package/src/icons/Manufacturer/index.tsx +28 -0
  200. package/src/icons/Rectangle/index.tsx +28 -0
  201. package/src/icons/RefreshLeft/index.tsx +28 -0
  202. package/src/icons/RefreshRight/index.tsx +28 -0
  203. package/src/icons/ShowLarge/index.tsx +28 -0
  204. package/src/icons/ShowSmall/index.tsx +28 -0
  205. package/src/icons/index.ts +180 -0
  206. package/src/index.ts +4 -0
  207. package/src/react-app-env.d.ts +71 -0
  208. package/src/reportWebVitals.ts +15 -0
  209. package/src/setupTests.ts +5 -0
  210. package/src/systems/drawer.ts +27 -0
  211. package/src/systems/index.ts +7 -0
  212. package/src/theme.ts +22 -0
@@ -0,0 +1,4 @@
1
+ import CircularProgress from './CircularProgress';
2
+ import LinearProgress from './LinearProgress';
3
+
4
+ export { CircularProgress, LinearProgress };
@@ -0,0 +1,35 @@
1
+ import { styled, Box, Radio } from '@mui/material';
2
+
3
+ export const Container = styled(Box)(({ theme }) => ({
4
+ display: 'inline-flex',
5
+ gap: theme.spacing(2),
6
+ }));
7
+
8
+ export const StyledRadio = styled(Radio)(({ theme }) => ({
9
+ width: '22px',
10
+ height: '22px',
11
+ padding: 0,
12
+ borderRadius: '50%',
13
+ '&.Mui-disabled, &.Mui-disabled + .MuiTypography-root': {
14
+ opacity: 0.4,
15
+ },
16
+ '&.Mui-focusVisible > div': {
17
+ boxShadow: `0 0 0 1px ${theme.palette.lunitTeal[10]}`,
18
+ },
19
+ }));
20
+
21
+ export const UncheckedIcon = styled('div')(({ theme }) => ({
22
+ width: '18px',
23
+ height: '18px',
24
+ border: `1.5px solid ${theme.palette.neutralGrey[45]}`,
25
+ borderRadius: '50%',
26
+ boxSizing: 'border-box',
27
+ }));
28
+
29
+ export const CheckedIcon = styled('div')(({ theme }) => ({
30
+ width: '18px',
31
+ height: '18px',
32
+ border: `4px solid ${theme.palette.lunitTeal[40]}`,
33
+ borderRadius: '50%',
34
+ boxSizing: 'border-box',
35
+ }));
@@ -0,0 +1,60 @@
1
+ import { Typography } from '@mui/material';
2
+ import clsx from 'clsx';
3
+ import React, { forwardRef } from 'react';
4
+ import { Container, StyledRadio, UncheckedIcon, CheckedIcon } from './Radio.styled';
5
+ import type { RadioProps } from './Radio.types';
6
+
7
+ const Radio = forwardRef<HTMLSpanElement, RadioProps>(
8
+ (
9
+ {
10
+ value,
11
+ name,
12
+ checked,
13
+ defaultChecked,
14
+ disabled,
15
+ required,
16
+ onChange,
17
+ onChangeCapture,
18
+ inputProps,
19
+ inputRef,
20
+ label,
21
+ ...rootProps
22
+ }: RadioProps,
23
+ ref,
24
+ ) => {
25
+ return (
26
+ <Container
27
+ {...rootProps}
28
+ className={clsx('radio', rootProps.className)}
29
+ component={label != null ? 'label' : 'span'}
30
+ ref={ref}
31
+ >
32
+ <StyledRadio
33
+ disableRipple
34
+ icon={<UncheckedIcon />}
35
+ checkedIcon={<CheckedIcon />}
36
+ value={value}
37
+ name={name}
38
+ checked={checked}
39
+ defaultChecked={defaultChecked}
40
+ disabled={disabled}
41
+ required={required}
42
+ onChange={onChange}
43
+ onChangeCapture={onChangeCapture}
44
+ inputProps={inputProps}
45
+ inputRef={inputRef}
46
+ />
47
+ {label && (
48
+ <Typography
49
+ variant="body_m1"
50
+ sx={{ display: 'flex', alignItems: 'center' }}
51
+ >
52
+ {label}
53
+ </Typography>
54
+ )}
55
+ </Container>
56
+ );
57
+ },
58
+ );
59
+
60
+ export default Radio;
@@ -0,0 +1,15 @@
1
+ import type { BoxProps, RadioProps as MuiRadioProps } from '@mui/material';
2
+
3
+ export interface RadioProps extends Omit<BoxProps<'span'>, 'onChange' | 'onChangeCapture'> {
4
+ value?: MuiRadioProps['value'];
5
+ name?: MuiRadioProps['name'];
6
+ checked?: MuiRadioProps['checked'];
7
+ defaultChecked?: MuiRadioProps['defaultChecked'];
8
+ disabled?: MuiRadioProps['disabled'];
9
+ required?: MuiRadioProps['required'];
10
+ onChange?: MuiRadioProps['onChange'];
11
+ onChangeCapture?: MuiRadioProps['onChangeCapture'];
12
+ label?: string;
13
+ inputProps?: MuiRadioProps['inputProps'];
14
+ inputRef?: MuiRadioProps['inputRef'];
15
+ }
@@ -0,0 +1,6 @@
1
+ import { styled, RadioGroup } from '@mui/material';
2
+
3
+ // eslint-disable-next-line import/prefer-default-export
4
+ export const StyledRadioGroup = styled(RadioGroup)(({ theme }) => ({
5
+ gap: theme.spacing(2),
6
+ }));
@@ -0,0 +1,23 @@
1
+ import React, { forwardRef } from 'react';
2
+ import { StyledRadioGroup } from './RadioGroup.styled';
3
+ import type { RadioGroupProps } from './RadioGroup.types';
4
+
5
+ const RadioGroup = forwardRef<HTMLDivElement, RadioGroupProps>(
6
+ ({ defaultValue, name, row, children, onChange, value, ...props }: RadioGroupProps, ref) => {
7
+ return (
8
+ <StyledRadioGroup
9
+ {...props}
10
+ defaultValue={defaultValue}
11
+ name={name}
12
+ onChange={onChange}
13
+ value={value}
14
+ row={row}
15
+ ref={ref}
16
+ >
17
+ {children}
18
+ </StyledRadioGroup>
19
+ );
20
+ },
21
+ );
22
+
23
+ export default RadioGroup;
@@ -0,0 +1,10 @@
1
+ import type { FormGroupProps, RadioGroupProps as MuiRadioGroupProps } from '@mui/material';
2
+
3
+ export interface RadioGroupProps extends MuiRadioGroupProps {
4
+ children?: FormGroupProps['children'];
5
+ defaultValue?: MuiRadioGroupProps['defaultValue'];
6
+ name?: MuiRadioGroupProps['name'];
7
+ onChange?: MuiRadioGroupProps['onChange'];
8
+ value?: MuiRadioGroupProps['value'];
9
+ row?: FormGroupProps['row'];
10
+ }
@@ -0,0 +1,7 @@
1
+ import Radio from './Radio';
2
+ import type { RadioProps } from './Radio.types';
3
+
4
+ import RadioGroup from './RadioGroup';
5
+ import type { RadioGroupProps } from './RadioGroup.types';
6
+
7
+ export { Radio, RadioGroup, RadioProps, RadioGroupProps };
@@ -0,0 +1,38 @@
1
+ import { Box, Typography, styled } from '@mui/material';
2
+ import { Chip } from '../Chip';
3
+ import theme from '../../theme';
4
+ import type { StepperTypographyProps } from './Stepper.types';
5
+
6
+ export const StepperContainer = styled(Box)({
7
+ display: 'flex',
8
+ flexDirection: 'column',
9
+ height: '64px',
10
+ });
11
+ export const ChipContainer = styled(Box)({
12
+ display: 'inline-block',
13
+ });
14
+
15
+ export const StepperChip = styled(Chip, {
16
+ shouldForwardProp: (prop) => prop !== 'disabled',
17
+ })(({ disabled }) => ({
18
+ backgroundColor: `${
19
+ !disabled ? theme.palette.lunitTeal[40] : theme.palette.neutralGrey[70]
20
+ } !important`,
21
+ color: `${!disabled ? theme.palette.lunitTeal[90] : theme.palette.neutralGrey[95]} !important`,
22
+ marginBottom: '4px',
23
+ '.MuiChip-label ': {
24
+ fontWeight: 400,
25
+ fontSize: '14px',
26
+ lineHeight: '24px',
27
+ },
28
+ }));
29
+
30
+ export const StepperTypography = styled(Typography, {
31
+ shouldForwardProp: (prop) => prop !== 'disabled',
32
+ })<StepperTypographyProps>(({ disabled }) => ({
33
+ color: !disabled ? 'white' : theme.palette.neutralGrey[70],
34
+ overflow: 'hidden',
35
+ textOverflow: 'ellipsis',
36
+ whiteSpace: 'nowrap',
37
+ cursor: 'default',
38
+ }));
@@ -0,0 +1,24 @@
1
+ import React from 'react';
2
+ import { ChipContainer, StepperChip, StepperContainer, StepperTypography } from './Stepper.styled';
3
+ import type { StepperProps } from './Stepper.types';
4
+
5
+ const Stepper = ({ step, title, disabled = false, sx }: StepperProps) => {
6
+ return (
7
+ <StepperContainer sx={sx}>
8
+ <ChipContainer>
9
+ <StepperChip
10
+ label={`STEP ${step}`}
11
+ disabled={disabled}
12
+ />
13
+ </ChipContainer>
14
+ <StepperTypography
15
+ variant="h7"
16
+ disabled={disabled}
17
+ >
18
+ {title}
19
+ </StepperTypography>
20
+ </StepperContainer>
21
+ );
22
+ };
23
+
24
+ export default Stepper;
@@ -0,0 +1,13 @@
1
+ import type { TypographyProps } from '@mui/material';
2
+ import type { SxProps } from '@mui/system';
3
+
4
+ export interface StepperProps {
5
+ step: number;
6
+ title: string;
7
+ disabled?: boolean;
8
+ sx?: SxProps;
9
+ }
10
+
11
+ export interface StepperTypographyProps extends TypographyProps {
12
+ disabled?: boolean;
13
+ }
@@ -0,0 +1,5 @@
1
+ import Stepper from './Stepper';
2
+ import type { StepperProps } from './Stepper.types';
3
+
4
+ export { Stepper };
5
+ export type { StepperProps };
@@ -0,0 +1,129 @@
1
+ import TabPanel from '@mui/lab/TabPanel/TabPanel';
2
+ import { Tab, Tabs, styled } from '@mui/material';
3
+ import type { Theme } from '@mui/material';
4
+ import type { BaseTabProps, BaseTabsProps, TabSize } from './TabbedPanel.types';
5
+
6
+ const tabSizeStyle = (size: TabSize) => {
7
+ return {
8
+ minHeight: `${size === 'small' ? '28px' : '44px'} !important`,
9
+ };
10
+ };
11
+
12
+ // Style for Tabs (Tab Group)
13
+ const baseTabMenuStyle = (theme: Theme) => {
14
+ return {
15
+ padding: 0,
16
+ borderBottom: `1px solid ${theme.palette.neutralGrey[65]}`,
17
+ };
18
+ };
19
+
20
+ const toggleTabMenuStyle = {
21
+ borderRadius: '8px',
22
+ outline: 'none',
23
+ boxShadow: 'none',
24
+ borderBottom: 'none',
25
+ };
26
+
27
+ // Style for Tab (Tab Button)
28
+ const baseTabStyle = (theme: Theme, size: TabSize) => {
29
+ return {
30
+ background: theme.palette.neutralGrey[90],
31
+ borderRadius: 'inherit',
32
+ color: theme.palette.neutralGrey[45],
33
+ minWidth: '100px',
34
+ padding: `${size === 'small' ? '4px 8px' : '12px 16px'}`,
35
+ textTransform: 'none' as const,
36
+ '&:hover': {
37
+ opacity: 0.8,
38
+ },
39
+ '&:active': {
40
+ background: theme.palette.neutralGrey[60],
41
+ color: theme.palette.neutralGrey[0],
42
+ },
43
+ '&.Mui-selected': {
44
+ background: theme.palette.neutralGrey[90],
45
+ color: theme.palette.neutralGrey[0],
46
+ },
47
+ };
48
+ };
49
+
50
+ const toggleTabStyle = (theme: Theme) => {
51
+ return {
52
+ outline: 'none',
53
+ borderRadius: 'inherit',
54
+ border: `1px solid ${theme.palette.neutralGrey[75]}`,
55
+ boxShadow: 'none',
56
+ background: theme.palette.neutralGrey[90],
57
+ color: theme.palette.neutralGrey[45],
58
+ '&:hover': {
59
+ opacity: 0.8,
60
+ },
61
+ '&:active': {
62
+ borderRadius: 'inherit',
63
+ boxShadow: 'none',
64
+ outline: 'none',
65
+ borderColor: theme.palette.neutralGrey[60],
66
+ background: theme.palette.neutralGrey[60],
67
+ color: theme.palette.neutralGrey[0],
68
+ },
69
+ '&.Mui-selected': {
70
+ borderRadius: 'inherit',
71
+ boxShadow: 'none',
72
+ outline: 'none',
73
+ borderColor: 'transparent',
74
+ background: theme.palette.neutralGrey[75],
75
+ color: theme.palette.neutralGrey[0],
76
+ '&:hover': { opacity: 1 },
77
+ },
78
+ '&:first-of-type': {
79
+ borderRadius: '8px 0 0 8px',
80
+ },
81
+ '&:last-of-type': {
82
+ borderRadius: '0 8px 8px 0',
83
+ },
84
+ };
85
+ };
86
+
87
+ const baseTabbedPanelStyle = {
88
+ padding: '0',
89
+ };
90
+
91
+ const BaseTabMenu = styled(Tabs, {
92
+ shouldForwardProp: (prop) => !['size', 'buttonVariant'].includes(prop.toString()),
93
+ })<BaseTabsProps>(({ theme, size, buttonVariant }) => {
94
+ let style = {
95
+ ...baseTabMenuStyle(theme),
96
+ ...tabSizeStyle(size ?? 'medium'),
97
+ };
98
+ if (buttonVariant === 'toggle') {
99
+ style = {
100
+ ...style,
101
+ ...toggleTabMenuStyle,
102
+ };
103
+ }
104
+ return style;
105
+ });
106
+
107
+ const BaseTab = styled(Tab, {
108
+ shouldForwardProp: (prop) => !['size', 'buttonVariant'].includes(prop.toString()),
109
+ })<BaseTabProps>(({ theme, size, buttonVariant }) => {
110
+ let style = {
111
+ ...baseTabStyle(theme, size ?? 'medium'),
112
+ ...tabSizeStyle(size ?? 'medium'),
113
+ };
114
+
115
+ if (buttonVariant === 'toggle') {
116
+ style = {
117
+ ...style,
118
+ ...toggleTabStyle(theme),
119
+ };
120
+ }
121
+
122
+ return style;
123
+ });
124
+
125
+ const BaseTabPanel = styled(TabPanel)(() => {
126
+ return baseTabbedPanelStyle;
127
+ });
128
+
129
+ export { BaseTabMenu, BaseTab, BaseTabPanel };
@@ -0,0 +1,70 @@
1
+ import React from 'react';
2
+ import { Box, Typography } from '@mui/material';
3
+ import TabContext from '@mui/lab/TabContext';
4
+ import { BaseTab, BaseTabMenu, BaseTabPanel } from './TabbedPanel.styled';
5
+ import type { TabbedPanelProps } from './TabbedPanel.types';
6
+
7
+ const TabbedPanel = ({
8
+ tabs,
9
+ size = 'medium',
10
+ buttonVariant = 'normal',
11
+ activatedTab,
12
+ TabPanelProps,
13
+ TabProps,
14
+ TabsProps,
15
+ menuVariant,
16
+ onActivatedTab,
17
+ onTabChangeListener,
18
+ }: TabbedPanelProps) => {
19
+ const handleChange = (_: React.SyntheticEvent, newValue: string) => {
20
+ if (onTabChangeListener) {
21
+ onTabChangeListener(newValue);
22
+ }
23
+ onActivatedTab(newValue);
24
+ };
25
+
26
+ // If prop is not explicitly set, use standard when there is only one tab
27
+ // This means by default, it will left-align when there is only one tab.
28
+ const menuVariantSetting = !menuVariant || tabs.length < 2 ? 'standard' : menuVariant;
29
+
30
+ return (
31
+ <Box>
32
+ <TabContext value={activatedTab}>
33
+ <BaseTabMenu
34
+ size={size}
35
+ value={activatedTab}
36
+ onChange={handleChange}
37
+ variant={menuVariantSetting}
38
+ buttonVariant={buttonVariant}
39
+ TabIndicatorProps={{ sx: { display: 'none' } }}
40
+ {...TabsProps}
41
+ >
42
+ {tabs.map((t) => (
43
+ <BaseTab
44
+ buttonVariant={buttonVariant}
45
+ size={size}
46
+ disabled={t.disabled}
47
+ disableTouchRipple
48
+ disableRipple
49
+ key={t.value}
50
+ label={<Typography variant="body_sb1">{t.value}</Typography>}
51
+ value={t.value}
52
+ {...TabProps}
53
+ />
54
+ ))}
55
+ </BaseTabMenu>
56
+ {tabs.map((t) => (
57
+ <BaseTabPanel
58
+ key={t.value}
59
+ value={t.value}
60
+ {...TabPanelProps}
61
+ >
62
+ {t.element}
63
+ </BaseTabPanel>
64
+ ))}
65
+ </TabContext>
66
+ </Box>
67
+ );
68
+ };
69
+
70
+ export default TabbedPanel;
@@ -0,0 +1,36 @@
1
+ import type { TabPanelProps } from '@mui/lab/TabPanel';
2
+ import type { TabProps, TabsProps } from '@mui/material';
3
+
4
+ type TabSize = 'small' | 'medium';
5
+ type ButtonVariant = 'normal' | 'toggle';
6
+
7
+ interface TabConfig {
8
+ value: string;
9
+ element: React.ReactNode;
10
+ disabled?: boolean;
11
+ }
12
+
13
+ interface BaseTabProps extends TabProps {
14
+ size?: TabSize;
15
+ buttonVariant?: ButtonVariant;
16
+ }
17
+
18
+ interface BaseTabsProps extends TabsProps {
19
+ size?: TabSize;
20
+ buttonVariant?: ButtonVariant;
21
+ }
22
+
23
+ interface TabbedPanelProps {
24
+ tabs: TabConfig[];
25
+ activatedTab: string;
26
+ size?: TabSize;
27
+ buttonVariant?: ButtonVariant;
28
+ menuVariant?: TabsProps['variant'];
29
+ TabsProps?: Partial<TabsProps>;
30
+ TabProps?: Partial<TabProps>;
31
+ TabPanelProps?: Partial<TabPanelProps>;
32
+ onActivatedTab: (tab: string) => void;
33
+ onTabChangeListener?: (newTabValue: string) => void;
34
+ }
35
+
36
+ export type { TabbedPanelProps, TabConfig, TabSize, BaseTabProps, BaseTabsProps };
@@ -0,0 +1,21 @@
1
+ import type { TabConfig } from './TabbedPanel.types';
2
+
3
+ /**
4
+ *
5
+ * @param defaultTab string | undefined
6
+ * @param tabs TabConfig[]
7
+ * @returns string
8
+ * @description returns the initial value for useState, based on defaultTab.
9
+ * If default tab is provided and matched, returns that,
10
+ * else, returns first tab.
11
+ *
12
+ */
13
+
14
+ function findDefaultTab(defaultTab: string | undefined, tabs: TabConfig[]): string {
15
+ if (defaultTab) {
16
+ return tabs.find((t) => t.value === defaultTab)?.value ?? tabs[0].value;
17
+ }
18
+ return tabs[0].value;
19
+ }
20
+
21
+ export { findDefaultTab };
@@ -0,0 +1,5 @@
1
+ import TabbedPanel from './TabbedPanel';
2
+ import type { TabbedPanelProps, TabConfig } from './TabbedPanel.types';
3
+
4
+ export { TabbedPanel };
5
+ export type { TabbedPanelProps, TabConfig };
@@ -0,0 +1,36 @@
1
+ import { styled, Theme } from '@mui/material';
2
+ import { styles } from '../BaseTextField/BaseTextField.styled';
3
+ import type { RootTextAreaProps } from './TextArea.types';
4
+ import { formatCSSSize } from '../BaseTextField/BaseTextField.utils';
5
+
6
+ const baseTextAreaStyle = (theme: Theme, height: string | number | undefined) => {
7
+ return {
8
+ ...styles.baseTextFieldStyle(theme),
9
+ height: height ? formatCSSSize(height) : '100px',
10
+ resize: 'none' as const,
11
+ '&::-webkit-scrollbar': {
12
+ width: '14px !important',
13
+ },
14
+ '&::-webkit-scrollbar-thumb': {
15
+ border: `4px solid ${theme.palette.neutralGrey[75]}`,
16
+ },
17
+ };
18
+ };
19
+
20
+ const BaseTextArea = styled('textarea', {
21
+ shouldForwardProp: (prop) => !['error', 'width', 'height'].includes(prop.toString()),
22
+ })<RootTextAreaProps>(({ theme, height, error }) => {
23
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
24
+ let resultStyle: any = baseTextAreaStyle(theme, height);
25
+
26
+ if (error) {
27
+ resultStyle = {
28
+ ...resultStyle,
29
+ ...styles.baseTextFieldErrorStyle(theme),
30
+ };
31
+ }
32
+
33
+ return resultStyle;
34
+ });
35
+
36
+ export default BaseTextArea;
@@ -0,0 +1,35 @@
1
+ import React, { forwardRef } from 'react';
2
+ import { InputMsg, BaseTextFieldContainer } from '../BaseTextField/BaseTextField.styled';
3
+ import BaseTextArea from './TextArea.styled';
4
+ import type { TextAreaProps } from './TextArea.types';
5
+
6
+ const TextArea = forwardRef(
7
+ (props: TextAreaProps, ref?: React.ForwardedRef<HTMLTextAreaElement>) => {
8
+ const { error, helperMsg, OuterBoxProps, ...areaProps } = props;
9
+
10
+ return (
11
+ <BaseTextFieldContainer
12
+ {...OuterBoxProps}
13
+ width={props.width}
14
+ >
15
+ <BaseTextArea
16
+ ref={ref}
17
+ {...areaProps}
18
+ multiline="true"
19
+ error={!!error}
20
+ />
21
+ {error ? (
22
+ <InputMsg
23
+ variant="body5"
24
+ error
25
+ >
26
+ {error}
27
+ </InputMsg>
28
+ ) : (
29
+ helperMsg && <InputMsg variant="body5">{helperMsg}</InputMsg>
30
+ )}
31
+ </BaseTextFieldContainer>
32
+ );
33
+ },
34
+ );
35
+ export default TextArea;
@@ -0,0 +1,28 @@
1
+ import type { BoxProps } from '@mui/material';
2
+ import type { HelperMsgProps, RootTextFieldProps } from '../BaseTextField/BaseTextField.types';
3
+
4
+ // props we define for the textarea element itself
5
+ interface RootTextAreaProps extends Omit<RootTextFieldProps, 'BoxProps'> {
6
+ multiline: 'true';
7
+ onChange?: (event: React.ChangeEvent<HTMLTextAreaElement>) => void;
8
+ error?: boolean;
9
+ ref?: React.ForwardedRef<HTMLTextAreaElement> | undefined;
10
+ placeholder?: string;
11
+ width?: string | number;
12
+ height?: string | number;
13
+ OuterBoxProps?: BoxProps;
14
+ }
15
+
16
+ // common props for a wrapped textarea and helper message
17
+ interface TextAreaWithHelperMsgProps
18
+ extends Omit<RootTextAreaProps, 'error' | 'multiline'>,
19
+ Omit<HelperMsgProps, 'error'> {
20
+ error?: string;
21
+ }
22
+
23
+ // props for TextArea
24
+ interface TextAreaProps extends TextAreaWithHelperMsgProps {}
25
+
26
+ export type { RootTextAreaProps, TextAreaProps };
27
+
28
+ // n.b structured to match TextInput