@sonhoseong/mfa-lib 1.3.5 → 1.3.7

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';
@@ -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,22 @@
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
+ logo?: React.ReactNode;
19
+ }
20
+ export declare const Lnb: React.FC<LnbProps>;
21
+ export default Lnb;
22
+ //# 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;IACjB,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACxB;AAED,eAAO,MAAM,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC,QAAQ,CAkHlC,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, logo }) => {
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: [(logo || appName) && (_jsx("div", { className: "app-lnb-logo", onClick: () => handleNavigate('/'), children: logo || appName })), title && !collapsed && _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 ${collapsed ? 'collapsed' : ''}`, children: [_jsxs("div", { className: "app-lnb-user-section", children: [_jsx("div", { className: "app-lnb-avatar", children: user?.name?.charAt(0) || user?.email?.charAt(0) || '?' }), !collapsed && user && (_jsx("span", { className: "app-lnb-user-name", children: user.name || user.email }))] }), _jsx("button", { className: "app-lnb-logout-icon", onClick: handleLogout, 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" })] }) })] }))] }));
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.5",
3
+ "version": "1.3.7",
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
+ }