veilkit 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +48 -0
- package/README.md +768 -99
- package/assets/demo-button.gif +0 -0
- package/assets/demo-hero.gif +0 -0
- package/assets/demo-presets.gif +0 -0
- package/assets/demo-spinners.gif +0 -0
- package/dist/angular/index.cjs +280 -14
- package/dist/angular/index.cjs.map +1 -1
- package/dist/angular/index.d.cts +39 -4
- package/dist/angular/index.d.ts +39 -4
- package/dist/angular/index.js +280 -14
- package/dist/angular/index.js.map +1 -1
- package/dist/{controller-Co5bvnaB.d.ts → controller-Cmc3Hp1j.d.ts} +5 -3
- package/dist/{controller-5OzP0U8X.d.cts → controller-CzNTbEGd.d.cts} +5 -3
- package/dist/element/index.cjs +285 -20
- package/dist/element/index.cjs.map +1 -1
- package/dist/element/index.d.cts +7 -1
- package/dist/element/index.d.ts +7 -1
- package/dist/element/index.js +285 -20
- package/dist/element/index.js.map +1 -1
- package/dist/index.cjs +288 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +36 -11
- package/dist/index.d.ts +36 -11
- package/dist/index.js +288 -14
- package/dist/index.js.map +1 -1
- package/dist/native/index.cjs +1 -1
- package/dist/native/index.cjs.map +1 -1
- package/dist/native/index.d.cts +10 -4
- package/dist/native/index.d.ts +10 -4
- package/dist/native/index.js +1 -1
- package/dist/native/index.js.map +1 -1
- package/dist/react/index.cjs +280 -14
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +38 -4
- package/dist/react/index.d.ts +38 -4
- package/dist/react/index.js +280 -14
- package/dist/react/index.js.map +1 -1
- package/dist/styles.css +133 -1
- package/dist/svelte/index.cjs +286 -20
- package/dist/svelte/index.cjs.map +1 -1
- package/dist/svelte/index.d.cts +9 -2
- package/dist/svelte/index.d.ts +9 -2
- package/dist/svelte/index.js +286 -20
- package/dist/svelte/index.js.map +1 -1
- package/dist/themes/index.d.cts +1 -1
- package/dist/themes/index.d.ts +1 -1
- package/dist/{types-Ciu5e5xt.d.cts → types-D2ryMkLU.d.cts} +45 -5
- package/dist/{types-Ciu5e5xt.d.ts → types-D2ryMkLU.d.ts} +45 -5
- package/dist/veilkit.min.js +288 -14
- package/dist/vue/index.cjs +270 -4
- package/dist/vue/index.cjs.map +1 -1
- package/dist/vue/index.d.cts +148 -2
- package/dist/vue/index.d.ts +148 -2
- package/dist/vue/index.js +270 -4
- package/dist/vue/index.js.map +1 -1
- package/package.json +41 -24
package/README.md
CHANGED
|
@@ -4,44 +4,121 @@
|
|
|
4
4
|
|
|
5
5
|
**Every loading state, beautifully. One package, every framework.**
|
|
6
6
|
|
|
7
|
-
[](https://www.npmjs.com/package/veilkit)
|
|
8
|
+
[](https://www.npmjs.com/package/veilkit)
|
|
9
|
+
[](https://bundlephobia.com/package/veilkit)
|
|
10
|
+
[](https://www.npmjs.com/package/veilkit)
|
|
11
|
+
[](https://veilkit.tashanto.com)
|
|
12
|
+
[](https://github.com/iamtashanto/veilkit)
|
|
13
|
+
[](https://opensource.org/licenses/MIT)
|
|
14
|
+
|
|
15
|
+
A production-grade, zero-dependency loading & skeleton UI toolkit built for the modern web and mobile ecosystem.
|
|
13
16
|
Pure GPU-accelerated motion (`transform` & `opacity`), synchronized timeline clocks, anti-flicker timing,
|
|
14
|
-
auto-measure DOM wrapping,
|
|
17
|
+
auto-measure DOM wrapping, 45 responsive presets, custom skeleton builder, 30 spinners, 30 GPU animations, 16 loading button styles, 5 shape styles, route progress, and frosted glass themes.
|
|
18
|
+
|
|
19
|
+
[**Live Interactive Playground & Documentation → https://veilkit.tashanto.com**](https://veilkit.tashanto.com)
|
|
20
|
+
|
|
21
|
+
<br />
|
|
15
22
|
|
|
16
|
-
|
|
23
|
+
<p align="center">
|
|
24
|
+
<a href="https://veilkit.tashanto.com">
|
|
25
|
+
<img src="https://raw.githubusercontent.com/iamtashanto/veilkit/main/assets/demo-hero.gif" alt="Veilkit Loading and Skeleton Demo" width="860" style="max-width: 100%; border-radius: 12px; box-shadow: 0 20px 50px rgba(0, 0, 0, 0.4);" />
|
|
26
|
+
</a>
|
|
27
|
+
</p>
|
|
17
28
|
|
|
18
29
|
</div>
|
|
19
30
|
|
|
20
31
|
---
|
|
21
32
|
|
|
33
|
+
## 📑 Table of Contents
|
|
34
|
+
|
|
35
|
+
- [Why Veilkit?](#-why-veilkit)
|
|
36
|
+
- [Key Features](#-key-features)
|
|
37
|
+
- [Package Architecture](#-package-architecture)
|
|
38
|
+
- [Installation](#-installation)
|
|
39
|
+
- [Framework Quickstarts](#-framework-quickstarts)
|
|
40
|
+
- [React & Next.js](#1-react--nextjs-veilkitreact)
|
|
41
|
+
- [Vue 3 & Nuxt 3](#2-vue-3--nuxt-3-veilkitvue)
|
|
42
|
+
- [Svelte 4/5 & SvelteKit](#3-svelte-45--sveltekit-veilkitsvelte)
|
|
43
|
+
- [Angular (17, 18, 19)](#4-angular-standalone-veilkitangular)
|
|
44
|
+
- [Web Components (Solid, Qwik, HTMX, HTML)](#5-web-components-veilkitelement)
|
|
45
|
+
- [React Native & Expo](#6-react-native--expo-veilkitnative)
|
|
46
|
+
- [Electron Desktop](#7-electron-desktop)
|
|
47
|
+
- [Vanilla JS & CDN](#8-vanilla-javascript--cdn)
|
|
48
|
+
- [45 Ready-Made Presets (5 Shape Styles)](#-45-ready-made-presets)
|
|
49
|
+
- [Custom Skeleton Layout Builder (Fluent API & JSON Engine)](#-custom-skeleton-layout-builder)
|
|
50
|
+
- [30 GPU-Accelerated Animations](#-30-gpu-accelerated-animations)
|
|
51
|
+
- [11 Built-in Themes & Custom Factory](#-11-built-in-themes--custom-theming)
|
|
52
|
+
- [30 Spinner Loaders](#-30-spinner-loaders)
|
|
53
|
+
- [Loading Button & State Machine (16 Styles)](#-loading-button--state-machine)
|
|
54
|
+
- [Auto-Measure & Reveal Engine](#-auto-measure--reveal-engine)
|
|
55
|
+
- [Anti-Flicker Timing Controller](#-anti-flicker-timing-controller)
|
|
56
|
+
- [Global Loading Manager & Tracker](#-global-loading-manager--request-tracking)
|
|
57
|
+
- [Accessibility (a11y) & Localization](#-accessibility-a11y--localization)
|
|
58
|
+
- [Veilkit CLI (`capture`)](#-veilkit-cli-capture)
|
|
59
|
+
- [GitHub Actions & npm Provenance](#-github-actions--npm-provenance)
|
|
60
|
+
- [Author & License](#-author--license)
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## 💡 Why Veilkit?
|
|
65
|
+
|
|
66
|
+
Most skeleton libraries suffer from several critical shortcomings:
|
|
67
|
+
1. **Layout Thrashing**: Animating background positions, widths, or margins forces constant layout recalculations and battery drain.
|
|
68
|
+
2. **Phase Jitter**: Shimmers that mount at different seconds animate out of sync, making pages look chaotic and disjointed.
|
|
69
|
+
3. **Flicker**: Fast API calls (under 100ms) briefly flash a skeleton before immediately rendering content, causing visual jarring.
|
|
70
|
+
4. **Framework Fragmentation**: Separate incompatible packages for React, Vue, Svelte, Angular, and React Native.
|
|
71
|
+
|
|
72
|
+
| Feature | Veilkit | react-loading-skeleton | react-content-loader | nprogress |
|
|
73
|
+
| :--- | :---: | :---: | :---: | :---: |
|
|
74
|
+
| **Zero Runtime Dependencies** | ✅ Yes | ❌ No | ❌ No | ✅ Yes |
|
|
75
|
+
| **Universal Platform Support** | ✅ React, Vue, Svelte, Angular, Native, Web Components | ❌ React only | ❌ React/React Native only | ❌ Vanilla only |
|
|
76
|
+
| **GPU Compositor Only (`transform`/`opacity`)**| ✅ 60 FPS | ❌ Background-position | ❌ SVG clipPath | ❌ CSS width |
|
|
77
|
+
| **Synchronized Global Phase Clocks** | ✅ Yes (zero jitter) | ❌ No | ❌ No | ❌ N/A |
|
|
78
|
+
| **Built-in Anti-Flicker (`delay`/`minVisible`)** | ✅ Built-in | ❌ Manual | ❌ Manual | ❌ No |
|
|
79
|
+
| **Auto-Measure DOM Tree Wrapping** | ✅ Built-in | ❌ No | ❌ No | ❌ N/A |
|
|
80
|
+
| **12 Spinners & Route Progress Included** | ✅ All-in-one | ❌ Skeletons only | ❌ SVG only | ❌ Progress only |
|
|
81
|
+
| **11 Design Themes (Glass, iOS, Neon, etc.)** | ✅ Built-in | ❌ Light/Dark only | ❌ Custom SVG | ❌ None |
|
|
82
|
+
| **Full TypeScript & Dual ESM/CJS Exports** | ✅ 100% | ⚠️ Limited | ⚠️ Limited | ❌ No DTS |
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
22
86
|
## ⚡️ Key Features
|
|
23
87
|
|
|
24
|
-
- **Zero Runtime Dependencies**: The core package has 0 dependencies.
|
|
25
|
-
- **Synchronized Global Timeline**: All
|
|
26
|
-
- **Zero Layout Thrashing**: Animations strictly use `transform` and `opacity`
|
|
27
|
-
- **
|
|
28
|
-
- **11
|
|
29
|
-
- **
|
|
30
|
-
- **
|
|
31
|
-
- **
|
|
32
|
-
- **
|
|
33
|
-
- **
|
|
34
|
-
- React & Next.js (`veilkit/react`)
|
|
35
|
-
- Vue 3 & Nuxt (`veilkit/vue`)
|
|
36
|
-
- Svelte 4/5 & SvelteKit (`veilkit/svelte`)
|
|
37
|
-
- Angular Standalone (`veilkit/angular`)
|
|
38
|
-
- Web Components (`veilkit/element`) for Solid, Qwik, HTMX, Astro, Blade, HTML
|
|
39
|
-
- React Native & Expo (`veilkit/native`)
|
|
40
|
-
- Electron & Desktop
|
|
88
|
+
- **Zero Runtime Dependencies**: The core package has 0 dependencies. All framework libraries are declared as optional peer dependencies.
|
|
89
|
+
- **Synchronized Global Timeline**: All shimmers across the page share a synced clock phase via negative CSS `animation-delay` offsets calculated from `performance.now() % duration`.
|
|
90
|
+
- **Zero Layout Thrashing**: Animations strictly use `transform` and `opacity` on the GPU compositor thread. Offscreen elements and hidden background tabs automatically pause execution via `IntersectionObserver` and `visibilitychange`.
|
|
91
|
+
- **30 GPU Animations**: `shimmer`, `wave`, `pulse`, `blink`, `breathe`, `glass-shine`, `gradient-flow`, `aurora`, `scan-line`, `sparkle`, `neon-glow`, `stagger`, `ripple`, `ping-pong`, `wipe`, `cascade`, `spotlight`, `rainbow`, `heartbeat`, `liquid`, `stripes`, `halftone`, `border-glow`, `typewriter`, `glitch`, `pixelate`, `tilt`, `diagonal-sweep`, `bounce-in`, `fade-slide`.
|
|
92
|
+
- **11 Themes**: `light`, `dark`, `auto`, `glass`, `ios`, `material`, `minimal`, `mono`, `neon`, `sunset`, `ocean`, plus `createTheme()` for brand palettes.
|
|
93
|
+
- **40 Canonical Presets**: Ready-made layouts with 5 shape styles (`rounded`, `pill`, `square`, `sharp`, `glass`).
|
|
94
|
+
- **30 Spinner Loaders**: Ultra-smooth CSS/SVG spinners with customizable size, color, speed, and glass variants.
|
|
95
|
+
- **Loading Button Machine**: 16 loading styles, auto-managed promise state machine (`idle → loading → success | error → idle`), result animations (`checkmark`, `cross`, `shake`, `success-burst`), press ripple/scale feedback, and native haptics.
|
|
96
|
+
- **Auto-Measure Engine**: Wrap real markup with `<Veil loading>` or `v-veil="loading"` to measure layout leaf elements with zero hydration mismatches.
|
|
97
|
+
- **Top Route Progress**: NProgress-style route loader with auto-trickle and error fallbacks.
|
|
41
98
|
|
|
42
99
|
---
|
|
43
100
|
|
|
44
|
-
## 📦
|
|
101
|
+
## 📦 Package Architecture
|
|
102
|
+
|
|
103
|
+
Veilkit is authored with pure TypeScript strict mode, bundled with `tsup`, and provides comprehensive subpath exports:
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
veilkit
|
|
107
|
+
├── veilkit # Core vanilla JS/TS runtime engine
|
|
108
|
+
├── veilkit/styles.css # Standalone static CSS bundle
|
|
109
|
+
├── veilkit/react # React 18/19 & Next.js client/server components & hooks
|
|
110
|
+
├── veilkit/vue # Vue 3 & Nuxt 3 components, composables, & directive
|
|
111
|
+
├── veilkit/svelte # Svelte 4/5 & SvelteKit runes & actions
|
|
112
|
+
├── veilkit/angular # Angular 17+ standalone components, directives & service
|
|
113
|
+
├── veilkit/element # Universal Web Components (<veil-skeleton>, etc.)
|
|
114
|
+
├── veilkit/native # React Native & Expo (Expo Go compatible)
|
|
115
|
+
├── veilkit/themes # Theme token definitions & createTheme()
|
|
116
|
+
└── dist/veilkit.min.js # Standalone UMD/IIFE bundle (global Veilkit)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## 🚀 Installation
|
|
45
122
|
|
|
46
123
|
```bash
|
|
47
124
|
# npm
|
|
@@ -52,171 +129,528 @@ pnpm add veilkit
|
|
|
52
129
|
|
|
53
130
|
# yarn
|
|
54
131
|
yarn add veilkit
|
|
132
|
+
|
|
133
|
+
# bun
|
|
134
|
+
bun add veilkit
|
|
55
135
|
```
|
|
56
136
|
|
|
57
137
|
---
|
|
58
138
|
|
|
59
|
-
##
|
|
139
|
+
## 💻 Framework Quickstarts
|
|
60
140
|
|
|
61
141
|
### 1. React & Next.js (`veilkit/react`)
|
|
62
142
|
|
|
143
|
+
Compatible with React 18 and 19, Next.js App Router, Pages Router, Server Components, and Suspense.
|
|
144
|
+
|
|
63
145
|
```tsx
|
|
64
146
|
import 'veilkit/styles.css';
|
|
65
|
-
import {
|
|
66
|
-
|
|
67
|
-
|
|
147
|
+
import { useState } from 'react';
|
|
148
|
+
import {
|
|
149
|
+
Skeleton,
|
|
150
|
+
SkeletonPreset,
|
|
151
|
+
Veil,
|
|
152
|
+
Spinner,
|
|
153
|
+
ProgressBar,
|
|
154
|
+
RouteProgress,
|
|
155
|
+
LoadingButton,
|
|
156
|
+
useLoading,
|
|
157
|
+
} from 'veilkit/react';
|
|
158
|
+
|
|
159
|
+
export default function UserDashboard() {
|
|
68
160
|
const [loading, setLoading] = useState(true);
|
|
69
161
|
|
|
70
162
|
return (
|
|
71
|
-
|
|
163
|
+
<div>
|
|
164
|
+
{/* Route progress bar for App and Pages router */}
|
|
165
|
+
<RouteProgress color="#38bdf8" />
|
|
166
|
+
|
|
72
167
|
{/* Ready-made card preset */}
|
|
73
168
|
<SkeletonPreset name="product-card" animation="shimmer" theme="glass" />
|
|
74
169
|
|
|
75
|
-
{/* Auto-measure wrapper
|
|
76
|
-
|
|
77
|
-
|
|
170
|
+
{/* Auto-measure wrapper: Renders identical markup on server/client.
|
|
171
|
+
Measures leaf nodes only after mount to prevent hydration errors. */}
|
|
172
|
+
<Veil loading={loading} reveal="fade" cacheKey="user-profile">
|
|
173
|
+
<div className="profile-card">
|
|
174
|
+
<img src="/avatar.jpg" alt="Avatar" />
|
|
175
|
+
<h2>Jane Doe</h2>
|
|
176
|
+
<p>Senior Staff UI Systems Architect</p>
|
|
177
|
+
<button>Connect</button>
|
|
178
|
+
</div>
|
|
78
179
|
</Veil>
|
|
79
180
|
|
|
80
|
-
{/* Inline Loading Button */}
|
|
81
|
-
<LoadingButton
|
|
181
|
+
{/* Inline Loading Button (preserves exact dimensions, prevents layout jumps) */}
|
|
182
|
+
<LoadingButton
|
|
183
|
+
loading={loading}
|
|
184
|
+
loadingText="Saving profile…"
|
|
185
|
+
onClick={() => setLoading(!loading)}
|
|
186
|
+
>
|
|
82
187
|
Save Changes
|
|
83
188
|
</LoadingButton>
|
|
84
|
-
|
|
189
|
+
|
|
190
|
+
{/* 12 GPU Spinners */}
|
|
191
|
+
<Spinner type="ios-activity" size={28} />
|
|
192
|
+
<Spinner type="glass-orb" size={32} />
|
|
193
|
+
</div>
|
|
85
194
|
);
|
|
86
195
|
}
|
|
87
196
|
```
|
|
88
197
|
|
|
89
|
-
|
|
198
|
+
#### Next.js App Router `loading.tsx` Example:
|
|
199
|
+
```tsx
|
|
200
|
+
// app/dashboard/loading.tsx
|
|
201
|
+
import { SkeletonPreset } from 'veilkit/react';
|
|
202
|
+
|
|
203
|
+
export default function Loading() {
|
|
204
|
+
return <SkeletonPreset name="dashboard" animation="aurora" theme="glass" />;
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
### 2. Vue 3 & Nuxt 3 (`veilkit/vue`)
|
|
90
211
|
|
|
91
212
|
```vue
|
|
92
|
-
<script setup>
|
|
213
|
+
<script setup lang="ts">
|
|
93
214
|
import 'veilkit/styles.css';
|
|
94
215
|
import { ref } from 'vue';
|
|
95
|
-
import {
|
|
216
|
+
import {
|
|
217
|
+
VSkeleton,
|
|
218
|
+
VSpinner,
|
|
219
|
+
VProgressBar,
|
|
220
|
+
VLoadingButton,
|
|
221
|
+
useProgress,
|
|
222
|
+
} from 'veilkit/vue';
|
|
96
223
|
|
|
97
224
|
const loading = ref(true);
|
|
225
|
+
const progress = useProgress();
|
|
98
226
|
</script>
|
|
99
227
|
|
|
100
228
|
<template>
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
229
|
+
<main>
|
|
230
|
+
<button @click="progress.start()">Simulate Navigation</button>
|
|
231
|
+
|
|
232
|
+
<!-- Auto-measure directive -->
|
|
233
|
+
<div v-veil="loading" class="card">
|
|
234
|
+
<h2>Vue 3 Dashboard</h2>
|
|
235
|
+
<p>Automatic DOM leaf measurement with ResizeObserver reflow.</p>
|
|
236
|
+
<button>Action</button>
|
|
237
|
+
</div>
|
|
238
|
+
|
|
239
|
+
<!-- Primitive Skeletons -->
|
|
240
|
+
<VSkeleton circle width="52px" height="52px" animation="wave" theme="ios" />
|
|
241
|
+
<VSkeleton type="heading" width="60%" height="28px" animation="shimmer" />
|
|
242
|
+
|
|
243
|
+
<!-- Spinners -->
|
|
244
|
+
<VSpinner type="orbit" size="32px" color="#38bdf8" />
|
|
245
|
+
</main>
|
|
109
246
|
</template>
|
|
110
247
|
```
|
|
111
248
|
|
|
112
|
-
|
|
249
|
+
#### Registering Vue Plugin globally:
|
|
250
|
+
```ts
|
|
251
|
+
// main.ts
|
|
252
|
+
import { createApp } from 'vue';
|
|
253
|
+
import App from './App.vue';
|
|
254
|
+
import veilkitPlugin from 'veilkit/vue';
|
|
255
|
+
import 'veilkit/styles.css';
|
|
256
|
+
|
|
257
|
+
const app = createApp(App);
|
|
258
|
+
app.use(veilkitPlugin, {
|
|
259
|
+
theme: 'glass',
|
|
260
|
+
animation: 'shimmer',
|
|
261
|
+
});
|
|
262
|
+
app.mount('#app');
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
### 3. Svelte 4/5 & SvelteKit (`veilkit/svelte`)
|
|
268
|
+
|
|
269
|
+
Runes-friendly, SSR-safe, with actions and SvelteKit route navigation hooks.
|
|
113
270
|
|
|
114
271
|
```svelte
|
|
115
|
-
<script>
|
|
272
|
+
<script lang="ts">
|
|
116
273
|
import 'veilkit/styles.css';
|
|
117
|
-
import { veil } from 'veilkit/svelte';
|
|
274
|
+
import { veil, skeletonAction, spinnerAction } from 'veilkit/svelte';
|
|
118
275
|
|
|
119
276
|
export let loading = true;
|
|
120
277
|
</script>
|
|
121
278
|
|
|
122
279
|
<!-- Auto-measure action -->
|
|
123
|
-
<div use:veil={{ loading, reveal: 'fade' }}>
|
|
280
|
+
<div use:veil={{ loading, reveal: 'fade', cacheKey: 'article-view' }}>
|
|
124
281
|
<article>
|
|
125
|
-
<h1>
|
|
126
|
-
<p>
|
|
282
|
+
<h1>Svelte 5 Runes Article</h1>
|
|
283
|
+
<p>High-performance loading skeletons with zero runtime dependencies.</p>
|
|
127
284
|
</article>
|
|
128
285
|
</div>
|
|
286
|
+
|
|
287
|
+
<!-- Svelte element actions -->
|
|
288
|
+
<div use:skeletonAction={{ width: '240px', height: '24px', animation: 'aurora' }}></div>
|
|
289
|
+
<div use:spinnerAction={{ type: 'pulse', size: 36 }}></div>
|
|
129
290
|
```
|
|
130
291
|
|
|
292
|
+
#### SvelteKit Route Progress (`+layout.svelte`):
|
|
293
|
+
```svelte
|
|
294
|
+
<script lang="ts">
|
|
295
|
+
import 'veilkit/styles.css';
|
|
296
|
+
import { setupSvelteKitProgress } from 'veilkit/svelte';
|
|
297
|
+
import { beforeNavigate, afterNavigate } from '$app/navigation';
|
|
298
|
+
|
|
299
|
+
setupSvelteKitProgress(beforeNavigate, afterNavigate);
|
|
300
|
+
</script>
|
|
301
|
+
|
|
302
|
+
<slot />
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
131
307
|
### 4. Angular Standalone (`veilkit/angular`)
|
|
132
308
|
|
|
309
|
+
Works with Angular 17, 18, and 19 (both zoneless and with zone.js), signals, and HTTP interceptors.
|
|
310
|
+
|
|
133
311
|
```typescript
|
|
134
312
|
import { Component } from '@angular/core';
|
|
135
|
-
import {
|
|
313
|
+
import {
|
|
314
|
+
VeilDirective,
|
|
315
|
+
VeilSkeletonComponent,
|
|
316
|
+
VeilSpinnerComponent,
|
|
317
|
+
VeilProgressBarComponent,
|
|
318
|
+
VeilService,
|
|
319
|
+
} from 'veilkit/angular';
|
|
136
320
|
import 'veilkit/styles.css';
|
|
137
321
|
|
|
138
322
|
@Component({
|
|
323
|
+
selector: 'app-root',
|
|
139
324
|
standalone: true,
|
|
140
|
-
imports: [
|
|
325
|
+
imports: [
|
|
326
|
+
VeilDirective,
|
|
327
|
+
VeilSkeletonComponent,
|
|
328
|
+
VeilSpinnerComponent,
|
|
329
|
+
VeilProgressBarComponent,
|
|
330
|
+
],
|
|
141
331
|
template: `
|
|
332
|
+
<!-- Structural / Attribute Directive -->
|
|
142
333
|
<div [veil]="loading">
|
|
143
|
-
<h2>
|
|
334
|
+
<h2>Angular Signals Workspace</h2>
|
|
335
|
+
<p>Data loaded over HTTP client.</p>
|
|
144
336
|
</div>
|
|
145
|
-
|
|
146
|
-
|
|
337
|
+
|
|
338
|
+
<!-- Standalone Components -->
|
|
339
|
+
<veil-skeleton type="heading" width="220px" animation="glass-shine" theme="glass"></veil-skeleton>
|
|
340
|
+
<veil-spinner type="ios-activity" size="32px"></veil-spinner>
|
|
147
341
|
`,
|
|
148
342
|
})
|
|
149
343
|
export class AppComponent {
|
|
150
344
|
loading = true;
|
|
345
|
+
constructor(public veil: VeilService) {}
|
|
151
346
|
}
|
|
152
347
|
```
|
|
153
348
|
|
|
154
|
-
|
|
349
|
+
#### Angular Functional HTTP Interceptor:
|
|
350
|
+
```typescript
|
|
351
|
+
// app.config.ts
|
|
352
|
+
import { ApplicationConfig } from '@angular/core';
|
|
353
|
+
import { provideHttpClient, withInterceptors } from '@angular/common/http';
|
|
354
|
+
import { veilHttpInterceptor } from 'veilkit/angular';
|
|
355
|
+
|
|
356
|
+
export const appConfig: ApplicationConfig = {
|
|
357
|
+
providers: [
|
|
358
|
+
provideHttpClient(withInterceptors([veilHttpInterceptor])),
|
|
359
|
+
],
|
|
360
|
+
};
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
---
|
|
364
|
+
|
|
365
|
+
### 5. Web Components (`veilkit/element`)
|
|
366
|
+
|
|
367
|
+
Universal custom elements with zero wrappers for Solid, Qwik, HTMX, Astro, Laravel/Blade, WordPress, and static HTML:
|
|
155
368
|
|
|
156
369
|
```html
|
|
157
370
|
<link rel="stylesheet" href="https://unpkg.com/veilkit/dist/styles.css" />
|
|
158
371
|
<script type="module" src="https://unpkg.com/veilkit/dist/element/index.js"></script>
|
|
159
372
|
|
|
160
|
-
<!-- Custom Elements -->
|
|
161
|
-
<veil-skeleton type="circle" width="
|
|
162
|
-
<veil-skeleton type="heading" width="
|
|
163
|
-
<veil-
|
|
373
|
+
<!-- Native Custom Elements -->
|
|
374
|
+
<veil-skeleton type="circle" width="56px" height="56px" animation="wave"></veil-skeleton>
|
|
375
|
+
<veil-skeleton type="heading" width="240px" height="24px" animation="aurora"></veil-skeleton>
|
|
376
|
+
<veil-skeleton lines="3" width="100%"></veil-skeleton>
|
|
377
|
+
<veil-spinner type="morph" size="32px" color="#38bdf8"></veil-spinner>
|
|
378
|
+
<veil-progress value="68" circular="true" show-percentage="true"></veil-progress>
|
|
164
379
|
```
|
|
165
380
|
|
|
381
|
+
---
|
|
382
|
+
|
|
166
383
|
### 6. React Native & Expo (`veilkit/native`)
|
|
167
384
|
|
|
385
|
+
Runs in Expo Go, supports New Architecture, iOS, Android, and `react-native-web`.
|
|
386
|
+
Automatically detects `expo-linear-gradient` / `react-native-linear-gradient` and falls back gracefully to a native driver opacity pulse if missing.
|
|
387
|
+
|
|
168
388
|
```tsx
|
|
169
|
-
import {
|
|
389
|
+
import {
|
|
390
|
+
Skeleton,
|
|
391
|
+
SkeletonGroup,
|
|
392
|
+
Spinner,
|
|
393
|
+
LoadingButton,
|
|
394
|
+
ProgressBar,
|
|
395
|
+
Overlay,
|
|
396
|
+
} from 'veilkit/native';
|
|
170
397
|
|
|
171
398
|
export default function MobileCard() {
|
|
399
|
+
const [loading, setLoading] = useState(false);
|
|
400
|
+
|
|
172
401
|
return (
|
|
173
402
|
<SkeletonGroup>
|
|
174
|
-
|
|
175
|
-
<Skeleton height={
|
|
176
|
-
|
|
403
|
+
{/* Rectangular image placeholder */}
|
|
404
|
+
<Skeleton height={180} radius={12} theme="auto" animation="shimmer" />
|
|
405
|
+
|
|
406
|
+
{/* Avatar circle */}
|
|
407
|
+
<Skeleton circle width={44} height={44} style={{ marginTop: 12 }} />
|
|
408
|
+
|
|
409
|
+
{/* Text lines */}
|
|
410
|
+
<Skeleton height={20} width="75%" radius={4} style={{ marginTop: 8 }} />
|
|
411
|
+
<Skeleton height={14} width="50%" radius={4} style={{ marginTop: 6 }} />
|
|
412
|
+
|
|
413
|
+
{/* Button */}
|
|
414
|
+
<LoadingButton
|
|
415
|
+
loading={loading}
|
|
416
|
+
title="Sync Database"
|
|
417
|
+
onPress={() => setLoading(!loading)}
|
|
418
|
+
/>
|
|
177
419
|
</SkeletonGroup>
|
|
178
420
|
);
|
|
179
421
|
}
|
|
180
422
|
```
|
|
181
423
|
|
|
182
|
-
|
|
424
|
+
---
|
|
425
|
+
|
|
426
|
+
### 7. Electron Desktop
|
|
427
|
+
|
|
428
|
+
Veilkit runs in Electron renderer processes with zero native dependencies.
|
|
429
|
+
|
|
430
|
+
- **IPC Loading Skeletons**: Automatically mask UI components while IPC requests (`ipcRenderer.invoke`) query native resources.
|
|
431
|
+
- **Strict CSP Support**: Compatible with strict Content Security Policies (`style-src 'self'`) by importing `veilkit/styles.css` directly or configuring a CSP nonce via `veil.configure({ nonce: '...' })`.
|
|
432
|
+
- **OS Theme Sync**: Responds to Electron's `nativeTheme.on('updated')` to synchronize light/dark modes.
|
|
433
|
+
|
|
434
|
+
---
|
|
435
|
+
|
|
436
|
+
### 8. Vanilla JavaScript & CDN
|
|
437
|
+
|
|
438
|
+
Drop-in UMD/IIFE bundle exporting the global `Veilkit`:
|
|
183
439
|
|
|
184
440
|
```html
|
|
185
|
-
|
|
186
|
-
<
|
|
187
|
-
<
|
|
188
|
-
|
|
189
|
-
|
|
441
|
+
<!DOCTYPE html>
|
|
442
|
+
<html>
|
|
443
|
+
<head>
|
|
444
|
+
<link rel="stylesheet" href="https://unpkg.com/veilkit/dist/styles.css" />
|
|
445
|
+
</head>
|
|
446
|
+
<body>
|
|
447
|
+
<div id="card-container"></div>
|
|
448
|
+
<button id="submit-btn">Save</button>
|
|
449
|
+
|
|
450
|
+
<script src="https://unpkg.com/veilkit/dist/veilkit.min.js"></script>
|
|
451
|
+
<script>
|
|
452
|
+
// 1. Render Preset
|
|
453
|
+
const card = Veilkit.createPreset({ name: 'card', animation: 'shimmer', theme: 'glass' });
|
|
454
|
+
document.getElementById('card-container').appendChild(card);
|
|
455
|
+
|
|
456
|
+
// 2. Route Progress
|
|
457
|
+
Veilkit.progress.start();
|
|
458
|
+
setTimeout(() => Veilkit.progress.done(), 1000);
|
|
459
|
+
|
|
460
|
+
// 3. Loading Button Controller
|
|
461
|
+
const btn = document.getElementById('submit-btn');
|
|
462
|
+
const btnController = Veilkit.wrapLoadingButton(btn, { loadingText: 'Saving…' });
|
|
463
|
+
|
|
464
|
+
btn.onclick = () => {
|
|
465
|
+
btnController.setLoading(true);
|
|
466
|
+
setTimeout(() => btnController.setLoading(false), 2000);
|
|
467
|
+
};
|
|
468
|
+
|
|
469
|
+
// 4. Auto-track async promises
|
|
470
|
+
Veilkit.track(fetch('/api/user'), { overlay: true });
|
|
471
|
+
</script>
|
|
472
|
+
</body>
|
|
473
|
+
</html>
|
|
474
|
+
```
|
|
190
475
|
|
|
191
|
-
|
|
192
|
-
Veilkit.progress.start();
|
|
193
|
-
setTimeout(() => Veilkit.progress.done(), 800);
|
|
476
|
+
---
|
|
194
477
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
478
|
+
## 🎨 45 Ready-Made Presets
|
|
479
|
+
|
|
480
|
+
Veilkit includes 45 canonical, responsive, customizable layout presets. Every preset supports responsive breakpoints and 5 shape styles (`rounded`, `pill`, `square`, `sharp`, `glass`).
|
|
481
|
+
|
|
482
|
+
<p align="center">
|
|
483
|
+
<img src="https://raw.githubusercontent.com/iamtashanto/veilkit/main/assets/demo-presets.gif" alt="Veilkit 45 Presets Demo" width="800" style="max-width: 100%; border-radius: 10px;" />
|
|
484
|
+
</p>
|
|
485
|
+
|
|
486
|
+
[**Browse all 45 Presets interactively in the Presets Gallery → https://veilkit.tashanto.com/presets**](https://veilkit.tashanto.com/presets)
|
|
487
|
+
|
|
488
|
+
### Shape Styles (`shape`)
|
|
489
|
+
- `rounded`: Default modern rounded corners (`8px` radius).
|
|
490
|
+
- `pill`: Fully rounded capsule corners (`9999px` radius).
|
|
491
|
+
- `square`: Subtle soft-square corners (`4px` radius).
|
|
492
|
+
- `sharp`: Geometric 0px razor-sharp borders (`0px` radius).
|
|
493
|
+
- `glass`: Translucent glassmorphic skeleton with `backdrop-filter: blur(12px)` and subtle frosted borders.
|
|
494
|
+
|
|
495
|
+
```tsx
|
|
496
|
+
<SkeletonPreset name="product-card" shape="glass" animation="aurora" />
|
|
198
497
|
```
|
|
199
498
|
|
|
499
|
+
| Category | Presets |
|
|
500
|
+
| :--- | :--- |
|
|
501
|
+
| **Cards & Content** | `card`, `product-card`, `product-grid`, `product-detail`, `e-commerce-checkout`, `feed-post`, `article`, `news-feed`, `media-card`, `map-card`, `pricing-card`, `testimonial`, `hero-banner` |
|
|
502
|
+
| **User & Social** | `profile`, `profile-header`, `stories-row`, `reels`, `social-story`, `comment-thread`, `chat` |
|
|
503
|
+
| **Dashboard & Data** | `dashboard`, `kpi-card`, `chart-bar`, `chart-line`, `chart-pie`, `kanban`, `timeline`, `calendar`, `table` |
|
|
504
|
+
| **Lists & Feeds** | `list`, `list-item`, `inbox-list`, `notification-list`, `order-list`, `search-results` |
|
|
505
|
+
| **Developer & Code** | `code-block`, `file-explorer` |
|
|
506
|
+
| **Forms & Navigation**| `form`, `navbar`, `sidebar`, `tabs`, `settings-page`, `faq-accordion` |
|
|
507
|
+
| **Media Players** | `video-player`, `music-player` |
|
|
508
|
+
|
|
200
509
|
---
|
|
201
510
|
|
|
202
|
-
##
|
|
511
|
+
## 🧩 Custom Skeleton Layout Builder
|
|
203
512
|
|
|
204
|
-
|
|
513
|
+
Need a skeleton that matches your exact custom website layout? Veilkit provides a fluent builder API and declarative JSON engine, plus an interactive visual builder studio on our website.
|
|
205
514
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
515
|
+
[**Try the Visual Custom Skeleton Studio → https://veilkit.tashanto.com/custom-builder**](https://veilkit.tashanto.com/custom-builder)
|
|
516
|
+
|
|
517
|
+
### 1. Fluent Builder API (`SkeletonBuilder`)
|
|
518
|
+
Build modular layouts using method chaining with full TypeScript auto-completion:
|
|
519
|
+
|
|
520
|
+
```typescript
|
|
521
|
+
import { SkeletonBuilder } from 'veilkit';
|
|
522
|
+
|
|
523
|
+
// Construct custom skeleton tree
|
|
524
|
+
const skeleton = new SkeletonBuilder({
|
|
525
|
+
animation: 'shimmer',
|
|
526
|
+
shape: 'rounded',
|
|
527
|
+
theme: 'dark'
|
|
528
|
+
})
|
|
529
|
+
.card((card) => {
|
|
530
|
+
// Top row with user avatar & meta
|
|
531
|
+
card.row((row) => {
|
|
532
|
+
row.avatar(48);
|
|
533
|
+
row.col((col) => {
|
|
534
|
+
col.heading('65%');
|
|
535
|
+
col.lines(2);
|
|
536
|
+
});
|
|
537
|
+
row.badge(60, 24);
|
|
538
|
+
});
|
|
539
|
+
|
|
540
|
+
// Content media banner
|
|
541
|
+
card.rect('100%', 160);
|
|
542
|
+
|
|
543
|
+
// Bottom action row
|
|
544
|
+
card.row((row) => {
|
|
545
|
+
row.button(110, 36);
|
|
546
|
+
row.button(80, 36);
|
|
547
|
+
});
|
|
548
|
+
})
|
|
549
|
+
.build(); // Returns a ready-to-mount HTMLDivElement
|
|
550
|
+
|
|
551
|
+
document.getElementById('my-app').appendChild(skeleton);
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
### 2. React `<CustomSkeleton />` Component
|
|
555
|
+
Pass your custom tree structure directly to the React component:
|
|
556
|
+
|
|
557
|
+
```tsx
|
|
558
|
+
import { CustomSkeleton, SkeletonBuilder } from 'veilkit/react';
|
|
559
|
+
|
|
560
|
+
const config = new SkeletonBuilder({ shape: 'glass', animation: 'aurora' })
|
|
561
|
+
.row((r) => {
|
|
562
|
+
r.avatar(52);
|
|
563
|
+
r.col((c) => {
|
|
564
|
+
c.heading('75%');
|
|
565
|
+
c.lines(3);
|
|
566
|
+
});
|
|
567
|
+
})
|
|
568
|
+
.toConfig();
|
|
569
|
+
|
|
570
|
+
export function MyCustomLoader() {
|
|
571
|
+
return <CustomSkeleton config={config} />;
|
|
215
572
|
}
|
|
216
573
|
```
|
|
217
574
|
|
|
218
|
-
|
|
575
|
+
### 3. Declarative JSON Schema (`createCustomSkeleton`)
|
|
576
|
+
Or define layouts as clean, serializable JSON configs (ideal for sharing across micro-frontends):
|
|
219
577
|
|
|
578
|
+
```typescript
|
|
579
|
+
import { createCustomSkeleton } from 'veilkit';
|
|
580
|
+
|
|
581
|
+
const element = createCustomSkeleton({
|
|
582
|
+
shape: 'rounded',
|
|
583
|
+
animation: 'wave',
|
|
584
|
+
root: {
|
|
585
|
+
type: 'card',
|
|
586
|
+
children: [
|
|
587
|
+
{ type: 'avatar', size: 48 },
|
|
588
|
+
{ type: 'heading', width: '80%', height: 24 },
|
|
589
|
+
{ type: 'lines', count: 3 },
|
|
590
|
+
{ type: 'button', width: 120, height: 38 }
|
|
591
|
+
]
|
|
592
|
+
}
|
|
593
|
+
});
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
---
|
|
597
|
+
|
|
598
|
+
## ✨ 30 GPU-Accelerated Animations
|
|
599
|
+
|
|
600
|
+
All animations strictly use `transform` and `opacity` to eliminate layout thrashing:
|
|
601
|
+
|
|
602
|
+
| Animation | Description |
|
|
603
|
+
| :--- | :--- |
|
|
604
|
+
| `shimmer` | Classic smooth linear gradient sweep |
|
|
605
|
+
| `wave` | Curved sinusoidal sweep overlay |
|
|
606
|
+
| `pulse` | Calm opacity breathing cycle (`0.4` ↔ `1.0`) |
|
|
607
|
+
| `blink` | Crisp, rhythmic stepped pulse |
|
|
608
|
+
| `breathe` | Subtly slow opacity + micro-scale (`0.995` ↔ `1.005`) |
|
|
609
|
+
| `glass-shine` | Angled diagonal sheen glint across frosted surface |
|
|
610
|
+
| `gradient-flow` | Continuous multi-stop hue transition across element width |
|
|
611
|
+
| `aurora` | Organic multi-chroma soft orbital drift |
|
|
612
|
+
| `scan-line` | High-tech precision laser line sweep |
|
|
613
|
+
| `sparkle` | Shifting micro-glint highlights |
|
|
614
|
+
| `neon-glow` | Luminous edge glow pulsing |
|
|
615
|
+
| `stagger` | Applies progressive animation delays to child elements in sequence |
|
|
616
|
+
| `ripple` | Radial circular pulse emanating outward from element center |
|
|
617
|
+
| `ping-pong` | Smooth sweeping highlight that reverses direction at edges |
|
|
618
|
+
| `wipe` | Sleek bar that slides across element revealing geometry |
|
|
619
|
+
| `cascade` | Top-to-bottom delayed wave across blocks |
|
|
620
|
+
| `spotlight` | Focused soft light cone traversing the container |
|
|
621
|
+
| `rainbow` | Chromatic multi-hue sweep transition |
|
|
622
|
+
| `heartbeat` | Rhythmic double-beat opacity pulse |
|
|
623
|
+
| `liquid` | Soft fluid morphing highlight sweep |
|
|
624
|
+
| `stripes` | Animated barber-pole diagonal stripe pattern |
|
|
625
|
+
| `halftone` | Stylized dot-matrix luminous pulse |
|
|
626
|
+
| `border-glow` | Luminous perimeter neon border trace |
|
|
627
|
+
| `typewriter` | Text placeholders that dynamically grow in width |
|
|
628
|
+
| `glitch` | Micro high-tech digital displacement flicker |
|
|
629
|
+
| `pixelate` | Retro 8-bit block pixel flicker matrix |
|
|
630
|
+
| `tilt` | Subtle 3D perspective tilt motion |
|
|
631
|
+
| `diagonal-sweep`| 45-degree corner-to-corner highlight sweep |
|
|
632
|
+
| `bounce-in` | Elastic micro-spring scale reveal |
|
|
633
|
+
| `fade-slide` | Subtle upward floating drift |
|
|
634
|
+
|
|
635
|
+
---
|
|
636
|
+
|
|
637
|
+
## 🎨 11 Built-in Themes & Custom Theming
|
|
638
|
+
|
|
639
|
+
| Theme | Description | Tokens / Styling |
|
|
640
|
+
| :--- | :--- | :--- |
|
|
641
|
+
| `light` | Crisp neutral gray | `#e5e7eb` base, `rgba(255, 255, 255, 0.7)` highlight |
|
|
642
|
+
| `dark` | Deep slate night palette | `#1f2937` base, `rgba(255, 255, 255, 0.12)` highlight |
|
|
643
|
+
| `auto` | System dynamic theme | Automatically switches light/dark via `prefers-color-scheme` |
|
|
644
|
+
| `glass` | Frosted translucency | `backdrop-filter: blur(12px)`, subtle border, inner glow |
|
|
645
|
+
| `ios` | Apple Human Interface aesthetic | Soft neutral gray `rgba(120, 120, 128, 0.18)`, iOS easing |
|
|
646
|
+
| `material`| Material You / M3 | Surface tonal elevations, pill radius, standard ease |
|
|
647
|
+
| `minimal` | Ultra-clean low contrast | Subtle neutral tint, 4px border radius |
|
|
648
|
+
| `mono` | Pure monochrome | High-contrast grayscale with crisp stops |
|
|
649
|
+
| `neon` | Cyberpunk luminous glow | Deep charcoal `#0c0b16` base, electric cyan `#00f0ff` glow |
|
|
650
|
+
| `sunset` | Warm golden twilight | Peach/coral base `#fed7aa` with warm amber glow |
|
|
651
|
+
| `ocean` | Deep marine azure | Deep sea `#0f2937` base with vibrant cyan highlight |
|
|
652
|
+
|
|
653
|
+
### Custom Brand Themes via `createTheme()`:
|
|
220
654
|
```ts
|
|
221
655
|
import { createTheme } from 'veilkit';
|
|
222
656
|
|
|
@@ -226,21 +660,256 @@ createTheme({
|
|
|
226
660
|
highlight: 'rgba(0, 240, 255, 0.6)',
|
|
227
661
|
radius: '8px',
|
|
228
662
|
border: '1px solid rgba(0, 240, 255, 0.3)',
|
|
663
|
+
glow: '0 0 16px rgba(0, 240, 255, 0.4)',
|
|
229
664
|
});
|
|
230
665
|
```
|
|
231
666
|
|
|
232
667
|
---
|
|
233
668
|
|
|
234
|
-
##
|
|
669
|
+
## 🔄 30 Spinner Loaders
|
|
670
|
+
|
|
671
|
+
All 30 spinners are GPU-accelerated, scalable via `size` and `color`, and support `glass` frosted blur variants and custom `speed`:
|
|
672
|
+
|
|
673
|
+
<p align="center">
|
|
674
|
+
<img src="https://raw.githubusercontent.com/iamtashanto/veilkit/main/assets/demo-spinners.gif" alt="Veilkit 30 Spinners Demo" width="800" style="max-width: 100%; border-radius: 10px;" />
|
|
675
|
+
</p>
|
|
676
|
+
|
|
677
|
+
[**Explore all 30 Spinners interactively in the Spinners Catalog → https://veilkit.tashanto.com/spinners**](https://veilkit.tashanto.com/spinners)
|
|
678
|
+
|
|
679
|
+
`ring` • `dual-ring` • `dots` • `bars` • `pulse` • `orbit` • `wave` • `bounce` • `ios-activity` • `glass-orb` • `morph` • `progress-circle` • `arc-gradient` • `pulse-ring` • `dots-circle` • `grid-dots` • `square-flip` • `cube-fold` • `hourglass` • `infinity` • `heartbeat-line` • `equalizer` • `chasing-dots` • `typing` • `liquid-fill` • `atom` • `clock` • `radar` • `ellipsis` • `flower`
|
|
680
|
+
|
|
681
|
+
```tsx
|
|
682
|
+
<Spinner type="arc-gradient" size={32} color="#38bdf8" speed={0.8} />
|
|
683
|
+
<Spinner type="atom" size={36} glass />
|
|
684
|
+
<Spinner type="infinity" size={28} color="#a855f7" />
|
|
685
|
+
```
|
|
686
|
+
|
|
687
|
+
---
|
|
688
|
+
|
|
689
|
+
## 🔘 Loading Button & State Machine
|
|
690
|
+
|
|
691
|
+
Veilkit includes a comprehensive loading button with state machine transitions, 16 loading styles, result animations, press feedback, and native haptics:
|
|
692
|
+
|
|
693
|
+
<p align="center">
|
|
694
|
+
<img src="https://raw.githubusercontent.com/iamtashanto/veilkit/main/assets/demo-button.gif" alt="Veilkit Loading Button Demo" width="800" style="max-width: 100%; border-radius: 10px;" />
|
|
695
|
+
</p>
|
|
696
|
+
|
|
697
|
+
- **State Machine**: `idle → loading → success | error → idle`. Automatically handles async promises or explicit `status` prop (`idle`, `loading`, `success`, `error`).
|
|
698
|
+
- **Auto-Reset**: Configurable `resetAfter` (default: 2000ms) resets success/error state back to idle.
|
|
699
|
+
- **Double-Click Protection**: Clicks are safely ignored while non-idle.
|
|
700
|
+
- **Result Animations**: Animated SVG `checkmark` draw, `cross` draw, error `shake`, and celebratory `success-burst`.
|
|
701
|
+
- **Press Feedback**: `ripple` (material ink ripple), `press-scale` (tactile spring down), or `glow-follow` (magnetic mouse highlight).
|
|
702
|
+
- **Native Haptics**: On React Native/Expo, automatically triggers light haptic on start, notification success on completion, and notification error on failure (via `expo-haptics`).
|
|
703
|
+
|
|
704
|
+
### 16 Loading Styles:
|
|
705
|
+
1. `spinner-left`: Spinner docked at the start of text
|
|
706
|
+
2. `spinner-right`: Spinner docked at the end of text
|
|
707
|
+
3. `spinner-replace`: Button text smoothly fades out, replaced by centered spinner
|
|
708
|
+
4. `dots-after-text`: Animated trailing ellipsis dots (`Saving...`)
|
|
709
|
+
5. `progress-fill`: Button background fills horizontally as determinate or indeterminate progress
|
|
710
|
+
6. `shimmer-surface`: Subtle GPU light sheen swept across button surface
|
|
711
|
+
7. `pulse-glow`: Luminous breathing glow around button border
|
|
712
|
+
8. `stripes-progress`: Animated diagonal barber-pole progress stripes
|
|
713
|
+
9. `morph-circle`: Button contracts into a compact circle spinner, then expands back to pill
|
|
714
|
+
10. `slide-text`: Active text slides upward as loading status slides into view
|
|
715
|
+
11. `border-trace`: Laser beam traced continuously along the button's perimeter
|
|
716
|
+
12. `liquid-fill`: Fluid wave that rises and fills the button interior
|
|
717
|
+
13. `bounce-dots`: Three rhythmic bouncing micro-dots
|
|
718
|
+
14. `glass-shine`: Glint reflecting across frosted glassmorphic button
|
|
719
|
+
15. `neon-pulse`: Electric neon aura pulsing around the button
|
|
720
|
+
16. `skeleton-button`: Button transforms seamlessly into a matching skeleton placeholder
|
|
721
|
+
|
|
722
|
+
```tsx
|
|
723
|
+
<LoadingButton
|
|
724
|
+
loadingStyle="morph-circle"
|
|
725
|
+
pressFeedback="ripple"
|
|
726
|
+
loadingText="Deploying..."
|
|
727
|
+
successText="Live!"
|
|
728
|
+
errorText="Failed"
|
|
729
|
+
onClick={async () => {
|
|
730
|
+
await deployProject();
|
|
731
|
+
}}
|
|
732
|
+
>
|
|
733
|
+
Deploy to Production
|
|
734
|
+
</LoadingButton>
|
|
735
|
+
```
|
|
736
|
+
|
|
737
|
+
---
|
|
738
|
+
|
|
739
|
+
## 📐 Auto-Measure & Reveal Engine
|
|
740
|
+
|
|
741
|
+
Wrap real UI components to automatically generate an accurate skeleton matching your real layout. When data finishes loading, Veilkit reveals the content with a smooth transition:
|
|
742
|
+
|
|
743
|
+
- **Reveal Transitions**: `fade`, `blur-in`, `slide-up`, `scale`, `stagger-children`, `none`.
|
|
744
|
+
- **Layout Caching**: Supports `cacheKey="profile-view"` with in-memory & `localStorage` caching for instant placeholder rendering on repeat visits.
|
|
745
|
+
- **Attributes**:
|
|
746
|
+
- `data-veil-ignore`: Skips element measurement.
|
|
747
|
+
- `data-veil-shape="circle|rect|line"`: Forces placeholder shape.
|
|
748
|
+
|
|
749
|
+
---
|
|
750
|
+
|
|
751
|
+
## ⏱️ Anti-Flicker Timing Controller
|
|
752
|
+
|
|
753
|
+
Veilkit includes built-in anti-flicker timing:
|
|
754
|
+
- `delay` (default `150ms`): If your data loads faster than 150ms, the loader is never shown, avoiding annoying micro-flashes.
|
|
755
|
+
- `minVisible` (default `300ms`): Once a skeleton or spinner appears, it remains visible for at least 300ms to eliminate visual flashing.
|
|
756
|
+
|
|
757
|
+
```ts
|
|
758
|
+
import { AntiFlickerController } from 'veilkit';
|
|
759
|
+
|
|
760
|
+
const controller = new AntiFlickerController({
|
|
761
|
+
delay: 150,
|
|
762
|
+
minVisible: 300,
|
|
763
|
+
onShow: () => showLoader(),
|
|
764
|
+
onHide: () => hideLoader(),
|
|
765
|
+
});
|
|
766
|
+
```
|
|
767
|
+
|
|
768
|
+
---
|
|
769
|
+
|
|
770
|
+
## 🌐 Global Loading Manager & Request Tracking
|
|
771
|
+
|
|
772
|
+
Coordinate multiple concurrent network requests with a unified manager:
|
|
773
|
+
|
|
774
|
+
```ts
|
|
775
|
+
import { veil } from 'veilkit';
|
|
776
|
+
|
|
777
|
+
// 1. Automatic Promise tracking with anti-flicker and overlay
|
|
778
|
+
const data = await veil.track(fetchUserData(), {
|
|
779
|
+
delay: 150,
|
|
780
|
+
minVisible: 300,
|
|
781
|
+
overlay: true,
|
|
782
|
+
progress: true,
|
|
783
|
+
});
|
|
784
|
+
|
|
785
|
+
// 2. Fetch wrapper (opt-in, never monkey-patches globals)
|
|
786
|
+
const trackedFetch = veil.wrapFetch(window.fetch, { progress: true });
|
|
787
|
+
await trackedFetch('/api/orders');
|
|
788
|
+
|
|
789
|
+
// 3. Concurrency Counter Subscription
|
|
790
|
+
veil.manager.subscribe((isLoading, count) => {
|
|
791
|
+
console.log(`Active operations: ${count}, Busy: ${isLoading}`);
|
|
792
|
+
});
|
|
793
|
+
```
|
|
794
|
+
|
|
795
|
+
---
|
|
796
|
+
|
|
797
|
+
## ♿️ Accessibility (a11y) & Localization
|
|
798
|
+
|
|
799
|
+
- Containers are marked with `aria-busy="true"` while loading.
|
|
800
|
+
- Skeletons are hidden from screen readers via `aria-hidden="true"`.
|
|
801
|
+
- Loading state announcements are delivered via polite live regions (`role="status"`, `aria-live="polite"`).
|
|
802
|
+
- Built-in multi-language localization dictionary:
|
|
803
|
+
- English (`en`), Spanish (`es`), French (`fr`), German (`de`), Japanese (`ja`), Chinese (`zh`), Arabic (`ar`).
|
|
804
|
+
- Configure globally: `veil.setLocale('es')` or override labels via `veil.setLabels({ loading: 'Espere por favor…' })`.
|
|
805
|
+
- Fully complies with `prefers-reduced-motion: reduce` and `forced-colors: active`.
|
|
806
|
+
|
|
807
|
+
---
|
|
808
|
+
|
|
809
|
+
## 🛠️ Veilkit CLI (`capture`)
|
|
810
|
+
|
|
811
|
+
Pre-render static layout maps using headless Chromium:
|
|
812
|
+
|
|
813
|
+
```bash
|
|
814
|
+
npx veilkit capture https://myapp.com/dashboard --out ./dashboard.veil.json --selector "#dashboard"
|
|
815
|
+
```
|
|
816
|
+
|
|
817
|
+
The resulting `.veil.json` file can be bundled directly with your application to render instant skeletons without requiring runtime DOM measurements.
|
|
818
|
+
|
|
819
|
+
---
|
|
820
|
+
|
|
821
|
+
## 🔒 GitHub Actions & npm Provenance
|
|
822
|
+
|
|
823
|
+
`veilkit` releases are published with verifiable **npm Provenance** backed by OpenID Connect (OIDC) and Sigstore public transparency logs. This guarantees cryptographic traceability from the published npm package directly to the verified source commit in GitHub Actions.
|
|
824
|
+
|
|
825
|
+
### Trusted Publisher Configuration
|
|
826
|
+
|
|
827
|
+
The package is configured on npm under **Trusted Publisher** with the following parameters:
|
|
828
|
+
|
|
829
|
+
| Setting | Value | Description |
|
|
830
|
+
| :--- | :--- | :--- |
|
|
831
|
+
| **Publisher** | `GitHub Actions` | Authenticates via GitHub OpenID Connect (OIDC) token exchange |
|
|
832
|
+
| **Label** | `veilkit` | Human-readable identifier on npmjs.com |
|
|
833
|
+
| **Organization or user** | `iamtashanto` | GitHub owner account (`github.com/iamtashanto`) |
|
|
834
|
+
| **Repository** | `veilkit` | GitHub source repository (`github.com/iamtashanto/veilkit`) |
|
|
835
|
+
| **Workflow filename** | `release.yml` | Dedicated workflow in `.github/workflows/release.yml` |
|
|
836
|
+
| **Environment name** | `npm-publish` | Protected GitHub Actions environment with scoped access |
|
|
837
|
+
| **Allowed actions** | `Allow npm publish`, `Allow npm dist-tag` | Permits version publishing and dist-tag management (`latest`, `next`) |
|
|
838
|
+
|
|
839
|
+
### Workflow Configuration (`.github/workflows/release.yml`)
|
|
840
|
+
|
|
841
|
+
```yaml
|
|
842
|
+
name: Release
|
|
843
|
+
|
|
844
|
+
on:
|
|
845
|
+
push:
|
|
846
|
+
branches:
|
|
847
|
+
- main
|
|
848
|
+
workflow_dispatch:
|
|
849
|
+
|
|
850
|
+
concurrency: ${{ github.workflow }}-${{ github.ref }}
|
|
851
|
+
|
|
852
|
+
jobs:
|
|
853
|
+
release:
|
|
854
|
+
name: Release & Publish to npm
|
|
855
|
+
runs-on: ubuntu-latest
|
|
856
|
+
environment: npm-publish
|
|
857
|
+
permissions:
|
|
858
|
+
contents: write
|
|
859
|
+
id-token: write # Required for npm provenance OIDC exchange
|
|
860
|
+
pull-requests: write
|
|
861
|
+
|
|
862
|
+
steps:
|
|
863
|
+
- uses: actions/checkout@v4
|
|
864
|
+
with:
|
|
865
|
+
fetch-depth: 0
|
|
866
|
+
|
|
867
|
+
- uses: pnpm/action-setup@v3
|
|
868
|
+
with:
|
|
869
|
+
version: 12
|
|
870
|
+
|
|
871
|
+
- uses: actions/setup-node@v4
|
|
872
|
+
with:
|
|
873
|
+
node-version: 20
|
|
874
|
+
cache: 'pnpm'
|
|
875
|
+
|
|
876
|
+
- run: pnpm install
|
|
877
|
+
- run: pnpm lint
|
|
878
|
+
- run: pnpm typecheck
|
|
879
|
+
- run: pnpm test
|
|
880
|
+
- run: pnpm build:all
|
|
881
|
+
- run: pnpm publint
|
|
882
|
+
|
|
883
|
+
- name: Publish to npm with Provenance
|
|
884
|
+
run: npm publish --access public --provenance
|
|
885
|
+
```
|
|
886
|
+
|
|
887
|
+
### Verifying Provenance
|
|
888
|
+
|
|
889
|
+
You can verify the authenticity and build attestation of any installed `veilkit` release:
|
|
890
|
+
|
|
891
|
+
```bash
|
|
892
|
+
# Verify signatures and build provenance using npm CLI
|
|
893
|
+
npm audit signatures
|
|
894
|
+
|
|
895
|
+
# View provenance details directly on npm:
|
|
896
|
+
# https://www.npmjs.com/package/veilkit
|
|
897
|
+
```
|
|
898
|
+
|
|
899
|
+
---
|
|
900
|
+
|
|
901
|
+
## 👤 Author & Maintainer
|
|
235
902
|
|
|
236
|
-
-
|
|
237
|
-
-
|
|
238
|
-
-
|
|
239
|
-
-
|
|
240
|
-
-
|
|
903
|
+
- **Creator & Maintainer**: **Md Tanvir Ahamed Shanto**
|
|
904
|
+
- **Website & Documentation**: [veilkit.tashanto.com](https://veilkit.tashanto.com)
|
|
905
|
+
- **GitHub**: [@iamtashanto](https://github.com/iamtashanto)
|
|
906
|
+
- **npm Account**: [@mdtanvirahamedshanto](https://www.npmjs.com/~mdtanvirahamedshanto)
|
|
907
|
+
- **Repository**: [github.com/iamtashanto/veilkit](https://github.com/iamtashanto/veilkit)
|
|
908
|
+
- **Issues & Feedback**: [github.com/iamtashanto/veilkit/issues](https://github.com/iamtashanto/veilkit/issues)
|
|
241
909
|
|
|
242
910
|
---
|
|
243
911
|
|
|
244
912
|
## 📄 License
|
|
245
913
|
|
|
246
|
-
|
|
914
|
+
Veilkit is open-source software licensed under the [MIT License](LICENSE).
|
|
915
|
+
© 2026 Md Tanvir Ahamed Shanto. All rights reserved.
|