Skip to content

Loader Component

A full-screen overlay component with a centered animated spinner for indicating loading states. The overlay prevents user interaction with underlying content while an async operation is in progress.


Table of Contents


Import

ts
import { Loader } from "dolphin-components";
import type { LoaderProps } from "dolphin-components";

Basic Usage

vue
<template>
  <button @click="loadData" class="btn btn-primary">Load Data</button>
  <Loader :show="isLoading" />
</template>

<script setup>
import { ref } from "vue";
import { Loader } from "dolphin-components";

const isLoading = ref(false);

const loadData = async () => {
  isLoading.value = true;
  // Simulate async operation
  await new Promise((resolve) => setTimeout(resolve, 2000));
  isLoading.value = false;
};
</script>

Props

PropTypeDefaultDescription
showbooleanfalseControls the visibility of the loader overlay.

Events

This component does not emit any events.

Slots

This component does not provide any slots.


TypeScript Interfaces

typescript
interface LoaderProps {
  show: boolean;
}

Usage Examples

With API Call

vue
<template>
  <Loader :show="isLoading" />

  <div v-if="data.length">
    <p>{{ data.length }} records loaded.</p>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from "vue";
import { Loader } from "dolphin-components";
import axios from "axios";

const isLoading = ref(false);
const data = ref([]);

onMounted(async () => {
  isLoading.value = true;
  try {
    const response = await axios.get("/api/records");
    data.value = response.data;
  } finally {
    isLoading.value = false;
  }
});
</script>

With Form Submission

vue
<template>
  <form @submit.prevent="submitForm">
    <input class="input-text" v-model="formData.name" placeholder="Name" />
    <button type="submit" class="btn btn-primary">Submit</button>
  </form>

  <Loader :show="isSubmitting" />
</template>

<script setup>
import { ref, reactive } from "vue";
import { Loader } from "dolphin-components";

const isSubmitting = ref(false);
const formData = reactive({ name: "" });

const submitForm = async () => {
  isSubmitting.value = true;
  await new Promise((resolve) => setTimeout(resolve, 1500));
  isSubmitting.value = false;
};
</script>

Visual Design

  • Full-screen overlay with a semi-transparent dark background
  • Centered animated spinner with a smooth rotation animation
  • High z-index (z-9999) ensures it appears above all other content
  • The overlay blocks all user interaction with underlying elements

Best Practices

  1. Use try/finally — Always wrap async operations with try/finally to ensure the loader is hidden even on errors.
  2. Keep loading times visible — Show the loader for a minimum perceivable duration (at least 200ms) to avoid flashing.
  3. Place near the root — Since the loader is full-screen with a fixed position, it can be placed anywhere in the template.
  4. One loader per page — Avoid multiple loader instances overlapping. Use a single reactive isLoading flag.

Troubleshooting

Loader stays visible

  • Ensure show is set back to false after the operation completes.
  • Check for unhandled promise rejections that might skip the isLoading = false assignment.
  • Use try/finally to guarantee cleanup.

Loader appears behind other elements

  • The loader uses z-index: 9999. If you have custom elements with a higher z-index, they may appear above the loader.