Blode UI
GitHub

Marker

A compact inline status line for activity feeds and transcripts, with optional icon, separator, and border variants.

Loading
Loading...
import { GitBranchesIcon, SearchIcon } from "blode-icons-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>
          <GitBranchesIcon />
        </MarkerIcon>
        <MarkerContent>Switched to a new branch</MarkerContent>
      </Marker>
      <Marker render={<output />}>
        <MarkerIcon>
          <Spinner />
        </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>
  );
}

Installation

npx shadcn@latest add "https://ui.blode.co/r/styles/default/marker"

Usage

import { Marker, MarkerContent, MarkerIcon } from "@/components/ui/marker";
<Marker>
  <MarkerIcon>
    <GitBranchesIcon />
  </MarkerIcon>
  <MarkerContent>Switched to a new branch</MarkerContent>
</Marker>

Examples

Variants

Use the variant prop to switch between default, separator, and border styles.

Loading
Loading...
import { Marker, MarkerContent } from "@/components/ui/marker";
 
export function MarkerVariantsDemo() {
  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>
  );
}

Icon

Wrap an icon in MarkerIcon to lead the line with a glyph.

Loading
Loading...
import { BookIcon, GitBranchesIcon, SearchIcon } from "blode-icons-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>
          <GitBranchesIcon />
        </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>
          <BookIcon />
        </MarkerIcon>
        <MarkerContent>Syncing completed</MarkerContent>
      </Marker>
    </div>
  );
}

Separator

The separator variant centers the content between two rules, useful for timeline dividers.

Loading
Loading...
import { Marker, MarkerContent } from "@/components/ui/marker";
 
export function MarkerSeparatorDemo() {
  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>
  );
}

Border

The border variant adds a bottom rule, useful for row boundaries in a feed.

Loading
Loading...
import { FileTextIcon, GitBranchesIcon, SearchIcon } from "blode-icons-react";
 
import { Marker, MarkerContent, MarkerIcon } from "@/components/ui/marker";
 
export function MarkerBorderDemo() {
  return (
    <div className="flex w-full max-w-sm flex-col gap-3 py-12">
      <Marker variant="border">
        <MarkerIcon>
          <GitBranchesIcon />
        </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>
  );
}

Status

Add a Spinner inside MarkerIcon and role="status" to announce in-progress work.

Loading
Loading...
import { Marker, MarkerContent, MarkerIcon } from "@/components/ui/marker";
import { Spinner } from "@/components/ui/spinner";
 
export function MarkerStatusDemo() {
  return (
    <div className="flex w-full max-w-sm flex-col gap-8 py-12">
      <Marker render={<output />}>
        <MarkerIcon>
          <Spinner />
        </MarkerIcon>
        <MarkerContent>Compacting conversation</MarkerContent>
      </Marker>
      <Marker render={<output />} variant="separator">
        <MarkerIcon>
          <Spinner />
        </MarkerIcon>
        <MarkerContent>Running tests</MarkerContent>
      </Marker>
    </div>
  );
}

Use the render prop to render the marker as a link or button.

Loading
Loading...
"use client";
 
import { GitBranchesIcon, RotateCcwIcon } from "blode-icons-react";
import { toast } from "sonner";
 
import { Marker, MarkerContent, MarkerIcon } from "@/components/ui/marker";
 
export function MarkerLinkButtonDemo() {
  return (
    <div className="flex w-full max-w-sm flex-col gap-8 py-12">
      <Marker render={<a aria-label="View the pull request" href="#links-and-buttons" />}>
        <MarkerIcon>
          <GitBranchesIcon />
        </MarkerIcon>
        <MarkerContent>View the pull request</MarkerContent>
      </Marker>
      <Marker
        render={
          <button
            aria-label="Revert this change"
            className="transition-colors hover:text-foreground"
            onClick={() => toast("You clicked the revert button")}
            type="button"
          />
        }
      >
        <MarkerIcon>
          <RotateCcwIcon />
        </MarkerIcon>
        <MarkerContent>Revert this change</MarkerContent>
      </Marker>
    </div>
  );
}

Streaming

Apply the shimmer utility to MarkerContent for a streaming, in-progress effect.

Loading
Loading...
import { Marker, MarkerContent } from "@/components/ui/marker";
 
export function MarkerShimmerDemo() {
  return (
    <div className="flex w-full max-w-sm flex-col gap-8 py-12">
      <Marker render={<output />}>
        <MarkerContent className="shimmer">Thinking...</MarkerContent>
      </Marker>
      <Marker render={<output />} variant="separator">
        <MarkerContent className="shimmer">Reading 4 files</MarkerContent>
      </Marker>
    </div>
  );
}