Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Box 컴포넌트 구현 #45

Merged
merged 20 commits into from
Jun 23, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions packages/wow-icons/src/component/RightArrow.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { forwardRef } from "react";
import { color } from "wowds-tokens";

import type { IconProps } from "@/types/Icon.ts";

const RightArrow = forwardRef<SVGSVGElement, IconProps>(
(
{
className,
width = "20",
height = "21",
viewBox = "0 0 20 21",
stroke = "white",
...rest
},
ref
) => {
return (
<svg
aria-label="rightArrow icon"
className={className}
fill="none"
height={height}
ref={ref}
viewBox={viewBox}
width={width}
xmlns="http://www.w3.org/2000/svg"
{...rest}
>
<path
d="M10 4.5L15 10.5L10 16.5"
stroke={color[stroke]}
strokeLinejoin="bevel"
strokeWidth="1.4"
/>
</svg>
);
}
);

RightArrow.displayName = "RightArrow";
export default RightArrow;
1 change: 1 addition & 0 deletions packages/wow-icons/src/component/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { default as Check } from "./Check.tsx";
export { default as RightArrow } from "./RightArrow.tsx";
3 changes: 3 additions & 0 deletions packages/wow-icons/src/svg/rightArrow.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions packages/wow-tokens/src/color.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export const mono900 = "#242424";
export const mono950 = "#121212";

export const white = "#FFFFFF";
export const black = "#000000";
export const black = "#232021";
eugene028 marked this conversation as resolved.
Show resolved Hide resolved

export const whiteOpacity20 = "rgba(255, 255, 255, 0.2)";

Expand Down Expand Up @@ -99,7 +99,7 @@ export const backgroundDimmer = blackOpacity80;

export const sub = mono700;
export const outline = mono400;
export const textBlack = black;
export const textBlack = mono950;
export const textWhite = white;

export const darkDisabled = mono400;
Expand Down
19 changes: 0 additions & 19 deletions packages/wow-ui/src/components/Box/Box.stories.ts

This file was deleted.

74 changes: 74 additions & 0 deletions packages/wow-ui/src/components/Box/Box.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import type { Meta, StoryObj } from "@storybook/react";
import { color } from "wowds-tokens";

import Box from "@/components/Box";

const meta = {
title: "Example/Box",
ghdtjgus76 marked this conversation as resolved.
Show resolved Hide resolved
component: Box,
tags: ["autodocs"],
eugene028 marked this conversation as resolved.
Show resolved Hide resolved
} satisfies Meta<typeof Box>;

export default meta;

type Story = StoryObj<typeof meta>;

export const Default: Story = {
args: {
text: "Text",
subText: "Subtext",
},
};

export const CheckBox: Story = {
args: {
text: "Text",
subText: "Subtext",
type: "checkbox",
},
};
eugene028 marked this conversation as resolved.
Show resolved Hide resolved

export const ArrowBox: Story = {
args: {
text: "Text",
subText: "Subtext",
type: "arrow",
onClick: () => {
console.log("클릭 이벤트 발생");
},
},
};

export const LongBox: Story = {
args: {
text: "Q. 서류, 면접 전형이 있나요?",
subText:
"없습니다! 홍익대학교 학생이라면 누구나 본 사이트의 '지원하기'를 통해 가입할 수 있어요.",
subTextColor: `${color.textBlack}`,
},
};

export const SuccessBox: Story = {
args: {
text: "Text",
subText: "Subtext",
type: "checkbox",
},
};

export const LeftElementBox: Story = {
args: {
text: "GDSC Hongik Discord",
subText: "디스코드 연동이 필요해요.",
textColor: `${color.discord}`,
status: "error",
type: "arrow",
leftElement: (
<img
alt="discord"
src="https://uxwing.com/wp-content/themes/uxwing/download/brands-and-social-media/discord-round-color-icon.svg"
width={50}
/>
),
},
};
137 changes: 121 additions & 16 deletions packages/wow-ui/src/components/Box/index.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,130 @@
import { css } from "@styled-system/css/css";
import type { ReactNode } from "react";
import { cva } from "@styled-system/css";
import { Flex, styled } from "@styled-system/jsx";
import type { CSSProperties, ReactNode } from "react";
import { RightArrow } from "wowds-icons";
import { color } from "wowds-tokens";

