rapidUI

Marker

Small status marker (dot, count or label) to annotate other elements.

Installation

pnpm dlx shadcn@latest add https://rdf.dev.360online.com/r/marker.json

Installs to @/components/ui/marker.

Manual installation

Install the dependencies:

pnpm add @base-ui/react@^1.8.0 class-variance-authority@^0.7.1

Copy the source into your project:

components/ui/marker.tsx
import { mergeProps } from '@base-ui/react/merge-props'
import { useRender } from '@base-ui/react/use-render'
import { cva, type VariantProps } from 'class-variance-authority'
import type * as React from 'react'
import { cn } from '@/lib/utils'

const markerVariants = cva(
	"group/marker relative flex min-h-4 w-full items-center gap-2 text-left text-sm text-muted-foreground [&_svg:not([class*='size-'])]:size-4 [a]:underline [a]:underline-offset-3 [a]:hover:text-foreground",
	{
		variants: {
			variant: {
				default: '',
				separator:
					'before:mr-1 before:h-px before:min-w-0 before:flex-1 before:bg-border after:ml-1 after:h-px after:min-w-0 after:flex-1 after:bg-border',
				border: 'border-b border-border pb-2',
			},
		},
	},
)

function Marker({
	className,
	variant = 'default',
	render,
	...props
}: useRender.ComponentProps<'div'> & VariantProps<typeof markerVariants>) {
	return useRender({
		defaultTagName: 'div',
		props: mergeProps<'div'>(
			{
				className: cn(markerVariants({ variant, className })),
			},
			props,
		),
		render,
		state: {
			slot: 'marker',
			variant,
		},
	})
}

function MarkerIcon({ className, ...props }: React.ComponentProps<'span'>) {
	return (
		<span
			data-slot="marker-icon"
			aria-hidden="true"
			className={cn("size-4 shrink-0 [&_svg:not([class*='size-'])]:size-4", className)}
			{...props}
		/>
	)
}

function MarkerContent({ className, ...props }: React.ComponentProps<'span'>) {
	return (
		<span
			data-slot="marker-content"
			className={cn(
				'min-w-0 wrap-break-word group-data-[variant=separator]/marker:flex-none group-data-[variant=separator]/marker:text-center *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground',
				className,
			)}
			{...props}
		/>
	)
}

export { Marker, MarkerIcon, MarkerContent, markerVariants }

Displays inline status updates, system notes and labelled separators in a conversation or activity log, such as "Case registered" or a date divider. Marker comes in default (inline), border (bordered row) and separator (centred label with divider lines) variants.

Features

  • Variants: default, separator and border
  • Optional decorative icon slot
  • Supports links inside the content
  • Works with Spinner and the shimmer utility for progress
  • render to render as another element, e.g. render={<output />}

Usage

import { Marker, MarkerContent, MarkerIcon } from '@/components/ui/marker'
import { Check } from 'lucide-react'

export function CaseRegistered() {
  return (
    <Marker>
      <MarkerIcon>
        <Check />
      </MarkerIcon>
      <MarkerContent>Case 2026-04812 was registered</MarkerContent>
    </Marker>
  )
}

Examples

Default

An inline status note.

Separator

Centred date labels and a closing note with divider lines.

Border

Rows separated by a bottom border.

Case History

Separator markers group the events of a case by day, with inline markers for each event and its time.

Progress

A completed step followed by a progress marker rendered as an output element.

A marker containing a link.

In Conversation

Markers mixed with messages in a conversation.

Accessibility

  • Marker is presentational by default; MarkerIcon is aria-hidden
  • For live progress updates render it as an output element or add role="status"
  • Use a real link or button (via the render prop) for interactive markers
  • Keep the text meaningful on its own without the icon