๐ข Indicator
Basic
NIndicator is a component that can be used to display a basic indicator with or without a label.
PR
Variant
indicator="{variant}" - change the variant of the indicator.
For the moment, only the
solid variant is available. You can add your own variant through configuration.| Variant | Description |
|---|---|
solid | The default variant. |
~ | The unstyle or base variant |
Color
indicator="{variant}-{color}" - change the color of the indicator.
You can use any color provided by the Tailwind CSS color palette, the default is
primary. You can also add your own colors to the palette through the Configuration section.PR
Label
label="{label}" - add label to the indicator.
11
NewNew
PR1 message1 message
Ping
ping - add a ping animation to the indicator.
PR
Size
indicator="{size}" - change the size of the indicator.
PR
PR
Visibility
visible - change the visibility of the indicator.
11
Placement
indicator="{placement}" - change the placement of the indicator.
| Placement | Description |
|---|---|
top-right | The default placement. |
top-left | Position indicator top left. |
bottom-right | Position indicator bottom right. |
bottom-left | Position indicator bottom left. |
You can add your own placement through configuration. see Configuration section.
TR
BR
TL
BL
Slots
| Name | Description |
|---|---|
default | The content of the indicator. |
indicator | The entire indicator, this will reset including the position. |
label | The label of the indicator. |
Props
export interface NIndicatorProps {
/**
* Set the size of the indicator.
*
* @default 'md'
*/
size?: string
/**
* Allows you to add `UnaUI` button preset properties,
* Think of it as a shortcut for adding options or variants to the preset if available.
*
* @see https://github.com/una-ui/una-ui/blob/main/packages/preset/src/_shortcuts/indicator.ts
* @example
* indicator="solid-green top-right"
*/
indicator?: string
/**
* Add a label to the indicator.
*
* @example
* label="new"
*/
label?: string
/**
* Add ping animation to the indicator.
*
* @default false
*/
ping?: boolean
/**
* Set visibility of the indicator.
*
* @default true
*/
visible?: boolean
/**
* `UnaUI` preset configuration
*
* @see https://github.com/una-ui/una-ui/blob/main/packages/preset/src/_shortcuts/indicator.ts
*/
una?: {
// base
indicator?: string
// wrapper
indicatorWrapper?: string
}
}
Presets
type IndicatorPrefix = 'indicator'
export const staticIndicator: Record<`${IndicatorPrefix}-${string}` | IndicatorPrefix, string> = {
// config
'indicator-default-variant': 'indicator-solid',
'indicator-default-placement': 'indicator-top-right',
// base
'indicator': 'absolute min-h-1.5em min-w-1.5em flex items-center justify-center rounded-full font-medium py-none px-0.3em ring-2 ring-$c-background',
// indicator type sizes
'indicator-dot': 'size-0.45em',
'indicator-label': 'size-0.75em',
// wrapper
'indicator-wrapper': 'relative inline-flex',
// placements
'indicator-top-right': 'top-0 -ml-1.3em -mt-0.1em',
'indicator-bottom-right': 'bottom-0 -ml-1.3em -mb-0.1em',
'indicator-top-left': 'top-0 left-0 -mr-1.3em -mt-0.1em',
'indicator-bottom-left': 'bottom-0 left-0 -mr-1.3em -mb-0.1em',
}
export const dynamicIndicator = [
[/^indicator-solid(-(\S+))?$/, ([, , c = 'primary']) => `bg-${c}-600 dark:bg-${c}-500 text-inverted`],
]
export const indicator = [
...dynamicIndicator,
staticIndicator,
]
Component
<script setup lang="ts">
import type { NIndicatorProps } from '../../types'
import { createReusableTemplate } from '@vueuse/core'
import { computed } from 'vue'
defineOptions({
inheritAttrs: false,
})
const props = withDefaults(defineProps<NIndicatorProps>(), {
visible: true,
})
const indicatorPlacements = ['top-left', 'top-right', 'bottom-left', 'bottom-right'] as const
const hasPlacement = computed(() => indicatorPlacements.some(indicatorPlacements => props.indicator?.includes(indicatorPlacements)))
const indicatorVariants = ['solid'] as const
const hasVariant = computed(() => indicatorVariants.some(indicatorVariants => props.indicator?.includes(indicatorVariants)))
const isBaseVariant = computed(() => props.indicator?.includes('~'))
const [DefineTemplate, ReuseTemplate] = createReusableTemplate<{
ping?: boolean
}>()
</script>
<template>
<div
indicator="wrapper"
:class="una?.indicatorWrapper"
>
<slot />
<span v-if="visible" :size="size">
<DefineTemplate v-slot="{ ping }">
<slot name="indicator">
<span
v-bind="$attrs"
:indicator="indicator"
class="indicator whitespace-nowrap"
:class="[
{ 'indicator-default-placement': !hasPlacement },
{ 'indicator-default-variant': !hasVariant && !isBaseVariant },
{ 'animate-ping ring-none': ping },
!label ? 'indicator-dot' : 'indicator-label',
una?.indicator,
]"
>
<slot name="label">
{{ label }}
</slot>
</span>
</slot>
</DefineTemplate>
<ReuseTemplate :ping="ping" />
<ReuseTemplate />
</span>
</div>
</template>