Indicator
Indicator places a status dot or count on a parent element.
Source
LLM docs
Package
Examples
5
Properties
39
Playground
Basics
Place
Indicator inside a relatively positioned container to pin a status dot to its corner.Loading demo…
import { Avatar, Block, Indicator } from '@plocks/ui';
export function Demo() {
return (
<Block position="relative">
<Avatar size="lg" fallback="JS" />
<Indicator size="md" accessibilityLabel="Online" />
</Block>
);
}Placements
Set
placement to pin the indicator to any corner of its container.Loading demo…
import { Block, Indicator, Row, Text } from '@plocks/ui';
const PLACEMENTS = ['top-left', 'top-right', 'bottom-left', 'bottom-right'] as const;
export function Demo() {
return (
<Row gap="md" wrap="wrap">
{PLACEMENTS.map((placement) => (
<Block
key={placement}
w={88}
h={88}
radius="lg"
bg="subtle"
position="relative"
align="center"
justify="center"
>
<Text size="xs" c="secondary">
{placement}
</Text>
<Indicator placement={placement} />
</Block>
))}
</Row>
);
}Sizes
Set the
size prop to any token (xs–3xl) for theme-aligned dots, or provide a raw number when you need a bespoke diameter for your badge.Loading demo…
import { Block, Card, Indicator, Row, Text } from '@plocks/ui';
const SIZES = ['xs', 'sm', 'md', 'lg', 'xl', '2xl', '3xl', 24] as const;
export function Demo() {
return (
<Row align="center" gap="lg" wrap="wrap">
{SIZES.map((size) => (
<Block key={size} align="center">
<Card w={56} h={56} radius="lg">
<Indicator placement="top-right" size={size} offset={4} />
</Card>
<Text variant="small">{size}</Text>
</Block>
))}
</Row>
);
}Statuses
Map presence states (online, idle, busy, offline) to palette colors with
color, and give each dot an accessibilityLabel so the status is announced, not just shown.Loading demo…
import { Avatar, Block, Indicator, Row, Text } from '@plocks/ui';
const presenceStatuses = [
{ label: 'Online', palette: 'success', avatar: require('../../../../assets/avatars/avatar-1.png') },
{ label: 'Idle', palette: 'warning', avatar: require('../../../../assets/avatars/avatar-2.png') },
{ label: 'Busy', palette: 'error', avatar: require('../../../../assets/avatars/avatar-3.png') },
{ label: 'Offline', palette: 'gray', avatar: require('../../../../assets/avatars/avatar-4.png') },
] as const;
export function Demo() {
return (
<Row gap="lg" wrap="wrap">
{presenceStatuses.map((status) => (
<Block key={status.label} align="center">
<Block position="relative">
<Avatar
size={56}
fallback={status.label.charAt(0)}
src={status.avatar}
/>
<Indicator size={14} color={status.palette} accessibilityLabel={status.label} />
</Block>
<Text size="xs" c="secondary">
{status.label}
</Text>
</Block>
))}
</Row>
);
}Labels & counts
Pass
label to render a count or short text inside the indicator — the dot expands to a pill so multi-digit values fit. labelProps accepts any <Text> props for fonts, weights, etc. For arbitrary custom content (icons, status markers), use children instead.Loading demo…
import { View } from 'react-native';
import { Block, Indicator, Row } from '@plocks/ui';
const Anchor = ({ children }: { children?: React.ReactNode }) => (
<Block w={48} h={48} radius="full" bg="subtle" position="relative" align="center" justify="center">
{children}
</Block>
);
export function Demo() {
return (
<Row gap="lg" wrap="wrap">
<Anchor>
<Indicator size={20} color="#ef4444" label={3} />
</Anchor>
<Anchor>
<Indicator size={20} color="#ef4444" label={12} />
</Anchor>
<Anchor>
<Indicator size={20} color="#ef4444" label="99+" />
</Anchor>
<Anchor>
<Indicator size={22} color="#0ea5e9" label="42" labelProps={{ ff: 'monospace' }} />
</Anchor>
<Anchor>
<Indicator
size={22}
color="#10b981"
label="NEW"
labelProps={{ tt: 'uppercase', lts: 1, size: 9 }}
/>
</Anchor>
<Anchor>
<Indicator size={16} color="#10b981">
<View style={{ width: 6, height: 6, borderRadius: 3, backgroundColor: '#fff' }} />
</Indicator>
</Anchor>
</Row>
);
}React Native design for iOS, Android, and Web.
Quick Links
Resources