Skip to content

Empty State

A user-friendly layout displayed when no data exists or a search yields no results, guiding users toward their next action.

Demo

Implementation

vue
<script setup lang="ts">
// 1. Component Imports (Default)
import CLIcon from '@codeandfunction/callaloo/CLIcon';
import CLHeading from '@codeandfunction/callaloo/CLHeading';
import CLText from '@codeandfunction/callaloo/CLText';
import CLButton from '@codeandfunction/callaloo/CLButton';

import { useToast } from '@codeandfunction/callaloo/composables/useToast';

// 2. Enum & Type Imports (Named)
import { 
  CLColors, 
  CLIconNames,
  CLIconSizes,
  CLHeadingLevels,
  CLAlign,
  CLButtonTypes
} from '@codeandfunction/callaloo';

// 3. State & Logic
const toast = useToast();

const handleAction = (): void => {
  toast.showToast({
    color: CLColors.Primary,
    message: 'Redirecting to creation form...',
    title: 'Action Triggered',
  });
};
</script>

<template>
  <div class="pattern-preview">
    <div class="empty-state-content">
      <div class="icon-wrapper">
        <CLIcon :name="CLIconNames.Folder" :size="CLIconSizes.XXXL" :color="CLColors.Neutral" />
      </div>
      <div class="text-group">
        <CLHeading :align="CLAlign.Center" :level="CLHeadingLevels.H3">No Projects Found</CLHeading>
        <CLText :color="CLColors.Neutral" :align="CLAlign.Center">
          You haven't created any projects yet. Start by creating your first project to organize your work.
        </CLText>
      </div>
      <CLButton 
        :color="CLColors.Primary" 
        :icon-before="CLIconNames.Plus"
        :type="CLButtonTypes.Button"
        @click="handleAction"
      >
        Create First Project
      </CLButton>
    </div>
  </div>
</template>

<style scoped>
  .pattern-preview {
    display: flex;
    justify-content: center;
    align-items: center;
    flex: 1;
  }
  .empty-state-content {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    max-width: 400px;
    gap: 1.5rem;
  }
  .icon-wrapper {
    display: flex;
    justify-content: center;
    align-items: center;
  }
  .text-group {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
  }
</style>

Released under the MIT License.