type NavType = "load" | "back" | "forward" | "go" | "push"; /** * The class for the global `route` object. */ export interface Route { /** The current path of the URL as a string. For instance `"/"` or `"/users/123/feed"`. Paths are normalized to always start with a `/` and never end with a `/` (unless it's the root path). */ path: string; /** An convenience array containing path segments, mapping to `path`. For instance `[]` (for `"/"`) or `['users', '123', 'feed']` (for `"/users/123/feed"`). */ p: string[]; /** The hash fragment including the leading `#`, or an empty string. For instance `"#my_section"` or `""`. */ hash: string; /** The query string interpreted as search parameters. So `"a=x&b=y"` becomes `{a: "x", b: "y"}`. */ search: Record; /** An object to be used for any additional data you want to associate with the current page. Data should be JSON-compatible. */ state: Record; /** The navigation depth of the current session. Starts at 1. Writing to this property has no effect. */ depth: number; /** The navigation action that got us to this page. Writing to this property has no effect. - `"load"`: An initial page load. - `"back"` or `"forward"`: When we navigated backwards or forwards in the stack. - `"go"`: When we added a new page on top of the stack. - `"push"`: When we added a new page on top of the stack, merging with the current page. Mostly useful for page transition animations. Writing to this property has no effect. */ nav: NavType; } /** * Configure logging on route changes. * @param value `true` to enable logging to console, `false` to disable logging, or a custom logging function. Defaults to `false`. */ export declare function setLog(value: boolean | ((...args: any[]) => void)): void; /** * A navigation guard, as registered by {@link setGuard}: called with the route * we're about to move to and the route we're at now, before the change is * applied. Return `false` — or a promise resolving to `false` — to veto the * change; any other return value lets it through. */ export type RouteGuard = (to: Route, from: Route) => boolean | Promise; /** * Register a navigation guard, or unregister it by passing `null`. At most one * guard can be registered at a time; the previously registered guard (or * `null`) is returned, so a temporary guard can be chained or restored later. * * The guard is consulted before any *navigation* is applied — any change of * history entry, meaning {@link go} / {@link push}, {@link back} / {@link up}, * and the browser's own back/forward buttons (`popstate`) — as well as before * in-place changes to `path` or `search` through the {@link current} proxy. * Same-page tweaks — mutating `current.state` (like {@link persistScroll} * saving scroll positions) or `current.hash`, and the browser jumping to a * `#fragment` — are applied without consulting the guard. * * When the guard returns (a promise of) `false`: * * - a `go()`/`back()`/`up()` call does nothing, and reports `false`; * - a browser back/forward is undone, by travelling the exact number of * history entries back to where we were — the depth delta is known, so even * a multi-entry jump (a long-press on the back button) restores correctly; * - a direct `route.current` mutation is reverted in place. With an *async* * guard the proxy is reverted while the verdict is pending and re-applied if * it passes — prefer `go()` for changes a guard may need to think about. * * While a verdict is pending, other attempted route changes are refused. A * browser navigation arriving in the meantime supersedes the change the guard * was being asked about — that change is dropped (reporting `false`) and, * once the verdict settles, the guard is consulted about wherever the browser * has ended up instead. * * The guard is invoked outside of any reactive scope (reading proxied state in * it doesn't subscribe anything), and receives plain copies of the routes, so * mutating them has no effect. A guard that throws counts as a veto. A guard * may itself navigate, enabling the redirect pattern: * * ```js * route.setGuard(to => { * if (to.path.startsWith('/admin') && !user.isAdmin) { * route.go('/login'); // recursively consults (and passes) the guard * return false; * } * return true; * }); * ``` */ export declare function setGuard(newGuard: RouteGuard | null): RouteGuard | null; type RouteTarget = string | (string | number)[] | Partial, "search"> & { /** An convenience array containing path segments, mapping to `path`. For instance `[]` (for `"/"`) or `['users', 123, 'feed']` (for `"/users/123/feed"`). Values may be integers but will be converted to strings.*/ p: (string | number)[]; /** The query string interpreted as search parameters. So `"a=x&b=y"` becomes `{a: "x", b: "y", c: 42}`. Values may be integers but will be converted to strings. */ search: Record; }>; /** * Navigate to a new URL by pushing a new history entry. * * Note that this happens synchronously, immediately updating `route` and processing any reactive updates based on that. * * @param target A subset of the {@link Route} properties to navigate to. If neither `p` nor `path` is given, the current path is used. For other properties, an empty/default value is assumed if not given. For convenience: * - You may pass a string instead of an object, which is interpreted as the `path`. * - You may pass an array instead of an object, which is interpreted as the `p` array. * - If you pass `p`, it may contain numbers, which will be converted to strings. * - If you pass `search`, its values may be numbers, which will be converted to strings. * * Examples: * ```js * // Navigate to /users/123 * route.go("/users/123"); * * // Navigate to /users/123?tab=feed#top * route.go({p: ["users", 123], search: {tab: "feed"}, hash: "top"}); * ``` * * @returns Whether the navigation was performed — `false` when a guard (see * {@link setGuard}) vetoed it. Without a guard, or with one that answers * synchronously, this stays a synchronous `boolean`; an async guard makes it a * promise, and the navigation is applied when (and if) that verdict passes. * Beware that a promise is truthy: `await` the result before branching on it, * unless you know the guard answers synchronously. */ export declare function go(target: RouteTarget, nav?: NavType): boolean | Promise; /** * Returns `true` if the current route matches `target`. * * Path must match exactly. Any search params specified in `target` must be present * in the current URL, but extra params in the current URL are allowed. * * Reactive: only reevaluates when the path changes to/from the target path, and * when target k/v search pairs are (un)set. * * Primary usage: 'active' status for menu items. * * @example * ```js * // This example assumes interceptLinks() has been called * A('a.my-button text=Users href=/users .is-active=', route.matchCurrent('/users')); * * // Alternatively a route object can be given * route.matchCurrent({path: '/users', search: {tab: 'profile'}}); * ``` */ export declare function matchCurrent(target: RouteTarget): boolean; /** * Modify the current route by merging `target` into it (using {@link aberdeen.merge | A.merge}), pushing a new history entry. * * This is useful for things like opening modals or side panels, where you want a browser back action to return to the previous state. * * @param target Same as for {@link go}, but merged into the current route instead deleting all state. * @param nav The navigation type to use. Defaults to `undefined`, meaning the navigation type is unchanged from the current route, * preventing unwanted page transition animations. * @returns The {@link go} verdict: `false` when a guard vetoed the navigation. */ export declare function push(target: RouteTarget, nav?: NavType): boolean | Promise; /** * Try to go back in history to the first entry that matches the given target. If none is found, the given state will replace the current page. This is useful for "cancel" or "close" actions that should return to the previous page if possible, but create a new page if not (for instance when arriving at the current page through a direct link). * * Consider using {@link up} to go up in the path hierarchy. * * @param target The target route to go back to. May be a subset of {@link Route}, or a string (for `path`), or an array of strings (for `p`). * @param fallback Defaults merged *under* `target` when no matching history * entry exists and the current one is replaced instead. Deliberately not part * of the match: use it for things (say, a `state`) that the replacement route * should carry but that a history entry needn't have to count as a match. * @returns A promise resolving `true` once we've landed — on the matched * history entry, or on the replacement — and `false` when a guard (see * {@link setGuard}) vetoed the change, or when another navigation superseded * the travel before it landed. */ export declare function back(target?: RouteTarget, fallback?: RouteTarget): Promise; /** * Navigate up in the path hierarchy, by going back to the first history entry * that has a shorter path than the current one. If there's none, we just shorten * the current path. * * Note that going back in browser history happens asynchronously, so `route` will not be updated immediately. * * @returns Like {@link back}: a promise resolving `true` once we've landed, * `false` when a guard vetoed the change or another navigation superseded it. */ export declare function up(stripCount?: number): Promise; /** * The global {@link Route} object reflecting the current URL and browser history state. Changes you make to this affect the current browser history item (modifying the URL if needed). */ export declare const current: Route; /** * Restore and store the vertical and horizontal scroll position for * the parent element to the page state. * * @param {string} name - A unique (within this page) name for this * scrollable element. Defaults to 'main'. * * The scroll position will be persisted in `route.aux.scroll.`. */ export declare function persistScroll(name?: string): void; /** * A link handler, as optionally passed to {@link interceptLinks}: called for * every local-link activation that passed the built-in exclusions, with the * resolved URL, the anchor element the activation landed on, and the DOM event. * * - Return `false` to leave the link to the browser (no `preventDefault`). * - Return `true` to claim the link: default handling is prevented and the * handler is assumed to have navigated (or decided not to) itself. * - Return nothing for the default: prevent and `go(href)`. */ export type LinkHandler = (url: URL, anchor: HTMLAnchorElement, event: Event) => boolean | void; /** * Intercept clicks and Enter key presses on links (`` tags) and use Aberdeen routing * instead of browser navigation for local paths (paths without a protocol or host). * * This allows you to use regular HTML anchor tags for navigation without needing to * manually attach click handlers to each link. * * Links with a `target` or `download` attribute, external/protocol links, * hash-only links, modified clicks (ctrl/cmd/shift/alt, non-primary buttons) * and events something else already handled (`defaultPrevented`) are left to * the browser. * * @param handler Optional {@link LinkHandler}, for routing systems that need to * decide *how* to navigate (say, based on where in the DOM the link sits) * without re-implementing link interception. It's consulted for every link * that passed the exclusions above; see {@link LinkHandler} for its protocol. * * @example * ```js * // In your root component: * route.interceptLinks(); * * // Now you can use regular anchor tags: * A('a text=About href=/corporate/about'); * ``` */ export declare function interceptLinks(handler?: LinkHandler): void; export {};