modern-loaders 1.2.2 → 1.2.3

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.
Files changed (2) hide show
  1. package/README.md +226 -116
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -24,15 +24,16 @@ npm install modern-loaders
24
24
 
25
25
  ## What is modern-loaders?
26
26
 
27
- A library of **212 loading animations** for React, all behind a single `<Loader />` component.
27
+ A library of **212 loading animations** for React, all behind a single
28
+ `<Loader />` component.
28
29
 
29
- **The problem.** Every app needs loading states. Building them by hand means writing CSS keyframes
30
- again and again. Most loader packages give you a handful of spinners, or pull in a JavaScript
31
- animation runtime you did not ask for.
30
+ **The problem.** Every app needs loading states. Building them by hand means
31
+ writing CSS keyframes again and again. Most loader packages give you a handful
32
+ of spinners, or pull in a JavaScript animation runtime you did not ask for.
32
33
 
33
- **This package.** Pick a loader by name, set the size, speed and colours if you want, and ship.
34
- Every animation is plain CSS, so nothing runs on the main thread and there is nothing to install
35
- alongside it.
34
+ **This package.** Pick a loader by name, set the size, speed and colours if you
35
+ want, and ship. Every animation is plain CSS, so nothing runs on the main
36
+ thread and there is nothing to install alongside it.
36
37
 
37
38
  ### Why developers use it
38
39
 
@@ -45,9 +46,7 @@ alongside it.
45
46
 
46
47
  ---
47
48
 
48
- ## Quick Start
49
-
50
- ### 1. Install
49
+ ## Installation
51
50
 
52
51
  ```bash
53
52
  npm install modern-loaders
@@ -58,12 +57,25 @@ npm install modern-loaders
58
57
 
59
58
  ```bash
60
59
  yarn add modern-loaders
60
+ ```
61
+
62
+ ```bash
61
63
  pnpm add modern-loaders
62
64
  ```
63
65
 
64
66
  </details>
65
67
 
66
- ### 2. Add a loader
68
+ **No CSS import needed.** The stylesheet is bundled and injects itself — nothing
69
+ to configure in Vite, Next.js, CRA, or Tailwind.
70
+
71
+ <sub>If your bundler strips side-effect imports, add
72
+ <code>import "modern-loaders/styles.css"</code>.</sub>
73
+
74
+ ---
75
+
76
+ ## Quick Start
77
+
78
+ ### 1. Render a loader
67
79
 
68
80
  ```tsx
69
81
  import { Loader } from "modern-loaders";
@@ -73,54 +85,48 @@ export default function App() {
73
85
  }
74
86
  ```
75
87
 
76
- That is the whole setup. **The stylesheet is bundled and injects itself** — no CSS import to
77
- remember, nothing to configure in Vite, Next.js, CRA, or Tailwind.
88
+ ### 2. Pick a variant
78
89
 
79
- <sub>If your bundler strips side-effect imports, add <code>import "modern-loaders/styles.css"</code>.</sub>
90
+ Every loader has a name. Pass it as `variant`:
80
91
 
81
- ### 3. Make it yours
92
+ ```tsx
93
+ <Loader variant="wave" />
94
+ ```
95
+
96
+ ### 3. Customise it
82
97
 
83
- Choose a variant by name, then tune the size, speed and colours:
98
+ Set the size, speed and colours:
84
99
 
85
100
  ```tsx
