@furystack/shades
Version:
A lightweight UI framework for FuryStack with JSX support
59 lines • 2.41 kB
JavaScript
import { serializeToQueryString } from '@furystack/rest';
import { compileRoute } from '../compile-route.js';
import { LocationService } from '../services/location-service.js';
/**
* Builds the resolved URL for a nested navigate call, including path parameters,
* serialized query string and hash segment. Exported for callers that need the
* URL without side effects (e.g. link rendering helpers).
*/
export const buildNestedNavigateUrl = (args) => {
const { path, params, query, hash } = args;
const resolvedPath = params && Object.keys(params).length > 0 ? compileRoute(path, params) : path;
const hasQuery = query && Object.keys(query).length > 0;
const search = hasQuery ? `?${serializeToQueryString(query)}` : '';
const hashPart = hash ? `#${hash}` : '';
return `${resolvedPath}${search}${hashPart}`;
};
/**
* Navigates to a route using the LocationService resolved from the given injector.
* Compiles parameterized routes (e.g. `/users/:id`), serializes the optional
* `query` record with the default `@furystack/rest` serializer, and appends the
* optional `hash` segment.
*
* @param injector - The injector instance to resolve LocationService from
* @param args - The navigation arguments
*/
export const nestedNavigate = (injector, args) => {
injector.get(LocationService).navigate(buildNestedNavigateUrl(args));
};
/**
* Creates a type-safe navigate function constrained to a specific route tree.
* The returned function has the same runtime behavior as {@link nestedNavigate}
* but narrows `path` to only accept valid route paths, requires `params` when
* the route has parameters, and enforces the route's declared `query` and
* `hash` schemas.
*
* Unlike {@link createNestedRouteLink}, the injector is passed at call time,
* not at creation time.
*
* @typeParam TRoutes - The route tree type (use `typeof yourRoutes`)
* @returns A type-safe navigate function
*
* @example
* ```typescript
* const appNavigate = createNestedNavigate<typeof appRoutes>()
*
* appNavigate(injector, { path: '/buttons' })
* appNavigate(injector, { path: '/users/:id', params: { id: '123' } })
* appNavigate(injector, {
* path: '/users/:id',
* params: { id: '123' },
* query: { tab: 'profile' },
* hash: 'settings',
* })
* ```
*/
export const createNestedNavigate = () => {
return nestedNavigate;
};
//# sourceMappingURL=nested-navigate.js.map