@uniai-fe/next-providers 0.1.12 → 0.1.14
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 +1 -1
- package/package.json +1 -1
- package/src/NextRoots.tsx +2 -8
- package/src/index.tsx +1 -4
- package/src/lib/RuntimeRouteGuard.tsx +8 -21
- package/src/lib/RouterEventsDetector.tsx +0 -28
package/README.md
CHANGED
|
@@ -8,4 +8,4 @@
|
|
|
8
8
|
- `modalProviders` 슬롯을 통해 `@uniai-fe/ui-legacy`나 신규 `@uniai-fe/uds-*` 모달 Provider를 서비스 측에서 직접 주입한다.
|
|
9
9
|
- `onRouteChange` 콜백을 전달해 라우트 변경 시 모달 스택 초기화 등 앱 전용 부가 로직을 실행할 수 있다.
|
|
10
10
|
- `SetQueryCookie` — query string 기반 쿠키 동기화
|
|
11
|
-
- `RuntimeRouteGuard`
|
|
11
|
+
- `RuntimeRouteGuard` — 런타임 환경에 따라 `/mobile` 등 경로를 강제하거나 차단하는 가드 (disabled prop으로 토글)
|
package/package.json
CHANGED
package/src/NextRoots.tsx
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
import { Suspense } from "react";
|
|
2
|
-
|
|
3
1
|
import StyledComponentsRegistry from "./lib/StyledComponentsRegistry";
|
|
4
2
|
import AirtableProvider from "./provider/AirtableProvider";
|
|
5
3
|
import { JotaiProvider } from "./provider/JotaiProvider";
|
|
6
4
|
import { ReactQueryProvider } from "./provider/ReactQueryProvider";
|
|
7
|
-
import RouterEventDetector from "./lib/RouterEventsDetector";
|
|
8
5
|
import SetQueryCookie from "./lib/SetQueryCookie";
|
|
9
6
|
import SystemThemeChecker from "./lib/SystemThemeChecker";
|
|
10
7
|
import type { SystemLanguageType } from "@uniai-fe/next-devkit/types";
|
|
@@ -30,13 +27,13 @@ export default function NextRoots({
|
|
|
30
27
|
locale = "ko",
|
|
31
28
|
systemThemeOptions,
|
|
32
29
|
modalProviders,
|
|
33
|
-
|
|
30
|
+
|
|
34
31
|
children,
|
|
35
32
|
}: {
|
|
36
33
|
locale?: SystemLanguageType;
|
|
37
34
|
systemThemeOptions?: { exceptPaths: string[] };
|
|
38
35
|
modalProviders?: React.ReactNode;
|
|
39
|
-
|
|
36
|
+
|
|
40
37
|
children: React.ReactNode;
|
|
41
38
|
}) {
|
|
42
39
|
return (
|
|
@@ -49,9 +46,6 @@ export default function NextRoots({
|
|
|
49
46
|
{modalProviders}
|
|
50
47
|
</AirtableProvider>
|
|
51
48
|
<SystemThemeChecker exceptPaths={systemThemeOptions?.exceptPaths} />
|
|
52
|
-
<Suspense fallback={null}>
|
|
53
|
-
<RouterEventDetector onRouteChange={onRouteChange} />
|
|
54
|
-
</Suspense>
|
|
55
49
|
</StyledComponentsRegistry>
|
|
56
50
|
</JotaiProvider>
|
|
57
51
|
</ReactQueryProvider>
|
package/src/index.tsx
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
export {
|
|
2
|
-
RuntimeRouteGuard,
|
|
3
|
-
runtimeRouteRedirectAtom,
|
|
4
|
-
} from "./lib/RuntimeRouteGuard";
|
|
1
|
+
export { RuntimeRouteGuard } from "./lib/RuntimeRouteGuard";
|
|
5
2
|
|
|
6
3
|
export { default as NextRoots } from "./NextRoots";
|
|
7
4
|
export { default as SetQueryCookie } from "./lib/SetQueryCookie";
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { useEffect } from "react";
|
|
4
4
|
import { usePathname, useRouter } from "next/navigation";
|
|
5
|
-
import {
|
|
5
|
+
import { useAtomValue } from "jotai";
|
|
6
6
|
import {
|
|
7
7
|
runtimeEnvState,
|
|
8
8
|
type RuntimeEnvState,
|
|
@@ -23,15 +23,9 @@ export type RuntimeRouteConditions = Pick<
|
|
|
23
23
|
export interface RuntimeRouteGuardProps {
|
|
24
24
|
mobileBasePath?: string;
|
|
25
25
|
desktopFallbackPath?: string;
|
|
26
|
-
|
|
26
|
+
disabled?: boolean;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
/**
|
|
30
|
-
* 모바일 경로 리디렉션 on/off 상태를 제어하는 Jotai atom.
|
|
31
|
-
* @constant
|
|
32
|
-
*/
|
|
33
|
-
export const runtimeRouteRedirectAtom = atom(true);
|
|
34
|
-
|
|
35
29
|
const isMobilePath = (pathname?: string | null, basePath?: string): boolean =>
|
|
36
30
|
typeof pathname === "string" &&
|
|
37
31
|
typeof basePath === "string" &&
|
|
@@ -63,26 +57,26 @@ const shouldPreventMobilePath = (
|
|
|
63
57
|
* @param {RuntimeRouteGuardProps} props
|
|
64
58
|
* @param {string} [props.mobileBasePath="/mobile"] 모바일 PWA 화면 루트 경로
|
|
65
59
|
* @param {string} [props.desktopFallbackPath="/"] 모바일 접근 제한 시 이동할 데스크톱 경로
|
|
66
|
-
* @param {
|
|
60
|
+
* @param {boolean} [props.disabled=false] 강제 정책 비활성화 여부
|
|
67
61
|
* @example
|
|
68
62
|
* <RuntimeRouteGuard mobileBasePath="/mobile" desktopFallbackPath="/" />
|
|
69
63
|
* @desc
|
|
70
64
|
* - 모바일 standalone(PWA) 환경에서는 지정된 모바일 경로로 강제 이동한다.
|
|
71
65
|
* - 모바일 브라우저 환경(비 PWA)에서는 모바일 경로 접근을 막고 기본 경로로 전환한다.
|
|
72
|
-
* -
|
|
66
|
+
* - disabled 값을 이용해 개발 단계에서 정책을 손쉽게 토글할 수 있다.
|
|
73
67
|
*/
|
|
74
68
|
export function RuntimeRouteGuard({
|
|
75
69
|
mobileBasePath = DEFAULT_MOBILE_BASE_PATH,
|
|
76
70
|
desktopFallbackPath = DEFAULT_DESKTOP_FALLBACK_PATH,
|
|
77
|
-
|
|
71
|
+
disabled = false,
|
|
78
72
|
}: RuntimeRouteGuardProps = {}) {
|
|
79
73
|
const router = useRouter();
|
|
80
74
|
const pathname = usePathname();
|
|
81
75
|
const env = useAtomValue(runtimeEnvState);
|
|
82
|
-
const redirectEnabled = useAtomValue(redirectAtom);
|
|
83
76
|
|
|
84
77
|
useEffect(() => {
|
|
85
|
-
|
|
78
|
+
// disabled일 때는 정책을 잠시 비활성화
|
|
79
|
+
if (disabled) return;
|
|
86
80
|
if (typeof pathname !== "string") return;
|
|
87
81
|
|
|
88
82
|
if (shouldForceMobilePath(pathname, env, mobileBasePath)) {
|
|
@@ -93,14 +87,7 @@ export function RuntimeRouteGuard({
|
|
|
93
87
|
if (shouldPreventMobilePath(pathname, env, mobileBasePath)) {
|
|
94
88
|
router.replace(desktopFallbackPath);
|
|
95
89
|
}
|
|
96
|
-
}, [
|
|
97
|
-
desktopFallbackPath,
|
|
98
|
-
env,
|
|
99
|
-
mobileBasePath,
|
|
100
|
-
pathname,
|
|
101
|
-
redirectEnabled,
|
|
102
|
-
router,
|
|
103
|
-
]);
|
|
90
|
+
}, [desktopFallbackPath, env, mobileBasePath, pathname, disabled, router]);
|
|
104
91
|
|
|
105
92
|
return null;
|
|
106
93
|
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import { usePathname } from "next/navigation";
|
|
4
|
-
import { useEffect } from "react";
|
|
5
|
-
|
|
6
|
-
export interface RouterEventDetectorProps {
|
|
7
|
-
onRouteChange?: () => void;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* 경로 변경 이벤트 감지 훅
|
|
12
|
-
* @component
|
|
13
|
-
* @param {RouterEventDetectorProps} props
|
|
14
|
-
* @param {() => void} [props.onRouteChange] 경로 변경 시 실행할 콜백
|
|
15
|
-
* @desc
|
|
16
|
-
* - 최상위 layout에서 경로 변경을 감지하고, 전달된 콜백을 실행한다.
|
|
17
|
-
*/
|
|
18
|
-
export default function RouterEventDetector({
|
|
19
|
-
onRouteChange,
|
|
20
|
-
}: RouterEventDetectorProps = {}) {
|
|
21
|
-
const pathname = usePathname();
|
|
22
|
-
|
|
23
|
-
useEffect(() => {
|
|
24
|
-
onRouteChange?.();
|
|
25
|
-
}, [onRouteChange, pathname]);
|
|
26
|
-
|
|
27
|
-
return null;
|
|
28
|
-
}
|