atomsystem 0.1.37 → 0.1.39

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.
@@ -1,306 +1,53 @@
1
- "use client";
1
+ "use client"
2
+
2
3
  import Link from "next/link";
3
- import Image from "next/image";
4
- import { useEffect, useState } from "react";
5
4
  import { usePathname } from "next/navigation";
6
- import clsx from "clsx";
7
- import { useMediaQuery } from "react-responsive";
8
5
 
9
- interface NavItemsAttr {
10
- type?: "topnav" | "sidenav";
11
- navMenu: {
12
- name: string;
13
- path?: string;
14
- }[];
6
+ // Navigation을 베이스 interface로 정의
7
+ export interface Navigation {
8
+ children: React.ReactNode;
15
9
  }
16
10
 
17
- // Custom CSS classes are now used via css/navigation.css
18
-
19
- const handleNavToggle = (targetId: string) => {
20
- const el = document.getElementById(targetId);
21
- if (el) {
22
- const isHidden = el.style.display === "none" || el.style.display === "";
23
- el.style.display = isHidden ? "block" : "none";
24
- }
25
- };
26
-
27
- const Navigation = ({
28
- children,
29
- id,
30
- className,
31
- type = "topnav",
32
- }: {
33
- children: React.ReactNode;
34
- id?: string;
35
- className?: string;
36
- type?: "topnav" | "sidenav";
37
- }) => {
38
- const isMobile = useMediaQuery({ maxWidth: 767 });
11
+ export interface NavLink extends Navigation {
12
+ href: string;
13
+ }
39
14
 
40
- const mobileClose = () => {
41
- if (isMobile) {
42
- if (id) {
43
- handleNavToggle(id);
44
- }
45
- }
46
- };
47
15
 
16
+ const Navigation = ({ children }: Navigation) => {
48
17
  return (
49
- <nav
50
- id={id ? id : undefined}
51
- className={`nav-container nav-${type} ${className} overflow-auto`}
52
- onClick={mobileClose}
53
- >
54
- {children}
55
- </nav>
56
- );
57
- };
18
+ <nav className="nav-menu flex items-center justify-between">
19
+ {children}
20
+ </nav>
21
+ )
22
+ }
58
23
 
59
- const NavItems = ({ navMenu, type = "sidenav" }: NavItemsAttr) => {
60
- const pathname = usePathname();
61
24
 
25
+ const NavBrand = ({children, href}: NavLink) => {
62
26
  return (
63
- <ul className={clsx(`nav-${type}`, { "flex flex-row items-center nav-gap": type === "topnav" })}>
64
- {navMenu.map((menu) => {
65
- return (
66
- <li className="relative group" key={menu.name}>
67
- <div className={clsx("flex justify-between items-center pr-4")}>
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>
74
- </div>
75
- </li>
76
- );
77
- })}
78
- </ul>
79
- );
80
- };
27
+ <Link href={href} className="flex items-center">{children}</Link>
28
+ )
29
+ }
81
30
 
82
- const NavToggleButton = ({
83
- children,
84
- targetId,
85
- className,
86
- }: {
87
- children: React.ReactNode;
88
- targetId: string;
89
- className?: string;
90
- }) => {
31
+ const NavList = ({children}: Navigation) => {
91
32
  return (
92
- <button className={className} onClick={() => handleNavToggle(targetId)}>
93
- {children}
94
- </button>
95
- );
96
- };
33
+ <ul className="flex items-center gap-0">{children}</ul>
34
+ )
35
+ }
97
36
 
98
- const Sidebar = ({ navMenu, type = "sidenav" }: NavItemsAttr) => {
99
- return (
100
- <nav
101
- className={clsx(
102
- `relative nav-container nav-${type} w-full md:w-[320px] h-full z-20 left-0 overflow-auto`
103
- )}
104
- >
105
- <ul>
106
- {navMenu.map((menu, idx) => {
107
- return (
108
- <li className="relative group" key={menu.name + idx}>
109
- <div className={clsx("flex justify-between items-center pr-4")}>
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>
118
- </div>
119
- </li>
120
- );
121
- })}
122
- </ul>
123
- </nav>
124
- );
125
- };
126
37
 
