<script setup lang="ts">
import { BookOpen, Clock, Users } from '@lucide/vue'
import { Card, Grid, Statistic } from '@hina-ui/vue'
</script>
<template>
<Grid :cols="3" gap="md" class="w-full max-w-3xl">
<Card>
<Statistic label="Pages this month" :value="12480" :delta="0.12" delta-label="vs last month">
<template #icon><BookOpen /></template>
</Statistic>
</Card>
<Card>
<Statistic
label="Reading time"
:value="36.5"
suffix="h"
:delta="-0.08"
delta-label="vs last month"
>
<template #icon><Clock /></template>
</Statistic>
</Card>
<Card>
<Statistic label="New followers" :value="212" :delta="0.31" delta-label="vs last month">
<template #icon><Users /></template>
</Statistic>
</Card>
</Grid>
</template>
Usage
import { Statistic } from '@hina-ui/vue'
label says what the figure is and value is the figure itself. Numbers are grouped according to the interface language; strings are shown as they are. The component has no border or background of its own; place it in a Card or a Panel.
<script setup lang="ts">
import { Card, Inline, Statistic } from '@hina-ui/vue'
</script>
<template>
<Inline gap="md" align="stretch">
<Card class="w-56">
<Statistic label="Reading" :value="12480" />
</Card>
<Card class="w-56">
<Statistic label="Status" value="Healthy" />
</Card>
</Inline>
</template>
Examples
Change
delta is the change against the previous period as a ratio, shown as a signed percentage: up in the success colour, down in the danger colour. deltaLabel names what it is compared with. For figures where lower is better, set invert.
<script setup lang="ts">
import { Card, Inline, Statistic } from '@hina-ui/vue'
</script>
<template>
<Inline gap="md" align="stretch">
<Card class="w-56">
<Statistic label="New reviews" :value="86" :delta="0.18" delta-label="vs last week" />
</Card>
<Card class="w-56">
<Statistic label="Active readers" :value="1204" :delta="-0.05" delta-label="vs last week" />
</Card>
<Card class="w-56">
<Statistic label="Reports" :value="3" :delta="-0.4" delta-label="vs last week" invert />
</Card>
</Inline>
</template>
Number format
format works as in NumberFormat: compact abbreviates large numbers, percent shows a percentage, currency shows money together with currency; precision caps the decimals.
<script setup lang="ts">
import { Card, Inline, Statistic } from '@hina-ui/vue'
</script>
<template>
<Inline gap="md" align="stretch">
<Card class="w-56">
<Statistic label="Total reads" :value="1284000" format="compact" />
</Card>
<Card class="w-56">
<Statistic label="Finish rate" :value="0.674" format="percent" :precision="1" />
</Card>
<Card class="w-56">
<Statistic label="Spent this month" :value="128.5" format="currency" currency="USD" />
</Card>
</Inline>
</template>
Prefix and suffix
prefix and suffix sit on either side of the figure in a smaller size, for units and symbols.
<script setup lang="ts">
import { Card, Inline, Statistic } from '@hina-ui/vue'
</script>
<template>
<Inline gap="md" align="stretch">
<Card class="w-56">
<Statistic label="Balance" :value="2480" prefix="$" />
</Card>
<Card class="w-56">
<Statistic label="Average session" :value="42" suffix="min" />
</Card>
</Inline>
</template>
Icon
The icon slot shows an icon on the right; it is decorative.
<script setup lang="ts">
import { Bookmark, MessageSquare } from '@lucide/vue'
import { Card, Inline, Statistic } from '@hina-ui/vue'
</script>
<template>
<Inline gap="md" align="stretch">
<Card class="w-56">
<Statistic label="Bookmarks" :value="318">
<template #icon><Bookmark /></template>
</Statistic>
</Card>
<Card class="w-56">
<Statistic label="Comments" :value="1024">
<template #icon><MessageSquare /></template>
</Statistic>
</Card>
</Inline>
</template>
Loading
With loading the figure and the change are each replaced by a skeleton while the label stays visible, so the layout does not jump.
<script setup lang="ts">
import { ref } from 'vue'
import { Card, Inline, Statistic, Switch } from '@hina-ui/vue'
const loading = ref(true)
</script>
<template>
<Inline gap="md" align="center">
<Card class="w-56">
<Statistic label="Pages this month" :value="12480" :delta="0.124" :loading="loading" />
</Card>
<Switch v-model="loading">Loading</Switch>
</Inline>
</template>
Sizes
Three sizes change only the size of the figure, md by default.
<script setup lang="ts">
import { Card, Inline, Statistic } from '@hina-ui/vue'
</script>
<template>
<Inline gap="md" align="stretch">
<Card class="w-48">
<Statistic label="Reading" :value="12480" size="sm" />
</Card>
<Card class="w-48">
<Statistic label="Reading" :value="12480" />
</Card>
<Card class="w-48">
<Statistic label="Reading" :value="12480" size="lg" />
</Card>
</Inline>
</template>
Accessibility
- Label, figure and change are plain text, read in reading order.
- The change arrow and the icon on the right are decorative and hidden from assistive technology; the direction is conveyed by the signed percentage.
API
Props
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | — | Required. What the figure is |
value | number | string | null | — | The figure; empty shows a dash |
format | 'decimal' | 'compact' | 'percent' | 'currency' | 'decimal' | Number format |
currency | string | — | Currency code, with currency |
precision | number | — | Maximum number of decimals |
prefix | string | — | Symbol before the figure |
suffix | string | — | Unit after the figure |
delta | number | — | Change as a ratio, 0.12 for 12% |
deltaLabel | string | — | What the change is compared with |
invert | boolean | false | Treat a decrease as the good change |
loading | boolean | false | Whether to show a skeleton |
size | 'sm' | 'md' | 'lg' | 'md' | Size of the figure |
class | string | — | Extra classes on the root element |
Slots
| Slot | Description |
|---|---|
| default | Content under the figure |
icon | Icon on the right |