Navigation Progress
Preview: Default
Thin progress bar pinned to the top of the page (or a positioned container) during route changes.
Import
import { NavigationProgress } from '@marbleui/ui'
import { useNavigationProgress } from '@marbleui/ui'Props
Hooks
useNavigationProgress(): { value: number | null; start: () => void; done: () => void; }Imperative controller for the top loading bar: start() trickles toward 90%, done() completes and fades out.
Usage notes
Thin bar across the top of the page (or a container) while a route change loads, driven by useNavigationProgress(). For progress you can actually measure use ProgressBar.
const progress = useNavigationProgress()
async function go(path: string) { progress.start(); await loadRoute(path); progress.done() }
<NavigationProgress value={progress.value} fixed />
- The progress is simulated:
start()jumps to 8% and creeps toward 90%,done()fills to 100% and hides the bar 400 ms later. It isn’t tied to any router, so call both from your navigation events. value={null}hides the bar.fixedpins it to the top of the viewport; otherwise it’sabsolute, so the parent needsrelative.- It’s a
role="progressbar"labelled “Page loading”, hidden from assistive tech while idle. - Calling
start()soon afterdone()cancels the pending hide, so back-to-back navigations show the bar.
Example source · show· hide
import { useState } from 'react'
import { Button } from '../button'
import { NavigationProgress, useNavigationProgress } from './navigation-progress'
function Demo() {
const p = useNavigationProgress()
const [page, setPage] = useState('Overview')
const go = (to: string) => { p.start(); setTimeout(() => { setPage(to); p.done() }, 1400) }
return (
<div className="relative w-96 overflow-hidden rounded-xl border border-border bg-surface">
<NavigationProgress value={p.value} />
<nav className="flex gap-1 border-b border-border p-2">{['Overview', 'Issues', 'Settings'].map((l) => <Button key={l} size="sm" variant={l === page ? 'soft' : 'ghost'} onPress={() => go(l)}>{l}</Button>)}</nav>
<div className="grid h-32 place-items-center text-sm text-fg-muted">{page}</div>
</div>
)
}
export const styles = { Default: Demo }Source: packages/ui/src/navigation-progress/navigation-progress.tsx
Catalog
- Category
- navigation
- Priority
- Extra
- Primitive
- composed
- React Aria
- ProgressBar
- Base UI
- Progress