@team-monolith/cds 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. package/README.md +46 -0
  2. package/dist/CodleDesignSystemProvider.d.ts +5 -0
  3. package/dist/CodleDesignSystemProvider.js +96 -0
  4. package/dist/components/AlertDialog/AlertDialog.d.ts +14 -0
  5. package/dist/components/AlertDialog/AlertDialog.js +45 -0
  6. package/dist/components/AlertDialog/AlertDialogActions.d.ts +8 -0
  7. package/dist/components/AlertDialog/AlertDialogActions.js +35 -0
  8. package/dist/components/AlertDialog/AlertDialogContent.d.ts +8 -0
  9. package/dist/components/AlertDialog/AlertDialogContent.js +36 -0
  10. package/dist/components/AlertDialog/AlertDialogTitle.d.ts +13 -0
  11. package/dist/components/AlertDialog/AlertDialogTitle.js +38 -0
  12. package/dist/components/AlertDialog/index.d.ts +4 -0
  13. package/dist/components/AlertDialog/index.js +4 -0
  14. package/dist/components/Banner.d.ts +29 -0
  15. package/dist/components/Banner.js +65 -0
  16. package/dist/components/Button.d.ts +26 -0
  17. package/dist/components/Button.js +72 -0
  18. package/dist/components/CheckboxInput.d.ts +27 -0
  19. package/dist/components/CheckboxInput.js +77 -0
  20. package/dist/components/Input.d.ts +17 -0
  21. package/dist/components/Input.js +72 -0
  22. package/dist/components/InputBase.d.ts +42 -0
  23. package/dist/components/InputBase.js +52 -0
  24. package/dist/components/Pagination.d.ts +27 -0
  25. package/dist/components/Pagination.js +32 -0
  26. package/dist/components/PinInput.d.ts +36 -0
  27. package/dist/components/PinInput.js +154 -0
  28. package/dist/components/RadioInput.d.ts +23 -0
  29. package/dist/components/RadioInput.js +78 -0
  30. package/dist/components/SquareButton.d.ts +26 -0
  31. package/dist/components/SquareButton.js +80 -0
  32. package/dist/components/Switch.d.ts +19 -0
  33. package/dist/components/Switch.js +59 -0
  34. package/dist/components/Tag.d.ts +21 -0
  35. package/dist/components/Tag.js +61 -0
  36. package/dist/components/Tooltip.d.ts +26 -0
  37. package/dist/components/Tooltip.js +50 -0
  38. package/dist/foundation/color.d.ts +75 -0
  39. package/dist/foundation/color.js +75 -0
  40. package/dist/foundation/shadows.d.ts +9 -0
  41. package/dist/foundation/shadows.js +10 -0
  42. package/dist/icons/arrows.d.ts +16 -0
  43. package/dist/icons/arrows.js +17 -0
  44. package/dist/icons/brand.d.ts +4 -0
  45. package/dist/icons/brand.js +13 -0
  46. package/dist/icons/map.d.ts +4 -0
  47. package/dist/icons/map.js +13 -0
  48. package/dist/icons/system.d.ts +25 -0
  49. package/dist/icons/system.js +20 -0
  50. package/dist/index.d.ts +2 -0
  51. package/dist/index.js +2 -0
  52. package/dist/patterns/Dropdown/Dropdown.d.ts +27 -0
  53. package/dist/patterns/Dropdown/Dropdown.js +41 -0
  54. package/dist/patterns/Dropdown/DropdownItem.d.ts +42 -0
  55. package/dist/patterns/Dropdown/DropdownItem.js +89 -0
  56. package/dist/patterns/Dropdown/DropdownMenu.d.ts +30 -0
  57. package/dist/patterns/Dropdown/DropdownMenu.js +85 -0
  58. package/dist/patterns/Dropdown/index.d.ts +2 -0
  59. package/dist/patterns/Dropdown/index.js +2 -0
  60. package/dist/patterns/EmptyState/EmptyState.d.ts +16 -0
  61. package/dist/patterns/EmptyState/EmptyState.js +36 -0
  62. package/dist/patterns/EmptyState/index.d.ts +2 -0
  63. package/dist/patterns/EmptyState/index.js +2 -0
  64. package/dist/patterns/Grid/EnhancedTableCell.d.ts +9 -0
  65. package/dist/patterns/Grid/EnhancedTableCell.js +122 -0
  66. package/dist/patterns/Grid/Grid.d.ts +51 -0
  67. package/dist/patterns/Grid/Grid.js +140 -0
  68. package/dist/patterns/Grid/index.d.ts +3 -0
  69. package/dist/patterns/Grid/index.js +2 -0
  70. package/dist/patterns/SegmentedControl/SegmentedControlButton.d.ts +8 -0
  71. package/dist/patterns/SegmentedControl/SegmentedControlButton.js +41 -0
  72. package/dist/patterns/SegmentedControl/SegmentedControlGroup.d.ts +26 -0
  73. package/dist/patterns/SegmentedControl/SegmentedControlGroup.js +50 -0
  74. package/dist/patterns/SegmentedControl/SegmentedControlGroupPropsContext.d.ts +5 -0
  75. package/dist/patterns/SegmentedControl/SegmentedControlGroupPropsContext.js +5 -0
  76. package/dist/patterns/SegmentedControl/SegmentedControlSquareButton.d.ts +8 -0
  77. package/dist/patterns/SegmentedControl/SegmentedControlSquareButton.js +45 -0
  78. package/dist/patterns/SegmentedControl/index.d.ts +3 -0
  79. package/dist/patterns/SegmentedControl/index.js +3 -0
  80. package/dist/patterns/Table/Table.d.ts +16 -0
  81. package/dist/patterns/Table/Table.js +33 -0
  82. package/dist/patterns/Table/TableBody.d.ts +8 -0
  83. package/dist/patterns/Table/TableBody.js +26 -0
  84. package/dist/patterns/Table/TableCell.d.ts +15 -0
  85. package/dist/patterns/Table/TableCell.js +78 -0
  86. package/dist/patterns/Table/TableHead.d.ts +8 -0
  87. package/dist/patterns/Table/TableHead.js +26 -0
  88. package/dist/patterns/Table/TableRow.d.ts +12 -0
  89. package/dist/patterns/Table/TableRow.js +29 -0
  90. package/dist/patterns/Table/TableSizeContext.d.ts +7 -0
  91. package/dist/patterns/Table/TableSizeContext.js +3 -0
  92. package/dist/patterns/Table/TableVariantContext.d.ts +6 -0
  93. package/dist/patterns/Table/TableVariantContext.js +3 -0
  94. package/dist/patterns/Table/index.d.ts +7 -0
  95. package/dist/patterns/Table/index.js +6 -0
  96. package/dist/utils/hover.d.ts +3 -0
  97. package/dist/utils/hover.js +14 -0
  98. package/dist/utils/reset.d.ts +2 -0
  99. package/dist/utils/reset.js +8 -0
  100. package/dist/utils/zIndex.d.ts +3 -0
  101. package/dist/utils/zIndex.js +3 -0
  102. package/package.json +52 -0
  103. package/public/favicon.ico +0 -0
  104. package/public/index.html +43 -0
  105. package/public/logo192.png +0 -0
  106. package/public/logo512.png +0 -0
  107. package/public/manifest.json +25 -0
  108. package/public/robots.txt +3 -0
  109. package/src/App.tsx +7 -0
  110. package/src/cds/CodleDesignSystemProvider.tsx +93 -0
  111. package/src/cds/README.md +23 -0
  112. package/src/cds/components/AlertDialog/AlertDialog.tsx +101 -0
  113. package/src/cds/components/AlertDialog/AlertDialogActions.tsx +34 -0
  114. package/src/cds/components/AlertDialog/AlertDialogContent.tsx +38 -0
  115. package/src/cds/components/AlertDialog/AlertDialogTitle.tsx +63 -0
  116. package/src/cds/components/AlertDialog/index.tsx +4 -0
  117. package/src/cds/components/Banner.tsx +176 -0
  118. package/src/cds/components/Button.tsx +239 -0
  119. package/src/cds/components/CheckboxInput.tsx +270 -0
  120. package/src/cds/components/Input.tsx +166 -0
  121. package/src/cds/components/InputBase.tsx +226 -0
  122. package/src/cds/components/Pagination.tsx +99 -0
  123. package/src/cds/components/PinInput.tsx +322 -0
  124. package/src/cds/components/RadioInput.tsx +226 -0
  125. package/src/cds/components/SquareButton.tsx +229 -0
  126. package/src/cds/components/Switch.tsx +129 -0
  127. package/src/cds/components/Tag.tsx +155 -0
  128. package/src/cds/components/Tooltip.tsx +104 -0
  129. package/src/cds/emotion.d.ts +70 -0
  130. package/src/cds/foundation/color.ts +83 -0
  131. package/src/cds/foundation/shadows.ts +17 -0
  132. package/src/cds/icons/arrows.tsx +61 -0
  133. package/src/cds/icons/brand.tsx +13 -0
  134. package/src/cds/icons/map.tsx +14 -0
  135. package/src/cds/icons/system.tsx +113 -0
  136. package/src/cds/index.ts +3 -0
  137. package/src/cds/patterns/Dropdown/Dropdown.tsx +111 -0
  138. package/src/cds/patterns/Dropdown/DropdownItem.tsx +203 -0
  139. package/src/cds/patterns/Dropdown/DropdownMenu.tsx +176 -0
  140. package/src/cds/patterns/Dropdown/index.tsx +2 -0
  141. package/src/cds/patterns/EmptyState/EmptyState.tsx +91 -0
  142. package/src/cds/patterns/EmptyState/empty-state-icon.svg +36 -0
  143. package/src/cds/patterns/EmptyState/index.tsx +2 -0
  144. package/src/cds/patterns/Grid/EnhancedTableCell.tsx +180 -0
  145. package/src/cds/patterns/Grid/Grid.tsx +360 -0
  146. package/src/cds/patterns/Grid/index.tsx +4 -0
  147. package/src/cds/patterns/SegmentedControl/SegmentedControlButton.tsx +41 -0
  148. package/src/cds/patterns/SegmentedControl/SegmentedControlGroup.tsx +81 -0
  149. package/src/cds/patterns/SegmentedControl/SegmentedControlGroupPropsContext.tsx +9 -0
  150. package/src/cds/patterns/SegmentedControl/SegmentedControlSquareButton.tsx +51 -0
  151. package/src/cds/patterns/SegmentedControl/index.ts +3 -0
  152. package/src/cds/patterns/Table/Table.tsx +56 -0
  153. package/src/cds/patterns/Table/TableBody.tsx +30 -0
  154. package/src/cds/patterns/Table/TableCell.tsx +242 -0
  155. package/src/cds/patterns/Table/TableHead.tsx +30 -0
  156. package/src/cds/patterns/Table/TableRow.tsx +54 -0
  157. package/src/cds/patterns/Table/TableSizeContext.tsx +10 -0
  158. package/src/cds/patterns/Table/TableVariantContext.tsx +9 -0
  159. package/src/cds/patterns/Table/index.tsx +15 -0
  160. package/src/cds/utils/hover.tsx +24 -0
  161. package/src/cds/utils/reset.tsx +19 -0
  162. package/src/cds/utils/zIndex.tsx +3 -0
  163. package/src/index.tsx +10 -0
  164. package/src/react-app-env.d.ts +1 -0
  165. package/tsconfig.json +22 -0
