@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.
- package/dist/components/button/ScrollTopButton.js +5 -3
- package/dist/components/error/ErrorBoundary.js +14 -4
- package/dist/components/error/NotFound.d.ts +20 -0
- package/dist/components/error/NotFound.d.ts.map +1 -0
- package/dist/components/error/NotFound.js +84 -0
- package/dist/components/error/index.d.ts +2 -0
- package/dist/components/error/index.d.ts.map +1 -1
- package/dist/components/error/index.js +1 -0
- package/dist/components/icons/Icons.d.ts +51 -0
- package/dist/components/icons/Icons.d.ts.map +1 -0
- package/dist/components/icons/Icons.js +100 -0
- package/dist/components/icons/index.d.ts +5 -0
- package/dist/components/icons/index.d.ts.map +1 -0
- package/dist/components/icons/index.js +4 -0
- package/dist/components/index.d.ts +3 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +6 -0
- package/dist/components/layout/Container.js +7 -2
- package/dist/components/loading/DeferredComponent.d.ts +19 -0
- package/dist/components/loading/DeferredComponent.d.ts.map +1 -0
- package/dist/components/loading/DeferredComponent.js +32 -0
- package/dist/components/loading/GlobalLoading.js +14 -3
- package/dist/components/loading/index.d.ts +1 -0
- package/dist/components/loading/index.d.ts.map +1 -1
- package/dist/components/loading/index.js +1 -0
- package/dist/components/logo/Logo.js +12 -3
- package/dist/components/modal/ModalContainer.js +17 -8
- package/dist/components/modal/ModalContext.js +2 -3
- package/dist/components/navigation/AppNavbar.js +21 -9
- package/dist/components/navigation/AppSidebar.css +58 -3
- package/dist/components/navigation/AppSidebar.d.ts +1 -1
- package/dist/components/navigation/AppSidebar.d.ts.map +1 -1
- package/dist/components/navigation/AppSidebar.js +58 -15
- package/dist/components/navigation/Footer.d.ts +15 -0
- package/dist/components/navigation/Footer.d.ts.map +1 -0
- package/dist/components/navigation/Footer.js +12 -0
- package/dist/components/navigation/Header.d.ts.map +1 -1
- package/dist/components/navigation/Header.js +17 -4
- package/dist/components/navigation/Lnb.d.ts +2 -7
- package/dist/components/navigation/Lnb.d.ts.map +1 -1
- package/dist/components/navigation/Lnb.js +34 -8
- package/dist/components/navigation/StickyNav.js +19 -11
- package/dist/components/navigation/index.d.ts +1 -0
- package/dist/components/navigation/index.d.ts.map +1 -1
- package/dist/components/navigation/index.js +1 -0
- package/dist/components/page/LoginPage.d.ts +4 -1
- package/dist/components/page/LoginPage.d.ts.map +1 -1
- package/dist/components/page/LoginPage.js +146 -21
- package/dist/components/remote/RemoteErrorBoundary.d.ts +28 -0
- package/dist/components/remote/RemoteErrorBoundary.d.ts.map +1 -0
- package/dist/components/remote/RemoteErrorBoundary.js +44 -0
- package/dist/components/remote/RemoteErrorFallback.d.ts +16 -0
- package/dist/components/remote/RemoteErrorFallback.d.ts.map +1 -0
- package/dist/components/remote/RemoteErrorFallback.js +76 -0
- package/dist/components/remote/index.d.ts +8 -0
- package/dist/components/remote/index.d.ts.map +1 -0
- package/dist/components/remote/index.js +5 -0
- package/dist/components/router/BrowserRouter.d.ts +13 -0
- package/dist/components/router/BrowserRouter.d.ts.map +1 -0
- package/dist/components/router/BrowserRouter.js +17 -0
- package/dist/components/router/RouteGuard.d.ts +79 -0
- package/dist/components/router/RouteGuard.d.ts.map +1 -0
- package/dist/components/router/RouteGuard.js +86 -0
- package/dist/components/router/index.d.ts +4 -0
- package/dist/components/router/index.d.ts.map +1 -0
- package/dist/components/router/index.js +2 -0
- package/dist/components/toast/ToastContainer.js +17 -6
- package/dist/components/toast/ToastContext.js +2 -3
- package/dist/hooks/index.d.ts +9 -1
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +15 -1
- package/dist/hooks/use-auth.d.ts +2 -1
- package/dist/hooks/use-auth.d.ts.map +1 -1
- package/dist/hooks/use-auth.js +19 -18
- package/dist/hooks/use-debounce.d.ts +56 -0
- package/dist/hooks/use-debounce.d.ts.map +1 -0
- package/dist/hooks/use-debounce.js +140 -0
- package/dist/hooks/use-effect-once.d.ts +77 -0
- package/dist/hooks/use-effect-once.d.ts.map +1 -0
- package/dist/hooks/use-effect-once.js +124 -0
- package/dist/hooks/use-error-notification.d.ts +1 -1
- package/dist/hooks/use-error-notification.js +1 -1
- package/dist/hooks/use-global-loading.d.ts +1 -1
- package/dist/hooks/use-global-loading.js +1 -1
- package/dist/hooks/use-initialize.d.ts +8 -1
- package/dist/hooks/use-initialize.d.ts.map +1 -1
- package/dist/hooks/use-initialize.js +126 -23
- package/dist/hooks/use-modal.d.ts +21 -5
- package/dist/hooks/use-modal.d.ts.map +1 -1
- package/dist/hooks/use-modal.js +57 -17
- package/dist/hooks/use-navigate.d.ts +1 -1
- package/dist/hooks/use-navigate.js +1 -1
- package/dist/hooks/use-network-status.d.ts +15 -0
- package/dist/hooks/use-network-status.d.ts.map +1 -0
- package/dist/hooks/use-network-status.js +49 -0
- package/dist/hooks/use-permission.d.ts +22 -0
- package/dist/hooks/use-permission.d.ts.map +1 -0
- package/dist/hooks/use-permission.js +73 -0
- package/dist/hooks/use-recent-menu.d.ts +46 -0
- package/dist/hooks/use-recent-menu.d.ts.map +1 -0
- package/dist/hooks/use-recent-menu.js +169 -0
- package/dist/hooks/use-scroll-restoration.d.ts +51 -0
- package/dist/hooks/use-scroll-restoration.d.ts.map +1 -0
- package/dist/hooks/use-scroll-restoration.js +143 -0
- package/dist/hooks/use-supabase-auth.d.ts +49 -0
- package/dist/hooks/use-supabase-auth.d.ts.map +1 -0
- package/dist/hooks/use-supabase-auth.js +229 -0
- package/dist/hooks/use-track-history.d.ts +2 -1
- package/dist/hooks/use-track-history.d.ts.map +1 -1
- package/dist/hooks/use-track-history.js +14 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/network/axios-factory.d.ts +30 -1
- package/dist/network/axios-factory.d.ts.map +1 -1
- package/dist/network/axios-factory.js +192 -24
- package/dist/network/index.d.ts +3 -1
- package/dist/network/index.d.ts.map +1 -1
- package/dist/network/index.js +5 -1
- package/dist/network/supabase-client.d.ts +28 -0
- package/dist/network/supabase-client.d.ts.map +1 -0
- package/dist/network/supabase-client.js +46 -0
- package/dist/store/app-store.d.ts +222 -12
- package/dist/store/app-store.d.ts.map +1 -1
- package/dist/store/app-store.js +46 -29
- package/dist/store/index.d.ts +2 -0
- package/dist/store/index.d.ts.map +1 -1
- package/dist/store/index.js +3 -0
- package/dist/store/menu-slice.d.ts +96 -0
- package/dist/store/menu-slice.d.ts.map +1 -0
- package/dist/store/menu-slice.js +98 -0
- package/dist/store/recent-menu-slice.d.ts +209 -0
- package/dist/store/recent-menu-slice.d.ts.map +1 -0
- package/dist/store/recent-menu-slice.js +110 -0
- package/dist/store/store-access.d.ts +1 -1
- package/dist/store/store-access.js +1 -1
- package/dist/types/index.d.ts +74 -17
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/service.d.ts +1 -1
- package/dist/types/service.js +1 -1
- package/dist/utils/classnames.d.ts +65 -0
- package/dist/utils/classnames.d.ts.map +1 -0
- package/dist/utils/classnames.js +98 -0
- package/dist/utils/formatter.d.ts +78 -0
- package/dist/utils/formatter.d.ts.map +1 -0
- package/dist/utils/formatter.js +216 -0
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +5 -0
- package/dist/utils/permission.d.ts +33 -0
- package/dist/utils/permission.d.ts.map +1 -0
- package/dist/utils/permission.js +132 -0
- package/dist/utils/query-string.d.ts +67 -0
- package/dist/utils/query-string.d.ts.map +1 -0
- package/dist/utils/query-string.js +136 -0
- package/dist/utils/storage.d.ts +1 -1
- package/dist/utils/storage.js +1 -1
- package/dist/utils/validation.d.ts +98 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +260 -0
- package/package.json +5 -3
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
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 (
|
|
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 (
|
|
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 +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"}
|
|
@@ -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 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/icons/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,SAAS,CAAC"}
|
|
@@ -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"}
|
package/dist/components/index.js
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Container Component - KOMCA 패턴
|
|
3
|
+
*
|
|
4
|
+
* 앱 전체를 감싸는 레이아웃 컨테이너
|
|
5
|
+
*/
|
|
6
|
+
import React from 'react';
|
|
2
7
|
export const Container = ({ children, className = '' }) => {
|
|
3
|
-
return (
|
|
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
|
-
|
|
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 (
|
|
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 +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,5 +1,4 @@
|
|
|
1
|
-
import
|
|
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 (
|
|
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 (
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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 (
|
|
65
|
+
return (React.createElement(ModalContext.Provider, { value: { modals, alert, confirm, openModal, closeModal, closeAll } }, children));
|
|
67
66
|
};
|
|
68
67
|
/**
|
|
69
68
|
* useModal Hook
|