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] Toast 컴포넌트 #157

Merged
merged 31 commits into from
Oct 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
e0f58c4
feat: 토스트 컴포넌트 구현
hamo-o Sep 3, 2024
50df9c5
feat: 토스트 컴포넌트 스토리북 작성
hamo-o Sep 3, 2024
418256a
chore: package.json 및 rollup 추가
hamo-o Sep 3, 2024
0d07e3b
chore: displayName 추가 및 export 형식 변경
hamo-o Sep 3, 2024
81aead7
design: 두 줄인 경우 줄바꿈
hamo-o Sep 3, 2024
5a8cc12
fix: type 옵셔널로 처리
hamo-o Sep 3, 2024
a0de86b
feat: 토스트 컴포넌트를 사라지게 하는 효과 추가
hamo-o Sep 3, 2024
1ad9dc4
feat: 아이콘 클릭 시 호출할 함수 추가, 배경 추가
hamo-o Sep 15, 2024
7315281
feat: 아이콘 클릭 함수 스토리 추가, state 활용 추가
hamo-o Sep 15, 2024
645f005
feat: 토스트 위치조정 및 배경 스타일 prop 추가
hamo-o Sep 15, 2024
0508da6
feat: toast 함수로 렌더링 가능하도록 로직 추가
hamo-o Sep 15, 2024
b27b03c
fix: 토스트가 여러개일 때 레이아웃 조정
hamo-o Sep 15, 2024
b8f1eeb
chore: useToast 빌드 포함
hamo-o Sep 15, 2024
438a278
fix: color contrast 검사 통과
hamo-o Sep 15, 2024
cfbcf15
feat: 토스트 duration 받을 수 있도록 추가
hamo-o Sep 22, 2024
d319141
feat: overlay zIndex 토큰 추가
hamo-o Sep 22, 2024
403b7af
refactor: zIndex 토큰 사용하도록 변경
hamo-o Sep 22, 2024
a0ab098
feat: 공통 타입 파일 내보내도록 스크립트 수정
hamo-o Sep 22, 2024
7e00b06
refactor: TypeIconComponent 네이밍 변경 및 공통 prop 빼기
hamo-o Sep 22, 2024
689cc2a
fix: 토스트 트리거 존재하는 경우 스토리 추가, 토스트가 없을 때 오버레이 공간 차지하지 않도록 조건부 렌더링
hamo-o Sep 22, 2024
301b804
docs: ToastProvider 내용 안내
hamo-o Sep 22, 2024
71d2fe9
docs: 스토리북 radio 옵션 추가 및 기본 컴포넌트 변경
hamo-o Sep 22, 2024
786e1bc
feat: 토스트 컴포넌트 제거 이후 실행되는 함수 추가
hamo-o Sep 22, 2024
fa6a9f2
feat: docs에도overlay 토큰 추가
hamo-o Sep 22, 2024
cefebe9
fix: type -> rightIcon 네이밍 변경
hamo-o Sep 26, 2024
73eee2d
docs: 스토리북 설명 및 타이틀 변경
hamo-o Sep 26, 2024
3f5ca3b
fix: 스크립트 content 변수 네이밍 변경
hamo-o Sep 26, 2024
e51aa8e
fix: icon prop 불리언으로 수정
hamo-o Sep 26, 2024
1e702e6
refactor: 현재 시각 대신 uuid로 토스트 id 지정
hamo-o Sep 26, 2024
1d800bd
feat: 정규식 입력 시 해당 정규식을 만족하는 아이디를 가진 토스트만 보여주기
hamo-o Sep 26, 2024
ed47550
chore: changeset 작성
hamo-o Oct 12, 2024
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
6 changes: 6 additions & 0 deletions .changeset/green-feet-teach.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"wowds-tokens": patch
"wowds-theme": patch
---

zIndex 토큰을 추가합니다.
5 changes: 5 additions & 0 deletions .changeset/pretty-cooks-join.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"wowds-icons": patch
---

Icon 공통 타입을 내보내기합니다.
5 changes: 5 additions & 0 deletions .changeset/seven-eggs-wait.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"wowds-ui": patch
---

