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;