๐ข 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 { computed } from 'vue'
import { createReusableTemplate } from '@vueuse/core'
import type { NIndicatorProps } from '../../types'
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>