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 https://herocn.dev/r/marker.jsonimport { 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 { toast } from "sonner";
import {
Marker,
MarkerContent,
MarkerIcon,
} from "@/components/ui/marker";
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("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" |
| render | ReactElement | function | — |
| className | string | — |
A decorative icon slot. Hidden from assistive tech with aria-hidden.
| Prop | Type | Default |
|---|---|---|
| className | string | — |
The marker text content.
| Prop | Type | Default |
|---|---|---|
| className | string | — |