From 3cc30fcf633e791eb36de3e01d76b41096a9f759 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=ED=98=84=EC=98=81?= <89445100+hamo-o@users.noreply.github.com> Date: Fri, 23 Aug 2024 17:38:52 +0900 Subject: [PATCH] =?UTF-8?q?[Fix]=20LinkButton=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8F=84=EB=A1=9D=20as=20prop?= =?UTF-8?q?=EC=9D=98=20=EB=84=A4=EC=9D=B4=EB=B0=8D=20=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?(#146)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: as -> asProp 이름 변경 * fix: Chip 테스트코드 prop 변경 * fix: Button, TextButton as prop 쓰인 부분 수정 * fix: LinkButton 스토리북 prop 이름 변경 * chore: changeset 추가 * fix: pressed 속성 active 속성으로 변경 * remove: useButton 훅 삭제 --- .changeset/slow-shirts-compete.md | 5 ++ apps/wow-docs/app/page.tsx | 5 ++ packages/wow-ui/panda.config.ts | 3 - .../src/components/Button/Button.stories.tsx | 67 +++++------------- .../wow-ui/src/components/Button/index.tsx | 45 ++---------- .../src/components/Chip/Chip.stories.tsx | 6 +- .../wow-ui/src/components/Chip/Chip.test.tsx | 8 +-- packages/wow-ui/src/components/Chip/index.tsx | 4 +- .../TextButton/TextButton.stories.tsx | 42 +---------- .../src/components/TextButton/index.tsx | 49 +------------ packages/wow-ui/src/hooks/useButton.ts | 70 ------------------- packages/wow-ui/src/types/Polymorphic.ts | 2 +- 12 files changed, 48 insertions(+), 258 deletions(-) create mode 100644 .changeset/slow-shirts-compete.md delete mode 100644 packages/wow-ui/src/hooks/useButton.ts diff --git a/.changeset/slow-shirts-compete.md b/.changeset/slow-shirts-compete.md new file mode 100644 index 00000000..eaaecb24 --- /dev/null +++ b/.changeset/slow-shirts-compete.md @@ -0,0 +1,5 @@ +--- +"wowds-ui": patch +--- + +Button 컴포넌트가 Link로 사용될 수 있도록 합니다. diff --git a/apps/wow-docs/app/page.tsx b/apps/wow-docs/app/page.tsx index 3d93c599..d89460d2 100644 --- a/apps/wow-docs/app/page.tsx +++ b/apps/wow-docs/app/page.tsx @@ -1,3 +1,5 @@ +import Link from "next/link"; +import Button from "wowds-ui/Button"; import Checkbox from "wowds-ui/Checkbox"; import Chip from "wowds-ui/Chip"; import Divider from "wowds-ui/Divider"; @@ -12,6 +14,9 @@ import Switch from "wowds-ui/Switch"; const Home = () => { return ( <> + diff --git a/packages/wow-ui/panda.config.ts b/packages/wow-ui/panda.config.ts index 9d15fe01..a5316864 100644 --- a/packages/wow-ui/panda.config.ts +++ b/packages/wow-ui/panda.config.ts @@ -32,7 +32,4 @@ export default defineConfig({ }, }, outdir: "styled-system", - conditions: { - hover: "&[aria-pressed=false]:not(:disabled):hover", - }, }); diff --git a/packages/wow-ui/src/components/Button/Button.stories.tsx b/packages/wow-ui/src/components/Button/Button.stories.tsx index 5b043ede..64928847 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 Link from "next/link"; import { Help } from "wowds-icons"; import Button from "@/components/Button"; @@ -25,7 +26,7 @@ const meta = { type: "text", }, }, - as: { + asProp: { description: "버튼을 구성할 HTML 태그의 종류를 나타냅니다.", table: { type: { summary: "ElementType" }, @@ -64,46 +65,6 @@ const meta = { options: ["solid", "outline"], }, }, - onKeyDown: { - description: - "버튼에 포커스 된 상태에서 엔터 키 또는 스페이스 바를 누르고 있는 동안 동작할 이벤트를 나타냅니다.", - table: { - type: { summary: "() => void" }, - }, - control: false, - }, - onKeyUp: { - description: - "버튼에 포커스 된 상태에서 엔터 키 또는 스페이스 바를 뗐을 때 동작할 이벤트를 나타냅니다.", - table: { - type: { summary: "() => void" }, - }, - control: false, - }, - onMouseLeave: { - description: - "버튼의 영역에서 마우스가 벗어났을 때 동작할 이벤트를 나타냅니다.", - table: { - type: { summary: "() => void" }, - }, - control: false, - }, - onPointerDown: { - description: - "버튼에 포커스 된 상태에서 마우스 또는 터치로 누르고 있는 동안 동작할 이벤트를 나타냅니다.", - table: { - type: { summary: "() => void" }, - }, - control: false, - }, - onPointerUp: { - description: - "버튼에 포커스 된 상태에서 마우스 또는 터치를 뗐을 때 동작할 이벤트를 나타냅니다.", - table: { - type: { summary: "() => void" }, - }, - control: false, - }, style: { description: "버튼의 커스텀 스타일을 나타냅니다.", table: { @@ -138,21 +99,21 @@ export const Primary: Story = { }, }; -export const LargeSolid: Story = { +export const LargeSolidButton: Story = { args: { children: "버튼", variant: "solid", }, }; -export const LargeOutline: Story = { +export const LargeOutlineButton: Story = { args: { children: "버튼", variant: "outline", }, }; -export const SmallSolid: Story = { +export const SmallSolidButton: Story = { args: { children: "버튼", size: "sm", @@ -160,7 +121,7 @@ export const SmallSolid: Story = { }, }; -export const SmallOutline: Story = { +export const SmallOutlineButton: Story = { args: { children: "버튼", size: "sm", @@ -168,7 +129,7 @@ export const SmallOutline: Story = { }, }; -export const SmallSub: Story = { +export const SmallSubButton: Story = { args: { children: "버튼", size: "sm", @@ -176,7 +137,7 @@ export const SmallSub: Story = { }, }; -export const LargeWithIcon: Story = { +export const LargeButtonWithIcon: Story = { args: { children: "버튼", variant: "solid", @@ -184,7 +145,7 @@ export const LargeWithIcon: Story = { }, }; -export const SmallWithIcon: Story = { +export const SmallButtonWithIcon: Story = { args: { children: "버튼", size: "sm", @@ -193,7 +154,7 @@ export const SmallWithIcon: Story = { }, }; -export const LargeWithSubText: Story = { +export const LargeButtonWithSubText: Story = { args: { children: "버튼", variant: "solid", @@ -201,3 +162,11 @@ export const LargeWithSubText: Story = { icon: , }, }; + +export const LinkButton: Story = { + args: { + children: "버튼", + asProp: Link, + href: "/", + }, +}; diff --git a/packages/wow-ui/src/components/Button/index.tsx b/packages/wow-ui/src/components/Button/index.tsx index a8529843..d6e32a30 100644 --- a/packages/wow-ui/src/components/Button/index.tsx +++ b/packages/wow-ui/src/components/Button/index.tsx @@ -5,7 +5,6 @@ import { styled } from "@styled-system/jsx"; import type { CSSProperties, ElementType, ReactNode } from "react"; import { forwardRef } from "react"; -import useButton from "@/hooks/useButton"; import type { PolymorphicComponentProps, PolymorphicComponentPropsWithRef, @@ -21,11 +20,6 @@ import type { * @param {"lg" | "sm"} [size] - 버튼의 크기. * @param {"solid" | "outline" | "sub"} [variant] - 버튼의 종류. * @param {ReactNode} [icon] - 버튼의 좌측에 들어갈 아이콘. - * @param {() => void} [onKeyUp] - 버튼에 포커스 된 상태에서 엔터 키 또는 스페이스 바를 뗐을 때 동작할 이벤트. - * @param {() => void} [onKeyDown] - 버튼에 포커스 된 상태에서 엔터 키 또는 스페이스 바를 누르고 있는 동안 동작할 이벤트. - * @param {() => void} [onMouseLeave] - 버튼의 영역에서 마우스가 벗어났을 때 동작할 이벤트. - * @param {() => void} [onPointerDown] - 버튼에 포커스 된 상태에서 마우스 또는 터치로 누르고 있는 동안 동작할 이벤트. - * @param {() => void} [onPointerUp] - 버튼에 포커스 된 상태에서 마우스 또는 터치를 뗐을 때 동작할 이벤트. * @param {CSSProperties} [style] - 버튼의 커스텀 스타일. * @param {string} [className] - 버튼에 전달하는 커스텀 클래스. * @param {ComponentPropsWithoutRef} rest 렌더링된 요소 또는 컴포넌트에 전달할 추가 props. @@ -60,55 +54,28 @@ type ButtonComponent = ( const Button: ButtonComponent & { displayName?: string } = forwardRef( ( { - as, + asProp, children, subText, disabled = false, size = "lg", variant = "solid", icon, - onKeyUp, - onKeyDown, - onMouseLeave, - onPointerDown, - onPointerUp, ...rest }: ButtonProps, ref?: PolymorphicRef ) => { - const Component = as || "button"; - - const { - pressed, - handleKeyDown, - handleKeyUp, - handlePointerDown, - handlePointerUp, - handleMouseLeave, - } = useButton({ - disabled, - onMouseLeave, - onKeyUp, - onKeyDown, - onPointerDown, - onPointerUp, - }); + const Component = asProp || "button"; return ( @@ -157,7 +124,7 @@ const ButtonStyle = cva({ _hover: { shadow: "blue", }, - _pressed: { + _active: { background: "bluePressed", }, }, @@ -178,7 +145,7 @@ const ButtonStyle = cva({ borderColor: "blueHover", color: "blueHover", }, - _pressed: { + _active: { borderColor: "bluePressed", background: "blueBackgroundPressed", color: "bluePressed", @@ -195,7 +162,7 @@ const ButtonStyle = cva({ _hover: { shadow: "blue", }, - _pressed: { + _active: { background: "blueDisabled", }, }, @@ -213,7 +180,7 @@ const ButtonStyle = cva({ borderColor: "textBlack", color: "textBlack", }, - _pressed: { + _active: { borderColor: "outline", background: "monoBackgroundPressed", color: "textBlack", diff --git a/packages/wow-ui/src/components/Chip/Chip.stories.tsx b/packages/wow-ui/src/components/Chip/Chip.stories.tsx index fea4a284..30b2773b 100644 --- a/packages/wow-ui/src/components/Chip/Chip.stories.tsx +++ b/packages/wow-ui/src/components/Chip/Chip.stories.tsx @@ -105,7 +105,7 @@ type Story = StoryObj; export const Default: Story = { args: { label: "Chip", - as: "button", + asProp: "button", clickable: true, }, }; @@ -114,7 +114,7 @@ export const DivChip: Story = { args: { label: "Chip", clickable: false, - as: "div", + asProp: "div", }, }; export const DisabledChip: Story = { @@ -122,7 +122,7 @@ export const DisabledChip: Story = { label: "Chip", clickable: true, disabled: true, - as: "button", + asProp: "button", }, }; diff --git a/packages/wow-ui/src/components/Chip/Chip.test.tsx b/packages/wow-ui/src/components/Chip/Chip.test.tsx index 59bc4b66..3354219f 100644 --- a/packages/wow-ui/src/components/Chip/Chip.test.tsx +++ b/packages/wow-ui/src/components/Chip/Chip.test.tsx @@ -6,7 +6,7 @@ import Chip from "@/components/Chip"; describe("Chip rendering Test", () => { let renderChip: RenderResult; beforeEach(() => { - renderChip = render(); + renderChip = render(); }); it("should render Chip", () => { @@ -24,7 +24,7 @@ describe("Chip rendering Test", () => { describe("Chip toggle Test", () => { let renderChip: RenderResult; beforeEach(() => { - renderChip = render(); + renderChip = render(); }); it("should toggle state when onClick event is fired", async () => { @@ -94,7 +94,7 @@ describe("external control and events", () => { }); it("should fire external onKeyDown event", async () => { - renderChip = render(); + renderChip = render(); const user = userEvent.setup(); const chipComponent = renderChip.getByRole("checkbox"); const onKeyDownHandler = jest.fn(); @@ -112,7 +112,7 @@ describe("external control and events", () => { const handleChange = () => { checked = !checked; }; - const rendered = render(); + const rendered = render(); const chipComponent = rendered.getByRole("checkbox"); chipComponent.onchange = handleChange; diff --git a/packages/wow-ui/src/components/Chip/index.tsx b/packages/wow-ui/src/components/Chip/index.tsx index 23a89efe..ddfbd67d 100644 --- a/packages/wow-ui/src/components/Chip/index.tsx +++ b/packages/wow-ui/src/components/Chip/index.tsx @@ -66,7 +66,7 @@ const ChipLabel = ({ const Chip: ChipComponent & { displayName?: string } = forwardRef( ( { - as, + asProp, label, clickable, onKeyDown, @@ -78,7 +78,7 @@ const Chip: ChipComponent & { displayName?: string } = forwardRef( }: ChipProps, ref: any ) => { - const Component = (as || "button") as React.ElementType; + const Component = (asProp || "button") as React.ElementType; const [ischecked, setIsChecked] = useState(() => checkedProp ? checkedProp : defaultChecked ); diff --git a/packages/wow-ui/src/components/TextButton/TextButton.stories.tsx b/packages/wow-ui/src/components/TextButton/TextButton.stories.tsx index 8afd64e3..71ccfc18 100644 --- a/packages/wow-ui/src/components/TextButton/TextButton.stories.tsx +++ b/packages/wow-ui/src/components/TextButton/TextButton.stories.tsx @@ -19,7 +19,7 @@ const meta = { type: "text", }, }, - as: { + asProp: { description: "텍스트 버튼을 구성할 HTML 태그의 종류를 나타냅니다.", table: { type: { summary: "ElementType" }, @@ -47,46 +47,6 @@ const meta = { options: ["lg", "sm"], }, }, - onKeyDown: { - description: - "텍스트 버튼에 포커스 된 상태에서 엔터 키 또는 스페이스 바를 누르고 있는 동안 동작할 이벤트를 나타냅니다.", - table: { - type: { summary: "() => void" }, - }, - control: false, - }, - onKeyUp: { - description: - "텍스트 버튼에 포커스 된 상태에서 엔터 키 또는 스페이스 바를 뗐을 때 동작할 이벤트를 나타냅니다.", - table: { - type: { summary: "() => void" }, - }, - control: false, - }, - onMouseLeave: { - description: - "텍스트 버튼의 영역에서 마우스가 벗어났을 때 동작할 이벤트를 나타냅니다.", - table: { - type: { summary: "() => void" }, - }, - control: false, - }, - onPointerDown: { - description: - "텍스트 버튼에 포커스 된 상태에서 마우스 또는 터치로 누르고 있는 동안 동작할 이벤트를 나타냅니다.", - table: { - type: { summary: "() => void" }, - }, - control: false, - }, - onPointerUp: { - description: - "텍스트 버튼에 포커스 된 상태에서 마우스 또는 터치를 뗐을 때 동작할 이벤트를 나타냅니다.", - table: { - type: { summary: "() => void" }, - }, - control: false, - }, style: { description: "텍스트 버튼의 커스텀 스타일을 나타냅니다.", table: { diff --git a/packages/wow-ui/src/components/TextButton/index.tsx b/packages/wow-ui/src/components/TextButton/index.tsx index 30d1b19a..b5b43ab0 100644 --- a/packages/wow-ui/src/components/TextButton/index.tsx +++ b/packages/wow-ui/src/components/TextButton/index.tsx @@ -5,7 +5,6 @@ import { styled } from "@styled-system/jsx"; import type { CSSProperties, ElementType, ReactNode } from "react"; import { forwardRef } from "react"; -import useButton from "@/hooks/useButton"; import type { PolymorphicComponentProps, PolymorphicComponentPropsWithRef, @@ -18,10 +17,6 @@ import type { * @param {string} text - 텍스트 버튼의 라벨. * @param {boolean} [disabled] - 텍스트 버튼이 비활성화되어 있는지 여부. * @param {"lg" | "sm"} [size] - 텍스트 버튼의 크기. - * @param {() => void} [onKeyDown] - 텍스트 버튼에 포커스 된 상태에서 엔터 키 또는 스페이스 바를 누르고 있는 동안 동작할 이벤트. - * @param {() => void} [onMouseLeave] - 텍스트 버튼의 영역에서 마우스가 벗어났을 때 동작할 이벤트. - * @param {() => void} [onPointerDown] - 텍스트 버튼에 포커스 된 상태에서 마우스 또는 터치로 누르고 있는 동안 동작할 이벤트. - * @param {() => void} [onPointerUp] - 텍스트 버튼에 포커스 된 상태에서 마우스 또는 터치를 뗐을 때 동작할 이벤트. * @param {CSSProperties} [style] - 텍스트 버튼의 커스텀 스타일. * @param {string} [className] - 텍스트 버튼에 전달하는 커스텀 클래스. * @param {ComponentPropsWithoutRef} rest 렌더링된 요소 또는 컴포넌트에 전달할 추가 props. @@ -32,11 +27,6 @@ export interface CustomButtonProps { text: string; disabled?: boolean; size?: "lg" | "sm"; - onKeyUp?: () => void; - onKeyDown?: () => void; - onMouseLeave?: () => void; - onPointerDown?: () => void; - onPointerUp?: () => void; style?: CSSProperties; className?: string; } @@ -52,50 +42,17 @@ type ButtonComponent = ( const TextButton: ButtonComponent & { displayName?: string } = forwardRef( ( - { - as, - text, - disabled = false, - size = "lg", - onKeyUp, - onKeyDown, - onMouseLeave, - onPointerDown, - onPointerUp, - ...rest - }: ButtonProps, + { asProp, text, disabled = false, size = "lg", ...rest }: ButtonProps, ref?: PolymorphicRef ) => { - const Component = as || "button"; - - const { - pressed, - handleKeyDown, - handleKeyUp, - handlePointerDown, - handlePointerUp, - handleMouseLeave, - } = useButton({ - disabled, - onKeyUp, - onKeyDown, - onMouseLeave, - onPointerDown, - onPointerUp, - }); + const Component = asProp || "button"; return ( void; - onKeyUp?: () => void; - onKeyDown?: () => void; - onPointerDown?: () => void; - onPointerUp?: () => void; -} - -const useButton = ({ - disabled = false, - onMouseLeave, - onKeyUp, - onKeyDown, - onPointerDown, - onPointerUp, -}: UseButtonProps) => { - const [pressed, setPressed] = useState(false); - - const handleMouseLeave = useCallback(() => { - if (!disabled) setPressed(false); - onMouseLeave?.(); - }, [setPressed, disabled, onMouseLeave]); - - const handlePointerDown = useCallback(() => { - if (!disabled) setPressed(true); - onPointerDown?.(); - }, [setPressed, disabled, onPointerDown]); - - const handlePointerUp = useCallback(() => { - if (!disabled) setPressed(false); - onPointerUp?.(); - }, [setPressed, disabled, onPointerUp]); - - const handleKeyDown = useCallback( - (event: KeyboardEvent) => { - if (event.key === " " || event.key === "Enter") { - setPressed(true); - onKeyDown?.(); - } - }, - [setPressed, onKeyDown] - ); - - const handleKeyUp = useCallback( - (event: KeyboardEvent) => { - if (event.key === " " || event.key === "Enter") { - setPressed(false); - onKeyUp?.(); - } - }, - [setPressed, onKeyUp] - ); - - return { - pressed, - handleKeyDown, - handleKeyUp, - handleMouseLeave, - handlePointerDown, - handlePointerUp, - }; -}; - -export default useButton; diff --git a/packages/wow-ui/src/types/Polymorphic.ts b/packages/wow-ui/src/types/Polymorphic.ts index 7193309d..72c7681c 100644 --- a/packages/wow-ui/src/types/Polymorphic.ts +++ b/packages/wow-ui/src/types/Polymorphic.ts @@ -5,7 +5,7 @@ import type { } from "react"; export interface AsProps { - as?: T; + asProp?: T; } export type PolymorphicRef =