loader-overlay 1.0.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/README.md ADDED
@@ -0,0 +1,366 @@
1
+ # loader-overlay
2
+
3
+ > A fully-featured React loader overlay component — 5 animation types, full theme control, progress tracking, outside-click dismissal, and **zero dependencies**.
4
+
5
+ <!--
6
+ [![npm version](https://img.shields.io/npm/v/loader-overlay.svg)](https://www.npmjs.com/package/loader-overlay)
7
+ [![npm downloads](https://img.shields.io/npm/dm/loader-overlay.svg)](https://www.npmjs.com/package/loader-overlay)
8
+ [![license](https://img.shields.io/npm/l/loader-overlay.svg)](LICENSE)
9
+ -->
10
+ [![TypeScript](https://img.shields.io/badge/TypeScript-ready-blue.svg)](https://www.typescriptlang.org/)
11
+ [![bundle size](https://img.shields.io/bundlephobia/minzip/loader-overlay)](https://bundlephobia.com/package/loader-overlay)
12
+
13
+ ---
14
+
15
+ ## ✨ Features
16
+
17
+ - 🎡 **5 loader types** — `spinner`, `dots`, `pulse`, `ring`, `bar`
18
+ - 🎨 **5 variants** — `dark`, `light`, `blur`, `transparent`, `gradient`
19
+ - 📊 **Progress bar** — animated shimmer progress tracking
20
+ - 🖱️ **Outside click dismiss** — close on backdrop click
21
+ - ⏱️ **Auto-dismiss** — timeout-based auto-hide
22
+ - ♿ **Accessible** — keyboard and screen reader friendly
23
+ - 📦 **Zero dependencies** — only peer dep is React 17+
24
+ - 🌳 **Tree-shakeable** — ESM and CJS builds
25
+ - 💙 **TypeScript ready** — full type definitions included
26
+
27
+ ---
28
+
29
+ ## 📦 Installation
30
+
31
+ ```bash
32
+ # npm
33
+ npm install loader-overlay
34
+
35
+ # yarn
36
+ yarn add loader-overlay
37
+
38
+ # pnpm
39
+ pnpm add loader-overlay
40
+
41
+ # bun
42
+ bun add loader-overlay
43
+ ```
44
+
45
+ ### Peer Dependencies
46
+
47
+ Make sure these are already in your project:
48
+
49
+ ```json
50
+ {
51
+ "react": ">=17.0.0",
52
+ "react-dom": ">=17.0.0"
53
+ }
54
+ ```
55
+
56
+ ---
57
+
58
+ ## 💻 Local Installation
59
+
60
+ We provide a dedicated `consumer-demo` application directly in the repository to guarantee a seamless local installation testing environment out-of-the-box.
61
+
62
+ ### Using the Built-in Consumer Demo
63
+
64
+ ```bash
65
+ git clone https://github.com/swapnilhpatil/loader-overlay.git
66
+ cd loader-overlay
67
+ npm install && npm run build
68
+
69
+ # Navigate to the standalone consumer-demo test application
70
+ cd consumer-demo
71
+ npm install # Automatically links to file:../
72
+ npm run dev # Tests the compiled library package locally!
73
+ ```
74
+
75
+ ### Install from Local Path (In your own App)
76
+
77
+ ```bash
78
+ # Point directly to your local clone of loader-overlay
79
+ npm install file:../loader-overlay # npm
80
+ yarn add ../loader-overlay # yarn
81
+ pnpm add ../loader-overlay # pnpm
82
+ ```
83
+
84
+ ### Install from Tarball
85
+
86
+ ```bash
87
+ # In loader-overlay dir
88
+ npm pack # creates loader-overlay-x.x.x.tgz
89
+
90
+ # In your app
91
+ npm install ../loader-overlay/loader-overlay-1.0.0.tgz
92
+ ```
93
+
94
+ ### Install from GitHub
95
+
96
+ ```bash
97
+ npm install swapnilhpatil/loader-overlay # latest
98
+ npm install swapnilhpatil/loader-overlay#v1.0.0 # specific tag
99
+ ```
100
+
101
+ > See [SETUP_GUIDE.md](SETUP_GUIDE.md) for the full local installation guide including workspaces, path aliases, and pnpm/yarn link methods.
102
+
103
+ ---
104
+
105
+ ## 🚀 Quick Start
106
+
107
+ ```jsx
108
+ import { useState } from 'react';
109
+ import LoaderOverlay from 'loader-overlay';
110
+
111
+ export default function App() {
112
+ const [loading, setLoading] = useState(false);
113
+
114
+ const fetchData = async () => {
115
+ setLoading(true);
116
+ await fetch('/api/data');
117
+ setLoading(false);
118
+ };
119
+
120
+ return (
121
+ <div style={{ position: 'relative' }}>
122
+ <LoaderOverlay show={loading} />
123
+ <button onClick={fetchData}>Load Data</button>
124
+ </div>
125
+ );
126
+ }
127
+ ```
128
+
129
+ ---
130
+
131
+ ## 📥 Imports
132
+
133
+ ```js
134
+ // Default import
135
+ import LoaderOverlay from 'loader-overlay';
136
+ ```
137
+
138
+ ```js
139
+ // Named imports — tree-shakeable (icons & constants)
140
+ import { SpinIcon, DotsIcon, PulseIcon, RingIcon, BarIcon } from 'loader-overlay';
141
+ import { SIZES, VARIANTS, ANIM_CSS, ICONS } from 'loader-overlay';
142
+ ```
143
+
144
+ ```ts
145
+ // TypeScript — no @types package needed, types are bundled
146
+ import type { LoaderOverlayProps, LoaderType, LoaderVariant, LoaderSize } from 'loader-overlay';
147
+ ```
148
+
149
+ ---
150
+
151
+ ## 📖 Usage Examples
152
+
153
+ ### With Progress Bar
154
+
155
+ ```jsx
156
+ <LoaderOverlay
157
+ show={uploading}
158
+ type="bar"
159
+ variant="gradient"
160
+ color="#60d394"
161
+ message="Uploading file..."
162
+ showProgress
163
+ progress={uploadPercent}
164
+ />
165
+ ```
166
+
167
+ ### Outside Click Dismiss
168
+
169
+ ```jsx
170
+ <LoaderOverlay
171
+ show={loading}
172
+ fullScreen
173
+ closeOnOutsideClick
174
+ closable
175
+ onClose={() => setLoading(false)}
176
+ message="Processing..."
177
+ />
178
+ ```
179
+
180
+ ### Auto-dismiss with Timeout
181
+
182
+ ```jsx
183
+ <LoaderOverlay
184
+ show={loading}
185
+ timeout={3000}
186
+ onClose={() => setLoading(false)}
187
+ message="Done in 3 seconds..."
188
+ type="dots"
189
+ />
190
+ ```
191
+
192
+ ### Custom Children
193
+
194
+ ```jsx
195
+ <LoaderOverlay show={loading} variant="dark">
196
+ <div style={{ textAlign: 'center' }}>
197
+ <img src="/logo-animated.svg" width={64} alt="loading" />
198
+ <p style={{ color: 'white' }}>Brewing your dashboard ☕</p>
199
+ </div>
200
+ </LoaderOverlay>
201
+ ```
202
+
203
+ ### TypeScript
204
+
205
+ ```tsx
206
+ import LoaderOverlay, { LoaderOverlayProps } from 'loader-overlay';
207
+
208
+ const props: LoaderOverlayProps = {
209
+ show: true,
210
+ type: 'spinner',
211
+ variant: 'dark',
212
+ color: '#a78bfa',
213
+ };
214
+ ```
215
+
216
+ ---
217
+
218
+ ## 🎛️ Props Reference
219
+
220
+ | Prop | Type | Default | Description |
221
+ |------|------|---------|-------------|
222
+ | `show` | `boolean` | `true` | Controls loader overlay visibility |
223
+ | `type` | `'spinner' \| 'dots' \| 'pulse' \| 'ring' \| 'bar'` | `'spinner'` | Selection of loader animation type |
224
+ | `size` | `'sm' \| 'md' \| 'lg' \| 'xl'` | `'md'` | Configures the size footprint of the loader |
225
+ | `variant` | `'dark' \| 'light' \| 'blur' \| 'transparent' \| 'gradient'` | `'dark'` | Defines the overlay background aesthetic |
226
+ | `color` | `string` | `'#a78bfa'` | Master accent color (hex, rgb, or css var) |
227
+ | `message` | `string` | `'Loading...'` | Primary status label |
228
+ | `submessage` | `string` | `''` | Secondary hint or details text |
229
+ | `fullScreen` | `boolean` | `false` | Fixes overlay relative to viewport vs parent |
230
+ | `zIndex` | `number` | `999` | Determines the CSS z-index |
231
+ | `opacity` | `number` | `1` | Configures the global backdrop opacity |
232
+ | `blur` | `number` | `8` | Frosts the backdrop via CSS blur (px) |
233
+ | `position` | `'center' \| 'top' \| 'bottom'` | `'center'` | Vertical alignment of the main content box |
234
+ | `showProgress` | `boolean` | `false` | Activates an animated precise progress bar |
235
+ | `progress` | `number` | `0` | Progress value injected into the bar (0–100) |
236
+ | `closable` | `boolean` | `false` | Displays a dismiss ✕ button in the corner |
237
+ | `onClose` | `() => void` | `() => {}` | Event fired exactly when the overlay unmounts |
238
+ | `closeOnOutsideClick` | `boolean` | `false` | Allows backdrop clicks to dismiss the loader |
239
+ | `onOutsideClick` | `() => void` | `() => {}` | Granular event fired on backdrop interaction |
240
+ | `animateIn` | `boolean` | `true` | Allows smooth CSS fade-in animations on mount |
241
+ | `timeout` | `number` | `0` | Automatic unmount dismissal after specified ms |
242
+ | `children` | `ReactNode` | `null` | Drops in totally generic DOM replacing core icons |
243
+
244
+ ---
245
+
246
+ ## 🔧 Reusable Hook
247
+
248
+ ```tsx
249
+ import { useState, useCallback } from 'react';
250
+ import LoaderOverlay from 'loader-overlay';
251
+
252
+ function useLoader() {
253
+ const [state, setState] = useState({
254
+ show: false,
255
+ message: 'Loading...',
256
+ progress: 0,
257
+ });
258
+
259
+ const start = useCallback((message = 'Loading...') => {
260
+ setState({ show: true, message, progress: 0 });
261
+ }, []);
262
+
263
+ const setProgress = useCallback((progress: number) => {
264
+ setState(s => ({ ...s, progress }));
265
+ }, []);
266
+
267
+ const stop = useCallback(() => {
268
+ setState(s => ({ ...s, show: false }));
269
+ }, []);
270
+
271
+ return { loaderProps: state, start, setProgress, stop };
272
+ }
273
+
274
+ // Usage
275
+ function MyPage() {
276
+ const { loaderProps, start, stop } = useLoader();
277
+
278
+ return (
279
+ <>
280
+ <LoaderOverlay {...loaderProps} showProgress fullScreen />
281
+ <button onClick={() => { start('Saving...'); setTimeout(stop, 2000); }}>
282
+ Save
283
+ </button>
284
+ </>
285
+ );
286
+ }
287
+ ```
288
+
289
+ ---
290
+
291
+ ## 🌐 Route Transitions (React Router v6)
292
+
293
+ ```tsx
294
+ import { useNavigation, Outlet } from 'react-router-dom';
295
+ import LoaderOverlay from 'loader-overlay';
296
+
297
+ export default function RootLayout() {
298
+ const navigation = useNavigation();
299
+
300
+ return (
301
+ <>
302
+ <LoaderOverlay
303
+ show={navigation.state !== 'idle'}
304
+ fullScreen
305
+ type="dots"
306
+ variant="dark"
307
+ message="Navigating..."
308
+ zIndex={9999}
309
+ />
310
+ <Outlet />
311
+ </>
312
+ );
313
+ }
314
+ ```
315
+
316
+ ---
317
+
318
+ ## 📁 Package Structure
319
+
320
+ ```text
321
+ loader-overlay/
322
+ ├── dist/
323
+ │ ├── loader-overlay.d.ts ← TypeScript declarations
324
+ │ ├── loader-overlay.es.js ← ES module (tree-shakeable)
325
+ │ ├── loader-overlay.es.js.map ← Source map
326
+ │ ├── loader-overlay.umd.js ← UMD for CommonJS / CDN use
327
+ │ └── loader-overlay.umd.js.map ← Source map
328
+ ├── src/
329
+ │ ├── index.jsx ← Main component entry
330
+ │ └── index.d.ts ← TypeScript source declarations
331
+ ├── README.md
332
+ └── package.json
333
+ ```
334
+
335
+ ---
336
+
337
+ ## 📝 Changelog
338
+
339
+ See [CHANGELOG.md](CHANGELOG.md) for full version history.
340
+
341
+ ---
342
+
343
+ ## 🤝 Contributing
344
+
345
+ 1. Fork the repository
346
+ 2. Create your feature branch: `git checkout -b feat/my-feature`
347
+ 3. Commit your changes: `git commit -m 'feat: add my feature'`
348
+ 4. Push to the branch: `git push origin feat/my-feature`
349
+ 5. Open a Pull Request
350
+
351
+ ---
352
+
353
+ <!--
354
+ ## 📄 License
355
+
356
+ MIT © [Swapnil Patil](https://github.com/swapnilhpatil)
357
+
358
+ ---
359
+ -->
360
+
361
+ ## 👤 Author
362
+
363
+ **Swapnil Patil**
364
+
365
+ [![GitHub](https://img.shields.io/badge/GitHub-swapnilhpatil-181717?logo=github&style=flat-square)](https://github.com/swapnilhpatil)
366
+ [![LinkedIn](https://img.shields.io/badge/LinkedIn-Swapnil%20Patil-0A66C2?logo=linkedin&style=flat-square)](https://www.linkedin.com/in/swapnilhpatil/)
@@ -0,0 +1,96 @@
1
+ import { ReactNode, CSSProperties } from "react";
2
+
3
+ // ─── Union Types ─────────────────────────────────────────────────────────────
4
+
5
+ export type LoaderSize = "sm" | "md" | "lg" | "xl";
6
+ export type LoaderVariant =
7
+ | "light"
8
+ | "dark"
9
+ | "blur"
10
+ | "transparent"
11
+ | "gradient";
12
+ export type LoaderType = "spinner" | "dots" | "pulse" | "ring" | "bar";
13
+ export type LoaderPosition = "center" | "top" | "bottom";
14
+
15
+ // ─── Props Interface ──────────────────────────────────────────────────────────
16
+
17
+ export interface LoaderOverlayProps {
18
+ /** Controls overlay visibility. Default: `true` */
19
+ show?: boolean;
20
+ /** Loading animation type. Default: `"spinner"` */
21
+ type?: LoaderType;
22
+ /** Size scale of the loader. Default: `"md"` */
23
+ size?: LoaderSize;
24
+ /** Overlay background & text theme. Default: `"dark"` */
25
+ variant?: LoaderVariant;
26
+ /** Accent color (any valid CSS color string). Default: `"#a78bfa"` */
27
+ color?: string;
28
+ /** Primary message shown below the loader. Default: `"Loading..."` */
29
+ message?: ReactNode;
30
+ /** Secondary hint string. Default: `""` */
31
+ submessage?: ReactNode;
32
+ /** `true` for `position: fixed` to cover the full viewport. Default: `false` */
33
+ fullScreen?: boolean;
34
+ /** CSS z-index value. Default: `999` */
35
+ zIndex?: number;
36
+ /** Overlay backdrop opacity (0–1). Default: `1` */
37
+ opacity?: number;
38
+ /** Backdrop blur strength in px. Default: `8` */
39
+ blur?: number;
40
+ /** Show an animated progress bar. Default: `false` */
41
+ showProgress?: boolean;
42
+ /** Progress bar value (0–100). Default: `0` */
43
+ progress?: number;
44
+ /** Show a ✕ close button. Default: `false` */
45
+ closable?: boolean;
46
+ /** Callback fired when the overlay is dismissed. */
47
+ onClose?: () => void;
48
+ /** Vertical alignment of the loader box. Default: `"center"` */
49
+ position?: LoaderPosition;
50
+ /** Apply fade-in animation on mount. Default: `true` */
51
+ animateIn?: boolean;
52
+ /** Auto-dismiss after N milliseconds. `0` to disable. Default: `0` */
53
+ timeout?: number;
54
+ /** Replace the loader icon with custom React content. */
55
+ children?: ReactNode;
56
+ /** Dismiss the overlay on backdrop click. Default: `false` */
57
+ closeOnOutsideClick?: boolean;
58
+ /** Callback fired when user clicks outside the loader box. */
59
+ onOutsideClick?: () => void;
60
+ }
61
+
62
+ // ─── Icon Component Type ─────────────────────────────────────────────────────
63
+
64
+ export interface IconProps {
65
+ /** Icon size in px */
66
+ s: number;
67
+ /** Accent color */
68
+ color: string;
69
+ }
70
+
71
+ // ─── Constants ───────────────────────────────────────────────────────────────
72
+
73
+ export declare const SIZES: Record<
74
+ LoaderSize,
75
+ { s: number; f: string; g: string }
76
+ >;
77
+ export declare const VARIANTS: Record<
78
+ LoaderVariant,
79
+ { bg: string; tx: string }
80
+ >;
81
+ export declare const ANIM_CSS: string;
82
+
83
+ // ─── Icon Components ─────────────────────────────────────────────────────────
84
+
85
+ export declare const SpinIcon: (props: IconProps) => JSX.Element;
86
+ export declare const DotsIcon: (props: IconProps) => JSX.Element;
87
+ export declare const PulseIcon: (props: IconProps) => JSX.Element;
88
+ export declare const RingIcon: (props: IconProps) => JSX.Element;
89
+ export declare const BarIcon: (props: IconProps) => JSX.Element;
90
+ export declare const ICONS: Record<LoaderType, (props: IconProps) => JSX.Element>;
91
+
92
+ // ─── Default Export ───────────────────────────────────────────────────────────
93
+
94
+ declare function LoaderOverlay(props: LoaderOverlayProps): JSX.Element | null;
95
+ export default LoaderOverlay;
96
+ export { LoaderOverlay };
@@ -0,0 +1,335 @@
1
+ import { jsx as t, jsxs as l, Fragment as N } from "react/jsx-runtime";
2
+ import { useState as W, useRef as k, useEffect as d } from "react";
3
+ const w = {
4
+ sm: { s: 28, f: "11px", g: "8px" },
5
+ md: { s: 44, f: "13px", g: "12px" },
6
+ lg: { s: 64, f: "15px", g: "16px" },
7
+ xl: { s: 88, f: "18px", g: "22px" }
8
+ }, F = {
9
+ light: { bg: "rgba(255,255,255,0.9)", tx: "#1a1a2e" },
10
+ dark: { bg: "rgba(10,10,20,0.92)", tx: "#f0f0f0" },
11
+ blur: { bg: "rgba(20,15,50,0.5)", tx: "#fff" },
12
+ transparent: { bg: "rgba(0,0,0,0)", tx: "#f0f0f0" },
13
+ gradient: {
14
+ bg: "linear-gradient(135deg,rgba(15,15,40,.95),rgba(50,10,80,.95))",
15
+ tx: "#e8d5ff"
16
+ }
17
+ }, V = `
18
+ @keyframes lSpin{to{transform:rotate(360deg)}}
19
+ @keyframes lBounce{0%,80%,100%{transform:scale(.6);opacity:.4}40%{transform:scale(1);opacity:1}}
20
+ @keyframes lPR{0%{transform:scale(.8);opacity:.6}100%{transform:scale(1.8);opacity:0}}
21
+ @keyframes lPC{0%,100%{transform:scale(.9)}50%{transform:scale(1.1)}}
22
+ @keyframes lBar{0%,100%{height:30%;opacity:.4}50%{height:100%;opacity:1}}
23
+ @keyframes lFI{from{opacity:0}to{opacity:1}}
24
+ @keyframes lShim{0%{background-position:0 50%}100%{background-position:200% 50%}}
25
+ `, Z = ({ s: e, color: n }) => /* @__PURE__ */ t(
26
+ "svg",
27
+ {
28
+ width: e,
29
+ height: e,
30
+ viewBox: "0 0 50 50",
31
+ style: { animation: "lSpin .9s linear infinite" },
32
+ children: /* @__PURE__ */ t(
33
+ "circle",
34
+ {
35
+ cx: "25",
36
+ cy: "25",
37
+ r: "20",
38
+ fill: "none",
39
+ stroke: n,
40
+ strokeWidth: "4",
41
+ strokeLinecap: "round",
42
+ strokeDasharray: "90 60"
43
+ }
44
+ )
45
+ }
46
+ ), _ = ({ s: e, color: n }) => /* @__PURE__ */ t("div", { style: { display: "flex", gap: e * 0.18, alignItems: "center" }, children: [0, 1, 2].map((i) => /* @__PURE__ */ t(
47
+ "div",
48
+ {
49
+ style: {
50
+ width: e * 0.22,
51
+ height: e * 0.22,
52
+ borderRadius: "50%",
53
+ background: n,
54
+ animation: `lBounce 1.2s ease-in-out ${i * 0.2}s infinite`
55
+ }
56
+ },
57
+ i
58
+ )) }), q = ({ s: e, color: n }) => /* @__PURE__ */ l("div", { style: { position: "relative", width: e, height: e }, children: [
59
+ /* @__PURE__ */ t(
60
+ "div",
61
+ {
62
+ style: {
63
+ position: "absolute",
64
+ inset: 0,
65
+ borderRadius: "50%",
66
+ background: n,
67
+ opacity: 0.2,
68
+ animation: "lPR 1.4s ease-out infinite"
69
+ }
70
+ }
71
+ ),
72
+ /* @__PURE__ */ t(
73
+ "div",
74
+ {
75
+ style: {
76
+ position: "absolute",
77
+ inset: "20%",
78
+ borderRadius: "50%",
79
+ background: n,
80
+ animation: "lPC 1.4s ease-in-out infinite"
81
+ }
82
+ }
83
+ )
84
+ ] }), C = ({ s: e, color: n }) => /* @__PURE__ */ t(
85
+ "div",
86
+ {
87
+ style: {
88
+ width: e,
89
+ height: e,
90
+ borderRadius: "50%",
91
+ border: `${e * 0.08}px solid ${n}22`,
92
+ borderTop: `${e * 0.08}px solid ${n}`,
93
+ animation: "lSpin .75s linear infinite"
94
+ }
95
+ }
96
+ ), G = ({ s: e, color: n }) => /* @__PURE__ */ t(
97
+ "div",
98
+ {
99
+ style: {
100
+ display: "flex",
101
+ gap: e * 0.1,
102
+ alignItems: "flex-end",
103
+ height: e * 0.7
104
+ },
105
+ children: [0, 1, 2, 3].map((i) => /* @__PURE__ */ t(
106
+ "div",
107
+ {
108
+ style: {
109
+ width: e * 0.15,
110
+ background: n,
111
+ borderRadius: 3,
112
+ animation: `lBar 1s ease-in-out ${i * 0.15}s infinite`
113
+ }
114
+ },
115
+ i
116
+ ))
117
+ }
118
+ ), B = {
119
+ spinner: Z,
120
+ dots: _,
121
+ pulse: q,
122
+ ring: C,
123
+ bar: G
124
+ };
125
+ function Q({
126
+ show: e = !0,
127
+ type: n = "spinner",
128
+ size: i = "md",
129
+ variant: o = "dark",
130
+ color: r = "#a78bfa",
131
+ message: S = "Loading...",
132
+ submessage: v = "",
133
+ fullScreen: z = !1,
134
+ zIndex: L = 999,
135
+ opacity: M = 1,
136
+ blur: c = 8,
137
+ showProgress: P = !1,
138
+ progress: R = 0,
139
+ closable: T = !1,
140
+ onClose: u = () => {
141
+ },
142
+ position: I = "center",
143
+ animateIn: A = !0,
144
+ timeout: m = 0,
145
+ children: E = null,
146
+ closeOnOutsideClick: y = !1,
147
+ onOutsideClick: h = () => {
148
+ }
149
+ }) {
150
+ const [s, p] = W(e), x = k(null), f = k(u), $ = k(h);
151
+ if (d(() => {
152
+ f.current = u;
153
+ }, [u]), d(() => {
154
+ $.current = h;
155
+ }, [h]), d(() => {
156
+ p(e);
157
+ }, [e]), d(() => {
158
+ if (!s || !y) return;
159
+ const g = (D) => {
160
+ x.current && !x.current.contains(D.target) && ($.current(), p(!1), f.current());
161
+ };
162
+ return document.addEventListener("mousedown", g), () => document.removeEventListener("mousedown", g);
163
+ }, [s, y]), d(() => {
164
+ if (m > 0 && s) {
165
+ const g = setTimeout(() => {
166
+ p(!1), f.current();
167
+ }, m);
168
+ return () => clearTimeout(g);
169
+ }
170
+ }, [m, s]), !s) return null;
171
+ const b = w[i] || w.md, a = F[o] || F.dark, j = B[n] || B.spinner;
172
+ return /* @__PURE__ */ l(N, { children: [
173
+ /* @__PURE__ */ t("style", { children: V }),
174
+ /* @__PURE__ */ t(
175
+ "div",
176
+ {
177
+ style: {
178
+ position: z ? "fixed" : "absolute",
179
+ inset: 0,
180
+ zIndex: L,
181
+ display: "flex",
182
+ alignItems: { center: "center", top: "flex-start", bottom: "flex-end" }[I] || "center",
183
+ justifyContent: "center",
184
+ padding: I !== "center" ? 40 : 0,
185
+ background: a.bg,
186
+ backdropFilter: c > 0 ? `blur(${c}px)` : "none",
187
+ WebkitBackdropFilter: c > 0 ? `blur(${c}px)` : "none",
188
+ opacity: M,
189
+ animation: A ? "lFI .25s ease" : "none"
190
+ },
191
+ children: /* @__PURE__ */ l(
192
+ "div",
193
+ {
194
+ ref: x,
195
+ style: {
196
+ display: "flex",
197
+ flexDirection: "column",
198
+ alignItems: "center",
199
+ gap: b.g,
200
+ padding: "28px 36px",
201
+ borderRadius: 16,
202
+ position: "relative",
203
+ background: o === "transparent" ? "transparent" : o === "gradient" ? "rgba(255,255,255,.04)" : "rgba(255,255,255,.07)",
204
+ border: o === "transparent" ? "none" : `1px solid ${r}25`,
205
+ boxShadow: o === "transparent" ? "none" : `0 8px 40px ${r}15`
206
+ },
207
+ children: [
208
+ T && /* @__PURE__ */ t(
209
+ "button",
210
+ {
211
+ onClick: () => {
212
+ p(!1), f.current();
213
+ },
214
+ style: {
215
+ position: "absolute",
216
+ top: 8,
217
+ right: 10,
218
+ background: "none",
219
+ border: "none",
220
+ cursor: "pointer",
221
+ color: a.tx,
222
+ fontSize: 16,
223
+ opacity: 0.45,
224
+ padding: "2px 6px",
225
+ borderRadius: 6
226
+ },
227
+ children: "✕"
228
+ }
229
+ ),
230
+ E || /* @__PURE__ */ t(j, { s: b.s, color: r }),
231
+ S && /* @__PURE__ */ t(
232
+ "p",
233
+ {
234
+ style: {
235
+ margin: 0,
236
+ color: a.tx,
237
+ fontSize: b.f,
238
+ fontWeight: 600,
239
+ letterSpacing: ".04em",
240
+ fontFamily: "system-ui,sans-serif"
241
+ },
242
+ children: S
243
+ }
244
+ ),
245
+ v && /* @__PURE__ */ t(
246
+ "p",
247
+ {
248
+ style: {
249
+ margin: 0,
250
+ color: a.tx,
251
+ fontSize: "11px",
252
+ opacity: 0.5,
253
+ fontFamily: "system-ui,sans-serif"
254
+ },
255
+ children: v
256
+ }
257
+ ),
258
+ P && /* @__PURE__ */ l("div", { style: { width: 140, marginTop: 2 }, children: [
259
+ /* @__PURE__ */ t(
260
+ "div",
261
+ {
262
+ style: {
263
+ width: "100%",
264
+ height: 4,
265
+ background: `${r}22`,
266
+ borderRadius: 99,
267
+ overflow: "hidden"
268
+ },
269
+ children: /* @__PURE__ */ t(
270
+ "div",
271
+ {
272
+ style: {
273
+ height: "100%",
274
+ width: `${Math.min(100, Math.max(0, R))}%`,
275
+ background: `linear-gradient(90deg,${r},${r}88,${r})`,
276
+ backgroundSize: "200% 100%",
277
+ borderRadius: 99,
278
+ transition: "width .3s ease",
279
+ animation: "lShim 1.5s linear infinite"
280
+ }
281
+ }
282
+ )
283
+ }
284
+ ),
285
+ /* @__PURE__ */ l(
286
+ "p",
287
+ {
288
+ style: {
289
+ margin: "3px 0 0",
290
+ textAlign: "right",
291
+ color: a.tx,
292
+ opacity: 0.4,
293
+ fontSize: 10,
294
+ fontFamily: "monospace"
295
+ },
296
+ children: [
297
+ R,
298
+ "%"
299
+ ]
300
+ }
301
+ )
302
+ ] }),
303
+ y && /* @__PURE__ */ t(
304
+ "p",
305
+ {
306
+ style: {
307
+ margin: "2px 0 0",
308
+ color: a.tx,
309
+ opacity: 0.3,
310
+ fontSize: 9,
311
+ fontFamily: "monospace"
312
+ },
313
+ children: "click outside to dismiss"
314
+ }
315
+ )
316
+ ]
317
+ }
318
+ )
319
+ }
320
+ )
321
+ ] });
322
+ }
323
+ export {
324
+ V as ANIM_CSS,
325
+ G as BarIcon,
326
+ _ as DotsIcon,
327
+ B as ICONS,
328
+ q as PulseIcon,
329
+ C as RingIcon,
330
+ w as SIZES,
331
+ Z as SpinIcon,
332
+ F as VARIANTS,
333
+ Q as default
334
+ };
335
+ //# sourceMappingURL=loader-overlay.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader-overlay.es.js","sources":["../src/constants/index.js","../src/components/icons/SpinIcon.jsx","../src/components/icons/DotsIcon.jsx","../src/components/icons/PulseIcon.jsx","../src/components/icons/RingIcon.jsx","../src/components/icons/BarIcon.jsx","../src/components/Icons.jsx","../src/index.jsx"],"sourcesContent":["export const SIZES = {\n sm: { s: 28, f: \"11px\", g: \"8px\" },\n md: { s: 44, f: \"13px\", g: \"12px\" },\n lg: { s: 64, f: \"15px\", g: \"16px\" },\n xl: { s: 88, f: \"18px\", g: \"22px\" },\n};\n\nexport const VARIANTS = {\n light: { bg: \"rgba(255,255,255,0.9)\", tx: \"#1a1a2e\" },\n dark: { bg: \"rgba(10,10,20,0.92)\", tx: \"#f0f0f0\" },\n blur: { bg: \"rgba(20,15,50,0.5)\", tx: \"#fff\" },\n transparent: { bg: \"rgba(0,0,0,0)\", tx: \"#f0f0f0\" },\n gradient: {\n bg: \"linear-gradient(135deg,rgba(15,15,40,.95),rgba(50,10,80,.95))\",\n tx: \"#e8d5ff\",\n },\n};\n\nexport const ANIM_CSS = `\n @keyframes lSpin{to{transform:rotate(360deg)}}\n @keyframes lBounce{0%,80%,100%{transform:scale(.6);opacity:.4}40%{transform:scale(1);opacity:1}}\n @keyframes lPR{0%{transform:scale(.8);opacity:.6}100%{transform:scale(1.8);opacity:0}}\n @keyframes lPC{0%,100%{transform:scale(.9)}50%{transform:scale(1.1)}}\n @keyframes lBar{0%,100%{height:30%;opacity:.4}50%{height:100%;opacity:1}}\n @keyframes lFI{from{opacity:0}to{opacity:1}}\n @keyframes lShim{0%{background-position:0 50%}100%{background-position:200% 50%}}\n`;\n","import React from \"react\";\n\nconst SpinIcon = ({ s, color }) => {\n return (\n <svg\n width={s}\n height={s}\n viewBox=\"0 0 50 50\"\n style={{ animation: \"lSpin .9s linear infinite\" }}\n >\n <circle\n cx=\"25\"\n cy=\"25\"\n r=\"20\"\n fill=\"none\"\n stroke={color}\n strokeWidth=\"4\"\n strokeLinecap=\"round\"\n strokeDasharray=\"90 60\"\n />\n </svg>\n );\n};\n\nexport default SpinIcon;\n","import React from \"react\";\n\nconst DotsIcon = ({ s, color }) => {\n return (\n <div style={{ display: \"flex\", gap: s * 0.18, alignItems: \"center\" }}>\n {[0, 1, 2].map((i) => (\n <div\n key={i}\n style={{\n width: s * 0.22,\n height: s * 0.22,\n borderRadius: \"50%\",\n background: color,\n animation: `lBounce 1.2s ease-in-out ${i * 0.2}s infinite`,\n }}\n />\n ))}\n </div>\n );\n};\n\nexport default DotsIcon;\n","import React from \"react\";\n\nconst PulseIcon = ({ s, color }) => {\n return (\n <div style={{ position: \"relative\", width: s, height: s }}>\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n borderRadius: \"50%\",\n background: color,\n opacity: 0.2,\n animation: \"lPR 1.4s ease-out infinite\",\n }}\n />\n <div\n style={{\n position: \"absolute\",\n inset: \"20%\",\n borderRadius: \"50%\",\n background: color,\n animation: \"lPC 1.4s ease-in-out infinite\",\n }}\n />\n </div>\n );\n};\n\nexport default PulseIcon;\n","import React from \"react\";\n\nconst RingIcon = ({ s, color }) => {\n return (\n <div\n style={{\n width: s,\n height: s,\n borderRadius: \"50%\",\n border: `${s * 0.08}px solid ${color}22`,\n borderTop: `${s * 0.08}px solid ${color}`,\n animation: \"lSpin .75s linear infinite\",\n }}\n />\n );\n};\n\nexport default RingIcon;\n","import React from \"react\";\n\nconst BarIcon = ({ s, color }) => {\n return (\n <div\n style={{\n display: \"flex\",\n gap: s * 0.1,\n alignItems: \"flex-end\",\n height: s * 0.7,\n }}\n >\n {[0, 1, 2, 3].map((i) => (\n <div\n key={i}\n style={{\n width: s * 0.15,\n background: color,\n borderRadius: 3,\n animation: `lBar 1s ease-in-out ${i * 0.15}s infinite`,\n }}\n />\n ))}\n </div>\n );\n};\n\nexport default BarIcon;\n","import SpinIcon from \"./icons/SpinIcon.jsx\";\nimport DotsIcon from \"./icons/DotsIcon.jsx\";\nimport PulseIcon from \"./icons/PulseIcon.jsx\";\nimport RingIcon from \"./icons/RingIcon.jsx\";\nimport BarIcon from \"./icons/BarIcon.jsx\";\n\nexport const ICONS = {\n spinner: SpinIcon,\n dots: DotsIcon,\n pulse: PulseIcon,\n ring: RingIcon,\n bar: BarIcon,\n};\n\nexport { SpinIcon, DotsIcon, PulseIcon, RingIcon, BarIcon };\nexport default ICONS;\n","import React, { useState, useRef, useEffect } from \"react\";\nimport { SIZES, VARIANTS, ANIM_CSS } from \"./constants/index.js\";\nimport { ICONS, SpinIcon, DotsIcon, PulseIcon, RingIcon, BarIcon } from \"./components/Icons.jsx\";\n\n// ─── Named exports for tree-shaking ─────────────────────────────────────────\nexport { SIZES, VARIANTS, ANIM_CSS };\nexport { ICONS, SpinIcon, DotsIcon, PulseIcon, RingIcon, BarIcon };\n\n/**\n * A highly customizable, accessible loading overlay.\n * @param {import('./types/index.js').LoaderOverlayProps} props\n */\nexport default function LoaderOverlay({\n show = true,\n type = \"spinner\",\n size = \"md\",\n variant = \"dark\",\n color = \"#a78bfa\",\n message = \"Loading...\",\n submessage = \"\",\n fullScreen = false,\n zIndex = 999,\n opacity = 1,\n blur = 8,\n showProgress = false,\n progress = 0,\n closable = false,\n onClose = () => {},\n position = \"center\",\n animateIn = true,\n timeout = 0,\n children = null,\n closeOnOutsideClick = false,\n onOutsideClick = () => {},\n}) {\n const [vis, setVis] = useState(show);\n const boxRef = useRef(null);\n const closeRef = useRef(onClose);\n const outsideRef = useRef(onOutsideClick);\n\n useEffect(() => {\n closeRef.current = onClose;\n }, [onClose]);\n useEffect(() => {\n outsideRef.current = onOutsideClick;\n }, [onOutsideClick]);\n useEffect(() => {\n setVis(show);\n }, [show]);\n\n useEffect(() => {\n if (!vis || !closeOnOutsideClick) return;\n const h = (e) => {\n if (boxRef.current && !boxRef.current.contains(e.target)) {\n outsideRef.current();\n setVis(false);\n closeRef.current();\n }\n };\n document.addEventListener(\"mousedown\", h);\n return () => document.removeEventListener(\"mousedown\", h);\n }, [vis, closeOnOutsideClick]);\n\n useEffect(() => {\n if (timeout > 0 && vis) {\n const t = setTimeout(() => {\n setVis(false);\n closeRef.current();\n }, timeout);\n return () => clearTimeout(t);\n }\n }, [timeout, vis]);\n\n if (!vis) return null;\n\n const sc = SIZES[size] || SIZES.md;\n const vc = VARIANTS[variant] || VARIANTS.dark;\n const Icon = ICONS[type] || ICONS.spinner;\n const alignMap = { center: \"center\", top: \"flex-start\", bottom: \"flex-end\" };\n\n return (\n <>\n <style>{ANIM_CSS}</style>\n <div\n style={{\n position: fullScreen ? \"fixed\" : \"absolute\",\n inset: 0,\n zIndex,\n display: \"flex\",\n alignItems: alignMap[position] || \"center\",\n justifyContent: \"center\",\n padding: position !== \"center\" ? 40 : 0,\n background: vc.bg,\n backdropFilter: blur > 0 ? `blur(${blur}px)` : \"none\",\n WebkitBackdropFilter: blur > 0 ? `blur(${blur}px)` : \"none\",\n opacity,\n animation: animateIn ? \"lFI .25s ease\" : \"none\",\n }}\n >\n <div\n ref={boxRef}\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: sc.g,\n padding: \"28px 36px\",\n borderRadius: 16,\n position: \"relative\",\n background:\n variant === \"transparent\"\n ? \"transparent\"\n : variant === \"gradient\"\n ? \"rgba(255,255,255,.04)\"\n : \"rgba(255,255,255,.07)\",\n border: variant === \"transparent\" ? \"none\" : `1px solid ${color}25`,\n boxShadow:\n variant === \"transparent\" ? \"none\" : `0 8px 40px ${color}15`,\n }}\n >\n {closable && (\n <button\n onClick={() => {\n setVis(false);\n closeRef.current();\n }}\n style={{\n position: \"absolute\",\n top: 8,\n right: 10,\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n color: vc.tx,\n fontSize: 16,\n opacity: 0.45,\n padding: \"2px 6px\",\n borderRadius: 6,\n }}\n >\n ✕\n </button>\n )}\n {children || <Icon s={sc.s} color={color} />}\n {message && (\n <p\n style={{\n margin: 0,\n color: vc.tx,\n fontSize: sc.f,\n fontWeight: 600,\n letterSpacing: \".04em\",\n fontFamily: \"system-ui,sans-serif\",\n }}\n >\n {message}\n </p>\n )}\n {submessage && (\n <p\n style={{\n margin: 0,\n color: vc.tx,\n fontSize: \"11px\",\n opacity: 0.5,\n fontFamily: \"system-ui,sans-serif\",\n }}\n >\n {submessage}\n </p>\n )}\n {showProgress && (\n <div style={{ width: 140, marginTop: 2 }}>\n <div\n style={{\n width: \"100%\",\n height: 4,\n background: `${color}22`,\n borderRadius: 99,\n overflow: \"hidden\",\n }}\n >\n <div\n style={{\n height: \"100%\",\n width: `${Math.min(100, Math.max(0, progress))}%`,\n background: `linear-gradient(90deg,${color},${color}88,${color})`,\n backgroundSize: \"200% 100%\",\n borderRadius: 99,\n transition: \"width .3s ease\",\n animation: \"lShim 1.5s linear infinite\",\n }}\n />\n </div>\n <p\n style={{\n margin: \"3px 0 0\",\n textAlign: \"right\",\n color: vc.tx,\n opacity: 0.4,\n fontSize: 10,\n fontFamily: \"monospace\",\n }}\n >\n {progress}%\n </p>\n </div>\n )}\n {closeOnOutsideClick && (\n <p\n style={{\n margin: \"2px 0 0\",\n color: vc.tx,\n opacity: 0.3,\n fontSize: 9,\n fontFamily: \"monospace\",\n }}\n >\n click outside to dismiss\n </p>\n )}\n </div>\n </div>\n </>\n );\n}\n"],"names":["SIZES","VARIANTS","ANIM_CSS","SpinIcon","s","color","jsx","DotsIcon","PulseIcon","jsxs","RingIcon","BarIcon","ICONS","LoaderOverlay","show","type","size","variant","message","submessage","fullScreen","zIndex","opacity","blur","showProgress","progress","closable","onClose","position","animateIn","timeout","children","closeOnOutsideClick","onOutsideClick","vis","setVis","useState","boxRef","useRef","closeRef","outsideRef","useEffect","h","e","t","sc","vc","Icon","Fragment"],"mappings":";;AAAY,MAACA,IAAQ;AAAA,EACnB,IAAI,EAAE,GAAG,IAAI,GAAG,QAAQ,GAAG,MAAK;AAAA,EAChC,IAAI,EAAE,GAAG,IAAI,GAAG,QAAQ,GAAG,OAAM;AAAA,EACjC,IAAI,EAAE,GAAG,IAAI,GAAG,QAAQ,GAAG,OAAM;AAAA,EACjC,IAAI,EAAE,GAAG,IAAI,GAAG,QAAQ,GAAG,OAAM;AACnC,GAEaC,IAAW;AAAA,EACtB,OAAO,EAAE,IAAI,yBAAyB,IAAI,UAAS;AAAA,EACnD,MAAM,EAAE,IAAI,uBAAuB,IAAI,UAAS;AAAA,EAChD,MAAM,EAAE,IAAI,sBAAsB,IAAI,OAAM;AAAA,EAC5C,aAAa,EAAE,IAAI,iBAAiB,IAAI,UAAS;AAAA,EACjD,UAAU;AAAA,IACR,IAAI;AAAA,IACJ,IAAI;AAAA,EACR;AACA,GAEaC,IAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GChBlBC,IAAW,CAAC,EAAE,GAAAC,GAAG,OAAAC,QAEnB,gBAAAC;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,OAAOF;AAAA,IACP,QAAQA;AAAA,IACR,SAAQ;AAAA,IACR,OAAO,EAAE,WAAW,4BAAA;AAAA,IAEpB,UAAA,gBAAAE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,IAAG;AAAA,QACH,IAAG;AAAA,QACH,GAAE;AAAA,QACF,MAAK;AAAA,QACL,QAAQD;AAAA,QACR,aAAY;AAAA,QACZ,eAAc;AAAA,QACd,iBAAgB;AAAA,MAAA;AAAA,IAAA;AAAA,EAClB;AAAA,GCjBAE,IAAW,CAAC,EAAE,GAAAH,GAAG,OAAAC,0BAElB,OAAA,EAAI,OAAO,EAAE,SAAS,QAAQ,KAAKD,IAAI,MAAM,YAAY,SAAA,GACvD,WAAC,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,MACd,gBAAAE;AAAA,EAAC;AAAA,EAAA;AAAA,IAEC,OAAO;AAAA,MACL,OAAOF,IAAI;AAAA,MACX,QAAQA,IAAI;AAAA,MACZ,cAAc;AAAA,MACd,YAAYC;AAAA,MACZ,WAAW,4BAA4B,IAAI,GAAG;AAAA,IAAA;AAAA,EAChD;AAAA,EAPK;AAAA,CASR,GACH,GCfEG,IAAY,CAAC,EAAE,GAAAJ,GAAG,OAAAC,QAEpB,gBAAAI,EAAC,OAAA,EAAI,OAAO,EAAE,UAAU,YAAY,OAAOL,GAAG,QAAQA,EAAA,GACpD,UAAA;AAAA,EAAA,gBAAAE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,OAAO;AAAA,QACL,UAAU;AAAA,QACV,OAAO;AAAA,QACP,cAAc;AAAA,QACd,YAAYD;AAAA,QACZ,SAAS;AAAA,QACT,WAAW;AAAA,MAAA;AAAA,IACb;AAAA,EAAA;AAAA,EAEF,gBAAAC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,OAAO;AAAA,QACL,UAAU;AAAA,QACV,OAAO;AAAA,QACP,cAAc;AAAA,QACd,YAAYD;AAAA,QACZ,WAAW;AAAA,MAAA;AAAA,IACb;AAAA,EAAA;AACF,GACF,GCtBEK,IAAW,CAAC,EAAE,GAAAN,GAAG,OAAAC,QAEnB,gBAAAC;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,OAAO;AAAA,MACL,OAAOF;AAAA,MACP,QAAQA;AAAA,MACR,cAAc;AAAA,MACd,QAAQ,GAAGA,IAAI,IAAI,YAAYC,CAAK;AAAA,MACpC,WAAW,GAAGD,IAAI,IAAI,YAAYC,CAAK;AAAA,MACvC,WAAW;AAAA,IAAA;AAAA,EACb;AAAA,GCVAM,IAAU,CAAC,EAAE,GAAAP,GAAG,OAAAC,QAElB,gBAAAC;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,OAAO;AAAA,MACL,SAAS;AAAA,MACT,KAAKF,IAAI;AAAA,MACT,YAAY;AAAA,MACZ,QAAQA,IAAI;AAAA,IAAA;AAAA,IAGb,UAAA,CAAC,GAAG,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,MACjB,gBAAAE;AAAA,MAAC;AAAA,MAAA;AAAA,QAEC,OAAO;AAAA,UACL,OAAOF,IAAI;AAAA,UACX,YAAYC;AAAA,UACZ,cAAc;AAAA,UACd,WAAW,uBAAuB,IAAI,IAAI;AAAA,QAAA;AAAA,MAC5C;AAAA,MANK;AAAA,IAAA,CAQR;AAAA,EAAA;AAAA,GChBMO,IAAQ;AAAA,EACnB,SAAST;AAAA,EACT,MAAMI;AAAA,EACN,OAAOC;AAAA,EACP,MAAME;AAAA,EACN,KAAKC;AACP;ACAA,SAAwBE,EAAc;AAAA,EACpC,MAAAC,IAAO;AAAA,EACP,MAAAC,IAAO;AAAA,EACP,MAAAC,IAAO;AAAA,EACP,SAAAC,IAAU;AAAA,EACV,OAAAZ,IAAQ;AAAA,EACR,SAAAa,IAAU;AAAA,EACV,YAAAC,IAAa;AAAA,EACb,YAAAC,IAAa;AAAA,EACb,QAAAC,IAAS;AAAA,EACT,SAAAC,IAAU;AAAA,EACV,MAAAC,IAAO;AAAA,EACP,cAAAC,IAAe;AAAA,EACf,UAAAC,IAAW;AAAA,EACX,UAAAC,IAAW;AAAA,EACX,SAAAC,IAAU,MAAM;AAAA,EAAC;AAAA,EACjB,UAAAC,IAAW;AAAA,EACX,WAAAC,IAAY;AAAA,EACZ,SAAAC,IAAU;AAAA,EACV,UAAAC,IAAW;AAAA,EACX,qBAAAC,IAAsB;AAAA,EACtB,gBAAAC,IAAiB,MAAM;AAAA,EAAC;AAC1B,GAAG;AACD,QAAM,CAACC,GAAKC,CAAM,IAAIC,EAAStB,CAAI,GAC7BuB,IAASC,EAAO,IAAI,GACpBC,IAAWD,EAAOX,CAAO,GACzBa,IAAaF,EAAOL,CAAc;AAmCxC,MAjCAQ,EAAU,MAAM;AACd,IAAAF,EAAS,UAAUZ;AAAA,EACrB,GAAG,CAACA,CAAO,CAAC,GACZc,EAAU,MAAM;AACd,IAAAD,EAAW,UAAUP;AAAA,EACvB,GAAG,CAACA,CAAc,CAAC,GACnBQ,EAAU,MAAM;AACd,IAAAN,EAAOrB,CAAI;AAAA,EACb,GAAG,CAACA,CAAI,CAAC,GAET2B,EAAU,MAAM;AACd,QAAI,CAACP,KAAO,CAACF,EAAqB;AAClC,UAAMU,IAAI,CAACC,MAAM;AACf,MAAIN,EAAO,WAAW,CAACA,EAAO,QAAQ,SAASM,EAAE,MAAM,MACrDH,EAAW,QAAA,GACXL,EAAO,EAAK,GACZI,EAAS,QAAA;AAAA,IAEb;AACA,oBAAS,iBAAiB,aAAaG,CAAC,GACjC,MAAM,SAAS,oBAAoB,aAAaA,CAAC;AAAA,EAC1D,GAAG,CAACR,GAAKF,CAAmB,CAAC,GAE7BS,EAAU,MAAM;AACd,QAAIX,IAAU,KAAKI,GAAK;AACtB,YAAMU,IAAI,WAAW,MAAM;AACzB,QAAAT,EAAO,EAAK,GACZI,EAAS,QAAA;AAAA,MACX,GAAGT,CAAO;AACV,aAAO,MAAM,aAAac,CAAC;AAAA,IAC7B;AAAA,EACF,GAAG,CAACd,GAASI,CAAG,CAAC,GAEb,CAACA,EAAK,QAAO;AAEjB,QAAMW,IAAK7C,EAAMgB,CAAI,KAAKhB,EAAM,IAC1B8C,IAAK7C,EAASgB,CAAO,KAAKhB,EAAS,MACnC8C,IAAOnC,EAAMG,CAAI,KAAKH,EAAM;AAGlC,SACE,gBAAAH,EAAAuC,GAAA,EACE,UAAA;AAAA,IAAA,gBAAA1C,EAAC,WAAO,UAAAJ,EAAA,CAAS;AAAA,IACjB,gBAAAI;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,OAAO;AAAA,UACL,UAAUc,IAAa,UAAU;AAAA,UACjC,OAAO;AAAA,UACP,QAAAC;AAAA,UACA,SAAS;AAAA,UACT,YAXS,EAAE,QAAQ,UAAU,KAAK,cAAc,QAAQ,WAAA,EAWnCO,CAAQ,KAAK;AAAA,UAClC,gBAAgB;AAAA,UAChB,SAASA,MAAa,WAAW,KAAK;AAAA,UACtC,YAAYkB,EAAG;AAAA,UACf,gBAAgBvB,IAAO,IAAI,QAAQA,CAAI,QAAQ;AAAA,UAC/C,sBAAsBA,IAAO,IAAI,QAAQA,CAAI,QAAQ;AAAA,UACrD,SAAAD;AAAA,UACA,WAAWO,IAAY,kBAAkB;AAAA,QAAA;AAAA,QAG3C,UAAA,gBAAApB;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,KAAK4B;AAAA,YACL,OAAO;AAAA,cACL,SAAS;AAAA,cACT,eAAe;AAAA,cACf,YAAY;AAAA,cACZ,KAAKQ,EAAG;AAAA,cACR,SAAS;AAAA,cACT,cAAc;AAAA,cACd,UAAU;AAAA,cACV,YACE5B,MAAY,gBACR,gBACAA,MAAY,aACV,0BACA;AAAA,cACR,QAAQA,MAAY,gBAAgB,SAAS,aAAaZ,CAAK;AAAA,cAC/D,WACEY,MAAY,gBAAgB,SAAS,cAAcZ,CAAK;AAAA,YAAA;AAAA,YAG3D,UAAA;AAAA,cAAAqB,KACC,gBAAApB;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,SAAS,MAAM;AACb,oBAAA6B,EAAO,EAAK,GACZI,EAAS,QAAA;AAAA,kBACX;AAAA,kBACA,OAAO;AAAA,oBACL,UAAU;AAAA,oBACV,KAAK;AAAA,oBACL,OAAO;AAAA,oBACP,YAAY;AAAA,oBACZ,QAAQ;AAAA,oBACR,QAAQ;AAAA,oBACR,OAAOO,EAAG;AAAA,oBACV,UAAU;AAAA,oBACV,SAAS;AAAA,oBACT,SAAS;AAAA,oBACT,cAAc;AAAA,kBAAA;AAAA,kBAEjB,UAAA;AAAA,gBAAA;AAAA,cAAA;AAAA,cAIFf,KAAY,gBAAAzB,EAACyC,GAAA,EAAK,GAAGF,EAAG,GAAG,OAAAxC,GAAc;AAAA,cACzCa,KACC,gBAAAZ;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,OAAO;AAAA,oBACL,QAAQ;AAAA,oBACR,OAAOwC,EAAG;AAAA,oBACV,UAAUD,EAAG;AAAA,oBACb,YAAY;AAAA,oBACZ,eAAe;AAAA,oBACf,YAAY;AAAA,kBAAA;AAAA,kBAGb,UAAA3B;AAAA,gBAAA;AAAA,cAAA;AAAA,cAGJC,KACC,gBAAAb;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,OAAO;AAAA,oBACL,QAAQ;AAAA,oBACR,OAAOwC,EAAG;AAAA,oBACV,UAAU;AAAA,oBACV,SAAS;AAAA,oBACT,YAAY;AAAA,kBAAA;AAAA,kBAGb,UAAA3B;AAAA,gBAAA;AAAA,cAAA;AAAA,cAGJK,uBACE,OAAA,EAAI,OAAO,EAAE,OAAO,KAAK,WAAW,EAAA,GACnC,UAAA;AAAA,gBAAA,gBAAAlB;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,OAAO;AAAA,sBACL,OAAO;AAAA,sBACP,QAAQ;AAAA,sBACR,YAAY,GAAGD,CAAK;AAAA,sBACpB,cAAc;AAAA,sBACd,UAAU;AAAA,oBAAA;AAAA,oBAGZ,UAAA,gBAAAC;AAAA,sBAAC;AAAA,sBAAA;AAAA,wBACC,OAAO;AAAA,0BACL,QAAQ;AAAA,0BACR,OAAO,GAAG,KAAK,IAAI,KAAK,KAAK,IAAI,GAAGmB,CAAQ,CAAC,CAAC;AAAA,0BAC9C,YAAY,yBAAyBpB,CAAK,IAAIA,CAAK,MAAMA,CAAK;AAAA,0BAC9D,gBAAgB;AAAA,0BAChB,cAAc;AAAA,0BACd,YAAY;AAAA,0BACZ,WAAW;AAAA,wBAAA;AAAA,sBACb;AAAA,oBAAA;AAAA,kBACF;AAAA,gBAAA;AAAA,gBAEF,gBAAAI;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,OAAO;AAAA,sBACL,QAAQ;AAAA,sBACR,WAAW;AAAA,sBACX,OAAOqC,EAAG;AAAA,sBACV,SAAS;AAAA,sBACT,UAAU;AAAA,sBACV,YAAY;AAAA,oBAAA;AAAA,oBAGb,UAAA;AAAA,sBAAArB;AAAA,sBAAS;AAAA,oBAAA;AAAA,kBAAA;AAAA,gBAAA;AAAA,cACZ,GACF;AAAA,cAEDO,KACC,gBAAA1B;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,OAAO;AAAA,oBACL,QAAQ;AAAA,oBACR,OAAOwC,EAAG;AAAA,oBACV,SAAS;AAAA,oBACT,UAAU;AAAA,oBACV,YAAY;AAAA,kBAAA;AAAA,kBAEf,UAAA;AAAA,gBAAA;AAAA,cAAA;AAAA,YAED;AAAA,UAAA;AAAA,QAAA;AAAA,MAEJ;AAAA,IAAA;AAAA,EACF,GACF;AAEJ;"}
@@ -0,0 +1,10 @@
1
+ (function(t,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],e):(t=typeof globalThis<"u"?globalThis:t||self,e(t.LoaderOverlay={},t.ReactJSXRuntime,t.React))})(this,function(t,e,r){"use strict";const u={sm:{s:28,f:"11px",g:"8px"},md:{s:44,f:"13px",g:"12px"},lg:{s:64,f:"15px",g:"16px"},xl:{s:88,f:"18px",g:"22px"}},y={light:{bg:"rgba(255,255,255,0.9)",tx:"#1a1a2e"},dark:{bg:"rgba(10,10,20,0.92)",tx:"#f0f0f0"},blur:{bg:"rgba(20,15,50,0.5)",tx:"#fff"},transparent:{bg:"rgba(0,0,0,0)",tx:"#f0f0f0"},gradient:{bg:"linear-gradient(135deg,rgba(15,15,40,.95),rgba(50,10,80,.95))",tx:"#e8d5ff"}},v=`
2
+ @keyframes lSpin{to{transform:rotate(360deg)}}
3
+ @keyframes lBounce{0%,80%,100%{transform:scale(.6);opacity:.4}40%{transform:scale(1);opacity:1}}
4
+ @keyframes lPR{0%{transform:scale(.8);opacity:.6}100%{transform:scale(1.8);opacity:0}}
5
+ @keyframes lPC{0%,100%{transform:scale(.9)}50%{transform:scale(1.1)}}
6
+ @keyframes lBar{0%,100%{height:30%;opacity:.4}50%{height:100%;opacity:1}}
7
+ @keyframes lFI{from{opacity:0}to{opacity:1}}
8
+ @keyframes lShim{0%{background-position:0 50%}100%{background-position:200% 50%}}
9
+ `,$=({s:n,color:i})=>e.jsx("svg",{width:n,height:n,viewBox:"0 0 50 50",style:{animation:"lSpin .9s linear infinite"},children:e.jsx("circle",{cx:"25",cy:"25",r:"20",fill:"none",stroke:i,strokeWidth:"4",strokeLinecap:"round",strokeDasharray:"90 60"})}),w=({s:n,color:i})=>e.jsx("div",{style:{display:"flex",gap:n*.18,alignItems:"center"},children:[0,1,2].map(a=>e.jsx("div",{style:{width:n*.22,height:n*.22,borderRadius:"50%",background:i,animation:`lBounce 1.2s ease-in-out ${a*.2}s infinite`}},a))}),E=({s:n,color:i})=>e.jsxs("div",{style:{position:"relative",width:n,height:n},children:[e.jsx("div",{style:{position:"absolute",inset:0,borderRadius:"50%",background:i,opacity:.2,animation:"lPR 1.4s ease-out infinite"}}),e.jsx("div",{style:{position:"absolute",inset:"20%",borderRadius:"50%",background:i,animation:"lPC 1.4s ease-in-out infinite"}})]}),F=({s:n,color:i})=>e.jsx("div",{style:{width:n,height:n,borderRadius:"50%",border:`${n*.08}px solid ${i}22`,borderTop:`${n*.08}px solid ${i}`,animation:"lSpin .75s linear infinite"}}),T=({s:n,color:i})=>e.jsx("div",{style:{display:"flex",gap:n*.1,alignItems:"flex-end",height:n*.7},children:[0,1,2,3].map(a=>e.jsx("div",{style:{width:n*.15,background:i,borderRadius:3,animation:`lBar 1s ease-in-out ${a*.15}s infinite`}},a))}),h={spinner:$,dots:w,pulse:E,ring:F,bar:T};function L({show:n=!0,type:i="spinner",size:a="md",variant:d="dark",color:o="#a78bfa",message:B="Loading...",submessage:A="",fullScreen:N=!1,zIndex:j=999,opacity:D=1,blur:c=8,showProgress:_=!1,progress:M=0,closable:V=!1,onClose:b=()=>{},position:P="center",animateIn:W=!0,timeout:x=0,children:q=null,closeOnOutsideClick:m=!1,onOutsideClick:S=()=>{}}){const[l,f]=r.useState(n),k=r.useRef(null),p=r.useRef(b),z=r.useRef(S);if(r.useEffect(()=>{p.current=b},[b]),r.useEffect(()=>{z.current=S},[S]),r.useEffect(()=>{f(n)},[n]),r.useEffect(()=>{if(!l||!m)return;const g=J=>{k.current&&!k.current.contains(J.target)&&(z.current(),f(!1),p.current())};return document.addEventListener("mousedown",g),()=>document.removeEventListener("mousedown",g)},[l,m]),r.useEffect(()=>{if(x>0&&l){const g=setTimeout(()=>{f(!1),p.current()},x);return()=>clearTimeout(g)}},[x,l]),!l)return null;const I=u[a]||u.md,s=y[d]||y.dark,C=h[i]||h.spinner,Z={center:"center",top:"flex-start",bottom:"flex-end"};return e.jsxs(e.Fragment,{children:[e.jsx("style",{children:v}),e.jsx("div",{style:{position:N?"fixed":"absolute",inset:0,zIndex:j,display:"flex",alignItems:Z[P]||"center",justifyContent:"center",padding:P!=="center"?40:0,background:s.bg,backdropFilter:c>0?`blur(${c}px)`:"none",WebkitBackdropFilter:c>0?`blur(${c}px)`:"none",opacity:D,animation:W?"lFI .25s ease":"none"},children:e.jsxs("div",{ref:k,style:{display:"flex",flexDirection:"column",alignItems:"center",gap:I.g,padding:"28px 36px",borderRadius:16,position:"relative",background:d==="transparent"?"transparent":d==="gradient"?"rgba(255,255,255,.04)":"rgba(255,255,255,.07)",border:d==="transparent"?"none":`1px solid ${o}25`,boxShadow:d==="transparent"?"none":`0 8px 40px ${o}15`},children:[V&&e.jsx("button",{onClick:()=>{f(!1),p.current()},style:{position:"absolute",top:8,right:10,background:"none",border:"none",cursor:"pointer",color:s.tx,fontSize:16,opacity:.45,padding:"2px 6px",borderRadius:6},children:"✕"}),q||e.jsx(C,{s:I.s,color:o}),B&&e.jsx("p",{style:{margin:0,color:s.tx,fontSize:I.f,fontWeight:600,letterSpacing:".04em",fontFamily:"system-ui,sans-serif"},children:B}),A&&e.jsx("p",{style:{margin:0,color:s.tx,fontSize:"11px",opacity:.5,fontFamily:"system-ui,sans-serif"},children:A}),_&&e.jsxs("div",{style:{width:140,marginTop:2},children:[e.jsx("div",{style:{width:"100%",height:4,background:`${o}22`,borderRadius:99,overflow:"hidden"},children:e.jsx("div",{style:{height:"100%",width:`${Math.min(100,Math.max(0,M))}%`,background:`linear-gradient(90deg,${o},${o}88,${o})`,backgroundSize:"200% 100%",borderRadius:99,transition:"width .3s ease",animation:"lShim 1.5s linear infinite"}})}),e.jsxs("p",{style:{margin:"3px 0 0",textAlign:"right",color:s.tx,opacity:.4,fontSize:10,fontFamily:"monospace"},children:[M,"%"]})]}),m&&e.jsx("p",{style:{margin:"2px 0 0",color:s.tx,opacity:.3,fontSize:9,fontFamily:"monospace"},children:"click outside to dismiss"})]})})]})}t.ANIM_CSS=v,t.BarIcon=T,t.DotsIcon=w,t.ICONS=h,t.PulseIcon=E,t.RingIcon=F,t.SIZES=u,t.SpinIcon=$,t.VARIANTS=y,t.default=L,Object.defineProperties(t,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
10
+ //# sourceMappingURL=loader-overlay.umd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader-overlay.umd.js","sources":["../src/constants/index.js","../src/components/icons/SpinIcon.jsx","../src/components/icons/DotsIcon.jsx","../src/components/icons/PulseIcon.jsx","../src/components/icons/RingIcon.jsx","../src/components/icons/BarIcon.jsx","../src/components/Icons.jsx","../src/index.jsx"],"sourcesContent":["export const SIZES = {\n sm: { s: 28, f: \"11px\", g: \"8px\" },\n md: { s: 44, f: \"13px\", g: \"12px\" },\n lg: { s: 64, f: \"15px\", g: \"16px\" },\n xl: { s: 88, f: \"18px\", g: \"22px\" },\n};\n\nexport const VARIANTS = {\n light: { bg: \"rgba(255,255,255,0.9)\", tx: \"#1a1a2e\" },\n dark: { bg: \"rgba(10,10,20,0.92)\", tx: \"#f0f0f0\" },\n blur: { bg: \"rgba(20,15,50,0.5)\", tx: \"#fff\" },\n transparent: { bg: \"rgba(0,0,0,0)\", tx: \"#f0f0f0\" },\n gradient: {\n bg: \"linear-gradient(135deg,rgba(15,15,40,.95),rgba(50,10,80,.95))\",\n tx: \"#e8d5ff\",\n },\n};\n\nexport const ANIM_CSS = `\n @keyframes lSpin{to{transform:rotate(360deg)}}\n @keyframes lBounce{0%,80%,100%{transform:scale(.6);opacity:.4}40%{transform:scale(1);opacity:1}}\n @keyframes lPR{0%{transform:scale(.8);opacity:.6}100%{transform:scale(1.8);opacity:0}}\n @keyframes lPC{0%,100%{transform:scale(.9)}50%{transform:scale(1.1)}}\n @keyframes lBar{0%,100%{height:30%;opacity:.4}50%{height:100%;opacity:1}}\n @keyframes lFI{from{opacity:0}to{opacity:1}}\n @keyframes lShim{0%{background-position:0 50%}100%{background-position:200% 50%}}\n`;\n","import React from \"react\";\n\nconst SpinIcon = ({ s, color }) => {\n return (\n <svg\n width={s}\n height={s}\n viewBox=\"0 0 50 50\"\n style={{ animation: \"lSpin .9s linear infinite\" }}\n >\n <circle\n cx=\"25\"\n cy=\"25\"\n r=\"20\"\n fill=\"none\"\n stroke={color}\n strokeWidth=\"4\"\n strokeLinecap=\"round\"\n strokeDasharray=\"90 60\"\n />\n </svg>\n );\n};\n\nexport default SpinIcon;\n","import React from \"react\";\n\nconst DotsIcon = ({ s, color }) => {\n return (\n <div style={{ display: \"flex\", gap: s * 0.18, alignItems: \"center\" }}>\n {[0, 1, 2].map((i) => (\n <div\n key={i}\n style={{\n width: s * 0.22,\n height: s * 0.22,\n borderRadius: \"50%\",\n background: color,\n animation: `lBounce 1.2s ease-in-out ${i * 0.2}s infinite`,\n }}\n />\n ))}\n </div>\n );\n};\n\nexport default DotsIcon;\n","import React from \"react\";\n\nconst PulseIcon = ({ s, color }) => {\n return (\n <div style={{ position: \"relative\", width: s, height: s }}>\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n borderRadius: \"50%\",\n background: color,\n opacity: 0.2,\n animation: \"lPR 1.4s ease-out infinite\",\n }}\n />\n <div\n style={{\n position: \"absolute\",\n inset: \"20%\",\n borderRadius: \"50%\",\n background: color,\n animation: \"lPC 1.4s ease-in-out infinite\",\n }}\n />\n </div>\n );\n};\n\nexport default PulseIcon;\n","import React from \"react\";\n\nconst RingIcon = ({ s, color }) => {\n return (\n <div\n style={{\n width: s,\n height: s,\n borderRadius: \"50%\",\n border: `${s * 0.08}px solid ${color}22`,\n borderTop: `${s * 0.08}px solid ${color}`,\n animation: \"lSpin .75s linear infinite\",\n }}\n />\n );\n};\n\nexport default RingIcon;\n","import React from \"react\";\n\nconst BarIcon = ({ s, color }) => {\n return (\n <div\n style={{\n display: \"flex\",\n gap: s * 0.1,\n alignItems: \"flex-end\",\n height: s * 0.7,\n }}\n >\n {[0, 1, 2, 3].map((i) => (\n <div\n key={i}\n style={{\n width: s * 0.15,\n background: color,\n borderRadius: 3,\n animation: `lBar 1s ease-in-out ${i * 0.15}s infinite`,\n }}\n />\n ))}\n </div>\n );\n};\n\nexport default BarIcon;\n","import SpinIcon from \"./icons/SpinIcon.jsx\";\nimport DotsIcon from \"./icons/DotsIcon.jsx\";\nimport PulseIcon from \"./icons/PulseIcon.jsx\";\nimport RingIcon from \"./icons/RingIcon.jsx\";\nimport BarIcon from \"./icons/BarIcon.jsx\";\n\nexport const ICONS = {\n spinner: SpinIcon,\n dots: DotsIcon,\n pulse: PulseIcon,\n ring: RingIcon,\n bar: BarIcon,\n};\n\nexport { SpinIcon, DotsIcon, PulseIcon, RingIcon, BarIcon };\nexport default ICONS;\n","import React, { useState, useRef, useEffect } from \"react\";\nimport { SIZES, VARIANTS, ANIM_CSS } from \"./constants/index.js\";\nimport { ICONS, SpinIcon, DotsIcon, PulseIcon, RingIcon, BarIcon } from \"./components/Icons.jsx\";\n\n// ─── Named exports for tree-shaking ─────────────────────────────────────────\nexport { SIZES, VARIANTS, ANIM_CSS };\nexport { ICONS, SpinIcon, DotsIcon, PulseIcon, RingIcon, BarIcon };\n\n/**\n * A highly customizable, accessible loading overlay.\n * @param {import('./types/index.js').LoaderOverlayProps} props\n */\nexport default function LoaderOverlay({\n show = true,\n type = \"spinner\",\n size = \"md\",\n variant = \"dark\",\n color = \"#a78bfa\",\n message = \"Loading...\",\n submessage = \"\",\n fullScreen = false,\n zIndex = 999,\n opacity = 1,\n blur = 8,\n showProgress = false,\n progress = 0,\n closable = false,\n onClose = () => {},\n position = \"center\",\n animateIn = true,\n timeout = 0,\n children = null,\n closeOnOutsideClick = false,\n onOutsideClick = () => {},\n}) {\n const [vis, setVis] = useState(show);\n const boxRef = useRef(null);\n const closeRef = useRef(onClose);\n const outsideRef = useRef(onOutsideClick);\n\n useEffect(() => {\n closeRef.current = onClose;\n }, [onClose]);\n useEffect(() => {\n outsideRef.current = onOutsideClick;\n }, [onOutsideClick]);\n useEffect(() => {\n setVis(show);\n }, [show]);\n\n useEffect(() => {\n if (!vis || !closeOnOutsideClick) return;\n const h = (e) => {\n if (boxRef.current && !boxRef.current.contains(e.target)) {\n outsideRef.current();\n setVis(false);\n closeRef.current();\n }\n };\n document.addEventListener(\"mousedown\", h);\n return () => document.removeEventListener(\"mousedown\", h);\n }, [vis, closeOnOutsideClick]);\n\n useEffect(() => {\n if (timeout > 0 && vis) {\n const t = setTimeout(() => {\n setVis(false);\n closeRef.current();\n }, timeout);\n return () => clearTimeout(t);\n }\n }, [timeout, vis]);\n\n if (!vis) return null;\n\n const sc = SIZES[size] || SIZES.md;\n const vc = VARIANTS[variant] || VARIANTS.dark;\n const Icon = ICONS[type] || ICONS.spinner;\n const alignMap = { center: \"center\", top: \"flex-start\", bottom: \"flex-end\" };\n\n return (\n <>\n <style>{ANIM_CSS}</style>\n <div\n style={{\n position: fullScreen ? \"fixed\" : \"absolute\",\n inset: 0,\n zIndex,\n display: \"flex\",\n alignItems: alignMap[position] || \"center\",\n justifyContent: \"center\",\n padding: position !== \"center\" ? 40 : 0,\n background: vc.bg,\n backdropFilter: blur > 0 ? `blur(${blur}px)` : \"none\",\n WebkitBackdropFilter: blur > 0 ? `blur(${blur}px)` : \"none\",\n opacity,\n animation: animateIn ? \"lFI .25s ease\" : \"none\",\n }}\n >\n <div\n ref={boxRef}\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: sc.g,\n padding: \"28px 36px\",\n borderRadius: 16,\n position: \"relative\",\n background:\n variant === \"transparent\"\n ? \"transparent\"\n : variant === \"gradient\"\n ? \"rgba(255,255,255,.04)\"\n : \"rgba(255,255,255,.07)\",\n border: variant === \"transparent\" ? \"none\" : `1px solid ${color}25`,\n boxShadow:\n variant === \"transparent\" ? \"none\" : `0 8px 40px ${color}15`,\n }}\n >\n {closable && (\n <button\n onClick={() => {\n setVis(false);\n closeRef.current();\n }}\n style={{\n position: \"absolute\",\n top: 8,\n right: 10,\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n color: vc.tx,\n fontSize: 16,\n opacity: 0.45,\n padding: \"2px 6px\",\n borderRadius: 6,\n }}\n >\n ✕\n </button>\n )}\n {children || <Icon s={sc.s} color={color} />}\n {message && (\n <p\n style={{\n margin: 0,\n color: vc.tx,\n fontSize: sc.f,\n fontWeight: 600,\n letterSpacing: \".04em\",\n fontFamily: \"system-ui,sans-serif\",\n }}\n >\n {message}\n </p>\n )}\n {submessage && (\n <p\n style={{\n margin: 0,\n color: vc.tx,\n fontSize: \"11px\",\n opacity: 0.5,\n fontFamily: \"system-ui,sans-serif\",\n }}\n >\n {submessage}\n </p>\n )}\n {showProgress && (\n <div style={{ width: 140, marginTop: 2 }}>\n <div\n style={{\n width: \"100%\",\n height: 4,\n background: `${color}22`,\n borderRadius: 99,\n overflow: \"hidden\",\n }}\n >\n <div\n style={{\n height: \"100%\",\n width: `${Math.min(100, Math.max(0, progress))}%`,\n background: `linear-gradient(90deg,${color},${color}88,${color})`,\n backgroundSize: \"200% 100%\",\n borderRadius: 99,\n transition: \"width .3s ease\",\n animation: \"lShim 1.5s linear infinite\",\n }}\n />\n </div>\n <p\n style={{\n margin: \"3px 0 0\",\n textAlign: \"right\",\n color: vc.tx,\n opacity: 0.4,\n fontSize: 10,\n fontFamily: \"monospace\",\n }}\n >\n {progress}%\n </p>\n </div>\n )}\n {closeOnOutsideClick && (\n <p\n style={{\n margin: \"2px 0 0\",\n color: vc.tx,\n opacity: 0.3,\n fontSize: 9,\n fontFamily: \"monospace\",\n }}\n >\n click outside to dismiss\n </p>\n )}\n </div>\n </div>\n </>\n );\n}\n"],"names":["SIZES","VARIANTS","ANIM_CSS","SpinIcon","s","color","jsx","DotsIcon","i","PulseIcon","jsxs","RingIcon","BarIcon","ICONS","LoaderOverlay","show","type","size","variant","message","submessage","fullScreen","zIndex","opacity","blur","showProgress","progress","closable","onClose","position","animateIn","timeout","children","closeOnOutsideClick","onOutsideClick","vis","setVis","useState","boxRef","useRef","closeRef","outsideRef","useEffect","h","e","t","sc","vc","Icon","alignMap","Fragment"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "loader-overlay",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "description": "Drop-in React overlay loader — 5 animation types, full theme control, progress tracking, and zero dependencies.",
6
+ "author": "Swapnil Patil (https://github.com/swapnilhpatil)",
7
+ "license": "MIT",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/swapnilhpatil/loader-overlay.git"
11
+ },
12
+ "homepage": "https://github.com/swapnilhpatil/loader-overlay#readme",
13
+ "bugs": {
14
+ "url": "https://github.com/swapnilhpatil/loader-overlay/issues"
15
+ },
16
+ "main": "dist/loader-overlay.umd.js",
17
+ "module": "dist/loader-overlay.es.js",
18
+ "types": "dist/loader-overlay.d.ts",
19
+ "typings": "dist/loader-overlay.d.ts",
20
+ "exports": {
21
+ ".": {
22
+ "types": "./dist/loader-overlay.d.ts",
23
+ "import": "./dist/loader-overlay.es.js",
24
+ "require": "./dist/loader-overlay.umd.js"
25
+ }
26
+ },
27
+ "files": [
28
+ "dist"
29
+ ],
30
+ "keywords": [
31
+ "react",
32
+ "loader",
33
+ "overlay",
34
+ "spinner",
35
+ "loading",
36
+ "progress",
37
+ "component",
38
+ "library"
39
+ ],
40
+ "scripts": {
41
+ "dev": "vite",
42
+ "build": "vite build",
43
+ "build:docs": "vite build --config vite.docs.config.js",
44
+ "preview": "vite preview"
45
+ },
46
+ "peerDependencies": {
47
+ "react": ">=17.0.0",
48
+ "react-dom": ">=17.0.0"
49
+ },
50
+ "devDependencies": {
51
+ "@vitejs/plugin-react": "^4.2.1",
52
+ "prop-types": "^15.8.1",
53
+ "react": "^18.2.0",
54
+ "react-dom": "^18.2.0",
55
+ "vite": "^5.2.0"
56
+ }
57
+ }