Toast 컴포넌트를 추가합니다.
4 changes: 4 additions & 0 deletions apps/wow-docs/styled-system/tokens/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,10 @@ const tokens = {
value: 10,
variable: "var(--z-index-dropdown)",
},
"zIndex.overlay": {
value: 9999,
variable: "var(--z-index-overlay)",
},
"shadows.blue": {
value: "0px 4px 8px 0px rgba(16, 43, 74, 0.2)",
variable: "var(--shadows-blue)",
Expand Down
3 changes: 2 additions & 1 deletion apps/wow-docs/styled-system/tokens/tokens.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ export type Token =
| "borderWidths.button"
| "borderWidths.arrow"
| "zIndex.dropdown"
| "zIndex.overlay"
| "shadows.blue"
| "shadows.mono"
| "breakpoints.xs"
Expand Down Expand Up @@ -323,7 +324,7 @@ export type RadiusToken = "sm" | "md" | "full";

export type BorderWidthToken = "button" | "arrow";

export type ZIndexToken = "dropdown";
export type ZIndexToken = "dropdown" | "overlay";

export type ShadowToken = "blue" | "mono";

Expand Down
13 changes: 9 additions & 4 deletions packages/scripts/generateBuildConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,22 @@ const excludedComponents = [
"CollectionContext",
"DropDownOptionList",
"pickerComponents",
"ToastContext",
];

// 추가할 컴포넌트 목록
const includedComponents = ["useToast"];

const getFilteredComponentFiles = async (directoryPath: string) => {
const files = await fs.readdir(directoryPath, { recursive: true });

return files.filter(
(file) =>
file.endsWith(".tsx") &&
!file.includes("test") &&
!file.includes("stories") &&
!excludedComponents.some((excluded) => file.includes(excluded))
(file.endsWith(".tsx") &&
!file.includes("test") &&
!file.includes("stories") &&
!excludedComponents.some((excluded) => file.includes(excluded))) ||
includedComponents.some((included) => file.includes(included))
);
};

Expand Down
4 changes: 3 additions & 1 deletion packages/scripts/generateReactComponentFromSvg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,9 @@ const generateExportFile = async (components: string[]) => {
)
.join("\n");

await fs.writeFile(EXPORT_FILE_PATH, exportFileContent);
const resolvedExportFileContent = `export * from "../types/Icon.ts";\n${exportFileContent}`;

await fs.writeFile(EXPORT_FILE_PATH, resolvedExportFileContent);
};

