@sonhoseong/mfa-lib 1.3.4 → 1.3.6

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.
@@ -4,6 +4,7 @@ export * from './toast';
4
4
  export * from './error';
5
5
  export * from './modal';
6
6
  export * from './navigation';
7
+ export * from './layout';
7
8
  export * from './logo';
8
9
  export * from './page';
9
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AACA,cAAc,UAAU,CAAC;AAGzB,cAAc,WAAW,CAAC;AAG1B,cAAc,SAAS,CAAC;AAGxB,cAAc,SAAS,CAAC;AAGxB,cAAc,SAAS,CAAC;AAGxB,cAAc,cAAc,CAAC;AAG7B,cAAc,QAAQ,CAAC;AAGvB,cAAc,QAAQ,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AACA,cAAc,UAAU,CAAC;AAGzB,cAAc,WAAW,CAAC;AAG1B,cAAc,SAAS,CAAC;AAGxB,cAAc,SAAS,CAAC;AAGxB,cAAc,SAAS,CAAC;AAGxB,cAAc,cAAc,CAAC;AAG7B,cAAc,UAAU,CAAC;AAGzB,cAAc,QAAQ,CAAC;AAGvB,cAAc,QAAQ,CAAC"}
@@ -10,6 +10,8 @@ export * from './error';
10
10
  export * from './modal';
11
11
  // Navigation
12
12
  export * from './navigation';
13
+ // Layout
14
+ export * from './layout';
13
15
  // Logo
14
16
  export * from './logo';
15
17
  // Page (LoginPage 등)
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Container Component - KOMCA 패턴
3
+ *
4
+ * 앱 전체를 감싸는 레이아웃 컨테이너
5
+ */
6
+ import React from 'react';
7
+ export interface ContainerProps {
8
+ children: React.ReactNode;
9
+ className?: string;
10
+ }
11
+ export declare const Container: React.FC<ContainerProps>;
12
+ export default Container;
13
+ //# sourceMappingURL=Container.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Container.d.ts","sourceRoot":"","sources":["../../../src/components/layout/Container.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,CAM9C,CAAC;AAEF,eAAe,SAAS,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ export const Container = ({ children, className = '' }) => {
3
+ return (_jsx("div", { className: `app-container ${className}`, children: children }));
4
+ };
5
+ export default Container;
@@ -0,0 +1,2 @@
1
+ export * from './Container';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/layout/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC"}
@@ -0,0 +1 @@
1
+ export * from './Container';
@@ -1 +1 @@
1
- {"version":3,"file":"AppSidebar.d.ts","sourceRoot":"","sources":["../../../src/components/navigation/AppSidebar.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAgC,MAAM,OAAO,CAAC;AAErD,MAAM,WAAW,eAAe;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,QAAQ,CAAC,EAAE,eAAe,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,eAAe;IAC5B,WAAW;IACX,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa;IACb,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,aAAa;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa;IACb,SAAS,CAAC,EAAE,eAAe,EAAE,CAAC;IAC9B,eAAe;IACf,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,gBAAgB;IAChB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,YAAY;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa;IACb,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,oBAAoB;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,kBAAkB;IAClB,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;CACpD;AAED,wBAAgB,UAAU,CAAC,EACvB,OAAe,EACf,eAAuB,EACvB,QAAQ,EACR,SAAS,EACT,SAAc,EACd,QAAQ,EACR,UAAU,EACV,WAAiB,EACjB,IAAI,EACJ,SAAS,EAAE,mBAAmB,EAC9B,iBAAiB,GACpB,EAAE,eAAe,2CAmLjB;AAED,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"AppSidebar.d.ts","sourceRoot":"","sources":["../../../src/components/navigation/AppSidebar.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAgC,MAAM,OAAO,CAAC;AAErD,MAAM,WAAW,eAAe;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,QAAQ,CAAC,EAAE,eAAe,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,eAAe;IAC5B,WAAW;IACX,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa;IACb,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,aAAa;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa;IACb,SAAS,CAAC,EAAE,eAAe,EAAE,CAAC;IAC9B,eAAe;IACf,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,gBAAgB;IAChB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,YAAY;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa;IACb,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,oBAAoB;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,kBAAkB;IAClB,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;CACpD;AAED,wBAAgB,UAAU,CAAC,EACvB,OAAe,EACf,eAAuB,EACvB,QAAQ,EACR,SAAS,EACT,SAAc,EACd,QAAQ,EACR,UAAU,EACV,WAAiB,EACjB,IAAI,EACJ,SAAS,EAAE,mBAAmB,EAC9B,iBAAiB,GACpB,EAAE,eAAe,2CAwLjB;AAED,eAAe,UAAU,CAAC"}
@@ -44,9 +44,9 @@ export function AppSidebar({ appName = 'MFA', isAuthenticated = false, userName,
44
44
  }
45
45
  }, title: collapsed ? item.title : undefined, children: [item.icon && _jsx("span", { className: "sidebar-menu-icon", children: item.icon }), !collapsed && _jsx("span", { className: "sidebar-menu-title", children: item.title }), !collapsed && hasChildren && (_jsx("svg", { className: `sidebar-menu-arrow ${isExpanded ? 'expanded' : ''}`, width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: _jsx("path", { d: "m9 18 6-6-6-6" }) }))] }), !collapsed && hasChildren && isExpanded && (_jsx("ul", { className: "sidebar-submenu", children: item.children.map(child => renderMenuItem(child, depth + 1)) }))] }, item.id));
