CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-reach--router

Next generation React routing library with accessible navigation and focus management.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

navigation.mddocs/

Navigation

Link components and programmatic navigation functions for moving between routes with accessibility features and state management.

Capabilities

Link Component

Accessible navigation link component with automatic active state detection and focus management.

/**
 * Accessible navigation link with active state detection and ref forwarding
 * @param props - Link configuration and standard anchor props
 * @param ref - Forwarded ref to the anchor element
 */
const Link: React.ForwardRefExoticComponent<{
  to: string;
  state?: any;
  replace?: boolean;
  getProps?: (props: LinkGetPropsArgument) => object;
  innerRef?: React.Ref<HTMLAnchorElement>;
} & React.AnchorHTMLAttributes<HTMLAnchorElement> & React.RefAttributes<HTMLAnchorElement>>;

interface LinkGetPropsArgument {
  isCurrent: boolean;
  isPartiallyCurrent: boolean;
  href: string;
  location: Location;
}

Props:

  • to (string, required) - Destination path (relative or absolute)
  • state (any, optional) - State to pass with navigation
  • replace (boolean, optional) - Replace current history entry instead of pushing
  • getProps (function, optional) - Function to compute additional props based on link state
  • innerRef (React.Ref, optional) - Ref to the underlying anchor element
  • All standard HTML anchor attributes are supported

Usage Examples:

import React from "react";
import { Link } from "@reach/router";

// Basic navigation links
const Navigation = () => (
  <nav>
    <Link to="/">Home</Link>
    <Link to="/about">About</Link>
    <Link to="/contact">Contact</Link>
  </nav>
);

// Link with state
const UserLink = ({ userId }) => (
  <Link 
    to={`/users/${userId}`}
    state={{ from: "user-list" }}
  >
    View User
  </Link>
);

// Dynamic styling based on active state
const NavLink = ({ to, children, ...props }) => (
  <Link
    to={to}
    getProps={({ isCurrent, isPartiallyCurrent }) => ({
      className: isCurrent ? "nav-link active" : "nav-link",
      "aria-current": isCurrent ? "page" : undefined
    })}
    {...props}
  >
    {children}
  </Link>
);

// Replace current history entry
const ReplaceLink = () => (
  <Link to="/new-page" replace>
    Replace Current Page
  </Link>
);

// Link with custom styling function
const StyledLink = ({ to, children }) => (
  <Link
    to={to}
    getProps={({ isCurrent, isPartiallyCurrent, href, location }) => {
      const baseStyle = { textDecoration: "none", padding: "8px" };
      const activeStyle = { backgroundColor: "#007bff", color: "white" };
      const partialStyle = { backgroundColor: "#e9ecef" };
      
      return {
        style: {
          ...baseStyle,
          ...(isCurrent ? activeStyle : isPartiallyCurrent ? partialStyle : {})
        }
      };
    }}
  >
    {children}
  </Link>
);

Programmatic Navigation

Navigate function for programmatic navigation outside of components or in response to events.

/**
 * Global navigation function for programmatic routing
 * @param to - Destination path or history delta
 * @param options - Navigation options
 */
function navigate(
  to: string | number, 
  options?: {
    state?: any;
    replace?: boolean;
  }
): Promise<void>;

Parameters:

  • to (string | number) - Destination path (string) or history delta (number)
  • options.state (any, optional) - State to associate with the navigation
  • options.replace (boolean, optional) - Replace current history entry

Usage Examples:

import { navigate } from "@reach/router";

// Basic navigation
const handleLogin = async () => {
  const success = await loginUser();
  if (success) {
    await navigate("/dashboard");
  }
};

// Navigation with state
const handleUserSelect = (userId) => {
  navigate(`/users/${userId}`, {
    state: { selectedFrom: "user-list" }
  });
};

// Replace current entry
const handleRedirect = () => {
  navigate("/new-location", { replace: true });
};

// History navigation (back/forward)
const goBack = () => navigate(-1);
const goForward = () => navigate(1);
const goBackTwoPages = () => navigate(-2);

// Navigation in form handlers
const handleFormSubmit = async (formData) => {
  try {
    await submitForm(formData);
    navigate("/success");
  } catch (error) {
    navigate("/error", { state: { error: error.message } });
  }
};

// Conditional navigation
const handleSave = async (data, shouldRedirect = true) => {
  await saveData(data);
  if (shouldRedirect) {
    navigate("/saved");
  }
};

Navigation Within Components

Navigation function provided to route components and available through context.

/**
 * Navigation function provided to route components
 * This is a scoped version that resolves relative paths
 */
interface RouteNavigateFunction {
  (to: string | number, options?: NavigateOptions): Promise<void>;
}

Usage Examples:

// In route components, navigate is provided as a prop
const UserProfile = ({ userId, navigate, location }) => {
  const handleEdit = () => {
    // Relative navigation from current route
    navigate("edit");
  };
  
  const handleDelete = async () => {
    await deleteUser(userId);
    // Absolute navigation
    navigate("/users");
  };
  
  const handleCancel = () => {
    // Go back in history
    navigate(-1);
  };
  
  return (
    <div>
      <h1>User: {userId}</h1>
      <button onClick={handleEdit}>Edit</button>
      <button onClick={handleDelete}>Delete</button>
      <button onClick={handleCancel}>Cancel</button>
    </div>
  );
};

// Using navigate with state
const ProductForm = ({ navigate }) => {
  const handleSubmit = async (productData) => {
    const newProduct = await createProduct(productData);
    navigate(`/products/${newProduct.id}`, {
      state: { justCreated: true }
    });
  };
  
  return <form onSubmit={handleSubmit}>{/* form content */}</form>;
};

Link Active States

Understanding how Link components determine active states for styling and accessibility.

/**
 * Link active state detection
 */
interface LinkActiveState {
  // True when link path exactly matches current location
  isCurrent: boolean;
  // True when current location starts with link path
  isPartiallyCurrent: boolean;
  // Resolved href for the link
  href: string;
  // Current location object
  location: Location;
}

Usage Examples:

// Understanding active states
const ExampleNavigation = () => (
  <nav>
    {/* isCurrent: true only when at exactly "/" */}
    <Link 
      to="/"
      getProps={({ isCurrent }) => ({
        className: isCurrent ? "current" : ""
      })}
    >
      Home
    </Link>
    
    {/* isPartiallyCurrent: true for "/products", "/products/123", etc. */}
    <Link 
      to="/products"
      getProps={({ isPartiallyCurrent }) => ({
        className: isPartiallyCurrent ? "partial" : ""
      })}
    >
      Products
    </Link>
    
    {/* Complex styling based on multiple states */}
    <Link
      to="/dashboard"
      getProps={({ isCurrent, isPartiallyCurrent, location }) => {
        const isActive = isCurrent || isPartiallyCurrent;
        return {
          className: `nav-item ${isActive ? "active" : ""}`,
          "aria-current": isCurrent ? "page" : undefined,
          "data-partial": isPartiallyCurrent ? "true" : undefined
        };
      }}
    >
      Dashboard
    </Link>
  </nav>
);

Install with Tessl CLI

npx tessl i tessl/npm-reach--router

docs

advanced-routing.md

history.md

hooks.md

index.md

location-context.md

navigation.md

routing.md

server-rendering.md

utilities.md

tile.json