loader-pack 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,92 @@
1
+ # loader-pack
2
+
3
+ A beautiful, cinematic intro/loader screen for React apps. Drop it in and give your portfolio, SPA, or landing page a stunning animated entry.
4
+
5
+ ![npm](https://img.shields.io/npm/v/loader-pack)
6
+ ![license](https://img.shields.io/npm/l/loader-pack)
7
+
8
+ ## Features
9
+
10
+ - Scrolling multilingual marquee (Hello in 12+ languages + code snippets)
11
+ - Animated name reveal with scale + stroke effect
12
+ - Smooth zoom-out transition into your app content
13
+ - Dark & light themes
14
+ - Optional ambient & click sound effects
15
+ - Fully customizable marquee text
16
+ - Zero runtime dependencies (only React as a peer dep)
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ npm install loader-pack
22
+ ```
23
+
24
+ ## Quick Start
25
+
26
+ ```tsx
27
+ import { LoaderPack } from "loader-pack";
28
+ import "loader-pack/styles";
29
+
30
+ function App() {
31
+ return (
32
+ <LoaderPack name="Your Name" theme="dark">
33
+ <div>
34
+ <h1>Welcome to my site!</h1>
35
+ <p>Your main content goes here.</p>
36
+ </div>
37
+ </LoaderPack>
38
+ );
39
+ }
40
+ ```
41
+
42
+ ## Props
43
+
44
+ | Prop | Type | Default | Description |
45
+ | --- | --- | --- | --- |
46
+ | `name` | `string` | *required* | Large centered display name |
47
+ | `children` | `ReactNode` | *required* | Content shown after clicking Start |
48
+ | `theme` | `"dark" \| "light"` | `"dark"` | Color scheme |
49
+ | `sound` | `boolean` | `false` | Enable ambient & click sounds |
50
+ | `ambientSoundSrc` | `string` | `"/loader-sound.mp3"` | Path to ambient sound file |
51
+ | `clickSoundSrc` | `string` | `"/click.mp3"` | Path to click sound file |
52
+ | `marqueeText` | `string` | multilingual default | Custom scrolling marquee text |
53
+
54
+ ## Examples
55
+
56
+ ### Dark theme (default)
57
+
58
+ ```tsx
59
+ <LoaderPack name="Jane Doe">
60
+ <YourApp />
61
+ </LoaderPack>
62
+ ```
63
+
64
+ ### Light theme with sound
65
+
66
+ ```tsx
67
+ <LoaderPack name="Jane Doe" theme="light" sound>
68
+ <YourApp />
69
+ </LoaderPack>
70
+ ```
71
+
72
+ ### Custom marquee
73
+
74
+ ```tsx
75
+ <LoaderPack
76
+ name="Studio X"
77
+ marqueeText="Design • Code • Ship • Repeat • "
78
+ >
79
+ <YourApp />
80
+ </LoaderPack>
81
+ ```
82
+
83
+ ## How It Works
84
+
85
+ 1. The loader screen appears full-screen with a marquee, your name, date/time, and a Start button
86
+ 2. User clicks **Start →**
87
+ 3. The screen zooms out with a smooth opacity transition
88
+ 4. Your `children` content fades in
89
+
90
+ ## License
91
+
92
+ MIT
@@ -0,0 +1,2 @@
1
+ import { LoaderPackProps } from './types';
2
+ export default function LoaderPack({ name, children, theme, sound, ambientSoundSrc, clickSoundSrc, marqueeText, }: LoaderPackProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ export { default as LoaderPack } from './LoaderPack';
2
+ export type { LoaderPackProps } from './types';
@@ -0,0 +1 @@
1
+ body{font-family:Geist Sans,system-ui,sans-serif}.lp-dark{--lp-bg: #000;--lp-text: #fff;--lp-muted: rgba(255,255,255,.35)}.lp-light{--lp-bg: #fff;--lp-text: #000;--lp-muted: rgba(0,0,0,.35)}.lp-container{position:fixed;inset:0;background:var(--lp-bg);display:flex;align-items:center;justify-content:center;z-index:9999;transition:transform .8s ease,opacity .8s ease}.lp-container.lp-zoom{transform:scale(1.15);opacity:0}.lp-marquee{position:absolute;top:3%;width:100%;height:40px;overflow:hidden}.lp-track{display:flex;width:max-content;animation:lpScroll 35s linear infinite}.lp-text{font-size:.75rem;letter-spacing:.15em;padding-right:4rem;white-space:nowrap}@keyframes lpScroll{0%{transform:translate(0)}to{transform:translate(-50%)}}.lp-center{position:relative;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center}.lp-name{font-size:clamp(2.2rem,10vw,6rem);font-weight:600;letter-spacing:-.02em;line-height:1.1;text-align:center;-webkit-text-stroke:1px rgba(255,255,255,.9);color:transparent;opacity:0;transform:scale(.28);animation:lpName 1.4s ease forwards}@keyframes lpName{to{opacity:1;transform:scale(1)}}.lp-button-wrapper{height:60px;display:flex;align-items:center;justify-content:center}.lp-button{background:none;border:none;font-size:.85rem;letter-spacing:.2em;text-transform:uppercase;cursor:pointer;opacity:0;animation:lpBtn .8s ease forwards}@keyframes lpBtn{to{opacity:1}}.lp-button:hover{opacity:.6;transform:translate(6px)}.lp-arrow{margin-left:6px}.lp-date,.lp-time{position:absolute;bottom:20px;font-size:.75rem;letter-spacing:.15em;opacity:.7}.lp-date{left:24px}.lp-time{right:24px}.lp-main{opacity:0;transform:translateY(20px) scale(.98)}.lp-main.reveal{animation:lpReveal .9s ease forwards}@keyframes lpReveal{to{opacity:1;transform:translateY(0) scale(1)}}.lp-name,.lp-text,.lp-button,.lp-date,.lp-time{color:var(--lp-text)}.lp-text{opacity:.4}
@@ -0,0 +1,61 @@
1
+ import { jsxs as l, Fragment as y, jsx as t } from "react/jsx-runtime";
2
+ import { useState as o, useEffect as s } from "react";
3
+ const A = 'Hello • नमस्ते • Bonjour • Hola • こんにちは • 안녕하세요 • 你好 • مرحبا • שלום • Ciao • Olá • Привет • Hallo • Selam • Ahoj • Hej • console.log("Hello World"); • printf("Hello World"); • System.out.println("Hello World"); • echo "Hello World"; • fmt.Println("Hello World"); • cout << "Hello World"; • println!("Hello World"); • write("Hello World"); •';
4
+ function D({
5
+ name: d,
6
+ children: m,
7
+ theme: u = "dark",
8
+ sound: a = !1,
9
+ ambientSoundSrc: n = "/loader-sound.mp3",
10
+ clickSoundSrc: p = "/click.mp3",
11
+ marqueeText: h = A
12
+ }) {
13
+ const [i, f] = o(!1), [v, H] = o(!1), [N, w] = o(!1), [c, k] = o(/* @__PURE__ */ new Date());
14
+ s(() => {
15
+ const e = setTimeout(() => w(!0), 1400), r = setInterval(() => k(/* @__PURE__ */ new Date()), 1e3);
16
+ return () => {
17
+ clearTimeout(e), clearInterval(r);
18
+ };
19
+ }, []), s(() => {
20
+ if (!a) return;
21
+ const e = new Audio(n);
22
+ e.volume = 0.4, e.play().catch(() => {
23
+ });
24
+ }, [a, n]);
25
+ const T = () => {
26
+ if (a) {
27
+ const e = new Audio(p);
28
+ e.volume = 0.9, e.play().catch(() => {
29
+ });
30
+ }
31
+ H(!0), setTimeout(() => f(!0), 800);
32
+ }, W = c.toLocaleTimeString(void 0, {
33
+ hour: "2-digit",
34
+ minute: "2-digit",
35
+ second: "2-digit",
36
+ hour12: !0
37
+ }), g = c.toLocaleDateString(void 0, {
38
+ weekday: "short",
39
+ day: "numeric",
40
+ month: "short",
41
+ year: "numeric"
42
+ });
43
+ return /* @__PURE__ */ l(y, { children: [
44
+ !i && /* @__PURE__ */ l("div", { className: `lp-container lp-${u} ${v ? "lp-zoom" : ""}`, children: [
45
+ /* @__PURE__ */ t("div", { className: "lp-marquee", children: /* @__PURE__ */ t("div", { className: "lp-track", children: Array(2).fill(h).map((e, r) => /* @__PURE__ */ t("span", { className: "lp-text", children: e }, r)) }) }),
46
+ /* @__PURE__ */ l("div", { className: "lp-center", children: [
47
+ /* @__PURE__ */ t("h1", { className: "lp-name", children: d }),
48
+ /* @__PURE__ */ t("div", { className: "lp-button-wrapper", children: N && /* @__PURE__ */ l("button", { className: "lp-button", onClick: T, children: [
49
+ "Start ",
50
+ /* @__PURE__ */ t("span", { className: "lp-arrow", children: "→" })
51
+ ] }) })
52
+ ] }),
53
+ /* @__PURE__ */ t("div", { className: "lp-date", children: g }),
54
+ /* @__PURE__ */ t("div", { className: "lp-time", children: W })
55
+ ] }),
56
+ i && /* @__PURE__ */ t("div", { className: "lp-main reveal", children: m })
57
+ ] });
58
+ }
59
+ export {
60
+ D as LoaderPack
61
+ };
@@ -0,0 +1 @@
1
+ (function(l,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):(l=typeof globalThis<"u"?globalThis:l||self,e(l.LoaderPack={},l["react/jsx-runtime"],l.React))})(this,(function(l,e,o){"use strict";const i='Hello • नमस्ते • Bonjour • Hola • こんにちは • 안녕하세요 • 你好 • مرحبا • שלום • Ciao • Olá • Привет • Hallo • Selam • Ahoj • Hej • console.log("Hello World"); • printf("Hello World"); • System.out.println("Hello World"); • echo "Hello World"; • fmt.Println("Hello World"); • cout << "Hello World"; • println!("Hello World"); • write("Hello World"); •';function d({name:u,children:m,theme:p="dark",sound:a=!1,ambientSoundSrc:s="/loader-sound.mp3",clickSoundSrc:f="/click.mp3",marqueeText:h=i}){const[n,v]=o.useState(!1),[H,N]=o.useState(!1),[S,y]=o.useState(!1),[c,T]=o.useState(new Date);o.useEffect(()=>{const t=setTimeout(()=>y(!0),1400),r=setInterval(()=>T(new Date),1e3);return()=>{clearTimeout(t),clearInterval(r)}},[]),o.useEffect(()=>{if(!a)return;const t=new Audio(s);t.volume=.4,t.play().catch(()=>{})},[a,s]);const k=()=>{if(a){const t=new Audio(f);t.volume=.9,t.play().catch(()=>{})}N(!0),setTimeout(()=>v(!0),800)},w=c.toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!0}),j=c.toLocaleDateString(void 0,{weekday:"short",day:"numeric",month:"short",year:"numeric"});return e.jsxs(e.Fragment,{children:[!n&&e.jsxs("div",{className:`lp-container lp-${p} ${H?"lp-zoom":""}`,children:[e.jsx("div",{className:"lp-marquee",children:e.jsx("div",{className:"lp-track",children:Array(2).fill(h).map((t,r)=>e.jsx("span",{className:"lp-text",children:t},r))})}),e.jsxs("div",{className:"lp-center",children:[e.jsx("h1",{className:"lp-name",children:u}),e.jsx("div",{className:"lp-button-wrapper",children:S&&e.jsxs("button",{className:"lp-button",onClick:k,children:["Start ",e.jsx("span",{className:"lp-arrow",children:"→"})]})})]}),e.jsx("div",{className:"lp-date",children:j}),e.jsx("div",{className:"lp-time",children:w})]}),n&&e.jsx("div",{className:"lp-main reveal",children:m})]})}l.LoaderPack=d,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"})}));
@@ -0,0 +1,16 @@
1
+ export type LoaderPackProps = {
2
+ /** The name displayed in the center of the intro screen */
3
+ name: string;
4
+ /** Your main app content — rendered after the user clicks Start */
5
+ children: React.ReactNode;
6
+ /** Color theme: "dark" (black bg) or "light" (white bg). Default: "dark" */
7
+ theme?: "dark" | "light";
8
+ /** Play click/ambient sound effects. Default: false */
9
+ sound?: boolean;
10
+ /** Path to the ambient sound file played on mount. Default: "/loader-sound.mp3" */
11
+ ambientSoundSrc?: string;
12
+ /** Path to the click sound file played on Start. Default: "/click.mp3" */
13
+ clickSoundSrc?: string;
14
+ /** Custom marquee text. Has a built-in multilingual default. */
15
+ marqueeText?: string;
16
+ };
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "loader-pack",
3
+ "version": "1.0.0",
4
+ "description": "A beautiful animated intro/loader screen for React apps",
5
+ "type": "module",
6
+ "main": "dist/loader-pack.umd.cjs",
7
+ "module": "dist/loader-pack.js",
8
+ "types": "dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/loader-pack.js",
13
+ "require": "./dist/loader-pack.umd.cjs"
14
+ },
15
+ "./styles": "./dist/loader-pack.css"
16
+ },
17
+ "files": [
18
+ "dist"
19
+ ],
20
+ "scripts": {
21
+ "dev": "vite",
22
+ "build": "tsc && vite build",
23
+ "prepublishOnly": "npm run build"
24
+ },
25
+ "peerDependencies": {
26
+ "react": ">=18.0.0",
27
+ "react-dom": ">=18.0.0"
28
+ },
29
+ "devDependencies": {
30
+ "@types/react": "^19.2.7",
31
+ "@types/react-dom": "^19.2.3",
32
+ "@vitejs/plugin-react": "^5.1.1",
33
+ "typescript": "~5.9.3",
34
+ "vite": "^7.3.1",
35
+ "vite-plugin-dts": "^5.0.0-beta.6"
36
+ },
37
+ "keywords": [
38
+ "react",
39
+ "loader",
40
+ "intro-screen",
41
+ "animation",
42
+ "portfolio"
43
+ ],
44
+ "license": "MIT",
45
+ "repository": {
46
+ "type": "git",
47
+ "url": "https://github.com/bhavya-madan/loader-pack"
48
+ }
49
+ }