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