diff --git a/.changeset/stupid-carrots-study.md b/.changeset/stupid-carrots-study.md
new file mode 100644
index 00000000..b9d387ae
--- /dev/null
+++ b/.changeset/stupid-carrots-study.md
@@ -0,0 +1,6 @@
+---
+"wowds-tokens": patch
+"wowds-ui": patch
+---
+
+Button 컴포넌트의 추가 스펙을 구현합니다.
diff --git a/packages/wow-tokens/src/shadow.ts b/packages/wow-tokens/src/shadow.ts
index c2d6a276..3a0e7829 100644
--- a/packages/wow-tokens/src/shadow.ts
+++ b/packages/wow-tokens/src/shadow.ts
@@ -1,4 +1,4 @@
-import { color } from "./index.ts";
+import * as color from "./color.ts";
export const blue = {
offsetX: 0,
diff --git a/packages/wow-ui/src/components/Button/Button.stories.tsx b/packages/wow-ui/src/components/Button/Button.stories.tsx
index c19c9ef7..5b043ede 100644
--- a/packages/wow-ui/src/components/Button/Button.stories.tsx
+++ b/packages/wow-ui/src/components/Button/Button.stories.tsx
@@ -1,4 +1,5 @@
import type { Meta, StoryObj } from "@storybook/react";
+import { Help } from "wowds-icons";
import Button from "@/components/Button";
@@ -166,3 +167,37 @@ export const SmallOutline: Story = {
variant: "outline",
},
};
+
+export const SmallSub: Story = {
+ args: {
+ children: "버튼",
+ size: "sm",
+ variant: "sub",
+ },
+};
+
+export const LargeWithIcon: Story = {
+ args: {
+ children: "버튼",
+ variant: "solid",
+ icon: ,
+ },
+};
+
+export const SmallWithIcon: Story = {
+ args: {
+ children: "버튼",
+ size: "sm",
+ variant: "solid",
+ icon: ,
+ },
+};
+
+export const LargeWithSubText: Story = {
+ args: {
+ children: "버튼",
+ variant: "solid",
+ subText: "최종 수정 일시 : 2024년 5월 23일 23:11",
+ icon: ,
+ },
+};
diff --git a/packages/wow-ui/src/components/Button/index.tsx b/packages/wow-ui/src/components/Button/index.tsx
index 9210c7db..a8529843 100644
--- a/packages/wow-ui/src/components/Button/index.tsx
+++ b/packages/wow-ui/src/components/Button/index.tsx
@@ -16,9 +16,11 @@ import type {
* @description 버튼 컴포넌트의 속성을 정의합니다.
*
* @param {ReactNode} children - 버튼의 자식 요소.
+ * @param {string} [subText] - 버튼의 하단에 위치할 보조 텍스트.
* @param {boolean} [disabled] - 버튼이 비활성화되어 있는지 여부.
* @param {"lg" | "sm"} [size] - 버튼의 크기.
- * @param {"solid" | "outline"} [variant] - 버튼의 종류.
+ * @param {"solid" | "outline" | "sub"} [variant] - 버튼의 종류.
+ * @param {ReactNode} [icon] - 버튼의 좌측에 들어갈 아이콘.
* @param {() => void} [onKeyUp] - 버튼에 포커스 된 상태에서 엔터 키 또는 스페이스 바를 뗐을 때 동작할 이벤트.
* @param {() => void} [onKeyDown] - 버튼에 포커스 된 상태에서 엔터 키 또는 스페이스 바를 누르고 있는 동안 동작할 이벤트.
* @param {() => void} [onMouseLeave] - 버튼의 영역에서 마우스가 벗어났을 때 동작할 이벤트.
@@ -32,9 +34,11 @@ import type {
export interface CustomButtonProps {
children: ReactNode;
+ subText?: string;
disabled?: boolean;
size?: "lg" | "sm";
- variant?: "solid" | "outline";
+ variant?: "solid" | "outline" | "sub";
+ icon?: ReactNode;
onKeyUp?: () => void;
onKeyDown?: () => void;
onMouseLeave?: () => void;
@@ -58,9 +62,11 @@ const Button: ButtonComponent & { displayName?: string } = forwardRef(
{
as,
children,
+ subText,
disabled = false,
size = "lg",
variant = "solid",
+ icon,
onKeyUp,
onKeyDown,
onMouseLeave,
@@ -95,7 +101,7 @@ const Button: ButtonComponent & { displayName?: string } = forwardRef(
disabled={disabled}
ref={ref}
className={ButtonStyle({
- size,
+ size: variant === "sub" ? "sm" : size,
variant,
})}
onKeyDown={handleKeyDown}
@@ -105,13 +111,11 @@ const Button: ButtonComponent & { displayName?: string } = forwardRef(
onPointerUp={handlePointerUp}
{...rest}
>
-
+
+ {icon}
{children}
+ {subText && {subText}}
);
}
@@ -120,8 +124,10 @@ const Button: ButtonComponent & { displayName?: string } = forwardRef(
const ButtonStyle = cva({
base: {
display: "flex",
+ flexDirection: "column",
alignItems: "center",
justifyContent: "center",
+ gap: "xs",
cursor: "pointer",
},
@@ -130,7 +136,6 @@ const ButtonStyle = cva({
lg: {
width: "100%",
maxWidth: { lgOnly: 316 },
- height: "3rem",
padding: "1rem",
borderRadius: "md",
},
@@ -145,7 +150,8 @@ const ButtonStyle = cva({
color: "textWhite",
_disabled: {
- background: "darkDisabled",
+ background: "monoBackgroundPressed",
+ color: "outline",
cursor: "not-allowed",
},
_hover: {
@@ -178,6 +184,21 @@ const ButtonStyle = cva({
color: "bluePressed",
},
},
+ sub: {
+ background: "blueBackgroundPressed",
+ color: "primary",
+
+ _disabled: {
+ color: "blueDisabled",
+ cursor: "not-allowed",
+ },
+ _hover: {
+ shadow: "blue",
+ },
+ _pressed: {
+ background: "blueDisabled",
+ },
+ },
},
},
compoundVariants: [
@@ -202,5 +223,25 @@ const ButtonStyle = cva({
],
});
+const ContentStyle = cva({
+ base: {
+ display: "flex",
+ alignItems: "center",
+ justifyContent: "center",
+ },
+ variants: {
+ size: {
+ lg: {
+ gap: "xs",
+ textStyle: "label1",
+ },
+ sm: {
+ gap: "xxs",
+ textStyle: "label2",
+ },
+ },
+ },
+});
+
Button.displayName = "Button";
export default Button;