127
- const GlobalNav = ({
128
- type = "sidebar",
129
- navMenu,
130
- brand = true,
131
- }: {
132
- type?: "sidebar" | "topmenu" | "mobile";
133
- navMenu: {
134
- name: string;
135
- path?: string;
136
- subItems?: { name: string; path: string }[];
137
- label?: boolean;
138
- }[];
139
- brand?: boolean;
140
- }) => {
141
- const [windowSize, setWindowSize] = useState<number>(); // 초기값 설정
142
- const [toggleMenu, setToggleMenu] = useState<boolean>(true);
38
+ const NavItem = ({children, href}: NavLink) => {
143
39
  const pathname = usePathname();
144
- const [openSubMenu, setOpenSubMenu] = useState<Record<string, boolean>>({});
145
-
146
- // 윈도우 사이즈 추적
147
- useEffect(() => {
148
- const handleResize = () => {
149
- setWindowSize(window.innerWidth); // 윈도우 사이즈 업데이트
150
- };
151
-
152
- window.addEventListener("resize", handleResize); // 리사이즈 이벤트 리스너 추가
153
-
154
- return () => window.removeEventListener("resize", handleResize); // 컴포넌트 언마운트 시 리스너 제거
155
- }, [windowSize]);
40
+ const active = pathname === href;
156
41
 
157
- // 초기 토글 값 설정
158
- useEffect(() => {
159
- if (window.innerWidth > 768) {
160
- } else {
161
- setToggleMenu(false);
162
- }
163
- }, []);
164
-
165
- const toggleSubMenu = (menuName: string) => {
166
- setOpenSubMenu((prev) => ({
167
- ...prev,
168
- [menuName]: !prev[menuName],
169
- }));
170
- };
42
+ return (
43
+ <Link href={href} className={`nav-item ${active ? "text-primary!" : ""}`}>{children}</Link>
44
+ )
45
+ }
171
46
 
172
- const navType = type === "sidebar" ? "sidenav" : "topnav";
173
47
 
174
- return (
175
- <nav
176
- className={clsx(
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" }
180
- )}
181
- >
182
- {/* brand */}
183
- {brand ? (
184
- <div className="brand">
185
- <div className={`flex items-center justify-between`}>
186
- <Link href={"/"}>
187
- <Image
188
- src={"/images/global/logo.png"}
189
- alt="Logo"
190
- width={180}
191
- height={45}
192
- draggable="false"
193
- ></Image>
194
- </Link>
195
- <button
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`}
197
- onClick={() => setToggleMenu(!toggleMenu)}
198
- >
199
- <span
200
- className={`material-symbols-outlined nav-text-standard nav-${navType}`}
201
- style={{ fontSize: "16px" }}
202
- >
203
- menu
204
- </span>
205
- </button>
206
- </div>
207
- </div>
208
- ) : null}
209
- {/* List */}
210
- <ul
211
- className={clsx("", {
212
- "flex flex-row": type == "topmenu",
213
- })}
214
- >
215
- {navMenu.map((menu, idx) => {
216
- switch (true) {
217
- case menu.label === true && type == "sidebar":
218
- return (
219
- <p
220
- key={menu.name + idx}
221
- className={`nav-text-sub nav-${navType} mt-2 mb-0 nav-padding`}
222
- >
223
- {menu.name}
224
- </p>
225
- );
226
- default:
227
- return (
228
- <li className="relative group" key={menu.name}>
229
- <div
230
- className={clsx("flex justify-between items-center pr-4")}
231
- >
232
- <Link
233
- href={menu.path || "#"}
234
- className={clsx(
235
- `block nav-text-standard nav-${navType} nav-padding`,
236
- {
237
- "nav-text-active":
238
- (menu.path && menu.path == pathname) ||
239
- menu.subItems?.some((sub) => sub.path === pathname),
240
- }
241
- )}
242
- >
243
- {menu.name}
244
- </Link>
245
- {menu.subItems && type == "sidebar" ? (
246
- <button
247
- className="cursor-pointer"
248
- onClick={() => toggleSubMenu(menu.name)}
249
- >
250
- <span
251
- className={clsx(
252
- `material-symbols-outlined nav-text-sub nav-${navType} transition-transform`,
253
- {
254
- "rotate-90": openSubMenu[menu.name],
255
- }
256
- )}
257
- style={{ fontSize: "16px" }}
258
- >
259
- keyboard_arrow_right
260
- </span>
261
- </button>
262
- ) : null}
263
- </div>
264
- {menu.subItems ? (
265
- <ul
266
- className={clsx(
267
- "block",
268
- {
269
- [`hidden absolute top-[42px] group-hover:block hover:block nav-bg nav-${navType} border nav-border`]:
270
- type == "topmenu",
271
- },
272
- {
273
- hidden: !openSubMenu[menu.name] && type == "sidebar",
274
- }
275
- )}
276
- >
277
- {menu.subItems.map((submenu) => {
278
- return (
279
- <li key={submenu.name}>
280
- <Link
281
- className={clsx(
282
- `block nav-text-standard nav-${navType} nav-padding`,
283
- {
284
- "nav-text-active": submenu.path == pathname,
285
- },
286
- { "pl-12 ": type == "sidebar" }
287
- )}
288
- href={submenu.path}
289
- >
290
- {submenu.name}
291
- </Link>
292
- </li>
293
- );
294
- })}
295
- </ul>
296
- ) : null}
297
- </li>
298
- );
299
- }
300
- })}
301
- </ul>
302
- </nav>
303
- );
304
- };
305
- export default Navigation;
306
- export { Sidebar, GlobalNav, NavToggleButton, NavItems };
48
+ export {
49
+ Navigation,
50
+ NavBrand,
51
+ NavList,
52
+ NavItem
53
+ }
@@ -1,69 +1,16 @@
1
+ .nav-menu{
2
+ background-color: var(--bg-card);
3
+ border-bottom: 1px solid var(--border-standard);
4
+ padding: var(--spacing-common-y) var(--spacing-common-x);
1
5
 
2
-
3
- .nav-container.nav-topnav {
4
- background-color: var(--bg-topnav);
5
- color: var(--text-topnav-standard);
6
- border-color: var(--border-topnav);
7
- }
8
-
9
- .nav-container.nav-sidenav {
10
- background-color: var(--bg-sidenav);
11
- color: var(--text-sidenav-standard);
12
- border-color: var(--border-sidenav);
13
- }
14
-
15
- .nav-bg.nav-topnav {
16
- background-color: var(--bg-topnav);
17
- }
18
-
19
- .nav-bg.nav-sidenav {
20
- background-color: var(--bg-sidenav);
21
- }
22
-
23
- .nav-border.nav-topnav {
24
- border-color: var(--border-topnav);
25
- }
26
-
27
- .nav-border.nav-sidenav {
28
- border-color: var(--border-sidenav);
29
- }
30
-
31
- .nav-text-standard.nav-topnav {
32
- color: var(--text-topnav-standard);
33
- }
34
-
35
- .nav-text-standard.nav-sidenav {
36
- color: var(--text-sidenav-standard);
37
- }
38
-
39
- .nav-text-active.nav-topnav {
40
- color: var(--text-topnav-active);
41
- }
42
-
43
- .nav-text-active.nav-sidenav {
44
- color: var(--text-sidenav-active);
45
- }
46
-
47
- .nav-text-sub.nav-topnav {
48
- color: var(--text-topnav-sub);
49
6
  }
50
7
 
51
- .nav-text-sub.nav-sidenav {
52
- color: var(--text-sidenav-sub);
8
+ .nav-item{
9
+ border-radius: var(--radius-common);
10
+ padding: var(--spacing-common-y) var(--spacing-common-x);
11
+ color: var(--text-standard);
53
12
  }
54
13
 
55
- .nav-padding.nav-topnav {
56
- padding: var(--spacing-topnav-y) var(--spacing-topnav-x);
57
- }
58
-
59
- .nav-padding.nav-sidenav {
60
- padding: var(--spacing-sidenav-y) var(--spacing-sidenav-x);
61
- }
62
-
63
- .nav-gap.nav-topnav {
64
- gap: var(--spacing-topnav-gap);
65
- }
66
-
67
- .nav-gap.nav-sidenav {
68
- gap: var(--spacing-sidenav-gap);
69
- }
14
+ .nav-item:hover{
15
+ background-color: var(--bg-hover);
16
+ }
@@ -0,0 +1,55 @@
1
+ "use client"
2
+
3
+ import Link from "next/link";
4
+ import { usePathname } from "next/navigation";
5
+
6
+ // Navigation을 베이스 interface로 정의
7
+ export interface Sidemenu {
8
+ children: React.ReactNode;
9
+ minWidth?: number
10
+ }
11
+
12
+ export interface NavLink {
13
+ children: React.ReactNode;
14
+ href: string;
15
+ }
16
+
17
+
18
+ const Sidemenu = ({ children, minWidth }: Sidemenu) => {
19
+ return (
20
+ <aside className={`nav-side flex flex-col overflow-auto h-full`} style={{minWidth: `${minWidth}px`}}>
21
+ {children}
22
+ </aside>
23
+ )
24
+ }
25
+
26
+
27
+ const NavBrand = ({children, href}: NavLink) => {
28
+ return (
29
+ <Link href={href} className="flex items-center">{children}</Link>
30
+ )
31
+ }
32
+
33
+ const NavList = ({children}: Sidemenu) => {
34
+ return (
35
+ <ul className="nav-list flex flex-col">{children}</ul>
36
+ )
37
+ }
38
+
39
+
40
+ const NavItem = ({children, href}: NavLink) => {
41
+ const pathname = usePathname();
42
+ const active = pathname === href;
43
+
44
+ return (
45
+ <Link href={href} className={`nav-item text-nowrap ${active ? "text-primary!" : ""}`}>{children}</Link>
46
+ )
47
+ }
48
+
49
+
50
+ export {
51
+ Sidemenu,
52
+ NavBrand,
53
+ NavList,
54
+ NavItem
55
+ }
@@ -0,0 +1,4 @@
1
+ .nav-side{
2
+ background-color: var(--bg-card);
3
+ border-right: 1px solid var(--border-standard);
4
+ }