UNPKG

one

Version:

One is a new React Framework that makes Vite serve both native and web.

329 lines 16.6 kB
import type { NavigationContainerRefWithCurrent, NavigationState, PartialState } from '@react-navigation/core'; import type { JSX, ReactNode } from 'react'; import type { GestureResponderEvent, PressableProps, TextProps } from 'react-native'; export declare namespace OneRouter { export interface __routes<T extends string = string> extends Record<string, unknown> { } export type Route<Path> = { Params: InputRouteParams<Path>; Props: { params: InputRouteParams<Path>; }; Loader: (props: { params: InputRouteParams<Path>; }) => any; }; /** * Helper type to get route information including params and loader props. * Uses generated RouteTypes from routes.d.ts if available for better intellisense. * * @example * const route = createRoute<'/docs/[slug]'>() * // route.createLoader gets params typed as { slug: string } * * type Route = RouteType<'/docs/[slug]'> * // Route.Params = { slug: string } * // Route.LoaderProps = { path: string; params: { slug: string }; request?: Request } */ export type RouteType<Path extends string> = Path extends keyof __routes['RouteTypes'] ? __routes['RouteTypes'][Path] : { Params: InputRouteParams<Path>; LoaderProps: import('../types').LoaderProps<InputRouteParams<Path>>; }; type StaticRoutes = __routes extends { StaticRoutes: string; } ? __routes['StaticRoutes'] : string; type DynamicRoutes<T extends string> = __routes<T> extends { DynamicRoutes: any; } ? T extends __routes<infer _>['DynamicRoutes'] ? T : never : string; export type DynamicRouteTemplate = __routes extends { DynamicRouteTemplate: string; } ? __routes['DynamicRouteTemplate'] : string; export type NavigationRef = NavigationContainerRefWithCurrent<ReactNavigation.RootParamList>; export type RelativePathString = `./${string}` | `../${string}` | '..'; export type AbsoluteRoute = DynamicRouteTemplate | StaticRoutes; export type ExternalPathString = `${string}:${string}`; export type OneRouterRoutes = DynamicRouteTemplate | StaticRoutes | RelativePathString; export type AllRoutes = OneRouterRoutes | ExternalPathString; export type LinkToOptions = { scroll?: boolean; }; type SearchOrHash = `?${string}` | `#${string}`; export type UnknownInputParams = Record<string, string | number | undefined | null | (string | number)[]>; type UnknownOutputParams = Record<string, string | string[]>; /** * Return only the RoutePart of a string. If the string has multiple parts return never * * string | type * ---------|------ * 123 | 123 * /123/abc | never * 123?abc | never * ./123 | never * /123 | never * 123/../ | never */ export type SingleRoutePart<S extends string> = S extends `${string}/${string}` ? never : S extends `${string}${SearchOrHash}` ? never : S extends '' ? never : S extends `(${string})` ? never : S extends `[${string}]` ? never : S; /** * Return only the CatchAll router part. If the string has search parameters or a hash return never */ export type CatchAllRoutePart<S extends string> = S extends `${string}${SearchOrHash}` ? never : S extends '' ? never : S extends `${string}(${string})${string}` ? never : S extends `${string}[${string}]${string}` ? never : S; /** * Return the name of a route parameter * '[test]' -> 'test' * 'test' -> never * '[...test]' -> '...test' */ type IsParameter<Part> = Part extends `[${infer ParamName}]` ? ParamName : never; /** * Return a union of all raw parameter names. If there are no names return never * * This differs from ParameterNames as it returns the `...` for catch all parameters * * /[test] -> 'test' * /[abc]/[...def] -> 'abc'|'...def' */ type ParameterNames<Path> = Path extends `${infer PartA}/${infer PartB}` ? IsParameter<PartA> | ParameterNames<PartB> : IsParameter<Path>; /** * Returns all segments of a route. * * /(group)/123/abc/[id]/[...rest] -> ['(group)', '123', 'abc', '[id]', '[...rest]' */ type RouteSegments<Path> = Path extends `${infer PartA}/${infer PartB}` ? PartA extends '' | '.' ? [...RouteSegments<PartB>] : [PartA, ...RouteSegments<PartB>] : Path extends '' ? [] : [Path]; type AllUngroupedRoutes<Path> = Path extends `(${infer PartA})/${infer PartB}` ? `(${PartA})/${AllUngroupedRoutes<PartB>}` | AllUngroupedRoutes<PartB> : Path; /** * Returns a Record of the routes parameters as strings and CatchAll parameters * * There are two versions, input and output, as you can input 'string | number' but * the output will always be 'string' * * /[id]/[...rest] -> { id: string, rest: string[] } * /no-params -> {} */ export type InputRouteParams<Path> = { [Key in ParameterNames<Path> as Key extends `...${infer Name}` ? Name : Key]: Key extends `...${string}` ? string[] : string; }; type OutputRouteParams<Path> = { [Key in ParameterNames<Path> as Key extends `...${infer Name}` ? Name : Key]: Key extends `...${string}` ? string[] : string; } & UnknownOutputParams; /** * Returns the search parameters for a route. */ export type SearchParams<T extends AllRoutes = never> = T extends DynamicRouteTemplate ? OutputRouteParams<T> : T extends StaticRoutes ? never : UnknownOutputParams; /********* * Href * *********/ export type DynamicRoutesHref = DynamicRouteString<{ __branded__: any; }, DynamicRouteTemplate>; export type DynamicRoutesHref2 = DynamicRouteString<string, DynamicRouteTemplate>; /** * The main routing type for One. Includes all available routes with strongly typed parameters. */ export type Href<T extends string | object = { __branded__: any; }> = StringRouteToType<AllUngroupedRoutes<StaticRoutes> | RelativePathString | ExternalPathString> | DynamicRouteString<T, DynamicRouteTemplate> | DynamicRouteObject<StaticRoutes | RelativePathString | ExternalPathString | DynamicRouteTemplate>; type StringRouteToType<T extends string> = T | `${T}${SearchOrHash}` | { pathname: T; params?: UnknownInputParams | never; }; /** * Converts a dynamic route template to a Href string type */ type DynamicRouteString<T extends string | object, P = DynamicRouteTemplate> = '__branded__' extends keyof T ? DynamicTemplateToHrefString<P> : T extends string ? DynamicRoutes<T> : never; type DynamicTemplateToHrefString<Path> = Path extends `${infer PartA}/${infer PartB}` ? `${PartA extends `[${string}]` ? string : PartA}/${DynamicTemplateToHrefString<PartB>}` : Path extends `[${string}]` ? string : Path; type DynamicRouteObject<T> = T extends DynamicRouteTemplate ? { pathname: T; params: InputRouteParams<T>; } : never; export type LoadingState = 'loading' | 'loaded'; export type ResultState = PartialState<NavigationState> & { state?: ResultState; hash?: string; linkOptions?: OneRouter.LinkToOptions; }; export type RootStateListener = (state: ResultState) => void; export type LoadingStateListener = (state: LoadingState) => void; /*********************** * One Exports * ***********************/ export type InputRouteParamsBlank = Record<string, string | undefined | null>; export type InpurRouteParamsGeneric = InputRouteParamsBlank | InputRouteParams<any>; export type Router = { /** Go back in the history. */ back: () => void; /** If there's history that supports invoking the `back` function. */ canGoBack: () => boolean; /** Navigate to the provided href using a push operation if possible. */ push: (href: Href, options?: LinkToOptions) => void; /** Navigate to the provided href. */ navigate: (href: Href, options?: LinkToOptions) => void; /** Navigate to route without appending to the history. */ replace: (href: Href, options?: LinkToOptions) => void; /** Navigate to the provided href using a push operation if possible. */ dismiss: (count?: number) => void; /** Navigate to first screen within the lowest stack. */ dismissAll: () => void; /** If there's history that supports invoking the `dismiss` and `dismissAll` function. */ canDismiss: () => boolean; /** Update the current route query params. */ setParams: <T = ''>(params?: T extends '' ? InputRouteParamsBlank : InputRouteParams<T>) => void; /** Subscribe to state updates from the router */ subscribe: (listener: RootStateListener) => () => void; /** Subscribe to loading state updates */ onLoadState: (listener: LoadingStateListener) => () => void; }; /** The imperative router. */ export const router: Router; /************ * <Link /> * ************/ export interface WebAnchorProps { /** * **Web only:** Specifies where to open the `href`. * * - **_self**: the current tab. * - **_blank**: opens in a new tab or window. * - **_parent**: opens in the parent browsing context. If no parent, defaults to **_self**. * - **_top**: opens in the highest browsing context ancestor. If no ancestors, defaults to **_self**. * * This property is passed to the underlying anchor (`<a>`) tag. * * @default '_self' * * @example * <Link href="https://expo.dev" target="_blank">Go to Expo in new tab</Link> */ target?: '_self' | '_blank' | '_parent' | '_top' | (string & object); /** * **Web only:** Specifies the relationship between the `href` and the current route. * * Common values: * - **nofollow**: Indicates to search engines that they should not follow the `href`. This is often used for user-generated content or links that should not influence search engine rankings. * - **noopener**: Suggests that the `href` should not have access to the opening window's `window.opener` object, which is a security measure to prevent potentially harmful behavior in cases of links that open new tabs or windows. * - **noreferrer**: Requests that the browser not send the `Referer` HTTP header when navigating to the `href`. This can enhance user privacy. * * The `rel` property is primarily used for informational and instructive purposes, helping browsers and web * crawlers make better decisions about how to handle and interpret the links on a web page. It is important * to use appropriate `rel` values to ensure that links behave as intended and adhere to best practices for web * development and SEO (Search Engine Optimization). * * This property is passed to the underlying anchor (`<a>`) tag. * * @example * <Link href="https://expo.dev" rel="nofollow">Go to Expo</Link> */ rel?: string; /** * **Web only:** Specifies that the `href` should be downloaded when the user clicks on the link, * instead of navigating to it. It is typically used for links that point to files that the user should download, * such as PDFs, images, documents, etc. * * The value of the `download` property, which represents the filename for the downloaded file. * This property is passed to the underlying anchor (`<a>`) tag. * * @example * <Link href="/image.jpg" download="my-image.jpg">Download image</Link> */ download?: string; } export interface LinkProps<T extends string | object> extends Omit<TextProps, 'href' | 'disabled' | 'onLongPress' | 'onPressIn' | 'onPressOut'>, Pick<PressableProps, 'disabled' | 'onLongPress' | 'onPressIn' | 'onPressOut'>, WebAnchorProps { /** Path to route to. */ href: Href<T>; /** Forward props to child component. Useful for custom buttons. */ asChild?: boolean; /** Should replace the current route without adding to the history. */ replace?: boolean; /** Should push the current route */ push?: boolean; /** On web, this sets the HTML `class` directly. On native, this can be used with CSS interop tools like Nativewind. */ className?: string; onPress?: (e: React.MouseEvent<HTMLAnchorElement, MouseEvent> | GestureResponderEvent) => void; } export interface LinkComponent { <T extends string | object>(props: React.PropsWithChildren<LinkProps<T>>): JSX.Element; /** Helper method to resolve an Href object into a string. */ resolveHref: (href: Href) => string; } /** * Component to render link to another route using a path. * Uses an anchor tag on the web. * * @param props.href Absolute path to route (e.g. \`/feeds/hot\`). * @param props.replace Should replace the current route without adding to the history. * @param props.asChild Forward props to child component. Useful for custom buttons. * @param props.children Child elements to render the content. * @param props.className On web, this sets the HTML \`class\` directly. On native, this can be used with CSS interop tools like Nativewind. */ export const Link: LinkComponent; /** Redirects to the href as soon as the component is mounted. */ export const Redirect: (props: React.PropsWithChildren<{ href: Href; }>) => ReactNode; export type Redirect = typeof Redirect; /** * Hooks */ export function useRouter(): Router; /** * Returns the URL search parameters for the contextually focused route. e.g. \`/acme?foo=bar\` -> \`{ foo: "bar" }\`. * This is useful for stacks where you may push a new screen that changes the query parameters. * * To observe updates even when the invoking route is not focused, use \`useActiveParams()\`. * @see \`useActiveParams\` */ export function useParams<TParams extends AllRoutes | UnknownOutputParams = UnknownOutputParams>(): TParams extends AllRoutes ? SearchParams<TParams> : TParams; /** * Get the globally selected query parameters, including dynamic path segments. This function will update even when the route is not focused. * Useful for analytics or other background operations that don't draw to the screen. * * When querying search params in a stack, opt-towards using \`useParams\` as these will only * update when the route is focused. * * @see \`useParams\` */ export function useActiveParams<T extends AllRoutes | UnknownOutputParams = UnknownOutputParams>(): T extends AllRoutes ? SearchParams<T> : T; /** * Get a list of selected file segments for the currently selected route. Segments are not normalized, so they will be the same as the file path. e.g. /[id]?id=normal -> ["[id]"] * * \`useSegments\` can be typed using an abstract. * Consider the following file structure, and strictly typed \`useSegments\` function: * * \`\`\`md * - app * - [user] * - index.js * - followers.js * - settings.js * \`\`\` * This can be strictly typed using the following abstract: * * \`\`\`ts * const [first, second] = useSegments<['settings'] | ['[user]'] | ['[user]', 'followers']>() * \`\`\` */ export function useSegments<T extends AbsoluteRoute | RouteSegments<AbsoluteRoute> | RelativePathString>(): T extends AbsoluteRoute ? RouteSegments<T> : T extends string ? string[] : T; export {}; } export declare namespace One { type Route<Path> = OneRouter.Route<Path>; type SitemapChangefreq = 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never'; type RouteSitemap = { /** * Priority for this route (0.0 to 1.0). */ priority?: number; /** * Change frequency for this route. */ changefreq?: SitemapChangefreq; /** * Last modification date for this route. */ lastmod?: string | Date; /** * Exclude this route from the sitemap. */ exclude?: boolean; }; } //# sourceMappingURL=router.d.ts.map