UNPKG

rvx

Version:

A signal based rendering library

330 lines (318 loc) 9.48 kB
/*! This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>. */ import { Expression } from './rvx.js'; import { Context } from './rvx.js'; import { Component } from './rvx.js'; import { View } from './rvx.js'; /** * Represents URL search parameters. */ declare class Query { #private; constructor(raw: string, params?: URLSearchParams); static from(init: QueryInit): Query | undefined; get raw(): string; get params(): URLSearchParams; } type QueryInit = ConstructorParameters<typeof URLSearchParams>[0]; /** * Format the specified query for use in a URL. * * Strings are returned as is. */ declare function formatQuery(value: QueryInit): string; /** * Represents a path with optional query parameters that may change over time. */ interface Router { /** * The root router. */ get root(): Router; /** * The parent of this router if any. */ get parent(): Router | undefined; /** * Reactively get the remaining normalized path in this context. */ get path(): string; /** * Reactively get the search parameters in this context. */ get query(): Query | undefined; /** * Navigate to the specified path within the path this router is mounted in. * * @param path The path. This may not be normalized. * @param query The query part. * * @example * ```tsx * import { ROUTER } from "rvx/router"; * * ROUTER.current!.root.push("/home"); * ``` */ push(path: string, query?: QueryInit): void; /** * Same as {@link push}, but replaces the URL in history if possible. * * @example * ```tsx * import { ROUTER } from "rvx/router"; * * ROUTER.current!.root.replace("/home"); * ``` */ replace(path: string, query?: QueryInit): void; } /** * Context for the current router. */ declare const ROUTER: Context<Router | undefined>; /** * A router that is located at a specific path and navigates within that path. */ declare class ChildRouter implements Router { #private; /** * Create a new child router. * * @param parent The parent router. * @param mountPath The path this router is mounted at. * @param path An expression to get the normalized rest path. */ constructor(parent: Router, mountPath: string, path: Expression<string>); get root(): Router; get parent(): Router | undefined; get path(): string; get query(): Query | undefined; push(path: string, query?: QueryInit): void; replace(path: string, query?: QueryInit): void; } interface HashRouterOptions { /** * The current location is parsed when one of these events occur. * * @default ["hashchange"] */ parseEvents?: string[]; } /** * A router that uses `location.hash` as the path ignoring the leading `"#"`. * * Everything after the first `"?"` is treated as query parameters. */ declare class HashRouter implements Router { #private; constructor(options?: HashRouterOptions); /** * Called to parse & update this router's state from the current browser location. */ parse(): void; get root(): Router; get parent(): Router | undefined; get path(): string; get query(): Query | undefined; push(path: string, query?: QueryInit): void; replace(path: string, query?: QueryInit): void; } interface HistoryRouterOptions { /** * The current location is parsed when one of these events occur. * * @default ["popstate", "rvx:router:update"] */ parseEvents?: string[]; /** * The leading base path to ignore when matching routes. * * @default "" */ basePath?: string; } /** * A router that uses the history API. */ declare class HistoryRouter implements Router { #private; constructor(options?: HistoryRouterOptions); /** * Called to parse & update this router's state from the current browser location. */ parse(): void; get root(): Router; get parent(): Router | undefined; get path(): string; get query(): Query | undefined; push(path: string, query?: QueryInit): void; replace(path: string, query?: QueryInit): void; } interface MemoryRouterOptions { /** * The initial path. */ path?: string; /** * The initial query. */ query?: QueryInit; parent?: Router; } /** * A router that keeps its state in memory instead of the browser location. */ declare class MemoryRouter implements Router { #private; constructor(options?: MemoryRouterOptions); get root(): Router; get parent(): Router | undefined; get path(): string; get query(): Query | undefined; push(path: string, query?: QueryInit): void; replace(path: string, query?: QueryInit): void; } /** * Normalize a path: * + Empty paths are represented as an empty string. * + Non-empty paths start with a slash. * * @param path The path to normalize. * @param preserveDir True to keep trailing slashes in non-empty paths. Default is `true`. * @returns The normalized path. */ declare function normalize(path: string, preserveDir?: boolean): string; /** * Join two paths. * * Note, that this dosn't handle empty, ".." or "." parts. * * @param parent The parent path. * @param child The child path. * @param preserveDir True to keep trailing slashes. Default is `true`. * @returns A {@link normalize normalized} path. */ declare function join(parent: string, child: string, preserveDir?: boolean): string; /** * Get a normalized relative path. * * Note, that this dosn't handle empty, ".." or "." parts, but inserts ".." parts if necessary. * * @param from The path from which the relative path starts. * @param to The path to which the relative path points. * @param preserveDir True to keep trailing slashes from the `to` path. Trailing slashes from the `from` path are always discarded. Default is `true`. * @returns A {@link normalize normalized} path. */ declare function relative(from: string, to: string, preserveDir?: boolean): string; interface RouteMatchResult { /** * The normalized matched path. */ path: string; /** * The parameters extracted from the matched path. */ params?: unknown; } interface RouteMatchFn { /** * Check if this route matches the specified path. * * @param path The path to match against. * @returns The match result or undefined if the path doesn't match. */ (path: string): RouteMatchResult | undefined; } interface Route { /** * The paths this route matches. */ match?: string | RegExp | RouteMatchFn; } interface ParentRouteMatch<T extends Route> { /** * The route that has been matched. */ route: T; /** * The normalized matched path. */ path: string; /** * The parameters extracted from the matched path. */ params?: unknown; } interface RouteMatch<T extends Route> extends ParentRouteMatch<T> { /** * The normalized remaining rest path. */ rest: string; } /** * Match a route against the specified path. * * @param path The {@link normalize normalized} path to match against. Non normalized paths result in undefined behavior. * @param route The route to match. * @returns A match or undefined if the route doesn't match. */ declare function matchRoute<T extends Route>(path: string, route: T): RouteMatch<T> | undefined; interface WatchedRoutes<T extends Route> { match: () => ParentRouteMatch<T> | undefined; rest: () => string; } /** * Watch and match routes against an expression. * * @param path The normalized path. * @param routes The routes to watch. * @returns An object with individually watchable route match and the unmatched rest path. */ declare function watchRoutes<T extends Route>(path: Expression<string>, routes: Expression<Iterable<T>>): WatchedRoutes<T>; /** * Props passed to the root component of a {@link ComponentRoute}. */ interface RouteProps<P = unknown> { /** Matched route parameters. */ params: P; } /** * A route where the content is a component to render. */ interface ComponentRoute<P = unknown> extends Route { content: Component<RouteProps<P>>; } /** * Match and render routes in the current context. * * A {@link ChildRouter} is provided as a replacement for the current router when rendering route content. */ declare function routes(routes: Expression<Iterable<ComponentRoute<any>>>): View; /** * Match and render routes in the current context. * * A {@link ChildRouter} is provided as a replacement for the current router when rendering route content. */ declare function Routes(props: { /** * The routes to match. */ routes: Expression<Iterable<ComponentRoute<any>>>; }): View; /** * Check if the specified pattern matches the current router's rest path. */ declare function isCurrent(match: Route["match"], router?: Router): boolean; export { ChildRouter, HashRouter, HistoryRouter, MemoryRouter, Query, ROUTER, Routes, formatQuery, isCurrent, join, matchRoute, normalize, relative, routes, watchRoutes }; export type { ComponentRoute, HashRouterOptions, HistoryRouterOptions, MemoryRouterOptions, ParentRouteMatch, QueryInit, Route, RouteMatch, RouteMatchFn, RouteMatchResult, RouteProps, Router, WatchedRoutes };