Docs
Shadcn

Marker 标记

为消息或内容片段提供紧凑的状态标记。

Preview
今天
已同步 128 首喜欢的歌曲
Code
import { GitBranchIcon, SearchIcon } from "lucide-react"

import {
  Marker,
  MarkerContent,
  MarkerIcon,
} from "@/styles/radix-rhea/ui/marker"
import { Spinner } from "@/styles/radix-rhea/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 />
        </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>
  )
}

The Marker component displays inline conversation markers such as status updates, system notes, bordered rows, and labeled separators. Compose it with Message in a conversation thread.

Scopify 说明

本页按 shadcn/ui 官方 Radix UI 组件文档的章节与示例完整整理。示例预览使用 Scopify 当前的 @scopify/ui/shadcn 实现;导入路径、主题 Token 和行为差异以本仓库源码为准。

Installation

npx shadcn@latest add marker

Usage

import { Marker, MarkerContent, MarkerIcon } from "@scopify/ui/shadcn/components/marker"
<Marker>
  <MarkerIcon>
    <CheckIcon />
  </MarkerIcon>
  <MarkerContent>Explored 4 files</MarkerContent>
</Marker>

Composition

Use the following composition to build a marker:

Marker
├── MarkerIcon
└── MarkerContent

Features

  • Inline marker, bordered row, and labeled separator variants
  • Decorative icon slot that is hidden from assistive tech
  • Polymorphic root via asChild for link and button markers
  • Pairs with the shimmer utility for streaming status text
  • Customizable styling through the className prop on every part

Variants

Use variant to switch between an inline marker, bordered row, and labeled separator.

Preview
今天
已同步 128 首喜欢的歌曲
Code
import { Marker, MarkerContent } from "@/styles/radix-rhea/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>
  )
}
VariantDescription
defaultAn inline marker for status, notes, and actions.
borderA default marker with a bottom border under the row.
separatorA centered label with divider lines on each side.

Status

Set role="status" and include a Spinner for streaming or in-progress markers so updates are announced.

Preview
今天
已同步 128 首喜欢的歌曲
Code
import {
  Marker,
  MarkerContent,
  MarkerIcon,
} from "@/styles/radix-rhea/ui/marker"
import { Spinner } from "@/styles/radix-rhea/ui/spinner"

export function MarkerStatusDemo() {
  return (
    <div className="flex w-full max-w-sm flex-col gap-8 py-12">
      <Marker role="status">
        <MarkerIcon>
          <Spinner />
        </MarkerIcon>
        <MarkerContent>Compacting conversation</MarkerContent>
      </Marker>
      <Marker variant="separator" role="status">
        <MarkerIcon>
          <Spinner />
        </MarkerIcon>
        <MarkerContent>Running tests</MarkerContent>
      </Marker>
    </div>
  )
}

Shimmer

Add the shimmer utility class to MarkerContent for an animated streaming-text effect. The utility ships with the shadcn package — see the shimmer docs for installation.

Preview
今天
已同步 128 首喜欢的歌曲
Code
import { Marker, MarkerContent } from "@/styles/radix-rhea/ui/marker"

export function MarkerShimmerDemo() {
  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>
  )
}

Separator

Use the separator variant for labeled dividers, such as dates or section breaks, in a conversation.

Preview
今天
已同步 128 首喜欢的歌曲
Code
import { Marker, MarkerContent } from "@/styles/radix-rhea/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

Use the border variant for status rows that should keep the default marker alignment while separating the next row.

Preview
今天
已同步 128 首喜欢的歌曲
Code
import { FileTextIcon, GitBranchIcon, SearchIcon } from "lucide-react"

import {
  Marker,
  MarkerContent,
  MarkerIcon,
} from "@/styles/radix-rhea/ui/marker"

export function MarkerBorderDemo() {
  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>
  )
}

With Icon

Use MarkerIcon to render an icon alongside the content. Use flex-col to stack the icon above the content.

Preview
今天
已同步 128 首喜欢的歌曲
Code
import { BookOpenCheck, GitBranchIcon, SearchIcon } from "lucide-react"

