Marker
An inline conversation marker — status lines, system notes, and labelled dividers — built on Base UI render, polymorphic to a link or button.
- Status
- Since
0.1.0- Accessibility pattern
- decorative icon + text
Last updated
Install
Add Marker from the VegaStack registry. The CLI verifies the item's integrity hash before writing it.
pnpm dlx shadcn@latest add @vegastack/markerUsage
import { Marker, MarkerContent, MarkerIcon } from "@/components/ui/marker";
<Marker>
<MarkerIcon>
<CheckIcon />
</MarkerIcon>
<MarkerContent>All checks passed</MarkerContent>
</Marker>;Anatomy
A Marker is a single inline row inside a conversation. MarkerIcon is a
decorative leading slot; MarkerContent is the (wrapping) text. The root is a
group/marker, so content can react to the chosen variant.
Marker— the row (data-slot="marker",data-variant). Built on Base UIuseRender, sorenderturns it into any element (a link, a button).MarkerIcon— the leading icon (data-slot="marker-icon",aria-hidden). Any baresvgchild is sized tosize-4.MarkerContent— the text (data-slot="marker-content"). Wraps long content; centres itself under theseparatorvariant.
Examples
Status markers
Variants
default, separator (a centred label with divider lines), and border (a row
with a bottom hairline).
Separators
variant="separator" renders a centred label flanked by divider lines — useful
for date dividers and section breaks within a thread.
Bordered list
variant="border" stacks status rows with a hairline under each.
Status (live region)
Give an in-progress marker role="status" so assistive tech announces it. Pair
with a Spinner for the visual cue.
Streaming text
Pair MarkerContent with the shimmer utility (with
or without a spinner) for in-progress, streaming copy.
As a link or button
Pass render to make the whole row a link or a button without losing the marker
styling.
Motion
Pass animateIn to pop a marker in (motion-pop-in) when its own appearance is the event — a
status note that just landed, a divider inserted at the head of a live thread. It's off by
default: markers that are part of an already-rendered thread history must not pop on page load.
Waiting for the merge…
Inline link in content
For a marker where only part of the text links — not the whole row — nest an
<a> inside MarkerContent. It inherits the underlined, hover-brightening link
affordance, leaving the rest of the row plain. Use this instead of render when
the marker itself isn't the link target.
Playground
Every Marker prop, auto-generated from its TypeScript types.
API Reference
Marker
| Prop | Type | Default | Description |
|---|---|---|---|
animateIn | boolean | false | Opt-in mount animation (motion-pop-in) for a marker that appears in
response to a real event — a status note that just landed, a new "Today"
divider inserted at the head of a thread. **Default off**: markers that are
part of an already-rendered thread history must not pop on initial page
load. Set it only for a marker whose own appearance is the signal (mirrors
Badge's animateIn). |
render | useRender.RenderProp<Record<string, unknown>> | — | Render the marker as a different element (e.g. a link or button) via Base UI
render composition. Pass a ReactElement or a render function. |
variant | MarkerVariant | 'default' | Layout style.
- default: a plain inline marker (default).
- separator: a centred label with divider lines either side.
- border: a row with a bottom hairline. |
MarkerIcon
The leading icon slot. Accepts the standard <span> props plus className; it
is aria-hidden and sizes any bare svg child to size-4.
MarkerIcon
MarkerIcon adds no props of its own — it accepts everything the underlying element or Base UI primitive accepts (className, ref, ARIA attributes, event handlers).
Data attributes and CSS variables on MarkerIcon
| Attribute | Values |
|---|---|
data-slot | "marker-icon" |
MarkerContent
The wrapping text slot. Accepts the standard <span> props plus className; it
centres under the separator variant and gives any nested <a> the underlined,
hover-brightening link affordance.
MarkerContent
MarkerContent adds no props of its own — it accepts everything the underlying element or Base UI primitive accepts (className, ref, ARIA attributes, event handlers).
Data attributes and CSS variables on MarkerContent
| Attribute | Values |
|---|---|
data-slot | "marker-content" |
Accessibility
MarkerIconisaria-hidden— the adjacentMarkerContenttext carries the meaning, so never rely on the icon alone.- When rendered as a link/button via
render, the element keeps native semantics and the global:focus-visiblering. - For an in-progress marker, add
role="status"so the row is announced as a live region when its text updates. - A streaming
shimmermarker honoursprefers-reduced-motion(the sweep stops).
| Contract | States tested |
|---|---|
| Behaviour | default |
| Accessibility | semantic-html |
| Visual | default, hover |