import { LiveGameEventToken } from "../../../../game/nlcore/types"; import React from "react"; export declare const RootPath = "/"; export declare class LayoutRouter { /** * Get current path * @example * ```typescript * const router = new LayoutRouter(game, "/home"); * console.log(router.getCurrentPath()); // "/home" * * router.navigate("/about"); * console.log(router.getCurrentPath()); // "/about" * ``` */ getCurrentPath(): string; /** * Get pathname (path without query parameters) * @example * ```typescript * const router = new LayoutRouter(game); * router.navigate("/settings?tab=general&theme=dark"); * console.log(router.getPathname()); // "/settings" * ``` */ getPathname(): string; /** * Get current query parameters * @example * ```typescript * const router = new LayoutRouter(game); * router.navigate("/settings?tab=general&theme=dark"); * console.log(router.getCurrentQuery()); // { tab: "general", theme: "dark" } * ``` */ getCurrentQuery(): Record; /** * Get query parameters (alias for getCurrentQuery) * @example * ```typescript * const router = new LayoutRouter(game); * router.navigate("/profile?user=john&tab=info"); * console.log(router.getQueryParams()); // { user: "john", tab: "info" } * ``` */ getQueryParams(): Record; /** * Get current full URL (path + query) * @example * ```typescript * const router = new LayoutRouter(game); * router.navigate("/settings", { tab: "general", theme: "dark" }); * console.log(router.getCurrentUrl()); // "/settings?tab=general&theme=dark" * ``` */ getCurrentUrl(): string; /** * Parse URL into path and query parameters * @param url URL string, e.g. "/me/settings?a=1&b=2" * @returns Object with path and query * @example * ```typescript * const router = new LayoutRouter(game); * const result = router.parseUrl("/me/settings?tab=general&theme=dark"); * console.log(result.path); // "/me/settings" * console.log(result.query); // { tab: "general", theme: "dark" } * * const simple = router.parseUrl("/about"); * console.log(simple.path); // "/about" * console.log(simple.query); // {} * ``` */ parseUrl(url: string): { path: string; query: Record; }; /** * Build URL from path and query parameters * @param path Path string * @param query Query parameters object * @returns Full URL string * @example * ```typescript * const router = new LayoutRouter(game); * * const url1 = router.buildUrl("/settings", { tab: "general", theme: "dark" }); * console.log(url1); // "/settings?tab=general&theme=dark" * * const url2 = router.buildUrl("/about", {}); * console.log(url2); // "/about" * * const url3 = router.buildUrl("/profile", { user: "john", tab: "info" }); * console.log(url3); // "/profile?user=john&tab=info" * ``` */ buildUrl(path: string, query: Record): string; /** * Get query parameter value * @param key Parameter key * @returns Parameter value or undefined if not found * @example * ```typescript * const router = new LayoutRouter(game); * router.navigate("/settings?tab=general&theme=dark"); * * console.log(router.getQueryParam("tab")); // "general" * console.log(router.getQueryParam("theme")); // "dark" * console.log(router.getQueryParam("nonexistent")); // undefined * ``` */ getQueryParam(key: string): string | undefined; /** * Set query parameter * @param key Parameter key * @param value Parameter value * @example * ```typescript * const router = new LayoutRouter(game, "/settings"); * * router.setQueryParam("tab", "general"); * console.log(router.getCurrentUrl()); // "/settings?tab=general" * * router.setQueryParam("theme", "dark"); * console.log(router.getCurrentUrl()); // "/settings?tab=general&theme=dark" * ``` */ setQueryParam(key: string, value: string): this; /** * Set multiple query parameters * @param params Object with key-value pairs * @example * ```typescript * const router = new LayoutRouter(game, "/settings"); * * router.setQueryParams({ * tab: "general", * theme: "dark", * lang: "en" * }); * console.log(router.getCurrentUrl()); // "/settings?tab=general&theme=dark&lang=en" * ``` */ setQueryParams(params: Record): this; /** * Remove query parameter * @param key Parameter key to remove * @example * ```typescript * const router = new LayoutRouter(game); * router.navigate("/settings?tab=general&theme=dark&lang=en"); * * router.removeQueryParam("theme"); * console.log(router.getCurrentUrl()); // "/settings?tab=general&lang=en" * ``` */ removeQueryParam(key: string): this; /** * Clear all query parameters * @example * ```typescript * const router = new LayoutRouter(game); * router.navigate("/settings?tab=general&theme=dark&lang=en"); * * router.clearQueryParams(); * console.log(router.getCurrentUrl()); // "/settings" * console.log(router.getCurrentQuery()); // {} * ``` */ clearQueryParams(): this; /** * Check if query parameter exists * @param key Parameter key * @returns Whether parameter exists * @example * ```typescript * const router = new LayoutRouter(game); * router.navigate("/settings?tab=general&theme=dark"); * * console.log(router.hasQueryParam("tab")); // true * console.log(router.hasQueryParam("theme")); // true * console.log(router.hasQueryParam("nonexistent")); // false * ``` */ hasQueryParam(key: string): boolean; /** * Get all query parameter keys * @returns Array of parameter keys * @example * ```typescript * const router = new LayoutRouter(game); * router.navigate("/settings?tab=general&theme=dark&lang=en"); * * console.log(router.getQueryParamKeys()); // ["tab", "theme", "lang"] * ``` */ getQueryParamKeys(): string[]; /** * Get query parameter count * @returns Number of query parameters * @example * ```typescript * const router = new LayoutRouter(game); * router.navigate("/settings?tab=general&theme=dark&lang=en"); * * console.log(router.getQueryParamCount()); // 3 * * router.clearQueryParams(); * console.log(router.getQueryParamCount()); // 0 * ``` */ getQueryParamCount(): number; /** * Get history records * @example * ```typescript * const router = new LayoutRouter(game, "/home"); * router.navigate("/about"); * router.navigate("/contact"); * * console.log(router.getHistory()); // ["/home", "/about", "/contact"] * ``` */ getHistory(): string[]; /** * Get current history index * @example * ```typescript * const router = new LayoutRouter(game, "/home"); * router.navigate("/about"); * router.navigate("/contact"); * * console.log(router.getHistoryIndex()); // 2 * * router.back(); * console.log(router.getHistoryIndex()); // 1 * ``` */ getHistoryIndex(): number; /** * Check if can go back * @example * ```typescript * const router = new LayoutRouter(game, "/home"); * console.log(router.canGoBack()); // false * * router.navigate("/about"); * console.log(router.canGoBack()); // true * * router.back(); * console.log(router.canGoBack()); // false * ``` */ canGoBack(): boolean; /** * Check if can go forward * @example * ```typescript * const router = new LayoutRouter(game, "/home"); * router.navigate("/about"); * router.navigate("/contact"); * * console.log(router.canGoForward()); // false * * router.back(); * console.log(router.canGoForward()); // true * * router.back(); * console.log(router.canGoForward()); // true * ``` */ canGoForward(): boolean; /** * Navigate to new path * @param path Target path, e.g. "/me/settings?a=1&b=2" or "./settings" or "../parent" * @param queryParams Optional query parameters to append to the path * @example * ```typescript * const router = new LayoutRouter(game, "/home"); * * // Navigate to absolute path * router.navigate("/about"); * console.log(router.getCurrentPath()); // "/about" * * // Navigate with query parameters * router.navigate("/settings", { tab: "general", theme: "dark" }); * console.log(router.getCurrentUrl()); // "/settings?tab=general&theme=dark" * * // Navigate to relative path * router.navigate("./profile"); * console.log(router.getCurrentPath()); // "/profile" * * // Navigate to parent directory * router.navigate("../parent"); * console.log(router.getCurrentPath()); // "/parent" * ``` */ navigate(path: string, queryParams?: Record): this; /** * Go back to previous path * @example * ```typescript * const router = new LayoutRouter(game, "/home"); * router.navigate("/about"); * router.navigate("/contact"); * * router.back(); * console.log(router.getCurrentPath()); // "/about" * * router.back(); * console.log(router.getCurrentPath()); // "/home" * * router.back(); // No effect, already at the beginning * console.log(router.getCurrentPath()); // "/home" * ``` */ back(): this; /** * Go forward to next path * @example * ```typescript * const router = new LayoutRouter(game, "/home"); * router.navigate("/about"); * router.navigate("/contact"); * * router.back(); // Go to "/about" * router.back(); // Go to "/home" * * router.forward(); // Go to "/about" * console.log(router.getCurrentPath()); // "/about" * * router.forward(); // Go to "/contact" * console.log(router.getCurrentPath()); // "/contact" * ``` */ forward(): this; /** * Replace current path (without adding to history) * @param path New path, supports relative paths like "./settings" or "../parent" * @param queryParams Optional query parameters to append to the path * @example * ```typescript * const router = new LayoutRouter(game, "/home"); * router.navigate("/about"); * router.navigate("/contact"); * * // Replace current path without affecting history * router.replace("/settings", { tab: "general" }); * console.log(router.getCurrentPath()); // "/settings" * console.log(router.getCurrentUrl()); // "/settings?tab=general" * * // Can still go back to previous paths * router.back(); * console.log(router.getCurrentPath()); // "/about" * ``` */ replace(path: string, queryParams?: Record): this; /** * Clear history records * @example * ```typescript * const router = new LayoutRouter(game, "/home"); * router.navigate("/about"); * router.navigate("/contact"); * * router.clear(); * console.log(router.getCurrentPath()); // "" * console.log(router.getHistory()); // [] * console.log(router.isActive()); // false * ``` */ clear(): this; /** * Clean history records, keep only current path * @example * ```typescript * const router = new LayoutRouter(game, "/home"); * router.navigate("/about"); * router.navigate("/contact"); * * router.cleanHistory(); * console.log(router.getHistory()); // ["/contact"] * * // Cannot go back anymore * console.log(router.canGoBack()); // false * ``` */ cleanHistory(): this; /** * Parse path into segments * @param path Path string, e.g. "/me/settings/a" * @returns Path segments array, e.g. ["me", "settings", "a"] * @example * ```typescript * const router = new LayoutRouter(game); * * console.log(router.parsePath("/me/settings/a")); // ["me", "settings", "a"] * console.log(router.parsePath("/about")); // ["about"] * console.log(router.parsePath("/")); // [] * console.log(router.parsePath("")); // [] * ``` */ parsePath(path: string): string[]; /** * Build path string * @param segments Path segments array * @returns Path string * @example * ```typescript * const router = new LayoutRouter(game); * * console.log(router.buildPath(["me", "settings", "a"])); // "/me/settings/a" * console.log(router.buildPath(["about"])); // "/about" * console.log(router.buildPath([])); // "/" * ``` */ buildPath(segments: string[]): string; /** * Get parent path of current path * @param path Current path * @returns Parent path, returns empty string if no parent * @example * ```typescript * const router = new LayoutRouter(game); * * console.log(router.getParentPath("/me/settings/a")); // "/me/settings" * console.log(router.getParentPath("/me/settings")); // "/me" * console.log(router.getParentPath("/me")); // "" * console.log(router.getParentPath("/")); // "" * ``` */ getParentPath(path: string): string; /** * Check if path matches pattern (supports prefix matching for nested layouts) * @param path Path to check * @param pattern Match pattern, supports wildcard * and parameters :param * @returns Whether matches * @example * ```typescript * const router = new LayoutRouter(game); * * // Exact match * console.log(router.matchPath("/about", "/about")); // true * console.log(router.matchPath("/about", "/contact")); // false * * // Prefix match (for nested layouts) * console.log(router.matchPath("/settings/sound", "/settings")); // true * console.log(router.matchPath("/settings/sound/char", "/settings")); // true * console.log(router.matchPath("/settings/sound", "/settings/sound")); // true * * // Wildcard match * console.log(router.matchPath("/user/123/profile", "/user/*" + "/profile")); // true * console.log(router.matchPath("/user/123/settings", "/user/*" + "/profile")); // false * * // Parameter match * console.log(router.matchPath("/user/123/profile", "/user/:id/profile")); // true * console.log(router.matchPath("/user/abc/profile", "/user/:id/profile")); // true * * // Mixed pattern * console.log(router.matchPath("/user/123/profile/edit", "/user/:id/*" + "/edit")); // true * ``` */ matchPath(path: string, pattern: string): boolean; /** * Check if path exactly matches pattern (requires exact segment count) * @param path Path to check * @param pattern Match pattern, supports wildcard * and parameters :param * @returns Whether exactly matches * @example * ```typescript * const router = new LayoutRouter(game); * * // Exact match * console.log(router.exactMatch("/about", "/about")); // true * console.log(router.exactMatch("/about", "/contact")); // false * * // No prefix matching (unlike matchPath) * console.log(router.exactMatch("/settings/sound", "/settings")); // false * console.log(router.exactMatch("/settings", "/settings")); // true * console.log(router.exactMatch("/settings/sound", "/settings/sound")); // true * * // Wildcard match (exact segment count required) * console.log(router.exactMatch("/user/123/profile", "/user/*" + "/profile")); // true * console.log(router.exactMatch("/user/123/profile/edit", "/user/*" + "/profile")); // false * * // Parameter match (exact segment count required) * console.log(router.exactMatch("/user/123/profile", "/user/:id/profile")); // true * console.log(router.exactMatch("/user/123", "/user/:id/profile")); // false * ``` */ exactMatch(path: string, pattern: string): boolean; /** * Extract path parameters * @param path Actual path * @param pattern Pattern with parameters, e.g. "/user/:id/profile/:tab" * @returns Parameter object * @example * ```typescript * const router = new LayoutRouter(game); * * const params1 = router.extractParams("/user/123/profile", "/user/:id/profile"); * console.log(params1); // { id: "123" } * * const params2 = router.extractParams("/user/456/profile/settings", "/user/:id/profile/:tab"); * console.log(params2); // { id: "456", tab: "settings" } * * const params3 = router.extractParams("/about", "/user/:id/profile"); * console.log(params3); // {} (no match) * ``` */ extractParams(path: string, pattern: string): Record; /** * Event listener for exit complete * @example * ```typescript * const router = new LayoutRouter(game); * * const token = router.onExitComplete(() => { * console.log("Page exit animation completed"); * // Clean up resources, show loading indicator, etc. * }); * * // Later, remove the listener * token.off(); * ``` */ onExitComplete(handler: () => void): LiveGameEventToken; /** * Event listener for exit complete (once) * @example * ```typescript * const router = new LayoutRouter(game); * * router.onceExitComplete(() => { * console.log("Page exit completed, this will only fire once"); * // Perform one-time cleanup * }); * ``` */ onceExitComplete(handler: () => void): LiveGameEventToken; /** * Event listener for page mount * @example * ```typescript * const router = new LayoutRouter(game); * * const token = router.onPageMount(() => { * console.log("New page mounted"); * // Initialize page-specific features, load data, etc. * }); * * // Later, remove the listener * token.off(); * ``` */ onPageMount(handler: () => void): LiveGameEventToken; /** * Event listener for page mount (once) * @example * ```typescript * const router = new LayoutRouter(game); * * router.oncePageMount(() => { * console.log("Page mounted, this will only fire once"); * // Perform one-time initialization * }); * ``` */ oncePageMount(handler: () => void): LiveGameEventToken; /** * Resolve relative path to absolute path * @param path Path to resolve, can be absolute or relative * @returns Resolved absolute path * @example * ```typescript * const router = new LayoutRouter(game, "/user/settings"); * * // Absolute paths * console.log(router.resolvePath("/about")); // "/about" * console.log(router.resolvePath("/user/profile")); // "/user/profile" * * // Relative paths * console.log(router.resolvePath("./profile")); // "/user/profile" * console.log(router.resolvePath("../admin")); // "/admin" * console.log(router.resolvePath("../../home")); // "/home" * * // Complex relative paths * console.log(router.resolvePath("./.././profile")); // "/profile" * console.log(router.resolvePath("../../user/./settings")); // "/user/settings" * ``` */ resolvePath(path: string): string; /** * Normalize path by removing duplicate slashes and trailing slashes * @param path Path to normalize * @returns Normalized path * @example * ```typescript * const router = new LayoutRouter(game); * * console.log(router.normalizePath("/home//about/")); // "/home/about" * console.log(router.normalizePath("//home//about//")); // "/home/about" * console.log(router.normalizePath("/home")); // "/home" * console.log(router.normalizePath("home")); // "home" * ``` */ normalizePath(path: string): string; /** * Join multiple path segments into a single path * @param path Base path * @param paths Additional path segments to join * @returns Joined and normalized path * @example * ```typescript * const router = new LayoutRouter(game); * * // Basic path joining * console.log(router.joinPath("/home", "about")); // "/home/about" * console.log(router.joinPath("/user", "profile", "settings")); // "/user/profile/settings" * * // Handle paths without leading slash * console.log(router.joinPath("home", "about")); // "/home/about" * * // Handle multiple segments * console.log(router.joinPath("/api", "v1", "users", "123")); // "/api/v1/users/123" * * // Normalize duplicate slashes * console.log(router.joinPath("/home//", "//about")); // "/home/about" * * // Handle empty segments * console.log(router.joinPath("/home", "", "about")); // "/home/about" * ``` */ joinPath(path: string, ...paths: string[]): string; } export declare function RouterProvider({ children }: { children: React.ReactNode; }): React.JSX.Element; export declare function useRouter(): LayoutRouter;