@sonhoseong/mfa-lib 1.3.8 → 1.3.10

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.
Files changed (160) hide show
  1. package/dist/components/button/ScrollTopButton.js +5 -3
  2. package/dist/components/error/ErrorBoundary.js +14 -4
  3. package/dist/components/error/NotFound.d.ts +20 -0
  4. package/dist/components/error/NotFound.d.ts.map +1 -0
  5. package/dist/components/error/NotFound.js +84 -0
  6. package/dist/components/error/index.d.ts +2 -0
  7. package/dist/components/error/index.d.ts.map +1 -1
  8. package/dist/components/error/index.js +1 -0
  9. package/dist/components/icons/Icons.d.ts +51 -0
  10. package/dist/components/icons/Icons.d.ts.map +1 -0
  11. package/dist/components/icons/Icons.js +100 -0
  12. package/dist/components/icons/index.d.ts +5 -0
  13. package/dist/components/icons/index.d.ts.map +1 -0
  14. package/dist/components/icons/index.js +4 -0
  15. package/dist/components/index.d.ts +3 -0
  16. package/dist/components/index.d.ts.map +1 -1
  17. package/dist/components/index.js +6 -0
  18. package/dist/components/layout/Container.js +7 -2
  19. package/dist/components/loading/DeferredComponent.d.ts +19 -0
  20. package/dist/components/loading/DeferredComponent.d.ts.map +1 -0
  21. package/dist/components/loading/DeferredComponent.js +32 -0
  22. package/dist/components/loading/GlobalLoading.js +14 -3
  23. package/dist/components/loading/index.d.ts +1 -0
  24. package/dist/components/loading/index.d.ts.map +1 -1
  25. package/dist/components/loading/index.js +1 -0
  26. package/dist/components/logo/Logo.js +12 -3
  27. package/dist/components/modal/ModalContainer.js +17 -8
  28. package/dist/components/modal/ModalContext.js +2 -3
  29. package/dist/components/navigation/AppNavbar.js +21 -9
  30. package/dist/components/navigation/AppSidebar.css +58 -3
  31. package/dist/components/navigation/AppSidebar.d.ts +1 -1
  32. package/dist/components/navigation/AppSidebar.d.ts.map +1 -1
  33. package/dist/components/navigation/AppSidebar.js +58 -15
  34. package/dist/components/navigation/Footer.d.ts +15 -0
  35. package/dist/components/navigation/Footer.d.ts.map +1 -0
  36. package/dist/components/navigation/Footer.js +12 -0
  37. package/dist/components/navigation/Header.d.ts.map +1 -1
  38. package/dist/components/navigation/Header.js +17 -4
  39. package/dist/components/navigation/Lnb.d.ts +2 -7
  40. package/dist/components/navigation/Lnb.d.ts.map +1 -1
  41. package/dist/components/navigation/Lnb.js +34 -8
  42. package/dist/components/navigation/StickyNav.js +19 -11
  43. package/dist/components/navigation/index.d.ts +1 -0
  44. package/dist/components/navigation/index.d.ts.map +1 -1
  45. package/dist/components/navigation/index.js +1 -0
  46. package/dist/components/page/LoginPage.d.ts +4 -1
  47. package/dist/components/page/LoginPage.d.ts.map +1 -1
  48. package/dist/components/page/LoginPage.js +146 -21
  49. package/dist/components/remote/RemoteErrorBoundary.d.ts +28 -0
  50. package/dist/components/remote/RemoteErrorBoundary.d.ts.map +1 -0
  51. package/dist/components/remote/RemoteErrorBoundary.js +44 -0
  52. package/dist/components/remote/RemoteErrorFallback.d.ts +16 -0
  53. package/dist/components/remote/RemoteErrorFallback.d.ts.map +1 -0
  54. package/dist/components/remote/RemoteErrorFallback.js +76 -0
  55. package/dist/components/remote/index.d.ts +8 -0
  56. package/dist/components/remote/index.d.ts.map +1 -0
  57. package/dist/components/remote/index.js +5 -0
  58. package/dist/components/router/BrowserRouter.d.ts +13 -0
  59. package/dist/components/router/BrowserRouter.d.ts.map +1 -0
  60. package/dist/components/router/BrowserRouter.js +17 -0
  61. package/dist/components/router/RouteGuard.d.ts +79 -0
  62. package/dist/components/router/RouteGuard.d.ts.map +1 -0
  63. package/dist/components/router/RouteGuard.js +86 -0
  64. package/dist/components/router/index.d.ts +4 -0
  65. package/dist/components/router/index.d.ts.map +1 -0
  66. package/dist/components/router/index.js +2 -0
  67. package/dist/components/toast/ToastContainer.js +17 -6
  68. package/dist/components/toast/ToastContext.js +2 -3
  69. package/dist/hooks/index.d.ts +9 -1
  70. package/dist/hooks/index.d.ts.map +1 -1
  71. package/dist/hooks/index.js +15 -1
  72. package/dist/hooks/use-auth.d.ts +2 -1
  73. package/dist/hooks/use-auth.d.ts.map +1 -1
  74. package/dist/hooks/use-auth.js +19 -18
  75. package/dist/hooks/use-debounce.d.ts +56 -0
  76. package/dist/hooks/use-debounce.d.ts.map +1 -0
  77. package/dist/hooks/use-debounce.js +140 -0
  78. package/dist/hooks/use-effect-once.d.ts +77 -0
  79. package/dist/hooks/use-effect-once.d.ts.map +1 -0
  80. package/dist/hooks/use-effect-once.js +124 -0
  81. package/dist/hooks/use-error-notification.d.ts +1 -1
  82. package/dist/hooks/use-error-notification.js +1 -1
  83. package/dist/hooks/use-global-loading.d.ts +1 -1
  84. package/dist/hooks/use-global-loading.js +1 -1
  85. package/dist/hooks/use-initialize.d.ts +8 -1
  86. package/dist/hooks/use-initialize.d.ts.map +1 -1
  87. package/dist/hooks/use-initialize.js +126 -23
  88. package/dist/hooks/use-modal.d.ts +21 -5
  89. package/dist/hooks/use-modal.d.ts.map +1 -1
  90. package/dist/hooks/use-modal.js +57 -17
  91. package/dist/hooks/use-navigate.d.ts +1 -1
  92. package/dist/hooks/use-navigate.js +1 -1
  93. package/dist/hooks/use-network-status.d.ts +15 -0
  94. package/dist/hooks/use-network-status.d.ts.map +1 -0
  95. package/dist/hooks/use-network-status.js +49 -0
  96. package/dist/hooks/use-permission.d.ts +22 -0
  97. package/dist/hooks/use-permission.d.ts.map +1 -0
  98. package/dist/hooks/use-permission.js +73 -0
  99. package/dist/hooks/use-recent-menu.d.ts +46 -0
  100. package/dist/hooks/use-recent-menu.d.ts.map +1 -0
  101. package/dist/hooks/use-recent-menu.js +169 -0
  102. package/dist/hooks/use-scroll-restoration.d.ts +51 -0
  103. package/dist/hooks/use-scroll-restoration.d.ts.map +1 -0
  104. package/dist/hooks/use-scroll-restoration.js +143 -0
  105. package/dist/hooks/use-supabase-auth.d.ts +49 -0
  106. package/dist/hooks/use-supabase-auth.d.ts.map +1 -0
  107. package/dist/hooks/use-supabase-auth.js +229 -0
  108. package/dist/hooks/use-track-history.d.ts +2 -1
  109. package/dist/hooks/use-track-history.d.ts.map +1 -1
  110. package/dist/hooks/use-track-history.js +14 -2
  111. package/dist/index.d.ts +1 -1
  112. package/dist/index.js +1 -1
  113. package/dist/network/axios-factory.d.ts +30 -1
  114. package/dist/network/axios-factory.d.ts.map +1 -1
  115. package/dist/network/axios-factory.js +192 -24
  116. package/dist/network/index.d.ts +3 -1
  117. package/dist/network/index.d.ts.map +1 -1
  118. package/dist/network/index.js +5 -1
  119. package/dist/network/supabase-client.d.ts +28 -0
  120. package/dist/network/supabase-client.d.ts.map +1 -0
  121. package/dist/network/supabase-client.js +46 -0
  122. package/dist/store/app-store.d.ts +222 -12
  123. package/dist/store/app-store.d.ts.map +1 -1
  124. package/dist/store/app-store.js +46 -29
  125. package/dist/store/index.d.ts +2 -0
  126. package/dist/store/index.d.ts.map +1 -1
  127. package/dist/store/index.js +3 -0
  128. package/dist/store/menu-slice.d.ts +96 -0
  129. package/dist/store/menu-slice.d.ts.map +1 -0
  130. package/dist/store/menu-slice.js +98 -0
  131. package/dist/store/recent-menu-slice.d.ts +209 -0
  132. package/dist/store/recent-menu-slice.d.ts.map +1 -0
  133. package/dist/store/recent-menu-slice.js +110 -0
  134. package/dist/store/store-access.d.ts +1 -1
  135. package/dist/store/store-access.js +1 -1
  136. package/dist/types/index.d.ts +74 -17
  137. package/dist/types/index.d.ts.map +1 -1
  138. package/dist/types/service.d.ts +1 -1
  139. package/dist/types/service.js +1 -1
  140. package/dist/utils/classnames.d.ts +65 -0
  141. package/dist/utils/classnames.d.ts.map +1 -0
  142. package/dist/utils/classnames.js +98 -0
  143. package/dist/utils/formatter.d.ts +78 -0
  144. package/dist/utils/formatter.d.ts.map +1 -0
  145. package/dist/utils/formatter.js +216 -0
  146. package/dist/utils/index.d.ts +5 -0
  147. package/dist/utils/index.d.ts.map +1 -1
  148. package/dist/utils/index.js +5 -0
  149. package/dist/utils/permission.d.ts +33 -0
  150. package/dist/utils/permission.d.ts.map +1 -0
  151. package/dist/utils/permission.js +132 -0
  152. package/dist/utils/query-string.d.ts +67 -0
  153. package/dist/utils/query-string.d.ts.map +1 -0
  154. package/dist/utils/query-string.js +136 -0
  155. package/dist/utils/storage.d.ts +1 -1
  156. package/dist/utils/storage.js +1 -1
  157. package/dist/utils/validation.d.ts +98 -0
  158. package/dist/utils/validation.d.ts.map +1 -0
  159. package/dist/utils/validation.js +260 -0
  160. package/package.json +5 -3