@@ -0,0 +1,34 @@
1
+ /** @jsxImportSource @emotion/react */
2
+ import { css } from "@emotion/react";
3
+ import React from "react";
4
+ export interface AlertDialogActionsProps {
5
+ className?: string;
6
+ component?: React.ElementType;
7
+
8
+ /** Content 내용으로 표기될 값 */
9
+ children: React.ReactNode;
10
+ }
11
+
12
+ export const AlertDialogActions = React.forwardRef<
13
+ any,
14
+ AlertDialogActionsProps
15
+ >((props, ref) => {
16
+ const { className, component: Component = "div", children, ...other } = props;
17
+ return (
18
+ <Component
19
+ {...other}
20
+ ref={ref}
21
+ className={className}
22
+ css={css`
23
+ grid-area: actions;
24
+
25
+ margin-top: 8px;
26
+ display: flex;
27
+ gap: 16px;
28
+ justify-content: flex-end;
29
+ `}
30
+ >
31
+ {children}
32
+ </Component>
33
+ );
34
+ });
@@ -0,0 +1,38 @@
1
+ /** @jsxImportSource @emotion/react */
2
+ import { css, useTheme } from "@emotion/react";
3
+ import React from "react";
4
+
5
+ export interface AlertDialogContentProps {
6
+ className?: string;
7
+ component?: React.ElementType;
8
+
9
+ /** Content 내용으로 표기될 값 */
10
+ children: React.ReactNode;
11
+ }
12
+
13
+ export const AlertDialogContent = React.forwardRef<
14
+ any,
15
+ AlertDialogContentProps
16
+ >((props, ref) => {
17
+ const { className, component: Component = "div", children, ...other } = props;
18
+ const theme = useTheme();
19
+ return (
20
+ <>
21
+ <Component
22
+ {...other}
23
+ ref={ref}
24
+ className={className}
25
+ css={css`
26
+ grid-area: content;
27
+
28
+ font-style: normal;
29
+ font-size: 18px;
30
+ line-height: 28px;
31
+ color: ${theme.color.foreground.neutralBase};
32
+ `}
33
+ >
34
+ {children}
35
+ </Component>
36
+ </>
37
+ );
38
+ });
@@ -0,0 +1,63 @@
1
+ /** @jsxImportSource @emotion/react */
2
+ import { css, useTheme } from "@emotion/react";
3
+ import React from "react";
4
+ import SquareButton from "../SquareButton";
5
+ import { CloseFillIcon } from "../../icons/system";
6
+
7
+ export interface AlertDialogTitleProps {
8
+ className?: string;
9
+ component?: React.ElementType;
10
+
11
+ /**
12
+ * 제목의 X 버튼을 누르를 때 호출되는 callback.
13
+ * 이 속성이 전달되면 X 버튼을 Title 영역에 그립니다.
14
+ */
15
+ onClose?: () => void;
16
+
17
+ /** Content 내용으로 표기될 값 */
18
+ children: React.ReactNode;
19
+ }
20
+
21
+ export const AlertDialogTitle = React.forwardRef<any, AlertDialogTitleProps>(
22
+ (props, ref) => {
23
+ const {
24
+ className,
25
+ component: Component = "div",
26
+ onClose,
27
+ children,
28
+ ...other
29
+ } = props;
30
+ const theme = useTheme();
31
+ return (
32
+ <>
33
+ <Component
34
+ {...other}
35
+ ref={ref}
36
+ className={className}
37
+ css={css`
38
+ grid-area: title;
39
+ font-family: "Pretendard";
40
+ font-style: normal;
41
+ font-weight: 500;
42
+ font-size: 20px;
43
+ line-height: 36px;
44
+ color: ${theme.color.foreground.neutralBase};
45
+
46
+ display: flex;
47
+ justify-content: space-between;
48
+ `}
49
+ >
50
+ {children}
51
+ {onClose && (
52
+ <SquareButton
53
+ color="icon"
54
+ size="small"
55
+ icon={<CloseFillIcon />}
56
+ onClick={onClose}
57
+ />
58
+ )}
59
+ </Component>
60
+ </>
61
+ );
62
+ }
63
+ );
@@ -0,0 +1,4 @@
1
+ export * from "./AlertDialog";
2
+ export * from "./AlertDialogTitle";
3
+ export * from "./AlertDialogContent";
4
+ export * from "./AlertDialogActions";
@@ -0,0 +1,176 @@
1
+ /** @jsxImportSource @emotion/react */
2
+ import { css, SerializedStyles, Theme, useTheme } from "@emotion/react";
3
+ import styled from "@emotion/styled";
4
+ import React from "react";
5
+ import COLOR from "../foundation/color";
6
+ import { CloseFillIcon } from "../icons/system";
7
+ import { RESET_BUTTON } from "../utils/reset";
8
+
9
+ export type BannerColor = "red" | "blue" | "green" | "yellow";
10
+
11
+ export interface BannerProps {
12
+ className?: string;
13
+ component?: React.ElementType;
14
+
15
+ /** 컴포넌트 내 헤드라인으로 표기될 문자열 */
16
+ headline?: string;
17
+
18
+ /** 컴포넌트 내용으로 표기될 값 */
19
+ content: React.ReactNode;
20
+
21
+ /** 컴포넌트 좌측에 표기될 아이콘 */
22
+ icon?: React.ReactNode;
23
+
24
+ /** 컴포넌트의 색상 */
25
+ color: BannerColor;
26
+
27
+ /** 컴포넌트 우측에 표기될 버튼의 라벨 */
28
+ buttonLabel?: string;
29
+
30
+ /** 컴포넌트 우측 버튼 클릭 시 호출될 콜백 함수 */
31
+ onButtonClick?: () => void;
32
+
33
+ /** 컴포넌트 우측에 표기될 닫기 버튼 유무 */
34
+ close?: boolean;
35
+
36
+ /** 닫기 버튼 클릭 시 호출될 콜백 함수 */
37
+ onClose?: () => void;
38
+
39
+ /** 전체 너비 유무 */
40
+ fullWidth?: boolean;
41
+ }
42
+
43
+ const COLOR_TO_STYLE = (theme: Theme, color: BannerColor): SerializedStyles =>
44
+ ({
45
+ red: css`
46
+ background: ${theme.color.container.dangerContainer};
47
+ color: ${theme.color.container.dangerOnContainer};
48
+ `,
49
+ blue: css`
50
+ background: ${theme.color.container.primaryContainer};
51
+ color: ${theme.color.container.primaryOnContainer};
52
+ `,
53
+ green: css`
54
+ background: ${theme.color.container.successContainer};
55
+ color: ${theme.color.container.successOnContainer};
56
+ `,
57
+ yellow: css`
58
+ background: ${theme.color.container.warningContainer};
59
+ color: ${theme.color.container.warningOnContainer};
60
+ `,
61
+ }[color]);
62
+
63
+ /**
64
+ * [피그마](https://www.figma.com/file/yhrRFizzmhPoHdw9FbYow2/Codle-PD-Kit---Components?type=design&node-id=44-2847&t=bhnL1ombbddld3RQ-0)
65
+ */
66
+ const Banner = React.forwardRef<any, BannerProps>(
67
+ (props, ref): React.ReactElement => {
68
+ const {
69
+ className,
70
+ component: Component = "div",
71
+ headline,
72
+ content,
73
+ icon,
74
+ color,
75
+ buttonLabel,
76
+ onButtonClick,
77
+ close,
78
+ onClose,
79
+ fullWidth,
80
+ ...other
81
+ } = props;
82
+ const theme = useTheme();
83
+ return (
84
+ <Component
85
+ {...other}
86
+ ref={ref}
87
+ className={className}
88
+ css={[
89
+ css`
90
+ box-sizing: border-box;
91
+ display: flex;
92
+ align-items: center;
93
+ color: ${COLOR.white};
94
+ line-height: 125%;
95
+ `,
96
+ COLOR_TO_STYLE(theme, color),
97
+ fullWidth
98
+ ? css`
99
+ width: 100%;
100
+ `
101
+ : css`
102
+ border-radius: 12px;
103
+ width: fit-content;
104
+ min-width: 343px;
105
+ `,
106
+ ]}
107
+ >
108
+ {icon && <IconDiv>{icon}</IconDiv>}
109
+ <TextContainer setPaddingRight={!close && !buttonLabel}>
110
+ {headline && <HeadlineDiv>{headline}</HeadlineDiv>}
111
+ <div>{content}</div>
112
+ </TextContainer>
113
+ {buttonLabel && (
114
+ <BannerButton onClick={onButtonClick}>{buttonLabel}</BannerButton>
115
+ )}
116
+ {close && (
117
+ <CloseButton onClick={onClose}>
118
+ <StyledCloseFillIcon />
119
+ </CloseButton>
120
+ )}
121
+ </Component>
122
+ );
123
+ }
124
+ );
125
+
126
+ const StyledCloseFillIcon = styled(CloseFillIcon)`
127
+ display: block;
128
+ padding: 14px;
129
+ width: 20px;
130
+ height: 20px;
131
+
132
+ color: currentColor;
133
+ `;
134
+
135
+ const IconDiv = styled.div`
136
+ display: flex;
137
+ align-items: center;
138
+ padding: 16px 0px 16px 16px;
139
+ `;
140
+
141
+ const HeadlineDiv = styled.div`
142
+ font-weight: 700;
143
+ `;
144
+
145
+ const TextContainer = styled.div<{ setPaddingRight: boolean }>`
146
+ flex: 1;
147
+
148
+ display: flex;
149
+ flex-direction: column;
150
+ align-items: flex-start;
151
+ padding: 16px 0px 16px 16px;
152
+ gap: 4px;
153
+ ${(props) =>
154
+ props.setPaddingRight &&
155
+ css`
156
+ padding-right: 16px;
157
+ `};
158
+ `;
159
+
160
+ const BannerButton = styled.button`
161
+ ${RESET_BUTTON}
162
+ display: flex;
163
+ justify-content: center;
164
+ align-items: center;
165
+ padding: 10px 12px;
166
+ cursor: pointer;
167
+ color: currentColor;
168
+ `;
169
+
170
+ const CloseButton = styled.button`
171
+ ${RESET_BUTTON}
172
+ cursor: pointer;
173
+ color: currentColor;
174
+ `;
175
+
176
+ export default Banner;
@@ -0,0 +1,239 @@
1
+ /** @jsxImportSource @emotion/react */
2
+ import { css, SerializedStyles, Theme, useTheme } from "@emotion/react";
3
+ import styled from "@emotion/styled";
4
+ import React from "react";
5
+ import { HOVER } from "../utils/hover";
6
+
7
+ export type ButtonColor =
8
+ | "primary"
9
+ | "secondary"
10
+ | "danger"
11
+ | "textNeutral"
12
+ | "textDanger"
13
+ | "textPrimary";
14
+
15
+ export type ButtonSize = "large" | "medium" | "small" | "xsmall";
16
+
17
+ export interface ButtonProps {
18
+ className?: string;
19
+ component?: React.ElementType;
20
+
21
+ /** 비활성화 여부 */
22
+ disabled?: boolean;
23
+
24
+ /** 컴포넌트 색상 */
25
+ color: ButtonColor;
26
+
27
+ /** 컴포넌트 크기 */
28
+ size: ButtonSize;
29
+
30
+ /** 컴포넌트 좌측에 표기될 아이콘 */
31
+ startIcon?: React.ReactNode;
32
+
33
+ /** 컴포넌트 우측에 표기될 아이콘 */
34
+ endIcon?: React.ReactNode;
35
+
36
+ /** 컴포넌트 내 표기될 문자열 */
37
+ label: string;
38
+
39
+ /** 버튼 클릭 시 호출될 콜백 함수 */
40
+ onClick?: () => void;
41
+ }
42
+
43
+ const COLOR_TO_BUTTON_STYLE = (theme: Theme, color: ButtonColor) =>
44
+ ({
45
+ primary: css`
46
+ background: ${theme.color.background.primary};
47
+ color: ${theme.color.foreground.neutralAlt};
48
+
49
+ ${HOVER(css`
50
+ background: ${theme.color.background.primaryActive};
51
+ `)}
52
+ &:disabled {
53
+ background: ${theme.color.background.primaryDisabled};
54
+ }
55
+ `,
56
+ secondary: css`
57
+ background: ${theme.color.background.neutralAlt};
58
+ color: ${theme.color.foreground.neutralBase};
59
+
60
+ ${HOVER(css`
61
+ background: ${theme.color.background.neutralAltActive};
62
+ color: ${theme.color.foreground.neutralBase};
63
+ `)}
64
+ &:disabled {
65
+ background: ${theme.color.background.neutralAlt};
66
+ color: ${theme.color.foreground.neutralBaseDisabled};
67
+ }
68
+ `,
69
+ danger: css`
70
+ background: ${theme.color.background.danger};
71
+ color: ${theme.color.foreground.neutralAlt};
72
+
73
+ ${HOVER(css`
74
+ background: ${theme.color.background.dangerActive};
75
+ `)}
76
+ &:disabled {
77
+ background: ${theme.color.background.dangerDisabled};
78
+ }
79
+ `,
80
+ textNeutral: css`
81
+ background: none;
82
+ color: ${theme.color.foreground.neutralBase};
83
+
84
+ ${HOVER(css`
85
+ background: ${theme.color.background.neutralAltActive};
86
+ color: ${theme.color.foreground.neutralBase};
87
+ `)}
88
+ &:disabled {
89
+ background: none;
90
+ color: ${theme.color.foreground.neutralBaseDisabled};
91
+ }
92
+ `,
93
+ textDanger: css`
94
+ background: none;
95
+ color: ${theme.color.foreground.danger};
96
+
97
+ ${HOVER(css`
98
+ background: ${theme.color.background.neutralAltActive};
99
+ color: ${theme.color.foreground.danger};
100
+ `)}
101
+ &:disabled {
102
+ background: none;
103
+ color: ${theme.color.foreground.dangerDisabled};
104
+ }
105
+ `,
106
+ textPrimary: css`
107
+ background: none;
108
+ color: ${theme.color.foreground.primary};
109
+
110
+ ${HOVER(css`
111
+ background: ${theme.color.background.neutralAltActive};
112
+ color: ${theme.color.foreground.primary};
113
+ `)}
114
+ &:disabled {
115
+ background: none;
116
+ color: ${theme.color.foreground.primaryDisabled};
117
+ }
118
+ `,
119
+ }[color]);
120
+
121
+ const SIZE_TO_BUTTON_STYLE: { [K in ButtonSize]: SerializedStyles } = {
122
+ large: css`
123
+ padding: 16px 20px;
124
+ gap: 10px;
125
+
126
+ svg {
127
+ width: 24px;
128
+ height: 24px;
129
+ }
130
+ `,
131
+ medium: css`
132
+ padding: 14px 16px;
133
+ gap: 8px;
134
+
135
+ svg {
136
+ width: 20px;
137
+ height: 20px;
138
+ }
139
+ `,
140
+ small: css`
141
+ padding: 10px 12px;
142
+ gap: 8px;
143
+
144
+ svg {
145
+ width: 16px;
146
+ height: 16px;
147
+ }
148
+ `,
149
+ xsmall: css`
150
+ padding: 6px 8px;
151
+ gap: 4px;
152
+
153
+ svg {
154
+ width: 12px;
155
+ height: 12px;
156
+ }
157
+ `,
158
+ };
159
+
160
+ const SIZE_TO_LABEL_STYLE: { [K in ButtonSize]: SerializedStyles } = {
161
+ large: css`
162
+ font-size: 20px;
163
+ line-height: 24px;
164
+ `,
165
+ medium: css`
166
+ font-size: 18px;
167
+ line-height: 20px;
168
+ `,
169
+ small: css`
170
+ font-size: 14px;
171
+ line-height: 16px;
172
+ `,
173
+ xsmall: css`
174
+ font-size: 14px;
175
+ line-height: 16px;
176
+ `,
177
+ };
178
+
179
+ /**
180
+ * [피그마](https://www.figma.com/file/yhrRFizzmhPoHdw9FbYow2/Codle-PD-Kit---Components?type=design&node-id=20-173&t=cXcCv3QijbX7MkoC-0)
181
+ */
182
+ const Button = React.forwardRef<any, ButtonProps>(
183
+ (props, ref): React.ReactElement => {
184
+ const {
185
+ className,
186
+ component: Component = "button",
187
+ disabled,
188
+ color,
189
+ size,
190
+ startIcon,
191
+ endIcon,
192
+ label,
193
+ onClick,
194
+ ...other
195
+ } = props;
196
+ const theme = useTheme();
197
+
198
+ return (
199
+ <Component
200
+ {...other}
201
+ className={className}
202
+ ref={ref}
203
+ css={[
204
+ css`
205
+ display: inline-flex;
206
+ align-items: center;
207
+ gap: 8px;
208
+
209
+ border: none;
210
+ border-radius: 8px;
211
+
212
+ cursor: pointer;
213
+ &:disabled {
214
+ cursor: default;
215
+ pointer-events: none;
216
+ }
217
+
218
+ font: inherit;
219
+ `,
220
+ COLOR_TO_BUTTON_STYLE(theme, color),
221
+ SIZE_TO_BUTTON_STYLE[size],
222
+ ]}
223
+ disabled={disabled}
224
+ onClick={onClick}
225
+ >
226
+ {startIcon}
227
+ <Label size={size}>{label}</Label>
228
+ {endIcon}
229
+ </Component>
230
+ );
231
+ }
232
+ );
233
+
234
+ const Label = styled.span<{ size: ButtonSize }>`
235
+ font-weight: 400;
236
+ ${({ size }) => SIZE_TO_LABEL_STYLE[size]}
237
+ `;
238
+
239
+ export default Button;