atomsystem 0.1.26 → 0.1.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,16 +7,16 @@ import clsx from "clsx";
7
7
  import { useMediaQuery } from "react-responsive";
8
8
 
9
9
  interface NavItemsAttr {
10
+ type?: "topnav" | "sidenav";
10
11
  navMenu: {
11
12
  name: string;
12
13
  path?: string;
13
14
  }[];
14
15
  }
15
16
 
16
- const navStandardStyle =
17
- "bg-[var(--background-card)] text-text-standard border-[var(--color-border)]";
17
+ // Custom CSS classes are now used via css/navigation.css
18
18
 
19
- const navToggle = (targetId: string) => {
19
+ const handleNavToggle = (targetId: string) => {
20
20
  const el = document.getElementById(targetId);
21
21
  if (el) {
22
22
  const isHidden = el.style.display === "none" || el.style.display === "";
@@ -28,18 +28,19 @@ const Navigation = ({
28
28
  children,
29
29
  id,
30
30
  className,
31
+ type = "topnav",
31
32
  }: {
32
33
  children: React.ReactNode;
33
34
  id?: string;
34
35
  className?: string;
36
+ type?: "topnav" | "sidenav";
35
37
  }) => {
36
38
  const isMobile = useMediaQuery({ maxWidth: 767 });
37
39
 
38
40
  const mobileClose = (e: React.MouseEvent) => {
39
41
  if (isMobile) {
40
- e.preventDefault();
41
42
  if (id) {
42
- navToggle(id);
43
+ handleNavToggle(id);
43
44
  }
44
45
  }
45
46
  };
@@ -47,7 +48,7 @@ const Navigation = ({
47
48
  return (
48
49
  <nav
49
50
  id={id ? id : undefined}
50
- className={`${navStandardStyle} ${className} overflow-auto`}
51
+ className={`nav-container nav-${type} ${className} overflow-auto`}
51
52
  onClick={mobileClose}
52
53
  >
53
54
  {children}
@@ -55,27 +56,21 @@ const Navigation = ({
55
56
  );
56
57
  };
57
58
 
58
- const NavItems = ({ navMenu }: NavItemsAttr) => {
59
+ const NavItems = ({ navMenu, type = "sidenav" }: NavItemsAttr) => {
59
60
  const pathname = usePathname();
60
61
 
61
62
  return (
62
- <ul>
63
+ <ul className={clsx(`nav-${type}`, { "flex flex-row items-center nav-gap": type === "topnav" })}>
63
64
  {navMenu.map((menu) => {
64
65
  return (
65
66
  <li className="relative group" key={menu.name}>
66
67
  <div className={clsx("flex justify-between items-center pr-4")}>
67
- {menu.path ? (
68
- <Link
69
- href={menu.path}
70
- className={`${pathname === menu.path ? `text-primary` : `text-[var(--text-standard)]`} px-4 py-2 block `}
71
- >
72
- {menu.name}
73
- </Link>
74
- ) : (
75
- <p className={`px-4 py-2 block text-[var(--text-standard)]`}>
76
- {menu.name}
77
- </p>
78
- )}
68
+ <Link
69
+ href={menu.path || "#"}
70
+ className={`${pathname === menu.path ? "nav-text-active" : "nav-text-standard"} nav-${type} block hover:opacity-80 transition-opacity nav-padding`}
71
+ >
72
+ {menu.name}
73
+ </Link>
79
74
  </div>
80
75
  </li>
81
76
  );
@@ -94,36 +89,32 @@ const NavToggleButton = ({
94
89
  className?: string;
95
90
  }) => {
96
91
  return (
97
- <button className={className} onClick={() => navToggle(targetId)}>
92
+ <button className={className} onClick={() => handleNavToggle(targetId)}>
98
93
  {children}
99
94
  </button>
100
95
  );
101
96
  };
102
97
 
103
- const Sidebar = ({ navMenu }: NavItemsAttr) => {
98
+ const Sidebar = ({ navMenu, type = "sidenav" }: NavItemsAttr) => {
104
99
  return (
105
100
  <nav
106
101
  className={clsx(
107
- `relative ${navStandardStyle} w-full md:w-[320px] h-full z-20 left-0 overflow-auto`
102
+ `relative nav-container nav-${type} w-full md:w-[320px] h-full z-20 left-0 overflow-auto`
108
103
  )}
109
104
  >
110
105
  <ul>
111
106
  {navMenu.map((menu, idx) => {
112
107
  return (
113
- <li className="relative group" key={menu.name}>
108
+ <li className="relative group" key={menu.name + idx}>
114
109
  <div className={clsx("flex justify-between items-center pr-4")}>
115
- {menu.path ? (
116
- <Link
117
- href={menu.path}
118
- className={clsx(
119
- "px-4 py-2 block text-[var(--text-standard)]"
120
- )}
121
- >
122
- {menu.name}
123
- </Link>
124
- ) : (
125
- <p></p>
126
- )}
110
+ <Link
111
+ href={menu.path || "#"}
112
+ className={clsx(
113
+ `block nav-text-standard nav-${type} hover:opacity-80 transition-opacity nav-padding`
114
+ )}
115
+ >
116
+ {menu.name}
117
+ </Link>
127
118
  </div>
128
119
  </li>
129
120
  );
@@ -178,12 +169,14 @@ const GlobalNav = ({
178
169
  }));
179
170
  };
180
171
 
172
+ const navType = type === "sidebar" ? "sidenav" : "topnav";
173
+
181
174
  return (
182
175
  <nav
183
176
  className={clsx(
184
- `fixed top-0 md:relative w-full bg-[var(--background-card)] text-text-standard z-20 left-0 ${toggleMenu ? "block" : "hidden"}`,
185
- { "h-full max-w-80 overflow-auto": type == "sidebar" },
186
- { "h-auto flex flex-row items-center": type == "topmenu" }
177
+ `fixed top-0 md:relative w-full nav-container nav-${navType} z-20 left-0 ${toggleMenu ? "block" : "hidden"}`,
178
+ { [`h-full max-w-80 overflow-auto border-r nav-border`]: type == "sidebar" },
179
+ { [`h-auto flex flex-row items-center border-b nav-border nav-${navType}`]: type == "topmenu" }
187
180
  )}
188
181
  >
189
182
  {/* brand */}
@@ -200,11 +193,11 @@ const GlobalNav = ({
200
193
  ></Image>
201
194
  </Link>
202
195
  <button
203
- className={`fixed shadow-md rounded-full bg-[var(--background-card)] w-12 h-12 top-6 left-6 cursor-pointer z-50`}
196
+ className={`fixed shadow-md rounded-full nav-bg nav-${navType} border nav-border w-12 h-12 top-6 left-6 cursor-pointer z-50`}
204
197
  onClick={() => setToggleMenu(!toggleMenu)}
205
198
  >
206
199
  <span
207
- className="material-symbols-outlined text-[var(--text-standard)]"
200
+ className={`material-symbols-outlined nav-text-standard nav-${navType}`}
208
201
  style={{ fontSize: "16px" }}
209
202
  >
210
203
  menu
@@ -225,25 +218,24 @@ const GlobalNav = ({
225
218
  return (
226
219
  <p
227
220
  key={menu.name + idx}
228
- className="px-4 text-sm text-sub mt-2 mb-0"
221
+ className={`nav-text-sub nav-${navType} mt-2 mb-0 nav-padding`}
229
222
  >
230
223
  {menu.name}
231
224
  </p>
232
225
  );
233
226
  default:
234
- if (!menu.path) return null;
235
227
  return (
236
228
  <li className="relative group" key={menu.name}>
237
229
  <div
238
230
  className={clsx("flex justify-between items-center pr-4")}
239
231
  >
240
232
  <Link
241
- href={menu.path}
233
+ href={menu.path || "#"}
242
234
  className={clsx(
243
- "px-4 py-2 block text-[var(--text-standard)]",
235
+ `block nav-text-standard nav-${navType} nav-padding`,
244
236
  {
245
- "text-primary":
246
- menu.path == pathname ||
237
+ "nav-text-active":
238
+ (menu.path && menu.path == pathname) ||
247
239
  menu.subItems?.some((sub) => sub.path === pathname),
248
240
  }
249
241
  )}
@@ -257,7 +249,7 @@ const GlobalNav = ({
257
249
  >
258
250
  <span
259
251
  className={clsx(
260
- "material-symbols-outlined text-[var(--text-sub)] transition-transform",
252
+ `material-symbols-outlined nav-text-sub nav-${navType} transition-transform`,
261
253
  {
262
254
  "rotate-90": openSubMenu[menu.name],
263
255
  }
@@ -274,7 +266,7 @@ const GlobalNav = ({
274
266
  className={clsx(
275
267
  "block",
276
268
  {
277
- "hidden absolute top-[42px] group-hover:block hover:block bg-[var(--background-card)]":
269
+ [`hidden absolute top-[42px] group-hover:block hover:block nav-bg nav-${navType} border nav-border`]:
278
270
  type == "topmenu",
279
271
  },
280
272
  {
@@ -287,9 +279,9 @@ const GlobalNav = ({
287
279
  <li key={submenu.name}>
288
280
  <Link
289
281
  className={clsx(
290
- "px-4 py-2 block text-[var(--text-standard)]",
282
+ `block nav-text-standard nav-${navType} nav-padding`,
291
283
  {
292
- "text-primary": submenu.path == pathname,
284
+ "nav-text-active": submenu.path == pathname,
293
285
  },
294
286
  { "pl-12 ": type == "sidebar" }
295
287
  )}
@@ -34,7 +34,7 @@ const Pagination = ({
34
34
  };
35
35
 
36
36
  return (
37
- <div className="text-[#999] flex">
37
+ <div className="pagination">
38
38
  <button
39
39
  disabled={pageStart === 1}
40
40
  onClick={() => {
@@ -43,11 +43,11 @@ const Pagination = ({
43
43
  setPageStart(newStart);
44
44
  onPageChange(newStart);
45
45
  }}
46
- className="px-2 py-8 cursor-pointer disabled:opacity-40"
46
+ className="pagination-btn"
47
47
  >
48
48
  <span className="material-symbols-outlined">keyboard_arrow_left</span>
49
49
  </button>
50
- <ul className="flex w-full">
50
+ <ul className="pagination-list">
51
51
  {[...Array(pageRange)].map((_, i) => {
52
52
  const page = pageStart + i;
53
53
 
@@ -74,8 +74,8 @@ const Pagination = ({
74
74
  }
75
75
  scrollTop();
76
76
  }}
77
- className={` w-full text-center py-8 cursor-pointer px-2 ${
78
- currentPage === page ? "text-primary" : ""
77
+ className={`pagination-item ${
78
+ currentPage === page ? "pagination-item-active" : ""
79
79
  }`}
80
80
  >
81
81
  {page}
@@ -93,7 +93,7 @@ const Pagination = ({
93
93
  onPageChange(newStart);
94
94
  }
95
95
  }}
96
- className="px-2 py-8 cursor-pointer disabled:opacity-40"
96
+ className="pagination-btn"
97
97
  >
98
98
  <span className="material-symbols-outlined">keyboard_arrow_right</span>
99
99
  </button>
@@ -6,12 +6,12 @@ import { useGSAP } from "@gsap/react";
6
6
 
7
7
  const Tab = ({
8
8
  tabs,
9
- tabClass = "w-full bg-[var(--background-wrapper)] border-b border-[var(--color-border)] relative z-0 h-[57px]",
10
- tabNavItemClass = "p-4",
11
- tabNavItemActiveClass = "bg-[var(--background-card)] border border-[var(--color-border)] border-b-[var(--background-card)] relative z-10",
9
+ tabClass = "tab",
10
+ tabNavItemClass = "tab-nav-item",
11
+ tabNavItemActiveClass = "tab-nav-item-active",
12
12
  tabContents,
13
- tabContentClass = "p-4 border border-t-0 border-[var(--color-border)] -mt-[1px]",
14
- tabContentItem = "text-[var(--text-standard)]",
13
+ tabContentClass = "tab-content",
14
+ tabContentItem = "tab-content-item",
15
15
  expectionValue,
16
16
  expectionLayout,
17
17
  }: {
@@ -76,7 +76,7 @@ const Tab = ({
76
76
  }, [activeContent]);
77
77
 
78
78
  return (
79
- <div className="flex flex-col">
79
+ <div className="flex flex-col w-full">
80
80
  <div className={tabClass}>
81
81
  {tabs.map((tab) => {
82
82
  return (
@@ -84,9 +84,9 @@ const Tab = ({
84
84
  key={tab.id}
85
85
  id={tab.id}
86
86
  onClick={() => handleTabActive(tab.target, tab.id)}
87
- className={`cursor-pointer ${tabNavItemClass} ${
87
+ className={`${tabNavItemClass} ${
88
88
  activeTab == tab.id
89
- ? `text-primary ${tabNavItemActiveClass}`
89
+ ? tabNavItemActiveClass
90
90
  : ""
91
91
  }`}
92
92
  >
@@ -101,8 +101,8 @@ const Tab = ({
101
101
  <div
102
102
  key={tabContent.id}
103
103
  id={tabContent.tag}
104
- className={`w-full sm:w-auto ${tabContentItem} ${
105
- activeTab == expectionValue ? expectionLayout : null
104
+ className={`${tabContentItem} ${
105
+ activeTab == expectionValue ? expectionLayout : ""
106
106
  }`}
107
107
  >
108
108
  {tabContent.content}
@@ -6,8 +6,8 @@ const Table = ({ tableData }: { tableData: Record<string, any>[] }) => {
6
6
  // tableData가 제공되지 않았거나 비어있는 경우, 데이터 없음 메시지를 표시합니다.
7
7
  if (!tableData || tableData.length === 0) {
8
8
  return (
9
- <div className="p-4 text-center">
10
- <p className="text-[var(--text-standard)]">표시할 데이터가 없습니다.</p>
9
+ <div className="table-empty">
10
+ <p>표시할 데이터가 없습니다.</p>
11
11
  </div>
12
12
  );
13
13
  }
@@ -15,17 +15,14 @@ const Table = ({ tableData }: { tableData: Record<string, any>[] }) => {
15
15
  const headers = Object.keys(tableData[0]);
16
16
 
17
17
  return (
18
- <div className="overflow-auto w-full">
19
- <table className="min-w-full border border-[var(--color-border)] rounded]">
20
- <thead className="bg-[var(--table-header-background)]">
18
+ <div className="table-container">
19
+ <table className="table">
20
+ <thead className="table-header">
21
21
  <tr>
22
22
  {/* 헤더 배열을 순회하며 각 헤더에 대한 <th>태그를 생성합니다. */}
23
23
  {headers.map((header, index) => {
24
24
  return (
25
- <th
26
- key={index}
27
- className="px-6 py-3 text-center text-[var(--table-header-text)] tracking-wider border-b border-[var(--color-border)]"
28
- >
25
+ <th key={index}>
29
26
  {header}
30
27
  </th>
31
28
  );
@@ -33,20 +30,14 @@ const Table = ({ tableData }: { tableData: Record<string, any>[] }) => {
33
30
  </tr>
34
31
  </thead>
35
32
  {/* 테이블 바디 부분 */}
36
- <tbody className={`divide-y divide-[var(--color-border)] `}>
33
+ <tbody className="table-body">
37
34
  {/* tableData 배열을 순회하며 각 데이터 객체(행)에 대한 <tr> 태그를 생성합니다. */}
38
35
  {tableData.map((row, rowIndex) => {
39
36
  return (
40
- <tr
41
- key={rowIndex}
42
- className={` ${rowIndex % 2 === 0 ? `bg-[var(--table-body-background)]` : `bg-[var(--table-body-background-even)]`}`}
43
- >
37
+ <tr key={rowIndex} className="table-row">
44
38
  {/* 각 행 내에서 헤더 배열을 다시 순회하며 해당 헤더에 맞는 셀(<td>)을 생성합니다. */}
45
39
  {headers.map((header, colIndex) => (
46
- <td
47
- key={colIndex} // 고유한 키를 제공합니다.
48
- className={`px-4 py-2 text-[var(--text-body-text)] border-b border-[var(--color-border)]`}
49
- >
40
+ <td key={colIndex} className="table-cell">
50
41
  {/* 현재 행 객체(row)에서 해당 헤더(키)에 해당하는 값을 가져와 셀에 표시합니다. */}
51
42
  {row[header]}
52
43
  </td>
@@ -1,118 +1,125 @@
1
1
  "use client";
2
2
 
3
3
  import { useEffect, useState } from "react";
4
- import { Radio } from "../Input/Input";
4
+ import { Radio } from "../Form/Form";
5
+ import { themes } from "@/build/typescript/theme";
6
+ import { Button } from "../Button/Button";
7
+ import { ModalContent } from "../Modal/Modal";
5
8
 
6
- export const ThemeSelector = ({
7
- type,
8
- }: {
9
- type: "all" | "theme" | "input";
10
- }) => {
11
- const themes = ["light", "dark"];
12
- const [selectedTheme, setSelectedTheme] = useState<string | null>("light");
13
- // const inputThemes = ["inputStandard", "inputCircle"];
14
- // const [selectedInputTheme, setSelectedInputTheme] = useState<string | null>(
15
- // null
16
- // );
9
+ export const ThemeSelector = () => {
10
+ const [selectedThemes, setSelectedThemes] = useState<Record<string, string>>({});
11
+ const [tempThemes, setTempThemes] = useState<Record<string, string>>({});
17
12
  const [isThemeLoading, setThemeLoading] = useState(false);
13
+ const [isModalOpen, setIsModalOpen] = useState(false);
18
14
 
19
15
  useEffect(() => {
20
16
  const chageThemeValue = () => {
21
- const storedTheme = localStorage.getItem("theme") || "light";
22
- // const storedInputTheme =
23
- // localStorage.getItem("inputTheme") || "inputStandard";
24
-
25
- setSelectedTheme(storedTheme);
26
- // setSelectedInputTheme(storedInputTheme);
17
+ const newThemes: Record<string, string> = {};
18
+ Object.entries(themes).forEach(([group, groupThemes]) => {
19
+ const storedKey = group === "global" ? "theme" : `theme-${group}`;
20
+ const storedTheme = localStorage.getItem(storedKey) || groupThemes[0];
21
+ newThemes[group] = storedTheme;
22
+ });
23
+ setSelectedThemes(newThemes);
24
+ setTempThemes(newThemes);
27
25
  };
28
26
 
29
27
  chageThemeValue();
30
28
  setThemeLoading(true);
31
29
  }, []);
32
30
 
33
- // main theme
34
- const handleThemeChange = (theme: string) => {
31
+ const handleTempThemeChange = (group: string, theme: string) => {
32
+ setTempThemes((prev) => ({ ...prev, [group]: theme }));
33
+ };
34
+
35
+ const handleApply = () => {
35
36
  if (typeof window !== "undefined") {
36
- localStorage.setItem("theme", theme);
37
+ Object.entries(tempThemes).forEach(([group, theme]) => {
38
+ const storedKey = group === "global" ? "theme" : `theme-${group}`;
39
+ localStorage.setItem(storedKey, theme);
40
+ });
37
41
  window.dispatchEvent(new Event("storage"));
38
- setSelectedTheme(theme);
42
+ setSelectedThemes(tempThemes);
43
+ setIsModalOpen(false);
39
44
  }
40
45
  };
41
- // input theme
42
- // const handleInputThemeChange = (theme: string) => {
43
- // if (typeof window !== "undefined") {
44
- // localStorage.setItem("inputTheme", theme);
45
- // window.dispatchEvent(new Event("storage"));
46
- // setSelectedInputTheme(theme);
47
- // }
48
- // };
49
- if (isThemeLoading == false) {
46
+
47
+ const handleOpenModal = () => {
48
+ setTempThemes(selectedThemes); // Reset to current applied themes
49
+ setIsModalOpen(true);
50
+ };
51
+
52
+ if (isThemeLoading === false) {
50
53
  return null;
51
54
  }
52
55
 
53
56
  return (
54
- <div className="flex flex-col gap-4">
55
- <p>theme 선택</p>
56
- <div className="flex flex-col gap-4">
57
- {type == "all" || type == "theme" ? (
58
- <div className="flex gap-4">
59
- {themes.map((theme) => (
60
- <Radio
61
- name="mainTheme"
62
- value={theme}
63
- key={theme}
64
- onChange={() => handleThemeChange(theme)}
65
- defaultChecked={theme == selectedTheme}
66
- />
67
- ))}
57
+ <>
58
+ <Button type="primary" onClick={handleOpenModal} style={{ width: "100%" }}>
59
+ <div className="flex items-center justify-center gap-2">
60
+ <span className="material-symbols-outlined" style={{ fontSize: "18px" }}>palette</span>
61
+ <span>테마 설정</span>
62
+ </div>
63
+ </Button>
64
+ <ModalContent
65
+ isOpen={isModalOpen}
66
+ onRequestClose={() => setIsModalOpen(false)}
67
+ modalTitle="테마 설정"
68
+ modalFooter={
69
+ <div className="flex justify-end gap-2 w-full mt-4">
70
+ <Button type="gray" onClick={() => setIsModalOpen(false)}>취소</Button>
71
+ <Button type="primary" onClick={handleApply}>적용</Button>
68
72
  </div>
69
- ) : null}
70
- {/* {type == "all" || type == "input" ? (
71
- <div className="flex gap-4">
72
- {inputThemes.map((inputTheme) => (
73
- <Radio
74
- name="inputTheme"
75
- value={inputTheme}
76
- key={inputTheme}
77
- onChange={() => handleInputThemeChange(inputTheme)}
78
- defaultChecked={inputTheme == selectedInputTheme}
79
- />
80
- ))}
81
- </div>
82
- ) : null} */}
83
- </div>
84
- </div>
73
+ }
74
+ >
75
+ <div className="flex flex-col gap-6 p-4">
76
+ {Object.entries(themes).map(([group, groupThemes]) => (
77
+ <div key={group} className="flex flex-col gap-3">
78
+ <p className="font-bold capitalize">{group} Theme</p>
79
+ <div className="flex gap-4 flex-wrap">
80
+ {groupThemes.map((theme) => (
81
+ <Radio
82
+ name={`theme-${group}-modal`}
83
+ value={theme}
84
+ key={theme}
85
+ onChange={() => handleTempThemeChange(group, theme)}
86
+ checked={theme === tempThemes[group]}
87
+ />
88
+ ))}
89
+ </div>
90
+ </div>
91
+ ))}
92
+ </div>
93
+ </ModalContent>
94
+ </>
85
95
  );
86
96
  };
87
97
 
88
- export const ThemeWrapper = ({
89
- children,
90
- className,
91
- }: {
92
- children: React.ReactNode;
93
- className: string;
94
- }) => {
95
- const [theme, setTheme] = useState<string | null>(null); // 테마 상태 추가
96
- const [inputTheme, setInputTheme] = useState<string | null>(null); // 테마 상태 추가
98
+ export const ThemeProvider = () => {
99
+ const [theme, setTheme] = useState<Record<string, string>>({});
97
100
  const [isThemeLoading, setThemeLoading] = useState(false);
98
- // theme setting
101
+
99
102
  useEffect(() => {
100
- // 로컬 스토리지에서 테마 가져오기
101
103
  const listenStorageChange = () => {
102
- setTheme(localStorage.getItem("theme") || "light");
103
- setInputTheme(localStorage.getItem("inputTheme") || "inputStandard");
104
-
105
- document.body.className = `${className} ${theme} ${inputTheme}`;
104
+ const newThemes: Record<string, string> = {};
105
+ Object.entries(themes).forEach(([group, groupThemes]) => {
106
+ const storedKey = group === "global" ? "theme" : `theme-${group}`;
107
+ const currentTheme = localStorage.getItem(storedKey) || groupThemes[0];
108
+ newThemes[group] = currentTheme;
109
+
110
+ document.documentElement.classList.remove(...groupThemes);
111
+ document.documentElement.classList.add(currentTheme);
112
+ });
113
+ setTheme(newThemes);
106
114
  };
115
+
107
116
  listenStorageChange();
108
117
  window.addEventListener("storage", listenStorageChange);
109
118
  setThemeLoading(true);
110
119
  return () => window.removeEventListener("storage", listenStorageChange);
111
- }, [theme]);
120
+ }, []);
112
121
 
113
- if (isThemeLoading == false) {
122
+ if (isThemeLoading === false) {
114
123
  return null;
115
124
  }
116
-
117
- return <>{children}</>;
118
125
  };
@@ -9,7 +9,7 @@ gsap.registerPlugin(useGSAP);
9
9
  // ✅ Toast Message 타입 정의
10
10
  export type ToastMessage = {
11
11
  id: string;
12
- status: "success" | "error";
12
+ status?: "standard" | "primary" | "secondary" | "success" | "danger" | "warning" | "info" | "error";
13
13
  message: string;
14
14
  desc?: string;
15
15
  };
@@ -55,7 +55,7 @@ export const Toast = () => {
55
55
  }, []);
56
56
 
57
57
  return (
58
- <div className="fixed flex flex-col gap-2 bottom-[24px] right-[24px] z-50">
58
+ <div className="toast-container">
59
59
  {messages.map((message) => (
60
60
  <ToastItem
61
61
  key={message.id}
@@ -97,10 +97,10 @@ const ToastItem = ({
97
97
  return (
98
98
  <div
99
99
  ref={elRef}
100
- className="bg-[var(--background-card)] border border-[var(--color-border)] rounded text-white p-4 shadow-md min-w-[250px]"
100
+ className={`toast-item ${message.status || "standard"}`}
101
101
  >
102
102
  <p>{message.message}</p>
103
- {message.desc ? <p className="text-sm">{message.desc}</p> : null}
103
+ {message.desc ? <p className="toast-desc">{message.desc}</p> : null}
104
104
  </div>
105
105
  );
106
106
  };