atomsystem 0.1.39 → 0.1.40

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.
@@ -2,6 +2,15 @@
2
2
 
3
3
  import Link from "next/link";
4
4
  import { usePathname } from "next/navigation";
5
+ import gsap from 'gsap';
6
+ import { useGSAP } from '@gsap/react';
7
+ import { useRef, createContext, useContext, useState } from "react";
8
+
9
+ // Icons
10
+ import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
11
+
12
+
13
+ gsap.registerPlugin(useGSAP); // register the hook to avoid React version discrepancies
5
14
 
6
15
  // Navigation을 베이스 interface로 정의
7
16
  export interface Navigation {
@@ -12,7 +21,33 @@ export interface NavLink extends Navigation {
12
21
  href: string;
13
22
  }
14
23
 
24
+ /**
25
+ * NavContextProps: 네비게이션 상태를 하위 컴포넌트와 공유하기 위한 인터페이스
26
+ * - isOpen: 메뉴가 열려 있는지 여부
27
+ * - setOpen: 메뉴 상태를 변경하는 함수
28
+ */
29
+ interface NavContextProps {
30
+ isOpen: boolean;
31
+ setOpen: (open: boolean) => void;
32
+ }
15
33
 
34
+ // NavContext: 상위 NavItem의 상태를 하 하위 NavTrigger와 NavContainer에 전달하는 통로(우체국)
35
+ const NavContext = createContext<NavContextProps | undefined>(undefined);
36
+
37
+ /**
38
+ * useNavContext: Context 정보를 쉽고 안전하게 꺼내 쓰기 위한 전용 커스텀 훅
39
+ * - 부모인 NavItem이 없을 경우(undefined)에도 에러가 나지 않도록 기본값을 반환하는 안전 장치 포함
40
+ */
41
+ const useNavContext = () => {
42
+ const context = useContext(NavContext);
43
+ if (!context) {
44
+ // 부모를 찾지 못했을 때 앱이 멈추지 않도록 기본 상태 반환
45
+ return { isOpen: false, setOpen: () => {} };
46
+ }
47
+ return context;
48
+ };
49
+
50
+ // 최상위 Navigation 레이아웃 컴포넌트
16
51
  const Navigation = ({ children }: Navigation) => {
17
52
  return (
18
53
  <nav className="nav-menu flex items-center justify-between">
@@ -21,33 +56,114 @@ const Navigation = ({ children }: Navigation) => {
21
56
  )
22
57
  }
23
58
 
24
-
59
+ // 로고나 브랜드명을 위한 컴포넌트
25
60
  const NavBrand = ({children, href}: NavLink) => {
26
61
  return (
27
- <Link href={href} className="flex items-center">{children}</Link>
62
+ <Link href={href} className="flex items-center h-full font-bold text-xl">{children}</Link>
63
+ )
64
+ }
65
+
66
+ /**
67
+ * NavItem: 개별 메뉴 항목 및 서브 메뉴의 상태를 관리하는 부모 컨테이너
68
+ * - 각각의 NavItem은 자신만의 isOpen 상태를 독립적으로 가짐
69
+ */
70
+ const NavItem = ({children}: Navigation) => {
71
+ const [isOpen, setIsOpen] = useState(false);
72
+ const setOpen = (open: boolean) => setIsOpen(open);
73
+
74
+ // 마우스가 메뉴 전체 영역을 완전히 벗어날 때 호출 (메뉴 닫기)
75
+ const handleMouseLeave = () => setIsOpen(false);
76
+
77
+ return (
78
+ <NavContext.Provider value={{ isOpen, setOpen }}>
79
+ <li
80
+ className={`nav-item`}
81
+ onMouseLeave={handleMouseLeave}
82
+ >
83
+ {children}
84
+ </li>
85
+ </NavContext.Provider>
28
86
  )
29
87
  }
30
88
 
89
+ // 메뉴 항목들을 가로로 정렬해주는 리스트 컨테이너
31
90
  const NavList = ({children}: Navigation) => {
32
91
  return (
33
92
  <ul className="flex items-center gap-0">{children}</ul>
34
93
  )
35
94
  }
36
95
 
37
-
38
- const NavItem = ({children, href}: NavLink) => {
96
+ // 일반적인 링크 메뉴 컴포넌트
97
+ const NavLink = ({children, href}: NavLink) => {
39
98
  const pathname = usePathname();
40
99
  const active = pathname === href;
41
100
 
42
101
  return (
43
- <Link href={href} className={`nav-item ${active ? "text-primary!" : ""}`}>{children}</Link>
102
+ <Link href={href} className={`nav-link ${active ? "active" : ""}`}>{children}</Link>
44
103
  )
45
104
  }
46
105
 
106
+ /**
107
+ * NavTrigger: 서브 메뉴를 여는 트리거 버튼
108
+ * - 마우스를 올렸을 때(onMouseEnter) 부모 NavItem의 상태를 열림(true)으로 변경
109
+ */
110
+ const NavTrigger = ({children}: Navigation) => {
111
+ const { isOpen, setOpen } = useNavContext();
112
+
113
+ // 트리거 영역에 진입했을 때만 메뉴 열기 실행
114
+ const handleMouseEnter = () => setOpen(true);
115
+
116
+ return (
117
+ <div
118
+ className="nav-link flex items-center gap-1"
119
+ onMouseEnter={handleMouseEnter}
120
+ >
121
+ {children}
122
+ {/* 상태에 따라 화살표 아이콘 회전 애니메이션 클래스 적용 */}
123
+ <KeyboardArrowDownIcon className={`nav-arrow ${isOpen ? "open" : ""}`} />
124
+ </div>
125
+ )
126
+ }
127
+
128
+ /**
129
+ * NavContainer: 서브 메뉴의 실제 내용물이 담기는 컨테이너
130
+ * - GSAP을 사용하여 나타날 때 부드러운 애니메이션 효과 적용
131
+ */
132
+ const NavContainer = ({children}: Navigation) => {
133
+ const { isOpen } = useNavContext();
134
+ const containerContentRef = useRef<HTMLUListElement>(null);
135
+
136
+ // 메뉴가 열릴 때 실행되는 GSAP 애니메이션
137
+ useGSAP(() => {
138
+ if (isOpen && containerContentRef.current) {
139
+ gsap.fromTo(containerContentRef.current,
140
+ { opacity: 0, y: -10 }, // 시작 상태: 투명하고 살짝 위쪽
141
+ { opacity: 1, y: 0, duration: 0.2, ease: "power2.out" } // 도착 상태: 불투명하고 제자리
142
+ );
143
+ }
144
+ }, [isOpen]);
145
+
146
+
147
+ // 닫혀 있을 때는 아예 렌더링하지 않음
148
+ if (!isOpen) return null;
149
+
150
+ return (
151
+ <div className="nav-container">
152
+ {/* 실제 박스 형태를 가진 내부 리스트 */}
153
+ <ul ref={containerContentRef} className="nav-content">
154
+ {children}
155
+ </ul>
156
+ </div>
157
+ )
158
+ }
159
+
47
160
 
48
161
  export {
49
162
  Navigation,
50
163
  NavBrand,
51
164
  NavList,
52
- NavItem
165
+ NavItem,
166
+ NavLink,
167
+ NavTrigger,
168
+ NavContainer
53
169
  }
@@ -1,16 +1,59 @@
1
1
  .nav-menu{
2
2
  background-color: var(--bg-card);
3
+ padding: 0 var(--spacing-common-x);
3
4
  border-bottom: 1px solid var(--border-standard);
4
- padding: var(--spacing-common-y) var(--spacing-common-x);
5
-
5
+ position: relative;
6
6
  }
7
7
 
8
8
  .nav-item{
9
+ display: block;
9
10
  border-radius: var(--radius-common);
11
+ padding: var(--spacing-common-y) 0;
12
+ color: var(--text-standard);
13
+ }
14
+
15
+
16
+ .nav-link{
17
+ display: block;
10
18
  padding: var(--spacing-common-y) var(--spacing-common-x);
11
- color: var(--text-standard);
19
+ border-radius: var(--radius-common);
20
+ cursor: pointer;
12
21
  }
13
22
 
14
- .nav-item:hover{
23
+ .nav-link:hover{
15
24
  background-color: var(--bg-hover);
16
- }
25
+ }
26
+
27
+ .nav-link.active{
28
+ color: var(--color-primary);
29
+ }
30
+
31
+ .nav-container {
32
+ position: absolute;
33
+ padding: var(--spacing-common-y) 0;
34
+ top: 100%;
35
+ left: 0;
36
+ right: 0;
37
+ width: 100%;
38
+ z-index: 100;
39
+ }
40
+
41
+ .nav-content {
42
+ display: flex;
43
+ width: 100%;
44
+ flex-wrap: wrap;
45
+ gap: var(--spacing-common-x);
46
+ background-color: var(--bg-card);
47
+ border: 1px solid var(--border-standard);
48
+ border-radius: var(--radius-common);
49
+ padding: var(--spacing-common-y) var(--spacing-common-x);
50
+ box-shadow: var(--shadow-standard);
51
+ }
52
+
53
+ .nav-arrow {
54
+ transition: transform 0.2s ease;
55
+ }
56
+
57
+ .nav-arrow.open {
58
+ transform: rotate(180deg);
59
+ }
@@ -0,0 +1,139 @@
1
+ "use client"
2
+
3
+ import Link from "next/link";
4
+ import { usePathname } from "next/navigation";
5
+ import gsap from 'gsap';
6
+ import { useGSAP } from '@gsap/react';
7
+ import { createContext, useContext, useRef, useState } from "react";
8
+
9
+ // Icons
10
+ import MenuIcon from '@mui/icons-material/Menu';
11
+
12
+ gsap.registerPlugin(useGSAP); // register the hook to avoid React version discrepancies
13
+
14
+ // Navigation을 베이스 interface로 정의
15
+ export interface Sidebar {
16
+ children: React.ReactNode;
17
+ minWidth?: number
18
+ }
19
+
20
+ export interface NavLink {
21
+ children: React.ReactNode;
22
+ href: string;
23
+ }
24
+
25
+ interface SideContext {
26
+ isOpen: boolean;
27
+ setToggle: (open: boolean) => void;
28
+ }
29
+
30
+ const SideContext = createContext<SideContext | undefined>(undefined);
31
+
32
+ const useSideContext = () => {
33
+ const context = useContext(SideContext);
34
+ if (!context) {
35
+ return { isOpen: false, setToggle: () => {} };
36
+ }
37
+ return context;
38
+ }
39
+
40
+ const SidebarProvider = ({ children }: { children: React.ReactNode }) => {
41
+ const [isOpen, setIsOpen] = useState(true);
42
+ const setToggle = (open: boolean) => setIsOpen(open);
43
+
44
+ return (
45
+ <SideContext.Provider value={{ isOpen, setToggle }}>
46
+ {children}
47
+ </SideContext.Provider>
48
+ );
49
+ };
50
+
51
+ const SidebarToggle = () => {
52
+ const { isOpen, setToggle } = useSideContext();
53
+ return (
54
+ <button className="cursor-pointer" onClick={() => setToggle(!isOpen)}><MenuIcon className="text-text-sub" sx={{fontSize: "20px"}}/></button>
55
+ )
56
+ }
57
+
58
+ const Sidebar = ({ children, minWidth }: Sidebar) => {
59
+ const { isOpen } = useSideContext();
60
+ const sidebarRef = useRef<HTMLDivElement>(null);
61
+
62
+ useGSAP(() => {
63
+ if (sidebarRef.current) {
64
+ if (isOpen) {
65
+ // 열릴 때: 나타나면서 제자리로
66
+ gsap.to(sidebarRef.current, {
67
+ display: "flex",
68
+ opacity: 1,
69
+ x: 0,
70
+ width: minWidth,
71
+ minWidth: minWidth,
72
+ duration: 0.3,
73
+ ease: "power2.out"
74
+ });
75
+ } else {
76
+ // 닫힐 때: 사라지면서 왼쪽으로, 너비도 0으로
77
+ gsap.to(sidebarRef.current, {
78
+ opacity: 0,
79
+ x: -20,
80
+ width: 0,
81
+ minWidth: 0,
82
+ duration: 0.3,
83
+ ease: "power2.in",
84
+ onComplete: () => {
85
+ gsap.set(sidebarRef.current, { display: "none" });
86
+ }
87
+ });
88
+ }
89
+ }
90
+ }, [isOpen]);
91
+
92
+
93
+ return (
94
+ <aside ref={sidebarRef} className={`nav-side flex-col overflow-hidden h-full`} style={{ width: isOpen ? minWidth : 0, minWidth: isOpen ? minWidth : 0 }}>
95
+ {children}
96
+ </aside>
97
+ )
98
+ }
99
+
100
+
101
+ const SideNavBrand = ({children, href}: NavLink) => {
102
+ return (
103
+ <Link href={href} className="flex items-center">{children}</Link>
104
+ )
105
+ }
106
+
107
+ const SideNavList = ({children}: Sidebar) => {
108
+ return (
109
+ <ul className="nav-list flex flex-col">{children}</ul>
110
+ )
111
+ }
112
+
113
+
114
+ const SideNavItem = ({children}: Sidebar) => {
115
+ return (
116
+ <li>{children}</li>
117
+ )
118
+ }
119
+
120
+ const SideNavLink = ({children, href}: NavLink) => {
121
+
122
+ const pathname = usePathname();
123
+ const active = pathname === href;
124
+
125
+ return (
126
+ <Link href={href} className={`nav-link text-nowrap ${active ? "active" : ""}`}>{children}</Link>
127
+ )
128
+ }
129
+
130
+
131
+ export {
132
+ Sidebar,
133
+ SidebarProvider,
134
+ SidebarToggle,
135
+ SideNavBrand,
136
+ SideNavList,
137
+ SideNavItem,
138
+ SideNavLink
139
+ }
@@ -1,251 +1,251 @@
1
- @theme {
2
- --color-gray-100: #f5f5f5;
3
- --color-gray-200: #e6e6e6;
4
- --color-gray-300: #dbdbdb;
5
- --color-gray-400: #d4d4d4;
6
- --color-gray-500: #cccccc;
7
- --color-gray-600: #bfbfbf;
8
- --color-gray-700: #b3b3b3;
9
- --color-gray-800: #a6a6a6;
10
- --color-gray-900: #999999;
11
- --color-gray-950: #707070;
12
- --color-dark-100: #111111;
13
- --color-dark-200: #222222;
14
- --color-dark-300: #333333;
15
- --color-dark-400: #444444;
16
- --color-dark-500: #555555;
17
- --color-dark-600: #666666;
18
- --color-dark-700: #777777;
19
- --color-dark-800: #888888;
20
- --color-dark-900: #999999;
21
- --color-dark-950: #b2b2b2;
22
- --color-blue-100: #e3f2fd;
23
- --color-blue-200: #bbdefb;
24
- --color-blue-300: #90caf9;
25
- --color-blue-400: #64b5f6;
26
- --color-blue-500: #2196f3;
27
- --color-blue-600: #1e88e5;
28
- --color-blue-700: #1976d2;
29
- --color-blue-800: #1565c0;
30
- --color-blue-900: #0d47a1;
31
- --color-blue-950: #0a2f6b;
32
- --color-indigo-100: #e8eaf6;
33
- --color-indigo-200: #c5cae9;
34
- --color-indigo-300: #7986cb;
35
- --color-indigo-400: #3f51b5;
36
- --color-indigo-500: #162c4e;
37
- --color-indigo-600: #122542;
38
- --color-indigo-700: #0e1d35;
39
- --color-indigo-800: #0a1628;
40
- --color-indigo-900: #070f1b;
41
- --color-indigo-950: #04080e;
42
- --color-red-100: #ffebee;
43
- --color-red-200: #ffcdd2;
44
- --color-red-300: #ef9a9a;
45
- --color-red-400: #e57373;
46
- --color-red-500: #f44336;
47
- --color-red-600: #e53935;
48
- --color-red-700: #d32f2f;
49
- --color-red-800: #c62828;
50
- --color-red-900: #b71c1c;
51
- --color-red-950: #7f1212;
52
- --color-yellow-100: #fff8e1;
53
- --color-yellow-200: #ffecb3;
54
- --color-yellow-300: #ffe082;
55
- --color-yellow-400: #ffd54f;
56
- --color-yellow-500: #ffb300;
57
- --color-yellow-600: #ffa000;
58
- --color-yellow-700: #ff8f00;
59
- --color-yellow-800: #ff6f00;
60
- --color-yellow-900: #e65100;
61
- --color-yellow-950: #9e3600;
62
- --color-green-100: #e8f5e9;
63
- --color-green-200: #c8e6c9;
64
- --color-green-300: #a5d6a7;
65
- --color-green-400: #81c784;
66
- --color-green-500: #4caf50;
67
- --color-green-600: #43a047;
68
- --color-green-700: #388e3c;
69
- --color-green-800: #2e7d32;
70
- --color-green-900: #1b5e20;
71
- --color-green-950: #104015;
72
- --color-black: #111111;
73
- --color-white: #fafafa;
74
- --color-primary: var(--color-blue-500);
75
- --color-secondary: var(--color-indigo-500);
76
- --color-danger: var(--color-red-500);
77
- --color-warning: var(--color-yellow-500);
78
- --color-info: var(--color-gray-900);
79
- --color-success: var(--color-green-500);
80
- --text-h1: 40px;
81
- --text-h2: 36px;
82
- --text-h3: 28px;
83
- --text-h4: 24px;
84
- --text-h5: 20px;
85
- --text-h6: 16px;
86
- --text-body: 16px;
87
- --text-sm: 12px;
88
- --font-weight-header: 700;
89
- --radius-common: 4px;
90
- --radius-circle: 10000000px;
91
- --font-spoqaNeo: Spoqa Han Sans Neo;
92
- --spacing-common-y: 12px;
93
- --spacing-common-x: 16px;
94
- --spacing-gap-small: 4px;
95
- --spacing-sm-y: 8px;
96
- --spacing-small: 20px;
97
-
98
- --color-bg-card: var(--bg-card);
99
- --color-bg-wrapper: var(--bg-wrapper);
100
- --color-bg-hover: var(--bg-hover);
101
- --color-bg-input-standard: var(--bg-input-standard);
102
- --color-bg-input-hover: var(--bg-input-hover);
103
- --color-bg-input-disabled: var(--bg-input-disabled);
104
- --color-text-title: var(--text-title);
105
- --color-text-body: var(--text-body);
106
- --color-text-sub: var(--text-sub);
107
- --color-text-standard: var(--text-standard);
108
- --color-text-active: var(--text-active);
109
- --color-text-placeholder: var(--text-placeholder);
110
- --color-text-disabled: var(--text-disabled);
111
- --color-border-standard: var(--border-standard);
112
- --color-border-active: var(--border-active);
113
- --color-button-primary-bg-disabled: var(--button-primary-bg-disabled);
114
- --color-button-primary-text-disabled: var(--button-primary-text-disabled);
115
- --color-button-primary-border-disabled: var(--button-primary-border-disabled);
116
- --color-button-secondary-bg-disabled: var(--button-secondary-bg-disabled);
117
- --color-button-secondary-text-disabled: var(--button-secondary-text-disabled);
118
- --color-button-secondary-border-disabled: var(--button-secondary-border-disabled);
119
- --color-button-success-bg-disabled: var(--button-success-bg-disabled);
120
- --color-button-success-text-disabled: var(--button-success-text-disabled);
121
- --color-button-success-border-disabled: var(--button-success-border-disabled);
122
- --color-button-danger-bg-disabled: var(--button-danger-bg-disabled);
123
- --color-button-danger-text-disabled: var(--button-danger-text-disabled);
124
- --color-button-danger-border-disabled: var(--button-danger-border-disabled);
125
- --color-button-warning-bg-disabled: var(--button-warning-bg-disabled);
126
- --color-button-warning-text-disabled: var(--button-warning-text-disabled);
127
- --color-button-warning-border-disabled: var(--button-warning-border-disabled);
128
- --color-button-gray-bg-disabled: var(--button-gray-bg-disabled);
129
- --color-button-gray-text-disabled: var(--button-gray-text-disabled);
130
- --color-button-gray-border-disabled: var(--button-gray-border-disabled);
131
- --color-table-header-bg: var(--table-header-bg);
132
- --color-table-header-text: var(--table-header-text);
133
- --color-table-header-border: var(--table-header-border);
134
- --color-table-body-bg: var(--table-body-bg);
135
- --color-table-body-bgEven: var(--table-body-bgEven);
136
- --color-table-body-text: var(--table-body-text);
137
- --color-table-body-border: var(--table-body-border);
138
- --color-pagination-bg-hover: var(--pagination-bg-hover);
139
- --color-callout-note-bg: var(--callout-note-bg);
140
- --color-callout-note-text: var(--callout-note-text);
141
- --color-callout-tip-bg: var(--callout-tip-bg);
142
- --color-callout-tip-text: var(--callout-tip-text);
143
- --color-callout-danger-bg: var(--callout-danger-bg);
144
- --color-callout-danger-text: var(--callout-danger-text);
145
- --color-callout-warning-bg: var(--callout-warning-bg);
146
- --color-callout-warning-text: var(--callout-warning-text);
147
- }
148
-
149
- .white {
150
- --bg-card: var(--color-white);
151
- --bg-wrapper: var(--color-gray-200);
152
- --bg-hover: var(--color-gray-200);
153
- --bg-input-standard: var(--color-gray-100);
154
- --bg-input-hover: var(--color-gray-200);
155
- --bg-input-disabled: var(--color-gray-500);
156
- --text-title: var(--color-dark-100);
157
- --text-body: var(--color-dark-400);
158
- --text-sub: var(--color-gray-950);
159
- --text-standard: var(--color-dark-300);
160
- --text-active: var(--color-gray-100);
161
- --text-placeholder: var(--color-gray-950);
162
- --text-disabled: var(--color-gray-950);
163
- --border-standard: var(--color-gray-500);
164
- --border-active: var(--color-dark-400);
165
- --button-primary-bg-disabled: var(--color-blue-200);
166
- --button-primary-text-disabled: var(--color-blue-400);
167
- --button-primary-border-disabled: var(--color-blue-200);
168
- --button-secondary-bg-disabled: var(--color-indigo-200);
169
- --button-secondary-text-disabled: var(--color-indigo-400);
170
- --button-secondary-border-disabled: var(--color-indigo-200);
171
- --button-success-bg-disabled: var(--color-green-200);
172
- --button-success-text-disabled: var(--color-green-400);
173
- --button-success-border-disabled: var(--color-green-200);
174
- --button-danger-bg-disabled: var(--color-red-200);
175
- --button-danger-text-disabled: var(--color-red-400);
176
- --button-danger-border-disabled: var(--color-red-200);
177
- --button-warning-bg-disabled: var(--color-yellow-200);
178
- --button-warning-text-disabled: var(--color-yellow-400);
179
- --button-warning-border-disabled: var(--color-yellow-200);
180
- --button-gray-bg-disabled: var(--color-gray-200);
181
- --button-gray-text-disabled: var(--color-gray-500);
182
- --button-gray-border-disabled: var(--color-gray-300);
183
- --table-header-bg: var(--color-gray-400);
184
- --table-header-text: var(--color-dark-500);
185
- --table-header-border: var(--color-gray-500);
186
- --table-body-bg: var(--color-white);
187
- --table-body-bgEven: var(--color-gray-100);
188
- --table-body-text: var(--color-dark-300);
189
- --table-body-border: var(--color-gray-300);
190
- --pagination-bg-hover: var(--color-gray-100);
191
- --callout-note-bg: var(--color-gray-100);
192
- --callout-note-text: var(--color-gray-900);
193
- --callout-tip-bg: var(--color-green-100);
194
- --callout-tip-text: var(--color-green-900);
195
- --callout-danger-bg: var(--color-red-100);
196
- --callout-danger-text: var(--color-red-900);
197
- --callout-warning-bg: var(--color-yellow-100);
198
- --callout-warning-text: var(--color-yellow-900);
199
- }
200
-
201
- .dark {
202
- --bg-card: var(--color-dark-200);
203
- --bg-wrapper: var(--color-black);
204
- --bg-hover: var(--color-dark-400);
205
- --bg-input-standard: var(--color-dark-300);
206
- --bg-input-hover: var(--color-dark-400);
207
- --bg-input-disabled: var(--color-dark-200);
208
- --text-title: var(--color-white);
209
- --text-body: var(--color-gray-200);
210
- --text-sub: var(--color-gray-600);
211
- --text-standard: var(--color-white);
212
- --text-active: var(--color-white);
213
- --text-placeholder: var(--color-gray-950);
214
- --text-disabled: var(--color-dark-400);
215
- --border-standard: var(--color-dark-400);
216
- --border-active: var(--color-gray-500);
217
- --button-primary-bg-disabled: var(--color-blue-900);
218
- --button-primary-text-disabled: var(--color-blue-700);
219
- --button-primary-border-disabled: var(--color-blue-800);
220
- --button-secondary-bg-disabled: var(--color-indigo-900);
221
- --button-secondary-text-disabled: var(--color-indigo-700);
222
- --button-secondary-border-disabled: var(--color-indigo-800);
223
- --button-success-bg-disabled: var(--color-green-900);
224
- --button-success-text-disabled: var(--color-green-700);
225
- --button-success-border-disabled: var(--color-green-800);
226
- --button-danger-bg-disabled: var(--color-red-900);
227
- --button-danger-text-disabled: var(--color-red-700);
228
- --button-danger-border-disabled: var(--color-red-800);
229
- --button-warning-bg-disabled: var(--color-yellow-900);
230
- --button-warning-text-disabled: var(--color-yellow-700);
231
- --button-warning-border-disabled: var(--color-yellow-800);
232
- --button-gray-bg-disabled: var(--color-gray-800);
233
- --button-gray-text-disabled: var(--color-gray-600);
234
- --button-gray-border-disabled: var(--color-gray-700);
235
- --table-header-bg: var(--color-dark-400);
236
- --table-header-text: var(--color-gray-200);
237
- --table-header-border: var(--color-dark-600);
238
- --table-body-bg: var(--color-dark-200);
239
- --table-body-bgEven: var(--color-dark-300);
240
- --table-body-text: var(--color-gray-200);
241
- --table-body-border: var(--color-dark-400);
242
- --pagination-bg-hover: var(--color-dark-300);
243
- --callout-note-bg: var(--color-dark-300);
244
- --callout-note-text: var(--color-white);
245
- --callout-tip-bg: var(--color-green-950);
246
- --callout-tip-text: var(--color-green-200);
247
- --callout-danger-bg: var(--color-red-950);
248
- --callout-danger-text: var(--color-red-200);
249
- --callout-warning-bg: var(--color-yellow-950);
250
- --callout-warning-text: var(--color-yellow-200);
1
+ @theme {
2
+ --color-gray-100: #f5f5f5;
3
+ --color-gray-200: #e6e6e6;
4
+ --color-gray-300: #dbdbdb;
5
+ --color-gray-400: #d4d4d4;
6
+ --color-gray-500: #cccccc;
7
+ --color-gray-600: #bfbfbf;
8
+ --color-gray-700: #b3b3b3;
9
+ --color-gray-800: #a6a6a6;
10
+ --color-gray-900: #999999;
11
+ --color-gray-950: #707070;
12
+ --color-dark-100: #111111;
13
+ --color-dark-200: #222222;
14
+ --color-dark-300: #333333;
15
+ --color-dark-400: #444444;
16
+ --color-dark-500: #555555;
17
+ --color-dark-600: #666666;
18
+ --color-dark-700: #777777;
19
+ --color-dark-800: #888888;
20
+ --color-dark-900: #999999;
21
+ --color-dark-950: #b2b2b2;
22
+ --color-blue-100: #e3f2fd;
23
+ --color-blue-200: #bbdefb;
24
+ --color-blue-300: #90caf9;
25
+ --color-blue-400: #64b5f6;
26
+ --color-blue-500: #2196f3;
27
+ --color-blue-600: #1e88e5;
28
+ --color-blue-700: #1976d2;
29
+ --color-blue-800: #1565c0;
30
+ --color-blue-900: #0d47a1;
31
+ --color-blue-950: #0a2f6b;
32
+ --color-indigo-100: #e8eaf6;
33
+ --color-indigo-200: #c5cae9;
34
+ --color-indigo-300: #7986cb;
35
+ --color-indigo-400: #3f51b5;
36
+ --color-indigo-500: #162c4e;
37
+ --color-indigo-600: #122542;
38
+ --color-indigo-700: #0e1d35;
39
+ --color-indigo-800: #0a1628;
40
+ --color-indigo-900: #070f1b;
41
+ --color-indigo-950: #04080e;
42
+ --color-red-100: #ffebee;
43
+ --color-red-200: #ffcdd2;
44
+ --color-red-300: #ef9a9a;
45
+ --color-red-400: #e57373;
46
+ --color-red-500: #f44336;
47
+ --color-red-600: #e53935;
48
+ --color-red-700: #d32f2f;
49
+ --color-red-800: #c62828;
50
+ --color-red-900: #b71c1c;
51
+ --color-red-950: #7f1212;
52
+ --color-yellow-100: #fff8e1;
53
+ --color-yellow-200: #ffecb3;
54
+ --color-yellow-300: #ffe082;
55
+ --color-yellow-400: #ffd54f;
56
+ --color-yellow-500: #ffb300;
57
+ --color-yellow-600: #ffa000;
58
+ --color-yellow-700: #ff8f00;
59
+ --color-yellow-800: #ff6f00;
60
+ --color-yellow-900: #e65100;
61
+ --color-yellow-950: #9e3600;
62
+ --color-green-100: #e8f5e9;
63
+ --color-green-200: #c8e6c9;
64
+ --color-green-300: #a5d6a7;
65
+ --color-green-400: #81c784;
66
+ --color-green-500: #4caf50;
67
+ --color-green-600: #43a047;
68
+ --color-green-700: #388e3c;
69
+ --color-green-800: #2e7d32;
70
+ --color-green-900: #1b5e20;
71
+ --color-green-950: #104015;
72
+ --color-black: #111111;
73
+ --color-white: #fafafa;
74
+ --color-primary: var(--color-blue-500);
75
+ --color-secondary: var(--color-indigo-500);
76
+ --color-danger: var(--color-red-500);
77
+ --color-warning: var(--color-yellow-500);
78
+ --color-info: var(--color-gray-900);
79
+ --color-success: var(--color-green-500);
80
+ --text-h1: 40px;
81
+ --text-h2: 36px;
82
+ --text-h3: 28px;
83
+ --text-h4: 24px;
84
+ --text-h5: 20px;
85
+ --text-h6: 16px;
86
+ --text-body: 16px;
87
+ --text-sm: 12px;
88
+ --font-weight-header: 700;
89
+ --radius-common: 4px;
90
+ --radius-circle: 10000000px;
91
+ --font-spoqaNeo: Spoqa Han Sans Neo;
92
+ --spacing-common-y: 12px;
93
+ --spacing-common-x: 16px;
94
+ --spacing-gap-small: 4px;
95
+ --spacing-sm-y: 8px;
96
+ --spacing-small: 20px;
97
+
98
+ --color-bg-card: var(--bg-card);
99
+ --color-bg-wrapper: var(--bg-wrapper);
100
+ --color-bg-hover: var(--bg-hover);
101
+ --color-bg-input-standard: var(--bg-input-standard);
102
+ --color-bg-input-hover: var(--bg-input-hover);
103
+ --color-bg-input-disabled: var(--bg-input-disabled);
104
+ --color-text-title: var(--text-title);
105
+ --color-text-body: var(--text-body);
106
+ --color-text-sub: var(--text-sub);
107
+ --color-text-standard: var(--text-standard);
108
+ --color-text-active: var(--text-active);
109
+ --color-text-placeholder: var(--text-placeholder);
110
+ --color-text-disabled: var(--text-disabled);
111
+ --color-border-standard: var(--border-standard);
112
+ --color-border-active: var(--border-active);
113
+ --color-button-primary-bg-disabled: var(--button-primary-bg-disabled);
114
+ --color-button-primary-text-disabled: var(--button-primary-text-disabled);
115
+ --color-button-primary-border-disabled: var(--button-primary-border-disabled);
116
+ --color-button-secondary-bg-disabled: var(--button-secondary-bg-disabled);
117
+ --color-button-secondary-text-disabled: var(--button-secondary-text-disabled);
118
+ --color-button-secondary-border-disabled: var(--button-secondary-border-disabled);
119
+ --color-button-success-bg-disabled: var(--button-success-bg-disabled);
120
+ --color-button-success-text-disabled: var(--button-success-text-disabled);
121
+ --color-button-success-border-disabled: var(--button-success-border-disabled);
122
+ --color-button-danger-bg-disabled: var(--button-danger-bg-disabled);
123
+ --color-button-danger-text-disabled: var(--button-danger-text-disabled);
124
+ --color-button-danger-border-disabled: var(--button-danger-border-disabled);
125
+ --color-button-warning-bg-disabled: var(--button-warning-bg-disabled);
126
+ --color-button-warning-text-disabled: var(--button-warning-text-disabled);
127
+ --color-button-warning-border-disabled: var(--button-warning-border-disabled);
128
+ --color-button-gray-bg-disabled: var(--button-gray-bg-disabled);
129
+ --color-button-gray-text-disabled: var(--button-gray-text-disabled);
130
+ --color-button-gray-border-disabled: var(--button-gray-border-disabled);
131
+ --color-table-header-bg: var(--table-header-bg);
132
+ --color-table-header-text: var(--table-header-text);
133
+ --color-table-header-border: var(--table-header-border);
134
+ --color-table-body-bg: var(--table-body-bg);
135
+ --color-table-body-bgEven: var(--table-body-bgEven);
136
+ --color-table-body-text: var(--table-body-text);
137
+ --color-table-body-border: var(--table-body-border);
138
+ --color-pagination-bg-hover: var(--pagination-bg-hover);
139
+ --color-callout-note-bg: var(--callout-note-bg);
140
+ --color-callout-note-text: var(--callout-note-text);
141
+ --color-callout-tip-bg: var(--callout-tip-bg);
142
+ --color-callout-tip-text: var(--callout-tip-text);
143
+ --color-callout-danger-bg: var(--callout-danger-bg);
144
+ --color-callout-danger-text: var(--callout-danger-text);
145
+ --color-callout-warning-bg: var(--callout-warning-bg);
146
+ --color-callout-warning-text: var(--callout-warning-text);
147
+ }
148
+
149
+ .white {
150
+ --bg-card: var(--color-white);
151
+ --bg-wrapper: var(--color-gray-200);
152
+ --bg-hover: var(--color-gray-200);
153
+ --bg-input-standard: var(--color-gray-100);
154
+ --bg-input-hover: var(--color-gray-200);
155
+ --bg-input-disabled: var(--color-gray-500);
156
+ --text-title: var(--color-dark-100);
157
+ --text-body: var(--color-dark-400);
158
+ --text-sub: var(--color-gray-950);
159
+ --text-standard: var(--color-dark-300);
160
+ --text-active: var(--color-gray-100);
161
+ --text-placeholder: var(--color-gray-950);
162
+ --text-disabled: var(--color-gray-950);
163
+ --border-standard: var(--color-gray-500);
164
+ --border-active: var(--color-dark-400);
165
+ --button-primary-bg-disabled: var(--color-blue-200);
166
+ --button-primary-text-disabled: var(--color-blue-400);
167
+ --button-primary-border-disabled: var(--color-blue-200);
168
+ --button-secondary-bg-disabled: var(--color-indigo-200);
169
+ --button-secondary-text-disabled: var(--color-indigo-400);
170
+ --button-secondary-border-disabled: var(--color-indigo-200);
171
+ --button-success-bg-disabled: var(--color-green-200);
172
+ --button-success-text-disabled: var(--color-green-400);
173
+ --button-success-border-disabled: var(--color-green-200);
174
+ --button-danger-bg-disabled: var(--color-red-200);
175
+ --button-danger-text-disabled: var(--color-red-400);
176
+ --button-danger-border-disabled: var(--color-red-200);
177
+ --button-warning-bg-disabled: var(--color-yellow-200);
178
+ --button-warning-text-disabled: var(--color-yellow-400);
179
+ --button-warning-border-disabled: var(--color-yellow-200);
180
+ --button-gray-bg-disabled: var(--color-gray-200);
181
+ --button-gray-text-disabled: var(--color-gray-500);
182
+ --button-gray-border-disabled: var(--color-gray-300);
183
+ --table-header-bg: var(--color-gray-400);
184
+ --table-header-text: var(--color-dark-500);
185
+ --table-header-border: var(--color-gray-500);
186
+ --table-body-bg: var(--color-white);
187
+ --table-body-bgEven: var(--color-gray-100);
188
+ --table-body-text: var(--color-dark-300);
189
+ --table-body-border: var(--color-gray-300);
190
+ --pagination-bg-hover: var(--color-gray-100);
191
+ --callout-note-bg: var(--color-gray-100);
192
+ --callout-note-text: var(--color-gray-900);
193
+ --callout-tip-bg: var(--color-green-100);
194
+ --callout-tip-text: var(--color-green-900);
195
+ --callout-danger-bg: var(--color-red-100);
196
+ --callout-danger-text: var(--color-red-900);
197
+ --callout-warning-bg: var(--color-yellow-100);
198
+ --callout-warning-text: var(--color-yellow-900);
199
+ }
200
+
201
+ .dark {
202
+ --bg-card: var(--color-dark-200);
203
+ --bg-wrapper: var(--color-black);
204
+ --bg-hover: var(--color-dark-400);
205
+ --bg-input-standard: var(--color-dark-300);
206
+ --bg-input-hover: var(--color-dark-400);
207
+ --bg-input-disabled: var(--color-dark-200);
208
+ --text-title: var(--color-white);
209
+ --text-body: var(--color-gray-200);
210
+ --text-sub: var(--color-gray-600);
211
+ --text-standard: var(--color-white);
212
+ --text-active: var(--color-white);
213
+ --text-placeholder: var(--color-gray-950);
214
+ --text-disabled: var(--color-dark-400);
215
+ --border-standard: var(--color-dark-400);
216
+ --border-active: var(--color-gray-500);
217
+ --button-primary-bg-disabled: var(--color-blue-900);
218
+ --button-primary-text-disabled: var(--color-blue-700);
219
+ --button-primary-border-disabled: var(--color-blue-800);
220
+ --button-secondary-bg-disabled: var(--color-indigo-900);
221
+ --button-secondary-text-disabled: var(--color-indigo-700);
222
+ --button-secondary-border-disabled: var(--color-indigo-800);
223
+ --button-success-bg-disabled: var(--color-green-900);
224
+ --button-success-text-disabled: var(--color-green-700);
225
+ --button-success-border-disabled: var(--color-green-800);
226
+ --button-danger-bg-disabled: var(--color-red-900);
227
+ --button-danger-text-disabled: var(--color-red-700);
228
+ --button-danger-border-disabled: var(--color-red-800);
229
+ --button-warning-bg-disabled: var(--color-yellow-900);
230
+ --button-warning-text-disabled: var(--color-yellow-700);
231
+ --button-warning-border-disabled: var(--color-yellow-800);
232
+ --button-gray-bg-disabled: var(--color-gray-800);
233
+ --button-gray-text-disabled: var(--color-gray-600);
234
+ --button-gray-border-disabled: var(--color-gray-700);
235
+ --table-header-bg: var(--color-dark-400);
236
+ --table-header-text: var(--color-gray-200);
237
+ --table-header-border: var(--color-dark-600);
238
+ --table-body-bg: var(--color-dark-200);
239
+ --table-body-bgEven: var(--color-dark-300);
240
+ --table-body-text: var(--color-gray-200);
241
+ --table-body-border: var(--color-dark-400);
242
+ --pagination-bg-hover: var(--color-dark-300);
243
+ --callout-note-bg: var(--color-dark-300);
244
+ --callout-note-text: var(--color-white);
245
+ --callout-tip-bg: var(--color-green-950);
246
+ --callout-tip-text: var(--color-green-200);
247
+ --callout-danger-bg: var(--color-red-950);
248
+ --callout-danger-text: var(--color-red-200);
249
+ --callout-warning-bg: var(--color-yellow-950);
250
+ --callout-warning-text: var(--color-yellow-200);
251
251
  }
@@ -1,6 +1,6 @@
1
- export const themes: Record<string, string[]> = {
2
- "global": [
3
- "white",
4
- "dark"
5
- ]
1
+ export const themes: Record<string, string[]> = {
2
+ "global": [
3
+ "white",
4
+ "dark"
5
+ ]
6
6
  };
package/cli/add.js CHANGED
@@ -20,7 +20,7 @@ const components = [
20
20
  "Collapse",
21
21
  "CodeBlock",
22
22
  "Navigation",
23
- "Sidemenu",
23
+ "Sidebar",
24
24
  "Input",
25
25
  "Theme",
26
26
  "Tab",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "atomsystem",
3
- "version": "0.1.39",
3
+ "version": "0.1.40",
4
4
  "type": "module",
5
5
  "homepage": "https://system.atomground.com",
6
6
  "bin": {
@@ -28,9 +28,13 @@
28
28
  "style-dictionary": "^4.2.0"
29
29
  },
30
30
  "dependencies": {
31
+ "@emotion/react": "^11.14.0",
32
+ "@emotion/styled": "^11.14.1",
31
33
  "@gsap/react": "^2.1.2",
32
34
  "@mdx-js/loader": "^3.1.0",
33
35
  "@mdx-js/react": "^3.1.0",
36
+ "@mui/icons-material": "^7.3.9",
37
+ "@mui/material": "^7.3.9",
34
38
  "@next/mdx": "^15.4.6",
35
39
  "@next/third-parties": "^15.0.3",
36
40
  "@tailwindcss/postcss": "^4.0.17",
@@ -1,55 +0,0 @@
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
- }