@@ -1,5 +1,4 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useState, useEffect, useCallback } from 'react';
1
+ import React, { useState, useEffect, useCallback } from 'react';
3
2
  const ScrollTopButton = ({ className = '', variant = 'primary', size = 'md', threshold = 100, title = '맨 위로', }) => {
4
3
  const [isVisible, setIsVisible] = useState(false);
5
4
  useEffect(() => {
@@ -23,6 +22,9 @@ const ScrollTopButton = ({ className = '', variant = 'primary', size = 'md', thr
23
22
  secondary: 'scroll-top-btn--secondary',
24
23
  ghost: 'scroll-top-btn--ghost',
25
24
  };
26
- return (_jsx("button", { type: "button", className: `scroll-top-btn ${sizeClasses[size]} ${variantClasses[variant]} ${isVisible ? 'visible' : ''} ${className}`, onClick: scrollToTop, title: title, "aria-label": title, children: _jsxs("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "3", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("polyline", { points: "17 11 12 6 7 11" }), _jsx("polyline", { points: "17 18 12 13 7 18" })] }) }));
25
+ return (React.createElement("button", { type: "button", className: `scroll-top-btn ${sizeClasses[size]} ${variantClasses[variant]} ${isVisible ? 'visible' : ''} ${className}`, onClick: scrollToTop, title: title, "aria-label": title },
26
+ React.createElement("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "3", strokeLinecap: "round", strokeLinejoin: "round" },
27
+ React.createElement("polyline", { points: "17 11 12 6 7 11" }),
28
+ React.createElement("polyline", { points: "17 18 12 13 7 18" }))));
27
29
  };
28
30
  export { ScrollTopButton };
@@ -1,9 +1,8 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
1
  /**
3
2
  * ErrorBoundary - KOMCA 패턴
4
3
  * 에러 발생 시 Fallback UI 표시
5
4
  */
6
- import { Component } from 'react';
5
+ import React, { Component } from 'react';
7
6
  class ErrorBoundary extends Component {
8
7
  constructor(props) {
9
8
  super(props);
@@ -29,7 +28,18 @@ class ErrorBoundary extends Component {
29
28
  return this.props.fallback;
30
29
  }
31
30
  // 기본 fallback UI
32
- return (_jsxs("div", { className: "error-boundary-fallback", children: [_jsxs("div", { className: "error-boundary-content", children: [_jsx("div", { className: "error-boundary-icon", children: "\u26A0\uFE0F" }), _jsx("h2", { className: "error-boundary-title", children: "\uBB38\uC81C\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4" }), _jsx("p", { className: "error-boundary-message", children: this.state.error.message || '알 수 없는 오류가 발생했습니다.' }), _jsxs("div", { className: "error-boundary-actions", children: [_jsx("button", { className: "error-boundary-button primary", onClick: this.resetError, children: "\uB2E4\uC2DC \uC2DC\uB3C4" }), _jsx("button", { className: "error-boundary-button secondary", onClick: () => window.location.reload(), children: "\uC0C8\uB85C\uACE0\uCE68" })] }), process.env.NODE_ENV === 'development' && (_jsxs("details", { className: "error-boundary-details", children: [_jsx("summary", { children: "\uC0C1\uC138 \uC815\uBCF4" }), _jsx("pre", { children: this.state.error.stack })] }))] }), _jsx("style", { children: `
31
+ return (React.createElement("div", { className: "error-boundary-fallback" },
32
+ React.createElement("div", { className: "error-boundary-content" },
33
+ React.createElement("div", { className: "error-boundary-icon" }, "\u26A0\uFE0F"),
34
+ React.createElement("h2", { className: "error-boundary-title" }, "\uBB38\uC81C\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4"),
35
+ React.createElement("p", { className: "error-boundary-message" }, this.state.error.message || '알 수 없는 오류가 발생했습니다.'),
36
+ React.createElement("div", { className: "error-boundary-actions" },
37
+ React.createElement("button", { className: "error-boundary-button primary", onClick: this.resetError }, "\uB2E4\uC2DC \uC2DC\uB3C4"),
38
+ React.createElement("button", { className: "error-boundary-button secondary", onClick: () => window.location.reload() }, "\uC0C8\uB85C\uACE0\uCE68")),
39
+ process.env.NODE_ENV === 'development' && (React.createElement("details", { className: "error-boundary-details" },
40
+ React.createElement("summary", null, "\uC0C1\uC138 \uC815\uBCF4"),
41
+ React.createElement("pre", null, this.state.error.stack)))),
42
+ React.createElement("style", null, `
33
43
  .error-boundary-fallback {
34
44
  display: flex;
35
45
  align-items: center;
@@ -122,7 +132,7 @@ class ErrorBoundary extends Component {
122
132
  overflow-x: auto;
123
133
  color: #ef4444;
124
134
  }
125
- ` })] }));
135
+ `)));
126
136
  }
127
137
  return this.props.children;
128
138
  }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * 404 NotFound 컴포넌트
3
+ * 존재하지 않는 페이지 접근 시 표시
4
+ */
5
+ import React from 'react';
6
+ export interface NotFoundProps {
7
+ /** 커스텀 타이틀 */
8
+ title?: string;
9
+ /** 커스텀 메시지 */
10
+ message?: string;
11
+ /** 홈 경로 */
12
+ homePath?: string;
13
+ /** 뒤로가기 버튼 표시 여부 */
14
+ showBackButton?: boolean;
15
+ /** 홈 버튼 표시 여부 */
16
+ showHomeButton?: boolean;
17
+ }
18
+ export declare const NotFound: React.FC<NotFoundProps>;
19
+ export default NotFound;
20
+ //# sourceMappingURL=NotFound.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NotFound.d.ts","sourceRoot":"","sources":["../../../src/components/error/NotFound.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,WAAW,aAAa;IAC5B,cAAc;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW;IACX,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oBAAoB;IACpB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,iBAAiB;IACjB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CAwD5C,CAAC;AAuDF,eAAe,QAAQ,CAAC"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * 404 NotFound 컴포넌트
3
+ * 존재하지 않는 페이지 접근 시 표시
4
+ */
5
+ import React from 'react';
6
+ import { useNavigate } from 'react-router-dom';
7
+ export const NotFound = ({ title = '페이지를 찾을 수 없습니다', message = '요청하신 페이지가 존재하지 않거나 이동되었을 수 있습니다.', homePath = '/', showBackButton = true, showHomeButton = true, }) => {
8
+ const navigate = useNavigate();
9
+ const handleGoBack = () => {
10
+ navigate(-1);
11
+ };
12
+ const handleGoHome = () => {
13
+ navigate(homePath);
14
+ };
15
+ return (React.createElement("div", { style: styles.container },
16
+ React.createElement("div", { style: styles.content },
17
+ React.createElement("div", { style: styles.errorCode }, "404"),
18
+ React.createElement("h1", { style: styles.title }, title),
19
+ React.createElement("p", { style: styles.message }, message),
20
+ React.createElement("div", { style: styles.buttonContainer },
21
+ showBackButton && (React.createElement("button", { onClick: handleGoBack, style: styles.button, onMouseEnter: (e) => {
22
+ e.currentTarget.style.backgroundColor = '#5a6268';
23
+ }, onMouseLeave: (e) => {
24
+ e.currentTarget.style.backgroundColor = '#6c757d';
25
+ } }, "\uC774\uC804 \uD398\uC774\uC9C0")),
26
+ showHomeButton && (React.createElement("button", { onClick: handleGoHome, style: { ...styles.button, ...styles.primaryButton }, onMouseEnter: (e) => {
27
+ e.currentTarget.style.backgroundColor = '#0056b3';
28
+ }, onMouseLeave: (e) => {
29
+ e.currentTarget.style.backgroundColor = '#007bff';
30
+ } }, "\uD648\uC73C\uB85C"))))));
31
+ };
32
+ const styles = {
33
+ container: {
34
+ display: 'flex',
35
+ alignItems: 'center',
36
+ justifyContent: 'center',
37
+ minHeight: '100vh',
38
+ backgroundColor: '#f8f9fa',
39
+ padding: '20px',
40
+ },
41
+ content: {
42
+ textAlign: 'center',
43
+ maxWidth: '500px',
44
+ },
45
+ errorCode: {
46
+ fontSize: '120px',
47
+ fontWeight: 'bold',
48
+ color: '#dee2e6',
49
+ lineHeight: 1,
50
+ marginBottom: '20px',
51
+ },
52
+ title: {
53
+ fontSize: '24px',
54
+ fontWeight: 600,
55
+ color: '#343a40',
56
+ marginBottom: '12px',
57
+ },
58
+ message: {
59
+ fontSize: '16px',
60
+ color: '#6c757d',
61
+ marginBottom: '32px',
62
+ lineHeight: 1.5,
63
+ },
64
+ buttonContainer: {
65
+ display: 'flex',
66
+ gap: '12px',
67
+ justifyContent: 'center',
68
+ },
69
+ button: {
70
+ padding: '12px 24px',
71
+ fontSize: '14px',
72
+ fontWeight: 500,
73
+ border: 'none',
74
+ borderRadius: '8px',
75
+ cursor: 'pointer',
76
+ backgroundColor: '#6c757d',
77
+ color: '#fff',
78
+ transition: 'background-color 0.2s',
79
+ },
80
+ primaryButton: {
81
+ backgroundColor: '#007bff',
82
+ },
83
+ };
84
+ export default NotFound;
@@ -1,2 +1,4 @@
1
1
  export { default as ErrorBoundary } from './ErrorBoundary';
2
+ export { NotFound } from './NotFound';
3
+ export type { NotFoundProps } from './NotFound';
2
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/error/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/error/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
@@ -1 +1,2 @@
1
1
  export { default as ErrorBoundary } from './ErrorBoundary';
2
+ export { NotFound } from './NotFound';
@@ -0,0 +1,51 @@
1
+ /**
2
+ * 공통 아이콘 컴포넌트
3
+ * SVG 아이콘을 React 컴포넌트로 제공
4
+ */
5
+ import React from 'react';
6
+ export interface IconProps {
7
+ size?: number;
8
+ color?: string;
9
+ className?: string;
10
+ }
11
+ /** 대시보드 아이콘 */
12
+ export declare const DashboardIcon: React.FC<IconProps>;
13
+ /** 문서/이력서 아이콘 */
14
+ export declare const DocumentIcon: React.FC<IconProps>;
15
+ /** 블로그/펜 아이콘 */
16
+ export declare const BlogIcon: React.FC<IconProps>;
17
+ /** 홈 아이콘 */
18
+ export declare const HomeIcon: React.FC<IconProps>;
19
+ /** 설정 아이콘 */
20
+ export declare const SettingsIcon: React.FC<IconProps>;
21
+ /** 사용자 아이콘 */
22
+ export declare const UserIcon: React.FC<IconProps>;
23
+ /** 로그인 아이콘 */
24
+ export declare const LoginIcon: React.FC<IconProps>;
25
+ /** 로그아웃 아이콘 */
26
+ export declare const LogoutIcon: React.FC<IconProps>;
27
+ /** 검색 아이콘 */
28
+ export declare const SearchIcon: React.FC<IconProps>;
29
+ /** 플러스 아이콘 */
30
+ export declare const PlusIcon: React.FC<IconProps>;
31
+ /** 편집 아이콘 */
32
+ export declare const EditIcon: React.FC<IconProps>;
33
+ /** 삭제 아이콘 */
34
+ export declare const TrashIcon: React.FC<IconProps>;
35
+ /** 메뉴 아이콘 */
36
+ export declare const MenuIcon: React.FC<IconProps>;
37
+ /** 닫기 아이콘 */
38
+ export declare const CloseIcon: React.FC<IconProps>;
39
+ /** 체크 아이콘 */
40
+ export declare const CheckIcon: React.FC<IconProps>;
41
+ /** 경고 아이콘 */
42
+ export declare const AlertIcon: React.FC<IconProps>;
43
+ /** 정보 아이콘 */
44
+ export declare const InfoIcon: React.FC<IconProps>;
45
+ /** 화살표 왼쪽 아이콘 */
46
+ export declare const ArrowLeftIcon: React.FC<IconProps>;
47
+ /** 화살표 오른쪽 아이콘 */
48
+ export declare const ArrowRightIcon: React.FC<IconProps>;
49
+ /** 포트폴리오 아이콘 */
50
+ export declare const PortfolioIcon: React.FC<IconProps>;
51
+ //# sourceMappingURL=Icons.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Icons.d.ts","sourceRoot":"","sources":["../../../src/components/icons/Icons.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAOD,eAAe;AACf,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,SAAS,CAO7C,CAAC;AAEF,iBAAiB;AACjB,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,SAAS,CAQ5C,CAAC;AAEF,gBAAgB;AAChB,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,SAAS,CAOxC,CAAC;AAEF,YAAY;AACZ,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,SAAS,CAKxC,CAAC;AAEF,aAAa;AACb,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,SAAS,CAK5C,CAAC;AAEF,cAAc;AACd,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,SAAS,CAKxC,CAAC;AAEF,cAAc;AACd,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,SAAS,CAMzC,CAAC;AAEF,eAAe;AACf,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,SAAS,CAM1C,CAAC;AAEF,aAAa;AACb,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,SAAS,CAK1C,CAAC;AAEF,cAAc;AACd,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,SAAS,CAKxC,CAAC;AAEF,aAAa;AACb,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,SAAS,CAKxC,CAAC;AAEF,aAAa;AACb,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,SAAS,CAKzC,CAAC;AAEF,aAAa;AACb,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,SAAS,CAMxC,CAAC;AAEF,aAAa;AACb,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,SAAS,CAKzC,CAAC;AAEF,aAAa;AACb,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,SAAS,CAIzC,CAAC;AAEF,aAAa;AACb,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,SAAS,CAMzC,CAAC;AAEF,aAAa;AACb,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,SAAS,CAMxC,CAAC;AAEF,iBAAiB;AACjB,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,SAAS,CAK7C,CAAC;AAEF,kBAAkB;AAClB,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,SAAS,CAK9C,CAAC;AAEF,gBAAgB;AAChB,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,SAAS,CAK7C,CAAC"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * 공통 아이콘 컴포넌트
3
+ * SVG 아이콘을 React 컴포넌트로 제공
4
+ */
5
+ import React from 'react';
6
+ const defaultProps = {
7
+ size: 20,
8
+ color: 'currentColor',
9
+ };
10
+ /** 대시보드 아이콘 */
11
+ export const DashboardIcon = ({ size = 20, color = 'currentColor', className }) => (React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", className: className },
12
+ React.createElement("rect", { x: "3", y: "3", width: "7", height: "7" }),
13
+ React.createElement("rect", { x: "14", y: "3", width: "7", height: "7" }),
14
+ React.createElement("rect", { x: "14", y: "14", width: "7", height: "7" }),
15
+ React.createElement("rect", { x: "3", y: "14", width: "7", height: "7" })));
16
+ /** 문서/이력서 아이콘 */
17
+ export const DocumentIcon = ({ size = 20, color = 'currentColor', className }) => (React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", className: className },
18
+ React.createElement("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
19
+ React.createElement("polyline", { points: "14 2 14 8 20 8" }),
20
+ React.createElement("line", { x1: "16", y1: "13", x2: "8", y2: "13" }),
21
+ React.createElement("line", { x1: "16", y1: "17", x2: "8", y2: "17" }),
22
+ React.createElement("polyline", { points: "10 9 9 9 8 9" })));
23
+ /** 블로그/펜 아이콘 */
24
+ export const BlogIcon = ({ size = 20, color = 'currentColor', className }) => (React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", className: className },
25
+ React.createElement("path", { d: "M12 19l7-7 3 3-7 7-3-3z" }),
26
+ React.createElement("path", { d: "M18 13l-1.5-7.5L2 2l3.5 14.5L13 18l5-5z" }),
27
+ React.createElement("path", { d: "M2 2l7.586 7.586" }),
28
+ React.createElement("circle", { cx: "11", cy: "11", r: "2" })));
29
+ /** 홈 아이콘 */
30
+ export const HomeIcon = ({ size = 20, color = 'currentColor', className }) => (React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", className: className },
31
+ React.createElement("path", { d: "m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" }),
32
+ React.createElement("polyline", { points: "9 22 9 12 15 12 15 22" })));
33
+ /** 설정 아이콘 */
34
+ export const SettingsIcon = ({ size = 20, color = 'currentColor', className }) => (React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", className: className },
35
+ React.createElement("circle", { cx: "12", cy: "12", r: "3" }),
36
+ React.createElement("path", { d: "M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z" })));
37
+ /** 사용자 아이콘 */
38
+ export const UserIcon = ({ size = 20, color = 'currentColor', className }) => (React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", className: className },
39
+ React.createElement("path", { d: "M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" }),
40
+ React.createElement("circle", { cx: "12", cy: "7", r: "4" })));
41
+ /** 로그인 아이콘 */
42
+ export const LoginIcon = ({ size = 18, color = 'currentColor', className }) => (React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", className: className },
43
+ React.createElement("path", { d: "M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4" }),
44
+ React.createElement("polyline", { points: "10 17 15 12 10 7" }),
45
+ React.createElement("line", { x1: "15", y1: "12", x2: "3", y2: "12" })));
46
+ /** 로그아웃 아이콘 */
47
+ export const LogoutIcon = ({ size = 18, color = 'currentColor', className }) => (React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", className: className },
48
+ React.createElement("path", { d: "M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" }),
49
+ React.createElement("polyline", { points: "16 17 21 12 16 7" }),
50
+ React.createElement("line", { x1: "21", y1: "12", x2: "9", y2: "12" })));
51
+ /** 검색 아이콘 */
52
+ export const SearchIcon = ({ size = 20, color = 'currentColor', className }) => (React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", className: className },
53
+ React.createElement("circle", { cx: "11", cy: "11", r: "8" }),
54
+ React.createElement("path", { d: "m21 21-4.35-4.35" })));
55
+ /** 플러스 아이콘 */
56
+ export const PlusIcon = ({ size = 20, color = 'currentColor', className }) => (React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", className: className },
57
+ React.createElement("line", { x1: "12", y1: "5", x2: "12", y2: "19" }),
58
+ React.createElement("line", { x1: "5", y1: "12", x2: "19", y2: "12" })));
59
+ /** 편집 아이콘 */
60
+ export const EditIcon = ({ size = 20, color = 'currentColor', className }) => (React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", className: className },
61
+ React.createElement("path", { d: "M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" }),
62
+ React.createElement("path", { d: "M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" })));
63
+ /** 삭제 아이콘 */
64
+ export const TrashIcon = ({ size = 20, color = 'currentColor', className }) => (React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", className: className },
65
+ React.createElement("polyline", { points: "3 6 5 6 21 6" }),
66
+ React.createElement("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" })));
67
+ /** 메뉴 아이콘 */
68
+ export const MenuIcon = ({ size = 20, color = 'currentColor', className }) => (React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", className: className },
69
+ React.createElement("line", { x1: "3", y1: "12", x2: "21", y2: "12" }),
70
+ React.createElement("line", { x1: "3", y1: "6", x2: "21", y2: "6" }),
71
+ React.createElement("line", { x1: "3", y1: "18", x2: "21", y2: "18" })));
72
+ /** 닫기 아이콘 */
73
+ export const CloseIcon = ({ size = 20, color = 'currentColor', className }) => (React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", className: className },
74
+ React.createElement("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
75
+ React.createElement("line", { x1: "6", y1: "6", x2: "18", y2: "18" })));
76
+ /** 체크 아이콘 */
77
+ export const CheckIcon = ({ size = 20, color = 'currentColor', className }) => (React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", className: className },
78
+ React.createElement("polyline", { points: "20 6 9 17 4 12" })));
79
+ /** 경고 아이콘 */
80
+ export const AlertIcon = ({ size = 20, color = 'currentColor', className }) => (React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", className: className },
81
+ React.createElement("circle", { cx: "12", cy: "12", r: "10" }),
82
+ React.createElement("line", { x1: "12", y1: "8", x2: "12", y2: "12" }),
83
+ React.createElement("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })));
84
+ /** 정보 아이콘 */
85
+ export const InfoIcon = ({ size = 20, color = 'currentColor', className }) => (React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", className: className },
86
+ React.createElement("circle", { cx: "12", cy: "12", r: "10" }),
87
+ React.createElement("line", { x1: "12", y1: "16", x2: "12", y2: "12" }),
88
+ React.createElement("line", { x1: "12", y1: "8", x2: "12.01", y2: "8" })));
89
+ /** 화살표 왼쪽 아이콘 */
90
+ export const ArrowLeftIcon = ({ size = 20, color = 'currentColor', className }) => (React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", className: className },
91
+ React.createElement("line", { x1: "19", y1: "12", x2: "5", y2: "12" }),
92
+ React.createElement("polyline", { points: "12 19 5 12 12 5" })));
93
+ /** 화살표 오른쪽 아이콘 */
94
+ export const ArrowRightIcon = ({ size = 20, color = 'currentColor', className }) => (React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", className: className },
95
+ React.createElement("line", { x1: "5", y1: "12", x2: "19", y2: "12" }),
96
+ React.createElement("polyline", { points: "12 5 19 12 12 19" })));
97
+ /** 포트폴리오 아이콘 */
98
+ export const PortfolioIcon = ({ size = 20, color = 'currentColor', className }) => (React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", className: className },
99
+ React.createElement("rect", { x: "2", y: "7", width: "20", height: "14", rx: "2", ry: "2" }),
100
+ React.createElement("path", { d: "M16 21V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16" })));
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Icons 모듈
3
+ */
4
+ export * from './Icons';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/icons/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,SAAS,CAAC"}
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Icons 모듈
3
+ */
4
+ export * from './Icons';
@@ -7,4 +7,7 @@ export * from './navigation';
7
7
  export * from './layout';
