Indicator
Mark an item that needs attention with a count or dot in its corner.
<script setup lang="ts">import { Bell, Inbox, MessageSquare } from '@lucide/vue'import { UiIndicator, UiIconButton } from 'grani'</script> <template> <div class="flex items-center gap-8"> <UiIndicator :count="0"> <UiIconButton :icon="Bell" ariaLabel="Notifications, none new" /> </UiIndicator> <UiIndicator :count="3"> <UiIconButton :icon="Bell" ariaLabel="Notifications, 3 new" /> </UiIndicator> <UiIndicator :count="12"> <UiIconButton :icon="Inbox" ariaLabel="Inbox, 12 new" /> </UiIndicator> <UiIndicator :count="150"> <UiIconButton :icon="MessageSquare" ariaLabel="Messages, more than 99 new" /> </UiIndicator> </div></template>
Also called notification dot, status dot, badge dot.
Usage
<UiIndicator>…</UiIndicator> With GraniResolver in the Vite config, a template needs no import: set it up once.
API
| Name · type | Default | Description |
|---|---|---|
| Behavior | ||
| countnumber= 0 | 0 | The number on the corner; 0 hides the mark unless dot is set. |
| maxnumber= 99 | 99 | The largest count shown as is; above it the mark reads 99+. |
| dotboolean= false | false | A dot instead of a number: online, unsaved, something new. |
| placementtop-end | top-start | bottom-end | bottom-start= "top-end" | "top-end" | Which corner of the element holds the mark. |
| pulseboolean= false | false | A ring that keeps expanding: the state is live. Stops under reduced motion. |
| roundboolean= false | false | The element is a circle (an avatar, as wide as it is tall): the mark sits on its edge, not on the corner of its box. |
| Look | ||
| tonebrand | neutral | success | warning | danger | info= "danger" | "danger" | Meaning of the mark: danger for unread by default, success for online. |
| sizesm | md= "md" | "md" | sm on an xs icon button or a small avatar, md on an sm or md icon button. |
Anything else lands on the root element: native attributes, aria-*, data-testid.