UNPKG

@furystack/shades

Version:

A lightweight UI framework for FuryStack with JSX support

65 lines 2.77 kB
import { LocationService } from '../services/location-service.js'; import { createComponent } from '../shade-component.js'; import { Shade } from '../shade.js'; import { buildNestedNavigateUrl } from './nested-navigate.js'; const _NestedRouteLink = Shade({ customElementName: 'nested-route-link', elementBase: HTMLAnchorElement, elementBaseName: 'a', css: { color: 'inherit', textDecoration: 'inherit', }, render: ({ children, props, injector, useHostProps }) => { const { path, params, query, hash } = props; const resolvedUrl = buildNestedNavigateUrl({ path, params, query, hash }); useHostProps({ href: resolvedUrl, onclick: (ev) => { ev.preventDefault(); // eslint-disable-next-line furystack/prefer-location-service -- This IS the SPA link component; it must call pushState directly. history.pushState('', props.title || '', resolvedUrl); injector.get(LocationService).updateState(); }, }); return createComponent(createComponent, null, children); }, }); /** * A link component for NestedRouter that supports SPA navigation with * type-safe route parameter compilation. * * Intercepts click events to use `history.pushState` for client-side navigation, * compiles parameterized routes (e.g. `/users/:id`) when `params` is provided, * serializes `query` to the URL search string and appends `hash` when set. * * Route parameters are automatically inferred from the `path` pattern: * - `path="/buttons"` — `params` is optional * - `path="/users/:id"` — `params: { id: string }` is required * * For additional URL validation against a route tree (including `query` and * `hash` narrowing), use {@link createNestedRouteLink}. */ export const NestedRouteLink = _NestedRouteLink; /** * Creates a type-safe wrapper around NestedRouteLink constrained to a specific * route tree. The returned component has the same runtime behavior 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. * * @typeParam TRoutes - The route tree type (use `typeof yourRoutes`) * @returns A narrowed NestedRouteLink component * * @example * ```typescript * const AppLink = createNestedRouteLink<typeof appRoutes>() * * <AppLink path="/buttons">Buttons</AppLink> * <AppLink path="/users/:id" params={{ id: '123' }}>User</AppLink> * <AppLink path="/users/:id" params={{ id: '1' }} query={{ tab: 'profile' }} hash="notes">User</AppLink> * ``` */ export const createNestedRouteLink = () => { return _NestedRouteLink; }; //# sourceMappingURL=nested-route-link.js.map