86
- <Loader variant="wave" size={72} speed={0.8} colors={["#f97316", "#ef4444", "#a855f7"]} />
101
+ <Loader
102
+ variant="wave"
103
+ size={72}
104
+ speed={0.8}
105
+ colors={["#f97316", "#ef4444", "#a855f7"]}
106
+ />
87
107
  ```
88
108
 
89
- Not sure which one to pick? [**Browse all 212 in the live gallery →**](https://modern-loaders.netlify.app/)
109
+ Not sure which one to pick?
110
+ [**Browse all 212 in the live gallery →**](https://modern-loaders.netlify.app/)
90
111
 
91
112
  ---
92
113
 
93
114
  ## Contents
94
115
 
95
- - [Props](#props)
96
- - [Which loader should I use?](#which-loader-should-i-use)
116
+ - [Choosing a loader](#choosing-a-loader)
97
117
  - [Recipes](#recipes)
118
+ - [Customization](#customization)
119
+ - [API](#api)
98
120
  - [All 212 variants](#all-212-variants)
99
- - [Theming](#theming)
100
121
  - [Accessibility](#accessibility)
101
122
  - [Bundle size](#bundle-size)
102
- - [Named exports](#named-exports)
103
123
  - [Browser support](#browser-support)
104
- - [Development](#development)
124
+ - [Contributing](#contributing)
105
125
  - [License](#license)
106
126
 
107
127
  ---
108
128
 
109
- ## Props
110
-
111
- | prop | type | default | description |
112
- |---|---|---|---|
113
- | `variant` | `LoaderVariant` | `"aurora"` | Which loader to render — any of the 212 ids below. |
114
- | `size` | `number \| string` | `48` | Overall size. A number means pixels; strings pass through (`"3rem"`). |
115
- | `speed` | `number \| string` | `1` | Base duration. A number means seconds; lower is faster. |
116
- | `colors` | `string[]` | indigo / pink / cyan | One to three colors. Fewer are cycled, so a single color gives a clean monochrome loader. |
117
- | `label` | `string \| null` | `"Loading"` | Screen-reader text. Pass `null` to mark the loader decorative. |
118
-
119
- Every other `div` prop — `className`, `style`, `id`, `onClick`, `data-*` — passes straight through.
120
-
121
- ---
122
-
123
- ## Which loader should I use?
129
+ ## Choosing a loader
124
130
 
125
131
  | situation | reach for | why |
126
132
  |---|---|---|
@@ -138,49 +144,177 @@ Every other `div` prop — `className`, `style`, `id`, `onClick`, `data-*` — p
138
144
 
139
145
  ## Recipes
140
146
 
141
- **A button that keeps its width while loading**
147
+ ### A button that keeps its width while loading
142
148
 
143
149
  ```tsx
144
150
  <button disabled={busy}>
145
- {busy
146
- ? <Loader variant="pulse-dots" size={16} colors={["currentColor"]} label={null} />
147
- : "Save"}
151
+ {busy ? (
152
+ <Loader
153
+ variant="pulse-dots"
154
+ size={16}
155
+ colors={["currentColor"]}
156
+ label={null}
157
+ />
158
+ ) : (
159
+ "Save"
160
+ )}
148
161
  </button>
149
162
  ```
150
163
 
151
- `colors={["currentColor"]}` inherits the button's own text color. `label={null}` stops screen
152
- readers announcing "Loading" twice when the button already conveys it.
164
+ `colors={["currentColor"]}` inherits the button's own text colour.
165
+ `label={null}` stops screen readers announcing "Loading" twice when the button
166
+ already conveys it.
153
167
 
154
- **A skeleton shaped like the thing you're waiting for**
168
+ ### A skeleton shaped like the thing you're waiting for
155
169
 
156
170
  ```tsx
157
- {isLoading ? <Loader variant="sk-card" size={64} /> : <ArticleCard {...article} />}
171
+ {isLoading ? (
172
+ <Loader
173
+ variant="sk-card"
174
+ size={64}
175
+ />
176
+ ) : (
177
+ <ArticleCard {...article} />
178
+ )}
158
179
  ```
159
180
 
160
- **A full-page overlay**
181
+ ### A full-page overlay
161
182
 
162
183
  ```tsx
163
- <div style={{ position: "fixed", inset: 0, display: "grid", placeItems: "center" }}>
164
- <Loader variant="aurora" size={80} label="Loading your dashboard" />
184
+ <div
185
+ style={{
186
+ position: "fixed",
187
+ inset: 0,
188
+ display: "grid",
189
+ placeItems: "center",
190
+ }}
191
+ >
192
+ <Loader
193
+ variant="aurora"
194
+ size={80}
195
+ label="Loading your dashboard"
196
+ />
165
197
  </div>
166
198
  ```
167
199
 
168
- **Build your own picker** — the manifest is exported:
200
+ ### Build your own picker
201
+
202
+ The manifest is exported, so you can map over it:
169
203
 
170
204
  ```tsx