8
8
  export * from './logo';
9
9
  export * from './page';
10
+ export * from './router';
11
+ export * from './remote';
12
+ export * from './icons';
10
13
  //# 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,UAAU,CAAC;AAGzB,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;AAGvB,cAAc,UAAU,CAAC;AAGzB,cAAc,UAAU,CAAC;AAEzB,cAAc,SAAS,CAAC"}
@@ -16,3 +16,9 @@ export * from './layout';
16
16
  export * from './logo';
17
17
  // Page (LoginPage 등)
18
18
  export * from './page';
19
+ // Router
20
+ export * from './router';
21
+ // Remote (MFA 관련)
22
+ export * from './remote';
23
+ // Icons
24
+ export * from './icons';
@@ -1,5 +1,10 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
1
+ /**
2
+ * Container Component - KOMCA 패턴
3
+ *
4
+ * 앱 전체를 감싸는 레이아웃 컨테이너
5
+ */
6
+ import React from 'react';
2
7
  export const Container = ({ children, className = '' }) => {
3
- return (_jsx("div", { className: `app-container ${className}`, children: children }));
8
+ return (React.createElement("div", { className: `app-container ${className}` }, children));
4
9
  };
5
10
  export default Container;
@@ -0,0 +1,19 @@
1
+ import React, { ReactNode } from 'react';
2
+ interface DeferredComponentProps {
3
+ children: ReactNode;
4
+ /** 지연 시간 (ms), 기본값 200ms */
5
+ delay?: number;
6
+ }
7
+ /**
8
+ * 지연된 렌더링 컴포넌트
9
+ * - 느린 네트워크: 즉시 children 렌더링
10
+ * - 빠른 네트워크: delay ms 후 children 렌더링
11
+ *
12
+ * 사용 예:
13
+ * <Suspense fallback={<DeferredComponent><Skeleton /></DeferredComponent>}>
14
+ * <AsyncComponent />
15
+ * </Suspense>
16
+ */
17
+ declare const DeferredComponent: React.FC<DeferredComponentProps>;
18
+ export default DeferredComponent;
19
+ //# sourceMappingURL=DeferredComponent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DeferredComponent.d.ts","sourceRoot":"","sources":["../../../src/components/loading/DeferredComponent.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,SAAS,EAAuB,MAAM,OAAO,CAAC;AAG9D,UAAU,sBAAsB;IAC9B,QAAQ,EAAE,SAAS,CAAC;IACpB,4BAA4B;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;GASG;AACH,QAAA,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAyBvD,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
@@ -0,0 +1,32 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import useNetworkStatus from '../../hooks/use-network-status';
3
+ /**
4
+ * 지연된 렌더링 컴포넌트
5
+ * - 느린 네트워크: 즉시 children 렌더링
6
+ * - 빠른 네트워크: delay ms 후 children 렌더링
7
+ *
8
+ * 사용 예:
9
+ * <Suspense fallback={<DeferredComponent><Skeleton /></DeferredComponent>}>
10
+ * <AsyncComponent />
11
+ * </Suspense>
12
+ */
13
+ const DeferredComponent = ({ children, delay = 200 }) => {
14
+ const { isSlowNetwork } = useNetworkStatus();
15
+ const [shouldRender, setShouldRender] = useState(false);
16
+ useEffect(() => {
17
+ // 느린 네트워크면 즉시 표시
18
+ if (isSlowNetwork) {
19
+ setShouldRender(true);
20
+ return;
21
+ }
22
+ // 빠른 네트워크면 delay 후 표시
23
+ const timeoutId = setTimeout(() => {
24
+ setShouldRender(true);
25
+ }, delay);
26
+ return () => clearTimeout(timeoutId);
27
+ }, [isSlowNetwork, delay]);
28
+ if (!shouldRender)
29
+ return null;
30
+ return React.createElement(React.Fragment, null, children);
31
+ };
32
+ export default DeferredComponent;
@@ -1,4 +1,8 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ /**
2
+ * GlobalLoading Component - KOMCA 패턴
3
+ * 전역 로딩 스피너 UI
4
+ */
5
+ import React from 'react';
2
6
  import { useSelector } from 'react-redux';