import {
  Marker,
  MarkerContent,
  MarkerIcon,
} from "@/styles/radix-rhea/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 asChild prop on Marker.

Preview
今天
已同步 128 首喜欢的歌曲
Code
"use client"

import { GitBranchIcon, RotateCcwIcon } from "lucide-react"
import { toast } from "sonner"

import {
  Marker,
  MarkerContent,
  MarkerIcon,
} from "@/styles/radix-rhea/ui/marker"

export function MarkerLinkButtonDemo() {
  return (
    <div className="flex w-full max-w-sm flex-col gap-8 py-12">
      <Marker asChild>
        <a href="#links-and-buttons">
          <MarkerIcon>
            <GitBranchIcon />
          </MarkerIcon>
          <MarkerContent>View the pull request</MarkerContent>
        </a>
      </Marker>
      <Marker asChild>
        <button
          type="button"
          className="transition-colors hover:text-foreground"
          onClick={() => toast("You clicked the revert button")}
        >
          <MarkerIcon>
            <RotateCcwIcon />
          </MarkerIcon>
          <MarkerContent>Revert this change</MarkerContent>
        </button>
      </Marker>
    </div>
  )
}
import { Marker, MarkerContent } from "@scopify/ui/shadcn/components/marker"

export function MarkerLinkDemo() {
  return (
    <Marker asChild>
      <a href="#">
        <MarkerContent>View the pull request</MarkerContent>
      </a>
    </Marker>
  )
}

Accessibility

Marker is presentational by default. The correct semantics depend on how you use it, so choose the role based on intent rather than relying on a single default.

Status and Progress

For streaming or progress markers such as "Thinking..." or a running tool, set role="status" so assistive tech announces the update as it appears. Marker forwards role to the underlying element.

<Marker role="status">
  <MarkerIcon>
    <Spinner />
  </MarkerIcon>
  <MarkerContent>Compacting conversation</MarkerContent>
</Marker>

Labeled Separators

A separator that carries text, such as a date or a section label, needs no role. The divider lines are decorative CSS pseudo-elements, and the text is announced as ordinary content.

<Marker variant="separator">
  <MarkerContent>Today</MarkerContent>
</Marker>

Note: Do not add role="separator" to a labeled divider. A separator takes its accessible name from aria-label, not from its text, and its contents are treated as presentational, so the visible label would not be announced. Reserve role="separator" for a divider with no meaningful text.

Bordered Markers

A bordered marker keeps the same semantics as the default marker. The bottom border is decorative, so choose role="status", asChild, or no role based on the marker's purpose.

<Marker variant="border">
  <MarkerIcon>
    <FileTextIcon />
  </MarkerIcon>
  <MarkerContent>Opened implementation notes</MarkerContent>
</Marker>

Decorative Icons

MarkerIcon is decorative and hidden from assistive tech with aria-hidden, so the adjacent MarkerContent carries the meaning. For an icon-only marker, provide an aria-label or visible text so it is not announced as empty.

<Marker aria-label="Synced">
  <MarkerIcon>
    <CheckIcon />
  </MarkerIcon>
</Marker>

Interactive Markers

When a marker links or triggers an action, render it as a real <button> or <a> with the asChild prop so it is focusable and exposes the correct role. The accessible name comes from the marker text.

<Marker asChild>
  <a href="/files">
    <MarkerIcon>
      <FileTextIcon />
    </MarkerIcon>
    <MarkerContent>Explored 4 files</MarkerContent>
  </a>
</Marker>

API Reference

Marker

The root marker element. The file also exports markerVariants for composing the marker styles into custom components.

PropTypeDefaultDescription
variant"default" | "border" | "separator""default"The marker layout.
asChildbooleanfalseRender as the child element, such as a link.
classNamestring-Additional classes to apply to the root element.

MarkerIcon

A decorative icon slot. Hidden from assistive tech with aria-hidden.

PropTypeDefaultDescription
classNamestring-Additional classes to apply to the icon slot.

MarkerContent

The marker text content.

PropTypeDefaultDescription
classNamestring-Additional classes to apply to the content slot.

本页内容