import { GitBranchIcon, SearchIcon } from "lucide-react";
import { Marker, MarkerContent, MarkerIcon,} from "@/components/ui/marker";import { Spinner } from "@/components/ui/spinner";
export function MarkerDemo() { return ( <div className="flex w-full max-w-sm flex-col gap-8 py-12"> <Marker> <MarkerIcon> <GitBranchIcon /> </MarkerIcon> <MarkerContent>Switched to a new branch</MarkerContent> </Marker> <Marker role="status"> <MarkerIcon> <Spinner size="sm" /> </MarkerIcon> <MarkerContent className="shimmer">Thinking...</MarkerContent> </Marker> <Marker variant="separator"> <MarkerContent>Conversation compacted</MarkerContent> </Marker> <Marker> <MarkerIcon> <SearchIcon /> </MarkerIcon> <MarkerContent>Explored 4 files</MarkerContent> </Marker> </div> );}pnpm dlx shadcn@latest add @herocn/markerimport { Marker, MarkerContent, MarkerIcon } from "@/components/ui/marker"<Marker> <MarkerIcon> <CheckIcon /> </MarkerIcon> <MarkerContent>Explored 4 files</MarkerContent></Marker>Use the following composition to build a marker:
Marker├── MarkerIcon└── MarkerContentUse variant to switch between an inline marker, bordered row, and labeled separator.
import { Marker, MarkerContent } from "@/components/ui/marker";
export function MarkerVariants() { return ( <div className="flex w-full max-w-sm flex-col gap-8 py-12"> <Marker> <MarkerContent>A default marker for inline notes.</MarkerContent> </Marker> <Marker variant="separator"> <MarkerContent>A separator marker</MarkerContent> </Marker> <Marker variant="border"> <MarkerContent>A border marker for row boundaries.</MarkerContent> </Marker> </div> );}Set role="status" and include a Spinner for streaming or in-progress markers so updates are announced.
import { Marker, MarkerContent, MarkerIcon,} from "@/components/ui/marker";import { Spinner } from "@/components/ui/spinner";
export function MarkerStatus() { return ( <div className="flex w-full max-w-sm flex-col gap-8 py-12"> <Marker role="status"> <MarkerIcon> <Spinner size="sm" /> </MarkerIcon> <MarkerContent>Compacting conversation</MarkerContent> </Marker> <Marker variant="separator" role="status"> <MarkerIcon> <Spinner size="sm" /> </MarkerIcon> <MarkerContent>Running tests</MarkerContent> </Marker> </div> );}Add the shimmer utility class to MarkerContent for an animated streaming-text effect.
import { Marker, MarkerContent } from "@/components/ui/marker";
export function MarkerShimmer() { return ( <div className="flex w-full max-w-sm flex-col gap-8 py-12"> <Marker role="status"> <MarkerContent className="shimmer">Thinking...</MarkerContent> </Marker> <Marker variant="separator" role="status"> <MarkerContent className="shimmer">Reading 4 files</MarkerContent> </Marker> </div> );}Use the separator variant for labeled dividers, such as dates or section breaks, in a conversation.
import { Marker, MarkerContent } from "@/components/ui/marker";
export function MarkerSeparator() { return ( <div className="flex w-full max-w-sm flex-col gap-8 py-12"> <Marker variant="separator"> <MarkerContent>Today</MarkerContent> </Marker> <Marker variant="separator"> <MarkerContent>Worked for 42s</MarkerContent> </Marker> <Marker variant="separator"> <MarkerContent>Conversation compacted</MarkerContent> </Marker> </div> );}Use the border variant for status rows that should keep the default marker alignment while separating the next row.
import { FileTextIcon, GitBranchIcon, SearchIcon } from "lucide-react";
import { Marker, MarkerContent, MarkerIcon,} from "@/components/ui/marker";
export function MarkerBorder() { return ( <div className="flex w-full max-w-sm flex-col gap-3 py-12"> <Marker variant="border"> <MarkerIcon> <GitBranchIcon /> </MarkerIcon> <MarkerContent>Switched to release-candidate</MarkerContent> </Marker> <Marker variant="border"> <MarkerIcon> <SearchIcon /> </MarkerIcon> <MarkerContent>Reviewed 8 related files</MarkerContent> </Marker> <Marker variant="border"> <MarkerIcon> <FileTextIcon /> </MarkerIcon> <MarkerContent>Opened implementation notes</MarkerContent> </Marker> </div> );}Use MarkerIcon to render an icon alongside the content. Use flex-col to stack the icon above the content.
import { BookOpenCheck, GitBranchIcon, SearchIcon } from "lucide-react";
import { Marker, MarkerContent, MarkerIcon,} from "@/components/ui/marker";
export function MarkerIconDemo() { return ( <div className="flex w-full max-w-sm flex-col gap-12 py-12"> <Marker> <MarkerIcon> <GitBranchIcon /> </MarkerIcon> <MarkerContent>Switched to a new branch</MarkerContent> </Marker> <Marker variant="separator"> <MarkerIcon> <SearchIcon /> </MarkerIcon> <MarkerContent>Explored 4 files</MarkerContent> </Marker> <Marker className="flex-col"> <MarkerIcon> <BookOpenCheck /> </MarkerIcon> <MarkerContent>Syncing completed</MarkerContent> </Marker> </div> );}Turn a marker into a link or button with the render prop on Marker.
"use client";
import { GitBranchIcon, RotateCcwIcon } from "lucide-react";import { Marker, MarkerContent, MarkerIcon,} from "@/components/ui/marker";import { toast } from "@/components/ui/toast";
export function MarkerLinkButton() { return ( <div className="flex w-full max-w-sm flex-col gap-8 py-12"> <Marker render={<a href="#" />}> <MarkerIcon> <GitBranchIcon /> </MarkerIcon> <MarkerContent>View the pull request</MarkerContent> </Marker> <Marker render={ <button type="button" className="transition-colors hover:text-foreground" onClick={() => toast.add({ title: "You clicked the revert button" }) } /> } > <MarkerIcon> <RotateCcwIcon /> </MarkerIcon> <MarkerContent>Revert this change</MarkerContent> </Marker> </div> );}import { Marker, MarkerContent } from "@/components/ui/marker"
export function MarkerLinkDemo() { return ( <Marker render={<a href="#" />}> <MarkerContent>View the pull request</MarkerContent> </Marker> )}The root marker element. The file also exports markerVariants for composing the marker styles into custom components.
| Prop | Type | Default |
|---|---|---|
| variant | "default" | "border" | "separator" | "default" |
The marker layout. | ||
| render | ReactElement | function | — |
Render as a different element, such as a link. | ||
| className | string | — |
Additional classes to apply to the root element. | ||
A decorative icon slot. Hidden from assistive tech with aria-hidden.
| Prop | Type | Default |
|---|---|---|
| className | string | — |
Additional classes to apply to the icon slot. | ||
The marker text content.
| Prop | Type | Default |
|---|---|---|
| className | string | — |
Additional classes to apply to the content slot. | ||