Marker
A Marker shows users a line in a conversation that nobody sent, such as a date, an event, or a status.
When to Use
- for an event in the conversation, such as “Camille sent INV-2026-014”
- for a break with a label, like “Today”, at
variant="separator" - for work in progress, like “Sending the invoice”, with a Spinner and
role="status" - as a button or a link, for an action on the conversation, like “Show 3 earlier messages”
An event isn’t a message. When an event is shown in a Bubble, users read it as something that a sender wrote.
When Not to Use
- for what a sender wrote (use a Bubble in a Message)
- for a line with no label (use a Separator)
- for the status of a record, such as “Paid” (use a Badge)
Anatomy
| Element | Usage |
|---|---|
| Content | Required |
| Icon | Optional |
| Container | Required |
A Marker is a row as wide as its container.
Place a Marker between two Messages or inside the MessageContent of one. See Message for both placements.
Variants
| Variant | Purpose |
|---|---|
default | An event, a note, or a status at the start of the row |
separator | A break with a centered label, like a date |
border | A row with a line under it, which separates it from what follows |
Behavior
The text of a Marker wraps, and a word that is longer than the row breaks.
Buttons and Links
To render a button or an a in place of the div, pass the element to render on Marker.
Shimmer
To make the text shimmer, add the class shimmer to MarkerContent, as “Elise is typing” has in the preview.
Content
| String | Rule | Example | Counterexample |
|---|---|---|---|
| An event | Say who did what, in sentence case, with no period | “Camille sent INV-2026-014” | “Invoice Sent.” |
| A status | Name the work that is in progress | “Sending the invoice” | “Please wait” |
| A button or a link | Start with the verb | “Show 3 earlier messages” | “3 earlier messages” |
Accessibility
A Marker is a div with no role, and it isn’t focusable. Its role depends on its purpose, so the product sets the role. MarkerIcon has aria-hidden="true", so the text alone names the Marker.
Requirements
A Marker that reports progress, for example “Sending the invoice”, needs role="status" so that screen readers can
announce it without moving focus, as WCAG 2.2 SC 4.1.3 Status Messages requires.
Avoid setting role="separator" on a separator Marker. That role gets its name from aria-label and hides its content, so screen readers would skip “Today”. When the Marker has no role, screen readers read the label as text.
Installation
npx shadcn@latest add @summit/markerUsage
import { Marker, MarkerContent } from '@/components/ui/marker';
<Marker>
<MarkerContent>Camille sent INV-2026-014</MarkerContent>
</Marker>;With an Icon
To show one icon before the text, use MarkerIcon.
import { MarkerIcon } from '@/components/ui/marker';
import { ReceiptIcon } from '@phosphor-icons/react';
<Marker>
<MarkerIcon>
<ReceiptIcon />
</MarkerIcon>
<MarkerContent>Camille sent INV-2026-014</MarkerContent>
</Marker>;A Status
Set role="status", and place a Spinner in MarkerIcon.
import { Spinner } from '@/components/ui/spinner';
<Marker role="status">
<MarkerIcon>
<Spinner />
</MarkerIcon>
<MarkerContent>Sending the invoice</MarkerContent>
</Marker>;A Labeled Break
Set variant="separator".
<Marker variant="separator">
<MarkerContent>Today</MarkerContent>
</Marker>As a Button
Pass a button with type="button" to render. For a link, pass an a.
<Marker render={<button type="button" />}>
<MarkerContent>Show 3 earlier messages</MarkerContent>
</Marker>While Someone Types
Add shimmer to MarkerContent.
<Marker>
<MarkerContent className="shimmer">Elise is typing</MarkerContent>
</Marker>API Reference
Other props are passed to the element of each part.
Marker
| Prop | Type | Default | Description |
|---|---|---|---|
variant | 'default' | 'separator' | 'border' | 'default' | The layout of the row and its lines |
See the Base UI useRender documentation for render.