Kpi Widget
Production-ready kpi widget with extensive token integration, state management, and semantic HTML.
Overview
The Kpi Widget component is a core building block of the Byteion design system, providing a robust, accessibility-compliant interface for its specific UI capabilities.
Why this exists
KPI widgets are large-format metric displays for hero dashboard positions. They emphasize a single number with visual context.
Mental model
A KPI widget is an oversized stat card. It dominates the dashboard and communicates the most important metric.
When to use
When not to use
Basic example
The following example demonstrates standard usage, fully compliant with Byteion's token-first approach.
Active Users
Number of active users in the last 30 days.
import { KpiWidget } from '@byteion/react';
export default function KpiWidgetDemo() {
return (
<div className="grid gap-4 p-6 md:grid-cols-3">
<KpiWidget title="MRR" value="$12,450" trend={{ value: '+8.4%', direction: 'up' }} />
<KpiWidget title="Active seats" value="84" trend={{ value: '+12', direction: 'up' }} />
<KpiWidget title="Avg response" value="1.4s" trend={{ value: '-0.3s', direction: 'down' }} tone="success" />
</div>
);
}
<script setup lang="ts">
import { KpiWidget } from '@byteion/vue';
</script>
<template>
<div class="grid gap-4 p-6 md:grid-cols-3">
<KpiWidget title="MRR" value="$12,450" :trend="{ value: '+8.4%', direction: 'up' }" />
<KpiWidget title="Active seats" value="84" :trend="{ value: '+12', direction: 'up' }" />
<KpiWidget title="Avg response" value="1.4s" :trend="{ value: '-0.3s', direction: 'down' }" tone="success" />
</div>
</template>
Variants
Each variant communicates a different meaning. Choose based on priority, not aesthetics.
Single default variant.
Sizes
Size should match the importance and context of the component.
- md — md size.
States
This component reacts seamlessly to the following interaction and data states:
- default — Resting appearance before interaction.
- hover — Pointer is over the element — visual feedback via color or shadow.
- focus — Keyboard or tab focus — shows ring indicator for accessibility.
- active — Currently selected or in use.
- disabled — Non-interactive — grayed out, cursor not-allowed.
- loading — Action in progress — spinner replaces icon, button is disabled.
Anatomy
Usage guidelines
- Use only for the top 1-3 metrics.
- Include a target or benchmark.
- Make the value the largest element.
Do and Don't
Do
- Use for top metrics.
- Include a target.
- Make value prominent.
Don't
- Do not use for secondary metrics.
- Do not clutter with too many elements.
- Do not omit context (target, trend).
Accessibility
Value must be accessible as text, not just visual.
Role:kpi-widget
Customization
Follows card and progress tokens.
Compose with React cva()
Use the exportedcva() +cn() utilities to compose your own variant on top of the Byteion tokens.
import { cva, cn, type VariantProps } from '@byteion/react';
const myKpiWidget = cva('base classes…', {
variants: {
accent: { soft:'border-primary-200', loud:'border-primary-500' },
},
defaultVariants: { accent:'soft' },
});
type Props = React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof myKpiWidget>;
Compose with Vue cva()
Use the exportedcva() +cn() utilities inside standard Vue setup blocks.
<script setup lang="ts">
import { computed, useAttrs } from 'vue';
import { cva, type VariantProps } from '@byteion/vue';
interface Props { accent?:'soft' |'loud' }
const props = withDefaults(defineProps<Props>(), { accent:'soft' });
const attrs = useAttrs();
const myKpiWidget = cva('base classes…', {
variants: { accent: { soft:'border-primary-200', loud:'border-primary-500' } },
});
const cls = computed(() => myKpiWidget({ accent: props.accent, class: attrs.class as string | undefined }));
</script>
Runtime events
Byteion keeps framework APIs idiomatic: HTML uses DOM custom events, React uses callback props, and Vue uses emitted events / v-model updates.
HTML / JS events
No HTML runtime events are declared by this adapter.
React callbacks
No React callback events are declared by this adapter.
Vue emits
No Vue emitted events are declared by this adapter.
Remote / AJAX
This component does not implement Byteion JS remote loading. Use normal HTML form submission, framework state, or your application data layer around it.
API Reference
Static HTML composition.
HTML Data Attributes
No custom data attributes required.
React Props · KpiWidgetProps
Extracted directly fromreact/src/components/KpiWidget.tsx.
export interface KpiWidgetProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title' | 'children'> {
title: ReactNode;
description?: ReactNode;
value: ReactNode;
trend?: KpiTrend;
status?: KpiStatus;
/** Light surface (default) or dark surface for premium emphasis. */
variant?: 'light' | 'dark';
/** Optional sparkline / chart node. Rendered to the right of the value on light, below on dark. */
chart?: ReactNode;
}
Vue Props · KpiWidgetProps
Extracted directly fromvue/src/components/KpiWidget.vue.
export interface KpiWidgetProps {
title: string;
description?: string;
value: string | number;
trend?: KpiTrend;
status?: KpiStatus;
variant?: 'light' | 'dark';
}
Developer tips
Common mistakes
- Using KPI widgets for too many metrics.
- Missing period, target, or benchmark.
- Showing trend without comparison context.
- Treating "up" as always good.
- Using the dark variant too often.
- Showing a chart without accessible meaning.
- Showing 0 while data is loading.
- Making the widget clickable without a clear destination.
- Using raw colours instead of tokens.
Production usage tips
- Test loading, empty, zero, negative, very large, stale, and missing values.
- Test long titles and localised number formats.
- Test positive, negative, neutral, warning, and critical statuses.
- Test chart visibility in light mode, dark mode, and branded themes.
- For Laravel or server-rendered dashboards, format values server-side or through shared helpers.
- For React or Vue SPAs, keep fetch, loading, and error state outside the presentational Kpi-widget.
- Coordinate Kpi-widget with Stat-card, Card, Progress, Badge, Skeleton, Empty state, Chart or Sparkline, Alert, and DataTable where needed.
Premium examples
Advanced patterns available in Byteion Pro:
Related components
- Stat-card — normal KPI grid surface
- Card — richer content surfaces
- Progress — goal or target progress
- Badge — inline status labels
- Skeleton — loading placeholder
- Empty state — no data state
- Alert — warning or error notifications
Unlock Premium Patterns
Get access to copy-paste ready Pro blocks, SaaS templates, and advanced data-tables built with this component.
Explore Pro Components