Skip to content

Commit

Permalink
feat: enhance Button component with tone and variant options
Browse files Browse the repository at this point in the history
  • Loading branch information
nhistory committed Jan 22, 2025
1 parent b7b77c0 commit 2a5b378
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 99 deletions.
32 changes: 3 additions & 29 deletions src/components/Button/Button.stories.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,14 @@
import type { Meta, StoryObj } from "@storybook/react";
import { expect, fn, userEvent } from "@storybook/test";
import { Button } from "./Button";

const meta = {
export default {
component: Button,
parameters: {
layout: "centered",
},
args: { onClick: fn() },
} satisfies Meta<typeof Button>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Basic: Story = {
args: {
type: "button",
children: "시작하기",
},
play: async ({ args: { onClick }, canvas, step }) => {
const button = canvas.getByRole("button");

await step("renders a button with text", async () => {
expect(button).toHaveTextContent("시작하기");
});

await step("calls onClick handler when clicked", async () => {
await userEvent.click(button);
expect(onClick).toHaveBeenCalledTimes(1);
});
},
};
} satisfies Meta<typeof Button>;

// export const Submit: Story = {
// args: {
// type: "submit",
// children: "Submit",
// },
// };
export const Basic: StoryObj<typeof Button> = {};
129 changes: 59 additions & 70 deletions src/components/Button/Button.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
import React from "react";
import React, { type HTMLAttributes } from "react";
import { css, cva } from "../../../styled-system/css";
import type { SystemStyleObject } from "@pandacss/types";
// import { colors } from "../../tokens/colors";

type ButtonVariant =
| "solid"
| "outline"
| "outline-gradient"
| "default"
| "accent"
| "danger"
| "warning";
type ButtonVariant = "solid" | "outline" | "transparent";

export interface ButtonProps {
/** 버튼 텍스트 */
type ButtonTone = "primary" | "neutral" | "accent" | "danger" | "warning";

export interface ButtonProps
extends Omit<HTMLAttributes<HTMLElement>, "style"> {
/** 텍스트 */
children: React.ReactNode;
/** 타입 */
type?: "button" | "submit";
onClick?: () => void;
variant?: ButtonVariant;
/** 종류 */
variant: ButtonVariant;
/** 색조 */
tone?: ButtonTone;
/** 추가 스타일 */
style?: SystemStyleObject; // Add style prop for custom inline styles
}

Expand All @@ -28,14 +28,15 @@ export const Button = ({
children,
type = "button",
onClick,
variant = "default",
variant = "solid",
tone = "primary",
style, // destructure the style prop
...rest
}: ButtonProps) => {
return (
<button
className={css(
styles.raw({ variant }),
styles.raw({ tone, variant }),
baseStyles,
...(Array.isArray(style) ? style : [style]) // Ensure style is an array
)}
Expand Down Expand Up @@ -74,84 +75,72 @@ const baseStyles = {
};

const styles = cva({
variants: {
variant: {
default: {
compoundVariants: [
{
variant: "solid",
tone: "primary",
css: {
background: "primary",
color: "{colors.violet.1}",
"&:active, &:hover": {
background: "{colors.violetDark.10}",
},
},
},
{
variant: "solid",
tone: "neutral",
css: {
background: "bg",
color: "text",
"&:active, &:hover": {
background: "bg.hover",
},
},
},
{
variant: "solid",
tone: "neutral",
css: {
background: "bg",
color: "text",
"&:active, &:hover": {
background: "bg.hover",
},
},
accent: {
},
{
variant: "solid",
tone: "accent",
css: {
background: "bg.accent",
color: "text.accent",
"&:active, &:hover": {
background: "bg.hover.accent",
},
},
danger: {
},
{
variant: "solid",
tone: "danger",
css: {
background: "bg.danger",
color: "text.danger",
"&:active, &:hover": {
background: "bg.hover.danger",
},
},
warning: {
},
{
variant: "solid",
tone: "warning",
css: {
background: "bg.warning",
color: "text.warning",
"&:active, &:hover": {
background: "bg.hover.warning",
},
},
solid: {
background: { base: "{colors.violet.9}", _dark: "{colors.violet.9}" },
color: { base: "{colors.violet.1}", _dark: "{colors.violet.1}" },
"&:active, &:hover": {
background: {
base: "{colors.violet.8}",
_dark: "{colors.violetDark.10}",
},
},
},
outline: {
background: {
base: "{colors.violet.2}",
_dark: "{colors.violetDark.8}",
},
color: {
base: "{colors.violetDark.1}",
_dark: "{colors.violet.1}",
},
border: "4px solid",
borderColor: {
base: "{colors.violetDark.10}",
_dark: "{colors.violet.7}",
},
"&:active, &:hover": {
background: {
base: "{colors.violet.4}",
_dark: "{colors.violetDark.10}",
},
},
},
"outline-gradient": {
"--gradient-color":
"linear-gradient(90deg,{colors.teal.9},{colors.violet.10})",
background: "transparent",
color: {
base: "{colors.violetDark.1}",
_dark: "{colors.violet.1}",
},
border: "4px solid transparent",
borderRadius: "10px",
backgroundClip: "padding-box, border-box",
backgroundOrigin: "padding-box, border-box",
borderImage: "var(--gradient-color)",
borderImageSlice: "1",
borderImageOutset: "0",
"&:active, &:hover": {},
},
},
},
],
});
2 changes: 2 additions & 0 deletions src/tokens/colors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ export const semanticColors: SemanticTokens["colors"] = {
base: {
value: { base: "{colors.gray.1}", _dark: "{colors.grayDark.1}" },
},
primary: { value: "{colors.violet.9}" },
secondary: { value: "{colors.teal.9}" },
bg: {
DEFAULT: {
DEFAULT: {
Expand Down

0 comments on commit 2a5b378

Please sign in to comment.