Skip to content

Indicator

A positioning utility that wraps content and places an overlay indicator (badge, dot, text) on any of 9 grid positions.

NameCategoryDescriptionTypeDefault
type? StyleType'primary' | 'success' | 'info' | 'warning' | 'danger''primary'
processing? StylePixel ping animationbooleanfalse
color? ColorCustom hex colorstring
placement? BehaviorIndicator position'top-start' | 'top-center' | 'top-end' | 'middle-start' | 'middle-center' | 'middle-end' | 'bottom-start' | 'bottom-center' | 'bottom-end''top-end'
offset? BehaviorOffset [x, y] in pixels[number, number]
inline? BehaviorUse inline-flex displaybooleanfalse
default? SlotWrapped content
indicator? SlotIndicator 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>