171
205
  import { VARIANTS, Loader } from "modern-loaders";
172
206
 
173
- VARIANTS.filter(v => v.group === "Skeletons")
174
- .map(v => <Loader key={v.id} variant={v.id} />);
207
+ VARIANTS
208
+ .filter((variant) => variant.group === "Skeletons")
209
+ .map((variant) => (
210
+ <Loader
211
+ key={variant.id}
212
+ variant={variant.id}
213
+ />
214
+ ));
215
+ ```
216
+
217
+ ---
218
+
219
+ ## Customization
220
+
221
+ The `colors` prop covers most cases. For anything else, override the CSS custom
222
+ properties — they cascade, so one rule themes a whole subtree:
223
+
224
+ ```css
225
+ .dashboard {
226
+ /* palette */
227
+ --c1: #6366f1;
228
+ --c2: #ec4899;
229
+ --c3: #22d3ee;
230
+
231
+ /* size and timing */
232
+ --size: 64px;
233
+ --speed: .9s;
234
+
235
+ /* rail behind progress bars */
236
+ --track: #1e1e2e;
237
+
238
+ /* shared gradient */
239
+ --grad: linear-gradient(
240
+ 90deg,
241
+ var(--c1),
242
+ var(--c3)
243
+ );
244
+ }
245
+ ```
246
+
247
+ `--track` and `--grad` derive from `--c1`–`--c3` automatically; set them
248
+ directly for finer control.
249
+
250
+ ---
251
+
252
+ ## API
253
+
254
+ ### Props
255
+
256
+ | prop | type | default | description |
257
+ |---|---|---|---|
258
+ | `variant` | `LoaderVariant` | `"aurora"` | Which loader to render — any of the 212 ids below. |
259
+ | `size` | `number \| string` | `48` | Overall size. A number means pixels; strings pass through (`"3rem"`). |
260
+ | `speed` | `number \| string` | `1` | Base duration. A number means seconds; lower is faster. |
261
+ | `colors` | `string[]` | indigo / pink / cyan | One to three colours. Fewer are cycled, so a single colour gives a clean monochrome loader. |
262
+ | `label` | `string \| null` | `"Loading"` | Screen-reader text. Pass `null` to mark the loader decorative. |
263
+
264
+ Every other `div` prop — `className`, `style`, `id`, `onClick`, `data-*` —
265
+ passes straight through.
266
+
267
+ ### Exports
268
+
269
+ | export | what it is |
270
+ |---|---|
271
+ | `Loader` | The component. |
272
+ | `VARIANTS` | Manifest of all 212: `{ id, label, group, cells }`. |
273
+ | `LOADER_VARIANTS` | Just the 212 ids, in display order. |
274
+ | `GROUPS` | The 20 families: `{ name, description }`. |
275
+
276
+ `Loader` is the main export. The original ten also have named wrappers, kept for
277
+ backward compatibility with 1.0.x:
278
+
279
+ ```tsx
280
+ import {
281
+ Aurora, Orbit, Rings, Wave, Bars,
282
+ Blob, Cube, Spiral, Bar, Grid,
283
+ } from "modern-loaders";
284
+ ```
285
+
286
+ Everything else is reached with `<Loader variant="…" />`. Two hundred named
287
+ exports would bloat the API surface for no real gain, and `variant`
288
+ autocompletes just as well.
289
+
290
+ ### TypeScript
291
+
292
+ Types ship with the package — no `@types` install:
293
+
294
+ ```tsx
295
+ import type {
296
+ LoaderProps,
297
+ LoaderVariant,
298
+ LoaderGroup,
299
+ VariantMeta,
300
+ } from "modern-loaders";
301
+
302
+ // a union of all 212 ids; typos fail to compile
303
+ const variant: LoaderVariant = "aurora";
304
+
305
+ // wrap Loader without re-declaring its props
306
+ function Busy(props: LoaderProps) {
307
+ return <Loader {...props} />;
308
+ }
175
309
  ```
176
310
 
177
311
  ---
178
312
 
179
313
  ## All 212 variants
180
314
 
181
- Every id maps to a `.ldr--<id>` CSS class. The tables below are the full reference; to *see* them
182
- moving, use the [live gallery](https://modern-loaders.netlify.app/) — it renders every variant with your own size, speed, and
183
- colours, and copies the JSX for you.
315
+ Every id maps to a `.ldr--<id>` CSS class. The tables below are the full
316
+ reference; to *see* them moving, use the [live gallery](https://modern-loaders.netlify.app/) — it renders
317
+ every variant with your own size, speed and colours, and copies the JSX for you.
184
318
 
185
319
  <details>
186
320
  <summary><b>Spinners</b> · 10 — Rings and arcs — the classic shape, modernised.</summary>
@@ -556,35 +690,11 @@ colours, and copies the JSX for you.
556
690
 
557
691
  ---
558
692
 
559
- ## Theming
560
-
561
- The `colors` prop covers most cases. For anything else, override the custom properties — they
562
- cascade, so one rule themes a whole subtree:
563
-
564
- ```css
565
- .dashboard {
566
- --c1: #6366f1; /* primary */
567
- --c2: #ec4899; /* secondary */
568
- --c3: #22d3ee; /* tertiary */
569
- --size: 64px; /* box size */
570
- --speed: .9s; /* base duration */
571
-
572
- --track: #1e1e2e; /* rail behind progress bars */
573
- --grad: linear-gradient(90deg, var(--c1), var(--c3)); /* shared gradient */
574
- }
575
- ```
576
-
577
- `--track` and `--grad` derive from `--c1`–`--c3` automatically; set them directly for finer control.
578
-
579
- ---
580
-
581
693
  ## Accessibility
582
694
 
583
695
  - Each loader renders as `role="status"` with `aria-label`, so assistive tech announces it once.
584
- - A decorative loader — one sitting beside visible "Loading…" text — should take `label={null}`,
585
- which switches it to `aria-hidden` and prevents a double announcement.
586
- - Under `prefers-reduced-motion: reduce`, every animation slows to a single calm 4s linear cycle
587
- rather than stopping. A frozen loader reads as a crashed app, which is worse than gentle motion.
696
+ - A decorative loader — one sitting beside visible "Loading…" text — should take `label={null}`, which switches it to `aria-hidden` and prevents a double announcement.
697
+ - Under `prefers-reduced-motion: reduce`, every animation slows to a single calm 4s linear cycle rather than stopping. A frozen loader reads as a crashed app, which is worse than gentle motion.
588
698
 
589
699
  ---
590
700
 
@@ -595,57 +705,57 @@ cascade, so one rule themes a whole subtree:
595
705
  | JS | ~18 kB | **~4 kB** |
596
706
  | CSS (all 212 variants) | ~166 kB | **~24 kB** |
597
707
 
598
- One caveat, stated plainly: **the CSS is not tree-shakeable.** Class-based styles cannot be
599
- dead-code eliminated, so importing a single variant still ships the sheet for all 212. At ~24 kB
600
- gzipped that is a fair trade for most apps, but it is real weight. If you need only a handful and
601
- every kilobyte counts, copy the specific `.ldr--*` blocks out of [`src/styles/`](./src/styles)
602
- into your own CSS and skip the package each block is self-contained apart from the shared
708
+ One caveat, stated plainly: **the CSS is not tree-shakeable.** Class-based
709
+ styles cannot be dead-code eliminated, so importing a single variant still ships
710
+ the sheet for all 212. At ~24 kB gzipped that is a fair trade for most apps, but
711
+ it is real weight. If you need only a handful and every kilobyte counts, copy
712
+ the specific `.ldr--*` blocks out of [`src/styles/`](./src/styles) into your own
713
+ CSS and skip the package — each block is self-contained apart from the shared
603
714
  keyframes in [`00-base.css`](./src/styles/00-base.css).
604
715
 
605
716
  ---
606
717
 
607
- ## Named exports
608
-
609
- `Loader` is the main export. The original ten also have wrappers, kept for backward compatibility
610
- with 1.0.x:
611
-
612
- ```tsx
613
- import { Aurora, Orbit, Rings, Wave, Bars, Blob, Cube, Spiral, Bar, Grid } from "modern-loaders";
614
- ```
615
-
616
- Everything else is reached with `<Loader variant="…" />`. Two hundred named exports would bloat
617
- the API surface for no real gain, and `variant` autocompletes just as well.
618
-
619
- ---
620
-
621
718
  ## Browser support
622
719
 
623
- Chrome 111+ · Safari 16.4+ · Firefox 113+ — the floor is set by `color-mix()`, alongside `mask`,
624
- `aspect-ratio`, `clip-path`, and the individual `translate` / `rotate` / `scale` properties. Older
625
- browsers degrade to solid shapes rather than breaking.
720
+ Chrome 111+ · Safari 16.4+ · Firefox 113+ — the floor is set by `color-mix()`,
721
+ alongside `mask`, `aspect-ratio`, `clip-path`, and the individual `translate` /
722
+ `rotate` / `scale` properties. Older browsers degrade to solid shapes rather
723
+ than breaking.
626
724
 
627
- Five variants — `neon-arc`, `pie`, `progress-ring`, `gradient-border`, `color-cycle` — animate a
628
- registered custom property via `@property` (Firefox 128+). Every use passes a fallback, so below
629
- that they render a sensible static frame instead of disappearing.
725
+ Five variants — `neon-arc`, `pie`, `progress-ring`, `gradient-border`,
726
+ `color-cycle` — animate a registered custom property via `@property`
727
+ (Firefox 128+). Every use passes a fallback, so below that they render a
728
+ sensible static frame instead of disappearing.
630
729
 
631
730
  ---
632
731
 
633
- ## Development
732
+ ## Contributing
634
733
 
635
734
  ```bash
