Menu

Change language

GitHub repo

Stats Band

blockmarketing

Interactive live telemetry and performance matrix band with multi-timeframe switching, real-time SLA verification, regional cluster drilldown, and JSON export.

Installation

$npx shadcn@latest add https://uipkge.dev/r/lit/stats-band.json
Manifest:https://uipkge.dev/r/lit/stats-band.jsonInstalls to:src/uip/blocks/stats-band/

Variants

Loading interactive previews…

Props

NameType / ValuesDefaultRequired
variant'plain' | 'bordered'borderedoptional

Schema

Type aliases exported from this item's source. Use these to shape the data you pass in.

MetricData
interface MetricData {
  id: string
  label: string
  subtitle: string
  values: Record<Timeframe, { main: string; change: string; isPositive: boolean; note: string }>
  icon: IconNode
  iconName: string
  breakdown: { region: string; val: string; status: string }[]
}
HTMLElementTagNameMap
interface HTMLElementTagNameMap {
    'uip-stats-band': UipStatsBand
  }
}

npm dependencies

Files installed (1)

  • src/uip/blocks/stats-band/stats-band.ts12.6 kB
    import { LitElement, css, html } from 'lit'
    import { Check, Clock, Copy, Globe, ShieldCheck, TrendingUp, Users, Zap, type IconNode } from 'lucide'
    import { cn } from '../../lib/utils'
    import { tailwind } from '../../lib/styles'
    import { ThemeController } from '../../lib/theme'
    import { icon } from '../../lib/icon'
    // Side-effect imports: register the composed elements for standalone use
    // (consumers who install only this block still get working primitives).
    import '../../components/badge/badge'
    import '../../components/button/button'
    
    type Timeframe = 'realtime' | '24h' | '7d' | '30d'
    
    interface MetricData {
      id: string
      label: string
      subtitle: string
      values: Record<Timeframe, { main: string; change: string; isPositive: boolean; note: string }>
      icon: IconNode
      iconName: string
      breakdown: { region: string; val: string; status: string }[]
    }
    
    // `iconName` beside each icon node: lucide nodes don't carry their kebab-case
    // name, which icon() needs for the lucide-<name> class.
    const stats: MetricData[] = [
      {
        id: 'uptime',
        label: 'Platform Availability',
        subtitle: 'Multi-region Active-Active SLA',
        icon: ShieldCheck,
        iconName: 'shield-check',
        values: {
          realtime: { main: '100.00%', change: '0 incident in 90d', isPositive: true, note: 'Zero degradation' },
          '24h': { main: '99.95%', change: '+0.001%', isPositive: true, note: '100% healthy' },
          '7d': { main: '99.995%', change: '+0.005%', isPositive: true, note: 'Target > 99.99%' },
          '30d': { main: '99.988%', change: '+0.02%', isPositive: true, note: 'Statutory SLA met' },
        },
        breakdown: [
          { region: 'us-east-1 (N. Virginia)', val: '100.0%', status: 'Operational' },
          { region: 'eu-west-1 (Frankfurt)', val: '100.0%', status: 'Operational' },
          { region: 'ap-southeast-1 (Singapore)', val: '100.0%', status: 'Operational' },
          { region: 'sa-east-1 (São Paulo)', val: '99.99%', status: 'Operational' },
        ],
      },
      {
        id: 'throughput',
        label: 'Component Installs & Pulls',
        subtitle: 'Daily registry resolutions',
        icon: Zap,
        iconName: 'zap',
        values: {
          realtime: { main: '1.42M', change: '+34.2k / hr', isPositive: true, note: 'Peak throughput' },
          '24h': { main: '3.89M', change: '+22.4% vs prev', isPositive: true, note: '320k unique repos' },
          '7d': { main: '26.4M', change: '+18.8%', isPositive: true, note: '1.4k new teams' },
          '30d': { main: '104.2M', change: '+41.0%', isPositive: true, note: 'Global scale' },
        },
        breakdown: [
          { region: 'Vue 3.5 / Nuxt 4 Core', val: '58.2%', status: 'Dominant' },
          { region: 'React 19 / Next.js Mirror', val: '41.8%', status: 'Growing' },
          { region: 'Direct CLI Installations', val: '88.4%', status: 'Automated' },
          { region: 'Manual Source Downloads', val: '11.6%', status: 'Direct' },
        ],
      },
      {
        id: 'latency',
        label: 'Global Edge P99 Latency',
        subtitle: 'Cloudflare Workers cache hits',
        icon: Clock,
        iconName: 'clock',
        values: {
          realtime: { main: '12ms', change: '-4ms reduction', isPositive: true, note: 'Global median: 8ms' },
          '24h': { main: '14ms', change: '-2ms vs baseline', isPositive: true, note: '99.9% cache hit' },
          '7d': { main: '16ms', change: '-12ms optimization', isPositive: true, note: 'Zero edge cold-starts' },
          '30d': { main: '18ms', change: '-24ms', isPositive: true, note: 'V4 pipeline rollout' },
        },
        breakdown: [
          { region: 'North America (Edge)', val: '9ms', status: 'Fastest' },
          { region: 'Europe (Edge)', val: '11ms', status: 'Optimal' },
          { region: 'Asia-Pacific (Edge)', val: '14ms', status: 'Optimal' },
          { region: 'Latin America (Edge)', val: '18ms', status: 'Optimal' },
        ],
      },
      {
        id: 'satisfaction',
        label: 'Enterprise Developer NPS',
        subtitle: 'Surveyed across 450+ companies',
        icon: Users,
        iconName: 'users',
        values: {
          realtime: { main: '+78', change: 'Top 1% dev tools', isPositive: true, note: 'Verified feedback' },
          '24h': { main: '4.94 / 5', change: '99.2% positive', isPositive: true, note: 'From 1,240 ratings' },
          '7d': { main: '+76', change: '+4 pts vs qtr', isPositive: true, note: '98% retention' },
          '30d': { main: '+74', change: '+12 pts YoY', isPositive: true, note: 'Industry benchmark' },
        },
        breakdown: [
          { region: 'Code Quality & Typing', val: '99.6%', status: '5 Stars' },
          { region: 'Zero-Lockin Ownership', val: '98.8%', status: '5 Stars' },
          { region: 'Visual Design Aesthetics', val: '99.2%', status: '5 Stars' },
          { region: 'Documentation & Demos', val: '97.4%', status: '4.9 Stars' },
        ],
      },
    ]
    
    const timeframes: { id: Timeframe; label: string }[] = [
      { id: 'realtime', label: 'Live P99' },
      { id: '24h', label: '24H' },
      { id: '7d', label: '7D' },
      { id: '30d', label: '30D' },
    ]
    
    /**
     * <uip-stats-band> — the registry StatsBand block as a web component.
     *
     * Class strings are React's StatsBand verbatim. React state (useState) becomes
     * @state fields. `variant` mirrors React's prop (default 'bordered').
     * NOTE: React's demo renders the "Plain" story with no variant, which falls
     * back to the same 'bordered' default — preserved here 1:1.
     */
    export class UipStatsBand extends LitElement {
      static shadowRootOptions = { ...LitElement.shadowRootOptions, delegatesFocus: true }
      // :host display can't be a utility class (the host has no template of its own).
      static styles = [tailwind, css`:host { display: block; }`]
    
      static properties = {
        variant: { reflect: true },
        selectedTimeframe: { state: true },
        activeStatIndex: { state: true },
        copied: { state: true },
      }
    
      variant: 'plain' | 'bordered' = 'bordered'
      private selectedTimeframe: Timeframe = 'realtime'
      private activeStatIndex: number | null = null
      private copied = false
      private timer?: number
    
      constructor() {
        super()
        new ThemeController(this)
      }
    
      connectedCallback() {
        super.connectedCallback()
        this.setAttribute('data-uipkge', '')
        this.setAttribute('data-slot', 'stats-band')
      }
    
      disconnectedCallback() {
        super.disconnectedCallback()
        if (this.timer) window.clearTimeout(this.timer)
      }
    
      private copyStatsPayload() {
        try {
          void navigator.clipboard?.writeText(JSON.stringify(stats, null, 2))
        } catch {
          // Clipboard unavailable (permissions, insecure context): still flash Copied.
        }
        this.copied = true
        if (this.timer) window.clearTimeout(this.timer)
        this.timer = window.setTimeout(() => {
          this.copied = false
        }, 2000)
      }
    
      render() {
        return html`
          <section
            data-slot="stats-band"
            class=${cn(
              'bg-card relative w-full overflow-hidden',
              this.variant === 'bordered' ? 'border-border rounded-2xl border shadow-xs' : '',
            )}
          >
            <div
              class="border-border bg-muted/20 flex flex-col justify-between gap-4 border-b px-6 py-4 sm:flex-row sm:items-center"
            >
              <div class="flex items-center gap-2.5">
                <div class="bg-success flex size-2.5 animate-pulse rounded-full"></div>
                <span class="text-foreground font-mono text-xs font-semibold tracking-wider uppercase">
                  Real-time Telemetry & Performance Matrix
                </span>
                <!-- Plain span carries the responsive class: display utilities
                     can't go on the uip-badge host (its :host display wins). -->
                <span class="hidden sm:contents">
                  <uip-badge
                    variant="outline"
                    class="border-success/20 bg-success/10 text-success text-success font-mono text-xs"
                  >
                    All Systems Operational
                  </uip-badge>
                </span>
              </div>
    
              <div class="flex items-center gap-2 self-end sm:self-auto">
                <div class="bg-background border-border flex items-center rounded-lg border p-0.5">
                  ${timeframes.map(
                    (tf) => html`<button
                      type="button"
                      class=${cn(
                        'rounded px-2.5 py-1 font-mono text-xs transition-colors',
                        this.selectedTimeframe === tf.id
                          ? 'bg-primary text-primary-foreground font-semibold shadow-xs'
                          : 'text-muted-foreground hover:text-foreground',
                      )}
                      @click=${() => {
                        this.selectedTimeframe = tf.id
                      }}
                    >
                      ${tf.label}
                    </button>`,
                  )}
                </div>
    
                <uip-button
                  variant="outline"
                  size="sm"
                  class="h-7 gap-1.5 px-2 font-mono text-xs"
                  @click=${this.copyStatsPayload}
                >
                  ${this.copied ? icon(Check, 'check', 'text-success size-3') : icon(Copy, 'copy', 'size-3')}
                  <span>${this.copied ? 'Copied' : 'JSON'}</span>
                </uip-button>
              </div>
            </div>
    
            <div class="divide-border grid grid-cols-1 divide-y sm:grid-cols-2 sm:divide-x sm:divide-y-0 lg:grid-cols-4">
              ${stats.map((item, idx) => {
                const isSelected = this.activeStatIndex === idx
                return html`
                  <div
                    class=${cn(
                      'hover:bg-muted/30 group relative cursor-pointer p-6 transition-colors',
                      isSelected ? 'bg-muted/40 ring-primary/30 ring-1 ring-inset' : '',
                    )}
                    @click=${() => {
                      this.activeStatIndex = isSelected ? null : idx
                    }}
                  >
                    <div class="flex items-start justify-between">
                      <p class="text-muted-foreground font-mono text-xs tracking-wider uppercase">${item.label}</p>
                      ${icon(item.icon, item.iconName, 'text-muted-foreground group-hover:text-primary size-4 transition-colors')}
                    </div>
    
                    <div class="mt-3 flex items-baseline gap-2">
                      <span class="text-foreground font-mono text-3xl font-bold tracking-tight">
                        ${item.values[this.selectedTimeframe].main}
                      </span>
                    </div>
    
                    <p class="text-muted-foreground mt-1 line-clamp-1 text-xs">${item.subtitle}</p>
    
                    <div class="border-border/60 mt-4 flex items-center justify-between border-t pt-3">
                      <span class="text-success inline-flex items-center gap-1 font-mono text-xs font-medium">
                        ${icon(TrendingUp, 'trending-up', 'size-3')} ${item.values[this.selectedTimeframe].change}
                      </span>
                      <span class="text-muted-foreground font-mono text-xs">${item.values[this.selectedTimeframe].note}</span>
                    </div>
                  </div>
                `
              })}
            </div>
    
            ${this.activeStatIndex !== null
              ? html`
                  <div class="bg-muted/20 border-border space-y-4 border-t p-6">
                    <div class="flex items-center justify-between">
                      <div class="flex items-center gap-2">
                        ${icon(Globe, 'globe', 'text-primary size-4')}
                        <span class="text-foreground text-xs font-semibold">
                          Regional Telemetry & Infrastructure Breakdown: ${stats[this.activeStatIndex].label}
                        </span>
                      </div>
                      <uip-button
                        variant="ghost"
                        size="sm"
                        class="h-6 text-xs"
                        @click=${() => {
                          this.activeStatIndex = null
                        }}
                      >
                        Close Breakdown
                      </uip-button>
                    </div>
    
                    <div class="grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4">
                      ${stats[this.activeStatIndex].breakdown.map(
                        (sub) => html`
                          <div
                            class="border-border bg-background flex items-center justify-between rounded-lg border p-3 shadow-xs"
                          >
                            <div>
                              <p class="text-foreground text-xs font-medium">${sub.region}</p>
                              <p class="text-muted-foreground mt-0.5 font-mono text-xs">${sub.status}</p>
                            </div>
                            <span class="text-success font-mono text-xs font-bold">${sub.val}</span>
                          </div>
                        `,
                      )}
                    </div>
                  </div>
                `
              : ''}
          </section>
        `
      }
    }
    
    customElements.get('uip-stats-band') || customElements.define('uip-stats-band', UipStatsBand)
    
    declare global {
      interface HTMLElementTagNameMap {
        'uip-stats-band': UipStatsBand
      }
    }
    

Raw manifest:https://uipkge.dev/r/lit/stats-band.json