shadcn.io is not affiliated with official shadcn/ui
Scroll Spy Navbar Block for Svelte
A navbar whose current link follows the section in view in a framed scrolling page preview, with a 1-pixel stroke that slides to it and links that scroll to their section.
Installation
Overview
A scroll-spy navbar for Svelte with Ark UI, for trail-guide documentation called Trailmark. Under the bar sits a framed, named page preview, 80 pixels tall and scrolling, with five drawn sections: Intro, Routes, Gear, Safety and Permits. As it scrolls, the link of the section crossing the window's middle becomes the current page (aria-current="page") and a 1-pixel stroke on the bar's bottom edge slides to it; choosing a link scrolls the preview, not the page, to its section. The wordmark leads, the five links follow, and an Open the guide Shine Button closes the row; below the md breakpoint a menu button opens a sheet from the top whose links scroll the preview too. It's built from Sheet, Guides, Shine Button and Button. For documentation and long-page sites whose bar says where you are.
FAQ
How does it know which section is in view?
An IntersectionObserver rooted on the preview watches every section with a root margin of -45% 0px -45%, which leaves a thin band across the window's middle: the section touching that band is the current one. There are no scroll handlers and no per-frame work. On your page, drop the preview, give your sections data-section attributes (or ids) that match SECTIONS, and use null as the observer's root so the window is the viewport; the links then scroll with scrollIntoView, and you can give the targets scroll-mt-20 to clear a sticky bar.
How does the stroke slide?
Its inline start and width come from the current link's measured box, in a layout effect that runs again when the bar resizes (the nav is hidden on a phone). The first position is set without a transition, and later moves ease over 300 milliseconds on inset-inline-start and width, so it follows the link in a right-to-left page too. The current link is also heavier and foreground-coloured, so the stroke isn't the only mark.
How does it work with a keyboard and a screen reader?
The preview is a named region, "Page preview", that takes focus, so the arrow keys scroll it and the current link follows; its drawn sections are hidden from assistive technology. The links sit in a nav named Main after the wordmark; activating one scrolls the preview and moves aria-current="page" to it as the scroll arrives.
Open the guide's asChild receives its props: spread them onto your router's link.
How does it work on a phone?
Below the md breakpoint the links fold: the wordmark, Open the guide and a menu button stay on the bar, and nothing wraps at 320 pixels. The preview stays under the bar, scrolls by touch and drives the current link. In the sheet the current page is tinted with a dot, and choosing a link scrolls the preview and closes the sheet. Focus moves into the sheet and stays there; Escape, the close button or choosing a link closes it, and focus goes back to the menu button.
What moves, and what happens with reduced motion?
Choosing a link scrolls the preview smoothly and the stroke glides to the new link; a band of light sweeps across Open the guide once on hover and keyboard focus. With reduced motion the preview jumps to its section at once, the stroke moves without gliding, the sheet appears without sliding and the light fades in where it stands.