3
7
  const GlobalLoading = ({ message }) => {
4
8
  const isLoading = useSelector((state) => state.app?.isLoading);
@@ -6,7 +10,14 @@ const GlobalLoading = ({ message }) => {
6
10
  if (!isLoading)
7
11
  return null;
8
12
  const displayMessage = message || globalLoadingTitle || '로딩 중...';
9
- return (_jsxs("div", { className: "global-loading-overlay", children: [_jsxs("div", { className: "global-loading-content", children: [_jsxs("div", { className: "global-loading-spinner", children: [_jsx("div", { className: "spinner-ring" }), _jsx("div", { className: "spinner-ring" }), _jsx("div", { className: "spinner-ring" })] }), displayMessage && (_jsx("p", { className: "global-loading-message", children: displayMessage }))] }), _jsx("style", { children: `
13
+ return (React.createElement("div", { className: "global-loading-overlay" },
14
+ React.createElement("div", { className: "global-loading-content" },
15
+ React.createElement("div", { className: "global-loading-spinner" },
16
+ React.createElement("div", { className: "spinner-ring" }),
17
+ React.createElement("div", { className: "spinner-ring" }),
18
+ React.createElement("div", { className: "spinner-ring" })),
19
+ displayMessage && (React.createElement("p", { className: "global-loading-message" }, displayMessage))),
20
+ React.createElement("style", null, `
10
21
  .global-loading-overlay {
11
22
  position: fixed;
12
23
  top: 0;
@@ -79,6 +90,6 @@ const GlobalLoading = ({ message }) => {
79
90
  color: #374151;
80
91
  font-weight: 500;
81
92
  }
82
- ` })] }));
93
+ `)));
83
94
  };
84
95
  export default GlobalLoading;
@@ -1,2 +1,3 @@
1
1
  export { default as GlobalLoading } from './GlobalLoading';
2
+ export { default as DeferredComponent } from './DeferredComponent';
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/loading/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/loading/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,qBAAqB,CAAC"}
@@ -1 +1,2 @@
1
1
  export { default as GlobalLoading } from './GlobalLoading';
2
+ export { default as DeferredComponent } from './DeferredComponent';
@@ -1,5 +1,4 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useState } from 'react';
1
+ import React, { useState } from 'react';
3
2
  const sizeMap = {
4
3
  sm: { main: 24, side: 14 },
5
4
  md: { main: 40, side: 22 },
@@ -33,6 +32,16 @@ export const Logo = ({ size = 'md', customSize, sideColor = '#1E3A5F', centerCol
33
32
  // 콧구멍 크기 (호버시 커짐)
34
33
  const noseRx = centerHover && interactive ? 5.5 : 4;
35
34
  const noseRy = centerHover && interactive ? 8 : 6;
36
- return (_jsxs("div", { style: styles.container, className: `logo ${className}`, onClick: onClick, role: onClick ? 'button' : undefined, children: [!centerOnly && (_jsx("svg", { viewBox: "0 0 48 48", fill: "none", xmlns: "http://www.w3.org/2000/svg", width: dimensions.side, height: dimensions.side, style: styles.side, onMouseEnter: () => setSideHover(true), onMouseLeave: () => setSideHover(false), children: _jsx("path", { d: "M 8 40 L 24 8 L 40 40", stroke: sideColor, strokeWidth: "14", strokeLinecap: "round", strokeLinejoin: "round", fill: "none" }) })), _jsxs("svg", { viewBox: "0 0 48 48", fill: "none", xmlns: "http://www.w3.org/2000/svg", width: dimensions.main, height: dimensions.main, style: styles.center, onMouseEnter: () => setCenterHover(true), onMouseLeave: () => setCenterHover(false), children: [_jsx("rect", { x: "20", y: "2", width: "8", height: "16", rx: "4", fill: centerColor }), _jsx("rect", { x: "6", y: "16", width: "36", height: "6", rx: "3", fill: centerColor }), _jsx("ellipse", { cx: "24", cy: "36", rx: "18", ry: "12", fill: centerColor }), _jsx("ellipse", { cx: "17", cy: eyeY, rx: noseRx, ry: noseRy, fill: eyeColor, style: { transition: 'all 0.2s ease' } }), _jsx("ellipse", { cx: "31", cy: eyeY, rx: noseRx, ry: noseRy, fill: eyeColor, style: { transition: 'all 0.2s ease' } })] }), !centerOnly && (_jsx("svg", { viewBox: "0 0 48 48", fill: "none", xmlns: "http://www.w3.org/2000/svg", width: dimensions.side, height: dimensions.side, style: styles.side, onMouseEnter: () => setSideHover(true), onMouseLeave: () => setSideHover(false), children: _jsx("path", { d: "M 8 40 L 24 8 L 40 40", stroke: sideColor, strokeWidth: "14", strokeLinecap: "round", strokeLinejoin: "round", fill: "none" }) }))] }));
35
+ return (React.createElement("div", { style: styles.container, className: `logo ${className}`, onClick: onClick, role: onClick ? 'button' : undefined },
36
+ !centerOnly && (React.createElement("svg", { viewBox: "0 0 48 48", fill: "none", xmlns: "http://www.w3.org/2000/svg", width: dimensions.side, height: dimensions.side, style: styles.side, onMouseEnter: () => setSideHover(true), onMouseLeave: () => setSideHover(false) },
37
+ React.createElement("path", { d: "M 8 40 L 24 8 L 40 40", stroke: sideColor, strokeWidth: "14", strokeLinecap: "round", strokeLinejoin: "round", fill: "none" }))),
38
+ React.createElement("svg", { viewBox: "0 0 48 48", fill: "none", xmlns: "http://www.w3.org/2000/svg", width: dimensions.main, height: dimensions.main, style: styles.center, onMouseEnter: () => setCenterHover(true), onMouseLeave: () => setCenterHover(false) },
39
+ React.createElement("rect", { x: "20", y: "2", width: "8", height: "16", rx: "4", fill: centerColor }),
40
+ React.createElement("rect", { x: "6", y: "16", width: "36", height: "6", rx: "3", fill: centerColor }),
41
+ React.createElement("ellipse", { cx: "24", cy: "36", rx: "18", ry: "12", fill: centerColor }),
42
+ React.createElement("ellipse", { cx: "17", cy: eyeY, rx: noseRx, ry: noseRy, fill: eyeColor, style: { transition: 'all 0.2s ease' } }),
43
+ React.createElement("ellipse", { cx: "31", cy: eyeY, rx: noseRx, ry: noseRy, fill: eyeColor, style: { transition: 'all 0.2s ease' } })),
44
+ !centerOnly && (React.createElement("svg", { viewBox: "0 0 48 48", fill: "none", xmlns: "http://www.w3.org/2000/svg", width: dimensions.side, height: dimensions.side, style: styles.side, onMouseEnter: () => setSideHover(true), onMouseLeave: () => setSideHover(false) },
45
+ React.createElement("path", { d: "M 8 40 L 24 8 L 40 40", stroke: sideColor, strokeWidth: "14", strokeLinecap: "round", strokeLinejoin: "round", fill: "none" })))));
37
46
  };
38
47
  export default Logo;
@@ -1,9 +1,8 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
1
  /**
3
2
  * Modal Container - KOMCA 패턴
4
3
  * 모달 UI 렌더링
5
4
  */
6
- import { useEffect } from 'react';
5
+ import React, { useEffect } from 'react';
7
6
  import { useModalContext } from './ModalContext';
8
7
  const ModalContainer = () => {
9
8
  const { modals, closeModal } = useModalContext();
@@ -47,11 +46,21 @@ const ModalContainer = () => {
47
46
  modal.onCancel?.();
48
47
  closeModal(modal.id, false);
49
48
  };
50
- return (_jsxs(_Fragment, { children: [modals.map((modal, index) => (_jsx("div", { className: "modal-overlay", style: { zIndex: 10000 + index }, onClick: () => handleOverlayClick(modal), children: _jsx("div", { className: "modal-container", onClick: (e) => e.stopPropagation(), children: modal.content ? (
51
- // 커스텀 컨텐츠
52
- modal.content) : (
53
- // 기본 Alert/Confirm UI
54
- _jsxs(_Fragment, { children: [modal.title && (_jsx("div", { className: "modal-header", children: _jsx("h3", { className: "modal-title", children: modal.title }) })), _jsx("div", { className: "modal-body", children: _jsx("p", { className: "modal-message", children: modal.message }) }), _jsxs("div", { className: "modal-footer", children: [modal.type === 'confirm' && modal.cancelText && (_jsx("button", { className: "modal-button secondary", onClick: () => handleCancel(modal), children: modal.cancelText })), _jsx("button", { className: "modal-button primary", onClick: () => handleConfirm(modal), children: modal.confirmText || '확인' })] })] })) }) }, modal.id))), _jsx("style", { children: `
49
+ return (React.createElement(React.Fragment, null,
50
+ modals.map((modal, index) => (React.createElement("div", { key: modal.id, className: "modal-overlay", style: { zIndex: 10000 + index }, onClick: () => handleOverlayClick(modal) },
51
+ React.createElement("div", { className: "modal-container", onClick: (e) => e.stopPropagation() }, modal.content ? (
52
+ // 커스텀 컨텐츠
53
+ modal.content) : (
54
+ // 기본 Alert/Confirm UI
55
+ React.createElement(React.Fragment, null,
56
+ modal.title && (React.createElement("div", { className: "modal-header" },
57
+ React.createElement("h3", { className: "modal-title" }, modal.title))),
58
+ React.createElement("div", { className: "modal-body" },
59
+ React.createElement("p", { className: "modal-message" }, modal.message)),
60
+ React.createElement("div", { className: "modal-footer" },
61
+ modal.type === 'confirm' && modal.cancelText && (React.createElement("button", { className: "modal-button secondary", onClick: () => handleCancel(modal) }, modal.cancelText)),
62
+ React.createElement("button", { className: "modal-button primary", onClick: () => handleConfirm(modal) }, modal.confirmText || '확인')))))))),
63
+ React.createElement("style", null, `
55
64
  .modal-overlay {
56
65
  position: fixed;
57
66
  top: 0;
@@ -156,6 +165,6 @@ const ModalContainer = () => {
156
165
  .modal-button.secondary:hover {
157
166
  background: #f3f4f6;
158
167
  }
159
- ` })] }));
168
+ `)));
160
169
  };
161
170
  export default ModalContainer;
@@ -1,9 +1,8 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
1
  /**
3
2
  * Modal Context - KOMCA 패턴
4
3
  * 전역 모달 상태 관리
5
4
  */
6
- import { createContext, useContext, useCallback, useState } from 'react';
5
+ import React, { createContext, useContext, useCallback, useState } from 'react';
7
6
  const ModalContext = createContext(null);
8
7
  /**
9
8
  * Modal Provider
@@ -63,7 +62,7 @@ export const ModalProvider = ({ children }) => {
63
62
  ]);
64
63
  });
65
64
  }, []);
66
- return (_jsx(ModalContext.Provider, { value: { modals, alert, confirm, openModal, closeModal, closeAll }, children: children }));
65
+ return (React.createElement(ModalContext.Provider, { value: { modals, alert, confirm, openModal, closeModal, closeAll } }, children));
67
66
  };
68
67
  /**
69
68
  * useModal Hook