(async () => {
Expand Down
1 change: 0 additions & 1 deletion packages/wow-icons/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
"package.json"
],
"type": "module",
"types": "./dist/index.d.ts",
"exports": {
ghdtjgus76 marked this conversation as resolved.
Show resolved Hide resolved
".": {
"types": "./dist/component/index.d.ts",
Expand Down
1 change: 1 addition & 0 deletions packages/wow-icons/src/component/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from "../types/Icon.ts";
export { default as BlueAvatar } from "./BlueAvatar.tsx";
export { default as Calendar } from "./Calendar.tsx";
export { default as Check } from "./Check.tsx";
Expand Down
3 changes: 3 additions & 0 deletions packages/wow-theme/src/tokens/zIndex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,7 @@ export const zIndex = defineTokens.zIndex({
dropdown: {
value: wowZIndex.dropdown,
},
overlay: {
value: wowZIndex.overlay,
},
});
1 change: 1 addition & 0 deletions packages/wow-tokens/src/zIndex.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export const dropdown = 10;
export const overlay = 9999;
19 changes: 18 additions & 1 deletion packages/wow-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,21 @@
"type": "module",
"exports": {
"./styles.css": "./dist/styles.css",
"./ToastProvider": {
"types": "./dist/components/Toast/ToastProvider.d.ts",
"require": "./dist/ToastProvider.cjs",
"import": "./dist/ToastProvider.js"
},
"./Toast": {
"types": "./dist/components/Toast/index.d.ts",
"require": "./dist/Toast.cjs",
"import": "./dist/Toast.js"
},
"./useToast": {
"types": "./dist/components/Toast/useToast.d.ts",
"require": "./dist/useToast.cjs",
"import": "./dist/useToast.js"
},
"./TextField": {
"types": "./dist/components/TextField/index.d.ts",
"require": "./dist/TextField.cjs",
Expand Down Expand Up @@ -179,12 +194,14 @@
"plop": "^4.0.1",
"rollup-plugin-peer-deps-external": "^2.2.4",
"storybook": "^8.1.9",
"typescript": "^5.3.3"
"typescript": "^5.3.3",
"@types/uuid": "^10.0.0"
},
"dependencies": {
"clsx": "^2.1.1",
"lottie-react": "^2.4.0",
"react-day-picker": "^9.0.8",
"uuid": "^10.0.0",
"wowds-icons": "workspace:^"
},
"peerDependencies": {
Expand Down
3 changes: 3 additions & 0 deletions packages/wow-ui/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ process.env.BABEL_ENV = "production";

export default {
input: {
ToastProvider: "./src/components/Toast/ToastProvider",
Toast: "./src/components/Toast",
useToast: "./src/components/Toast/useToast",
TextField: "./src/components/TextField",
TextButton: "./src/components/TextButton",
Tag: "./src/components/Tag",
Expand Down
173 changes: 173 additions & 0 deletions packages/wow-ui/src/components/Toast/Toast.stories.tsx
hamo-o marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
import type { Meta, StoryObj } from "@storybook/react";
import { useEffect } from "react";
import { Warn } from "wowds-icons";

import Button from "@/components/Button";

import Toast from ".";
import ToastProvider from "./ToastProvider";
import useToast from "./useToast";

const meta: Meta<typeof Toast> = {
title: "UI/Toast",
component: Toast,
tags: ["autodocs"],
parameters: {
componentSubtitle: "Toast 컴포넌트",
a11y: {
config: {
rules: [{ id: "color-contrast", enabled: false }],
},
},
docs: {
description: {
component:
"토스트가 필요한 레이아웃에서 children을 ToastProvider로 감싸 사용합니다.",
},
},
},
decorators: [
(Story) => (
<ToastProvider>
<Story />
</ToastProvider>
),
],
argTypes: {
text: {
description: "Toast에 들어갈 메인 텍스트를 나타냅니다.",
control: { type: "text" },
},
subText: {
description: "Toast에 들어갈 보조 텍스트를 나타냅니다.",
control: { type: "text" },
},
rightIcon: {
description: "Toast의 우측에 들어갈 아이콘을 나타냅니다.",
table: {
type: { summary: "none | close | arrow" },
defaultValue: { summary: "none" },
},
control: "radio",
options: ["none", "close", "arrow"],
},
id: {
description: "Toast 컴포넌트의 id를 나타냅니다.",
control: false,
},
onClickArrowIcon: {
description:
"Toast 컴포넌트의 화살표 아이콘을 클릭했을 때 호출되는 함수를 나타냅니다.",
control: false,
},
onRemove: {
description: "Toast 컴포넌트가 닫힌 이후 호출되는 함수를 나타냅니다.",
control: false,
},
showLeftIcon: {
description: "Toast 좌측에 들어갈 아이콘의 노출 여부를 나타냅니다.",
control: "boolean",
},
toastDuration: {
description: "Toast가 보여지는 시간(ms)을 나타냅니다.",
control: { type: "number" },
},
style: {
description: "Toast에 커스텀 스타일을 적용하기 위한 객체를 나타냅니다.",
control: false,
},
className: {
description: "Toast에 커스텀 클래스를 적용하기 위한 문자열을 나타냅니다.",
control: false,
},
},
} satisfies Meta<typeof Toast>;

export default meta;

type Story = StoryObj<typeof meta>;

export const Default: Story = {
args: {
id: "1",
text: "Text",
subText: "subtext",
toastDuration: 60 * 60 * 1000,
},
};

export const WithTrigger = () => {
const { toast } = useToast();

return (
<Button onClick={() => toast({ text: "Text", subText: "subtext" })}>
토스트 열기
</Button>
);
};

export const WithCloseIcon = () => {
const { toast } = useToast();
useEffect(() => {
toast({
text: "Text",
subText: "subtext",
rightIcon: "close",
});
}, []);
};

export const WithArrowIcon = () => {
const { toast } = useToast();
useEffect(() => {
toast({
text: "Text",
subText: "subtext",
rightIcon: "arrow",
});
}, []);
};

export const WithLeftIcon = () => {
const { toast } = useToast();
useEffect(() => {
toast({
text: "Text",
subText: "subtext",
showLeftIcon: true,
});
}, []);
};

export const WithLeftAndArrowIcons = () => {
const { toast } = useToast();
useEffect(() => {
toast({
text: "Text",
subText: "subtext",
showLeftIcon: true,
rightIcon: "arrow",
});
}, []);
};

export const TwoLines = () => {
const { toast } = useToast();
useEffect(() => {
toast({
showLeftIcon: true,
text: "TextTextTextTextTextTextTextTextTextTextTextTextTextTextTextText",
});
}, []);
};

export const Slow = () => {
const { toast } = useToast();
useEffect(() => {
toast({
text: "Text",
subText: "subtext",
toastDuration: 5000,
});
}, []);
};
22 changes: 22 additions & 0 deletions packages/wow-ui/src/components/Toast/ToastContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { createContext } from "react";

import useSafeContext from "@/hooks/useSafeContext";

import type { ToastProps } from ".";

interface ToastContextProps {
toasts: ToastProps[];
addToast: (
toast: Omit<ToastProps, "id"> & Partial<Pick<ToastProps, "id">>
) => void;
removeToast: (id: string) => void;
}

export const ToastContext = createContext<ToastContextProps | undefined>(
undefined
);

export const useToastContext = () => {
const context = useSafeContext(ToastContext);
return context;
};
Loading
Loading