# NavigationProgress

A controlled navigation loading bar with delayed start and completion feedback.

Page: https://sui.draco.dev/docs/components/navigation-progress

### Example: navigation-progress-demo

```tsx
import { Button } from "@workspace/ui/components/button";
import { NavigationProgress } from "@workspace/ui/components/navigation-progress";
import { useState } from "react";
import type { ExampleProps } from "../types";

export default function NavigationProgressDemo({ locale }: ExampleProps) {
  const zh = locale === "zh-CN";
  const stateLabels = zh
    ? {
        navigating: "页面切换中…",
        ready: "页面已就绪",
      }
    : {
        navigating: "Navigating…",
        ready: "Page ready",
      };
  const [active, setActive] = useState(false);
  return (
    <div className="relative flex w-full max-w-md flex-col gap-4 overflow-hidden rounded-2xl border p-6">
      <NavigationProgress
        active={active}
        position="absolute"
        label={zh ? "正在加载页面" : "Loading page"}
      />
      <p className="text-muted-foreground text-sm" role="status">
        {active ? stateLabels.navigating : stateLabels.ready}
      </p>
      <div className="flex gap-2">
        <Button onClick={() => setActive(true)} disabled={active}>
          {zh ? "开始导航" : "Start navigation"}
        </Button>
        <Button
          variant="outline"
          onClick={() => setActive(false)}
          disabled={!active}
        >
          {zh ? "完成" : "Complete"}
        </Button>
      </div>
    </div>
  );
}
```

## Installation

```bash
bunx --bun shadcn@latest add @sui/navigation-progress
```

Install with the shadcn CLI or use the shared `@workspace/ui` package. Follow the [installation guide](/docs/installation) to configure the registry, load styles, and choose import aliases.

```tsx
import { NavigationProgress } from "@workspace/ui/components/navigation-progress"
```

## Router integration

The shared UI component accepts loading state from any router. The documentation application connects it to TanStack Router:

```tsx
import { useRouterState } from "@tanstack/react-router"
import { NavigationProgress } from "@workspace/ui/components/navigation-progress"

function RouterProgress() {
  const active = useRouterState({ select: (state) => state.status === "pending" })
  return <NavigationProgress active={active} />
}
```

The bar waits before appearing, advances toward a capped estimate, completes when `active` becomes false, then hides. Quick transitions that finish before `delay` produce no flash. The displayed length is an estimate; the accessible progress state remains indeterminate during loading. Reduced-motion preferences disable transition animation.

## API

| Prop | Default | Description |
| --- | --- | --- |
| `active` | Required | Whether navigation is pending. |
| `delay` | `120` | Delay before showing the bar, in milliseconds. |
| `finishDelay` | `180` | Time to show completion before hiding. |
| `position` | `fixed` | `fixed` for the page top, `absolute` within a positioned container. |
| `label` | `Loading page` | Accessible progress name. |
| `className` | — | Placement and layout classes. |

Inspired by [shadcn-admin NavigationProgress](https://github.com/satnaing/shadcn-admin/blob/main/src/components/navigation-progress.tsx). This implementation uses the existing Base UI dependency, SUI semantic tokens, and React timers, with no `react-top-loading-bar` or router dependency in the UI package.
