Indicator
A positioning utility that wraps content and places an overlay indicator (badge, dot, text) on any of 9 grid positions.
| Name | Category | Description | Type | Default |
|---|---|---|---|---|
type | Style | Type | 'primary' | 'success' | 'info' | 'warning' | 'danger' | 'primary' |
processing | Style | Pixel ping animation | boolean | false |
color | Color | Custom hex color | string | — |
placement | Behavior | Indicator position | 'top-start' | 'top-center' | 'top-end' | 'middle-start' | 'middle-center' | 'middle-end' | 'bottom-start' | 'bottom-center' | 'bottom-end' | 'top-end' |
offset | Behavior | Offset [x, y] in pixels | [number, number] | — |
inline | Behavior | Use inline-flex display | boolean | false |
default | Slot | Wrapped content | — | |
indicator | Slot | Indicator content (renders as dot when empty) | — |
Basic Usage
Wrap any content and the indicator appears as a dot by default. Use the indicator slot for custom content.
<template>
<div class="demo-indicator">
<px-indicator>
<div class="demo-box">Content</div>
</px-indicator>
<px-indicator type="danger">
<div class="demo-box">Alerts</div>
</px-indicator>
<px-indicator type="success">
<template #indicator>
<px-badge type="success" size="small">New</px-badge>
</template>
<div class="demo-box">Updates</div>
</px-indicator>
</div>
</template>
<style scoped>
.demo-indicator {
display: flex;
flex-wrap: wrap;
gap: 32px;
align-items: center;
}
.demo-box {
width: 80px;
height: 80px;
display: flex;
align-items: center;
justify-content: center;
border: 2px solid var(--px-border-color);
font-family: var(--px-font-family);
font-size: var(--px-font-size-base);
}
</style>Placement
Use placement to position the indicator in one of 9 grid positions.
<template>
<div class="demo-indicator-grid">
<px-indicator
v-for="p in placements"
:key="p"
:placement="p"
type="danger"
>
<template #indicator>
<px-badge type="danger" size="small">{{ p }}</px-badge>
</template>
<div class="demo-box" />
</px-indicator>
</div>
</template>
<script setup lang="ts">
const placements = [
'top-start',
'top-center',
'top-end',
'middle-start',
'middle-center',
'middle-end',
'bottom-start',
'bottom-center',
'bottom-end',
] as const;
</script>
<style scoped>
.demo-indicator-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 40px;
max-width: 720px;
padding: 40px;
justify-items: center;
}
.demo-box {
width: 80px;
height: 80px;
border: 2px solid var(--px-border-color);
}
</style>Types
Use type to set the indicator color theme.
<template>
<div class="demo-indicator">
<px-indicator v-for="t in types" :key="t" :type="t">
<div class="demo-box">{{ t }}</div>
</px-indicator>
</div>
</template>
<script setup lang="ts">
const types = ['primary', 'success', 'info', 'warning', 'danger'] as const;
</script>
<style scoped>
.demo-indicator {
display: flex;
flex-wrap: wrap;
gap: 32px;
align-items: center;
}
.demo-box {
width: 80px;
height: 80px;
display: flex;
align-items: center;
justify-content: center;
border: 2px solid var(--px-border-color);
font-family: var(--px-font-family);
font-size: 12px;
}
</style>With Badge
Combine with PxBadge in the indicator slot for number counters and labels.
<template>
<div class="demo-indicator">
<px-indicator>
<template #indicator>
<px-badge type="danger" size="small">3</px-badge>
</template>
<px-button>Messages</px-button>
</px-indicator>
<px-indicator placement="top-start">
<template #indicator>
<px-badge type="warning" size="small">99+</px-badge>
</template>
<px-button type="primary">Notifications</px-button>
</px-indicator>
<px-indicator>
<template #indicator>
<px-badge type="success" size="small" icon="check" />
</template>
<px-button type="success" plain>Verified</px-button>
</px-indicator>
</div>
</template>
<style scoped>
.demo-indicator {
display: flex;
flex-wrap: wrap;
gap: 32px;
align-items: center;
}
</style>Processing
Use processing to add a pixel ping animation for live status.
<template>
<div class="demo-indicator">
<px-indicator processing>
<div class="demo-box">Live</div>
</px-indicator>
<px-indicator processing type="danger">
<div class="demo-box">Alert</div>
</px-indicator>
<px-indicator processing type="success">
<div class="demo-box">Online</div>
</px-indicator>
</div>
</template>
<style scoped>
.demo-indicator {
display: flex;
flex-wrap: wrap;
gap: 32px;
align-items: center;
}
.demo-box {
width: 80px;
height: 80px;
display: flex;
align-items: center;
justify-content: center;
border: 2px solid var(--px-border-color);
font-family: var(--px-font-family);
font-size: var(--px-font-size-base);
}
</style>Offset
Use offset to fine-tune the indicator position with [x, y] pixel values.
<template>
<div class="demo-indicator">
<px-indicator :offset="[0, 0]">
<template #indicator>
<px-badge type="danger" size="small">0,0</px-badge>
</template>
<div class="demo-box">Default</div>
</px-indicator>
<px-indicator :offset="[8, 8]">
<template #indicator>
<px-badge type="primary" size="small">8,8</px-badge>
</template>
<div class="demo-box">Outward</div>
</px-indicator>
<px-indicator :offset="[-8, -8]">
<template #indicator>
<px-badge type="success" size="small">-8,-8</px-badge>
</template>
<div class="demo-box">Inward</div>
</px-indicator>
</div>
</template>
<style scoped>
.demo-indicator {
display: flex;
flex-wrap: wrap;
gap: 48px;
align-items: center;
}
.demo-box {
width: 80px;
height: 80px;
display: flex;
align-items: center;
justify-content: center;
border: 2px solid var(--px-border-color);
font-family: var(--px-font-family);
font-size: 12px;
}
</style>Custom Color
Use color to set a custom hex color for the dot indicator.
<template>
<div class="demo-indicator">
<px-indicator color="#ff6600">
<div class="demo-box">Orange</div>
</px-indicator>
<px-indicator color="#9333ea">
<div class="demo-box">Purple</div>
</px-indicator>
<px-indicator color="#06b6d4">
<template #indicator>
<px-badge color="#06b6d4" size="small">5</px-badge>
</template>
<div class="demo-box">Cyan</div>
</px-indicator>
</div>
</template>
<style scoped>
.demo-indicator {
display: flex;
flex-wrap: wrap;
gap: 32px;
align-items: center;
}
.demo-box {
width: 80px;
height: 80px;
display: flex;
align-items: center;
justify-content: center;
border: 2px solid var(--px-border-color);
font-family: var(--px-font-family);
font-size: var(--px-font-size-base);
}
</style>Inline
Use inline for inline-flex display, useful when embedding in text flow.
<template>
<div class="demo-indicator">
<p>
You have
<px-indicator inline type="danger">
<template #indicator>
<px-badge type="danger" size="small">3</px-badge>
</template>
<strong>unread messages</strong>
</px-indicator>
in your inbox.
</p>
</div>
</template>
<style scoped>
.demo-indicator {
font-family: var(--px-font-family);
font-size: var(--px-font-size-base);
line-height: 2;
}
</style>