modern-loaders 1.0.0 → 1.1.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/LICENSE +15 -0
- package/README.md +316 -71
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +1 -1
- package/dist/index.d.ts +551 -3
- package/dist/index.js +158 -58
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
ISC License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 suman
|
|
4
|
+
|
|
5
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
+
purpose with or without fee is hereby granted, provided that the above
|
|
7
|
+
copyright notice and this permission notice appear in all copies.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
10
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
11
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
12
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
13
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
14
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
15
|
+
PERFORMANCE OF THIS SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,115 +1,360 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
# modern-loaders
|
|
4
|
+
|
|
5
|
+
**100 colorful, animated loaders for React.**
|
|
6
|
+
|
|
7
|
+
Pure CSS motion behind one typed component — no runtime dependencies, no SVG, no images.
|
|
8
|
+
|
|
9
|
+
[](https://www.npmjs.com/package/modern-loaders)
|
|
10
|
+
[](https://bundlephobia.com/package/modern-loaders)
|
|
11
|
+
[](https://www.npmjs.com/package/modern-loaders)
|
|
12
|
+
[](./LICENSE)
|
|
13
|
+
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
---
|
|
5
17
|
|
|
6
18
|
```bash
|
|
7
|
-
npm i
|
|
19
|
+
npm i modern-loaders
|
|
8
20
|
```
|
|
9
21
|
|
|
10
22
|
```tsx
|
|
11
|
-
import { Loader } from "
|
|
23
|
+
import { Loader } from "modern-loaders";
|
|
12
24
|
|
|
13
25
|
<Loader />
|
|
14
26
|
<Loader variant="wave" size={72} speed={0.8} colors={["#f97316", "#ef4444", "#a855f7"]} />
|
|
15
27
|
```
|
|
16
28
|
|
|
17
|
-
|
|
18
|
-
|
|
29
|
+
That is the whole setup. **The stylesheet is bundled and injects itself** — no CSS import to
|
|
30
|
+
remember, nothing to configure in Vite, Next.js, CRA, or Tailwind.
|
|
19
31
|
|
|
20
|
-
|
|
32
|
+
<sub>If your bundler strips side-effect imports, add <code>import "modern-loaders/styles.css"</code>.</sub>
|
|
21
33
|
|
|
22
|
-
|
|
23
|
-
|-----------|--------------------|-------------|--------------------------------------------------------------|
|
|
24
|
-
| `variant` | `LoaderVariant` | `"aurora"` | one of the 10 below |
|
|
25
|
-
| `size` | `number \| string` | `48` | a number means pixels |
|
|
26
|
-
| `speed` | `number \| string` | `1` | a number means seconds |
|
|
27
|
-
| `colors` | `string[]` | Nebula | 1–3 colors; fewer are cycled, so one color gives a monochrome loader |
|
|
28
|
-
| `label` | `string \| null` | `"Loading"` | screen-reader text; `null` marks the loader decorative (`aria-hidden`) |
|
|
34
|
+
## Why this one
|
|
29
35
|
|
|
30
|
-
|
|
36
|
+
- **100 variants across 10 families** — spinners, dots, bars, shapes, progress, grids, pulses, organic, skeletons, and dimensional.
|
|
37
|
+
- **Three props to learn.** `size`, `speed`, `colors`. Everything else has a sensible default.
|
|
38
|
+
- **Zero dependencies.** ~2 kB of JS. All motion is CSS keyframes, so it runs off the main thread.
|
|
39
|
+
- **Fully typed.** `variant` autocompletes every id, and a typo is a compile error.
|
|
40
|
+
- **Accessible by default.** Each loader is a labelled `role="status"` and honours `prefers-reduced-motion`.
|
|
41
|
+
- **Themeable without a build step.** Every value is a CSS custom property you can override.
|
|
31
42
|
|
|
32
|
-
##
|
|
43
|
+
## Usage
|
|
33
44
|
|
|
34
|
-
|
|
35
|
-
|------------|-----------------------------------------------|
|
|
36
|
-
| `aurora` | multi-color conic sweep with a soft glow |
|
|
37
|
-
| `orbit` | three-color comet trail |
|
|
38
|
-
| `rings` | sonar pulses in three hues |
|
|
39
|
-
| `wave` | rainbow dots riding a sine |
|
|
40
|
-
| `bars` | gradient equalizer |
|
|
41
|
-
| `blob` | morphing gradient squircle |
|
|
42
|
-
| `cube` | 3D flip, a gradient per face |
|
|
43
|
-
| `spiral` | two arcs spinning opposite directions |
|
|
44
|
-
| `bar` | indeterminate gradient progress track |
|
|
45
|
-
| `grid` | 3×3 cells pulsing on a diagonal |
|
|
45
|
+
### Props
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
| prop | type | default | description |
|
|
48
|
+
|---|---|---|---|
|
|
49
|
+
| `variant` | `LoaderVariant` | `"aurora"` | Which loader to render — any of the 100 ids below. |
|
|
50
|
+
| `size` | `number \| string` | `48` | Overall size. A number means pixels; strings pass through (`"3rem"`). |
|
|
51
|
+
| `speed` | `number \| string` | `1` | Base duration. A number means seconds; lower is faster. |
|
|
52
|
+
| `colors` | `string[]` | indigo / pink / cyan | One to three colors. Fewer are cycled, so a single color gives a clean monochrome loader. |
|
|
53
|
+
| `label` | `string \| null` | `"Loading"` | Screen-reader text. Pass `null` to mark the loader decorative. |
|
|
50
54
|
|
|
51
|
-
|
|
55
|
+
Every other `div` prop — `className`, `style`, `id`, `onClick`, `data-*` — passes straight through.
|
|
52
56
|
|
|
53
|
-
|
|
57
|
+
### Which loader should I use?
|
|
54
58
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
59
|
+
| situation | reach for | why |
|
|
60
|
+
|---|---|---|
|
|
61
|
+
| Page or section loading | **Skeletons** | Shows the layout arriving. Beats a spinner on perceived speed. |
|
|
62
|
+
| Button or inline action | **Dots**, or a spinner at `size={16}` | Fits the line box without shifting text. |
|
|
63
|
+
| Upload, install, multi-step work | **Progress** | Says "work is moving", not just "wait". |
|
|
64
|
+
| Live, polling, listening | **Pulses** | Reads as a heartbeat rather than a block. |
|
|
65
|
+
| Splash, empty state, 404 | **Shapes**, **Organic**, **Dimensional** | Personality is worth the pixels here. |
|
|
58
66
|
|
|
59
|
-
|
|
60
|
-
for a different tint. Under `prefers-reduced-motion: reduce` every animation slows to one
|
|
61
|
-
calm 4s linear cycle rather than freezing — a stopped loader reads as a broken app.
|
|
67
|
+
### Recipes
|
|
62
68
|
|
|
63
|
-
|
|
69
|
+
**A button that keeps its width while loading**
|
|
64
70
|
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
71
|
+
```tsx
|
|
72
|
+
<button disabled={busy}>
|
|
73
|
+
{busy
|
|
74
|
+
? <Loader variant="dots" size={16} colors={["currentColor"]} label={null} />
|
|
75
|
+
: "Save"}
|
|
76
|
+
</button>
|
|
69
77
|
```
|
|
70
78
|
|
|
71
|
-
|
|
79
|
+
`colors={["currentColor"]}` inherits the button's own text color. `label={null}` stops screen
|
|
80
|
+
readers announcing "Loading" twice when the button already conveys it.
|
|
72
81
|
|
|
73
|
-
|
|
82
|
+
**A skeleton shaped like the thing you're waiting for**
|
|
74
83
|
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
npm view @sumanrana/modern-loaders # 404 = the name is free
|
|
84
|
+
```tsx
|
|
85
|
+
{isLoading ? <Loader variant="sk-card" size={64} /> : <ArticleCard {...article} />}
|
|
78
86
|
```
|
|
79
87
|
|
|
80
|
-
|
|
81
|
-
(or an unscoped name that's still free), then:
|
|
88
|
+
**A full-page overlay**
|
|
82
89
|
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
|
|
90
|
+
```tsx
|
|
91
|
+
<div style={{ position: "fixed", inset: 0, display: "grid", placeItems: "center" }}>
|
|
92
|
+
<Loader variant="aurora" size={80} label="Loading your dashboard" />
|
|
93
|
+
</div>
|
|
86
94
|
```
|
|
87
95
|
|
|
88
|
-
|
|
96
|
+
**Build your own picker** — the manifest is exported:
|
|
89
97
|
|
|
90
|
-
|
|
98
|
+
```tsx
|
|
99
|
+
import { VARIANTS, Loader } from "modern-loaders";
|
|
91
100
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
npm run preview:demo # check it locally
|
|
101
|
+
VARIANTS.filter(v => v.group === "Skeletons")
|
|
102
|
+
.map(v => <Loader key={v.id} variant={v.id} />);
|
|
95
103
|
```
|
|
96
104
|
|
|
97
|
-
|
|
105
|
+
## All 100 variants
|
|
98
106
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
107
|
+
Expand a family to see its variants. Every id maps to a `.ldr--<id>` CSS class.
|
|
108
|
+
|
|
109
|
+
<details>
|
|
110
|
+
<summary><b>Spinners</b> · 10 — Rings and arcs — the classic shape, modernised.</summary>
|
|
111
|
+
|
|
112
|
+
| variant | what it looks like |
|
|
113
|
+
|---|---|
|
|
114
|
+
| `aurora` | multi-color conic sweep with a soft glow |
|
|
115
|
+
| `spiral` | two arcs spinning opposite directions |
|
|
116
|
+
| `ring-dash` | a dashed ring drawing itself |
|
|
117
|
+
| `ring-gap` | solid ring with a travelling gap |
|
|
118
|
+
| `comet` | gradient tail chasing a bright head |
|
|
119
|
+
| `arc-trio` | three nested arcs at different speeds |
|
|
120
|
+
| `halo` | still ring with a glow orbiting it |
|
|
121
|
+
| `sweep` | radar-style cone sweeping a disc |
|
|
122
|
+
| `dot-ring` | eight dots fading around a circle |
|
|
123
|
+
| `petal` | radiating rounded blades, iOS-style but colorful |
|
|
124
|
+
|
|
125
|
+
</details>
|
|
126
|
+
|
|
127
|
+
<details>
|
|
128
|
+
<summary><b>Dots</b> · 10 — Small, quiet, and good inline with text.</summary>
|
|
129
|
+
|
|
130
|
+
| variant | what it looks like |
|
|
131
|
+
|---|---|
|
|
132
|
+
| `wave` | rainbow dots riding a sine |
|
|
133
|
+
| `orbit` | three-color comet trail |
|
|
134
|
+
| `bounce` | three dots with squash on landing |
|
|
135
|
+
| `fade-dots` | three dots handing off opacity |
|
|
136
|
+
| `pulse-dots` | three dots breathing in sequence |
|
|
137
|
+
| `typing` | chat-bubble typing indicator |
|
|
138
|
+
| `chase` | six dots circling with a scale pulse |
|
|
139
|
+
| `snake` | dots sliding along a track |
|
|
140
|
+
| `swap` | two dots trading places |
|
|
141
|
+
| `juggle` | three dots arcing over each other |
|
|
142
|
+
|
|
143
|
+
</details>
|
|
144
|
+
|
|
145
|
+
<details>
|
|
146
|
+
<summary><b>Bars</b> · 10 — Equalizer-style motion with a strong rhythm.</summary>
|
|
147
|
+
|
|
148
|
+
| variant | what it looks like |
|
|
149
|
+
|---|---|
|
|
150
|
+
| `bars` | gradient equalizer |
|
|
151
|
+
| `ladder` | bars lighting up bottom to top |
|
|
152
|
+
| `stretch` | bars scaling from the centre with a color shift |
|
|
153
|
+
| `flip-bars` | bars flipping on the X axis |
|
|
154
|
+
| `slide-bars` | stacked bars sliding sideways |
|
|
155
|
+
| `drop-bars` | bars falling and rebounding |
|
|
156
|
+
| `meter` | signal-strength staircase |
|
|
157
|
+
| `wave-bars` | seven bars translating through a sine |
|
|
158
|
+
| `split-bars` | pairs opening away from the centre |
|
|
159
|
+
| `scan-bars` | a highlight sweeping across a static row |
|
|
160
|
+
|
|
161
|
+
</details>
|
|
162
|
+
|
|
163
|
+
<details>
|
|
164
|
+
<summary><b>Shapes</b> · 10 — Geometry that morphs, folds, and turns.</summary>
|
|
165
|
+
|
|
166
|
+
| variant | what it looks like |
|
|
167
|
+
|---|---|
|
|
168
|
+
| `blob` | morphing gradient squircle |
|
|
169
|
+
| `cube` | 3D flip, a gradient per face |
|
|
170
|
+
| `triangle` | spinning gradient triangle |
|
|
171
|
+
| `hexagon` | hexagon pulsing and turning |
|
|
172
|
+
| `diamond` | rotated square breathing |
|
|
173
|
+
| `star` | five-point star turning |
|
|
174
|
+
| `squircle` | square relaxing into a circle |
|
|
175
|
+
| `folding` | four quadrants folding away in turn |
|
|
176
|
+
| `pentagon` | pentagon rocking on its base |
|
|
177
|
+
| `shape-shift` | square ↔ circle with a hue sweep |
|
|
178
|
+
|
|
179
|
+
</details>
|
|
180
|
+
|
|
181
|
+
<details>
|
|
182
|
+
<summary><b>Progress</b> · 10 — Wide, indeterminate tracks for page and upload states.</summary>
|
|
183
|
+
|
|
184
|
+
| variant | what it looks like |
|
|
185
|
+
|---|---|
|
|
186
|
+
| `bar` | indeterminate runner |
|
|
187
|
+
| `bar-stripes` | barber-pole fill |
|
|
188
|
+
| `bar-dual` | two runners passing each other |
|
|
189
|
+
| `bar-segments` | discrete blocks filling in turn |
|
|
190
|
+
| `bar-pill` | a pill bouncing wall to wall |
|
|
191
|
+
| `bar-glow` | runner with a light bloom |
|
|
192
|
+
| `bar-wave` | gradient sliding under a fixed window |
|
|
193
|
+
| `bar-dots` | dots marching along a rail |
|
|
194
|
+
| `bar-snake` | thin runner that stretches and contracts |
|
|
195
|
+
| `bar-fill` | repeatedly filling left to right |
|
|
196
|
+
|
|
197
|
+
</details>
|
|
198
|
+
|
|
199
|
+
<details>
|
|
200
|
+
<summary><b>Grids</b> · 10 — Cell fields that pulse, flip, and cascade.</summary>
|
|
201
|
+
|
|
202
|
+
| variant | what it looks like |
|
|
203
|
+
|---|---|
|
|
204
|
+
| `grid` | 3x3 cells pulsing on a diagonal |
|
|
205
|
+
| `checker` | alternating cells trading places |
|
|
206
|
+
| `cascade` | a wave rolling from the top-left corner |
|
|
207
|
+
| `tiles` | cells flipping like a split-flap board |
|
|
208
|
+
| `pixel` | 4x4 field blinking in scattered order |
|
|
209
|
+
| `matrix` | rows sweeping downward |
|
|
210
|
+
| `mosaic` | cells cycling through the palette |
|
|
211
|
+
| `ripple-grid` | a pulse spreading from the centre cell |
|
|
212
|
+
| `domino` | cells tipping over one after another |
|
|
213
|
+
| `sparkle` | cells twinkling at different sizes |
|
|
214
|
+
|
|
215
|
+
</details>
|
|
216
|
+
|
|
217
|
+
<details>
|
|
218
|
+
<summary><b>Pulses</b> · 10 — Expanding rings for live, waiting, or listening states.</summary>
|
|
219
|
+
|
|
220
|
+
| variant | what it looks like |
|
|
221
|
+
|---|---|
|
|
222
|
+
| `rings` | sonar pulses in three hues |
|
|
223
|
+
| `radar` | sweeping cone over a ring |
|
|
224
|
+
| `sonar` | filled discs expanding outward |
|
|
225
|
+
| `echo` | rings that expand then snap back |
|
|
226
|
+
| `shockwave` | a ring that thins as it grows |
|
|
227
|
+
| `bloom` | soft gradient discs blooming open |
|
|
228
|
+
| `droplet` | a dot falling into its own ripple |
|
|
229
|
+
| `concentric` | three static rings breathing together |
|
|
230
|
+
| `aura` | a soft glow breathing behind a core |
|
|
231
|
+
| `beacon` | steady dot with an expanding halo |
|
|
232
|
+
|
|
233
|
+
</details>
|
|
234
|
+
|
|
235
|
+
<details>
|
|
236
|
+
<summary><b>Organic</b> · 10 — Playful, physical motion with personality.</summary>
|
|
237
|
+
|
|
238
|
+
| variant | what it looks like |
|
|
239
|
+
|---|---|
|
|
240
|
+
| `heart` | a heartbeat: a rotated square with two round lobes |
|
|
241
|
+
| `moon` | a crescent turning through its phases |
|
|
242
|
+
| `sun` | a core with rays reaching out |
|
|
243
|
+
| `flame` | a flickering teardrop |
|
|
244
|
+
| `bubble` | bubbles rising and popping |
|
|
245
|
+
| `jelly` | squash and stretch |
|
|
246
|
+
| `spring` | a coil compressing and releasing |
|
|
247
|
+
| `float` | an orb bobbing over its shadow |
|
|
248
|
+
| `leaf` | a teardrop tumbling as it turns |
|
|
249
|
+
| `windmill` | four blades turning together |
|
|
250
|
+
|
|
251
|
+
</details>
|
|
252
|
+
|
|
253
|
+
<details>
|
|
254
|
+
<summary><b>Skeletons</b> · 10 — Content-shaped placeholders — use these over spinners for page loads.</summary>
|
|
255
|
+
|
|
256
|
+
| variant | what it looks like |
|
|
257
|
+
|---|---|
|
|
258
|
+
| `shimmer` | a single sweeping block |
|
|
259
|
+
| `sk-text` | three lines of copy |
|
|
260
|
+
| `sk-card` | thumbnail with two lines beside it |
|
|
261
|
+
| `sk-avatar` | a circle and a name line |
|
|
262
|
+
| `sk-image` | a framed image placeholder |
|
|
263
|
+
| `sk-list` | stacked rows with leading bullets |
|
|
264
|
+
| `sk-table` | a header row above body rows |
|
|
265
|
+
| `sk-chip` | a row of tag placeholders |
|
|
266
|
+
| `sk-paragraph` | four lines of body copy |
|
|
267
|
+
| `sk-media` | a 16:9 block with a caption under it |
|
|
268
|
+
|
|
269
|
+
</details>
|
|
270
|
+
|
|
271
|
+
<details>
|
|
272
|
+
<summary><b>Dimensional</b> · 10 — Depth, 3D rotation, and orbital motion.</summary>
|
|
273
|
+
|
|
274
|
+
| variant | what it looks like |
|
|
275
|
+
|---|---|
|
|
276
|
+
| `helix` | two strands weaving past each other |
|
|
277
|
+
| `pendulum` | a Newton's cradle |
|
|
278
|
+
| `atom` | electron shells around a nucleus |
|
|
279
|
+
| `gyro` | nested rings turning on different axes |
|
|
280
|
+
| `coil` | stacked rings travelling down a spring |
|
|
281
|
+
| `vortex` | arcs drawn into a funnel |
|
|
282
|
+
| `prism` | three gradient triangles orbiting a centre |
|
|
283
|
+
| `torus` | a ring tumbling in 3D |
|
|
284
|
+
| `cylinder` | stacked ellipses rolling downward |
|
|
285
|
+
| `galaxy` | dots spiralling out from the core |
|
|
286
|
+
|
|
287
|
+
</details>
|
|
288
|
+
|
|
289
|
+
## Theming
|
|
290
|
+
|
|
291
|
+
The `colors` prop covers most cases. For anything else, override the custom properties — they
|
|
292
|
+
cascade, so one rule themes a whole subtree:
|
|
293
|
+
|
|
294
|
+
```css
|
|
295
|
+
.dashboard {
|
|
296
|
+
--c1: #6366f1; /* primary */
|
|
297
|
+
--c2: #ec4899; /* secondary */
|
|
298
|
+
--c3: #22d3ee; /* tertiary */
|
|
299
|
+
--size: 64px; /* box size */
|
|
300
|
+
--speed: .9s; /* base duration */
|
|
301
|
+
|
|
302
|
+
--track: #1e1e2e; /* rail behind progress bars */
|
|
303
|
+
--grad: linear-gradient(90deg, var(--c1), var(--c3)); /* shared gradient */
|
|
304
|
+
}
|
|
103
305
|
```
|
|
104
306
|
|
|
105
|
-
|
|
307
|
+
`--track` and `--grad` derive from `--c1`–`--c3` automatically; set them directly for finer control.
|
|
106
308
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
309
|
+
## Accessibility
|
|
310
|
+
|
|
311
|
+
- Each loader renders as `role="status"` with `aria-label`, so assistive tech announces it once.
|
|
312
|
+
- A decorative loader — one sitting beside visible "Loading…" text — should take `label={null}`,
|
|
313
|
+
which switches it to `aria-hidden` and prevents a double announcement.
|
|
314
|
+
- Under `prefers-reduced-motion: reduce`, every animation slows to a single calm 4s linear cycle
|
|
315
|
+
rather than stopping. A frozen loader reads as a crashed app, which is worse than gentle motion.
|
|
316
|
+
|
|
317
|
+
## Bundle size
|
|
318
|
+
|
|
319
|
+
| | raw | gzipped |
|
|
320
|
+
|---|---|---|
|
|
321
|
+
| JS | ~7 kB | **~2 kB** |
|
|
322
|
+
| CSS (all 100 variants) | ~58 kB | **~8 kB** |
|
|
323
|
+
|
|
324
|
+
One caveat, stated plainly: **the CSS is not tree-shakeable.** Class-based styles cannot be
|
|
325
|
+
dead-code eliminated, so importing a single variant still ships the sheet for all 100. That is a
|
|
326
|
+
fair trade for most apps. If you need only a handful and every kilobyte counts, copy the specific
|
|
327
|
+
`.ldr--*` blocks out of [`src/styles/`](./src/styles) into your own CSS and skip the package.
|
|
328
|
+
|
|
329
|
+
## Named exports
|
|
330
|
+
|
|
331
|
+
`Loader` is the main export. The original ten also have wrappers, kept for backward compatibility
|
|
332
|
+
with 1.0.x:
|
|
333
|
+
|
|
334
|
+
```tsx
|
|
335
|
+
import { Aurora, Orbit, Rings, Wave, Bars, Blob, Cube, Spiral, Bar, Grid } from "modern-loaders";
|
|
110
336
|
```
|
|
111
337
|
|
|
338
|
+
The other 90 are reached with `<Loader variant="…" />`. A hundred named exports would bloat the
|
|
339
|
+
API surface for no real gain.
|
|
340
|
+
|
|
112
341
|
## Browser support
|
|
113
342
|
|
|
114
|
-
|
|
115
|
-
Older browsers degrade to solid shapes rather than breaking.
|
|
343
|
+
Chrome 111+ · Safari 16.2+ · Firefox 113+ — the floor is set by `color-mix()`, alongside `mask`,
|
|
344
|
+
`aspect-ratio`, and `clip-path`. Older browsers degrade to solid shapes rather than breaking.
|
|
345
|
+
|
|
346
|
+
## Development
|
|
347
|
+
|
|
348
|
+
```bash
|
|
349
|
+
npm run dev # demo gallery: search, family tabs, live palette / size / speed controls
|
|
350
|
+
npm run build # typecheck, then emit dist/ (ESM + CJS + .d.ts + CSS)
|
|
351
|
+
npm run build:demo # static demo site → dist-demo/
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
Adding a variant takes two edits: a `.ldr--<id>` block in `src/styles/`, and a row in
|
|
355
|
+
[`src/variants.ts`](./src/variants.ts). The component, the types, and the demo all read from that
|
|
356
|
+
one manifest.
|
|
357
|
+
|
|
358
|
+
## License
|
|
359
|
+
|
|
360
|
+
ISC © suman
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require('./index.css');const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require('./index.css');const e=require("react/jsx-runtime"),n=[{id:"aurora",label:"Aurora",group:"Spinners",cells:0},{id:"spiral",label:"Spiral",group:"Spinners",cells:0},{id:"ring-dash",label:"Ring Dash",group:"Spinners",cells:0},{id:"ring-gap",label:"Ring Gap",group:"Spinners",cells:0},{id:"comet",label:"Comet",group:"Spinners",cells:1},{id:"arc-trio",label:"Arc Trio",group:"Spinners",cells:3},{id:"halo",label:"Halo",group:"Spinners",cells:1},{id:"sweep",label:"Sweep",group:"Spinners",cells:0},{id:"dot-ring",label:"Dot Ring",group:"Spinners",cells:8},{id:"petal",label:"Petal",group:"Spinners",cells:8},{id:"wave",label:"Wave",group:"Dots",cells:5},{id:"orbit",label:"Orbit",group:"Dots",cells:3},{id:"bounce",label:"Bounce",group:"Dots",cells:3},{id:"fade-dots",label:"Fade Dots",group:"Dots",cells:3},{id:"pulse-dots",label:"Pulse Dots",group:"Dots",cells:3},{id:"typing",label:"Typing",group:"Dots",cells:3},{id:"chase",label:"Chase",group:"Dots",cells:6},{id:"snake",label:"Snake",group:"Dots",cells:5},{id:"swap",label:"Swap",group:"Dots",cells:2},{id:"juggle",label:"Juggle",group:"Dots",cells:3},{id:"bars",label:"Bars",group:"Bars",cells:5},{id:"ladder",label:"Ladder",group:"Bars",cells:4},{id:"stretch",label:"Stretch",group:"Bars",cells:5},{id:"flip-bars",label:"Flip Bars",group:"Bars",cells:5},{id:"slide-bars",label:"Slide Bars",group:"Bars",cells:3},{id:"drop-bars",label:"Drop Bars",group:"Bars",cells:5},{id:"meter",label:"Meter",group:"Bars",cells:5},{id:"wave-bars",label:"Wave Bars",group:"Bars",cells:7},{id:"split-bars",label:"Split Bars",group:"Bars",cells:4},{id:"scan-bars",label:"Scan Bars",group:"Bars",cells:6},{id:"blob",label:"Blob",group:"Shapes",cells:0},{id:"cube",label:"Cube",group:"Shapes",cells:2},{id:"triangle",label:"Triangle",group:"Shapes",cells:0},{id:"hexagon",label:"Hexagon",group:"Shapes",cells:0},{id:"diamond",label:"Diamond",group:"Shapes",cells:0},{id:"star",label:"Star",group:"Shapes",cells:0},{id:"squircle",label:"Squircle",group:"Shapes",cells:0},{id:"folding",label:"Folding",group:"Shapes",cells:4},{id:"pentagon",label:"Pentagon",group:"Shapes",cells:0},{id:"shape-shift",label:"Shape Shift",group:"Shapes",cells:0},{id:"bar",label:"Bar",group:"Progress",cells:0},{id:"bar-stripes",label:"Bar Stripes",group:"Progress",cells:0},{id:"bar-dual",label:"Bar Dual",group:"Progress",cells:0},{id:"bar-segments",label:"Bar Segments",group:"Progress",cells:5},{id:"bar-pill",label:"Bar Pill",group:"Progress",cells:0},{id:"bar-glow",label:"Bar Glow",group:"Progress",cells:0},{id:"bar-wave",label:"Bar Wave",group:"Progress",cells:0},{id:"bar-dots",label:"Bar Dots",group:"Progress",cells:5},{id:"bar-snake",label:"Bar Snake",group:"Progress",cells:0},{id:"bar-fill",label:"Bar Fill",group:"Progress",cells:0},{id:"grid",label:"Grid",group:"Grids",cells:9},{id:"checker",label:"Checker",group:"Grids",cells:9},{id:"cascade",label:"Cascade",group:"Grids",cells:9},{id:"tiles",label:"Tiles",group:"Grids",cells:9},{id:"pixel",label:"Pixel",group:"Grids",cells:16},{id:"matrix",label:"Matrix",group:"Grids",cells:9},{id:"mosaic",label:"Mosaic",group:"Grids",cells:9},{id:"ripple-grid",label:"Ripple Grid",group:"Grids",cells:9},{id:"domino",label:"Domino",group:"Grids",cells:9},{id:"sparkle",label:"Sparkle",group:"Grids",cells:9},{id:"rings",label:"Rings",group:"Pulses",cells:3},{id:"radar",label:"Radar",group:"Pulses",cells:2},{id:"sonar",label:"Sonar",group:"Pulses",cells:3},{id:"echo",label:"Echo",group:"Pulses",cells:3},{id:"shockwave",label:"Shockwave",group:"Pulses",cells:2},{id:"bloom",label:"Bloom",group:"Pulses",cells:3},{id:"droplet",label:"Droplet",group:"Pulses",cells:2},{id:"concentric",label:"Concentric",group:"Pulses",cells:3},{id:"aura",label:"Aura",group:"Pulses",cells:1},{id:"beacon",label:"Beacon",group:"Pulses",cells:2},{id:"heart",label:"Heart",group:"Organic",cells:0},{id:"moon",label:"Moon",group:"Organic",cells:0},{id:"sun",label:"Sun",group:"Organic",cells:8},{id:"flame",label:"Flame",group:"Organic",cells:0},{id:"bubble",label:"Bubble",group:"Organic",cells:3},{id:"jelly",label:"Jelly",group:"Organic",cells:0},{id:"spring",label:"Spring",group:"Organic",cells:0},{id:"float",label:"Float",group:"Organic",cells:1},{id:"leaf",label:"Leaf",group:"Organic",cells:0},{id:"windmill",label:"Windmill",group:"Organic",cells:4},{id:"shimmer",label:"Shimmer",group:"Skeletons",cells:0},{id:"sk-text",label:"Text",group:"Skeletons",cells:3},{id:"sk-card",label:"Card",group:"Skeletons",cells:3},{id:"sk-avatar",label:"Avatar",group:"Skeletons",cells:2},{id:"sk-image",label:"Image",group:"Skeletons",cells:0},{id:"sk-list",label:"List",group:"Skeletons",cells:3},{id:"sk-table",label:"Table",group:"Skeletons",cells:4},{id:"sk-chip",label:"Chips",group:"Skeletons",cells:3},{id:"sk-paragraph",label:"Paragraph",group:"Skeletons",cells:4},{id:"sk-media",label:"Media",group:"Skeletons",cells:2},{id:"helix",label:"Helix",group:"Dimensional",cells:8},{id:"pendulum",label:"Pendulum",group:"Dimensional",cells:5},{id:"atom",label:"Atom",group:"Dimensional",cells:3},{id:"gyro",label:"Gyro",group:"Dimensional",cells:3},{id:"coil",label:"Coil",group:"Dimensional",cells:5},{id:"vortex",label:"Vortex",group:"Dimensional",cells:4},{id:"prism",label:"Prism",group:"Dimensional",cells:3},{id:"torus",label:"Torus",group:"Dimensional",cells:0},{id:"cylinder",label:"Cylinder",group:"Dimensional",cells:4},{id:"galaxy",label:"Galaxy",group:"Dimensional",cells:6}],b=[{name:"Spinners",description:"Rings and arcs — the classic shape, modernised."},{name:"Dots",description:"Small, quiet, and good inline with text."},{name:"Bars",description:"Equalizer-style motion with a strong rhythm."},{name:"Shapes",description:"Geometry that morphs, folds, and turns."},{name:"Progress",description:"Wide, indeterminate tracks for page and upload states."},{name:"Grids",description:"Cell fields that pulse, flip, and cascade."},{name:"Pulses",description:"Expanding rings for live, waiting, or listening states."},{name:"Organic",description:"Playful, physical motion with personality."},{name:"Skeletons",description:"Content-shaped placeholders — use these over spinners for page loads."},{name:"Dimensional",description:"Depth, 3D rotation, and orbital motion."}],m=n.map(l=>l.id),S=Object.fromEntries(n.map(l=>[l.id,l.cells])),d=(l,i)=>typeof l=="number"?`${l}${i}`:l;function s({variant:l="aurora",size:i=48,speed:p=1,colors:a,label:o="Loading",className:c,style:g,...t}){const r={"--size":d(i,"px"),"--speed":d(p,"s")};return a!=null&&a.length&&(r["--c1"]=a[0],r["--c2"]=a[1%a.length],r["--c3"]=a[2%a.length]),e.jsx("div",{...t,className:["ldr",`ldr--${l}`,c].filter(Boolean).join(" "),style:{...r,...g},role:o?"status":void 0,"aria-label":o??void 0,"aria-hidden":o?void 0:!0,children:Array.from({length:S[l]??0},(O,u)=>e.jsx("span",{},u))})}const h=l=>e.jsx(s,{variant:"aurora",...l}),B=l=>e.jsx(s,{variant:"orbit",...l}),D=l=>e.jsx(s,{variant:"rings",...l}),P=l=>e.jsx(s,{variant:"wave",...l}),k=l=>e.jsx(s,{variant:"bars",...l}),x=l=>e.jsx(s,{variant:"blob",...l}),v=l=>e.jsx(s,{variant:"cube",...l}),f=l=>e.jsx(s,{variant:"spiral",...l}),G=l=>e.jsx(s,{variant:"bar",...l}),y=l=>e.jsx(s,{variant:"grid",...l});exports.Aurora=h;exports.Bar=G;exports.Bars=k;exports.Blob=x;exports.Cube=v;exports.GROUPS=b;exports.Grid=y;exports.LOADER_VARIANTS=m;exports.Loader=s;exports.Orbit=B;exports.Rings=D;exports.Spiral=f;exports.VARIANTS=n;exports.Wave=P;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../src/Loader.tsx"],"sourcesContent":["import type { CSSProperties, HTMLAttributes } from \"react\";\nimport \"./loaders.css\";\n\nexport const LOADER_VARIANTS = [\n \"aurora\",\n \"orbit\",\n \"rings\",\n \"wave\",\n \"bars\",\n \"blob\",\n \"cube\",\n \"spiral\",\n \"bar\",\n \"grid\",\n] as const;\n\nexport type LoaderVariant = (typeof LOADER_VARIANTS)[number];\n\n/** How many <span> children each variant's CSS expects. */\nconst CELLS: Record<LoaderVariant, number> = {\n aurora: 0,\n orbit: 3,\n rings: 3,\n wave: 5,\n bars: 5,\n blob: 0,\n cube: 2,\n spiral: 0,\n bar: 0,\n grid: 9,\n};\n\nexport interface LoaderProps extends Omit<HTMLAttributes<HTMLDivElement>, \"color\"> {\n /** Which loader to render. @default \"aurora\" */\n variant?: LoaderVariant;\n /** Box size. A number is treated as pixels. @default 48 */\n size?: number | string;\n /** Base animation duration. A number is treated as seconds. @default 1 */\n speed?: number | string;\n /**\n * One to three colors. Fewer than three are cycled, so a single color still\n * produces a coherent (monochrome) loader.\n */\n colors?: string[];\n /** Announced to screen readers. Pass `null` to render the loader as decorative. */\n label?: string | null;\n}\n\nconst unit = (v: number | string | undefined, suffix: string) =>\n typeof v === \"number\" ? `${v}${suffix}` : v;\n\nexport function Loader({\n variant = \"aurora\",\n size = 48,\n speed = 1,\n colors,\n label = \"Loading\",\n className,\n style,\n ...rest\n}: LoaderProps) {\n const vars: CSSProperties & Record<string, string | undefined> = {\n \"--size\": unit(size, \"px\"),\n \"--speed\": unit(speed, \"s\"),\n };\n\n if (colors?.length) {\n // Cycle whatever was given across the three slots the CSS reads.\n vars[\"--c1\"] = colors[0];\n vars[\"--c2\"] = colors[1 % colors.length];\n vars[\"--c3\"] = colors[2 % colors.length];\n }\n\n const cells = CELLS[variant];\n\n return (\n <div\n {...rest}\n className={[\"ldr\", `ldr--${variant}`, className].filter(Boolean).join(\" \")}\n style={{ ...vars, ...style }}\n role={label ? \"status\" : undefined}\n aria-label={label ?? undefined}\n aria-hidden={label ? undefined : true}\n >\n {Array.from({ length: cells }, (_, i) => (\n <span key={i} />\n ))}\n </div>\n );\n}\n\n/** Convenience wrappers, so `<Aurora />` works as well as `<Loader variant=\"aurora\" />`. */\ntype VariantProps = Omit<LoaderProps, \"variant\">;\n\nexport const Aurora = (p: VariantProps) => <Loader variant=\"aurora\" {...p} />;\nexport const Orbit = (p: VariantProps) => <Loader variant=\"orbit\" {...p} />;\nexport const Rings = (p: VariantProps) => <Loader variant=\"rings\" {...p} />;\nexport const Wave = (p: VariantProps) => <Loader variant=\"wave\" {...p} />;\nexport const Bars = (p: VariantProps) => <Loader variant=\"bars\" {...p} />;\nexport const Blob = (p: VariantProps) => <Loader variant=\"blob\" {...p} />;\nexport const Cube = (p: VariantProps) => <Loader variant=\"cube\" {...p} />;\nexport const Spiral = (p: VariantProps) => <Loader variant=\"spiral\" {...p} />;\nexport const Bar = (p: VariantProps) => <Loader variant=\"bar\" {...p} />;\nexport const Grid = (p: VariantProps) => <Loader variant=\"grid\" {...p} />;\n"],"names":["LOADER_VARIANTS","CELLS","unit","v","suffix","Loader","variant","size","speed","colors","label","className","style","rest","vars","cells","jsx","_","i","Aurora","p","Orbit","Rings","Wave","Bars","Blob","Cube","Spiral","Bar","Grid"],"mappings":"qHAGaA,EAAkB,CAC7B,SACA,QACA,QACA,OACA,OACA,OACA,OACA,SACA,MACA,MACF,EAKMC,EAAuC,CAC3C,OAAQ,EACR,MAAO,EACP,MAAO,EACP,KAAM,EACN,KAAM,EACN,KAAM,EACN,KAAM,EACN,OAAQ,EACR,IAAK,EACL,KAAM,CACR,EAkBMC,EAAO,CAACC,EAAgCC,IAC5C,OAAOD,GAAM,SAAW,GAAGA,CAAC,GAAGC,CAAM,GAAKD,EAErC,SAASE,EAAO,CACrB,QAAAC,EAAU,SACV,KAAAC,EAAO,GACP,MAAAC,EAAQ,EACR,OAAAC,EACA,MAAAC,EAAQ,UACR,UAAAC,EACA,MAAAC,EACA,GAAGC,CACL,EAAgB,CACd,MAAMC,EAA2D,CAC/D,SAAUZ,EAAKK,EAAM,IAAI,EACzB,UAAWL,EAAKM,EAAO,GAAG,CAAA,EAGxBC,GAAA,MAAAA,EAAQ,SAEVK,EAAK,MAAM,EAAIL,EAAO,CAAC,EACvBK,EAAK,MAAM,EAAIL,EAAO,EAAIA,EAAO,MAAM,EACvCK,EAAK,MAAM,EAAIL,EAAO,EAAIA,EAAO,MAAM,GAGzC,MAAMM,EAAQd,EAAMK,CAAO,EAE3B,OACEU,EAAAA,IAAC,MAAA,CACE,GAAGH,EACJ,UAAW,CAAC,MAAO,QAAQP,CAAO,GAAIK,CAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,EACzE,MAAO,CAAE,GAAGG,EAAM,GAAGF,CAAA,EACrB,KAAMF,EAAQ,SAAW,OACzB,aAAYA,GAAS,OACrB,cAAaA,EAAQ,OAAY,GAEhC,SAAA,MAAM,KAAK,CAAE,OAAQK,CAAA,EAAS,CAACE,EAAGC,IACjCF,EAAAA,IAAC,OAAA,CAAA,EAAUE,CAAG,CACf,CAAA,CAAA,CAGP,CAKO,MAAMC,EAAUC,GAAoBJ,MAACX,GAAO,QAAQ,SAAU,GAAGe,CAAA,CAAG,EAC9DC,EAAUD,GAAoBJ,MAACX,GAAO,QAAQ,QAAU,GAAGe,CAAA,CAAG,EAC9DE,EAAUF,GAAoBJ,MAACX,GAAO,QAAQ,QAAU,GAAGe,CAAA,CAAG,EAC9DG,EAAUH,GAAoBJ,MAACX,GAAO,QAAQ,OAAU,GAAGe,CAAA,CAAG,EAC9DI,EAAUJ,GAAoBJ,MAACX,GAAO,QAAQ,OAAU,GAAGe,CAAA,CAAG,EAC9DK,EAAUL,GAAoBJ,MAACX,GAAO,QAAQ,OAAU,GAAGe,CAAA,CAAG,EAC9DM,EAAUN,GAAoBJ,MAACX,GAAO,QAAQ,OAAU,GAAGe,CAAA,CAAG,EAC9DO,EAAUP,GAAoBJ,MAACX,GAAO,QAAQ,SAAU,GAAGe,CAAA,CAAG,EAC9DQ,EAAUR,GAAoBJ,MAACX,GAAO,QAAQ,MAAU,GAAGe,CAAA,CAAG,EAC9DS,EAAUT,GAAoBJ,MAACX,GAAO,QAAQ,OAAU,GAAGe,CAAA,CAAG"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/variants.ts","../src/Loader.tsx"],"sourcesContent":["/**\n * The single source of truth for every loader.\n * `id` must match a `.ldr--<id>` class in ./styles, and `cells` is how many\n * <span> children that variant's CSS expects.\n */\nexport const VARIANTS = [\n // ---- Spinners ----\n { id: \"aurora\", label: \"Aurora\", group: \"Spinners\", cells: 0 },\n { id: \"spiral\", label: \"Spiral\", group: \"Spinners\", cells: 0 },\n { id: \"ring-dash\", label: \"Ring Dash\", group: \"Spinners\", cells: 0 },\n { id: \"ring-gap\", label: \"Ring Gap\", group: \"Spinners\", cells: 0 },\n { id: \"comet\", label: \"Comet\", group: \"Spinners\", cells: 1 },\n { id: \"arc-trio\", label: \"Arc Trio\", group: \"Spinners\", cells: 3 },\n { id: \"halo\", label: \"Halo\", group: \"Spinners\", cells: 1 },\n { id: \"sweep\", label: \"Sweep\", group: \"Spinners\", cells: 0 },\n { id: \"dot-ring\", label: \"Dot Ring\", group: \"Spinners\", cells: 8 },\n { id: \"petal\", label: \"Petal\", group: \"Spinners\", cells: 8 },\n // ---- Dots ----\n { id: \"wave\", label: \"Wave\", group: \"Dots\", cells: 5 },\n { id: \"orbit\", label: \"Orbit\", group: \"Dots\", cells: 3 },\n { id: \"bounce\", label: \"Bounce\", group: \"Dots\", cells: 3 },\n { id: \"fade-dots\", label: \"Fade Dots\", group: \"Dots\", cells: 3 },\n { id: \"pulse-dots\", label: \"Pulse Dots\", group: \"Dots\", cells: 3 },\n { id: \"typing\", label: \"Typing\", group: \"Dots\", cells: 3 },\n { id: \"chase\", label: \"Chase\", group: \"Dots\", cells: 6 },\n { id: \"snake\", label: \"Snake\", group: \"Dots\", cells: 5 },\n { id: \"swap\", label: \"Swap\", group: \"Dots\", cells: 2 },\n { id: \"juggle\", label: \"Juggle\", group: \"Dots\", cells: 3 },\n // ---- Bars ----\n { id: \"bars\", label: \"Bars\", group: \"Bars\", cells: 5 },\n { id: \"ladder\", label: \"Ladder\", group: \"Bars\", cells: 4 },\n { id: \"stretch\", label: \"Stretch\", group: \"Bars\", cells: 5 },\n { id: \"flip-bars\", label: \"Flip Bars\", group: \"Bars\", cells: 5 },\n { id: \"slide-bars\", label: \"Slide Bars\", group: \"Bars\", cells: 3 },\n { id: \"drop-bars\", label: \"Drop Bars\", group: \"Bars\", cells: 5 },\n { id: \"meter\", label: \"Meter\", group: \"Bars\", cells: 5 },\n { id: \"wave-bars\", label: \"Wave Bars\", group: \"Bars\", cells: 7 },\n { id: \"split-bars\", label: \"Split Bars\", group: \"Bars\", cells: 4 },\n { id: \"scan-bars\", label: \"Scan Bars\", group: \"Bars\", cells: 6 },\n // ---- Shapes ----\n { id: \"blob\", label: \"Blob\", group: \"Shapes\", cells: 0 },\n { id: \"cube\", label: \"Cube\", group: \"Shapes\", cells: 2 },\n { id: \"triangle\", label: \"Triangle\", group: \"Shapes\", cells: 0 },\n { id: \"hexagon\", label: \"Hexagon\", group: \"Shapes\", cells: 0 },\n { id: \"diamond\", label: \"Diamond\", group: \"Shapes\", cells: 0 },\n { id: \"star\", label: \"Star\", group: \"Shapes\", cells: 0 },\n { id: \"squircle\", label: \"Squircle\", group: \"Shapes\", cells: 0 },\n { id: \"folding\", label: \"Folding\", group: \"Shapes\", cells: 4 },\n { id: \"pentagon\", label: \"Pentagon\", group: \"Shapes\", cells: 0 },\n { id: \"shape-shift\", label: \"Shape Shift\", group: \"Shapes\", cells: 0 },\n // ---- Progress ----\n { id: \"bar\", label: \"Bar\", group: \"Progress\", cells: 0 },\n { id: \"bar-stripes\", label: \"Bar Stripes\", group: \"Progress\", cells: 0 },\n { id: \"bar-dual\", label: \"Bar Dual\", group: \"Progress\", cells: 0 },\n { id: \"bar-segments\", label: \"Bar Segments\", group: \"Progress\", cells: 5 },\n { id: \"bar-pill\", label: \"Bar Pill\", group: \"Progress\", cells: 0 },\n { id: \"bar-glow\", label: \"Bar Glow\", group: \"Progress\", cells: 0 },\n { id: \"bar-wave\", label: \"Bar Wave\", group: \"Progress\", cells: 0 },\n { id: \"bar-dots\", label: \"Bar Dots\", group: \"Progress\", cells: 5 },\n { id: \"bar-snake\", label: \"Bar Snake\", group: \"Progress\", cells: 0 },\n { id: \"bar-fill\", label: \"Bar Fill\", group: \"Progress\", cells: 0 },\n // ---- Grids ----\n { id: \"grid\", label: \"Grid\", group: \"Grids\", cells: 9 },\n { id: \"checker\", label: \"Checker\", group: \"Grids\", cells: 9 },\n { id: \"cascade\", label: \"Cascade\", group: \"Grids\", cells: 9 },\n { id: \"tiles\", label: \"Tiles\", group: \"Grids\", cells: 9 },\n { id: \"pixel\", label: \"Pixel\", group: \"Grids\", cells: 16 },\n { id: \"matrix\", label: \"Matrix\", group: \"Grids\", cells: 9 },\n { id: \"mosaic\", label: \"Mosaic\", group: \"Grids\", cells: 9 },\n { id: \"ripple-grid\", label: \"Ripple Grid\", group: \"Grids\", cells: 9 },\n { id: \"domino\", label: \"Domino\", group: \"Grids\", cells: 9 },\n { id: \"sparkle\", label: \"Sparkle\", group: \"Grids\", cells: 9 },\n // ---- Pulses ----\n { id: \"rings\", label: \"Rings\", group: \"Pulses\", cells: 3 },\n { id: \"radar\", label: \"Radar\", group: \"Pulses\", cells: 2 },\n { id: \"sonar\", label: \"Sonar\", group: \"Pulses\", cells: 3 },\n { id: \"echo\", label: \"Echo\", group: \"Pulses\", cells: 3 },\n { id: \"shockwave\", label: \"Shockwave\", group: \"Pulses\", cells: 2 },\n { id: \"bloom\", label: \"Bloom\", group: \"Pulses\", cells: 3 },\n { id: \"droplet\", label: \"Droplet\", group: \"Pulses\", cells: 2 },\n { id: \"concentric\", label: \"Concentric\", group: \"Pulses\", cells: 3 },\n { id: \"aura\", label: \"Aura\", group: \"Pulses\", cells: 1 },\n { id: \"beacon\", label: \"Beacon\", group: \"Pulses\", cells: 2 },\n // ---- Organic ----\n { id: \"heart\", label: \"Heart\", group: \"Organic\", cells: 0 },\n { id: \"moon\", label: \"Moon\", group: \"Organic\", cells: 0 },\n { id: \"sun\", label: \"Sun\", group: \"Organic\", cells: 8 },\n { id: \"flame\", label: \"Flame\", group: \"Organic\", cells: 0 },\n { id: \"bubble\", label: \"Bubble\", group: \"Organic\", cells: 3 },\n { id: \"jelly\", label: \"Jelly\", group: \"Organic\", cells: 0 },\n { id: \"spring\", label: \"Spring\", group: \"Organic\", cells: 0 },\n { id: \"float\", label: \"Float\", group: \"Organic\", cells: 1 },\n { id: \"leaf\", label: \"Leaf\", group: \"Organic\", cells: 0 },\n { id: \"windmill\", label: \"Windmill\", group: \"Organic\", cells: 4 },\n // ---- Skeletons ----\n { id: \"shimmer\", label: \"Shimmer\", group: \"Skeletons\", cells: 0 },\n { id: \"sk-text\", label: \"Text\", group: \"Skeletons\", cells: 3 },\n { id: \"sk-card\", label: \"Card\", group: \"Skeletons\", cells: 3 },\n { id: \"sk-avatar\", label: \"Avatar\", group: \"Skeletons\", cells: 2 },\n { id: \"sk-image\", label: \"Image\", group: \"Skeletons\", cells: 0 },\n { id: \"sk-list\", label: \"List\", group: \"Skeletons\", cells: 3 },\n { id: \"sk-table\", label: \"Table\", group: \"Skeletons\", cells: 4 },\n { id: \"sk-chip\", label: \"Chips\", group: \"Skeletons\", cells: 3 },\n { id: \"sk-paragraph\", label: \"Paragraph\", group: \"Skeletons\", cells: 4 },\n { id: \"sk-media\", label: \"Media\", group: \"Skeletons\", cells: 2 },\n // ---- Dimensional ----\n { id: \"helix\", label: \"Helix\", group: \"Dimensional\", cells: 8 },\n { id: \"pendulum\", label: \"Pendulum\", group: \"Dimensional\", cells: 5 },\n { id: \"atom\", label: \"Atom\", group: \"Dimensional\", cells: 3 },\n { id: \"gyro\", label: \"Gyro\", group: \"Dimensional\", cells: 3 },\n { id: \"coil\", label: \"Coil\", group: \"Dimensional\", cells: 5 },\n { id: \"vortex\", label: \"Vortex\", group: \"Dimensional\", cells: 4 },\n { id: \"prism\", label: \"Prism\", group: \"Dimensional\", cells: 3 },\n { id: \"torus\", label: \"Torus\", group: \"Dimensional\", cells: 0 },\n { id: \"cylinder\", label: \"Cylinder\", group: \"Dimensional\", cells: 4 },\n { id: \"galaxy\", label: \"Galaxy\", group: \"Dimensional\", cells: 6 },\n] as const;\n\nexport const GROUPS = [\n { name: \"Spinners\", description: \"Rings and arcs — the classic shape, modernised.\" },\n { name: \"Dots\", description: \"Small, quiet, and good inline with text.\" },\n { name: \"Bars\", description: \"Equalizer-style motion with a strong rhythm.\" },\n { name: \"Shapes\", description: \"Geometry that morphs, folds, and turns.\" },\n { name: \"Progress\", description: \"Wide, indeterminate tracks for page and upload states.\" },\n { name: \"Grids\", description: \"Cell fields that pulse, flip, and cascade.\" },\n { name: \"Pulses\", description: \"Expanding rings for live, waiting, or listening states.\" },\n { name: \"Organic\", description: \"Playful, physical motion with personality.\" },\n { name: \"Skeletons\", description: \"Content-shaped placeholders — use these over spinners for page loads.\" },\n { name: \"Dimensional\", description: \"Depth, 3D rotation, and orbital motion.\" },\n] as const;\n\nexport type LoaderVariant = (typeof VARIANTS)[number][\"id\"];\nexport type LoaderGroup = (typeof GROUPS)[number][\"name\"];\nexport type VariantMeta = (typeof VARIANTS)[number];\n","import type { CSSProperties, HTMLAttributes } from \"react\";\nimport { VARIANTS, type LoaderVariant } from \"./variants\";\nimport \"./loaders.css\";\n\nexport { VARIANTS, GROUPS } from \"./variants\";\nexport type { LoaderVariant, LoaderGroup, VariantMeta } from \"./variants\";\n\n/** Every variant id, in display order. */\nexport const LOADER_VARIANTS = VARIANTS.map((v) => v.id) as readonly LoaderVariant[];\n\n/** How many <span> children each variant's CSS expects. */\nconst CELLS = Object.fromEntries(VARIANTS.map((v) => [v.id, v.cells])) as Record<\n LoaderVariant,\n number\n>;\n\nexport interface LoaderProps extends Omit<HTMLAttributes<HTMLDivElement>, \"color\"> {\n /** Which loader to render. @default \"aurora\" */\n variant?: LoaderVariant;\n /** Box size. A number is treated as pixels. @default 48 */\n size?: number | string;\n /** Base animation duration. A number is treated as seconds. @default 1 */\n speed?: number | string;\n /**\n * One to three colors. Fewer than three are cycled, so a single color still\n * produces a coherent (monochrome) loader.\n */\n colors?: string[];\n /** Announced to screen readers. Pass `null` to render the loader as decorative. */\n label?: string | null;\n}\n\nconst unit = (v: number | string | undefined, suffix: string) =>\n typeof v === \"number\" ? `${v}${suffix}` : v;\n\nexport function Loader({\n variant = \"aurora\",\n size = 48,\n speed = 1,\n colors,\n label = \"Loading\",\n className,\n style,\n ...rest\n}: LoaderProps) {\n const vars: CSSProperties & Record<string, string | undefined> = {\n \"--size\": unit(size, \"px\"),\n \"--speed\": unit(speed, \"s\"),\n };\n\n if (colors?.length) {\n // Cycle whatever was given across the three slots the CSS reads.\n vars[\"--c1\"] = colors[0];\n vars[\"--c2\"] = colors[1 % colors.length];\n vars[\"--c3\"] = colors[2 % colors.length];\n }\n\n return (\n <div\n {...rest}\n className={[\"ldr\", `ldr--${variant}`, className].filter(Boolean).join(\" \")}\n style={{ ...vars, ...style }}\n role={label ? \"status\" : undefined}\n aria-label={label ?? undefined}\n aria-hidden={label ? undefined : true}\n >\n {Array.from({ length: CELLS[variant] ?? 0 }, (_, i) => (\n <span key={i} />\n ))}\n </div>\n );\n}\n\n/**\n * Named wrappers for the original ten variants, kept for backward compatibility\n * with 1.0.x. The other 90 are reached through `<Loader variant=\"…\" />` — a hundred\n * named exports would bloat the API surface for no real gain.\n */\ntype VariantProps = Omit<LoaderProps, \"variant\">;\n\nexport const Aurora = (p: VariantProps) => <Loader variant=\"aurora\" {...p} />;\nexport const Orbit = (p: VariantProps) => <Loader variant=\"orbit\" {...p} />;\nexport const Rings = (p: VariantProps) => <Loader variant=\"rings\" {...p} />;\nexport const Wave = (p: VariantProps) => <Loader variant=\"wave\" {...p} />;\nexport const Bars = (p: VariantProps) => <Loader variant=\"bars\" {...p} />;\nexport const Blob = (p: VariantProps) => <Loader variant=\"blob\" {...p} />;\nexport const Cube = (p: VariantProps) => <Loader variant=\"cube\" {...p} />;\nexport const Spiral = (p: VariantProps) => <Loader variant=\"spiral\" {...p} />;\nexport const Bar = (p: VariantProps) => <Loader variant=\"bar\" {...p} />;\nexport const Grid = (p: VariantProps) => <Loader variant=\"grid\" {...p} />;\n"],"names":["VARIANTS","GROUPS","LOADER_VARIANTS","v","CELLS","unit","suffix","Loader","variant","size","speed","colors","label","className","style","rest","vars","jsx","_","i","Aurora","p","Orbit","Rings","Wave","Bars","Blob","Cube","Spiral","Bar","Grid"],"mappings":"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"}
|