46
46
  };
47
- return (_jsxs("aside", { className: `app-sidebar ${collapsed ? 'collapsed' : ''}`, children: [_jsxs("div", { className: "sidebar-header", children: [_jsxs("button", { className: "sidebar-logo", onClick: () => handleNavigate('/'), children: [logo || (_jsxs("svg", { viewBox: "0 0 48 48", fill: "none", width: "32", height: "32", children: [_jsx("rect", { x: "20", y: "2", width: "8", height: "16", rx: "4", fill: "#0EA5E9" }), _jsx("rect", { x: "6", y: "16", width: "36", height: "6", rx: "3", fill: "#0EA5E9" }), _jsx("ellipse", { cx: "24", cy: "36", rx: "18", ry: "12", fill: "#0EA5E9" }), _jsx("ellipse", { cx: "17", cy: "36", rx: "4", ry: "6", fill: "#FFFFFF" }), _jsx("ellipse", { cx: "31", cy: "36", rx: "4", ry: "6", fill: "#FFFFFF" })] })), !collapsed && _jsx("span", { className: "sidebar-app-name", children: appName })] }), _jsx("button", { className: "sidebar-toggle-inner", onClick: toggleCollapsed, title: collapsed ? '메뉴 열기' : '메뉴 닫기', children: _jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: collapsed ? (_jsx("path", { d: "M3 12h18M3 6h18M3 18h18" })) : (_jsx("path", { d: "M18 6L6 18M6 6l12 12" })) }) })] }), _jsx("nav", { className: "sidebar-nav", children: menuItems.length > 0 ? (_jsx("ul", { className: "sidebar-menu", children: menuItems.map(item => renderMenuItem(item)) })) : (_jsx("ul", { className: "sidebar-menu", children: _jsx("li", { className: "sidebar-menu-item", children: _jsxs("button", { className: `sidebar-menu-btn ${currentPath === '/' ? 'active' : ''}`, onClick: () => handleNavigate('/'), title: collapsed ? '홈' : undefined, children: [_jsx("span", { className: "sidebar-menu-icon", children: _jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [_jsx("path", { d: "m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" }), _jsx("polyline", { points: "9 22 9 12 15 12 15 22" })] }) }), !collapsed && _jsx("span", { className: "sidebar-menu-title", children: "\uD648" })] }) }) })) }), _jsx("div", { className: `sidebar-footer ${collapsed ? 'collapsed' : ''}`, children: isAuthenticated ? (collapsed ? (
48
- // 접힌 상태: 아바타만 표시 (클릭하면 펼침)
49
- _jsx("button", { className: "sidebar-user-avatar-btn", onClick: toggleCollapsed, title: `${userName || '사용자'} - 클릭하여 메뉴 열기`, children: userName?.charAt(0).toUpperCase() || 'U' })) : (
47
+ return (_jsxs("aside", { className: `app-sidebar ${collapsed ? 'collapsed' : ''}`, children: [_jsx("button", { className: "sidebar-toggle-btn", onClick: toggleCollapsed, title: collapsed ? '메뉴 열기' : '메뉴 닫기', children: _jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: collapsed ? (_jsx("path", { d: "M3 12h18M3 6h18M3 18h18" })) : (_jsx("path", { d: "M18 6L6 18M6 6l12 12" })) }) }), _jsx("div", { className: "sidebar-header", children: _jsxs("button", { className: "sidebar-logo", onClick: () => handleNavigate('/'), children: [logo || (_jsxs("svg", { viewBox: "0 0 48 48", fill: "none", width: "32", height: "32", children: [_jsx("rect", { x: "20", y: "2", width: "8", height: "16", rx: "4", fill: "#0EA5E9" }), _jsx("rect", { x: "6", y: "16", width: "36", height: "6", rx: "3", fill: "#0EA5E9" }), _jsx("ellipse", { cx: "24", cy: "36", rx: "18", ry: "12", fill: "#0EA5E9" }), _jsx("ellipse", { cx: "17", cy: "36", rx: "4", ry: "6", fill: "#FFFFFF" }), _jsx("ellipse", { cx: "31", cy: "36", rx: "4", ry: "6", fill: "#FFFFFF" })] })), !collapsed && _jsx("span", { className: "sidebar-app-name", children: appName })] }) }), _jsx("nav", { className: "sidebar-nav", children: menuItems.length > 0 ? (_jsx("ul", { className: "sidebar-menu", children: menuItems.map(item => renderMenuItem(item)) })) : (_jsx("ul", { className: "sidebar-menu", children: _jsx("li", { className: "sidebar-menu-item", children: _jsxs("button", { className: `sidebar-menu-btn ${currentPath === '/' ? 'active' : ''}`, onClick: () => handleNavigate('/'), title: collapsed ? '홈' : undefined, children: [_jsx("span", { className: "sidebar-menu-icon", children: _jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [_jsx("path", { d: "m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" }), _jsx("polyline", { points: "9 22 9 12 15 12 15 22" })] }) }), !collapsed && _jsx("span", { className: "sidebar-menu-title", children: "\uD648" })] }) }) })) }), _jsx("div", { className: `sidebar-footer ${collapsed ? 'collapsed' : ''}`, children: isAuthenticated ? (collapsed ? (
48
+ // 접힌 상태: 로그아웃 버튼만 표시
49
+ _jsx("button", { className: "sidebar-logout-btn-collapsed", onClick: onLogout, title: "\uB85C\uADF8\uC544\uC6C3", children: _jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [_jsx("path", { d: "M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" }), _jsx("polyline", { points: "16 17 21 12 16 7" }), _jsx("line", { x1: "21", y1: "12", x2: "9", y2: "12" })] }) })) : (
50
50
  // 펼친 상태: 전체 유저 정보 표시
51
51
  _jsxs("div", { className: "sidebar-user", children: [_jsx("div", { className: "sidebar-user-avatar", children: userName?.charAt(0).toUpperCase() || 'U' }), _jsxs("div", { className: "sidebar-user-info", children: [_jsx("span", { className: "sidebar-user-name", children: userName || '사용자' }), userEmail && _jsx("span", { className: "sidebar-user-email", children: userEmail })] }), _jsx("button", { className: "sidebar-logout-btn", onClick: onLogout, title: "\uB85C\uADF8\uC544\uC6C3", children: _jsxs("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [_jsx("path", { d: "M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" }), _jsx("polyline", { points: "16 17 21 12 16 7" }), _jsx("line", { x1: "21", y1: "12", x2: "9", y2: "12" })] }) })] }))) : (_jsxs("button", { className: `sidebar-login-btn ${collapsed ? 'collapsed' : ''}`, onClick: () => collapsed ? toggleCollapsed() : handleNavigate('/login'), title: collapsed ? '로그인' : undefined, children: [_jsxs("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [_jsx("path", { d: "M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4" }), _jsx("polyline", { points: "10 17 15 12 10 7" }), _jsx("line", { x1: "15", y1: "12", x2: "3", y2: "12" })] }), !collapsed && '로그인'] })) })] }));
