Isaiah

BJORK Minimap scrollbar

Component

About

Minimap scrollbar is a production-ready navigation component from BJORK UI, packaged for shadcn registries.

Built with React and Tailwind. Copy the prompt and paste it into Claude Code, Cursor or Lovable: your agent adds BJORK Minimap scrollbar to your project and fits it to your theme.

Code

How BJORK Minimap scrollbar is used: the demo's code. The component's own source comes with a free account.

Usage.tsx

"use client";
import { ThemeProvider as BjorkDemoThemeProvider } from "next-themes";
import { useEffect, useRef, useState } from "react";
import { MinimapScrollbar } from "@/components/ui/bjork-minimap-scrollbar";

function MinimapDemo() {
  const isPreview = false;
  const scrollRef = useRef<HTMLDivElement>(null);
  const [debugHoverAt, setDebugHoverAt] = useState<number | undefined>(undefined);

  // Preview pose: scrolled to 38%, with the label pill on section 03.
  useEffect(() => {
    if (!isPreview) return;
    const frame = requestAnimationFrame(() => {
      const el = scrollRef.current;
      if (!el) return;
      el.scrollTop = 0.38 * (el.scrollHeight - el.clientHeight);
      const third = el.querySelectorAll<HTMLElement>("h2")[2];
      if (third) setDebugHoverAt(third.offsetTop / el.scrollHeight);
    });
    return () => cancelAnimationFrame(frame);
  }, [isPreview]);

  return (
    <div className="relative h-[440px] w-[min(760px,calc(100vw-56px))] overflow-hidden rounded-[16px] border border-[color:var(--bjork-border)] bg-[color:var(--bjork-surface)]">
      <div
        ref={scrollRef}
        className="absolute inset-0 overflow-y-auto text-[color:var(--bjork-text)]"
        style={{ padding: "40px 56px 40px 40px", scrollbarWidth: "thin" }}
      >
        <article>
          <h1 className="text-[28px] font-semibold leading-tight tracking-[-0.02em]">Notes on optical alignment</h1>
          <p className="mt-3 text-[14px] leading-[1.65] text-[color:var(--bjork-text-medium)]">
            Measured centres and visual centres rarely agree. These notes collect the habits that close the gap,
            from small icons to long columns of figures.
          </p>

          <h2 className="mt-8 text-[18px] font-semibold tracking-[-0.01em]">Starting from the eye</h2>
          <p className="mt-3 text-[14px] leading-[1.65] text-[color:var(--bjork-text-medium)]">
            A box can be perfectly centred and still look low. Filled shapes carry more weight than outlines, and
            flat edges read heavier than curves of the same size.
          </p>
          <p className="mt-3 text-[14px] leading-[1.65] text-[color:var(--bjork-text-medium)]">
            Start with the bounding box, then step back and judge the weight. Move in small steps and stop when
            the shape stops feeling off.
          </p>

          <h2 className="mt-8 text-[18px] font-semibold tracking-[-0.01em]">Centring small shapes</h2>
          <p className="mt-3 text-[14px] leading-[1.65] text-[color:var(--bjork-text-medium)]">
            Small glyphs need the most attention because a pixel is a large share of their size.
          </p>

          <h3 className="mt-5 text-[14px] font-semibold">Icon centring</h3>
          <p className="mt-2 text-[14px] leading-[1.65] text-[color:var(--bjork-text-medium)]">
            Triangles and arrows should sit slightly toward the direction they point. Their centroid is what the
            eye reads, not the corners of their box.
          </p>
          <p className="mt-2 text-[14px] leading-[1.65] text-[color:var(--bjork-text-medium)]">
            Round icons can overshoot the box a little so they match the square ones next to them.
          </p>

          <h2 className="mt-8 text-[18px] font-semibold tracking-[-0.01em]">Padding and balance</h2>
          <p className="mt-3 text-[14px] leading-[1.65] text-[color:var(--bjork-text-medium)]">
            Equal padding on every side often looks uneven. A label with a leading icon usually needs less space on
            the icon side.
          </p>

          <h3 className="mt-5 text-[14px] font-semibold">Padding asymmetry</h3>
          <p className="mt-2 text-[14px] leading-[1.65] text-[color:var(--bjork-text-medium)]">
            Trim the side that already carries an icon by a couple of pixels. Leave the text side alone so the
            words keep their rhythm.
          </p>
          <p className="mt-2 text-[14px] leading-[1.65] text-[color:var(--bjork-text-medium)]">
            Check the result with the blur test. The visual mass should land where the box centre is.
          </p>

          <h2 className="mt-8 text-[18px] font-semibold tracking-[-0.01em]">Shape weight and punctuation</h2>
          <p className="mt-3 text-[14px] leading-[1.65] text-[color:var(--bjork-text-medium)]">
            Counters, the open space inside letters, change how heavy a word looks. Tight counters darken a line,
            open ones lighten it.
          </p>
          <p className="mt-3 text-[14px] leading-[1.65] text-[color:var(--bjork-text-medium)]">
            Hanging punctuation lets quotes and bullets sit outside the text edge, so the first letters line up
            down the column.
          </p>

          <h2 className="mt-8 text-[18px] font-semibold tracking-[-0.01em]">Type at small and large sizes</h2>
          <p className="mt-3 text-[14px] leading-[1.65] text-[color:var(--bjork-text-medium)]">
            A single typeface can behave differently across sizes. Display cuts run tighter with finer joins, while
            text cuts open up for legibility.
          </p>

          <h3 className="mt-5 text-[14px] font-semibold">Optical sizes</h3>
          <p className="mt-2 text-[14px] leading-[1.65] text-[color:var(--bjork-text-medium)]">
            Pick the cut that matches the size on screen. A large heading set in a text cut looks loose and
            underweight.
          </p>
          <p className="mt-2 text-[14px] leading-[1.65] text-[color:var(--bjork-text-medium)]">
            Keep optical sizing automatic where the font supports it, and only override it when a layout demands
            a fixed look.
          </p>

          <h2 className="mt-8 text-[18px] font-semibold tracking-[-0.01em]">Figures in columns</h2>
          <p className="mt-3 text-[14px] leading-[1.65] text-[color:var(--bjork-text-medium)]">
            Numbers that change, such as counters and timers, should keep a fixed width so the layout does not
            wobble on every tick.
          </p>

          <h3 className="mt-5 text-[14px] font-semibold">Tabular numerals</h3>
          <p className="mt-2 text-[14px] leading-[1.65] text-[color:var(--bjork-text-medium)]">
            Set columns of figures with tabular numerals so the digits share one advance width and line up by
            their place value.
          </p>
          <p className="mt-2 text-[14px] leading-[1.65] text-[color:var(--bjork-text-medium)]">
            Proportional figures look nicer in running prose. Switch to tabular only where digits stack.
          </p>
        </article>
      </div>

      <MinimapScrollbar target={scrollRef} debugHoverAt={debugHoverAt} />
    </div>
  );
}
function SourceDemo(){

return <>

      <MinimapDemo />
    
</>;
}
export default function BjorkRegistryPreview(){return <BjorkDemoThemeProvider attribute="class" defaultTheme="dark" enableSystem={false} storageKey="bjork-review-demo-theme"><div data-component-demo className="dark flex min-h-screen w-full items-center justify-center bg-[var(--bjork-bg)] p-8 text-[var(--bjork-text)]"><div className="w-full max-w-[850px]"><SourceDemo/></div></div></BjorkDemoThemeProvider>}

Dependencies

More by Isaiah

View all
  • Agent Plan

    Agent Plan

    2.2K
  • Video Scroll Hero

    Video Scroll Hero

    1.4K
  • Voice Powered Orb

    Voice Powered Orb

    1.3K
  • Reveal Text

    Reveal Text

    1.1K
  • Leads Data Table

    Leads Data Table

    935
  • Portfolio Gallery

    Portfolio Gallery

    923
  • Message Dock

    Message Dock

    833
  • Ruler Carousel

    Ruler Carousel

    619