Menu

Change language

GitHub repo

Dashboard Kpis

blockanalytics

Four-tile KPI row. Each tile is an inline Card: label, big number, signed trend pill, and a sparkline. No items prop — edit the tiles in place after install.

Installation

$npx uipkge-ng@latest add dashboard-kpis
Manifest:https://uipkge.dev/r/angular/dashboard-kpis.jsonInstalls to:src/app/components/blocks/dashboard-kpis/

Variants

Loading interactive previews…

npm dependencies

Files installed (2)

  • src/app/components/blocks/dashboard-kpis/dashboard-kpis.component.ts4.6 kB
    // Four-tile KPI row. Each tile is an inline Card: label, big number, signed
    // trend pill, and a sparkline. No items input -- edit the tiles in place.
    import { Component, ChangeDetectionStrategy } from '@angular/core'
    import { LucideAngularModule, TrendingDown, TrendingUp } from 'lucide-angular'
    import {
      UiCardComponent,
      UiCardContentComponent,
      UiCardHeaderComponent,
      UiCardTitleComponent,
    } from '@/ui/card/card.component'
    import { UiSparklineComponent } from '@/ui/charts/sparkline/sparkline.component'
    import { UiKpiGridComponent } from '@/ui/kpi-grid/kpi-grid.component'
    
    const headcount = [108, 112, 115, 119, 121, 122, 124]
    const openRoles = [18, 16, 17, 15, 14, 13, 12]
    const timeToFill = [42, 40, 38, 39, 36, 34, 32]
    const attrition = [8.4, 8.1, 8.6, 8.2, 7.9, 8.0, 7.6]
    
    @Component({
      changeDetection: ChangeDetectionStrategy.Eager,
      selector: 'ui-dashboard-kpis, [ui-dashboard-kpis]',
      standalone: true,
      host: { class: 'contents', 'data-slot': 'dashboard-kpis' },
      imports: [
        LucideAngularModule,
        UiCardComponent,
        UiCardHeaderComponent,
        UiCardTitleComponent,
        UiCardContentComponent,
        UiSparklineComponent,
        UiKpiGridComponent,
      ],
      template: `
        <div ui-kpi-grid>
          <div ui-card class="flex flex-col justify-between">
            <div ui-card-header class="flex flex-row items-start justify-between pb-2">
              <h3 ui-card-title class="text-muted-foreground text-xs font-medium tracking-widest uppercase">Headcount</h3>
              <span
                class="bg-success/10 text-success inline-flex items-center gap-1 rounded-full px-1.5 py-0.5 text-xs font-medium"
              >
                <lucide-icon [img]="TrendingUp" class="size-3" aria-hidden="true" />
                +12
              </span>
            </div>
            <div ui-card-content class="space-y-3">
              <p class="text-2xl font-semibold tracking-tight tabular-nums">124</p>
              <ui-sparkline [data]="headcount" [height]="36" ariaLabel="Headcount trend" />
            </div>
          </div>
    
          <div ui-card class="flex flex-col justify-between">
            <div ui-card-header class="flex flex-row items-start justify-between pb-2">
              <h3 ui-card-title class="text-muted-foreground text-xs font-medium tracking-widest uppercase">Open roles</h3>
              <span
                class="bg-success/10 text-success inline-flex items-center gap-1 rounded-full px-1.5 py-0.5 text-xs font-medium"
              >
                <lucide-icon [img]="TrendingDown" class="size-3" aria-hidden="true" />
                −6
              </span>
            </div>
            <div ui-card-content class="space-y-3">
              <p class="text-2xl font-semibold tracking-tight tabular-nums">12</p>
              <ui-sparkline [data]="openRoles" [height]="36" ariaLabel="Open roles trend" />
            </div>
          </div>
    
          <div ui-card class="flex flex-col justify-between">
            <div ui-card-header class="flex flex-row items-start justify-between pb-2">
              <h3 ui-card-title class="text-muted-foreground text-xs font-medium tracking-widest uppercase">
                Time to fill
              </h3>
              <span
                class="bg-success/10 text-success inline-flex items-center gap-1 rounded-full px-1.5 py-0.5 text-xs font-medium"
              >
                <lucide-icon [img]="TrendingDown" class="size-3" aria-hidden="true" />
                −10d
              </span>
            </div>
            <div ui-card-content class="space-y-3">
              <p class="text-2xl font-semibold tracking-tight tabular-nums">32d</p>
              <ui-sparkline [data]="timeToFill" [height]="36" ariaLabel="Time to fill trend" />
            </div>
          </div>
    
          <div ui-card class="flex flex-col justify-between">
            <div ui-card-header class="flex flex-row items-start justify-between pb-2">
              <h3 ui-card-title class="text-muted-foreground text-xs font-medium tracking-widest uppercase">Attrition</h3>
              <span
                class="bg-success/10 text-success inline-flex items-center gap-1 rounded-full px-1.5 py-0.5 text-xs font-medium"
              >
                <lucide-icon [img]="TrendingDown" class="size-3" aria-hidden="true" />
                −0.8pt
              </span>
            </div>
            <div ui-card-content class="space-y-3">
              <p class="text-2xl font-semibold tracking-tight tabular-nums">7.6%</p>
              <ui-sparkline [data]="attrition" [height]="36" ariaLabel="Attrition trend" />
            </div>
          </div>
        </div>
      `,
    })
    export class UiDashboardKpisComponent {
      protected readonly TrendingUp = TrendingUp
      protected readonly TrendingDown = TrendingDown
      protected readonly headcount = headcount
      protected readonly openRoles = openRoles
      protected readonly timeToFill = timeToFill
      protected readonly attrition = attrition
    }
    
  • src/app/components/blocks/dashboard-kpis/index.ts0.1 kB

Raw manifest:https://uipkge.dev/r/angular/dashboard-kpis.json