@pinnacle0/react-stack-router
Advanced tools
Comparing version 0.1.3-beta.22 to 0.1.3-beta.23
@@ -20,2 +20,3 @@ import React from "react"; | ||
const keyframe = typeof enter === "function" ? enter(element) : enter; | ||
onEntering?.(); | ||
if (!keyframe) { | ||
@@ -25,3 +26,2 @@ onEntered?.(); | ||
} | ||
onEntering?.(); | ||
const animation = element.animate(keyframe.frames, keyframe.options); | ||
@@ -41,2 +41,3 @@ if (onEntered) | ||
const keyframe = typeof exit === "function" ? exit(element) : exit; | ||
onExiting?.(); | ||
if (!keyframe) { | ||
@@ -46,3 +47,2 @@ exited(); | ||
} | ||
onExiting?.(); | ||
const animation = element.animate(keyframe.frames, keyframe.options); | ||
@@ -49,0 +49,0 @@ if (exited) |
@@ -21,5 +21,6 @@ import { jsx as _jsx } from "react/jsx-runtime"; | ||
const context = { location: screen.history.location, lifecycle: screen.lifecycle, params: screen.history.params }; | ||
return (_jsx(Animated.div, { className: classNames("g-stack-router-screen", { overlay: index > 0 }), enter: () => screen.transition.enteringKeyframes, exit: () => screen.transition.exitingKeyframes, onEntering: () => screen.lifecycle.trigger("willEnter"), onEntered: () => screen.lifecycle.trigger("didEnter"), onExiting: () => screen.lifecycle.trigger("willExit"), onExited: () => screen.lifecycle.trigger("didExit"), children: _jsx(RouteContext.Provider, { value: context, children: _jsx(screen.content, { "$routeProps": context }) }) }, screen.history.location.key)); | ||
console.log(screen.history.location.state.$key); | ||
return (_jsx(Animated.div, { className: classNames("g-stack-router-screen", { overlay: index > 0 }), enter: () => screen.transition.enteringKeyframes, exit: () => screen.transition.exitingKeyframes, onEntering: () => screen.lifecycle.trigger("willEnter"), onEntered: () => screen.lifecycle.trigger("didEnter"), onExiting: () => screen.lifecycle.trigger("willExit"), onExited: () => screen.lifecycle.trigger("didExit"), children: _jsx(RouteContext.Provider, { value: context, children: _jsx(screen.content, {}) }) }, screen.history.location.state.$key)); | ||
}) }) })); | ||
} | ||
//# sourceMappingURL=index.js.map |
@@ -1,5 +0,5 @@ | ||
import type { History, Location } from "history"; | ||
import type { History } from "history"; | ||
import type { Lifecycle } from "./screen/lifecycle"; | ||
import type { Router } from "./type"; | ||
export interface RouterContext extends Pick<Router, "push" | "replace" | "pop" | "reset"> { | ||
import type { Location, Router } from "./type"; | ||
export interface RouterContext extends Pick<Router, "push" | "replace" | "pop"> { | ||
history: History; | ||
@@ -6,0 +6,0 @@ } |
@@ -38,3 +38,3 @@ import { jsx as _jsx } from "react/jsx-runtime"; | ||
const replace = router.replace.bind(router); | ||
const reset = router.reset.bind(router); | ||
const replaceHash = router.replaceHash.bind(router); | ||
const Root = ({ children }) => { | ||
@@ -49,3 +49,3 @@ const route = useMemo(() => createChildrenRoute(children, null), [children]); | ||
}, []); | ||
return (_jsx(RouterContext.Provider, { value: { history: historyRef.current, push, pop, replace, reset }, children: _jsx(Stack, { router: router }) })); | ||
return (_jsx(RouterContext.Provider, { value: { history: historyRef.current, push, pop, replace }, children: _jsx(Stack, { router: router }) })); | ||
}; | ||
@@ -58,5 +58,5 @@ return { | ||
replace, | ||
reset, | ||
replaceHash, | ||
}; | ||
} | ||
//# sourceMappingURL=createRouter.js.map |
import { RouterContext } from "./context"; | ||
import type { History, Location } from "history"; | ||
import type { History } from "history"; | ||
import type { LocationState, Location } from "./type"; | ||
/** | ||
* Route History hooks | ||
*/ | ||
export type Navigate = Omit<RouterContext, "history">; | ||
export declare const useNavigate: () => Navigate; | ||
export declare const useHistory: () => History; | ||
export declare const useParams: <T extends Record<string, unknown>>() => T; | ||
export declare function useLocationState<T extends LocationState>(): Partial<T>; | ||
export declare const useParams: <T extends Record<string, string>>() => T; | ||
export declare const useLocation: () => Location; | ||
export declare const useHash: () => string; | ||
export declare const useSearch: <T extends Record<string, unknown>>() => T; | ||
export type LocationMatchCallback = (location: Location) => void; | ||
export declare const useLocationMatch: (callback: LocationMatchCallback) => void; | ||
/** | ||
* Screen lifecycle hooks | ||
*/ | ||
export declare const useWillEnterEffect: (callback: () => any) => void; | ||
@@ -10,0 +21,0 @@ export declare const useDidEnterEffect: (callback: () => any) => void; |
@@ -1,6 +0,6 @@ | ||
import { useContext, useEffect } from "react"; | ||
import { useContext, useEffect, useLayoutEffect, useRef } from "react"; | ||
import { RouteContext, RouterContext } from "./context"; | ||
export const useNavigate = () => { | ||
const { push, pop, reset, replace } = useContext(RouterContext); | ||
return { push, pop, reset, replace }; | ||
const { push, pop, replace } = useContext(RouterContext); | ||
return { push, pop, replace }; | ||
}; | ||
@@ -10,2 +10,9 @@ export const useHistory = () => { | ||
}; | ||
export function useLocationState() { | ||
const location = useLocation(); | ||
if ("userState" in location.state) { | ||
return location.state.userState; | ||
} | ||
return {}; | ||
} | ||
export const useParams = () => { | ||
@@ -17,2 +24,5 @@ return useContext(RouteContext).params; | ||
}; | ||
export const useHash = () => { | ||
return useContext(RouterContext).history.location.hash; | ||
}; | ||
export const useSearch = () => { | ||
@@ -22,26 +32,29 @@ const { search } = useLocation(); | ||
}; | ||
export const useWillEnterEffect = (callback) => { | ||
const { lifecycle } = useContext(RouteContext); | ||
export const useLocationMatch = (callback) => { | ||
const { history: { location: currentLocation }, } = useContext(RouterContext); | ||
const location = useLocation(); | ||
const callbackRef = useRef(callback); | ||
callbackRef.current = callback; | ||
useEffect(() => { | ||
return lifecycle.attach("willEnter", callback); | ||
}, [callback, lifecycle]); | ||
if (location.key === currentLocation.key) { | ||
callbackRef.current(location); | ||
} | ||
}, [location, currentLocation.key]); | ||
}; | ||
export const useDidEnterEffect = (callback) => { | ||
/** | ||
* Screen lifecycle hooks | ||
*/ | ||
export const useWillEnterEffect = (callback) => useLifecycle("willEnter", callback); | ||
export const useDidEnterEffect = (callback) => useLifecycle("didEnter", callback); | ||
export const useWillExitEffect = (callback) => useLifecycle("willExit", callback); | ||
export const useDidExitEffect = (callback) => useLifecycle("didExit", callback); | ||
function useLifecycle(hook, callback) { | ||
const { lifecycle } = useContext(RouteContext); | ||
useEffect(() => { | ||
return lifecycle.attach("didEnter", callback); | ||
}, [callback, lifecycle]); | ||
}; | ||
export const useWillExitEffect = (callback) => { | ||
const { lifecycle } = useContext(RouteContext); | ||
useEffect(() => { | ||
return lifecycle.attach("willExit", callback); | ||
}, [callback, lifecycle]); | ||
}; | ||
export const useDidExitEffect = (callback) => { | ||
const { lifecycle } = useContext(RouteContext); | ||
useEffect(() => { | ||
return lifecycle.attach("didExit", callback); | ||
}, [callback, lifecycle]); | ||
}; | ||
const callbackRef = useRef(callback); | ||
callbackRef.current; | ||
useLayoutEffect(() => { | ||
const unsubscribe = lifecycle.attach(hook, () => callbackRef.current()); | ||
return () => unsubscribe(); | ||
}, [hook, lifecycle]); | ||
} | ||
//# sourceMappingURL=hooks.js.map |
@@ -5,5 +5,6 @@ export { createRouter } from "./createRouter"; | ||
export * from "./hooks"; | ||
export type { History } from "history"; | ||
export type { RouteProps, PathRouteProps, ComponentRouteProps } from "./component/Route"; | ||
export type { HistoryState, Router, PushOption, ReplaceOption, TransitionOption } from "./type"; | ||
export type { LocationState as HistoryState, Location, Router, PushOption, ReplaceOption, TransitionOption } from "./type"; | ||
export type { LifecycleHook } from "./screen/lifecycle"; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -1,5 +0,5 @@ | ||
import type { Location } from "history"; | ||
import { Lifecycle } from "./lifecycle"; | ||
import { Transition } from "./transition"; | ||
import type { Location } from "../type"; | ||
import type { TransitionType } from "./transition"; | ||
import { Transition } from "./transition"; | ||
export interface HistoryInfo { | ||
@@ -6,0 +6,0 @@ location: Location; |
@@ -32,4 +32,5 @@ import { Route } from "../route"; | ||
pop(): Promise<void>; | ||
replace(to: To, state?: Record<string, any>): Promise<void>; | ||
reset(): void; | ||
replace(to: To, state?: Record<string, any>): void; | ||
replaceHash(hash: string): void; | ||
private createKey; | ||
private notify; | ||
@@ -36,0 +37,0 @@ private getTopScreen; |
@@ -64,3 +64,3 @@ import { Action } from "history"; | ||
this.pushOption.value = option ?? null; | ||
this.stackHistory.push(to, option?.state); | ||
this.stackHistory.push(to, { $key: this.createKey(), userState: option?.state ?? {} }); | ||
return wait; | ||
@@ -73,10 +73,14 @@ } | ||
} | ||
async replace(to, state) { | ||
replace(to, state) { | ||
if (!this.matchRoute(to)) | ||
return; | ||
const wait = new Promise(resolve => (this.resolve.value = resolve)); | ||
this.stackHistory.replace(to, state); | ||
return wait; | ||
this.stackHistory.replace(to, { $key: this.stackHistory.location.state?.$key ?? this.createKey(), userState: state ?? {} }); | ||
} | ||
reset() { } | ||
replaceHash(hash) { | ||
const location = this.stackHistory.location; | ||
this.stackHistory.replace({ pathname: location.pathname, search: location.search, hash }, location.state?.userState ?? {}); | ||
} | ||
createKey() { | ||
return Date.now().toString(36) + Math.random().toString(36).substring(2); | ||
} | ||
notify() { | ||
@@ -83,0 +87,0 @@ this.subscribers.forEach(_ => _([...this.screens])); |
/** | ||
* Aim at detect popstate event triggered by Safari edge swipe gesture | ||
* Aim at detect popstate event triggered by mobile Safari edge swipe gesture | ||
* | ||
* for left edge swipe (back): clientX of touchend event is always be a negative value | ||
* for right edge swipe (forward): popstate event fired with only touchstart triggered | ||
* | ||
* therefore, if there are any popstate event fired within 300ms after above scenarios, it recognized as a native swipe back pop event | ||
@@ -6,0 +8,0 @@ */ |
/** | ||
* Aim at detect popstate event triggered by Safari edge swipe gesture | ||
* Aim at detect popstate event triggered by mobile Safari edge swipe gesture | ||
* | ||
* for left edge swipe (back): clientX of touchend event is always be a negative value | ||
* for right edge swipe (forward): popstate event fired with only touchstart triggered | ||
* | ||
* therefore, if there are any popstate event fired within 300ms after above scenarios, it recognized as a native swipe back pop event | ||
@@ -6,0 +8,0 @@ */ |
@@ -1,2 +0,3 @@ | ||
import type { History, Location, To, Update } from "history"; | ||
import type { History, To, Update } from "history"; | ||
import type { Location } from "../type"; | ||
export type Listener = (update: Update) => void; | ||
@@ -8,5 +9,5 @@ export interface StackHistory<S extends Record<string, any>> { | ||
pop: () => void; | ||
currentLocation: Location; | ||
location: Location<S>; | ||
} | ||
export declare const createStackHistory: <S extends Record<string, any>>(history: History) => StackHistory<S>; | ||
//# sourceMappingURL=stackHistory.d.ts.map |
@@ -33,6 +33,10 @@ import { Action } from "history"; | ||
const nextState = next.state; | ||
return nextState.__createAt > currentState.__createAt; | ||
if (isValidHistoryState(nextState) && isValidHistoryState(currentState)) { | ||
return nextState.__createAt > currentState.__createAt; | ||
} | ||
return false; | ||
}; | ||
const handler = ({ action, location }) => { | ||
switch (action) { | ||
const handler = (update) => { | ||
const location = update.location; | ||
switch (update.action) { | ||
case Action.Push: | ||
@@ -56,3 +60,3 @@ notify(Action.Push, location); | ||
listen, | ||
get currentLocation() { | ||
get location() { | ||
return currentLocation; | ||
@@ -62,2 +66,5 @@ }, | ||
}; | ||
function isValidHistoryState(object) { | ||
return typeof object === "object" && object !== null && "__createAt" in object; | ||
} | ||
//# sourceMappingURL=stackHistory.js.map |
import type React from "react"; | ||
import type { To } from "history"; | ||
import type { To, Location as HistoryLocation } from "history"; | ||
import type { RouteProps } from "./component/Route"; | ||
import type { TransitionType } from "./screen/transition"; | ||
import type { RouteContext } from "./context"; | ||
export type HistoryState = Record<string, any>; | ||
export type LocationState = Record<string, any>; | ||
export type Location<S extends Record<string, any> = Record<string, any>> = Omit<HistoryLocation, "state"> & { | ||
state: S; | ||
}; | ||
export interface TransitionOption { | ||
@@ -12,3 +14,3 @@ transition?: TransitionType; | ||
export interface PushOption extends TransitionOption { | ||
state?: HistoryState; | ||
state?: LocationState; | ||
} | ||
@@ -18,7 +20,4 @@ export interface ReplaceOption { | ||
add: TransitionOption; | ||
state?: HistoryState; | ||
state?: LocationState; | ||
} | ||
export interface RouteRenderBaseProps { | ||
$routeProps: RouteContext; | ||
} | ||
export interface Router { | ||
@@ -29,5 +28,5 @@ Root: React.ComponentType<React.PropsWithChildren>; | ||
pop: () => Promise<void>; | ||
replace: (to: To, state?: Record<string, any>) => Promise<void>; | ||
reset: () => void; | ||
replace: (to: To, state?: Record<string, any>) => void; | ||
replaceHash: (hash: string) => void; | ||
} | ||
//# sourceMappingURL=type.d.ts.map |
{ | ||
"name": "@pinnacle0/react-stack-router", | ||
"version": "0.1.3-beta.22", | ||
"version": "0.1.3-beta.23", | ||
"author": "Pinnacle", | ||
@@ -38,3 +38,2 @@ "license": "MIT", | ||
"react-dom": "18.2.0", | ||
"tsup": "7.1.0", | ||
"@pinnacle0/devtool-util": "1.2.7" | ||
@@ -41,0 +40,0 @@ }, |
import {createContext} from "react"; | ||
import type {History, Location} from "history"; | ||
import type {History} from "history"; | ||
import type {Lifecycle} from "./screen/lifecycle"; | ||
import type {Router} from "./type"; | ||
import type {Location, Router} from "./type"; | ||
export interface RouterContext extends Pick<Router, "push" | "replace" | "pop" | "reset"> { | ||
export interface RouterContext extends Pick<Router, "push" | "replace" | "pop"> { | ||
history: History; | ||
@@ -8,0 +8,0 @@ } |
@@ -1,9 +0,14 @@ | ||
import {useContext, useEffect} from "react"; | ||
import {useContext, useEffect, useLayoutEffect, useRef} from "react"; | ||
import {RouteContext, RouterContext} from "./context"; | ||
import type {History, Location} from "history"; | ||
import type {History} from "history"; | ||
import type {LocationState, Location} from "./type"; | ||
import type {LifecycleHook} from "./screen/lifecycle"; | ||
/** | ||
* Route History hooks | ||
*/ | ||
export type Navigate = Omit<RouterContext, "history">; | ||
export const useNavigate = (): Navigate => { | ||
const {push, pop, reset, replace} = useContext(RouterContext); | ||
return {push, pop, reset, replace}; | ||
const {push, pop, replace} = useContext(RouterContext); | ||
return {push, pop, replace}; | ||
}; | ||
@@ -15,3 +20,11 @@ | ||
export const useParams = <T extends Record<string, unknown>>(): T => { | ||
export function useLocationState<T extends LocationState>(): Partial<T> { | ||
const location = useLocation(); | ||
if ("userState" in location.state) { | ||
return location.state.userState; | ||
} | ||
return {}; | ||
} | ||
export const useParams = <T extends Record<string, string>>(): T => { | ||
return useContext(RouteContext).params as T; | ||
@@ -24,2 +37,6 @@ }; | ||
export const useHash = (): string => { | ||
return useContext(RouterContext).history.location.hash; | ||
}; | ||
export const useSearch = <T extends Record<string, unknown>>(): T => { | ||
@@ -30,32 +47,41 @@ const {search} = useLocation(); | ||
export const useWillEnterEffect = (callback: () => any) => { | ||
const {lifecycle} = useContext(RouteContext); | ||
export type LocationMatchCallback = (location: Location) => void; | ||
useEffect(() => { | ||
return lifecycle.attach("willEnter", callback); | ||
}, [callback, lifecycle]); | ||
}; | ||
export const useLocationMatch = (callback: LocationMatchCallback) => { | ||
const { | ||
history: {location: currentLocation}, | ||
} = useContext(RouterContext); | ||
const location = useLocation(); | ||
export const useDidEnterEffect = (callback: () => any) => { | ||
const {lifecycle} = useContext(RouteContext); | ||
const callbackRef = useRef(callback); | ||
callbackRef.current = callback; | ||
useEffect(() => { | ||
return lifecycle.attach("didEnter", callback); | ||
}, [callback, lifecycle]); | ||
if (location.key === currentLocation.key) { | ||
callbackRef.current(location); | ||
} | ||
}, [location, currentLocation.key]); | ||
}; | ||
export const useWillExitEffect = (callback: () => any) => { | ||
const {lifecycle} = useContext(RouteContext); | ||
/** | ||
* Screen lifecycle hooks | ||
*/ | ||
useEffect(() => { | ||
return lifecycle.attach("willExit", callback); | ||
}, [callback, lifecycle]); | ||
}; | ||
export const useWillEnterEffect = (callback: () => any) => useLifecycle("willEnter", callback); | ||
export const useDidExitEffect = (callback: () => any) => { | ||
export const useDidEnterEffect = (callback: () => any) => useLifecycle("didEnter", callback); | ||
export const useWillExitEffect = (callback: () => any) => useLifecycle("willExit", callback); | ||
export const useDidExitEffect = (callback: () => any) => useLifecycle("didExit", callback); | ||
function useLifecycle(hook: LifecycleHook, callback: () => void) { | ||
const {lifecycle} = useContext(RouteContext); | ||
const callbackRef = useRef(callback); | ||
callbackRef.current; | ||
useEffect(() => { | ||
return lifecycle.attach("didExit", callback); | ||
}, [callback, lifecycle]); | ||
}; | ||
useLayoutEffect(() => { | ||
const unsubscribe = lifecycle.attach(hook, () => callbackRef.current()); | ||
return () => unsubscribe(); | ||
}, [hook, lifecycle]); | ||
} |
@@ -5,4 +5,5 @@ export {createRouter} from "./createRouter"; | ||
export * from "./hooks"; | ||
export type {History} from "history"; | ||
export type {RouteProps, PathRouteProps, ComponentRouteProps} from "./component/Route"; | ||
export type {HistoryState, Router, PushOption, ReplaceOption, TransitionOption} from "./type"; | ||
export type {LocationState as HistoryState, Location, Router, PushOption, ReplaceOption, TransitionOption} from "./type"; | ||
export type {LifecycleHook} from "./screen/lifecycle"; |
@@ -1,5 +0,5 @@ | ||
import type {Location} from "history"; | ||
import {Lifecycle} from "./lifecycle"; | ||
import {Transition} from "./transition"; | ||
import type {Location} from "../type"; | ||
import type {TransitionType} from "./transition"; | ||
import {Transition} from "./transition"; | ||
@@ -6,0 +6,0 @@ export interface HistoryInfo { |
import {Action} from "history"; | ||
import type {Match} from "../route"; | ||
import {Route, formatPath} from "../route"; | ||
@@ -9,4 +8,5 @@ import {Screen} from "../screen"; | ||
import type React from "react"; | ||
import type {History, Location, Update, To} from "history"; | ||
import type {HistoryState, PushOption} from "../type"; | ||
import type {History, Update, To} from "history"; | ||
import type {LocationState, Location, PushOption} from "../type"; | ||
import type {Match} from "../route"; | ||
import type {StackHistory} from "./stackHistory"; | ||
@@ -17,2 +17,7 @@ import type {TransitionType} from "../screen/transition"; | ||
type InternalLocationState<S extends LocationState> = { | ||
$key: string; | ||
userState: S; | ||
}; | ||
export type StackRoutePattern = { | ||
@@ -32,3 +37,3 @@ pattern: string; | ||
private screens: Screen[] = []; | ||
private stackHistory: StackHistory<HistoryState>; | ||
private stackHistory: StackHistory<InternalLocationState<any>>; | ||
private subscribers = new Set<Subscriber>(); | ||
@@ -98,3 +103,3 @@ private route = new Route<StackRoutePayload>(); | ||
this.pushOption.value = option ?? null; | ||
this.stackHistory.push(to, option?.state); | ||
this.stackHistory.push(to, {$key: this.createKey(), userState: option?.state ?? {}}); | ||
@@ -110,11 +115,15 @@ return wait; | ||
async replace(to: To, state?: Record<string, any>): Promise<void> { | ||
replace(to: To, state?: Record<string, any>): void { | ||
if (!this.matchRoute(to)) return; | ||
this.stackHistory.replace(to, {$key: (this.stackHistory.location.state as any)?.$key ?? this.createKey(), userState: state ?? {}}); | ||
} | ||
const wait = new Promise<void>(resolve => (this.resolve.value = resolve)); | ||
this.stackHistory.replace(to, state); | ||
return wait; | ||
replaceHash(hash: string): void { | ||
const location = this.stackHistory.location; | ||
this.stackHistory.replace({pathname: location.pathname, search: location.search, hash}, location.state?.userState ?? {}); | ||
} | ||
reset() {} | ||
private createKey() { | ||
return Date.now().toString(36) + Math.random().toString(36).substring(2); | ||
} | ||
@@ -199,3 +208,3 @@ private notify() { | ||
case Action.Push: | ||
this.pushScreen(location, this.safariEdgeSwipeDetector.isForwardPop ? "none" : "both"); | ||
this.pushScreen(location as any, this.safariEdgeSwipeDetector.isForwardPop ? "none" : "both"); | ||
break; | ||
@@ -206,3 +215,3 @@ case Action.Pop: | ||
case Action.Replace: | ||
this.replaceScreen(location); | ||
this.replaceScreen(location as any); | ||
break; | ||
@@ -209,0 +218,0 @@ } |
/** | ||
* Aim at detect popstate event triggered by Safari edge swipe gesture | ||
* Aim at detect popstate event triggered by mobile Safari edge swipe gesture | ||
* | ||
* for left edge swipe (back): clientX of touchend event is always be a negative value | ||
* for right edge swipe (forward): popstate event fired with only touchstart triggered | ||
* | ||
* therefore, if there are any popstate event fired within 300ms after above scenarios, it recognized as a native swipe back pop event | ||
@@ -6,0 +8,0 @@ */ |
import {Action} from "history"; | ||
import type {History, Location, To, Update} from "history"; | ||
import type {History, To, Update} from "history"; | ||
import type {Location} from "../type"; | ||
@@ -16,3 +17,3 @@ interface InternalState { | ||
pop: () => void; | ||
currentLocation: Location; | ||
location: Location<S>; | ||
} | ||
@@ -46,3 +47,3 @@ | ||
const notify = (action: Action, location: Location) => { | ||
const notify = (action: Action, location: Location<S>) => { | ||
listeners.forEach(_ => _({action, location})); | ||
@@ -54,11 +55,15 @@ }; | ||
*/ | ||
const isForwardPop = (next: Location): boolean => { | ||
const isForwardPop = (next: Location<S>): boolean => { | ||
if (!currentLocation.state) return false; | ||
const currentState = currentLocation.state as InternalState; | ||
const nextState = next.state as InternalState; | ||
return nextState.__createAt > currentState.__createAt; | ||
const currentState = currentLocation.state as any; | ||
const nextState = next.state as any; | ||
if (isValidHistoryState(nextState) && isValidHistoryState(currentState)) { | ||
return nextState.__createAt > currentState.__createAt; | ||
} | ||
return false; | ||
}; | ||
const handler = ({action, location}: Update) => { | ||
switch (action) { | ||
const handler = (update: Update) => { | ||
const location = update.location as any; | ||
switch (update.action) { | ||
case Action.Push: | ||
@@ -84,6 +89,10 @@ notify(Action.Push, location); | ||
listen, | ||
get currentLocation() { | ||
return currentLocation; | ||
get location(): Location<S> { | ||
return currentLocation as any; | ||
}, | ||
}; | ||
}; | ||
function isValidHistoryState(object: unknown): object is Record<string, any> { | ||
return typeof object === "object" && object !== null && "__createAt" in object; | ||
} |
import type React from "react"; | ||
import type {To} from "history"; | ||
import type {To, Location as HistoryLocation} from "history"; | ||
import type {RouteProps} from "./component/Route"; | ||
import type {TransitionType} from "./screen/transition"; | ||
import type {RouteContext} from "./context"; | ||
export type HistoryState = Record<string, any>; | ||
export type LocationState = Record<string, any>; | ||
export type Location<S extends Record<string, any> = Record<string, any>> = Omit<HistoryLocation, "state"> & { | ||
state: S; | ||
}; | ||
export interface TransitionOption { | ||
@@ -15,3 +18,3 @@ transition?: TransitionType; | ||
export interface PushOption extends TransitionOption { | ||
state?: HistoryState; | ||
state?: LocationState; | ||
} | ||
@@ -22,9 +25,5 @@ | ||
add: TransitionOption; | ||
state?: HistoryState; | ||
state?: LocationState; | ||
} | ||
export interface RouteRenderBaseProps { | ||
$routeProps: RouteContext; | ||
} | ||
export interface Router { | ||
@@ -35,4 +34,4 @@ Root: React.ComponentType<React.PropsWithChildren>; | ||
pop: () => Promise<void>; | ||
replace: (to: To, state?: Record<string, any>) => Promise<void>; | ||
reset: () => void; | ||
replace: (to: To, state?: Record<string, any>) => void; | ||
replaceHash: (hash: string) => void; | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
147281
6
2376