-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #32 from DaleStudy/25-button-component
25 button component
- Loading branch information
Showing
6 changed files
with
437 additions
and
87 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
import type { Meta, StoryObj } from "@storybook/react"; | ||
import { Button } from "./Button"; | ||
import { vstack } from "../../../styled-system/patterns"; | ||
|
||
export default { | ||
component: Button, | ||
parameters: { | ||
layout: "centered", | ||
}, | ||
args: { | ||
children: "์์ํ๊ธฐ", | ||
variant: "solid", | ||
}, | ||
} satisfies Meta<typeof Button>; | ||
|
||
export const Basic: StoryObj<typeof Button> = {}; | ||
|
||
export const Variants: StoryObj<typeof Button> = { | ||
render: (args) => { | ||
return ( | ||
<div className={vstack({ gap: "4" })}> | ||
<Button {...args} variant="solid"> | ||
์๋ฆฌ๋ ๋ฒํผ | ||
</Button> | ||
<Button {...args} variant="outline"> | ||
์์๋ผ์ธ ๋ฒํผ | ||
</Button> | ||
</div> | ||
); | ||
}, | ||
argTypes: { | ||
children: { | ||
control: false, | ||
}, | ||
variant: { | ||
control: false, | ||
}, | ||
}, | ||
}; | ||
|
||
export const Tones: StoryObj<typeof Button> = { | ||
render: (args) => { | ||
return ( | ||
<div className={vstack({ gap: "4" })}> | ||
<Button {...args} tone="neutral"> | ||
์ค๋ฆฝ ์์กฐ | ||
</Button> | ||
<Button {...args} tone="accent"> | ||
๊ฐ์กฐ ์์กฐ | ||
</Button> | ||
<Button {...args} tone="danger"> | ||
์ํ ์์กฐ | ||
</Button> | ||
<Button {...args} tone="warning"> | ||
๊ฒฝ๊ณ ์์กฐ | ||
</Button> | ||
</div> | ||
); | ||
}, | ||
argTypes: { | ||
children: { | ||
control: false, | ||
}, | ||
tone: { | ||
control: false, | ||
}, | ||
}, | ||
}; | ||
|
||
export const Sizes: StoryObj<typeof Button> = { | ||
render: (args) => { | ||
return ( | ||
<div className={vstack({ gap: "4" })}> | ||
<Button {...args} size="sm"> | ||
์์ ๋ฒํผ | ||
</Button> | ||
<Button {...args} size="md"> | ||
์ค๊ฐ ๋ฒํผ | ||
</Button> | ||
<Button {...args} size="lg"> | ||
ํฐ ๋ฒํผ | ||
</Button> | ||
</div> | ||
); | ||
}, | ||
argTypes: { | ||
children: { | ||
control: false, | ||
}, | ||
size: { | ||
control: false, | ||
}, | ||
}, | ||
}; | ||
|
||
export const Disabled: StoryObj<typeof Button> = { | ||
render: (args) => { | ||
return ( | ||
<div className={vstack({ gap: "4" })}> | ||
<Button {...args} disabled> | ||
๋นํ์ฑํ ๋ฒํผ | ||
</Button> | ||
<Button {...args}>ํ์ฑํ ๋ฒํผ</Button> | ||
</div> | ||
); | ||
}, | ||
argTypes: { | ||
children: { | ||
control: false, | ||
}, | ||
disabled: { | ||
control: false, | ||
}, | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,108 @@ | ||
import { render, screen } from "@testing-library/react"; | ||
import userEvent from "@testing-library/user-event"; | ||
import { expect, describe, it, vi } from "vitest"; | ||
import { composeStories } from "@storybook/react"; | ||
import { render, screen, fireEvent } from "@testing-library/react"; | ||
import { expect, test, vi } from "vitest"; | ||
import * as stories from "./Button.stories"; | ||
import { Button } from "./Button"; | ||
|
||
describe("<Button>", () => { | ||
it("renders a button with text", () => { | ||
render(<Button>Click</Button>); | ||
const { Basic, Variants, Tones, Sizes, Disabled } = composeStories(stories); | ||
|
||
expect(screen.getByRole("button")).toHaveTextContent("Click"); | ||
}); | ||
test("renders the button with the correct text content", () => { | ||
render(<Basic>ํ ์คํธ</Basic>); | ||
|
||
it("calls onClick handler when clicked", async () => { | ||
const user = userEvent.setup(); | ||
const handleClick = vi.fn(); | ||
expect(screen.getByText("ํ ์คํธ")).toBeInTheDocument(); | ||
}); | ||
|
||
test("applies the correct variant styles", () => { | ||
render(<Variants />); | ||
|
||
expect(screen.getByText("์๋ฆฌ๋ ๋ฒํผ")).toHaveClass("bg_bg"); | ||
expect(screen.getByText("์์๋ผ์ธ ๋ฒํผ")).toHaveClass("bd_3px_solid"); | ||
}); | ||
|
||
test("applies the correct tone styles", () => { | ||
render(<Tones />); | ||
|
||
expect(screen.getByText("์ค๋ฆฝ ์์กฐ")).toHaveClass("bg_bg"); | ||
expect(screen.getByText("๊ฐ์กฐ ์์กฐ")).toHaveClass("bg_bg.accent"); | ||
expect(screen.getByText("์ํ ์์กฐ")).toHaveClass("bg_bg.danger"); | ||
expect(screen.getByText("๊ฒฝ๊ณ ์์กฐ")).toHaveClass("bg_bg.warning"); | ||
}); | ||
|
||
test("applies the correct font size based on the size prop", () => { | ||
render(<Sizes />); | ||
|
||
expect(screen.getByText("์์ ๋ฒํผ")).toHaveClass("fs_sm"); | ||
expect(screen.getByText("์ค๊ฐ ๋ฒํผ")).toHaveClass("fs_md"); | ||
expect(screen.getByText("ํฐ ๋ฒํผ")).toHaveClass("fs_lg"); | ||
}); | ||
|
||
test("applies the correct disabled styles", () => { | ||
render(<Disabled />); | ||
|
||
render(<Button onClick={handleClick}>Click</Button>); | ||
expect(screen.getByText("๋นํ์ฑํ ๋ฒํผ")).toBeDisabled(); | ||
expect(screen.getByText("ํ์ฑํ ๋ฒํผ")).toBeEnabled(); | ||
expect(screen.getByText("๋นํ์ฑํ ๋ฒํผ")).toHaveClass("[&:disabled]:op_0.5"); | ||
}); | ||
|
||
test("renders a button with type='button' by default", () => { | ||
render(<Basic>Default Button</Basic>); | ||
const button = screen.getByText("Default Button"); | ||
expect(button).toHaveAttribute("type", "button"); | ||
}); | ||
|
||
await user.click(screen.getByRole("button")); | ||
test("renders a button with type='button' by default", () => { | ||
render(<Basic variant="solid">Default Button</Basic>); | ||
const button = screen.getByText("Default Button"); | ||
expect(button).toHaveAttribute("type", "button"); | ||
}); | ||
|
||
test("renders a button with type='button' when specified", () => { | ||
render( | ||
<Button type="button" variant="solid"> | ||
Button Type Button | ||
</Button> | ||
); | ||
const button = screen.getByText("Button Type Button"); | ||
expect(button).toHaveAttribute("type", "button"); | ||
}); | ||
|
||
test("renders a button with type='submit' when specified", () => { | ||
render( | ||
<form> | ||
<Button type="submit" variant="solid"> | ||
Submit Type Button | ||
</Button> | ||
</form> | ||
); | ||
const button = screen.getByText("Submit Type Button"); | ||
expect(button).toHaveAttribute("type", "submit"); | ||
}); | ||
|
||
test("submits the form when type='submit' button is clicked", () => { | ||
const handleSubmit = vi.fn(); | ||
render( | ||
<form onSubmit={handleSubmit}> | ||
<Button type="submit" variant="solid"> | ||
Submit Button | ||
</Button> | ||
</form> | ||
); | ||
|
||
const submitButton = screen.getByText("Submit Button"); | ||
fireEvent.click(submitButton); | ||
expect(handleSubmit).toHaveBeenCalledTimes(1); | ||
}); | ||
|
||
expect(handleClick).toHaveBeenCalledTimes(1); | ||
}); | ||
test("does not submit the form when type='button' button is clicked", () => { | ||
const handleSubmit = vi.fn(); | ||
render( | ||
<form onSubmit={handleSubmit}> | ||
<Button type="button" variant="solid"> | ||
Button Type Button | ||
</Button> | ||
</form> | ||
); | ||
const buttonTypeButton = screen.getByText("Button Type Button"); | ||
fireEvent.click(buttonTypeButton); | ||
expect(handleSubmit).toHaveBeenCalledTimes(0); | ||
}); |
Oops, something went wrong.