@solapi/ui-kit 1.0.0
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/README.md +153 -0
- package/dist/GlobalMfa-F9T2HvGA.cjs +1 -0
- package/dist/GlobalMfa-a9UddAbl.js +2176 -0
- package/dist/components/AuthFlow/AuthFlowGoogleOtpForm.d.ts +11 -0
- package/dist/components/AuthFlow/AuthFlowPasswordForm.d.ts +15 -0
- package/dist/components/AuthFlow/AuthFlowQueueItem.d.ts +6 -0
- package/dist/components/AuthFlow/AuthFlowSelfCert.d.ts +16 -0
- package/dist/components/AuthFlow/AuthFlowSimpleCert.d.ts +15 -0
- package/dist/components/AuthFlow/AuthFlowSmsForm.d.ts +33 -0
- package/dist/components/AuthFlow/AuthFlowTimer.d.ts +16 -0
- package/dist/components/AuthFlow/index.d.ts +6 -0
- package/dist/components/Confirm/Confirm.d.ts +3 -0
- package/dist/components/DatePicker/DatePicker.d.ts +21 -0
- package/dist/components/DatePicker/DateTimeField.d.ts +16 -0
- package/dist/components/DatePicker/MonthCalendar.d.ts +19 -0
- package/dist/components/DatePicker/TimeSelector.d.ts +13 -0
- package/dist/components/DatePicker/index.d.ts +4 -0
- package/dist/components/GlobalMfa/GlobalMfa.d.ts +3 -0
- package/dist/components/ListFilter/FilterChip.d.ts +21 -0
- package/dist/components/ListFilter/FilterPanelContent.d.ts +9 -0
- package/dist/components/ListFilter/ListFilter.d.ts +37 -0
- package/dist/components/ListFilter/NumberConditionSelect.d.ts +6 -0
- package/dist/components/ListFilter/SelectOptionButtons.d.ts +9 -0
- package/dist/components/ListFilter/index.d.ts +2 -0
- package/dist/components/Menu/Menu.d.ts +43 -0
- package/dist/components/Menu/index.d.ts +2 -0
- package/dist/components/Mfa/MfaEmail.d.ts +17 -0
- package/dist/components/Mfa/MfaMultiCert.d.ts +23 -0
- package/dist/components/Mfa/MfaPasswordNumPad.d.ts +11 -0
- package/dist/components/Mfa/MfaQueueItem.d.ts +7 -0
- package/dist/components/Mfa/MfaSelfCert.d.ts +20 -0
- package/dist/components/Mfa/MfaSms.d.ts +28 -0
- package/dist/components/Mfa/index.d.ts +4 -0
- package/dist/components/MiniTabs/MiniTabs.d.ts +28 -0
- package/dist/components/MiniTabs/index.d.ts +2 -0
- package/dist/components/Modal/Modal.d.ts +9 -0
- package/dist/components/Snackbar/Snackbar.d.ts +9 -0
- package/dist/components/Tabs/Tabs.d.ts +22 -0
- package/dist/components/Tabs/index.d.ts +1 -0
- package/dist/components/TextInput/TextInput.d.ts +30 -0
- package/dist/components/TextInput/index.d.ts +2 -0
- package/dist/components/common/Box.d.ts +27 -0
- package/dist/components/common/Button.d.ts +22 -0
- package/dist/components/common/Collapse.d.ts +19 -0
- package/dist/components/common/Divider.d.ts +15 -0
- package/dist/components/common/Grid.d.ts +51 -0
- package/dist/components/common/IconButton.d.ts +20 -0
- package/dist/components/common/Info.d.ts +10 -0
- package/dist/components/common/Paper.d.ts +19 -0
- package/dist/components/common/Popover.d.ts +20 -0
- package/dist/components/common/Stack.d.ts +17 -0
- package/dist/components/common/Typography.d.ts +20 -0
- package/dist/components/common/index.d.ts +15 -0
- package/dist/export/GlobalUIProvider.d.ts +20 -0
- package/dist/export/UIHost.d.ts +1 -0
- package/dist/export/UIProvider.d.ts +42 -0
- package/dist/export/index.d.ts +13 -0
- package/dist/federation/componentLoader.d.ts +8 -0
- package/dist/federation/hookLoader.d.ts +8 -0
- package/dist/federation/index.d.ts +4 -0
- package/dist/federation/providerLoader.d.ts +11 -0
- package/dist/federation/safeImport.d.ts +14 -0
- package/dist/federation.cjs +1 -0
- package/dist/federation.js +132 -0
- package/dist/hooks/useConfirm.d.ts +7 -0
- package/dist/hooks/useEnhancedMutation.d.ts +8 -0
- package/dist/hooks/useLingeringValue.d.ts +7 -0
- package/dist/hooks/useModal.d.ts +7 -0
- package/dist/hooks/useSnackbar.d.ts +12 -0
- package/dist/index-BpqgYc0Q.cjs +5 -0
- package/dist/index-DV20NPKR.js +18341 -0
- package/dist/index.cjs +1 -0
- package/dist/index.js +43 -0
- package/dist/lib/createMutationConfig.d.ts +62 -0
- package/dist/lib/phoneUtils.d.ts +1 -0
- package/dist/lib/typeDetector.d.ts +59 -0
- package/dist/stores/createConfirmStore.d.ts +24 -0
- package/dist/stores/createModalStore.d.ts +37 -0
- package/dist/stores/createSnackbarStore.d.ts +20 -0
- package/dist/stores/requestQueueStore.d.ts +41 -0
- package/dist/theme/ThemeProvider.d.ts +29 -0
- package/dist/theme/index.d.ts +8 -0
- package/dist/theme/tokens.d.ts +17 -0
- package/dist/theme/types.d.ts +126 -0
- package/dist/theme/utils.d.ts +52 -0
- package/dist/ui-kit.css +1 -0
- package/dist/utils/scrollLock.d.ts +6 -0
- package/dist/utils/supportAdapter.d.ts +22 -0
- package/package.json +66 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Collapse Component
|
|
3
|
+
* MUI Collapse 대체 컴포넌트
|
|
4
|
+
*/
|
|
5
|
+
import React, { CSSProperties } from 'react';
|
|
6
|
+
interface CollapseProps {
|
|
7
|
+
children?: React.ReactNode;
|
|
8
|
+
className?: string;
|
|
9
|
+
in?: boolean;
|
|
10
|
+
timeout?: number | {
|
|
11
|
+
enter?: number;
|
|
12
|
+
exit?: number;
|
|
13
|
+
};
|
|
14
|
+
unmountOnExit?: boolean;
|
|
15
|
+
style?: CSSProperties;
|
|
16
|
+
sx?: Record<string, any>;
|
|
17
|
+
}
|
|
18
|
+
export declare const Collapse: React.FC<CollapseProps>;
|
|
19
|
+
export default Collapse;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Divider Component
|
|
3
|
+
* MUI Divider 대체 컴포넌트
|
|
4
|
+
*/
|
|
5
|
+
import React, { CSSProperties } from 'react';
|
|
6
|
+
interface DividerProps {
|
|
7
|
+
className?: string;
|
|
8
|
+
orientation?: 'horizontal' | 'vertical';
|
|
9
|
+
variant?: 'fullWidth' | 'inset' | 'middle';
|
|
10
|
+
flexItem?: boolean;
|
|
11
|
+
style?: CSSProperties;
|
|
12
|
+
sx?: Record<string, any>;
|
|
13
|
+
}
|
|
14
|
+
export declare const Divider: React.FC<DividerProps>;
|
|
15
|
+
export default Divider;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Grid Component
|
|
3
|
+
* MUI Grid v2 스타일 컴포넌트
|
|
4
|
+
* @see https://mui.com/material-ui/react-grid/
|
|
5
|
+
*/
|
|
6
|
+
import React, { CSSProperties } from 'react';
|
|
7
|
+
type ResponsiveSize = number | 'auto' | 'grow';
|
|
8
|
+
type ResponsiveSizeValue = ResponsiveSize | {
|
|
9
|
+
xs?: ResponsiveSize;
|
|
10
|
+
sm?: ResponsiveSize;
|
|
11
|
+
md?: ResponsiveSize;
|
|
12
|
+
lg?: ResponsiveSize;
|
|
13
|
+
xl?: ResponsiveSize;
|
|
14
|
+
};
|
|
15
|
+
type ResponsiveOffset = number | 'auto' | {
|
|
16
|
+
xs?: number | 'auto';
|
|
17
|
+
sm?: number | 'auto';
|
|
18
|
+
md?: number | 'auto';
|
|
19
|
+
lg?: number | 'auto';
|
|
20
|
+
xl?: number | 'auto';
|
|
21
|
+
};
|
|
22
|
+
interface GridProps {
|
|
23
|
+
children?: React.ReactNode;
|
|
24
|
+
className?: string;
|
|
25
|
+
/** Grid 컨테이너 여부 */
|
|
26
|
+
container?: boolean;
|
|
27
|
+
/** @deprecated MUI Grid v2에서는 item prop이 필요 없음 (하위 호환성을 위해 유지) */
|
|
28
|
+
item?: boolean;
|
|
29
|
+
/** 컬럼 크기 (1-12 또는 'auto', 'grow') */
|
|
30
|
+
size?: ResponsiveSizeValue;
|
|
31
|
+
/** 오프셋 (왼쪽 여백) */
|
|
32
|
+
offset?: ResponsiveOffset;
|
|
33
|
+
/** 아이템 간 간격 (spacingUnit 배수) */
|
|
34
|
+
spacing?: number;
|
|
35
|
+
/** 컬럼 수 (기본값: 12) */
|
|
36
|
+
columns?: number;
|
|
37
|
+
/** flex 방향 */
|
|
38
|
+
direction?: 'row' | 'column' | 'row-reverse' | 'column-reverse';
|
|
39
|
+
/** flex wrap */
|
|
40
|
+
wrap?: 'nowrap' | 'wrap' | 'wrap-reverse';
|
|
41
|
+
/** @deprecated MUI 호환성을 위해 유지 */
|
|
42
|
+
flexWrap?: 'nowrap' | 'wrap' | 'wrap-reverse';
|
|
43
|
+
/** 수직 정렬 */
|
|
44
|
+
alignItems?: 'flex-start' | 'center' | 'flex-end' | 'stretch' | 'baseline';
|
|
45
|
+
/** 수평 정렬 */
|
|
46
|
+
justifyContent?: 'flex-start' | 'center' | 'flex-end' | 'space-between' | 'space-around' | 'space-evenly';
|
|
47
|
+
style?: CSSProperties;
|
|
48
|
+
sx?: Record<string, any>;
|
|
49
|
+
}
|
|
50
|
+
export declare const Grid: React.FC<GridProps>;
|
|
51
|
+
export default Grid;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IconButton Component
|
|
3
|
+
* MUI IconButton 대체 컴포넌트
|
|
4
|
+
*/
|
|
5
|
+
import React, { CSSProperties } from 'react';
|
|
6
|
+
interface IconButtonProps {
|
|
7
|
+
children: React.ReactNode;
|
|
8
|
+
className?: string;
|
|
9
|
+
color?: 'default' | 'primary' | 'secondary' | 'error' | 'warning' | 'info' | 'success';
|
|
10
|
+
size?: 'small' | 'medium' | 'large';
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
onClick?: (e: React.MouseEvent<HTMLButtonElement>) => void;
|
|
13
|
+
type?: 'button' | 'submit' | 'reset';
|
|
14
|
+
'aria-label'?: string;
|
|
15
|
+
title?: string;
|
|
16
|
+
style?: CSSProperties;
|
|
17
|
+
sx?: Record<string, any>;
|
|
18
|
+
}
|
|
19
|
+
export declare const IconButton: React.FC<IconButtonProps>;
|
|
20
|
+
export default IconButton;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Paper Component
|
|
3
|
+
* MUI Paper 대체 컴포넌트
|
|
4
|
+
*/
|
|
5
|
+
import React, { CSSProperties } from 'react';
|
|
6
|
+
interface PaperProps {
|
|
7
|
+
children?: React.ReactNode;
|
|
8
|
+
className?: string;
|
|
9
|
+
elevation?: 'none' | 'sm' | 'md' | 'lg' | 'xl';
|
|
10
|
+
variant?: 'elevation' | 'outlined';
|
|
11
|
+
square?: boolean;
|
|
12
|
+
radius?: 'none' | 'sm' | 'md' | 'lg' | 'xl' | 'full' | string | number;
|
|
13
|
+
style?: CSSProperties;
|
|
14
|
+
sx?: Record<string, any>;
|
|
15
|
+
component?: keyof JSX.IntrinsicElements;
|
|
16
|
+
onClick?: (e: React.MouseEvent) => void;
|
|
17
|
+
}
|
|
18
|
+
export declare const Paper: React.FC<PaperProps>;
|
|
19
|
+
export default Paper;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Popper Component
|
|
3
|
+
* MUI Paper 대체 컴포넌트
|
|
4
|
+
*/
|
|
5
|
+
import React from 'react';
|
|
6
|
+
export type PopoverPosition = 'top' | 'top-start' | 'top-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'left' | 'left-start' | 'left-end' | 'right' | 'right-start' | 'right-end';
|
|
7
|
+
export interface PopoverProps {
|
|
8
|
+
open: boolean;
|
|
9
|
+
onClose: () => void;
|
|
10
|
+
onExited?: () => void;
|
|
11
|
+
anchorEl?: HTMLElement | null;
|
|
12
|
+
position?: PopoverPosition;
|
|
13
|
+
/** 뷰포트 밖이면 clamp(기본) vs 트리거 반대쪽으로 flip(메뉴가 트리거 덮음) */
|
|
14
|
+
overflowBehavior?: 'clamp' | 'flip';
|
|
15
|
+
/** 포탈 레이어 z-index (모달 위에 띄울 때 등) */
|
|
16
|
+
zIndex?: number;
|
|
17
|
+
children?: React.ReactNode;
|
|
18
|
+
className?: string;
|
|
19
|
+
}
|
|
20
|
+
export declare const Popover: React.FC<PopoverProps>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stack Component
|
|
3
|
+
* MUI Stack 대체 컴포넌트
|
|
4
|
+
*/
|
|
5
|
+
import React, { CSSProperties } from 'react';
|
|
6
|
+
interface StackProps {
|
|
7
|
+
children?: React.ReactNode;
|
|
8
|
+
className?: string;
|
|
9
|
+
direction?: 'row' | 'column' | 'row-reverse' | 'column-reverse';
|
|
10
|
+
spacing?: number | string;
|
|
11
|
+
alignItems?: 'flex-start' | 'center' | 'flex-end' | 'stretch' | 'baseline';
|
|
12
|
+
justifyContent?: 'flex-start' | 'center' | 'flex-end' | 'space-between' | 'space-around' | 'space-evenly';
|
|
13
|
+
style?: CSSProperties;
|
|
14
|
+
sx?: Record<string, any>;
|
|
15
|
+
}
|
|
16
|
+
export declare const Stack: React.FC<StackProps>;
|
|
17
|
+
export default Stack;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typography Component
|
|
3
|
+
* MUI Typography 대체 컴포넌트
|
|
4
|
+
*/
|
|
5
|
+
import React, { CSSProperties } from 'react';
|
|
6
|
+
interface TypographyProps {
|
|
7
|
+
children?: React.ReactNode;
|
|
8
|
+
className?: string;
|
|
9
|
+
variant?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'body1' | 'body2' | 'caption' | 'subtitle1' | 'subtitle2';
|
|
10
|
+
component?: keyof JSX.IntrinsicElements;
|
|
11
|
+
color?: 'primary' | 'secondary' | 'error' | 'warning' | 'info' | 'success' | 'text.primary' | 'text.secondary' | 'textSecondary';
|
|
12
|
+
gutterBottom?: boolean;
|
|
13
|
+
noWrap?: boolean;
|
|
14
|
+
display?: 'block' | 'inline' | 'inline-block';
|
|
15
|
+
align?: 'left' | 'center' | 'right' | 'justify';
|
|
16
|
+
style?: CSSProperties;
|
|
17
|
+
sx?: Record<string, any>;
|
|
18
|
+
}
|
|
19
|
+
export declare const Typography: React.FC<TypographyProps>;
|
|
20
|
+
export default Typography;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Common Components Export
|
|
3
|
+
* MUI 대체 컴포넌트들
|
|
4
|
+
*/
|
|
5
|
+
export { Box } from './Box';
|
|
6
|
+
export { Stack } from './Stack';
|
|
7
|
+
export { Grid } from './Grid';
|
|
8
|
+
export { Typography } from './Typography';
|
|
9
|
+
export { Button } from './Button';
|
|
10
|
+
export { IconButton } from './IconButton';
|
|
11
|
+
export { Divider } from './Divider';
|
|
12
|
+
export { Collapse } from './Collapse';
|
|
13
|
+
export { Paper } from './Paper';
|
|
14
|
+
export { Popover } from './Popover';
|
|
15
|
+
export { Info } from './Info';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { MfaConfig, PortalContainerGetter } from './UIProvider';
|
|
3
|
+
import type { ThemeConfig } from 'theme/types';
|
|
4
|
+
import 'styles/global.css';
|
|
5
|
+
interface GlobalUIProviderProps {
|
|
6
|
+
children: React.ReactNode;
|
|
7
|
+
themeConfig?: ThemeConfig;
|
|
8
|
+
mfaConfig?: MfaConfig;
|
|
9
|
+
portalContainer?: PortalContainerGetter;
|
|
10
|
+
/** Modal, Snackbar 등의 기본 z-index (기본값: 1300) */
|
|
11
|
+
baseZIndex?: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* UI 컴포넌트들을 사용하기 위한 통합 Provider.
|
|
15
|
+
* - QueryClientProvider + UIProvider + UIHost는 항상 추가(중첩 허용).
|
|
16
|
+
* - ThemeProvider는 상위에 theme 없을 때만 추가
|
|
17
|
+
* - portalContainer: 포탈 렌더 타깃. baseZIndex: 오버레이 기본 z-index(기본 1300). mfaConfig: MFA/팝업 설정.
|
|
18
|
+
*/
|
|
19
|
+
export declare function GlobalUIProvider({ children, themeConfig, mfaConfig, portalContainer, baseZIndex }: GlobalUIProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const UIHost: () => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { StoreApi } from 'zustand/vanilla';
|
|
3
|
+
import { type SnackbarState } from 'stores/createSnackbarStore';
|
|
4
|
+
import { type ModalState } from 'stores/createModalStore';
|
|
5
|
+
import { type ConfirmState } from 'stores/createConfirmStore';
|
|
6
|
+
type UIContextValue = {
|
|
7
|
+
snackbarStore: StoreApi<SnackbarState>;
|
|
8
|
+
modalStore: StoreApi<ModalState>;
|
|
9
|
+
confirmStore: StoreApi<ConfirmState>;
|
|
10
|
+
};
|
|
11
|
+
export type MfaConfig = {
|
|
12
|
+
enable?: boolean;
|
|
13
|
+
popupWidth?: number;
|
|
14
|
+
redirectUrl?: string;
|
|
15
|
+
hostWindow?: Window;
|
|
16
|
+
};
|
|
17
|
+
export type PortalContainerGetter = () => HTMLElement | null;
|
|
18
|
+
export type UIConfig = {
|
|
19
|
+
mfaConfig?: MfaConfig;
|
|
20
|
+
portalContainer?: PortalContainerGetter;
|
|
21
|
+
/** Modal, Snackbar 등의 기본 z-index (기본값: 1300) */
|
|
22
|
+
baseZIndex?: number;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Portal 컨테이너를 반환하는 hook
|
|
26
|
+
* 설정된 portalContainer가 없으면 document.body 반환
|
|
27
|
+
* host 앱에 MUI 등의 focus trap이 있는 presentation 컨테이너가 열려있으면
|
|
28
|
+
* 그 안에 렌더링하여 focus 호환성을 확보
|
|
29
|
+
*/
|
|
30
|
+
export declare const usePortalContainer: () => HTMLElement;
|
|
31
|
+
export declare const useUIConfig: () => UIConfig;
|
|
32
|
+
interface UIProviderProps {
|
|
33
|
+
children: React.ReactNode;
|
|
34
|
+
config?: UIConfig;
|
|
35
|
+
}
|
|
36
|
+
export declare const UIProvider: ({ children, config }: UIProviderProps) => import("react/jsx-runtime").JSX.Element;
|
|
37
|
+
export declare const useUIOptional: () => UIContextValue | null;
|
|
38
|
+
export declare const useUI: () => UIContextValue;
|
|
39
|
+
export declare const useSnackbarSelector: <T>(selector: (s: SnackbarState) => T) => T;
|
|
40
|
+
export declare const useModalSelector: <T>(selector: (s: ModalState) => T) => T;
|
|
41
|
+
export declare const useConfirmSelector: <T>(selector: (s: ConfirmState) => T) => T;
|
|
42
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { GlobalUIProvider } from './GlobalUIProvider';
|
|
2
|
+
export { useSnackbar } from 'hooks/useSnackbar';
|
|
3
|
+
export { useModal } from 'hooks/useModal';
|
|
4
|
+
export { useConfirm } from 'hooks/useConfirm';
|
|
5
|
+
export { useEnhancedMutation } from 'hooks/useEnhancedMutation';
|
|
6
|
+
export { default as MiniTabs } from 'components/MiniTabs';
|
|
7
|
+
export { default as Tabs } from 'components/Tabs';
|
|
8
|
+
export { default as Menu } from 'components/Menu';
|
|
9
|
+
export { default as ListFilter } from 'components/ListFilter';
|
|
10
|
+
export { default as TextInput } from 'components/TextInput';
|
|
11
|
+
export { DatePicker } from 'components/DatePicker';
|
|
12
|
+
export { type Theme, type ThemeMode, type ThemeConfig, type ThemeColors, type ThemeSpacing, type ThemeTypography, type ThemeBorderRadius, type ThemeShadows, type ThemeTransition, type ThemeBreakpoints, defaultTheme, lightColors, darkColors, ThemeProvider, useTheme, useThemeOptional, getCSSVariable, setCSSVariable, getThemeColor, getThemeSpacing, getThemeFontSize, getThemeBorderRadius, getThemeShadow, createTransition, mediaQuery, withAlpha, spacing } from 'theme/index';
|
|
13
|
+
export { Box, Stack, Grid, Typography, Button, Divider, Collapse, Paper, IconButton } from 'components/common';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React, { ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Module Federation 모듈에서 컴포넌트를 안전하게 로드
|
|
4
|
+
* 컴포넌트를 찾지 못한 경우 노란 경고 박스를 표시
|
|
5
|
+
*/
|
|
6
|
+
export declare const createSafeComponentLoader: <T = {
|
|
7
|
+
children?: ReactNode;
|
|
8
|
+
}>(moduleImport: () => Promise<any>, componentName: string) => React.FC<T>;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 원격 hook을 안전하게 로드하는 wrapper 생성
|
|
3
|
+
*
|
|
4
|
+
* 전제: createSafeProviderLoader가 로딩 완료까지 children을 렌더하지 않음
|
|
5
|
+
* → useSafeHook() 호출 시 모듈은 이미 캐시에 있거나, 실패로 확정된 상태
|
|
6
|
+
* → 캐시에서 동기 조회 후 원격 hook 또는 fallback 반환
|
|
7
|
+
*/
|
|
8
|
+
export declare const createSafeHookLoader: <T>(moduleImport: () => Promise<any>, hookName: string, fallback: T) => (() => T);
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { loadModuleSafely, getModuleFromCache, clearModuleCache, isModuleEmpty, findExportInModule } from './safeImport';
|
|
2
|
+
export { createSafeProviderLoader, type SafeProviderLoaderOptions } from './providerLoader';
|
|
3
|
+
export { createSafeComponentLoader } from './componentLoader';
|
|
4
|
+
export { createSafeHookLoader } from './hookLoader';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React, { ReactNode } from 'react';
|
|
2
|
+
export interface SafeProviderLoaderOptions {
|
|
3
|
+
warningMessage?: string;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Module Federation 모듈을 안전하게 로드하는 유틸 함수
|
|
7
|
+
* 모듈 로드 실패 시 전역 경고 배너를 표시하고 children을 렌더링
|
|
8
|
+
*/
|
|
9
|
+
export declare const createSafeProviderLoader: <T = {
|
|
10
|
+
children?: ReactNode;
|
|
11
|
+
}>(moduleImport: () => Promise<any>, componentName: string, options?: SafeProviderLoaderOptions) => React.FC<T>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 동적 import를 안전하게 실행하고 결과를 캐시
|
|
3
|
+
* - 로드 실패 시 빈 객체({})를 캐싱하여 재시도 방지
|
|
4
|
+
* - default export 래핑 자동 처리 (Module Federation 호환)
|
|
5
|
+
*/
|
|
6
|
+
export declare const loadModuleSafely: (moduleImport: () => Promise<any>) => Promise<any>;
|
|
7
|
+
/** 캐시에서 동기 조회 — hooks에서 사용 */
|
|
8
|
+
export declare const getModuleFromCache: (moduleImport: () => Promise<any>) => any | null;
|
|
9
|
+
/** 실패한 모듈 캐시를 제거하여 재시도 가능하게 함 */
|
|
10
|
+
export declare const clearModuleCache: (moduleImport?: () => Promise<any>) => void;
|
|
11
|
+
/** 모듈이 비어있는지 확인 (로드 실패 시 빈 객체가 캐싱됨) */
|
|
12
|
+
export declare const isModuleEmpty: (module: any) => boolean;
|
|
13
|
+
/** 모듈에서 named export를 찾아 반환, 없으면 에러 로깅 */
|
|
14
|
+
export declare const findExportInModule: (module: any, exportName: string, exportType: string) => any;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react/jsx-runtime"),l=require("react"),d=new Map,h=new Map,C=async e=>{const t=h.get(e);if(t)return t;const o=d.get(e);if(o)return o;const s=e().then(n=>{const c=n?.default||n;return d.set(e,c),c}).catch(n=>(console.error("모듈 로드 실패:",n),d.set(e,{}),{})).finally(()=>{h.delete(e)});return h.set(e,s),s},p=e=>d.get(e)??null,F=e=>{e?(d.delete(e),h.delete(e)):(d.clear(),h.clear())},M=e=>!e||Object.keys(e).length===0,y=(e,t,o)=>{if(!e)return;const n=(e?.default||e)?.[t]??e?.[t];return n||console.error(`[${t}] ${o}를 모듈에서 찾을 수 없습니다.`,"모듈 키:",Object.keys(e||{})),n},b=({message:e})=>r.jsxs("div",{style:{height:"43px",lineHeight:"41px",backgroundColor:"#feebec",color:"#cf3035",textAlign:"center",fontSize:"14px",fontWeight:500,borderBottom:"1px solid #cf3035",zIndex:1e4},children:["⚠️ ",e]}),k=(e,t,o={})=>{const{warningMessage:s}=o;return n=>{const[c,a]=l.useState(null),[S,g]=l.useState(!0),[x,i]=l.useState(!1),u=l.useRef(e);if(u.current=e,l.useEffect(()=>{C(u.current).then(f=>{if(M(f)){i(!0);return}const L=y(f,t,"모듈");L?a(()=>L):i(!0)}).finally(()=>g(!1))},[t]),S)return null;if(x){const f=n?.children;return r.jsxs(r.Fragment,{children:[s&&r.jsx(b,{message:s}),f&&r.jsx("div",{style:{paddingTop:"16px"},children:f})]})}if(c)return r.jsx(c,{...n});const j=n?.children;return j?r.jsx(r.Fragment,{children:j}):null}},v=({componentName:e,children:t})=>r.jsxs("div",{style:{padding:"16px",backgroundColor:"#fff3cd",border:"1px solid #ffc107",borderRadius:"4px"},children:[r.jsxs("p",{style:{fontWeight:500},children:["⚠️ ",e," 컴포넌트를 찾을 수 없습니다."]}),t]}),R=(e,t)=>o=>{const[s,n]=l.useState(null),[c,a]=l.useState(!0),[S,g]=l.useState(!1),x=l.useRef(e);if(x.current=e,l.useEffect(()=>{C(x.current).then(i=>{if(M(i)){g(!0);return}const u=y(i,t,"컴포넌트");u?n(()=>u):g(!0)}).finally(()=>a(!1))},[t]),c){const i=o?.children;return i?r.jsx(r.Fragment,{children:i}):null}if(S||!s){const i=o?.children;return r.jsx(v,{componentName:t,children:i})}return r.jsx(s,{...o})},E=(e,t,o)=>{let s=null,n=!1;return()=>{if(!n){const c=p(e);if(c&&(n=!0,!M(c))){const a=y(c,t,"hook");a&&typeof a=="function"&&(s=a)}}if(s)try{return s()}catch(c){return console.error(`[${t}] 원격 hook 호출 실패, fallback 사용:`,c),o}return o}};exports.clearModuleCache=F;exports.createSafeComponentLoader=R;exports.createSafeHookLoader=E;exports.createSafeProviderLoader=k;exports.findExportInModule=y;exports.getModuleFromCache=p;exports.isModuleEmpty=M;exports.loadModuleSafely=C;
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { jsxs as y, Fragment as M, jsx as l } from "react/jsx-runtime";
|
|
2
|
+
import { useState as d, useRef as F, useEffect as v } from "react";
|
|
3
|
+
const a = /* @__PURE__ */ new Map(), h = /* @__PURE__ */ new Map(), S = async (e) => {
|
|
4
|
+
const n = h.get(e);
|
|
5
|
+
if (n) return n;
|
|
6
|
+
const r = a.get(e);
|
|
7
|
+
if (r) return r;
|
|
8
|
+
const o = e().then((t) => {
|
|
9
|
+
const c = t?.default || t;
|
|
10
|
+
return a.set(e, c), c;
|
|
11
|
+
}).catch((t) => (console.error("모듈 로드 실패:", t), a.set(e, {}), {})).finally(() => {
|
|
12
|
+
h.delete(e);
|
|
13
|
+
});
|
|
14
|
+
return h.set(e, o), o;
|
|
15
|
+
}, j = (e) => a.get(e) ?? null, H = (e) => {
|
|
16
|
+
e ? (a.delete(e), h.delete(e)) : (a.clear(), h.clear());
|
|
17
|
+
}, L = (e) => !e || Object.keys(e).length === 0, p = (e, n, r) => {
|
|
18
|
+
if (!e) return;
|
|
19
|
+
const t = (e?.default || e)?.[n] ?? e?.[n];
|
|
20
|
+
return t || console.error(
|
|
21
|
+
`[${n}] ${r}를 모듈에서 찾을 수 없습니다.`,
|
|
22
|
+
"모듈 키:",
|
|
23
|
+
Object.keys(e || {})
|
|
24
|
+
), t;
|
|
25
|
+
}, R = ({ message: e }) => /* @__PURE__ */ y(
|
|
26
|
+
"div",
|
|
27
|
+
{
|
|
28
|
+
style: {
|
|
29
|
+
height: "43px",
|
|
30
|
+
lineHeight: "41px",
|
|
31
|
+
backgroundColor: "#feebec",
|
|
32
|
+
color: "#cf3035",
|
|
33
|
+
textAlign: "center",
|
|
34
|
+
fontSize: "14px",
|
|
35
|
+
fontWeight: 500,
|
|
36
|
+
borderBottom: "1px solid #cf3035",
|
|
37
|
+
zIndex: 1e4
|
|
38
|
+
},
|
|
39
|
+
children: [
|
|
40
|
+
"⚠️ ",
|
|
41
|
+
e
|
|
42
|
+
]
|
|
43
|
+
}
|
|
44
|
+
), P = (e, n, r = {}) => {
|
|
45
|
+
const { warningMessage: o } = r;
|
|
46
|
+
return (t) => {
|
|
47
|
+
const [c, i] = d(null), [C, g] = d(!0), [x, s] = d(!1), f = F(e);
|
|
48
|
+
if (f.current = e, v(() => {
|
|
49
|
+
S(f.current).then((u) => {
|
|
50
|
+
if (L(u)) {
|
|
51
|
+
s(!0);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const k = p(u, n, "모듈");
|
|
55
|
+
k ? i(() => k) : s(!0);
|
|
56
|
+
}).finally(() => g(!1));
|
|
57
|
+
}, [n]), C) return null;
|
|
58
|
+
if (x) {
|
|
59
|
+
const u = t?.children;
|
|
60
|
+
return /* @__PURE__ */ y(M, { children: [
|
|
61
|
+
o && /* @__PURE__ */ l(R, { message: o }),
|
|
62
|
+
u && /* @__PURE__ */ l("div", { style: { paddingTop: "16px" }, children: u })
|
|
63
|
+
] });
|
|
64
|
+
}
|
|
65
|
+
if (c) return /* @__PURE__ */ l(c, { ...t });
|
|
66
|
+
const b = t?.children;
|
|
67
|
+
return b ? /* @__PURE__ */ l(M, { children: b }) : null;
|
|
68
|
+
};
|
|
69
|
+
}, w = ({
|
|
70
|
+
componentName: e,
|
|
71
|
+
children: n
|
|
72
|
+
}) => /* @__PURE__ */ y("div", { style: {
|
|
73
|
+
padding: "16px",
|
|
74
|
+
backgroundColor: "#fff3cd",
|
|
75
|
+
border: "1px solid #ffc107",
|
|
76
|
+
borderRadius: "4px"
|
|
77
|
+
}, children: [
|
|
78
|
+
/* @__PURE__ */ y("p", { style: { fontWeight: 500 }, children: [
|
|
79
|
+
"⚠️ ",
|
|
80
|
+
e,
|
|
81
|
+
" 컴포넌트를 찾을 수 없습니다."
|
|
82
|
+
] }),
|
|
83
|
+
n
|
|
84
|
+
] }), T = (e, n) => (r) => {
|
|
85
|
+
const [o, t] = d(null), [c, i] = d(!0), [C, g] = d(!1), x = F(e);
|
|
86
|
+
if (x.current = e, v(() => {
|
|
87
|
+
S(x.current).then((s) => {
|
|
88
|
+
if (L(s)) {
|
|
89
|
+
g(!0);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const f = p(s, n, "컴포넌트");
|
|
93
|
+
f ? t(() => f) : g(!0);
|
|
94
|
+
}).finally(() => i(!1));
|
|
95
|
+
}, [n]), c) {
|
|
96
|
+
const s = r?.children;
|
|
97
|
+
return s ? /* @__PURE__ */ l(M, { children: s }) : null;
|
|
98
|
+
}
|
|
99
|
+
if (C || !o) {
|
|
100
|
+
const s = r?.children;
|
|
101
|
+
return /* @__PURE__ */ l(w, { componentName: n, children: s });
|
|
102
|
+
}
|
|
103
|
+
return /* @__PURE__ */ l(o, { ...r });
|
|
104
|
+
}, W = (e, n, r) => {
|
|
105
|
+
let o = null, t = !1;
|
|
106
|
+
return () => {
|
|
107
|
+
if (!t) {
|
|
108
|
+
const c = j(e);
|
|
109
|
+
if (c && (t = !0, !L(c))) {
|
|
110
|
+
const i = p(c, n, "hook");
|
|
111
|
+
i && typeof i == "function" && (o = i);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (o)
|
|
115
|
+
try {
|
|
116
|
+
return o();
|
|
117
|
+
} catch (c) {
|
|
118
|
+
return console.error(`[${n}] 원격 hook 호출 실패, fallback 사용:`, c), r;
|
|
119
|
+
}
|
|
120
|
+
return r;
|
|
121
|
+
};
|
|
122
|
+
};
|
|
123
|
+
export {
|
|
124
|
+
H as clearModuleCache,
|
|
125
|
+
T as createSafeComponentLoader,
|
|
126
|
+
W as createSafeHookLoader,
|
|
127
|
+
P as createSafeProviderLoader,
|
|
128
|
+
p as findExportInModule,
|
|
129
|
+
j as getModuleFromCache,
|
|
130
|
+
L as isModuleEmpty,
|
|
131
|
+
S as loadModuleSafely
|
|
132
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ConfirmProps } from 'stores/createConfirmStore';
|
|
2
|
+
export declare function useConfirm(): {
|
|
3
|
+
confirms: import("stores/createConfirmStore").Confirm[];
|
|
4
|
+
confirm: (props: ConfirmProps) => Promise<boolean>;
|
|
5
|
+
alert: (props: Omit<ConfirmProps, "alertMode">) => Promise<boolean>;
|
|
6
|
+
close: (id: string, result: boolean) => void;
|
|
7
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { UseMutationResult } from '@tanstack/react-query';
|
|
2
|
+
import { EnhancedMutationOptions } from '../lib/createMutationConfig';
|
|
3
|
+
/**
|
|
4
|
+
* useMutation을 감싸서 로그 기록, MFA 처리, 알림 기능을 제공하는 사용자 정의 훅.
|
|
5
|
+
* ui-kit 내부 전용 - Module Federation으로 외부 노출 시 createMutationConfig 사용.
|
|
6
|
+
*/
|
|
7
|
+
export declare function useEnhancedMutation<TData = unknown, TError = unknown, TVariables = void, TContext = unknown>(options?: EnhancedMutationOptions<TData, TError, TVariables, TContext>): UseMutationResult<TData, TError, TVariables, TContext>;
|
|
8
|
+
export default useEnhancedMutation;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ModalProps } from 'stores/createModalStore';
|
|
2
|
+
export declare function useModal(): {
|
|
3
|
+
modals: import("stores/createModalStore").Modal[];
|
|
4
|
+
openModal: (props: ModalProps) => Promise<boolean>;
|
|
5
|
+
closeModal: (id: string, result: boolean) => void;
|
|
6
|
+
closeAllModals: () => void;
|
|
7
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { SnackbarAction } from 'stores/createSnackbarStore';
|
|
2
|
+
type SnackbarOptions = {
|
|
3
|
+
duration?: number;
|
|
4
|
+
actions?: SnackbarAction[];
|
|
5
|
+
};
|
|
6
|
+
export declare function useSnackbar(): {
|
|
7
|
+
success: (msg: string, msOrOpts?: number | SnackbarOptions) => void;
|
|
8
|
+
info: (msg: string, msOrOpts?: number | SnackbarOptions) => void;
|
|
9
|
+
warning: (msg: string, msOrOpts?: number | SnackbarOptions) => void;
|
|
10
|
+
error: (msg: string, msOrOpts?: number | SnackbarOptions) => void;
|
|
11
|
+
};
|
|
12
|
+
export {};
|