@modastar/z-router 0.0.4 → 0.0.6
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/index.cjs +11 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -1
- package/package.json +17 -3
- package/vite.config.ts +10 -0
package/dist/index.cjs
CHANGED
|
@@ -24,6 +24,7 @@ __export(index_exports, {
|
|
|
24
24
|
LocationContext: () => LocationContext,
|
|
25
25
|
LocationProvider: () => LocationProvider,
|
|
26
26
|
PageRenderer: () => PageRenderer,
|
|
27
|
+
RedirectError: () => RedirectError,
|
|
27
28
|
RouteComponent: () => RouteComponent,
|
|
28
29
|
RouteContext: () => RouteContext,
|
|
29
30
|
RouterContext: () => RouterContext,
|
|
@@ -506,12 +507,22 @@ var StackComponent = () => {
|
|
|
506
507
|
var Stack = ({ rootRoute }) => {
|
|
507
508
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(RouteProvider, { rootRoute, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(StackComponent, {}) });
|
|
508
509
|
};
|
|
510
|
+
|
|
511
|
+
// src/types.d.ts
|
|
512
|
+
var RedirectError = class extends Error {
|
|
513
|
+
options;
|
|
514
|
+
constructor(options) {
|
|
515
|
+
super();
|
|
516
|
+
this.options = options;
|
|
517
|
+
}
|
|
518
|
+
};
|
|
509
519
|
// Annotate the CommonJS export names for ESM import in node:
|
|
510
520
|
0 && (module.exports = {
|
|
511
521
|
DefaultTransitionDuration,
|
|
512
522
|
LocationContext,
|
|
513
523
|
LocationProvider,
|
|
514
524
|
PageRenderer,
|
|
525
|
+
RedirectError,
|
|
515
526
|
RouteComponent,
|
|
516
527
|
RouteContext,
|
|
517
528
|
RouterContext,
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/context/locationContext.ts","../src/components/locationProvider.tsx","../src/components/routeComponent.tsx","../src/hooks/useRouter.ts","../src/context/routerContext.ts","../src/components/routerProvider.tsx","../src/utils.ts","../src/components/stack.tsx","../src/hooks/useLocation.ts","../src/hooks/useRoute.ts","../src/context/routeContext.ts","../src/hooks/useMatches.ts","../src/components/routeProvider.tsx"],"sourcesContent":["export * from \"./components/index.js\";\nexport * from \"./context/index.js\";\nexport * from \"./hooks/index.js\";\nexport * from \"./utils.js\";\n","import { createContext } from \"react\";\n\nimport type { Location } from \"@/types.js\";\n\nexport const LocationContext = createContext<Location | null>(null);\n","import { LocationContext } from \"@/context/locationContext.js\";\nimport type { Location } from \"@/types.js\";\n\nexport const LocationProvider = ({\n location,\n children,\n}: {\n location: Location;\n children: React.ReactNode;\n}) => {\n return (\n <LocationContext.Provider value={location}>\n {children}\n </LocationContext.Provider>\n );\n};\n","import { useEffect, useState } from \"react\";\n\nimport { useRouter } from \"@/hooks/useRouter.js\";\nimport type { Route } from \"@/types.js\";\n\nexport const RouteComponent = ({\n route,\n children,\n}: {\n route: Route;\n children?: React.ReactNode;\n}) => {\n const router = useRouter();\n const [pending, setPending] = useState(!!route.beforeLoad);\n\n useEffect(() => {\n if (route.beforeLoad) {\n route\n .beforeLoad({ location: router.location! })\n .catch((error: unknown) => {\n if (\n error instanceof Error &&\n typeof error.cause === \"object\" &&\n error.cause !== null &&\n \"to\" in error.cause\n ) {\n router.navigate({\n to: (error.cause as any).to,\n replace: (error.cause as any).replace,\n });\n }\n })\n .finally(() => setPending(false));\n }\n }, []);\n\n if (pending) {\n const PendingComponent = route.pendingComponent!;\n return <PendingComponent />;\n }\n\n const Component = route.component;\n return Component ? <Component>{children}</Component> : children;\n};\n","import { useContext } from \"react\";\n\nimport { RouterContext } from \"@/context/routerContext.js\";\n\nexport const useRouter = () => {\n const router = useContext(RouterContext);\n if (router === null) {\n throw new Error(\"useRouter must be used within a Stack\");\n }\n return router;\n};\n","import { createContext } from \"react\";\n\nimport type {\n BackOptions,\n ForwardOptions,\n Location,\n NavigateOptions,\n RouterOptions,\n} from \"@/types.js\";\n\nexport interface RouterContextType {\n // Router Config\n options: RouterOptions;\n\n // Navigation State\n history: Location[];\n currentLocationIndex: number;\n location: Location | null;\n canGoBack: boolean;\n canGoForward: boolean;\n\n // Transition state\n isTransitioning: boolean;\n transitionDuration: number;\n transitioningToIndex: number | null;\n\n // Actions\n navigate: (options: NavigateOptions) => void;\n back: (options: BackOptions) => void;\n forward: (options: ForwardOptions) => void;\n}\n\nexport const RouterContext = createContext<RouterContextType | null>(null);\n","import { useCallback, useEffect, useState } from \"react\";\n\nimport { RouterContext } from \"@/context/routerContext.js\";\nimport type {\n BackOptions,\n ForwardOptions,\n Location,\n NavigateOptions,\n RouterOptions,\n} from \"@/types.js\";\nimport { DefaultTransitionDuration } from \"@/utils.js\";\n\nexport const RouterProvider = ({\n router,\n children,\n}: {\n router: RouterOptions;\n children: React.ReactNode;\n}) => {\n const [history, setHistory] = useState<Location[]>([]);\n const [currentLocationIndex, setCurrentLocationIndex] = useState<number>(-1);\n const [isTransitioning, setIsTransitioning] = useState<boolean>(false);\n const [transitionDuration, setTransitionDuration] = useState<number>(\n DefaultTransitionDuration\n );\n const [transitioningToIndex, setTransitioningToIndex] = useState<\n number | null\n >(null);\n\n const navigate = useCallback(\n ({\n to,\n replace,\n transition,\n duration,\n updateHistory,\n onFinish,\n ...locationOptions\n }: NavigateOptions) => {\n if (isTransitioning) return;\n const newLocationIndex = replace\n ? currentLocationIndex\n : currentLocationIndex + 1;\n const newLocation: Location = {\n index: newLocationIndex,\n params: {},\n query: {},\n state: new Map(),\n pathname: to,\n ...locationOptions,\n };\n if (newLocationIndex === history.length) {\n setHistory([...history, newLocation]);\n } else {\n setHistory((prevHistory) => {\n const newHistory = [...prevHistory];\n newHistory[newLocationIndex] = newLocation;\n return newHistory.slice(0, currentLocationIndex + 2);\n });\n }\n if (\n !replace &&\n currentLocationIndex >= 0 &&\n (transition ??\n router.defaultViewTransition?.(\n history.at(currentLocationIndex),\n history.at(newLocationIndex)\n ))\n ) {\n const currentDuration = duration ?? DefaultTransitionDuration;\n setIsTransitioning(true);\n setTransitionDuration(currentDuration);\n setTransitioningToIndex(newLocationIndex);\n setTimeout(() => {\n setIsTransitioning(false);\n setTransitioningToIndex(null);\n setCurrentLocationIndex(newLocationIndex);\n onFinish?.();\n if (updateHistory) {\n window.history.pushState({}, \"\", to);\n }\n }, currentDuration);\n } else if (!replace) {\n setCurrentLocationIndex(newLocationIndex);\n if (updateHistory) {\n window.history.pushState({}, \"\", to);\n }\n } else if (updateHistory) {\n window.history.replaceState({}, \"\", to);\n }\n },\n [currentLocationIndex, history, isTransitioning, router]\n );\n\n useEffect(() => {\n console.log(\"Navigate: History updated:\", history);\n }, [history]);\n\n const back = useCallback(\n (options: BackOptions) => {\n if (isTransitioning) return;\n const newLocationIndex = currentLocationIndex - (options?.depth ?? 1);\n if (\n currentLocationIndex > 0 &&\n (options?.transition ??\n router.defaultViewTransition?.(\n history.at(currentLocationIndex),\n history.at(newLocationIndex)\n ))\n ) {\n const currentDuration = options?.duration ?? DefaultTransitionDuration;\n setIsTransitioning(true);\n setTransitionDuration(currentDuration);\n setTransitioningToIndex(newLocationIndex);\n setTimeout(() => {\n setIsTransitioning(false);\n setTransitioningToIndex(null);\n setCurrentLocationIndex(newLocationIndex);\n options?.onFinish?.();\n }, currentDuration);\n } else {\n setCurrentLocationIndex(newLocationIndex);\n }\n },\n [currentLocationIndex, history, isTransitioning, router]\n );\n\n const forward = useCallback(\n (options: ForwardOptions) => {\n if (isTransitioning) return;\n const newLocationIndex = currentLocationIndex + 1;\n if (\n newLocationIndex < history.length &&\n (options?.transition ??\n router.defaultViewTransition?.(\n history.at(currentLocationIndex),\n history.at(newLocationIndex)\n ))\n ) {\n const duration = options?.duration ?? DefaultTransitionDuration;\n setIsTransitioning(true);\n setTransitionDuration(duration);\n setTransitioningToIndex(newLocationIndex);\n setTimeout(() => {\n setIsTransitioning(false);\n setTransitioningToIndex(null);\n setCurrentLocationIndex(newLocationIndex);\n options?.onFinish?.();\n }, duration);\n } else {\n setCurrentLocationIndex(newLocationIndex);\n }\n },\n [currentLocationIndex, history, isTransitioning, router]\n );\n\n return (\n <RouterContext.Provider\n value={{\n options: router,\n\n history,\n currentLocationIndex,\n location: history.at(currentLocationIndex) || null,\n canGoBack: currentLocationIndex > 0,\n canGoForward: currentLocationIndex < history.length - 1,\n\n isTransitioning,\n transitionDuration,\n transitioningToIndex,\n\n navigate,\n back,\n forward,\n }}\n >\n {children}\n </RouterContext.Provider>\n );\n};\n","import type { Location, RootRoute, Route, RouterOptions } from \"./types.js\";\n\nexport const DefaultTransitionDuration = 300;\n\nexport const redirect = (options: { to: string; replace?: boolean }) => {\n return new Error(\"\", { cause: options });\n};\n\nexport const matchUrl = (\n pattern: string,\n url: string\n): { params: Record<string, string>; query: Record<string, string> } | null => {\n try {\n // 解析 URL\n let pathname, searchParams;\n\n if (url.startsWith(\"http://\") || url.startsWith(\"https://\")) {\n const urlObj = new URL(url);\n pathname = urlObj.pathname;\n searchParams = urlObj.searchParams;\n } else {\n // 處理相對路徑\n const [path, queryString] = url.split(\"?\");\n if (!path) {\n return null;\n }\n pathname = path;\n searchParams = new URLSearchParams(queryString || \"\");\n }\n\n // 移除路徑首尾的斜線以便比較\n const cleanPath = pathname.replaceAll(/^\\/|\\/$/g, \"\");\n const cleanPattern = pattern.replaceAll(/^\\/|\\/$/g, \"\");\n\n // 分割路徑段\n const pathSegments = cleanPath.split(\"/\");\n const patternSegments = cleanPattern.split(\"/\");\n\n // 路徑段數量不同則不匹配\n if (pathSegments.length !== patternSegments.length) {\n return null;\n }\n\n // 提取路徑參數\n const params: Record<string, string> = {};\n for (let i = 0; i < patternSegments.length; i++) {\n const patternSegment = patternSegments[i];\n const pathSegment = pathSegments[i];\n\n if (patternSegment.startsWith(\":\")) {\n // 動態參數\n const paramName = patternSegment.slice(1);\n params[paramName] = decodeURIComponent(pathSegment);\n } else if (patternSegment !== pathSegment) {\n // 靜態段不匹配\n return null;\n }\n }\n\n // 提取查詢參數\n const query = Object.fromEntries(searchParams.entries());\n\n return { params, query };\n } catch {\n return null;\n }\n};\n\nexport const matchRoute = (\n rootRoute: RootRoute,\n url: string\n): {\n matches: Route[];\n params: Record<string, string>;\n query: Record<string, string>;\n} | null => {\n const _matchRoute = (\n matches: Route[],\n route: Route\n ): {\n matches: Route[];\n params: Record<string, string>;\n query: Record<string, string>;\n } | null => {\n if (route.children) {\n for (const childRoute of route.children) {\n const matchesResult = _matchRoute([...matches, childRoute], childRoute);\n if (matchesResult) {\n return matchesResult;\n }\n }\n return null;\n }\n\n let pattern = \"\";\n for (const match of matches) {\n if (match.pathname === undefined) continue;\n pattern += `/${match.pathname}`;\n }\n const result = matchUrl(pattern, url);\n if (result) {\n return { matches, ...result };\n }\n return null;\n };\n\n return _matchRoute([], rootRoute);\n};\n\nexport const parseLocationFromHref = (\n rootRoute: RootRoute,\n to: string\n): Pick<Location, \"pathname\" | \"params\" | \"query\"> | null => {\n const result = matchRoute(rootRoute, to);\n if (!result) return null;\n return {\n pathname: to,\n params: result.params,\n query: result.query,\n };\n};\n\nexport const createRouter = (options: RouterOptions): RouterOptions => {\n return options;\n};\n","import { useEffect, useState } from \"react\";\n\nimport { useMatches } from \"@/hooks/useMatches.js\";\nimport { useRoute } from \"@/hooks/useRoute.js\";\nimport { useRouter } from \"@/hooks/useRouter.js\";\nimport type { RootRoute } from \"@/types.js\";\n\nimport { LocationProvider } from \"./locationProvider.js\";\nimport { RouteComponent } from \"./routeComponent.js\";\nimport { RouteProvider } from \"./routeProvider.js\";\n\nexport const PageRenderer = () => {\n const route = useRoute();\n const matches = useMatches();\n if (!matches || matches.length === 0) {\n const NotFoundComponent = route.notFoundComponent!;\n return <NotFoundComponent />;\n }\n let content: React.ReactNode = null;\n for (let i = matches.length - 1; i >= 0; i--) {\n const route = matches[i];\n content = <RouteComponent route={route}>{content}</RouteComponent>;\n }\n return content;\n};\n\nconst StackComponent = () => {\n const {\n history,\n currentLocationIndex,\n canGoBack,\n canGoForward,\n isTransitioning,\n transitioningToIndex,\n transitionDuration,\n back,\n forward,\n } = useRouter();\n\n const [isDragging, setIsDragging] = useState(false);\n const [startX, setStartX] = useState(0);\n const [dragOffset, setDragOffset] = useState(0);\n const [isCanceling, setIsCanceling] = useState(false);\n const [isTransitionStarted, setIsTransitionStarted] = useState(false);\n\n useEffect(() => {\n if (!isTransitioning || transitioningToIndex === null) return;\n setIsTransitionStarted(true);\n setTimeout(() => {\n setIsTransitionStarted(false);\n }, transitionDuration);\n }, [isTransitioning, transitioningToIndex]);\n\n const reset = () => {\n setIsDragging(false);\n setDragOffset(0);\n setIsCanceling(false);\n };\n\n const handleTouchStart = (e: React.TouchEvent) => {\n if (isTransitioning || (!canGoForward && !canGoBack)) return;\n setIsDragging(true);\n setStartX(e.touches[0].clientX);\n };\n\n const handleTouchMove = (e: React.TouchEvent) => {\n if (!isDragging) return;\n const offset = e.touches[0].clientX - startX;\n if (\n (offset > 0 && currentLocationIndex === 0) ||\n (offset < 0 && currentLocationIndex + 1 === history.length)\n ) {\n setDragOffset(0);\n return;\n }\n setDragOffset(Math.min(window.innerWidth, offset));\n };\n\n const handleTouchEnd = () => {\n if (!isDragging) return;\n\n if (dragOffset > window.innerWidth * 0.3 && canGoBack) {\n back({\n onFinish: reset,\n });\n } else if (dragOffset < -window.innerWidth * 0.3 && canGoForward) {\n forward({\n onFinish: reset,\n });\n } else {\n setIsCanceling(true);\n setTimeout(reset, transitionDuration);\n }\n };\n\n return (\n <div className=\"relative inset-0 h-full w-full overflow-hidden\">\n {currentLocationIndex >= 1 && (\n <div className=\"absolute inset-0 -z-10\">\n <LocationProvider location={history.at(currentLocationIndex - 1)!}>\n <PageRenderer key={currentLocationIndex - 1} />\n </LocationProvider>\n </div>\n )}\n <div\n key={currentLocationIndex}\n className=\"bg-background absolute inset-0 overflow-hidden\"\n style={{\n transform:\n isTransitioning &&\n transitioningToIndex !== null &&\n transitioningToIndex < currentLocationIndex\n ? `translateX(100%)`\n : isDragging && dragOffset > 0 && !isCanceling\n ? `translateX(${dragOffset}px)`\n : \"translateX(0px)\",\n transition:\n isCanceling ||\n (isTransitioning &&\n transitioningToIndex !== null &&\n transitioningToIndex < currentLocationIndex)\n ? `transform ${transitionDuration}ms ease-out`\n : \"\",\n boxShadow:\n isDragging && dragOffset > 0\n ? \"-4px 0 8px rgba(0,0,0,0.1)\"\n : \"none\",\n }}\n onTouchStart={handleTouchStart}\n onTouchMove={handleTouchMove}\n onTouchEnd={handleTouchEnd}\n >\n <LocationProvider location={history.at(currentLocationIndex)!}>\n <PageRenderer key={currentLocationIndex} />\n </LocationProvider>\n </div>\n {((isDragging && dragOffset < 0) ||\n (isTransitioning &&\n transitioningToIndex !== null &&\n currentLocationIndex < transitioningToIndex)) && (\n <div\n key={transitioningToIndex}\n className=\"bg-background absolute inset-0 z-10 overflow-hidden transition-transform ease-in\"\n style={{\n transform: isTransitionStarted\n ? `translateX(0px)`\n : isDragging && !isCanceling\n ? `translateX(${window.innerWidth + dragOffset}px)`\n : \"translateX(100%)\",\n transitionDuration:\n isTransitioning || isCanceling\n ? `${transitionDuration}ms`\n : \"0ms\",\n }}\n >\n <LocationProvider\n location={\n isDragging\n ? history.at(currentLocationIndex + 1)!\n : history.at(transitioningToIndex!)!\n }\n >\n <PageRenderer key={transitioningToIndex} />\n </LocationProvider>\n </div>\n )}\n </div>\n );\n};\n\nexport const Stack = ({ rootRoute }: { rootRoute: RootRoute }) => {\n return (\n <RouteProvider rootRoute={rootRoute}>\n <StackComponent />\n </RouteProvider>\n );\n};\n","import { useContext } from \"react\";\n\nimport { LocationContext } from \"@/context/locationContext.js\";\n\nexport const useLocation = () => {\n const context = useContext(LocationContext);\n if (context === null) {\n throw new Error(\"useLocation must be used within a LocationProvider\");\n }\n return context;\n};\n","import { useContext } from \"react\";\n\nimport { RouteContext } from \"@/context/routeContext.js\";\n\nexport const useRoute = () => {\n const route = useContext(RouteContext);\n if (route === null) {\n throw new Error(\"useRoute must be used within a RouteProvider\");\n }\n return route;\n};\n","import { createContext } from \"react\";\n\nimport type { RootRoute } from \"@/types.js\";\n\nexport const RouteContext = createContext<RootRoute | null>(null);\n","import { matchRoute } from \"@/utils.js\";\n\nimport { useLocation } from \"./useLocation.js\";\nimport { useRoute } from \"./useRoute.js\";\n\nexport const useMatches = () => {\n const route = useRoute();\n const location = useLocation();\n if (!location) return [];\n return matchRoute(route, location.pathname)?.matches || [];\n};\n","import { useEffect } from \"react\";\n\nimport { RouteContext } from \"@/context/routeContext.js\";\nimport { useRouter } from \"@/hooks/useRouter.js\";\nimport type { RootRoute } from \"@/types.js\";\nimport { parseLocationFromHref } from \"@/utils.js\";\n\nexport const RouteProvider = ({\n rootRoute,\n children,\n}: {\n rootRoute: RootRoute;\n children: React.ReactNode;\n}) => {\n const router = useRouter();\n\n useEffect(() => {\n const currentLocation = parseLocationFromHref(\n rootRoute,\n window.location.href\n );\n if (!currentLocation) return;\n router.navigate({\n to: currentLocation.pathname,\n params: currentLocation.params,\n query: currentLocation.query,\n });\n return () => {\n router.back();\n };\n }, []);\n\n return (\n <RouteContext.Provider value={rootRoute}>{children}</RouteContext.Provider>\n );\n};\n"],"mappings":"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","names":["import_react","import_react","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_react","import_react","import_react","import_react","import_jsx_runtime","import_jsx_runtime","route"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/context/locationContext.ts","../src/components/locationProvider.tsx","../src/components/routeComponent.tsx","../src/hooks/useRouter.ts","../src/context/routerContext.ts","../src/components/routerProvider.tsx","../src/utils.ts","../src/components/stack.tsx","../src/hooks/useLocation.ts","../src/hooks/useRoute.ts","../src/context/routeContext.ts","../src/hooks/useMatches.ts","../src/components/routeProvider.tsx","../src/types.d.ts"],"sourcesContent":["export * from \"./components/index.js\";\nexport * from \"./context/index.js\";\nexport * from \"./hooks/index.js\";\nexport * from \"./types.d.js\";\nexport * from \"./utils.js\";\n","import { createContext } from \"react\";\n\nimport type { Location } from \"@/types.js\";\n\nexport const LocationContext = createContext<Location | null>(null);\n","import { LocationContext } from \"@/context/locationContext.js\";\nimport type { Location } from \"@/types.js\";\n\nexport const LocationProvider = ({\n location,\n children,\n}: {\n location: Location;\n children: React.ReactNode;\n}) => {\n return (\n <LocationContext.Provider value={location}>\n {children}\n </LocationContext.Provider>\n );\n};\n","import { useEffect, useState } from \"react\";\n\nimport { useRouter } from \"@/hooks/useRouter.js\";\nimport type { Route } from \"@/types.js\";\n\nexport const RouteComponent = ({\n route,\n children,\n}: {\n route: Route;\n children?: React.ReactNode;\n}) => {\n const router = useRouter();\n const [pending, setPending] = useState(!!route.beforeLoad);\n\n useEffect(() => {\n if (route.beforeLoad) {\n route\n .beforeLoad({ location: router.location! })\n .catch((error: unknown) => {\n if (\n error instanceof Error &&\n typeof error.cause === \"object\" &&\n error.cause !== null &&\n \"to\" in error.cause\n ) {\n router.navigate({\n to: (error.cause as any).to,\n replace: (error.cause as any).replace,\n });\n }\n })\n .finally(() => setPending(false));\n }\n }, []);\n\n if (pending) {\n const PendingComponent = route.pendingComponent!;\n return <PendingComponent />;\n }\n\n const Component = route.component;\n return Component ? <Component>{children}</Component> : children;\n};\n","import { useContext } from \"react\";\n\nimport { RouterContext } from \"@/context/routerContext.js\";\n\nexport const useRouter = () => {\n const router = useContext(RouterContext);\n if (router === null) {\n throw new Error(\"useRouter must be used within a Stack\");\n }\n return router;\n};\n","import { createContext } from \"react\";\n\nimport type {\n BackOptions,\n ForwardOptions,\n Location,\n NavigateOptions,\n RouterOptions,\n} from \"@/types.js\";\n\nexport interface RouterContextType {\n // Router Config\n options: RouterOptions;\n\n // Navigation State\n history: Location[];\n currentLocationIndex: number;\n location: Location | null;\n canGoBack: boolean;\n canGoForward: boolean;\n\n // Transition state\n isTransitioning: boolean;\n transitionDuration: number;\n transitioningToIndex: number | null;\n\n // Actions\n navigate: (options: NavigateOptions) => void;\n back: (options: BackOptions) => void;\n forward: (options: ForwardOptions) => void;\n}\n\nexport const RouterContext = createContext<RouterContextType | null>(null);\n","import { useCallback, useEffect, useState } from \"react\";\n\nimport { RouterContext } from \"@/context/routerContext.js\";\nimport type {\n BackOptions,\n ForwardOptions,\n Location,\n NavigateOptions,\n RouterOptions,\n} from \"@/types.js\";\nimport { DefaultTransitionDuration } from \"@/utils.js\";\n\nexport const RouterProvider = ({\n router,\n children,\n}: {\n router: RouterOptions;\n children: React.ReactNode;\n}) => {\n const [history, setHistory] = useState<Location[]>([]);\n const [currentLocationIndex, setCurrentLocationIndex] = useState<number>(-1);\n const [isTransitioning, setIsTransitioning] = useState<boolean>(false);\n const [transitionDuration, setTransitionDuration] = useState<number>(\n DefaultTransitionDuration\n );\n const [transitioningToIndex, setTransitioningToIndex] = useState<\n number | null\n >(null);\n\n const navigate = useCallback(\n ({\n to,\n replace,\n transition,\n duration,\n updateHistory,\n onFinish,\n ...locationOptions\n }: NavigateOptions) => {\n if (isTransitioning) return;\n const newLocationIndex = replace\n ? currentLocationIndex\n : currentLocationIndex + 1;\n const newLocation: Location = {\n index: newLocationIndex,\n params: {},\n query: {},\n state: new Map(),\n pathname: to,\n ...locationOptions,\n };\n if (newLocationIndex === history.length) {\n setHistory([...history, newLocation]);\n } else {\n setHistory((prevHistory) => {\n const newHistory = [...prevHistory];\n newHistory[newLocationIndex] = newLocation;\n return newHistory.slice(0, currentLocationIndex + 2);\n });\n }\n if (\n !replace &&\n currentLocationIndex >= 0 &&\n (transition ??\n router.defaultViewTransition?.(\n history.at(currentLocationIndex),\n history.at(newLocationIndex)\n ))\n ) {\n const currentDuration = duration ?? DefaultTransitionDuration;\n setIsTransitioning(true);\n setTransitionDuration(currentDuration);\n setTransitioningToIndex(newLocationIndex);\n setTimeout(() => {\n setIsTransitioning(false);\n setTransitioningToIndex(null);\n setCurrentLocationIndex(newLocationIndex);\n onFinish?.();\n if (updateHistory) {\n window.history.pushState({}, \"\", to);\n }\n }, currentDuration);\n } else if (!replace) {\n setCurrentLocationIndex(newLocationIndex);\n if (updateHistory) {\n window.history.pushState({}, \"\", to);\n }\n } else if (updateHistory) {\n window.history.replaceState({}, \"\", to);\n }\n },\n [currentLocationIndex, history, isTransitioning, router]\n );\n\n useEffect(() => {\n console.log(\"Navigate: History updated:\", history);\n }, [history]);\n\n const back = useCallback(\n (options: BackOptions) => {\n if (isTransitioning) return;\n const newLocationIndex = currentLocationIndex - (options?.depth ?? 1);\n if (\n currentLocationIndex > 0 &&\n (options?.transition ??\n router.defaultViewTransition?.(\n history.at(currentLocationIndex),\n history.at(newLocationIndex)\n ))\n ) {\n const currentDuration = options?.duration ?? DefaultTransitionDuration;\n setIsTransitioning(true);\n setTransitionDuration(currentDuration);\n setTransitioningToIndex(newLocationIndex);\n setTimeout(() => {\n setIsTransitioning(false);\n setTransitioningToIndex(null);\n setCurrentLocationIndex(newLocationIndex);\n options?.onFinish?.();\n }, currentDuration);\n } else {\n setCurrentLocationIndex(newLocationIndex);\n }\n },\n [currentLocationIndex, history, isTransitioning, router]\n );\n\n const forward = useCallback(\n (options: ForwardOptions) => {\n if (isTransitioning) return;\n const newLocationIndex = currentLocationIndex + 1;\n if (\n newLocationIndex < history.length &&\n (options?.transition ??\n router.defaultViewTransition?.(\n history.at(currentLocationIndex),\n history.at(newLocationIndex)\n ))\n ) {\n const duration = options?.duration ?? DefaultTransitionDuration;\n setIsTransitioning(true);\n setTransitionDuration(duration);\n setTransitioningToIndex(newLocationIndex);\n setTimeout(() => {\n setIsTransitioning(false);\n setTransitioningToIndex(null);\n setCurrentLocationIndex(newLocationIndex);\n options?.onFinish?.();\n }, duration);\n } else {\n setCurrentLocationIndex(newLocationIndex);\n }\n },\n [currentLocationIndex, history, isTransitioning, router]\n );\n\n return (\n <RouterContext.Provider\n value={{\n options: router,\n\n history,\n currentLocationIndex,\n location: history.at(currentLocationIndex) || null,\n canGoBack: currentLocationIndex > 0,\n canGoForward: currentLocationIndex < history.length - 1,\n\n isTransitioning,\n transitionDuration,\n transitioningToIndex,\n\n navigate,\n back,\n forward,\n }}\n >\n {children}\n </RouterContext.Provider>\n );\n};\n","import type { Location, RootRoute, Route, RouterOptions } from \"./types.js\";\n\nexport const DefaultTransitionDuration = 300;\n\nexport const redirect = (options: { to: string; replace?: boolean }) => {\n return new Error(\"\", { cause: options });\n};\n\nexport const matchUrl = (\n pattern: string,\n url: string\n): { params: Record<string, string>; query: Record<string, string> } | null => {\n try {\n // 解析 URL\n let pathname, searchParams;\n\n if (url.startsWith(\"http://\") || url.startsWith(\"https://\")) {\n const urlObj = new URL(url);\n pathname = urlObj.pathname;\n searchParams = urlObj.searchParams;\n } else {\n // 處理相對路徑\n const [path, queryString] = url.split(\"?\");\n if (!path) {\n return null;\n }\n pathname = path;\n searchParams = new URLSearchParams(queryString || \"\");\n }\n\n // 移除路徑首尾的斜線以便比較\n const cleanPath = pathname.replaceAll(/^\\/|\\/$/g, \"\");\n const cleanPattern = pattern.replaceAll(/^\\/|\\/$/g, \"\");\n\n // 分割路徑段\n const pathSegments = cleanPath.split(\"/\");\n const patternSegments = cleanPattern.split(\"/\");\n\n // 路徑段數量不同則不匹配\n if (pathSegments.length !== patternSegments.length) {\n return null;\n }\n\n // 提取路徑參數\n const params: Record<string, string> = {};\n for (let i = 0; i < patternSegments.length; i++) {\n const patternSegment = patternSegments[i];\n const pathSegment = pathSegments[i];\n\n if (patternSegment.startsWith(\":\")) {\n // 動態參數\n const paramName = patternSegment.slice(1);\n params[paramName] = decodeURIComponent(pathSegment);\n } else if (patternSegment !== pathSegment) {\n // 靜態段不匹配\n return null;\n }\n }\n\n // 提取查詢參數\n const query = Object.fromEntries(searchParams.entries());\n\n return { params, query };\n } catch {\n return null;\n }\n};\n\nexport const matchRoute = (\n rootRoute: RootRoute,\n url: string\n): {\n matches: Route[];\n params: Record<string, string>;\n query: Record<string, string>;\n} | null => {\n const _matchRoute = (\n matches: Route[],\n route: Route\n ): {\n matches: Route[];\n params: Record<string, string>;\n query: Record<string, string>;\n } | null => {\n if (route.children) {\n for (const childRoute of route.children) {\n const matchesResult = _matchRoute([...matches, childRoute], childRoute);\n if (matchesResult) {\n return matchesResult;\n }\n }\n return null;\n }\n\n let pattern = \"\";\n for (const match of matches) {\n if (match.pathname === undefined) continue;\n pattern += `/${match.pathname}`;\n }\n const result = matchUrl(pattern, url);\n if (result) {\n return { matches, ...result };\n }\n return null;\n };\n\n return _matchRoute([], rootRoute);\n};\n\nexport const parseLocationFromHref = (\n rootRoute: RootRoute,\n to: string\n): Pick<Location, \"pathname\" | \"params\" | \"query\"> | null => {\n const result = matchRoute(rootRoute, to);\n if (!result) return null;\n return {\n pathname: to,\n params: result.params,\n query: result.query,\n };\n};\n\nexport const createRouter = (options: RouterOptions): RouterOptions => {\n return options;\n};\n","import { useEffect, useState } from \"react\";\n\nimport { useMatches } from \"@/hooks/useMatches.js\";\nimport { useRoute } from \"@/hooks/useRoute.js\";\nimport { useRouter } from \"@/hooks/useRouter.js\";\nimport type { RootRoute } from \"@/types.js\";\n\nimport { LocationProvider } from \"./locationProvider.js\";\nimport { RouteComponent } from \"./routeComponent.js\";\nimport { RouteProvider } from \"./routeProvider.js\";\n\nexport const PageRenderer = () => {\n const route = useRoute();\n const matches = useMatches();\n if (!matches || matches.length === 0) {\n const NotFoundComponent = route.notFoundComponent!;\n return <NotFoundComponent />;\n }\n let content: React.ReactNode = null;\n for (let i = matches.length - 1; i >= 0; i--) {\n const route = matches[i];\n content = <RouteComponent route={route}>{content}</RouteComponent>;\n }\n return content;\n};\n\nconst StackComponent = () => {\n const {\n history,\n currentLocationIndex,\n canGoBack,\n canGoForward,\n isTransitioning,\n transitioningToIndex,\n transitionDuration,\n back,\n forward,\n } = useRouter();\n\n const [isDragging, setIsDragging] = useState(false);\n const [startX, setStartX] = useState(0);\n const [dragOffset, setDragOffset] = useState(0);\n const [isCanceling, setIsCanceling] = useState(false);\n const [isTransitionStarted, setIsTransitionStarted] = useState(false);\n\n useEffect(() => {\n if (!isTransitioning || transitioningToIndex === null) return;\n setIsTransitionStarted(true);\n setTimeout(() => {\n setIsTransitionStarted(false);\n }, transitionDuration);\n }, [isTransitioning, transitioningToIndex]);\n\n const reset = () => {\n setIsDragging(false);\n setDragOffset(0);\n setIsCanceling(false);\n };\n\n const handleTouchStart = (e: React.TouchEvent) => {\n if (isTransitioning || (!canGoForward && !canGoBack)) return;\n setIsDragging(true);\n setStartX(e.touches[0].clientX);\n };\n\n const handleTouchMove = (e: React.TouchEvent) => {\n if (!isDragging) return;\n const offset = e.touches[0].clientX - startX;\n if (\n (offset > 0 && currentLocationIndex === 0) ||\n (offset < 0 && currentLocationIndex + 1 === history.length)\n ) {\n setDragOffset(0);\n return;\n }\n setDragOffset(Math.min(window.innerWidth, offset));\n };\n\n const handleTouchEnd = () => {\n if (!isDragging) return;\n\n if (dragOffset > window.innerWidth * 0.3 && canGoBack) {\n back({\n onFinish: reset,\n });\n } else if (dragOffset < -window.innerWidth * 0.3 && canGoForward) {\n forward({\n onFinish: reset,\n });\n } else {\n setIsCanceling(true);\n setTimeout(reset, transitionDuration);\n }\n };\n\n return (\n <div className=\"relative inset-0 h-full w-full overflow-hidden\">\n {currentLocationIndex >= 1 && (\n <div className=\"absolute inset-0 -z-10\">\n <LocationProvider location={history.at(currentLocationIndex - 1)!}>\n <PageRenderer key={currentLocationIndex - 1} />\n </LocationProvider>\n </div>\n )}\n <div\n key={currentLocationIndex}\n className=\"bg-background absolute inset-0 overflow-hidden\"\n style={{\n transform:\n isTransitioning &&\n transitioningToIndex !== null &&\n transitioningToIndex < currentLocationIndex\n ? `translateX(100%)`\n : isDragging && dragOffset > 0 && !isCanceling\n ? `translateX(${dragOffset}px)`\n : \"translateX(0px)\",\n transition:\n isCanceling ||\n (isTransitioning &&\n transitioningToIndex !== null &&\n transitioningToIndex < currentLocationIndex)\n ? `transform ${transitionDuration}ms ease-out`\n : \"\",\n boxShadow:\n isDragging && dragOffset > 0\n ? \"-4px 0 8px rgba(0,0,0,0.1)\"\n : \"none\",\n }}\n onTouchStart={handleTouchStart}\n onTouchMove={handleTouchMove}\n onTouchEnd={handleTouchEnd}\n >\n <LocationProvider location={history.at(currentLocationIndex)!}>\n <PageRenderer key={currentLocationIndex} />\n </LocationProvider>\n </div>\n {((isDragging && dragOffset < 0) ||\n (isTransitioning &&\n transitioningToIndex !== null &&\n currentLocationIndex < transitioningToIndex)) && (\n <div\n key={transitioningToIndex}\n className=\"bg-background absolute inset-0 z-10 overflow-hidden transition-transform ease-in\"\n style={{\n transform: isTransitionStarted\n ? `translateX(0px)`\n : isDragging && !isCanceling\n ? `translateX(${window.innerWidth + dragOffset}px)`\n : \"translateX(100%)\",\n transitionDuration:\n isTransitioning || isCanceling\n ? `${transitionDuration}ms`\n : \"0ms\",\n }}\n >\n <LocationProvider\n location={\n isDragging\n ? history.at(currentLocationIndex + 1)!\n : history.at(transitioningToIndex!)!\n }\n >\n <PageRenderer key={transitioningToIndex} />\n </LocationProvider>\n </div>\n )}\n </div>\n );\n};\n\nexport const Stack = ({ rootRoute }: { rootRoute: RootRoute }) => {\n return (\n <RouteProvider rootRoute={rootRoute}>\n <StackComponent />\n </RouteProvider>\n );\n};\n","import { useContext } from \"react\";\n\nimport { LocationContext } from \"@/context/locationContext.js\";\n\nexport const useLocation = () => {\n const context = useContext(LocationContext);\n if (context === null) {\n throw new Error(\"useLocation must be used within a LocationProvider\");\n }\n return context;\n};\n","import { useContext } from \"react\";\n\nimport { RouteContext } from \"@/context/routeContext.js\";\n\nexport const useRoute = () => {\n const route = useContext(RouteContext);\n if (route === null) {\n throw new Error(\"useRoute must be used within a RouteProvider\");\n }\n return route;\n};\n","import { createContext } from \"react\";\n\nimport type { RootRoute } from \"@/types.js\";\n\nexport const RouteContext = createContext<RootRoute | null>(null);\n","import { matchRoute } from \"@/utils.js\";\n\nimport { useLocation } from \"./useLocation.js\";\nimport { useRoute } from \"./useRoute.js\";\n\nexport const useMatches = () => {\n const route = useRoute();\n const location = useLocation();\n if (!location) return [];\n return matchRoute(route, location.pathname)?.matches || [];\n};\n","import { useEffect } from \"react\";\n\nimport { RouteContext } from \"@/context/routeContext.js\";\nimport { useRouter } from \"@/hooks/useRouter.js\";\nimport type { RootRoute } from \"@/types.js\";\nimport { parseLocationFromHref } from \"@/utils.js\";\n\nexport const RouteProvider = ({\n rootRoute,\n children,\n}: {\n rootRoute: RootRoute;\n children: React.ReactNode;\n}) => {\n const router = useRouter();\n\n useEffect(() => {\n const currentLocation = parseLocationFromHref(\n rootRoute,\n window.location.href\n );\n if (!currentLocation) return;\n router.navigate({\n to: currentLocation.pathname,\n params: currentLocation.params,\n query: currentLocation.query,\n });\n return () => {\n router.back();\n };\n }, []);\n\n return (\n <RouteContext.Provider value={rootRoute}>{children}</RouteContext.Provider>\n );\n};\n","export interface Route {\n id?: string;\n pathname?: string;\n beforeLoad?: ({ location }: { location: Location }) => Promise<void>;\n component?: React.ComponentType<{ children?: React.ReactNode }>;\n pendingComponent?: React.ComponentType;\n children?: Route[];\n}\n\nexport interface RootRoute extends Route {\n notFoundComponent?: React.ComponentType;\n}\n\nexport interface Location {\n index: number;\n pathname: string;\n params: any;\n query: any;\n state?: Map<string, any>;\n}\n\nexport interface RouterOptions {\n defaultViewTransition?: (\n fromLocation: Location | undefined,\n toLocation: Location | undefined\n ) => boolean;\n}\n\nexport interface TransitionOptions {\n transition?: boolean;\n duration?: number;\n onFinish?: () => void;\n}\n\nexport type NavigateOptions = Partial<\n Pick<Location, \"params\" | \"query\" | \"state\">\n> & {\n to: string;\n replace?: boolean;\n updateHistory?: boolean;\n} & TransitionOptions;\n\nexport type BackOptions =\n | (TransitionOptions & {\n depth?: number;\n })\n | void;\n\nexport type ForwardOptions =\n | (TransitionOptions & {\n depth?: number;\n })\n | void;\n\nexport class RedirectError extends Error {\n options: { to: string; replace?: boolean };\n constructor(options: { to: string; replace?: boolean }) {\n super();\n this.options = options;\n }\n}\n"],"mappings":"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","names":["import_react","import_react","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_react","import_react","import_react","import_react","import_jsx_runtime","import_jsx_runtime","route"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -55,6 +55,14 @@ type ForwardOptions =
|
|
|
55
55
|
})
|
|
56
56
|
| void;
|
|
57
57
|
|
|
58
|
+
declare class RedirectError extends Error {
|
|
59
|
+
options: { to: string; replace?: boolean };
|
|
60
|
+
constructor(options: { to: string; replace?: boolean }) {
|
|
61
|
+
super();
|
|
62
|
+
this.options = options;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
58
66
|
declare const LocationProvider: ({ location, children, }: {
|
|
59
67
|
location: Location;
|
|
60
68
|
children: React.ReactNode;
|
|
@@ -120,4 +128,4 @@ declare const matchRoute: (rootRoute: RootRoute, url: string) => {
|
|
|
120
128
|
declare const parseLocationFromHref: (rootRoute: RootRoute, to: string) => Pick<Location, "pathname" | "params" | "query"> | null;
|
|
121
129
|
declare const createRouter: (options: RouterOptions) => RouterOptions;
|
|
122
130
|
|
|
123
|
-
export { DefaultTransitionDuration, LocationContext, LocationProvider, PageRenderer, RouteComponent, RouteContext, RouterContext, type RouterContextType, RouterProvider, Stack, createRouter, matchRoute, matchUrl, parseLocationFromHref, redirect, useLocation, useMatches, useRoute, useRouter };
|
|
131
|
+
export { type BackOptions, DefaultTransitionDuration, type ForwardOptions, type Location, LocationContext, LocationProvider, type NavigateOptions, PageRenderer, RedirectError, type RootRoute, type Route, RouteComponent, RouteContext, RouterContext, type RouterContextType, type RouterOptions, RouterProvider, Stack, type TransitionOptions, createRouter, matchRoute, matchUrl, parseLocationFromHref, redirect, useLocation, useMatches, useRoute, useRouter };
|
package/dist/index.d.ts
CHANGED
|
@@ -55,6 +55,14 @@ type ForwardOptions =
|
|
|
55
55
|
})
|
|
56
56
|
| void;
|
|
57
57
|
|
|
58
|
+
declare class RedirectError extends Error {
|
|
59
|
+
options: { to: string; replace?: boolean };
|
|
60
|
+
constructor(options: { to: string; replace?: boolean }) {
|
|
61
|
+
super();
|
|
62
|
+
this.options = options;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
58
66
|
declare const LocationProvider: ({ location, children, }: {
|
|
59
67
|
location: Location;
|
|
60
68
|
children: React.ReactNode;
|
|
@@ -120,4 +128,4 @@ declare const matchRoute: (rootRoute: RootRoute, url: string) => {
|
|
|
120
128
|
declare const parseLocationFromHref: (rootRoute: RootRoute, to: string) => Pick<Location, "pathname" | "params" | "query"> | null;
|
|
121
129
|
declare const createRouter: (options: RouterOptions) => RouterOptions;
|
|
122
130
|
|
|
123
|
-
export { DefaultTransitionDuration, LocationContext, LocationProvider, PageRenderer, RouteComponent, RouteContext, RouterContext, type RouterContextType, RouterProvider, Stack, createRouter, matchRoute, matchUrl, parseLocationFromHref, redirect, useLocation, useMatches, useRoute, useRouter };
|
|
131
|
+
export { type BackOptions, DefaultTransitionDuration, type ForwardOptions, type Location, LocationContext, LocationProvider, type NavigateOptions, PageRenderer, RedirectError, type RootRoute, type Route, RouteComponent, RouteContext, RouterContext, type RouterContextType, type RouterOptions, RouterProvider, Stack, type TransitionOptions, createRouter, matchRoute, matchUrl, parseLocationFromHref, redirect, useLocation, useMatches, useRoute, useRouter };
|
package/dist/index.js
CHANGED
|
@@ -463,11 +463,21 @@ var StackComponent = () => {
|
|
|
463
463
|
var Stack = ({ rootRoute }) => {
|
|
464
464
|
return /* @__PURE__ */ jsx5(RouteProvider, { rootRoute, children: /* @__PURE__ */ jsx5(StackComponent, {}) });
|
|
465
465
|
};
|
|
466
|
+
|
|
467
|
+
// src/types.d.ts
|
|
468
|
+
var RedirectError = class extends Error {
|
|
469
|
+
options;
|
|
470
|
+
constructor(options) {
|
|
471
|
+
super();
|
|
472
|
+
this.options = options;
|
|
473
|
+
}
|
|
474
|
+
};
|
|
466
475
|
export {
|
|
467
476
|
DefaultTransitionDuration,
|
|
468
477
|
LocationContext,
|
|
469
478
|
LocationProvider,
|
|
470
479
|
PageRenderer,
|
|
480
|
+
RedirectError,
|
|
471
481
|
RouteComponent,
|
|
472
482
|
RouteContext,
|
|
473
483
|
RouterContext,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/context/locationContext.ts","../src/components/locationProvider.tsx","../src/components/routeComponent.tsx","../src/hooks/useRouter.ts","../src/context/routerContext.ts","../src/components/routerProvider.tsx","../src/utils.ts","../src/components/stack.tsx","../src/hooks/useLocation.ts","../src/hooks/useRoute.ts","../src/context/routeContext.ts","../src/hooks/useMatches.ts","../src/components/routeProvider.tsx"],"sourcesContent":["import { createContext } from \"react\";\n\nimport type { Location } from \"@/types.js\";\n\nexport const LocationContext = createContext<Location | null>(null);\n","import { LocationContext } from \"@/context/locationContext.js\";\nimport type { Location } from \"@/types.js\";\n\nexport const LocationProvider = ({\n location,\n children,\n}: {\n location: Location;\n children: React.ReactNode;\n}) => {\n return (\n <LocationContext.Provider value={location}>\n {children}\n </LocationContext.Provider>\n );\n};\n","import { useEffect, useState } from \"react\";\n\nimport { useRouter } from \"@/hooks/useRouter.js\";\nimport type { Route } from \"@/types.js\";\n\nexport const RouteComponent = ({\n route,\n children,\n}: {\n route: Route;\n children?: React.ReactNode;\n}) => {\n const router = useRouter();\n const [pending, setPending] = useState(!!route.beforeLoad);\n\n useEffect(() => {\n if (route.beforeLoad) {\n route\n .beforeLoad({ location: router.location! })\n .catch((error: unknown) => {\n if (\n error instanceof Error &&\n typeof error.cause === \"object\" &&\n error.cause !== null &&\n \"to\" in error.cause\n ) {\n router.navigate({\n to: (error.cause as any).to,\n replace: (error.cause as any).replace,\n });\n }\n })\n .finally(() => setPending(false));\n }\n }, []);\n\n if (pending) {\n const PendingComponent = route.pendingComponent!;\n return <PendingComponent />;\n }\n\n const Component = route.component;\n return Component ? <Component>{children}</Component> : children;\n};\n","import { useContext } from \"react\";\n\nimport { RouterContext } from \"@/context/routerContext.js\";\n\nexport const useRouter = () => {\n const router = useContext(RouterContext);\n if (router === null) {\n throw new Error(\"useRouter must be used within a Stack\");\n }\n return router;\n};\n","import { createContext } from \"react\";\n\nimport type {\n BackOptions,\n ForwardOptions,\n Location,\n NavigateOptions,\n RouterOptions,\n} from \"@/types.js\";\n\nexport interface RouterContextType {\n // Router Config\n options: RouterOptions;\n\n // Navigation State\n history: Location[];\n currentLocationIndex: number;\n location: Location | null;\n canGoBack: boolean;\n canGoForward: boolean;\n\n // Transition state\n isTransitioning: boolean;\n transitionDuration: number;\n transitioningToIndex: number | null;\n\n // Actions\n navigate: (options: NavigateOptions) => void;\n back: (options: BackOptions) => void;\n forward: (options: ForwardOptions) => void;\n}\n\nexport const RouterContext = createContext<RouterContextType | null>(null);\n","import { useCallback, useEffect, useState } from \"react\";\n\nimport { RouterContext } from \"@/context/routerContext.js\";\nimport type {\n BackOptions,\n ForwardOptions,\n Location,\n NavigateOptions,\n RouterOptions,\n} from \"@/types.js\";\nimport { DefaultTransitionDuration } from \"@/utils.js\";\n\nexport const RouterProvider = ({\n router,\n children,\n}: {\n router: RouterOptions;\n children: React.ReactNode;\n}) => {\n const [history, setHistory] = useState<Location[]>([]);\n const [currentLocationIndex, setCurrentLocationIndex] = useState<number>(-1);\n const [isTransitioning, setIsTransitioning] = useState<boolean>(false);\n const [transitionDuration, setTransitionDuration] = useState<number>(\n DefaultTransitionDuration\n );\n const [transitioningToIndex, setTransitioningToIndex] = useState<\n number | null\n >(null);\n\n const navigate = useCallback(\n ({\n to,\n replace,\n transition,\n duration,\n updateHistory,\n onFinish,\n ...locationOptions\n }: NavigateOptions) => {\n if (isTransitioning) return;\n const newLocationIndex = replace\n ? currentLocationIndex\n : currentLocationIndex + 1;\n const newLocation: Location = {\n index: newLocationIndex,\n params: {},\n query: {},\n state: new Map(),\n pathname: to,\n ...locationOptions,\n };\n if (newLocationIndex === history.length) {\n setHistory([...history, newLocation]);\n } else {\n setHistory((prevHistory) => {\n const newHistory = [...prevHistory];\n newHistory[newLocationIndex] = newLocation;\n return newHistory.slice(0, currentLocationIndex + 2);\n });\n }\n if (\n !replace &&\n currentLocationIndex >= 0 &&\n (transition ??\n router.defaultViewTransition?.(\n history.at(currentLocationIndex),\n history.at(newLocationIndex)\n ))\n ) {\n const currentDuration = duration ?? DefaultTransitionDuration;\n setIsTransitioning(true);\n setTransitionDuration(currentDuration);\n setTransitioningToIndex(newLocationIndex);\n setTimeout(() => {\n setIsTransitioning(false);\n setTransitioningToIndex(null);\n setCurrentLocationIndex(newLocationIndex);\n onFinish?.();\n if (updateHistory) {\n window.history.pushState({}, \"\", to);\n }\n }, currentDuration);\n } else if (!replace) {\n setCurrentLocationIndex(newLocationIndex);\n if (updateHistory) {\n window.history.pushState({}, \"\", to);\n }\n } else if (updateHistory) {\n window.history.replaceState({}, \"\", to);\n }\n },\n [currentLocationIndex, history, isTransitioning, router]\n );\n\n useEffect(() => {\n console.log(\"Navigate: History updated:\", history);\n }, [history]);\n\n const back = useCallback(\n (options: BackOptions) => {\n if (isTransitioning) return;\n const newLocationIndex = currentLocationIndex - (options?.depth ?? 1);\n if (\n currentLocationIndex > 0 &&\n (options?.transition ??\n router.defaultViewTransition?.(\n history.at(currentLocationIndex),\n history.at(newLocationIndex)\n ))\n ) {\n const currentDuration = options?.duration ?? DefaultTransitionDuration;\n setIsTransitioning(true);\n setTransitionDuration(currentDuration);\n setTransitioningToIndex(newLocationIndex);\n setTimeout(() => {\n setIsTransitioning(false);\n setTransitioningToIndex(null);\n setCurrentLocationIndex(newLocationIndex);\n options?.onFinish?.();\n }, currentDuration);\n } else {\n setCurrentLocationIndex(newLocationIndex);\n }\n },\n [currentLocationIndex, history, isTransitioning, router]\n );\n\n const forward = useCallback(\n (options: ForwardOptions) => {\n if (isTransitioning) return;\n const newLocationIndex = currentLocationIndex + 1;\n if (\n newLocationIndex < history.length &&\n (options?.transition ??\n router.defaultViewTransition?.(\n history.at(currentLocationIndex),\n history.at(newLocationIndex)\n ))\n ) {\n const duration = options?.duration ?? DefaultTransitionDuration;\n setIsTransitioning(true);\n setTransitionDuration(duration);\n setTransitioningToIndex(newLocationIndex);\n setTimeout(() => {\n setIsTransitioning(false);\n setTransitioningToIndex(null);\n setCurrentLocationIndex(newLocationIndex);\n options?.onFinish?.();\n }, duration);\n } else {\n setCurrentLocationIndex(newLocationIndex);\n }\n },\n [currentLocationIndex, history, isTransitioning, router]\n );\n\n return (\n <RouterContext.Provider\n value={{\n options: router,\n\n history,\n currentLocationIndex,\n location: history.at(currentLocationIndex) || null,\n canGoBack: currentLocationIndex > 0,\n canGoForward: currentLocationIndex < history.length - 1,\n\n isTransitioning,\n transitionDuration,\n transitioningToIndex,\n\n navigate,\n back,\n forward,\n }}\n >\n {children}\n </RouterContext.Provider>\n );\n};\n","import type { Location, RootRoute, Route, RouterOptions } from \"./types.js\";\n\nexport const DefaultTransitionDuration = 300;\n\nexport const redirect = (options: { to: string; replace?: boolean }) => {\n return new Error(\"\", { cause: options });\n};\n\nexport const matchUrl = (\n pattern: string,\n url: string\n): { params: Record<string, string>; query: Record<string, string> } | null => {\n try {\n // 解析 URL\n let pathname, searchParams;\n\n if (url.startsWith(\"http://\") || url.startsWith(\"https://\")) {\n const urlObj = new URL(url);\n pathname = urlObj.pathname;\n searchParams = urlObj.searchParams;\n } else {\n // 處理相對路徑\n const [path, queryString] = url.split(\"?\");\n if (!path) {\n return null;\n }\n pathname = path;\n searchParams = new URLSearchParams(queryString || \"\");\n }\n\n // 移除路徑首尾的斜線以便比較\n const cleanPath = pathname.replaceAll(/^\\/|\\/$/g, \"\");\n const cleanPattern = pattern.replaceAll(/^\\/|\\/$/g, \"\");\n\n // 分割路徑段\n const pathSegments = cleanPath.split(\"/\");\n const patternSegments = cleanPattern.split(\"/\");\n\n // 路徑段數量不同則不匹配\n if (pathSegments.length !== patternSegments.length) {\n return null;\n }\n\n // 提取路徑參數\n const params: Record<string, string> = {};\n for (let i = 0; i < patternSegments.length; i++) {\n const patternSegment = patternSegments[i];\n const pathSegment = pathSegments[i];\n\n if (patternSegment.startsWith(\":\")) {\n // 動態參數\n const paramName = patternSegment.slice(1);\n params[paramName] = decodeURIComponent(pathSegment);\n } else if (patternSegment !== pathSegment) {\n // 靜態段不匹配\n return null;\n }\n }\n\n // 提取查詢參數\n const query = Object.fromEntries(searchParams.entries());\n\n return { params, query };\n } catch {\n return null;\n }\n};\n\nexport const matchRoute = (\n rootRoute: RootRoute,\n url: string\n): {\n matches: Route[];\n params: Record<string, string>;\n query: Record<string, string>;\n} | null => {\n const _matchRoute = (\n matches: Route[],\n route: Route\n ): {\n matches: Route[];\n params: Record<string, string>;\n query: Record<string, string>;\n } | null => {\n if (route.children) {\n for (const childRoute of route.children) {\n const matchesResult = _matchRoute([...matches, childRoute], childRoute);\n if (matchesResult) {\n return matchesResult;\n }\n }\n return null;\n }\n\n let pattern = \"\";\n for (const match of matches) {\n if (match.pathname === undefined) continue;\n pattern += `/${match.pathname}`;\n }\n const result = matchUrl(pattern, url);\n if (result) {\n return { matches, ...result };\n }\n return null;\n };\n\n return _matchRoute([], rootRoute);\n};\n\nexport const parseLocationFromHref = (\n rootRoute: RootRoute,\n to: string\n): Pick<Location, \"pathname\" | \"params\" | \"query\"> | null => {\n const result = matchRoute(rootRoute, to);\n if (!result) return null;\n return {\n pathname: to,\n params: result.params,\n query: result.query,\n };\n};\n\nexport const createRouter = (options: RouterOptions): RouterOptions => {\n return options;\n};\n","import { useEffect, useState } from \"react\";\n\nimport { useMatches } from \"@/hooks/useMatches.js\";\nimport { useRoute } from \"@/hooks/useRoute.js\";\nimport { useRouter } from \"@/hooks/useRouter.js\";\nimport type { RootRoute } from \"@/types.js\";\n\nimport { LocationProvider } from \"./locationProvider.js\";\nimport { RouteComponent } from \"./routeComponent.js\";\nimport { RouteProvider } from \"./routeProvider.js\";\n\nexport const PageRenderer = () => {\n const route = useRoute();\n const matches = useMatches();\n if (!matches || matches.length === 0) {\n const NotFoundComponent = route.notFoundComponent!;\n return <NotFoundComponent />;\n }\n let content: React.ReactNode = null;\n for (let i = matches.length - 1; i >= 0; i--) {\n const route = matches[i];\n content = <RouteComponent route={route}>{content}</RouteComponent>;\n }\n return content;\n};\n\nconst StackComponent = () => {\n const {\n history,\n currentLocationIndex,\n canGoBack,\n canGoForward,\n isTransitioning,\n transitioningToIndex,\n transitionDuration,\n back,\n forward,\n } = useRouter();\n\n const [isDragging, setIsDragging] = useState(false);\n const [startX, setStartX] = useState(0);\n const [dragOffset, setDragOffset] = useState(0);\n const [isCanceling, setIsCanceling] = useState(false);\n const [isTransitionStarted, setIsTransitionStarted] = useState(false);\n\n useEffect(() => {\n if (!isTransitioning || transitioningToIndex === null) return;\n setIsTransitionStarted(true);\n setTimeout(() => {\n setIsTransitionStarted(false);\n }, transitionDuration);\n }, [isTransitioning, transitioningToIndex]);\n\n const reset = () => {\n setIsDragging(false);\n setDragOffset(0);\n setIsCanceling(false);\n };\n\n const handleTouchStart = (e: React.TouchEvent) => {\n if (isTransitioning || (!canGoForward && !canGoBack)) return;\n setIsDragging(true);\n setStartX(e.touches[0].clientX);\n };\n\n const handleTouchMove = (e: React.TouchEvent) => {\n if (!isDragging) return;\n const offset = e.touches[0].clientX - startX;\n if (\n (offset > 0 && currentLocationIndex === 0) ||\n (offset < 0 && currentLocationIndex + 1 === history.length)\n ) {\n setDragOffset(0);\n return;\n }\n setDragOffset(Math.min(window.innerWidth, offset));\n };\n\n const handleTouchEnd = () => {\n if (!isDragging) return;\n\n if (dragOffset > window.innerWidth * 0.3 && canGoBack) {\n back({\n onFinish: reset,\n });\n } else if (dragOffset < -window.innerWidth * 0.3 && canGoForward) {\n forward({\n onFinish: reset,\n });\n } else {\n setIsCanceling(true);\n setTimeout(reset, transitionDuration);\n }\n };\n\n return (\n <div className=\"relative inset-0 h-full w-full overflow-hidden\">\n {currentLocationIndex >= 1 && (\n <div className=\"absolute inset-0 -z-10\">\n <LocationProvider location={history.at(currentLocationIndex - 1)!}>\n <PageRenderer key={currentLocationIndex - 1} />\n </LocationProvider>\n </div>\n )}\n <div\n key={currentLocationIndex}\n className=\"bg-background absolute inset-0 overflow-hidden\"\n style={{\n transform:\n isTransitioning &&\n transitioningToIndex !== null &&\n transitioningToIndex < currentLocationIndex\n ? `translateX(100%)`\n : isDragging && dragOffset > 0 && !isCanceling\n ? `translateX(${dragOffset}px)`\n : \"translateX(0px)\",\n transition:\n isCanceling ||\n (isTransitioning &&\n transitioningToIndex !== null &&\n transitioningToIndex < currentLocationIndex)\n ? `transform ${transitionDuration}ms ease-out`\n : \"\",\n boxShadow:\n isDragging && dragOffset > 0\n ? \"-4px 0 8px rgba(0,0,0,0.1)\"\n : \"none\",\n }}\n onTouchStart={handleTouchStart}\n onTouchMove={handleTouchMove}\n onTouchEnd={handleTouchEnd}\n >\n <LocationProvider location={history.at(currentLocationIndex)!}>\n <PageRenderer key={currentLocationIndex} />\n </LocationProvider>\n </div>\n {((isDragging && dragOffset < 0) ||\n (isTransitioning &&\n transitioningToIndex !== null &&\n currentLocationIndex < transitioningToIndex)) && (\n <div\n key={transitioningToIndex}\n className=\"bg-background absolute inset-0 z-10 overflow-hidden transition-transform ease-in\"\n style={{\n transform: isTransitionStarted\n ? `translateX(0px)`\n : isDragging && !isCanceling\n ? `translateX(${window.innerWidth + dragOffset}px)`\n : \"translateX(100%)\",\n transitionDuration:\n isTransitioning || isCanceling\n ? `${transitionDuration}ms`\n : \"0ms\",\n }}\n >\n <LocationProvider\n location={\n isDragging\n ? history.at(currentLocationIndex + 1)!\n : history.at(transitioningToIndex!)!\n }\n >\n <PageRenderer key={transitioningToIndex} />\n </LocationProvider>\n </div>\n )}\n </div>\n );\n};\n\nexport const Stack = ({ rootRoute }: { rootRoute: RootRoute }) => {\n return (\n <RouteProvider rootRoute={rootRoute}>\n <StackComponent />\n </RouteProvider>\n );\n};\n","import { useContext } from \"react\";\n\nimport { LocationContext } from \"@/context/locationContext.js\";\n\nexport const useLocation = () => {\n const context = useContext(LocationContext);\n if (context === null) {\n throw new Error(\"useLocation must be used within a LocationProvider\");\n }\n return context;\n};\n","import { useContext } from \"react\";\n\nimport { RouteContext } from \"@/context/routeContext.js\";\n\nexport const useRoute = () => {\n const route = useContext(RouteContext);\n if (route === null) {\n throw new Error(\"useRoute must be used within a RouteProvider\");\n }\n return route;\n};\n","import { createContext } from \"react\";\n\nimport type { RootRoute } from \"@/types.js\";\n\nexport const RouteContext = createContext<RootRoute | null>(null);\n","import { matchRoute } from \"@/utils.js\";\n\nimport { useLocation } from \"./useLocation.js\";\nimport { useRoute } from \"./useRoute.js\";\n\nexport const useMatches = () => {\n const route = useRoute();\n const location = useLocation();\n if (!location) return [];\n return matchRoute(route, location.pathname)?.matches || [];\n};\n","import { useEffect } from \"react\";\n\nimport { RouteContext } from \"@/context/routeContext.js\";\nimport { useRouter } from \"@/hooks/useRouter.js\";\nimport type { RootRoute } from \"@/types.js\";\nimport { parseLocationFromHref } from \"@/utils.js\";\n\nexport const RouteProvider = ({\n rootRoute,\n children,\n}: {\n rootRoute: RootRoute;\n children: React.ReactNode;\n}) => {\n const router = useRouter();\n\n useEffect(() => {\n const currentLocation = parseLocationFromHref(\n rootRoute,\n window.location.href\n );\n if (!currentLocation) return;\n router.navigate({\n to: currentLocation.pathname,\n params: currentLocation.params,\n query: currentLocation.query,\n });\n return () => {\n router.back();\n };\n }, []);\n\n return (\n <RouteContext.Provider value={rootRoute}>{children}</RouteContext.Provider>\n );\n};\n"],"mappings":"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","names":["createContext","jsx","useEffect","useState","jsx","useState","useEffect","useEffect","useState","useContext","useContext","useContext","createContext","useContext","useEffect","jsx","useEffect","jsx","route","useState","useEffect"]}
|
|
1
|
+
{"version":3,"sources":["../src/context/locationContext.ts","../src/components/locationProvider.tsx","../src/components/routeComponent.tsx","../src/hooks/useRouter.ts","../src/context/routerContext.ts","../src/components/routerProvider.tsx","../src/utils.ts","../src/components/stack.tsx","../src/hooks/useLocation.ts","../src/hooks/useRoute.ts","../src/context/routeContext.ts","../src/hooks/useMatches.ts","../src/components/routeProvider.tsx","../src/types.d.ts"],"sourcesContent":["import { createContext } from \"react\";\n\nimport type { Location } from \"@/types.js\";\n\nexport const LocationContext = createContext<Location | null>(null);\n","import { LocationContext } from \"@/context/locationContext.js\";\nimport type { Location } from \"@/types.js\";\n\nexport const LocationProvider = ({\n location,\n children,\n}: {\n location: Location;\n children: React.ReactNode;\n}) => {\n return (\n <LocationContext.Provider value={location}>\n {children}\n </LocationContext.Provider>\n );\n};\n","import { useEffect, useState } from \"react\";\n\nimport { useRouter } from \"@/hooks/useRouter.js\";\nimport type { Route } from \"@/types.js\";\n\nexport const RouteComponent = ({\n route,\n children,\n}: {\n route: Route;\n children?: React.ReactNode;\n}) => {\n const router = useRouter();\n const [pending, setPending] = useState(!!route.beforeLoad);\n\n useEffect(() => {\n if (route.beforeLoad) {\n route\n .beforeLoad({ location: router.location! })\n .catch((error: unknown) => {\n if (\n error instanceof Error &&\n typeof error.cause === \"object\" &&\n error.cause !== null &&\n \"to\" in error.cause\n ) {\n router.navigate({\n to: (error.cause as any).to,\n replace: (error.cause as any).replace,\n });\n }\n })\n .finally(() => setPending(false));\n }\n }, []);\n\n if (pending) {\n const PendingComponent = route.pendingComponent!;\n return <PendingComponent />;\n }\n\n const Component = route.component;\n return Component ? <Component>{children}</Component> : children;\n};\n","import { useContext } from \"react\";\n\nimport { RouterContext } from \"@/context/routerContext.js\";\n\nexport const useRouter = () => {\n const router = useContext(RouterContext);\n if (router === null) {\n throw new Error(\"useRouter must be used within a Stack\");\n }\n return router;\n};\n","import { createContext } from \"react\";\n\nimport type {\n BackOptions,\n ForwardOptions,\n Location,\n NavigateOptions,\n RouterOptions,\n} from \"@/types.js\";\n\nexport interface RouterContextType {\n // Router Config\n options: RouterOptions;\n\n // Navigation State\n history: Location[];\n currentLocationIndex: number;\n location: Location | null;\n canGoBack: boolean;\n canGoForward: boolean;\n\n // Transition state\n isTransitioning: boolean;\n transitionDuration: number;\n transitioningToIndex: number | null;\n\n // Actions\n navigate: (options: NavigateOptions) => void;\n back: (options: BackOptions) => void;\n forward: (options: ForwardOptions) => void;\n}\n\nexport const RouterContext = createContext<RouterContextType | null>(null);\n","import { useCallback, useEffect, useState } from \"react\";\n\nimport { RouterContext } from \"@/context/routerContext.js\";\nimport type {\n BackOptions,\n ForwardOptions,\n Location,\n NavigateOptions,\n RouterOptions,\n} from \"@/types.js\";\nimport { DefaultTransitionDuration } from \"@/utils.js\";\n\nexport const RouterProvider = ({\n router,\n children,\n}: {\n router: RouterOptions;\n children: React.ReactNode;\n}) => {\n const [history, setHistory] = useState<Location[]>([]);\n const [currentLocationIndex, setCurrentLocationIndex] = useState<number>(-1);\n const [isTransitioning, setIsTransitioning] = useState<boolean>(false);\n const [transitionDuration, setTransitionDuration] = useState<number>(\n DefaultTransitionDuration\n );\n const [transitioningToIndex, setTransitioningToIndex] = useState<\n number | null\n >(null);\n\n const navigate = useCallback(\n ({\n to,\n replace,\n transition,\n duration,\n updateHistory,\n onFinish,\n ...locationOptions\n }: NavigateOptions) => {\n if (isTransitioning) return;\n const newLocationIndex = replace\n ? currentLocationIndex\n : currentLocationIndex + 1;\n const newLocation: Location = {\n index: newLocationIndex,\n params: {},\n query: {},\n state: new Map(),\n pathname: to,\n ...locationOptions,\n };\n if (newLocationIndex === history.length) {\n setHistory([...history, newLocation]);\n } else {\n setHistory((prevHistory) => {\n const newHistory = [...prevHistory];\n newHistory[newLocationIndex] = newLocation;\n return newHistory.slice(0, currentLocationIndex + 2);\n });\n }\n if (\n !replace &&\n currentLocationIndex >= 0 &&\n (transition ??\n router.defaultViewTransition?.(\n history.at(currentLocationIndex),\n history.at(newLocationIndex)\n ))\n ) {\n const currentDuration = duration ?? DefaultTransitionDuration;\n setIsTransitioning(true);\n setTransitionDuration(currentDuration);\n setTransitioningToIndex(newLocationIndex);\n setTimeout(() => {\n setIsTransitioning(false);\n setTransitioningToIndex(null);\n setCurrentLocationIndex(newLocationIndex);\n onFinish?.();\n if (updateHistory) {\n window.history.pushState({}, \"\", to);\n }\n }, currentDuration);\n } else if (!replace) {\n setCurrentLocationIndex(newLocationIndex);\n if (updateHistory) {\n window.history.pushState({}, \"\", to);\n }\n } else if (updateHistory) {\n window.history.replaceState({}, \"\", to);\n }\n },\n [currentLocationIndex, history, isTransitioning, router]\n );\n\n useEffect(() => {\n console.log(\"Navigate: History updated:\", history);\n }, [history]);\n\n const back = useCallback(\n (options: BackOptions) => {\n if (isTransitioning) return;\n const newLocationIndex = currentLocationIndex - (options?.depth ?? 1);\n if (\n currentLocationIndex > 0 &&\n (options?.transition ??\n router.defaultViewTransition?.(\n history.at(currentLocationIndex),\n history.at(newLocationIndex)\n ))\n ) {\n const currentDuration = options?.duration ?? DefaultTransitionDuration;\n setIsTransitioning(true);\n setTransitionDuration(currentDuration);\n setTransitioningToIndex(newLocationIndex);\n setTimeout(() => {\n setIsTransitioning(false);\n setTransitioningToIndex(null);\n setCurrentLocationIndex(newLocationIndex);\n options?.onFinish?.();\n }, currentDuration);\n } else {\n setCurrentLocationIndex(newLocationIndex);\n }\n },\n [currentLocationIndex, history, isTransitioning, router]\n );\n\n const forward = useCallback(\n (options: ForwardOptions) => {\n if (isTransitioning) return;\n const newLocationIndex = currentLocationIndex + 1;\n if (\n newLocationIndex < history.length &&\n (options?.transition ??\n router.defaultViewTransition?.(\n history.at(currentLocationIndex),\n history.at(newLocationIndex)\n ))\n ) {\n const duration = options?.duration ?? DefaultTransitionDuration;\n setIsTransitioning(true);\n setTransitionDuration(duration);\n setTransitioningToIndex(newLocationIndex);\n setTimeout(() => {\n setIsTransitioning(false);\n setTransitioningToIndex(null);\n setCurrentLocationIndex(newLocationIndex);\n options?.onFinish?.();\n }, duration);\n } else {\n setCurrentLocationIndex(newLocationIndex);\n }\n },\n [currentLocationIndex, history, isTransitioning, router]\n );\n\n return (\n <RouterContext.Provider\n value={{\n options: router,\n\n history,\n currentLocationIndex,\n location: history.at(currentLocationIndex) || null,\n canGoBack: currentLocationIndex > 0,\n canGoForward: currentLocationIndex < history.length - 1,\n\n isTransitioning,\n transitionDuration,\n transitioningToIndex,\n\n navigate,\n back,\n forward,\n }}\n >\n {children}\n </RouterContext.Provider>\n );\n};\n","import type { Location, RootRoute, Route, RouterOptions } from \"./types.js\";\n\nexport const DefaultTransitionDuration = 300;\n\nexport const redirect = (options: { to: string; replace?: boolean }) => {\n return new Error(\"\", { cause: options });\n};\n\nexport const matchUrl = (\n pattern: string,\n url: string\n): { params: Record<string, string>; query: Record<string, string> } | null => {\n try {\n // 解析 URL\n let pathname, searchParams;\n\n if (url.startsWith(\"http://\") || url.startsWith(\"https://\")) {\n const urlObj = new URL(url);\n pathname = urlObj.pathname;\n searchParams = urlObj.searchParams;\n } else {\n // 處理相對路徑\n const [path, queryString] = url.split(\"?\");\n if (!path) {\n return null;\n }\n pathname = path;\n searchParams = new URLSearchParams(queryString || \"\");\n }\n\n // 移除路徑首尾的斜線以便比較\n const cleanPath = pathname.replaceAll(/^\\/|\\/$/g, \"\");\n const cleanPattern = pattern.replaceAll(/^\\/|\\/$/g, \"\");\n\n // 分割路徑段\n const pathSegments = cleanPath.split(\"/\");\n const patternSegments = cleanPattern.split(\"/\");\n\n // 路徑段數量不同則不匹配\n if (pathSegments.length !== patternSegments.length) {\n return null;\n }\n\n // 提取路徑參數\n const params: Record<string, string> = {};\n for (let i = 0; i < patternSegments.length; i++) {\n const patternSegment = patternSegments[i];\n const pathSegment = pathSegments[i];\n\n if (patternSegment.startsWith(\":\")) {\n // 動態參數\n const paramName = patternSegment.slice(1);\n params[paramName] = decodeURIComponent(pathSegment);\n } else if (patternSegment !== pathSegment) {\n // 靜態段不匹配\n return null;\n }\n }\n\n // 提取查詢參數\n const query = Object.fromEntries(searchParams.entries());\n\n return { params, query };\n } catch {\n return null;\n }\n};\n\nexport const matchRoute = (\n rootRoute: RootRoute,\n url: string\n): {\n matches: Route[];\n params: Record<string, string>;\n query: Record<string, string>;\n} | null => {\n const _matchRoute = (\n matches: Route[],\n route: Route\n ): {\n matches: Route[];\n params: Record<string, string>;\n query: Record<string, string>;\n } | null => {\n if (route.children) {\n for (const childRoute of route.children) {\n const matchesResult = _matchRoute([...matches, childRoute], childRoute);\n if (matchesResult) {\n return matchesResult;\n }\n }\n return null;\n }\n\n let pattern = \"\";\n for (const match of matches) {\n if (match.pathname === undefined) continue;\n pattern += `/${match.pathname}`;\n }\n const result = matchUrl(pattern, url);\n if (result) {\n return { matches, ...result };\n }\n return null;\n };\n\n return _matchRoute([], rootRoute);\n};\n\nexport const parseLocationFromHref = (\n rootRoute: RootRoute,\n to: string\n): Pick<Location, \"pathname\" | \"params\" | \"query\"> | null => {\n const result = matchRoute(rootRoute, to);\n if (!result) return null;\n return {\n pathname: to,\n params: result.params,\n query: result.query,\n };\n};\n\nexport const createRouter = (options: RouterOptions): RouterOptions => {\n return options;\n};\n","import { useEffect, useState } from \"react\";\n\nimport { useMatches } from \"@/hooks/useMatches.js\";\nimport { useRoute } from \"@/hooks/useRoute.js\";\nimport { useRouter } from \"@/hooks/useRouter.js\";\nimport type { RootRoute } from \"@/types.js\";\n\nimport { LocationProvider } from \"./locationProvider.js\";\nimport { RouteComponent } from \"./routeComponent.js\";\nimport { RouteProvider } from \"./routeProvider.js\";\n\nexport const PageRenderer = () => {\n const route = useRoute();\n const matches = useMatches();\n if (!matches || matches.length === 0) {\n const NotFoundComponent = route.notFoundComponent!;\n return <NotFoundComponent />;\n }\n let content: React.ReactNode = null;\n for (let i = matches.length - 1; i >= 0; i--) {\n const route = matches[i];\n content = <RouteComponent route={route}>{content}</RouteComponent>;\n }\n return content;\n};\n\nconst StackComponent = () => {\n const {\n history,\n currentLocationIndex,\n canGoBack,\n canGoForward,\n isTransitioning,\n transitioningToIndex,\n transitionDuration,\n back,\n forward,\n } = useRouter();\n\n const [isDragging, setIsDragging] = useState(false);\n const [startX, setStartX] = useState(0);\n const [dragOffset, setDragOffset] = useState(0);\n const [isCanceling, setIsCanceling] = useState(false);\n const [isTransitionStarted, setIsTransitionStarted] = useState(false);\n\n useEffect(() => {\n if (!isTransitioning || transitioningToIndex === null) return;\n setIsTransitionStarted(true);\n setTimeout(() => {\n setIsTransitionStarted(false);\n }, transitionDuration);\n }, [isTransitioning, transitioningToIndex]);\n\n const reset = () => {\n setIsDragging(false);\n setDragOffset(0);\n setIsCanceling(false);\n };\n\n const handleTouchStart = (e: React.TouchEvent) => {\n if (isTransitioning || (!canGoForward && !canGoBack)) return;\n setIsDragging(true);\n setStartX(e.touches[0].clientX);\n };\n\n const handleTouchMove = (e: React.TouchEvent) => {\n if (!isDragging) return;\n const offset = e.touches[0].clientX - startX;\n if (\n (offset > 0 && currentLocationIndex === 0) ||\n (offset < 0 && currentLocationIndex + 1 === history.length)\n ) {\n setDragOffset(0);\n return;\n }\n setDragOffset(Math.min(window.innerWidth, offset));\n };\n\n const handleTouchEnd = () => {\n if (!isDragging) return;\n\n if (dragOffset > window.innerWidth * 0.3 && canGoBack) {\n back({\n onFinish: reset,\n });\n } else if (dragOffset < -window.innerWidth * 0.3 && canGoForward) {\n forward({\n onFinish: reset,\n });\n } else {\n setIsCanceling(true);\n setTimeout(reset, transitionDuration);\n }\n };\n\n return (\n <div className=\"relative inset-0 h-full w-full overflow-hidden\">\n {currentLocationIndex >= 1 && (\n <div className=\"absolute inset-0 -z-10\">\n <LocationProvider location={history.at(currentLocationIndex - 1)!}>\n <PageRenderer key={currentLocationIndex - 1} />\n </LocationProvider>\n </div>\n )}\n <div\n key={currentLocationIndex}\n className=\"bg-background absolute inset-0 overflow-hidden\"\n style={{\n transform:\n isTransitioning &&\n transitioningToIndex !== null &&\n transitioningToIndex < currentLocationIndex\n ? `translateX(100%)`\n : isDragging && dragOffset > 0 && !isCanceling\n ? `translateX(${dragOffset}px)`\n : \"translateX(0px)\",\n transition:\n isCanceling ||\n (isTransitioning &&\n transitioningToIndex !== null &&\n transitioningToIndex < currentLocationIndex)\n ? `transform ${transitionDuration}ms ease-out`\n : \"\",\n boxShadow:\n isDragging && dragOffset > 0\n ? \"-4px 0 8px rgba(0,0,0,0.1)\"\n : \"none\",\n }}\n onTouchStart={handleTouchStart}\n onTouchMove={handleTouchMove}\n onTouchEnd={handleTouchEnd}\n >\n <LocationProvider location={history.at(currentLocationIndex)!}>\n <PageRenderer key={currentLocationIndex} />\n </LocationProvider>\n </div>\n {((isDragging && dragOffset < 0) ||\n (isTransitioning &&\n transitioningToIndex !== null &&\n currentLocationIndex < transitioningToIndex)) && (\n <div\n key={transitioningToIndex}\n className=\"bg-background absolute inset-0 z-10 overflow-hidden transition-transform ease-in\"\n style={{\n transform: isTransitionStarted\n ? `translateX(0px)`\n : isDragging && !isCanceling\n ? `translateX(${window.innerWidth + dragOffset}px)`\n : \"translateX(100%)\",\n transitionDuration:\n isTransitioning || isCanceling\n ? `${transitionDuration}ms`\n : \"0ms\",\n }}\n >\n <LocationProvider\n location={\n isDragging\n ? history.at(currentLocationIndex + 1)!\n : history.at(transitioningToIndex!)!\n }\n >\n <PageRenderer key={transitioningToIndex} />\n </LocationProvider>\n </div>\n )}\n </div>\n );\n};\n\nexport const Stack = ({ rootRoute }: { rootRoute: RootRoute }) => {\n return (\n <RouteProvider rootRoute={rootRoute}>\n <StackComponent />\n </RouteProvider>\n );\n};\n","import { useContext } from \"react\";\n\nimport { LocationContext } from \"@/context/locationContext.js\";\n\nexport const useLocation = () => {\n const context = useContext(LocationContext);\n if (context === null) {\n throw new Error(\"useLocation must be used within a LocationProvider\");\n }\n return context;\n};\n","import { useContext } from \"react\";\n\nimport { RouteContext } from \"@/context/routeContext.js\";\n\nexport const useRoute = () => {\n const route = useContext(RouteContext);\n if (route === null) {\n throw new Error(\"useRoute must be used within a RouteProvider\");\n }\n return route;\n};\n","import { createContext } from \"react\";\n\nimport type { RootRoute } from \"@/types.js\";\n\nexport const RouteContext = createContext<RootRoute | null>(null);\n","import { matchRoute } from \"@/utils.js\";\n\nimport { useLocation } from \"./useLocation.js\";\nimport { useRoute } from \"./useRoute.js\";\n\nexport const useMatches = () => {\n const route = useRoute();\n const location = useLocation();\n if (!location) return [];\n return matchRoute(route, location.pathname)?.matches || [];\n};\n","import { useEffect } from \"react\";\n\nimport { RouteContext } from \"@/context/routeContext.js\";\nimport { useRouter } from \"@/hooks/useRouter.js\";\nimport type { RootRoute } from \"@/types.js\";\nimport { parseLocationFromHref } from \"@/utils.js\";\n\nexport const RouteProvider = ({\n rootRoute,\n children,\n}: {\n rootRoute: RootRoute;\n children: React.ReactNode;\n}) => {\n const router = useRouter();\n\n useEffect(() => {\n const currentLocation = parseLocationFromHref(\n rootRoute,\n window.location.href\n );\n if (!currentLocation) return;\n router.navigate({\n to: currentLocation.pathname,\n params: currentLocation.params,\n query: currentLocation.query,\n });\n return () => {\n router.back();\n };\n }, []);\n\n return (\n <RouteContext.Provider value={rootRoute}>{children}</RouteContext.Provider>\n );\n};\n","export interface Route {\n id?: string;\n pathname?: string;\n beforeLoad?: ({ location }: { location: Location }) => Promise<void>;\n component?: React.ComponentType<{ children?: React.ReactNode }>;\n pendingComponent?: React.ComponentType;\n children?: Route[];\n}\n\nexport interface RootRoute extends Route {\n notFoundComponent?: React.ComponentType;\n}\n\nexport interface Location {\n index: number;\n pathname: string;\n params: any;\n query: any;\n state?: Map<string, any>;\n}\n\nexport interface RouterOptions {\n defaultViewTransition?: (\n fromLocation: Location | undefined,\n toLocation: Location | undefined\n ) => boolean;\n}\n\nexport interface TransitionOptions {\n transition?: boolean;\n duration?: number;\n onFinish?: () => void;\n}\n\nexport type NavigateOptions = Partial<\n Pick<Location, \"params\" | \"query\" | \"state\">\n> & {\n to: string;\n replace?: boolean;\n updateHistory?: boolean;\n} & TransitionOptions;\n\nexport type BackOptions =\n | (TransitionOptions & {\n depth?: number;\n })\n | void;\n\nexport type ForwardOptions =\n | (TransitionOptions & {\n depth?: number;\n })\n | void;\n\nexport class RedirectError extends Error {\n options: { to: string; replace?: boolean };\n constructor(options: { to: string; replace?: boolean }) {\n super();\n this.options = options;\n }\n}\n"],"mappings":"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","names":["createContext","jsx","useEffect","useState","jsx","useState","useEffect","useEffect","useState","useContext","useContext","useContext","createContext","useContext","useEffect","jsx","useEffect","jsx","route","useState","useEffect"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@modastar/z-router",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
4
|
"description": "",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"homepage": "https://github.com/xLanStar/z-router#readme",
|
|
@@ -17,18 +17,32 @@
|
|
|
17
17
|
"main": "dist/index.js",
|
|
18
18
|
"module": "dist/index.mjs",
|
|
19
19
|
"types": "dist/index.d.ts",
|
|
20
|
+
"exports": {
|
|
21
|
+
"import": {
|
|
22
|
+
"types": "./dist/index.d.ts",
|
|
23
|
+
"import": "./dist/index.js"
|
|
24
|
+
},
|
|
25
|
+
"require": {
|
|
26
|
+
"types": "./dist/index.d.cts",
|
|
27
|
+
"require": "./dist/index.cjs"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
20
30
|
"scripts": {
|
|
21
31
|
"build": "tsup",
|
|
22
32
|
"build:watch": "tsup --watch",
|
|
23
|
-
"prepublishOnly": "pnpm run build"
|
|
33
|
+
"prepublishOnly": "pnpm run build",
|
|
34
|
+
"test": "vitest"
|
|
24
35
|
},
|
|
25
36
|
"packageManager": "pnpm@10.23.0",
|
|
26
37
|
"dependencies": {
|
|
27
38
|
"react": "^19.2.0"
|
|
28
39
|
},
|
|
29
40
|
"devDependencies": {
|
|
41
|
+
"@types/node": "^24.10.1",
|
|
30
42
|
"@types/react": "^19.2.7",
|
|
31
43
|
"tsup": "^8.5.1",
|
|
32
|
-
"typescript": "^5.9.3"
|
|
44
|
+
"typescript": "^5.9.3",
|
|
45
|
+
"vite": "^7.2.4",
|
|
46
|
+
"vitest": "^4.0.13"
|
|
33
47
|
}
|
|
34
48
|
}
|