52
52
  }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Header Component - KOMCA 패턴
3
+ *
4
+ * gnbItems만 받고 내부에서 navigate, logout 처리
5
+ */
6
+ import React from 'react';
7
+ export interface GnbItem {
8
+ id: string;
9
+ title: string;
10
+ path: string;
11
+ }
12
+ export interface HeaderProps {
13
+ gnbItems: GnbItem[];
14
+ appName?: string;
15
+ logo?: React.ReactNode;
16
+ }
17
+ export declare const Header: React.FC<HeaderProps>;
18
+ export default Header;
19
+ //# sourceMappingURL=Header.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Header.d.ts","sourceRoot":"","sources":["../../../src/components/navigation/Header.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,MAAM,OAAO,CAAC;AAK1B,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACxB;AAED,eAAO,MAAM,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CA4CxC,CAAC;AAEF,eAAe,MAAM,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useNavigate } from 'react-router-dom';
3
+ import { useSelector, useDispatch } from 'react-redux';
4
+ import { logout } from '../../store/app-store';
5
+ export const Header = ({ gnbItems, appName = '앱', logo }) => {
6
+ const navigate = useNavigate();
7
+ const dispatch = useDispatch();
8
+ const user = useSelector((state) => state.app?.user);
9
+ const handleNavigate = (path) => {
10
+ navigate(path);
11
+ };
12
+ const handleLogout = () => {
13
+ dispatch(logout());
14
+ navigate('/');
15
+ };
16
+ return (_jsx("header", { className: "app-header", children: _jsxs("div", { className: "app-header-inner", children: [_jsx("div", { className: "app-header-logo", onClick: () => handleNavigate('/'), children: logo || appName }), _jsx("nav", { className: "app-header-nav", children: gnbItems.map((item) => (_jsx("button", { className: "app-header-nav-item", onClick: () => handleNavigate(item.path), children: item.title }, item.id))) }), _jsx("div", { className: "app-header-user", children: user && (_jsxs(_Fragment, { children: [_jsx("span", { className: "app-header-user-name", children: user.name || user.email }), _jsx("button", { className: "app-header-logout", onClick: handleLogout, children: "\uB85C\uADF8\uC544\uC6C3" })] })) })] }) }));
17
+ };
18
+ export default Header;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Lnb (Left Navigation Bar) Component - KOMCA 패턴
3
+ *
4
+ * lnbItems만 받고 내부에서 navigate 처리
5
+ */
6
+ import React from 'react';
7
+ export interface LnbMenuItem {
8
+ id: string;
9
+ title: string;
10
+ path?: string;
11
+ icon?: React.ReactNode;
12
+ children?: Omit<LnbMenuItem, 'icon' | 'children'>[];
13
+ }
14
+ export interface LnbProps {
15
+ lnbItems: LnbMenuItem[];
16
+ title?: string;
17
+ appName?: string;
18
+ }
19
+ export declare const Lnb: React.FC<LnbProps>;
20
+ export default Lnb;
21
+ //# sourceMappingURL=Lnb.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Lnb.d.ts","sourceRoot":"","sources":["../../../src/components/navigation/Lnb.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAmB,MAAM,OAAO,CAAC;AAKxC,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,QAAQ,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,UAAU,CAAC,EAAE,CAAC;CACrD;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC,QAAQ,CAyGlC,CAAC;AAEF,eAAe,GAAG,CAAC"}
@@ -0,0 +1,38 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ /**
3
+ * Lnb (Left Navigation Bar) Component - KOMCA 패턴
4
+ *
5
+ * lnbItems만 받고 내부에서 navigate 처리
6
+ */
7
+ import { useState } from 'react';
8
+ import { useNavigate, useLocation } from 'react-router-dom';
9
+ import { useSelector, useDispatch } from 'react-redux';
10
+ import { logout } from '../../store/app-store';
11
+ export const Lnb = ({ lnbItems, title, appName = '앱' }) => {
12
+ const navigate = useNavigate();
13
+ const location = useLocation();
14
+ const dispatch = useDispatch();
15
+ const [expandedItems, setExpandedItems] = useState([]);
16
+ const [collapsed, setCollapsed] = useState(false);
17
+ const user = useSelector((state) => state.app?.user);
18
+ const isAuthenticated = useSelector((state) => !!state.app?.accessToken);
19
+ const handleNavigate = (path) => {
20
+ navigate(path);
21
+ };
22
+ const handleLogout = () => {
23
+ dispatch(logout());
24
+ navigate('/');
25
+ };
26
+ const toggleExpand = (itemId) => {
27
+ setExpandedItems((prev) => prev.includes(itemId)
28
+ ? prev.filter((id) => id !== itemId)
29
+ : [...prev, itemId]);
30
+ };
31
+ const isActive = (path) => {
32
+ if (!path)
33
+ return false;
34
+ return location.pathname === path || location.pathname.startsWith(path + '/');
35
+ };
36
+ return (_jsxs("aside", { className: `app-lnb ${collapsed ? 'collapsed' : ''}`, children: [_jsxs("div", { className: "app-lnb-header", children: [_jsx("div", { className: "app-lnb-logo", onClick: () => handleNavigate('/'), children: appName }), title && _jsx("div", { className: "app-lnb-title", children: title }), _jsx("button", { className: "app-lnb-toggle", onClick: () => setCollapsed(!collapsed), children: collapsed ? '>' : '<' })] }), _jsx("nav", { className: "app-lnb-nav", children: lnbItems.map((item) => (_jsx("div", { className: "app-lnb-item", children: item.children ? (_jsxs(_Fragment, { children: [_jsxs("button", { className: `app-lnb-item-btn ${expandedItems.includes(item.id) ? 'expanded' : ''}`, onClick: () => toggleExpand(item.id), children: [item.icon && _jsx("span", { className: "app-lnb-icon", children: item.icon }), !collapsed && _jsx("span", { className: "app-lnb-text", children: item.title }), !collapsed && (_jsx("span", { className: "app-lnb-arrow", children: expandedItems.includes(item.id) ? '▼' : '▶' }))] }), expandedItems.includes(item.id) && !collapsed && (_jsx("div", { className: "app-lnb-subitems", children: item.children.map((child) => (_jsx("button", { className: `app-lnb-subitem ${isActive(child.path) ? 'active' : ''}`, onClick: () => child.path && handleNavigate(child.path), children: child.title }, child.id))) }))] })) : (_jsxs("button", { className: `app-lnb-item-btn ${isActive(item.path) ? 'active' : ''}`, onClick: () => item.path && handleNavigate(item.path), children: [item.icon && _jsx("span", { className: "app-lnb-icon", children: item.icon }), !collapsed && _jsx("span", { className: "app-lnb-text", children: item.title })] })) }, item.id))) }), isAuthenticated && (_jsxs("div", { className: "app-lnb-footer", children: [user && !collapsed && (_jsx("div", { className: "app-lnb-user", children: _jsx("span", { className: "app-lnb-user-name", children: user.name || user.email }) })), _jsx("button", { className: "app-lnb-logout", onClick: handleLogout, children: collapsed ? '⏻' : '로그아웃' })] }))] }));
37
+ };
38
+ export default Lnb;
@@ -1,4 +1,6 @@
1
1
  export * from './StickyNav';
2
2
  export * from './AppNavbar';
3
3
  export * from './AppSidebar';
4
+ export * from './Header';
5
+ export * from './Lnb';
4
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/navigation/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/navigation/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,OAAO,CAAC"}
@@ -1,3 +1,5 @@
1
1
  export * from './StickyNav';
2
2
  export * from './AppNavbar';
3
3
  export * from './AppSidebar';
4
+ export * from './Header';
5
+ export * from './Lnb';
package/package.json CHANGED
@@ -1,10 +1,13 @@
1
1
  {
2
2
  "name": "@sonhoseong/mfa-lib",
3
- "version": "1.3.4",
3
+ "version": "1.3.6",
4
4
  "description": "MFA 공통 라이브러리 - KOMCA 패턴",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
- "files": ["dist", "README.md"],
7
+ "files": [
8
+ "dist",
9
+ "README.md"
10
+ ],
8
11
  "scripts": {
9
12
  "build": "tsc",
10
13
  "watch": "tsc --watch"
@@ -24,4 +27,4 @@
24
27
  "react-redux": "^9.0.0",
25
28
  "react-router-dom": "^7.0.0"
26
29
  }
27
- }
30
+ }