Skip to content
Last update: June 24, 2025

Dashboard Widget Card Component

The DashboardWidgetCard component is a reusable UI element designed for displaying dashboard widgets in VC-Shell applications. It provides a consistent layout structure with a header, action buttons, and content area for widget data visualization.

The dashboard widget card serves as the container for individual widget content within draggable dashboard layouts. It provides a consistent styling and structure for dashboard widgets while allowing for customizable content through slots.

Component structure

<DashboardWidgetCard 
  header="Sales Overview" 
  icon="material-trending_up"
  :loading="isLoading"
>
  <!-- Widget content goes here -->
</DashboardWidgetCard>

API reference

Props

Prop Type Default Description
header string undefined The header text to display in the widget.
icon string undefined Optional icon name (Material Design) for the header.
loading boolean false If true, displays a loading indicator over the content area.

Slots

Slot Description
header Allows providing custom markup for the entire header section, replacing the default structure (icon + title text).
actions For placing interactive elements like buttons or menus in the top-right corner of the header.
content The main area for the widget's body content.

Styling

The component uses custom CSS variables for theming:

:root {
  --dashboard-widget-card-header-color: var(--additional-50);
  --dashboard-widget-card-header-text-color: var(--neutrals-950);
  --dashboard-widget-card-icon-color: var(--neutrals-950);
  --dashboard-widget-card-header-border-color: var(--neutrals-200);
}

Basic usage example

<template>
  <DashboardWidgetCard 
    header="Sales Overview" 
    icon="material-trending_up"
    :loading="isLoading"
  >
    <template #actions>
      <VcButton 
        icon="material-refresh" 
        size="sm" 
        variant="text" 
        @click="refreshData"
      />
      <VcButton 
        icon="material-more_vert" 
        size="sm" 
        variant="text" 
        @click="showMenu"
      />
    </template>

    <template #content>
      <div class="tw-p-6">
        <div class="tw-text-3xl tw-font-bold">{{ salesTotal }}</div>
        <div class="tw-flex tw-items-center tw-mt-2">
          <VcIcon 
            :icon="trendIcon" 
            :class="trendClass" 
            size="sm" 
          />
          <span :class="trendClass">{{ trendPercentage }}%</span>
        </div>
        <div class="tw-mt-4">
          <SalesChart :data="chartData" />
        </div>
      </div>
    </template>
  </DashboardWidgetCard>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue';
import { DashboardWidgetCard } from '@vc-shell/framework';
import { VcButton, VcIcon } from '@vc-shell/framework';
import SalesChart from './SalesChart.vue';

const isLoading = ref(false);
const salesTotal = ref('$15,892');
const trendPercentage = ref(12.5);

const trendIcon = computed(() => {
  return trendPercentage.value >= 0 
    ? 'material-trending_up' 
    : 'material-trending_down';
});

const trendClass = computed(() => {
  return trendPercentage.value >= 0 
    ? 'tw-text-[var(--success-500)]' 
    : 'tw-text-[var(--error-500)]';
});

const chartData = ref([42, 58, 65, 72, 81, 95, 102]);

async function refreshData() {
  isLoading.value = true;
  try {
    // Fetch updated data
    await new Promise(resolve => setTimeout(resolve, 1000));
    salesTotal.value = '$16,275';
    trendPercentage.value = 15.2;
    chartData.value = [45, 62, 70, 78, 85, 92, 110];
  } finally {
    isLoading.value = false;
  }
}

function showMenu() {
  // Show widget options menu
  console.log('Show widget menu');
}
</script>

Create custom widget with DashboardWidgetCard

When implementing custom widgets for a dashboard, the DashboardWidgetCard provides the outer container while you supply the specific visualization or content:

<!-- SalesWidget.vue -->
<template>
  <DashboardWidgetCard 
    header="Sales Data" 
    icon="material-analytics"
    :loading="loading"
  >
    <template #actions>
      <VcButton 
        icon="material-refresh" 
        size="sm" 
        variant="text" 
        @click="refreshData"
      />
    </template>

    <template #content>
      <div class="tw-p-6">
        <!-- Your specific sales widget content here -->
      </div>
    </template>
  </DashboardWidgetCard>
</template>

Usage with draggable dashboard

The DashboardWidgetCard component is designed to work with the DraggableDashboard component, but requires an additional step using useDashboard to register the widget:

import { useDashboard } from '@vc-shell/framework';
import SalesWidget from './SalesWidget.vue';

export function registerDashboardWidgets() {
  const dashboard = useDashboard();

  dashboard.registerWidget({
    id: 'sales-overview',
    name: 'Sales Overview',
    component: SalesWidget,
    size: { width: 2, height: 1 },
    position: { x: 0, y: 0 }
  });
}