export interface ButtonProps {
children: ReactNode;
import Checkbox from "@/components/Checkbox";

export interface BoxProps {
leftElement?: ReactNode;
type?: "text" | "checkbox" | "arrow";
text: string;
textColor?: string;
subText?: string;
eugene028 marked this conversation as resolved.
Show resolved Hide resolved
subTextColor?: string;
eugene028 marked this conversation as resolved.
Show resolved Hide resolved
status?: "default" | "success" | "error";
onClick?: () => void;
style?: CSSProperties;
}

const Box = ({ children }: ButtonProps) => {
/**
* @description 사용자에게 보여주어야 하는 정보를 담을 수 있는 Box 컴포넌트입니다.
* @param {ReactNode} [leftElement] Box 컴포넌트의 왼쪽에 들어갈 수 있는 요소입니다. (아이콘, 이미지 등)
* @param {string} [textColor] text의 색상을 변경할 수 있습니다.
* @param {"text" | "checkbox" | "arrow"} [type] Box 컴포넌트의 타입을 설정합니다.
* @param {string} text Box 컴포넌트에 메인으로 표기할 텍스트를 입력합니다.
* @param {string} [subText] Box 컴포넌트에 작성할 추가 정보를 입력합니다.
* @param {string} [subTextColor] subtext의 색상을 변경할 수 있습니다.
* @param {"default" | "success" | "error"} [status] Box 컴포넌트를 통해 사용자의 상태를 반환합니다.
* @param {() => void} [onClick] Box 컴포넌트의 타입이 "checkbox"와 "arrow"일때 수행할 onClick 함수를 입력합니다.
* @throws {onClick} onClick 함수는 "text" type에서 사용할 수 없습니다.
* @param {CSSProperties} [style] Box 컴포넌트에 적용할 수 있는 custom style
*/
eugene028 marked this conversation as resolved.
Show resolved Hide resolved

const Box = ({
leftElement,
type = "text",
text,
textColor,
subText,
subTextColor,
status = "default",
onClick,
style,
...rest
}: BoxProps) => {
return (
<button
eugene028 marked this conversation as resolved.
Show resolved Hide resolved
className={css({
bg: "blue.100",
fontFamily: "Inter",
px: "4",
py: "3",
borderRadius: "md",
_hover: { bg: "blue.400" },
})}
<Flex
alignItems="center"
className={containerStyle({ status: status })}
direction="row"
eugene028 marked this conversation as resolved.
Show resolved Hide resolved
gap="lg"
id={`box-${text}`}
justifyContent="space-between"
eugene028 marked this conversation as resolved.
Show resolved Hide resolved
style={{ ...style }}
{...rest}
eugene028 marked this conversation as resolved.
Show resolved Hide resolved
eugene028 marked this conversation as resolved.
Show resolved Hide resolved
>
{children}
</button>
<Flex alignItems="center" direction="row" gap="xs">
{leftElement}
<Flex direction="column" gap="xxs">
<styled.span
color="red"
fontWeight="600"
eugene028 marked this conversation as resolved.
Show resolved Hide resolved
textStyle="h3"
eugene028 marked this conversation as resolved.
Show resolved Hide resolved
style={{
color: textColor ? textColor : `${color.textBlack}`,
}}
>
eugene028 marked this conversation as resolved.
Show resolved Hide resolved
{text}
</styled.span>
<styled.span
textStyle="body1"
style={{
color: subTextColor ? subTextColor : `${color.sub}`,
}}
eugene028 marked this conversation as resolved.
Show resolved Hide resolved
>
{subText}
</styled.span>
</Flex>
</Flex>
<div aria-label="box-rightElement" role="button" tabIndex={0}>
{type === "checkbox" ? (
eugene028 marked this conversation as resolved.
Show resolved Hide resolved
<Checkbox />
) : type === "arrow" ? (
eugene028 marked this conversation as resolved.
Show resolved Hide resolved
<RightArrow
height={20}
style={{ cursor: "pointer" }}
width={20}
eugene028 marked this conversation as resolved.
Show resolved Hide resolved
stroke={
status === "default"
? "outline"
: status === "error"
? "error"
: "primary"
}
eugene028 marked this conversation as resolved.
Show resolved Hide resolved
onClick={onClick}
/>
eugene028 marked this conversation as resolved.
Show resolved Hide resolved
) : null}
</div>
</Flex>
);
};

export default Box;

const containerStyle = cva({
base: {
width: "100%",
paddingX: "xl",
paddingTop: "xl",
paddingBottom: "lg",
borderRadius: "md",
border: "1px solid",
maxWidth: "40.75rem",
backgroundColor: "white",
},
eugene028 marked this conversation as resolved.
Show resolved Hide resolved
variants: {
status: {
default: {
borderColor: "outline",
},
success: {
borderColor: "primary",
},
error: {
borderColor: "error",
},
},
},
});
Loading