Skip to content

Commit 2c3b7ae

Browse files
committed
feat: base button 컴포넌트 추가, button, icon button 컴포넌트 수정
1 parent de510ac commit 2c3b7ae

File tree

9 files changed

+96
-34
lines changed

9 files changed

+96
-34
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
@use "@/styles/mixins" as *;
2+
3+
.BaseButton {
4+
cursor: pointer;
5+
margin: 0;
6+
border: none;
7+
border-radius: 0.875rem;
8+
width: 100%;
9+
height: 3.25rem;
10+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import React from "react";
2+
3+
import classNames from "classnames";
4+
5+
import styles from "@/components/ui/BaseButton/BaseButton.module.scss";
6+
import type { BaseButtonProps } from "@/components/ui/BaseButton/BaseButton.types";
7+
8+
const BaseButton = React.forwardRef<HTMLButtonElement, BaseButtonProps>(
9+
({ className, children, type = "button", ...props }, ref) => {
10+
return (
11+
<button className={classNames(styles.BaseButton, className)} ref={ref} type={type} {...props}>
12+
{children}
13+
</button>
14+
);
15+
},
16+
);
17+
18+
export default BaseButton;
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export interface ButtonOwnProps {
2+
as?: React.ElementType;
3+
text?: string;
4+
}
5+
6+
export type BaseButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement>;

src/components/ui/Button/Button.module.scss

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,6 @@
11
@use "@/styles/mixins" as *;
22

33
.Button {
4-
cursor: pointer;
5-
margin: 0;
6-
border: none;
7-
border-radius: 0.875rem;
8-
padding: 0.875rem;
9-
width: 100%;
10-
height: 3.25rem;
11-
124
&.style-primary {
135
background-color: var(--color-text01);
146
color: var(--color-white);

src/components/ui/Button/Button.tsx

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,37 @@
1-
import React from "react";
1+
import React, { useCallback } from "react";
22

33
import classNames from "classnames";
44

5+
import BaseButton from "@/components/ui/BaseButton/BaseButton";
56
import styles from "@/components/ui/Button/Button.module.scss";
67
import type { ButtonProps } from "@/components/ui/Button/Button.types";
78

89
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
9-
({ className, variant = "primary", text, ...props }, ref) => {
10+
(
11+
{ as = BaseButton, className, variant = "primary", text, disabled = false, onClick, ...props },
12+
ref,
13+
) => {
14+
const Comp = as as typeof BaseButton;
15+
16+
const handleClick = useCallback(
17+
(e: React.MouseEvent<HTMLButtonElement>) => {
18+
if (!disabled) {
19+
onClick?.(e);
20+
}
21+
},
22+
[onClick, disabled],
23+
);
24+
1025
return (
11-
<button
12-
className={classNames(styles.Button, styles[`style-${variant}`], className)}
26+
<Comp
1327
ref={ref}
28+
className={classNames(styles.Button, styles[`style-${variant}`], className)}
29+
disabled={disabled}
30+
onClick={handleClick}
1431
{...props}
1532
>
1633
{text}
17-
</button>
34+
</Comp>
1835
);
1936
},
2037
);
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
export type ButtonVariant = "primary" | "secondary" | "disabled";
1+
import type { ButtonOwnProps } from "@/components/ui/BaseButton/BaseButton.types";
22

3-
export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
4-
type?: "button" | "submit";
5-
text?: string;
3+
type ButtonVariant = "primary" | "secondary" | "disabled";
4+
5+
export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, ButtonOwnProps {
66
variant?: ButtonVariant;
77
}

src/components/ui/IconButton/IconButton.module.scss

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,12 @@
11
@use "@/styles/mixins" as *;
22

33
.IconButton {
4-
cursor: pointer;
5-
margin: 0;
6-
border: none;
7-
border-radius: 0.875rem;
8-
padding: 0.875rem;
9-
width: 100%;
10-
114
display: flex;
125
justify-content: center;
136
align-items: center;
147

158
&.size-md {
169
gap: 0.375rem;
17-
height: 3.25rem;
1810
background-color: var(--color-gray400);
1911
color: var(--color-white);
2012
@include buttonSecondary;

src/components/ui/IconButton/IconButton.tsx

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,48 @@
1-
import React from "react";
1+
import React, { useCallback } from "react";
22

33
import classNames from "classnames";
44

5+
import BaseButton from "@/components/ui/BaseButton/BaseButton";
56
import Icon from "@/components/ui/Icon/Icon";
67
import styles from "@/components/ui/IconButton/IconButton.module.scss";
78
import type { IconButtonProps } from "@/components/ui/IconButton/IconButton.types";
89

910
const IconButton = React.forwardRef<HTMLButtonElement, IconButtonProps>(
10-
({ className, size = "md", text, iconName, ...props }, ref) => {
11+
(
12+
{
13+
as = BaseButton,
14+
className,
15+
size = "md",
16+
disabled = false,
17+
onClick,
18+
text,
19+
iconName,
20+
...props
21+
},
22+
ref,
23+
) => {
24+
const Comp = as as typeof BaseButton;
25+
26+
const handleClick = useCallback(
27+
(e: React.MouseEvent<HTMLButtonElement>) => {
28+
if (!disabled) {
29+
onClick?.(e);
30+
}
31+
},
32+
[onClick, disabled],
33+
);
34+
1135
return (
12-
<button
13-
className={classNames(styles.IconButton, styles[`size-${size}`], className)}
36+
<Comp
1437
ref={ref}
38+
className={classNames(styles.IconButton, styles[`size-${size}`], className)}
39+
disabled={disabled}
40+
onClick={handleClick}
1541
{...props}
1642
>
1743
<Icon name={iconName} />
1844
{text}
19-
</button>
45+
</Comp>
2046
);
2147
},
2248
);
Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1+
import type { ButtonOwnProps } from "@/components/ui/BaseButton/BaseButton.types";
12
import type { IconNameType } from "@/components/ui/Icon/Icon";
23

3-
export type IconButtonSize = "md" | "sm";
4+
type IconButtonSize = "md" | "sm";
45

5-
export interface IconButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
6-
type?: "button" | "submit";
7-
text?: string;
6+
export interface IconButtonProps
7+
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
8+
ButtonOwnProps {
89
size?: IconButtonSize;
910
iconName: IconNameType;
1011
}

0 commit comments

Comments
 (0)