import * as React from 'react'; import React__default, { ReactNode, ReactElement } from 'react'; interface StoryData { viewMode?: string; storyId?: string; refId?: string; } declare const parsePath: (path: string | undefined) => StoryData; interface Args { [key: string]: any; } declare const DEEPLY_EQUAL: unique symbol; declare const deepDiff: (value: any, update: any) => any; declare const buildArgsParam: (initialArgs: Args | undefined, args: Args) => string; interface Query { [key: string]: any; } declare const queryFromLocation: (location: Partial) => Query; declare const stringifyQuery: (query: Query) => string; type Match$1 = { path: string; }; declare const getMatch: (current: string, target: string | RegExp, startsWith?: any) => Match$1 | null; /** * Actions represent the type of change to a location value. */ declare enum Action { /** * A POP indicates a change to an arbitrary index in the history stack, such * as a back or forward navigation. It does not describe the direction of the * navigation, only that the current index changed. * * Note: This is the default action for newly created history objects. */ Pop = "POP", /** * A PUSH indicates a new entry being added to the history stack, such as when * a link is clicked and a new page loads. When this happens, all subsequent * entries in the stack are lost. */ Push = "PUSH", /** * A REPLACE indicates the entry at the current index in the history stack * being replaced by a new one. */ Replace = "REPLACE" } /** * The pathname, search, and hash values of a URL. */ interface Path { /** * A URL pathname, beginning with a /. */ pathname: string; /** * A URL search string, beginning with a ?. */ search: string; /** * A URL fragment identifier, beginning with a #. */ hash: string; } /** * An entry in a history stack. A location contains information about the * URL path, as well as possibly some arbitrary state and a key. */ interface Location$2 extends Path { /** * A value of arbitrary data associated with this location. */ state: any; /** * A unique string associated with this location. May be used to safely store * and retrieve data in some other storage API, like `localStorage`. * * Note: This value is always "default" on the initial location. */ key: string; } /** * A change to the current location. */ interface Update { /** * The action that triggered the change. */ action: Action; /** * The new location. */ location: Location$2; /** * The delta between this location and the former location in the history stack */ delta: number | null; } /** * A function that receives notifications about location changes. */ interface Listener { (update: Update): void; } /** * Describes a location that is the destination of some navigation, either via * `history.push` or `history.replace`. May be either a URL or the pieces of a * URL path. */ type To = string | Partial; /** * A history is an interface to the navigation stack. The history serves as the * source of truth for the current location, as well as provides a set of * methods that may be used to change it. * * It is similar to the DOM's `window.history` object, but with a smaller, more * focused API. */ interface History { /** * The last action that modified the current location. This will always be * Action.Pop when a history instance is first created. This value is mutable. */ readonly action: Action; /** * The current location. This value is mutable. */ readonly location: Location$2; /** * Returns a valid href for the given `to` value that may be used as * the value of an attribute. * * @param to - The destination URL */ createHref(to: To): string; /** * Returns a URL for the given `to` value * * @param to - The destination URL */ createURL(to: To): URL; /** * Encode a location the same way window.history would do (no-op for memory * history) so we ensure our PUSH/REPLACE navigations for data routers * behave the same as POP * * @param to Unencoded path */ encodeLocation(to: To): Path; /** * Pushes a new location onto the history stack, increasing its length by one. * If there were any entries in the stack after the current one, they are * lost. * * @param to - The new URL * @param state - Data to associate with the new location */ push(to: To, state?: any): void; /** * Replaces the current location in the history stack with a new one. The * location that was replaced will no longer be available. * * @param to - The new URL * @param state - Data to associate with the new location */ replace(to: To, state?: any): void; /** * Navigates `n` entries backward/forward in the history stack relative to the * current index. For example, a "back" navigation would use go(-1). * * @param delta - The delta in the stack index */ go(delta: number): void; /** * Sets up a listener that will be called whenever the current location * changes. * * @param listener - A function that will be called when the location changes * @returns unlisten - A function that may be used to stop listening */ listen(listener: Listener): () => void; } /** * Map of routeId -> data returned from a loader/action/error */ interface RouteData { [routeId: string]: any; } declare enum ResultType { data = "data", deferred = "deferred", redirect = "redirect", error = "error" } /** * Successful result from a loader or action */ interface SuccessResult { type: ResultType.data; data: any; statusCode?: number; headers?: Headers; } /** * Successful defer() result from a loader or action */ interface DeferredResult { type: ResultType.deferred; deferredData: DeferredData; statusCode?: number; headers?: Headers; } /** * Redirect result from a loader or action */ interface RedirectResult { type: ResultType.redirect; status: number; location: string; revalidate: boolean; reloadDocument?: boolean; } /** * Unsuccessful result from a loader or action */ interface ErrorResult { type: ResultType.error; error: any; headers?: Headers; } /** * Result from a loader or action - potentially successful or unsuccessful */ type DataResult = SuccessResult | DeferredResult | RedirectResult | ErrorResult; type LowerCaseFormMethod = "get" | "post" | "put" | "patch" | "delete"; type UpperCaseFormMethod = Uppercase; /** * Active navigation/fetcher form methods are exposed in lowercase on the * RouterState */ type FormMethod = LowerCaseFormMethod; /** * In v7, active navigation/fetcher form methods are exposed in uppercase on the * RouterState. This is to align with the normalization done via fetch(). */ type V7_FormMethod = UpperCaseFormMethod; type FormEncType = "application/x-www-form-urlencoded" | "multipart/form-data" | "application/json" | "text/plain"; type JsonObject = { [Key in string]: JsonValue; } & { [Key in string]?: JsonValue | undefined; }; type JsonArray = JsonValue[] | readonly JsonValue[]; type JsonPrimitive = string | number | boolean | null; type JsonValue = JsonPrimitive | JsonObject | JsonArray; /** * @private * Internal interface to pass around for action submissions, not intended for * external consumption */ type Submission = { formMethod: FormMethod | V7_FormMethod; formAction: string; formEncType: FormEncType; formData: FormData; json: undefined; text: undefined; } | { formMethod: FormMethod | V7_FormMethod; formAction: string; formEncType: FormEncType; formData: undefined; json: JsonValue; text: undefined; } | { formMethod: FormMethod | V7_FormMethod; formAction: string; formEncType: FormEncType; formData: undefined; json: undefined; text: string; }; /** * @private * Arguments passed to route loader/action functions. Same for now but we keep * this as a private implementation detail in case they diverge in the future. */ interface DataFunctionArgs { request: Request; params: Params; context?: any; } /** * Arguments passed to loader functions */ interface LoaderFunctionArgs extends DataFunctionArgs { } /** * Arguments passed to action functions */ interface ActionFunctionArgs extends DataFunctionArgs { } /** * Loaders and actions can return anything except `undefined` (`null` is a * valid return value if there is no data to return). Responses are preferred * and will ease any future migration to Remix */ type DataFunctionValue = Response | NonNullable | null; /** * Route loader function signature */ interface LoaderFunction { (args: LoaderFunctionArgs): Promise | DataFunctionValue; } /** * Route action function signature */ interface ActionFunction { (args: ActionFunctionArgs): Promise | DataFunctionValue; } /** * Route shouldRevalidate function signature. This runs after any submission * (navigation or fetcher), so we flatten the navigation/fetcher submission * onto the arguments. It shouldn't matter whether it came from a navigation * or a fetcher, what really matters is the URLs and the formData since loaders * have to re-run based on the data models that were potentially mutated. */ interface ShouldRevalidateFunction { (args: { currentUrl: URL; currentParams: AgnosticDataRouteMatch["params"]; nextUrl: URL; nextParams: AgnosticDataRouteMatch["params"]; formMethod?: Submission["formMethod"]; formAction?: Submission["formAction"]; formEncType?: Submission["formEncType"]; text?: Submission["text"]; formData?: Submission["formData"]; json?: Submission["json"]; actionResult?: DataResult; defaultShouldRevalidate: boolean; }): boolean; } /** * Keys we cannot change from within a lazy() function. We spread all other keys * onto the route. Either they're meaningful to the router, or they'll get * ignored. */ type ImmutableRouteKey = "lazy" | "caseSensitive" | "path" | "id" | "index" | "children"; type RequireOne = Exclude<{ [K in keyof T]: K extends Key ? Omit & Required> : never; }[keyof T], undefined>; /** * lazy() function to load a route definition, which can add non-matching * related properties to a route */ interface LazyRouteFunction { (): Promise>>; } /** * Base RouteObject with common props shared by all types of routes */ type AgnosticBaseRouteObject = { caseSensitive?: boolean; path?: string; id?: string; loader?: LoaderFunction; action?: ActionFunction; hasErrorBoundary?: boolean; shouldRevalidate?: ShouldRevalidateFunction; handle?: any; lazy?: LazyRouteFunction; }; /** * Index routes must not have children */ type AgnosticIndexRouteObject = AgnosticBaseRouteObject & { children?: undefined; index: true; }; /** * Non-index routes may have children, but cannot have index */ type AgnosticNonIndexRouteObject = AgnosticBaseRouteObject & { children?: AgnosticRouteObject[]; index?: false; }; /** * A route object represents a logical route, with (optionally) its child * routes organized in a tree-like structure. */ type AgnosticRouteObject = AgnosticIndexRouteObject | AgnosticNonIndexRouteObject; type AgnosticDataIndexRouteObject = AgnosticIndexRouteObject & { id: string; }; type AgnosticDataNonIndexRouteObject = AgnosticNonIndexRouteObject & { children?: AgnosticDataRouteObject[]; id: string; }; /** * A data route object, which is just a RouteObject with a required unique ID */ type AgnosticDataRouteObject = AgnosticDataIndexRouteObject | AgnosticDataNonIndexRouteObject; /** * The parameters that were parsed from the URL path. */ type Params = { readonly [key in Key]: string | undefined; }; /** * A RouteMatch contains info about how a route matched a URL. */ interface AgnosticRouteMatch { /** * The names and values of dynamic parameters in the URL. */ params: Params; /** * The portion of the URL pathname that was matched. */ pathname: string; /** * The portion of the URL pathname that was matched before child routes. */ pathnameBase: string; /** * The route object that was used to match. */ route: RouteObjectType; } interface AgnosticDataRouteMatch extends AgnosticRouteMatch { } declare class DeferredData { private pendingKeysSet; private controller; private abortPromise; private unlistenAbortSignal; private subscribers; data: Record; init?: ResponseInit; deferredKeys: string[]; constructor(data: Record, responseInit?: ResponseInit); private trackPromise; private onSettle; private emit; subscribe(fn: (aborted: boolean, settledKey?: string) => void): () => boolean; cancel(): void; resolveData(signal: AbortSignal): Promise; get done(): boolean; get unwrappedData(): {}; get pendingKeys(): string[]; } /** * State maintained internally by the router. During a navigation, all states * reflect the the "old" location unless otherwise noted. */ interface RouterState { /** * The action of the most recent navigation */ historyAction: Action; /** * The current location reflected by the router */ location: Location$2; /** * The current set of route matches */ matches: AgnosticDataRouteMatch[]; /** * Tracks whether we've completed our initial data load */ initialized: boolean; /** * Current scroll position we should start at for a new view * - number -> scroll position to restore to * - false -> do not restore scroll at all (used during submissions) * - null -> don't have a saved position, scroll to hash or top of page */ restoreScrollPosition: number | false | null; /** * Indicate whether this navigation should skip resetting the scroll position * if we are unable to restore the scroll position */ preventScrollReset: boolean; /** * Tracks the state of the current navigation */ navigation: Navigation; /** * Tracks any in-progress revalidations */ revalidation: RevalidationState; /** * Data from the loaders for the current matches */ loaderData: RouteData; /** * Data from the action for the current matches */ actionData: RouteData | null; /** * Errors caught from loaders for the current matches */ errors: RouteData | null; /** * Map of current fetchers */ fetchers: Map; /** * Map of current blockers */ blockers: Map; } /** * Data that can be passed into hydrate a Router from SSR */ type HydrationState = Partial>; type RelativeRoutingType = "route" | "path"; /** * Potential states for state.navigation */ type NavigationStates = { Idle: { state: "idle"; location: undefined; formMethod: undefined; formAction: undefined; formEncType: undefined; formData: undefined; json: undefined; text: undefined; }; Loading: { state: "loading"; location: Location$2; formMethod: Submission["formMethod"] | undefined; formAction: Submission["formAction"] | undefined; formEncType: Submission["formEncType"] | undefined; formData: Submission["formData"] | undefined; json: Submission["json"] | undefined; text: Submission["text"] | undefined; }; Submitting: { state: "submitting"; location: Location$2; formMethod: Submission["formMethod"]; formAction: Submission["formAction"]; formEncType: Submission["formEncType"]; formData: Submission["formData"]; json: Submission["json"]; text: Submission["text"]; }; }; type Navigation = NavigationStates[keyof NavigationStates]; type RevalidationState = "idle" | "loading"; /** * Potential states for fetchers */ type FetcherStates = { Idle: { state: "idle"; formMethod: undefined; formAction: undefined; formEncType: undefined; text: undefined; formData: undefined; json: undefined; data: TData | undefined; " _hasFetcherDoneAnything "?: boolean; }; Loading: { state: "loading"; formMethod: Submission["formMethod"] | undefined; formAction: Submission["formAction"] | undefined; formEncType: Submission["formEncType"] | undefined; text: Submission["text"] | undefined; formData: Submission["formData"] | undefined; json: Submission["json"] | undefined; data: TData | undefined; " _hasFetcherDoneAnything "?: boolean; }; Submitting: { state: "submitting"; formMethod: Submission["formMethod"]; formAction: Submission["formAction"]; formEncType: Submission["formEncType"]; text: Submission["text"]; formData: Submission["formData"]; json: Submission["json"]; data: TData | undefined; " _hasFetcherDoneAnything "?: boolean; }; }; type Fetcher = FetcherStates[keyof FetcherStates]; interface BlockerBlocked { state: "blocked"; reset(): void; proceed(): void; location: Location$2; } interface BlockerUnblocked { state: "unblocked"; reset: undefined; proceed: undefined; location: undefined; } interface BlockerProceeding { state: "proceeding"; reset: undefined; proceed: undefined; location: Location$2; } type Blocker = BlockerUnblocked | BlockerBlocked | BlockerProceeding; interface NavigateOptions$1 { replace?: boolean; state?: any; preventScrollReset?: boolean; relative?: RelativeRoutingType; } /** * A Navigator is a "location changer"; it's how you get to different locations. * * Every history instance conforms to the Navigator interface, but the * distinction is useful primarily when it comes to the low-level API * where both the location and a navigator must be provided separately in order * to avoid "tearing" that may occur in a suspense-enabled app if the action * and/or location were to be read directly from the history instance. */ interface Navigator { createHref: History["createHref"]; encodeLocation?: History["encodeLocation"]; go: History["go"]; push(to: To, state?: any, opts?: NavigateOptions$1): void; replace(to: To, state?: any, opts?: NavigateOptions$1): void; } interface FutureConfig { v7_startTransition: boolean; } interface RouterProps { basename?: string; children?: React.ReactNode; location: Partial | string; navigationType?: Action; navigator: Navigator; static?: boolean; } /** * Provides location context for the rest of the app. * * Note: You usually won't render a directly. Instead, you'll render a * router that is more specific to your environment such as a * in web browsers or a for server rendering. * * @see https://reactrouter.com/router-components/router */ declare function Router({ basename: basenameProp, children, location: locationProp, navigationType, navigator, static: staticProp, }: RouterProps): React.ReactElement | null; /** * NOTE: If you refactor this to split up the modules into separate files, * you'll need to update the rollup config for react-router-dom-v5-compat. */ declare global { var __staticRouterHydrationData: HydrationState | undefined; } interface BrowserRouterProps { basename?: string; children?: React.ReactNode; future?: FutureConfig; window?: Window; } /** * A `` for use in web browsers. Provides the cleanest URLs. */ declare function BrowserRouter({ basename, children, future, window, }: BrowserRouterProps): React.JSX.Element; interface Other extends StoryData { path: string; singleStory?: boolean; } type NavigateOptions = NavigateOptions$1 & { plain?: boolean; }; type NavigateFunction = (to: To | number, options?: NavigateOptions) => void; type RouterData = { location: Partial; navigate: NavigateFunction; } & Other; type RenderData = Pick & Other; interface LinkProps { to: string; children: ReactNode; } interface MatchingData { match: null | { path: string; }; } interface LocationProps { children: (renderData: RenderData) => any; } interface MatchPropsStartsWith { path: string; startsWith: boolean; children: (matchingData: MatchingData) => ReactNode; } interface MatchPropsDefault { path: RegExp; startsWith: false; children: (matchingData: MatchingData) => ReactNode; } interface RoutePropsStartsWith { path: string; startsWith?: boolean; children: ReactNode; } interface RoutePropsDefault { path: RegExp; startsWith?: false; children: ReactNode; } declare const useNavigate: () => (to: To | number, { plain, ...options }?: NavigateOptions) => void; /** A component that will navigate to a new location/path when clicked */ declare const Link: { ({ to, children, ...rest }: LinkProps): React__default.JSX.Element; displayName: string; }; /** * A render-prop component where children is called with a location and will be called whenever it * changes */ declare const Location$1: { ({ children }: LocationProps): React__default.JSX.Element; displayName: string; }; /** * A render-prop component for rendering when a certain path is hit. It's immensely similar to * `Location` but it receives an addition data property: `match`. match has a truthy value when the * path is hit. */ declare function Match(props: MatchPropsStartsWith): ReactElement; declare function Match(props: MatchPropsDefault): ReactElement; declare namespace Match { var displayName: string; } /** A component to conditionally render children based on matching a target path */ declare function Route(props: RoutePropsDefault): ReactElement; declare function Route(props: RoutePropsStartsWith): ReactElement; declare namespace Route { var displayName: string; } declare const LocationProvider: typeof BrowserRouter; declare const BaseLocationProvider: typeof Router; export { BaseLocationProvider, DEEPLY_EQUAL, Link, type LinkProps, Location$1 as Location, LocationProvider, Match, type NavigateFunction, type NavigateOptions, type Other, type RenderData, Route, type RouterData, type StoryData, buildArgsParam, deepDiff, getMatch, parsePath, queryFromLocation, stringifyQuery, useNavigate };