636
- npm run dev # showcase: search, 20 family filters, live size / speed / palette, detail sheet
637
- npm run build # typecheck, then emit dist/ (ESM + CJS + .d.ts + CSS)
638
- npm run build:demo # static showcase → dist-demo/ (deployed to modern-loaders.netlify.app)
735
+ # Live showcase with search and filters
736
+ npm run dev
737
+
738
+ # Typecheck, then build dist/
739
+ npm run build
740
+
741
+ # Build the static showcase
742
+ npm run build:demo
639
743
  ```
640
744
 
641
- Adding a variant takes two edits: a `.ldr--<id>` block in `src/styles/`, and a row in
642
- [`src/variants.ts`](./src/variants.ts). The component, the types, the README catalogue, and the
643
- showcase all read from that one manifest — `cells` is how many `<span>` children the CSS expects.
745
+ `build` emits ESM + CJS + `.d.ts` + CSS into `dist/`. `build:demo` writes the
746
+ static showcase to `dist-demo/`, which is what gets deployed to
747
+ [modern-loaders.netlify.app](https://modern-loaders.netlify.app/).
748
+
749
+ Adding a variant takes two edits: a `.ldr--<id>` block in `src/styles/`, and a
750
+ row in [`src/variants.ts`](./src/variants.ts). The component, the types, the
751
+ README catalogue and the showcase all read from that one manifest — `cells` is
752
+ how many `<span>` children the CSS expects.
644
753
 
645
754
  Two rules keep the motion composable inside a variant: put a whole radial chain
646
- (`rotate(…) translateY(…)`) in a single `transform` so the offset happens in the rotated frame,
647
- and reach for the standalone `translate` / `rotate` / `scale` properties when an element already
648
- animates `transform` — they compose instead of overwriting it.
755
+ (`rotate(…) translateY(…)`) in a single `transform` so the offset happens in the
756
+ rotated frame, and reach for the standalone `translate` / `rotate` / `scale`
757
+ properties when an element already animates `transform` — they compose instead
758
+ of overwriting it.
649
759
 
650
760
  ---
651
761
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "modern-loaders",
3
- "version": "1.2.2",
3
+ "version": "1.2.3",
4
4
  "description": "212 modern, colorful, animated React loaders \u2014 pure CSS, zero runtime dependencies",
5
5
  "author": "suman",
6
6
  "homepage": "https://modern-loaders.netlify.app/",