88 events ,
99 win ,
1010} from "@remix-run/events" ;
11- import { connect } from "@remix-run/dom" ;
1211import { AppStorage , type RouteHandlers , type RouteMap } from "@remix-run/fetch-router" ;
1312import type {
1413 FormEncType ,
@@ -794,7 +793,8 @@ export class Router<Renderable> extends EventTarget {
794793 * @param path - The path to check
795794 * @param exact - If true, requires exact match. Default is false (partial match)
796795 */
797- isActive ( path : string | URL | Path , exact = false ) : boolean {
796+ isActive ( path : string | URL | Path | undefined , exact = false ) : boolean {
797+ if ( ! path ) return false ;
798798 const pathname = this . #pathToString( path ) ;
799799 const currentPath = this . #location. pathname ;
800800
@@ -816,7 +816,8 @@ export class Router<Renderable> extends EventTarget {
816816 * @param path - The path to check
817817 * @param exact - If true, requires exact match. Default is false (partial match)
818818 */
819- isPending ( path : string | URL | Path , exact = false ) : boolean {
819+ isPending ( path : string | URL | Path | undefined , exact = false ) : boolean {
820+ if ( ! path ) return false ;
820821 if ( this . #navigating. to . state === "idle" ) {
821822 return false ;
822823 }
@@ -838,6 +839,21 @@ export class Router<Renderable> extends EventTarget {
838839 return pendingPath === pathname || pendingPath . startsWith ( `${ pathname } /` ) ;
839840 }
840841
842+ when < T , U > (
843+ path : string | URL | Path | undefined ,
844+ options : { active : T ; pending : U }
845+ ) : T | U | undefined {
846+ if ( this . isActive ( path ) ) {
847+ return options . active ;
848+ }
849+
850+ if ( this . isPending ( path ) ) {
851+ return options . pending ;
852+ }
853+
854+ return undefined ;
855+ }
856+
841857 /**
842858 * Submit event handler for forms that routes submissions through the router.
843859 * Use this with event listeners for forms when you need manual control.
@@ -985,54 +1001,6 @@ export class Router<Renderable> extends EventTarget {
9851001 } , options ) ;
9861002 }
9871003
988- /**
989- * Create an event descriptor that manages active and pending classes on a navigation link.
990- * Unlike {@link enhanceLink}, this method applies classes immediately on mount and keeps
991- * them in sync with router state changes.
992- *
993- * @example
994- * ```tsx
995- * <a href="/about" on={router.navLink({ activeClass: 'active', pendingClass: 'loading' })}>
996- * About
997- * </a>
998- * ```
999- *
1000- * @param styles - Configuration object with activeClass and/or pendingClass
1001- * @param options - Optional event listener options (e.g., signal for cleanup)
1002- */
1003- navLink (
1004- styles : { activeClass ?: string ; pendingClass ?: string } ,
1005- options : AddEventListenerOptions = { }
1006- ) : EventDescriptor < HTMLAnchorElement > {
1007- return connect ( event => {
1008- const anchor = event . currentTarget as HTMLAnchorElement ;
1009- const targetPath = anchor . pathname + anchor . search + anchor . hash ;
1010-
1011- // Helper to update classes based on current state
1012- const updateClasses = ( ) => {
1013- const active = this . isActive ( targetPath ) ;
1014- const pending = ! active && this . isPending ( targetPath ) ;
1015-
1016- const { activeClass, pendingClass } = styles ?? { } ;
1017-
1018- if ( activeClass ) anchor . classList . toggle ( activeClass , active ) ;
1019- if ( pendingClass ) anchor . classList . toggle ( pendingClass , pending ) ;
1020-
1021- // If neither state applies, both toggles above remove their classes.
1022- // Drop the attribute entirely if no classes remain.
1023- if ( ! anchor . classList . length ) {
1024- anchor . removeAttribute ( "class" ) ;
1025- }
1026- } ;
1027-
1028- // Apply initial classes
1029- updateClasses ( ) ;
1030-
1031- // Listen to router updates and return cleanup function
1032- return events ( this , [ Router . update ( updateClasses ) ] ) ;
1033- } , options ) ;
1034- }
1035-
10361004 /**
10371005 * Wrap a form submission handler to emit optimistic updates while the mutation is pending.
10381006 *
0 commit comments