@ubay182/sveltekit-auto-shimmer
v0.1.0
Published
Sveltekit auto shimmer loading component
Maintainers
Readme
✨ Svelte Auto Shimmer
🚀 Auto-adapting shimmer loader untuk Svelte 5 yang otomatis menyesuaikan bentuk, ukuran, dan posisi dengan UI asli Anda. Tidak ada lagi skeleton manual yang tidak presisi!

✨ Fitur
- 🎯 Auto-Measurement: Shimmer otomatis mengukur dimensi elemen asli (teks, gambar, button, dll)
- 🧠 Smart Caching: Dimensi disimpan per
cacheKey, shimmer presis di load berikutnya - 🎨 Blueprint Skeleton: Berikan template HTML di snippet
skeletonuntuk first-load yang akurat - 📐 Padding & Border Aware: Mendukung padding, border, border-radius, dan box-shadow via props
- 🔄 Resize Observer: Auto-update saat konten berubah ukuran (responsive, flex-wrap, dll)
- 🌗 Framework Agnostic: Tidak tergantung Tailwind, Bootstrap, atau CSS framework apapun
- 🟢 SvelteKit Ready: SSR-safe, bekerja langsung di SvelteKit
- 📦 Zero CSS Import: Komponen sepenuhnya self-contained, tidak perlu import CSS terpisah
- 🛠️ TypeScript Ready: Full type definitions included
📦 Instalasi
# npm
npm install @ubay182/svelte-auto-shimmer
# yarn
yarn add @ubay182/svelte-auto-shimmer
# pnpm
pnpm add @ubay182/svelte-auto-shimmerBasic Usage
<script lang="ts">
import { Shimmer } from "@ubay182/svelte-auto-shimmer";
let loading = $state(true);
let data: { title: string; description: string } | null = $state(null);
</script>
<Shimmer {loading} cacheKey="my-card">
<!-- Konten Asli -->
{#snippet children()}
<div class="card">
<h2>{data?.title}</h2>
<p>{data?.description}</p>
</div>
{/snippet}
<!-- Blueprint Skeleton (untuk first load) -->
{#snippet skeleton()}
<div class="card">
<h2>Loading title...</h2>
<p>Loading description...</p>
</div>
{/snippet}
</Shimmer>Usage with SvelteKit
<script lang="ts">
import { onMount } from "svelte";
import { Shimmer } from "@ubay182/svelte-auto-shimmer";
let loading = $state(true);
let user: {
name: string;
bio: string;
avatar: string;
tags: string[];
} | null = $state(null);
const fetchData = () => {
loading = true;
const names = ["Ubaidillah Rahman", "Budi Santoso", "Siti Aminah"];
const randomName = names[Math.floor(Math.random() * names.length)];
setTimeout(() => {
user = {
name: randomName,
bio: "Fullstack Developer & Svelte Enthusiast.",
avatar: "https://placehold.co/100x100/e2e8f0/475569?text=UR",
tags: ["Svelte", "TypeScript", "UI/UX", "Frontend", "Backend", "DevOps"],
};
loading = false;
}, 5000);
};
onMount(() => fetchData());
</script>
<Shimmer
{loading}
cacheKey="user-profile"
border="1px solid #e5e7eb"
borderRadius="12px"
boxShadow="0 4px 12px rgba(0,0,0,0.05)"
bgColor="#ffffff"
padding="1.5rem"
>
<!-- KONTEN ASLI -->
{#snippet children()}
<div class="profile-content">
{#if user?.avatar}
<img src={user.avatar} alt={user.name} class="avatar" />
{/if}
<h2 class="title">{user?.name || "Loading Name..."}</h2>
<p class="bio">{user?.bio || "Loading bio..."}</p>
<!-- Tags Container dengan Flex Wrap -->
{#if user?.tags}
<div class="tags">
{#each user.tags as tag (tag)}
<span class="tag">{tag}</span>
{/each}
</div>
{/if}
<a href="/profile" class="btn action">View Profile</a>
</div>
{/snippet}
<!-- SKELETON BLUEPRINT -->
{#snippet skeleton()}
<div class="profile-content">
<div class="avatar-placeholder"></div>
<h2 class="title-placeholder"></h2>
<p class="bio-placeholder"></p>
<div class="tags">
<span class="tag-placeholder"></span>
<span class="tag-placeholder"></span>
<span class="tag-placeholder"></span>
<span class="tag-placeholder"></span>
<span class="tag-placeholder"></span>
<span class="tag-placeholder"></span>
</div>
<button class="btn action">View Profile</button>
</div>
{/snippet}
</Shimmer>📚 API Reference
| Prop | Tipe | Default | Deskripsi | | ------------ | ------- | ---------------------------- | --------------------------------------------------------------------------------- | | loading | boolean | false | Kontrol state loading (true = tampilkan shimmer) | | cacheKey | string | - | Unique key untuk caching dimensi. Wajib agar shimmer presis di refresh berikutnya | | border | string | '1px solid #e5e7eb' | CSS border untuk wrapper container | | borderRadius | string | '8px' | CSS border-radius untuk wrapper | | boxShadow | string | '0 2px 8px rgba(0,0,0,0.05)' | CSS box-shadow untuk wrapper | | bgColor | string | '#ffffff' | Background color wrapper | | padding | string | '1.5rem' | Padding internal wrapper (shimmer blocks diukur relatif terhadap area ini) |
Snippets
| Snippet | Deskripsi | | -------- | -------------------------------------------------------------------------------------------------------------- | | children | Konten asli yang akan ditampilkan saat loading=false | | skeleton | Blueprint HTML untuk first-load shimmer. Strukturnya sebaiknya mirip dengan konten asli agar pengukuran akurat |
🎨 Advanced Usage (Dynamic Content + API Fetch)
<script lang="ts">
import { onMount } from "svelte";
import { Shimmer } from "@ubay182/svelte-auto-shimmer";
let loading = $state(true);
let user: any = $state(null);
const fetchUser = async (id: number) => {
loading = true;
try {
const res = await fetch(`https://api.example.com/users/${id}`);
user = await res.json();
} finally {
loading = false;
}
};
onMount(() => fetchUser(123));
</script>
<Shimmer {loading} cacheKey="user-profile">
{#snippet children()}
<div class="profile">
<img src={user?.avatar} alt={user?.name} class="avatar" />
<h1>{user?.name}</h1>
<p>{user?.bio}</p>
</div>
{/snippet}
{#snippet skeleton()}
<div class="profile">
<div class="avatar-placeholder"></div>
<h1 class="name-placeholder"></h1>
<p class="bio-placeholder"></p>
</div>
{/snippet}
</Shimmer>Skip Elements
Gunakan data-shimmer-ignore untuk mengecualikan elemen tertentu dari shimmer:
<div>
<h2>Title</h2>
<p data-shimmer-ignore>Ini tidak akan jadi shimmer</p>
<button>Action</button>
</div>Skip Entire Section
<div data-shimmer-skip>
<!-- Konten ini tidak akan di-scan untuk shimmer -->
<StaticBanner />
</div>🛠️ Development
# Clone repo
git clone https://github.com/ubay1/svelte-auto-shimmer.git
cd svelte-auto-shimmer
# Install dependencies
npm install
# Run dev server
npm run dev
# Build library
npm run build
# Preview build output
npm run preview🤝 Contributing
Contributions welcome!
Silakan:
- Fork repo
- Buat branch fitur (
git checkout -b feat/amazing-feature) - Commit perubahan (
git commit -m 'Add amazing feature') - Push ke branch (
git push origin feat/amazing-feature) - Buka Pull Request
Pastikan:
- ✅ Code mengikuti style yang ada
- ✅ Tidak ada error TypeScript
- ✅ Playground masih berjalan normal
- ✅ Update README jika menambah fitur baru
📄 License
MIT License - see LICENSE file for details.
