@ghostly-ui/core 0.2.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 +84 -0
- package/dist/ghostly.css +329 -0
- package/dist/index.cjs +84 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +37 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.js +51 -0
- package/dist/index.js.map +1 -0
- package/dist/tailwind.cjs +61 -0
- package/dist/tailwind.cjs.map +1 -0
- package/dist/tailwind.d.cts +148 -0
- package/dist/tailwind.d.ts +148 -0
- package/dist/tailwind.js +30 -0
- package/dist/tailwind.js.map +1 -0
- package/package.json +69 -0
package/README.md
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# @ghostly-ui/core
|
|
2
|
+
|
|
3
|
+
CSS-first skeleton loading engine. Zero dependencies. Framework-agnostic.
|
|
4
|
+
|
|
5
|
+
> Your component IS the skeleton. Ghostly uses CSS to hide text and images, replacing them with animated placeholders -- preserving the exact same layout.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @ghostly-ui/core
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
Import the CSS and add `data-ghostly` to any container:
|
|
16
|
+
|
|
17
|
+
```css
|
|
18
|
+
@import '@ghostly-ui/core/css';
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
```html
|
|
22
|
+
<div data-ghostly="shimmer">
|
|
23
|
+
<h2>This becomes a skeleton</h2>
|
|
24
|
+
<p>So does this</p>
|
|
25
|
+
<img src="photo.jpg" />
|
|
26
|
+
</div>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Remove the attribute to show real content. That's it.
|
|
30
|
+
|
|
31
|
+
## Features
|
|
32
|
+
|
|
33
|
+
- **3 animations** -- shimmer, pulse, wave (all pure CSS)
|
|
34
|
+
- **Dark mode** -- auto-detects via `.dark`, `data-theme="dark"`, or `prefers-color-scheme`
|
|
35
|
+
- **Accessible** -- `prefers-reduced-motion: reduce` disables animations
|
|
36
|
+
- **Zero specificity** -- uses `:where()` selectors, easy to override
|
|
37
|
+
- **Tiny** -- ~2KB gzipped, zero dependencies
|
|
38
|
+
|
|
39
|
+
## CSS Custom Properties
|
|
40
|
+
|
|
41
|
+
```css
|
|
42
|
+
:root {
|
|
43
|
+
--ghostly-color: hsl(220 13% 87%); /* skeleton base color */
|
|
44
|
+
--ghostly-shine: hsl(220 13% 94%); /* shimmer highlight */
|
|
45
|
+
--ghostly-radius: 4px; /* border radius */
|
|
46
|
+
--ghostly-speed: 1.5s; /* animation duration */
|
|
47
|
+
--ghostly-transition: 0.3s; /* fade-out transition */
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Data Attributes
|
|
52
|
+
|
|
53
|
+
| Attribute | Description |
|
|
54
|
+
|-----------|-------------|
|
|
55
|
+
| `data-ghostly="shimmer\|pulse\|wave"` | Activate skeleton on a container |
|
|
56
|
+
| `data-ghostly-ignore` | Exclude element from skeleton effect |
|
|
57
|
+
| `data-ghostly-lines="1-8"` | Control skeleton line count for text |
|
|
58
|
+
| `data-ghostly-ratio="16/9"` | Set aspect ratio for images |
|
|
59
|
+
| `data-ghostly-smooth` | Enable fade-out transition |
|
|
60
|
+
|
|
61
|
+
## Tailwind CSS Plugin
|
|
62
|
+
|
|
63
|
+
```js
|
|
64
|
+
// tailwind.config.js
|
|
65
|
+
import ghostly from '@ghostly-ui/core/tailwind'
|
|
66
|
+
|
|
67
|
+
export default {
|
|
68
|
+
plugins: [ghostly],
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Utilities: `ghostly-radius-*`, `ghostly-speed-*`, `ghostly-color-[...]`, `ghostly-shine-[...]`, `ghostly:` variant.
|
|
73
|
+
|
|
74
|
+
## Framework Adapters
|
|
75
|
+
|
|
76
|
+
- **[@ghostly-ui/react](https://www.npmjs.com/package/@ghostly-ui/react)** -- React components with `<Ghostly>`, `<GhostlyList>`, `<GhostlySuspense>`
|
|
77
|
+
|
|
78
|
+
## Documentation
|
|
79
|
+
|
|
80
|
+
Full docs at [ghostly.adanulissess.com](https://ghostly.adanulissess.com)
|
|
81
|
+
|
|
82
|
+
## License
|
|
83
|
+
|
|
84
|
+
MIT
|
package/dist/ghostly.css
ADDED
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
/* ============================================================
|
|
2
|
+
GHOSTLY — Zero-config skeleton loaders
|
|
3
|
+
|
|
4
|
+
Usage: add data-ghostly="shimmer|pulse|wave" to any container.
|
|
5
|
+
All leaf elements inside become skeleton blocks automatically.
|
|
6
|
+
============================================================ */
|
|
7
|
+
|
|
8
|
+
/* --- Custom properties (override these to customize) --- */
|
|
9
|
+
|
|
10
|
+
:root {
|
|
11
|
+
--ghostly-color: hsl(220 13% 87%);
|
|
12
|
+
--ghostly-shine: hsl(220 13% 94%);
|
|
13
|
+
--ghostly-radius: 4px;
|
|
14
|
+
--ghostly-speed: 1.5s;
|
|
15
|
+
--ghostly-transition: 0.3s;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/* --- Dark mode (automatic) --- */
|
|
19
|
+
|
|
20
|
+
.dark,
|
|
21
|
+
[data-theme='dark'] {
|
|
22
|
+
--ghostly-color: hsl(220 13% 18%);
|
|
23
|
+
--ghostly-shine: hsl(220 13% 25%);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
@media (prefers-color-scheme: dark) {
|
|
27
|
+
:root:not(.light):not([data-theme='light']) {
|
|
28
|
+
--ghostly-color: hsl(220 13% 18%);
|
|
29
|
+
--ghostly-shine: hsl(220 13% 25%);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/* ============================================================
|
|
34
|
+
1. SKELETON TARGET — shared base for all skeleton elements
|
|
35
|
+
============================================================ */
|
|
36
|
+
|
|
37
|
+
/* All targetable elements inside a ghostly container */
|
|
38
|
+
[data-ghostly] :where(
|
|
39
|
+
h1, h2, h3, h4, h5, h6,
|
|
40
|
+
p, span, a, li, td, th, dt, dd,
|
|
41
|
+
label, legend, figcaption, caption, summary,
|
|
42
|
+
blockquote, cite, q, em, strong, small, mark, code, pre,
|
|
43
|
+
button, input, textarea, select, option,
|
|
44
|
+
fieldset, dialog, details, address,
|
|
45
|
+
time, abbr, sub, sup, del, ins,
|
|
46
|
+
img, svg, video, canvas, picture, iframe
|
|
47
|
+
) {
|
|
48
|
+
--_ghostly-target: 1;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/* ============================================================
|
|
52
|
+
2. CONTAINER — Blocks interaction while loading
|
|
53
|
+
============================================================ */
|
|
54
|
+
|
|
55
|
+
[data-ghostly] {
|
|
56
|
+
pointer-events: none;
|
|
57
|
+
user-select: none;
|
|
58
|
+
cursor: default;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/* ============================================================
|
|
62
|
+
3. TEXT ELEMENTS — Become opaque skeleton blocks
|
|
63
|
+
============================================================ */
|
|
64
|
+
|
|
65
|
+
[data-ghostly] :where(
|
|
66
|
+
h1, h2, h3, h4, h5, h6,
|
|
67
|
+
p, span, a, li, td, th, dt, dd,
|
|
68
|
+
label, legend, figcaption, caption, summary,
|
|
69
|
+
blockquote, cite, q, em, strong, small, mark, code, pre,
|
|
70
|
+
button, input, textarea, select, option,
|
|
71
|
+
fieldset, dialog, details, address,
|
|
72
|
+
time, abbr, sub, sup, del, ins
|
|
73
|
+
) {
|
|
74
|
+
color: transparent !important;
|
|
75
|
+
background-color: var(--ghostly-color) !important;
|
|
76
|
+
background-image: none !important;
|
|
77
|
+
border-radius: var(--ghostly-radius) !important;
|
|
78
|
+
border-color: transparent !important;
|
|
79
|
+
box-shadow: none !important;
|
|
80
|
+
text-decoration: none !important;
|
|
81
|
+
outline: none !important;
|
|
82
|
+
min-height: 1em;
|
|
83
|
+
min-width: 2rem;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/* Headings get proportional min-height */
|
|
87
|
+
[data-ghostly] :where(h1) { min-height: 1.75em; min-width: 40%; }
|
|
88
|
+
[data-ghostly] :where(h2) { min-height: 1.5em; min-width: 50%; }
|
|
89
|
+
[data-ghostly] :where(h3) { min-height: 1.3em; min-width: 55%; }
|
|
90
|
+
[data-ghostly] :where(h4, h5, h6) { min-height: 1.15em; min-width: 45%; }
|
|
91
|
+
|
|
92
|
+
/* Paragraphs simulate multi-line text */
|
|
93
|
+
[data-ghostly] :where(p) { min-height: 3em; min-width: 80%; }
|
|
94
|
+
|
|
95
|
+
/* Code blocks need more height */
|
|
96
|
+
[data-ghostly] :where(pre) { min-height: 5em; min-width: 100%; }
|
|
97
|
+
|
|
98
|
+
/* Inputs keep their shape */
|
|
99
|
+
[data-ghostly] :where(input, textarea, select) {
|
|
100
|
+
min-height: 2.5rem;
|
|
101
|
+
min-width: 6rem;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/* Buttons keep their shape */
|
|
105
|
+
[data-ghostly] :where(button) {
|
|
106
|
+
min-height: 2.25rem;
|
|
107
|
+
min-width: 5rem;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/* ============================================================
|
|
111
|
+
4. CUSTOM LINE COUNT — data-ghostly-lines="N"
|
|
112
|
+
============================================================ */
|
|
113
|
+
|
|
114
|
+
[data-ghostly] :where([data-ghostly-lines="1"]) { min-height: 1em; }
|
|
115
|
+
[data-ghostly] :where([data-ghostly-lines="2"]) { min-height: 2em; }
|
|
116
|
+
[data-ghostly] :where([data-ghostly-lines="3"]) { min-height: 3em; }
|
|
117
|
+
[data-ghostly] :where([data-ghostly-lines="4"]) { min-height: 4em; }
|
|
118
|
+
[data-ghostly] :where([data-ghostly-lines="5"]) { min-height: 5em; }
|
|
119
|
+
[data-ghostly] :where([data-ghostly-lines="6"]) { min-height: 6em; }
|
|
120
|
+
[data-ghostly] :where([data-ghostly-lines="7"]) { min-height: 7em; }
|
|
121
|
+
[data-ghostly] :where([data-ghostly-lines="8"]) { min-height: 8em; }
|
|
122
|
+
|
|
123
|
+
/* ============================================================
|
|
124
|
+
5. MEDIA ELEMENTS — Become solid skeleton blocks
|
|
125
|
+
============================================================ */
|
|
126
|
+
|
|
127
|
+
[data-ghostly] :where(img, svg, video, canvas, picture, iframe) {
|
|
128
|
+
color: transparent !important;
|
|
129
|
+
background-color: var(--ghostly-color) !important;
|
|
130
|
+
border-radius: var(--ghostly-radius) !important;
|
|
131
|
+
border-color: transparent !important;
|
|
132
|
+
box-shadow: none !important;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/* Hide actual content (images, video frames) */
|
|
136
|
+
[data-ghostly] :where(img) {
|
|
137
|
+
object-position: -9999px;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
[data-ghostly] :where(video, iframe) {
|
|
141
|
+
opacity: 0;
|
|
142
|
+
background-color: var(--ghostly-color) !important;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/* Images without explicit dimensions — use aspect-ratio */
|
|
146
|
+
[data-ghostly] :where(img:not([width]):not([style*="width"]), picture:not([width])) {
|
|
147
|
+
aspect-ratio: 16/9;
|
|
148
|
+
width: 100%;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/* Custom aspect ratio via data attribute */
|
|
152
|
+
[data-ghostly] :where([data-ghostly-ratio="1/1"]) { aspect-ratio: 1/1 !important; }
|
|
153
|
+
[data-ghostly] :where([data-ghostly-ratio="4/3"]) { aspect-ratio: 4/3 !important; }
|
|
154
|
+
[data-ghostly] :where([data-ghostly-ratio="16/9"]) { aspect-ratio: 16/9 !important; }
|
|
155
|
+
[data-ghostly] :where([data-ghostly-ratio="21/9"]) { aspect-ratio: 21/9 !important; }
|
|
156
|
+
[data-ghostly] :where([data-ghostly-ratio="3/4"]) { aspect-ratio: 3/4 !important; }
|
|
157
|
+
[data-ghostly] :where([data-ghostly-ratio="9/16"]) { aspect-ratio: 9/16 !important; }
|
|
158
|
+
|
|
159
|
+
/* SVG icons (typically small) */
|
|
160
|
+
[data-ghostly] :where(svg) {
|
|
161
|
+
min-height: 1.5rem;
|
|
162
|
+
min-width: 1.5rem;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/* ============================================================
|
|
166
|
+
6. DECORATIVE — Strip visual noise
|
|
167
|
+
============================================================ */
|
|
168
|
+
|
|
169
|
+
[data-ghostly] :where(hr) {
|
|
170
|
+
border-color: var(--ghostly-color) !important;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
[data-ghostly] :where(
|
|
174
|
+
[class*="badge"],
|
|
175
|
+
[class*="chip"],
|
|
176
|
+
[class*="tag"],
|
|
177
|
+
[class*="avatar"]
|
|
178
|
+
) {
|
|
179
|
+
color: transparent !important;
|
|
180
|
+
background-color: var(--ghostly-color) !important;
|
|
181
|
+
background-image: none !important;
|
|
182
|
+
border-color: transparent !important;
|
|
183
|
+
box-shadow: none !important;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/* ============================================================
|
|
187
|
+
7. EXCLUSIONS — data-ghostly-ignore restores original styles
|
|
188
|
+
============================================================ */
|
|
189
|
+
|
|
190
|
+
[data-ghostly] [data-ghostly-ignore],
|
|
191
|
+
[data-ghostly] [data-ghostly-ignore] * {
|
|
192
|
+
color: inherit !important;
|
|
193
|
+
background-color: inherit !important;
|
|
194
|
+
background-image: initial !important;
|
|
195
|
+
border-color: inherit !important;
|
|
196
|
+
box-shadow: initial !important;
|
|
197
|
+
visibility: visible !important;
|
|
198
|
+
pointer-events: auto;
|
|
199
|
+
user-select: auto;
|
|
200
|
+
min-height: initial;
|
|
201
|
+
min-width: initial;
|
|
202
|
+
animation: none !important;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/* ============================================================
|
|
206
|
+
8. ANIMATIONS — Applied via --_ghostly-target marker
|
|
207
|
+
============================================================ */
|
|
208
|
+
|
|
209
|
+
/* --- Shimmer — gradient sweep left to right --- */
|
|
210
|
+
|
|
211
|
+
[data-ghostly='shimmer'] :where([style*="--_ghostly-target"]),
|
|
212
|
+
[data-ghostly='shimmer'] :where(
|
|
213
|
+
h1, h2, h3, h4, h5, h6,
|
|
214
|
+
p, span, a, li, td, th, dt, dd,
|
|
215
|
+
label, legend, figcaption, caption, summary,
|
|
216
|
+
blockquote, cite, q, em, strong, small, mark, code, pre,
|
|
217
|
+
button, input, textarea, select, option,
|
|
218
|
+
fieldset, dialog, details, address,
|
|
219
|
+
time, abbr, sub, sup, del, ins,
|
|
220
|
+
img, svg, video, canvas, picture, iframe
|
|
221
|
+
) {
|
|
222
|
+
background: linear-gradient(
|
|
223
|
+
90deg,
|
|
224
|
+
var(--ghostly-color) 0%,
|
|
225
|
+
var(--ghostly-color) 33%,
|
|
226
|
+
var(--ghostly-shine) 50%,
|
|
227
|
+
var(--ghostly-color) 66%,
|
|
228
|
+
var(--ghostly-color) 100%
|
|
229
|
+
) !important;
|
|
230
|
+
background-size: 300% 100% !important;
|
|
231
|
+
animation: ghostly-shimmer var(--ghostly-speed) ease-in-out infinite !important;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
@keyframes ghostly-shimmer {
|
|
235
|
+
0% { background-position: 100% 0; }
|
|
236
|
+
100% { background-position: -100% 0; }
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/* --- Pulse — opacity fade in/out --- */
|
|
240
|
+
|
|
241
|
+
[data-ghostly='pulse'] :where(
|
|
242
|
+
h1, h2, h3, h4, h5, h6,
|
|
243
|
+
p, span, a, li, td, th, dt, dd,
|
|
244
|
+
label, legend, figcaption, caption, summary,
|
|
245
|
+
blockquote, cite, q, em, strong, small, mark, code, pre,
|
|
246
|
+
button, input, textarea, select, option,
|
|
247
|
+
fieldset, dialog, details, address,
|
|
248
|
+
time, abbr, sub, sup, del, ins,
|
|
249
|
+
img, svg, video, canvas, picture, iframe
|
|
250
|
+
) {
|
|
251
|
+
animation: ghostly-pulse var(--ghostly-speed) ease-in-out infinite !important;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
@keyframes ghostly-pulse {
|
|
255
|
+
0%, 100% { opacity: 1; }
|
|
256
|
+
50% { opacity: 0.4; }
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/* --- Wave — cascading pulse with stagger --- */
|
|
260
|
+
|
|
261
|
+
[data-ghostly='wave'] :where(
|
|
262
|
+
h1, h2, h3, h4, h5, h6,
|
|
263
|
+
p, span, a, li, td, th, dt, dd,
|
|
264
|
+
label, legend, figcaption, caption, summary,
|
|
265
|
+
blockquote, cite, q, em, strong, small, mark, code, pre,
|
|
266
|
+
button, input, textarea, select, option,
|
|
267
|
+
fieldset, dialog, details, address,
|
|
268
|
+
time, abbr, sub, sup, del, ins,
|
|
269
|
+
img, svg, video, canvas, picture, iframe
|
|
270
|
+
) {
|
|
271
|
+
animation: ghostly-wave var(--ghostly-speed) ease-in-out infinite !important;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
@keyframes ghostly-wave {
|
|
275
|
+
0% { opacity: 1; }
|
|
276
|
+
25% { opacity: 0.3; }
|
|
277
|
+
50% { opacity: 0.8; }
|
|
278
|
+
75% { opacity: 0.4; }
|
|
279
|
+
100% { opacity: 1; }
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/* Stagger direct children for cascading effect */
|
|
283
|
+
[data-ghostly='wave'] > :nth-child(1) { animation-delay: 0ms !important; }
|
|
284
|
+
[data-ghostly='wave'] > :nth-child(2) { animation-delay: 80ms !important; }
|
|
285
|
+
[data-ghostly='wave'] > :nth-child(3) { animation-delay: 160ms !important; }
|
|
286
|
+
[data-ghostly='wave'] > :nth-child(4) { animation-delay: 240ms !important; }
|
|
287
|
+
[data-ghostly='wave'] > :nth-child(5) { animation-delay: 320ms !important; }
|
|
288
|
+
[data-ghostly='wave'] > :nth-child(6) { animation-delay: 400ms !important; }
|
|
289
|
+
[data-ghostly='wave'] > :nth-child(7) { animation-delay: 480ms !important; }
|
|
290
|
+
[data-ghostly='wave'] > :nth-child(8) { animation-delay: 560ms !important; }
|
|
291
|
+
[data-ghostly='wave'] > :nth-child(9) { animation-delay: 640ms !important; }
|
|
292
|
+
[data-ghostly='wave'] > :nth-child(10) { animation-delay: 720ms !important; }
|
|
293
|
+
[data-ghostly='wave'] > :nth-child(11) { animation-delay: 800ms !important; }
|
|
294
|
+
[data-ghostly='wave'] > :nth-child(12) { animation-delay: 880ms !important; }
|
|
295
|
+
[data-ghostly='wave'] > :nth-child(n+13) { animation-delay: 960ms !important; }
|
|
296
|
+
|
|
297
|
+
/* ============================================================
|
|
298
|
+
9. SMOOTH TRANSITION — fade out when loading ends
|
|
299
|
+
============================================================ */
|
|
300
|
+
|
|
301
|
+
[data-ghostly-smooth] :where(
|
|
302
|
+
h1, h2, h3, h4, h5, h6,
|
|
303
|
+
p, span, a, li, td, th, dt, dd,
|
|
304
|
+
label, legend, figcaption, caption, summary,
|
|
305
|
+
blockquote, cite, q, em, strong, small, mark, code, pre,
|
|
306
|
+
button, input, textarea, select, option,
|
|
307
|
+
fieldset, dialog, details, address,
|
|
308
|
+
time, abbr, sub, sup, del, ins,
|
|
309
|
+
img, svg, video, canvas, picture, iframe
|
|
310
|
+
) {
|
|
311
|
+
transition:
|
|
312
|
+
color var(--ghostly-transition) ease-out,
|
|
313
|
+
background-color var(--ghostly-transition) ease-out,
|
|
314
|
+
background-image var(--ghostly-transition) ease-out,
|
|
315
|
+
opacity var(--ghostly-transition) ease-out;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/* ============================================================
|
|
319
|
+
10. ACCESSIBILITY
|
|
320
|
+
============================================================ */
|
|
321
|
+
|
|
322
|
+
@media (prefers-reduced-motion: reduce) {
|
|
323
|
+
[data-ghostly] *,
|
|
324
|
+
[data-ghostly] *::before,
|
|
325
|
+
[data-ghostly] *::after {
|
|
326
|
+
animation: none !important;
|
|
327
|
+
transition: none !important;
|
|
328
|
+
}
|
|
329
|
+
}
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
CSS_VARS: () => CSS_VARS,
|
|
24
|
+
RADIUS_MAP: () => RADIUS_MAP,
|
|
25
|
+
SPEED_MAP: () => SPEED_MAP,
|
|
26
|
+
VALID_ANIMATIONS: () => VALID_ANIMATIONS,
|
|
27
|
+
VALID_RADII: () => VALID_RADII,
|
|
28
|
+
VALID_SPEEDS: () => VALID_SPEEDS,
|
|
29
|
+
validateGhostlyProps: () => validateGhostlyProps
|
|
30
|
+
});
|
|
31
|
+
module.exports = __toCommonJS(index_exports);
|
|
32
|
+
|
|
33
|
+
// src/types.ts
|
|
34
|
+
var CSS_VARS = {
|
|
35
|
+
color: "--ghostly-color",
|
|
36
|
+
shine: "--ghostly-shine",
|
|
37
|
+
radius: "--ghostly-radius",
|
|
38
|
+
speed: "--ghostly-speed"
|
|
39
|
+
};
|
|
40
|
+
var RADIUS_MAP = {
|
|
41
|
+
none: "0px",
|
|
42
|
+
xs: "2px",
|
|
43
|
+
sm: "4px",
|
|
44
|
+
md: "8px",
|
|
45
|
+
lg: "12px",
|
|
46
|
+
full: "9999px"
|
|
47
|
+
};
|
|
48
|
+
var SPEED_MAP = {
|
|
49
|
+
slow: "2s",
|
|
50
|
+
normal: "1.5s",
|
|
51
|
+
fast: "0.8s"
|
|
52
|
+
};
|
|
53
|
+
var VALID_ANIMATIONS = ["shimmer", "pulse", "wave", "none"];
|
|
54
|
+
var VALID_RADII = ["none", "xs", "sm", "md", "lg", "full"];
|
|
55
|
+
var VALID_SPEEDS = ["slow", "normal", "fast"];
|
|
56
|
+
function validateGhostlyProps(component, props) {
|
|
57
|
+
if (process.env.NODE_ENV === "production") return;
|
|
58
|
+
if (props.animation && !VALID_ANIMATIONS.includes(props.animation)) {
|
|
59
|
+
console.warn(
|
|
60
|
+
`[Ghostly] <${component}> received invalid animation="${props.animation}". Valid values: ${VALID_ANIMATIONS.join(", ")}`
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
if (props.radius && !VALID_RADII.includes(props.radius)) {
|
|
64
|
+
console.warn(
|
|
65
|
+
`[Ghostly] <${component}> received invalid radius="${props.radius}". Valid values: ${VALID_RADII.join(", ")}`
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
if (props.speed && !VALID_SPEEDS.includes(props.speed)) {
|
|
69
|
+
console.warn(
|
|
70
|
+
`[Ghostly] <${component}> received invalid speed="${props.speed}". Valid values: ${VALID_SPEEDS.join(", ")}`
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
75
|
+
0 && (module.exports = {
|
|
76
|
+
CSS_VARS,
|
|
77
|
+
RADIUS_MAP,
|
|
78
|
+
SPEED_MAP,
|
|
79
|
+
VALID_ANIMATIONS,
|
|
80
|
+
VALID_RADII,
|
|
81
|
+
VALID_SPEEDS,
|
|
82
|
+
validateGhostlyProps
|
|
83
|
+
});
|
|
84
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/types.ts"],"sourcesContent":["export type { GhostlyAnimation, GhostlyRadius, GhostlySpeed, GhostlyConfig } from './types'\nexport { CSS_VARS, RADIUS_MAP, SPEED_MAP, VALID_ANIMATIONS, VALID_RADII, VALID_SPEEDS, validateGhostlyProps } from './types'\n","export type GhostlyAnimation = 'shimmer' | 'pulse' | 'wave' | 'none'\n\nexport type GhostlyRadius = 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'full'\n\nexport type GhostlySpeed = 'slow' | 'normal' | 'fast'\n\nexport interface GhostlyConfig {\n /** Animation style. Default: 'shimmer' */\n animation?: GhostlyAnimation\n /** Border radius for skeleton blocks. Default: 'sm' */\n radius?: GhostlyRadius\n /** Animation speed. Default: 'normal' */\n speed?: GhostlySpeed\n /** Custom skeleton base color (any CSS color value) */\n color?: string\n /** Custom shimmer highlight color (any CSS color value) */\n shine?: string\n}\n\n/** CSS custom property names used by Ghostly */\nexport const CSS_VARS = {\n color: '--ghostly-color',\n shine: '--ghostly-shine',\n radius: '--ghostly-radius',\n speed: '--ghostly-speed',\n} as const\n\n/** Maps radius prop to CSS value */\nexport const RADIUS_MAP: Record<GhostlyRadius, string> = {\n none: '0px',\n xs: '2px',\n sm: '4px',\n md: '8px',\n lg: '12px',\n full: '9999px',\n}\n\n/** Maps speed prop to CSS duration */\nexport const SPEED_MAP: Record<GhostlySpeed, string> = {\n slow: '2s',\n normal: '1.5s',\n fast: '0.8s',\n}\n\n/** Valid values for each prop (used for dev validation) */\nexport const VALID_ANIMATIONS: readonly string[] = ['shimmer', 'pulse', 'wave', 'none']\nexport const VALID_RADII: readonly string[] = ['none', 'xs', 'sm', 'md', 'lg', 'full']\nexport const VALID_SPEEDS: readonly string[] = ['slow', 'normal', 'fast']\n\n/**\n * Validates Ghostly config props in development.\n * No-op in production builds (tree-shaken via process.env.NODE_ENV check).\n */\nexport function validateGhostlyProps(\n component: string,\n props: Partial<GhostlyConfig>,\n): void {\n if (process.env.NODE_ENV === 'production') return\n\n if (props.animation && !VALID_ANIMATIONS.includes(props.animation)) {\n console.warn(\n `[Ghostly] <${component}> received invalid animation=\"${props.animation}\". ` +\n `Valid values: ${VALID_ANIMATIONS.join(', ')}`,\n )\n }\n if (props.radius && !VALID_RADII.includes(props.radius)) {\n console.warn(\n `[Ghostly] <${component}> received invalid radius=\"${props.radius}\". ` +\n `Valid values: ${VALID_RADII.join(', ')}`,\n )\n }\n if (props.speed && !VALID_SPEEDS.includes(props.speed)) {\n console.warn(\n `[Ghostly] <${component}> received invalid speed=\"${props.speed}\". ` +\n `Valid values: ${VALID_SPEEDS.join(', ')}`,\n )\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACoBO,IAAM,WAAW;AAAA,EACtB,OAAO;AAAA,EACP,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,OAAO;AACT;AAGO,IAAM,aAA4C;AAAA,EACvD,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,MAAM;AACR;AAGO,IAAM,YAA0C;AAAA,EACrD,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,MAAM;AACR;AAGO,IAAM,mBAAsC,CAAC,WAAW,SAAS,QAAQ,MAAM;AAC/E,IAAM,cAAiC,CAAC,QAAQ,MAAM,MAAM,MAAM,MAAM,MAAM;AAC9E,IAAM,eAAkC,CAAC,QAAQ,UAAU,MAAM;AAMjE,SAAS,qBACd,WACA,OACM;AACN,MAAI,QAAQ,IAAI,aAAa,aAAc;AAE3C,MAAI,MAAM,aAAa,CAAC,iBAAiB,SAAS,MAAM,SAAS,GAAG;AAClE,YAAQ;AAAA,MACN,cAAc,SAAS,iCAAiC,MAAM,SAAS,oBACtD,iBAAiB,KAAK,IAAI,CAAC;AAAA,IAC9C;AAAA,EACF;AACA,MAAI,MAAM,UAAU,CAAC,YAAY,SAAS,MAAM,MAAM,GAAG;AACvD,YAAQ;AAAA,MACN,cAAc,SAAS,8BAA8B,MAAM,MAAM,oBAChD,YAAY,KAAK,IAAI,CAAC;AAAA,IACzC;AAAA,EACF;AACA,MAAI,MAAM,SAAS,CAAC,aAAa,SAAS,MAAM,KAAK,GAAG;AACtD,YAAQ;AAAA,MACN,cAAc,SAAS,6BAA6B,MAAM,KAAK,oBAC9C,aAAa,KAAK,IAAI,CAAC;AAAA,IAC1C;AAAA,EACF;AACF;","names":[]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
type GhostlyAnimation = 'shimmer' | 'pulse' | 'wave' | 'none';
|
|
2
|
+
type GhostlyRadius = 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'full';
|
|
3
|
+
type GhostlySpeed = 'slow' | 'normal' | 'fast';
|
|
4
|
+
interface GhostlyConfig {
|
|
5
|
+
/** Animation style. Default: 'shimmer' */
|
|
6
|
+
animation?: GhostlyAnimation;
|
|
7
|
+
/** Border radius for skeleton blocks. Default: 'sm' */
|
|
8
|
+
radius?: GhostlyRadius;
|
|
9
|
+
/** Animation speed. Default: 'normal' */
|
|
10
|
+
speed?: GhostlySpeed;
|
|
11
|
+
/** Custom skeleton base color (any CSS color value) */
|
|
12
|
+
color?: string;
|
|
13
|
+
/** Custom shimmer highlight color (any CSS color value) */
|
|
14
|
+
shine?: string;
|
|
15
|
+
}
|
|
16
|
+
/** CSS custom property names used by Ghostly */
|
|
17
|
+
declare const CSS_VARS: {
|
|
18
|
+
readonly color: "--ghostly-color";
|
|
19
|
+
readonly shine: "--ghostly-shine";
|
|
20
|
+
readonly radius: "--ghostly-radius";
|
|
21
|
+
readonly speed: "--ghostly-speed";
|
|
22
|
+
};
|
|
23
|
+
/** Maps radius prop to CSS value */
|
|
24
|
+
declare const RADIUS_MAP: Record<GhostlyRadius, string>;
|
|
25
|
+
/** Maps speed prop to CSS duration */
|
|
26
|
+
declare const SPEED_MAP: Record<GhostlySpeed, string>;
|
|
27
|
+
/** Valid values for each prop (used for dev validation) */
|
|
28
|
+
declare const VALID_ANIMATIONS: readonly string[];
|
|
29
|
+
declare const VALID_RADII: readonly string[];
|
|
30
|
+
declare const VALID_SPEEDS: readonly string[];
|
|
31
|
+
/**
|
|
32
|
+
* Validates Ghostly config props in development.
|
|
33
|
+
* No-op in production builds (tree-shaken via process.env.NODE_ENV check).
|
|
34
|
+
*/
|
|
35
|
+
declare function validateGhostlyProps(component: string, props: Partial<GhostlyConfig>): void;
|
|
36
|
+
|
|
37
|
+
export { CSS_VARS, type GhostlyAnimation, type GhostlyConfig, type GhostlyRadius, type GhostlySpeed, RADIUS_MAP, SPEED_MAP, VALID_ANIMATIONS, VALID_RADII, VALID_SPEEDS, validateGhostlyProps };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
type GhostlyAnimation = 'shimmer' | 'pulse' | 'wave' | 'none';
|
|
2
|
+
type GhostlyRadius = 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'full';
|
|
3
|
+
type GhostlySpeed = 'slow' | 'normal' | 'fast';
|
|
4
|
+
interface GhostlyConfig {
|
|
5
|
+
/** Animation style. Default: 'shimmer' */
|
|
6
|
+
animation?: GhostlyAnimation;
|
|
7
|
+
/** Border radius for skeleton blocks. Default: 'sm' */
|
|
8
|
+
radius?: GhostlyRadius;
|
|
9
|
+
/** Animation speed. Default: 'normal' */
|
|
10
|
+
speed?: GhostlySpeed;
|
|
11
|
+
/** Custom skeleton base color (any CSS color value) */
|
|
12
|
+
color?: string;
|
|
13
|
+
/** Custom shimmer highlight color (any CSS color value) */
|
|
14
|
+
shine?: string;
|
|
15
|
+
}
|
|
16
|
+
/** CSS custom property names used by Ghostly */
|
|
17
|
+
declare const CSS_VARS: {
|
|
18
|
+
readonly color: "--ghostly-color";
|
|
19
|
+
readonly shine: "--ghostly-shine";
|
|
20
|
+
readonly radius: "--ghostly-radius";
|
|
21
|
+
readonly speed: "--ghostly-speed";
|
|
22
|
+
};
|
|
23
|
+
/** Maps radius prop to CSS value */
|
|
24
|
+
declare const RADIUS_MAP: Record<GhostlyRadius, string>;
|
|
25
|
+
/** Maps speed prop to CSS duration */
|
|
26
|
+
declare const SPEED_MAP: Record<GhostlySpeed, string>;
|
|
27
|
+
/** Valid values for each prop (used for dev validation) */
|
|
28
|
+
declare const VALID_ANIMATIONS: readonly string[];
|
|
29
|
+
declare const VALID_RADII: readonly string[];
|
|
30
|
+
declare const VALID_SPEEDS: readonly string[];
|
|
31
|
+
/**
|
|
32
|
+
* Validates Ghostly config props in development.
|
|
33
|
+
* No-op in production builds (tree-shaken via process.env.NODE_ENV check).
|
|
34
|
+
*/
|
|
35
|
+
declare function validateGhostlyProps(component: string, props: Partial<GhostlyConfig>): void;
|
|
36
|
+
|
|
37
|
+
export { CSS_VARS, type GhostlyAnimation, type GhostlyConfig, type GhostlyRadius, type GhostlySpeed, RADIUS_MAP, SPEED_MAP, VALID_ANIMATIONS, VALID_RADII, VALID_SPEEDS, validateGhostlyProps };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// src/types.ts
|
|
2
|
+
var CSS_VARS = {
|
|
3
|
+
color: "--ghostly-color",
|
|
4
|
+
shine: "--ghostly-shine",
|
|
5
|
+
radius: "--ghostly-radius",
|
|
6
|
+
speed: "--ghostly-speed"
|
|
7
|
+
};
|
|
8
|
+
var RADIUS_MAP = {
|
|
9
|
+
none: "0px",
|
|
10
|
+
xs: "2px",
|
|
11
|
+
sm: "4px",
|
|
12
|
+
md: "8px",
|
|
13
|
+
lg: "12px",
|
|
14
|
+
full: "9999px"
|
|
15
|
+
};
|
|
16
|
+
var SPEED_MAP = {
|
|
17
|
+
slow: "2s",
|
|
18
|
+
normal: "1.5s",
|
|
19
|
+
fast: "0.8s"
|
|
20
|
+
};
|
|
21
|
+
var VALID_ANIMATIONS = ["shimmer", "pulse", "wave", "none"];
|
|
22
|
+
var VALID_RADII = ["none", "xs", "sm", "md", "lg", "full"];
|
|
23
|
+
var VALID_SPEEDS = ["slow", "normal", "fast"];
|
|
24
|
+
function validateGhostlyProps(component, props) {
|
|
25
|
+
if (process.env.NODE_ENV === "production") return;
|
|
26
|
+
if (props.animation && !VALID_ANIMATIONS.includes(props.animation)) {
|
|
27
|
+
console.warn(
|
|
28
|
+
`[Ghostly] <${component}> received invalid animation="${props.animation}". Valid values: ${VALID_ANIMATIONS.join(", ")}`
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
if (props.radius && !VALID_RADII.includes(props.radius)) {
|
|
32
|
+
console.warn(
|
|
33
|
+
`[Ghostly] <${component}> received invalid radius="${props.radius}". Valid values: ${VALID_RADII.join(", ")}`
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
if (props.speed && !VALID_SPEEDS.includes(props.speed)) {
|
|
37
|
+
console.warn(
|
|
38
|
+
`[Ghostly] <${component}> received invalid speed="${props.speed}". Valid values: ${VALID_SPEEDS.join(", ")}`
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export {
|
|
43
|
+
CSS_VARS,
|
|
44
|
+
RADIUS_MAP,
|
|
45
|
+
SPEED_MAP,
|
|
46
|
+
VALID_ANIMATIONS,
|
|
47
|
+
VALID_RADII,
|
|
48
|
+
VALID_SPEEDS,
|
|
49
|
+
validateGhostlyProps
|
|
50
|
+
};
|
|
51
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["export type GhostlyAnimation = 'shimmer' | 'pulse' | 'wave' | 'none'\n\nexport type GhostlyRadius = 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'full'\n\nexport type GhostlySpeed = 'slow' | 'normal' | 'fast'\n\nexport interface GhostlyConfig {\n /** Animation style. Default: 'shimmer' */\n animation?: GhostlyAnimation\n /** Border radius for skeleton blocks. Default: 'sm' */\n radius?: GhostlyRadius\n /** Animation speed. Default: 'normal' */\n speed?: GhostlySpeed\n /** Custom skeleton base color (any CSS color value) */\n color?: string\n /** Custom shimmer highlight color (any CSS color value) */\n shine?: string\n}\n\n/** CSS custom property names used by Ghostly */\nexport const CSS_VARS = {\n color: '--ghostly-color',\n shine: '--ghostly-shine',\n radius: '--ghostly-radius',\n speed: '--ghostly-speed',\n} as const\n\n/** Maps radius prop to CSS value */\nexport const RADIUS_MAP: Record<GhostlyRadius, string> = {\n none: '0px',\n xs: '2px',\n sm: '4px',\n md: '8px',\n lg: '12px',\n full: '9999px',\n}\n\n/** Maps speed prop to CSS duration */\nexport const SPEED_MAP: Record<GhostlySpeed, string> = {\n slow: '2s',\n normal: '1.5s',\n fast: '0.8s',\n}\n\n/** Valid values for each prop (used for dev validation) */\nexport const VALID_ANIMATIONS: readonly string[] = ['shimmer', 'pulse', 'wave', 'none']\nexport const VALID_RADII: readonly string[] = ['none', 'xs', 'sm', 'md', 'lg', 'full']\nexport const VALID_SPEEDS: readonly string[] = ['slow', 'normal', 'fast']\n\n/**\n * Validates Ghostly config props in development.\n * No-op in production builds (tree-shaken via process.env.NODE_ENV check).\n */\nexport function validateGhostlyProps(\n component: string,\n props: Partial<GhostlyConfig>,\n): void {\n if (process.env.NODE_ENV === 'production') return\n\n if (props.animation && !VALID_ANIMATIONS.includes(props.animation)) {\n console.warn(\n `[Ghostly] <${component}> received invalid animation=\"${props.animation}\". ` +\n `Valid values: ${VALID_ANIMATIONS.join(', ')}`,\n )\n }\n if (props.radius && !VALID_RADII.includes(props.radius)) {\n console.warn(\n `[Ghostly] <${component}> received invalid radius=\"${props.radius}\". ` +\n `Valid values: ${VALID_RADII.join(', ')}`,\n )\n }\n if (props.speed && !VALID_SPEEDS.includes(props.speed)) {\n console.warn(\n `[Ghostly] <${component}> received invalid speed=\"${props.speed}\". ` +\n `Valid values: ${VALID_SPEEDS.join(', ')}`,\n )\n }\n}\n"],"mappings":";AAoBO,IAAM,WAAW;AAAA,EACtB,OAAO;AAAA,EACP,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,OAAO;AACT;AAGO,IAAM,aAA4C;AAAA,EACvD,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,MAAM;AACR;AAGO,IAAM,YAA0C;AAAA,EACrD,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,MAAM;AACR;AAGO,IAAM,mBAAsC,CAAC,WAAW,SAAS,QAAQ,MAAM;AAC/E,IAAM,cAAiC,CAAC,QAAQ,MAAM,MAAM,MAAM,MAAM,MAAM;AAC9E,IAAM,eAAkC,CAAC,QAAQ,UAAU,MAAM;AAMjE,SAAS,qBACd,WACA,OACM;AACN,MAAI,QAAQ,IAAI,aAAa,aAAc;AAE3C,MAAI,MAAM,aAAa,CAAC,iBAAiB,SAAS,MAAM,SAAS,GAAG;AAClE,YAAQ;AAAA,MACN,cAAc,SAAS,iCAAiC,MAAM,SAAS,oBACtD,iBAAiB,KAAK,IAAI,CAAC;AAAA,IAC9C;AAAA,EACF;AACA,MAAI,MAAM,UAAU,CAAC,YAAY,SAAS,MAAM,MAAM,GAAG;AACvD,YAAQ;AAAA,MACN,cAAc,SAAS,8BAA8B,MAAM,MAAM,oBAChD,YAAY,KAAK,IAAI,CAAC;AAAA,IACzC;AAAA,EACF;AACA,MAAI,MAAM,SAAS,CAAC,aAAa,SAAS,MAAM,KAAK,GAAG;AACtD,YAAQ;AAAA,MACN,cAAc,SAAS,6BAA6B,MAAM,KAAK,oBAC9C,aAAa,KAAK,IAAI,CAAC;AAAA,IAC1C;AAAA,EACF;AACF;","names":[]}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/tailwind.ts
|
|
31
|
+
var tailwind_exports = {};
|
|
32
|
+
__export(tailwind_exports, {
|
|
33
|
+
default: () => tailwind_default
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(tailwind_exports);
|
|
36
|
+
var import_plugin = __toESM(require("tailwindcss/plugin"), 1);
|
|
37
|
+
var tailwind_default = (0, import_plugin.default)(function ghostlyPlugin({ addUtilities, addVariant, matchUtilities }) {
|
|
38
|
+
addVariant("ghostly", "[data-ghostly] &");
|
|
39
|
+
addUtilities({
|
|
40
|
+
".ghostly-radius-none": { "--ghostly-radius": "0px" },
|
|
41
|
+
".ghostly-radius-xs": { "--ghostly-radius": "2px" },
|
|
42
|
+
".ghostly-radius-sm": { "--ghostly-radius": "4px" },
|
|
43
|
+
".ghostly-radius-md": { "--ghostly-radius": "8px" },
|
|
44
|
+
".ghostly-radius-lg": { "--ghostly-radius": "12px" },
|
|
45
|
+
".ghostly-radius-full": { "--ghostly-radius": "9999px" }
|
|
46
|
+
});
|
|
47
|
+
addUtilities({
|
|
48
|
+
".ghostly-speed-slow": { "--ghostly-speed": "2s" },
|
|
49
|
+
".ghostly-speed-normal": { "--ghostly-speed": "1.5s" },
|
|
50
|
+
".ghostly-speed-fast": { "--ghostly-speed": "0.8s" }
|
|
51
|
+
});
|
|
52
|
+
matchUtilities(
|
|
53
|
+
{ "ghostly-color": (value) => ({ "--ghostly-color": value }) },
|
|
54
|
+
{ values: {}, type: ["color"] }
|
|
55
|
+
);
|
|
56
|
+
matchUtilities(
|
|
57
|
+
{ "ghostly-shine": (value) => ({ "--ghostly-shine": value }) },
|
|
58
|
+
{ values: {}, type: ["color"] }
|
|
59
|
+
);
|
|
60
|
+
});
|
|
61
|
+
//# sourceMappingURL=tailwind.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/tailwind.ts"],"sourcesContent":["import plugin from 'tailwindcss/plugin'\n\n/**\n * Tailwind CSS plugin for Ghostly skeleton loaders.\n *\n * Adds utilities for configuring ghostly CSS variables\n * and a `ghostly:` variant for conditional skeleton styles.\n *\n * @example\n * ```js\n * // tailwind.config.js\n * import ghostly from '@ghostly-ui/core/tailwind'\n * export default { plugins: [ghostly] }\n * ```\n *\n * Usage in templates:\n * ```html\n * <div class=\"ghostly-radius-lg ghostly-speed-fast\">\n * ...\n * </div>\n * ```\n */\nexport default plugin(function ghostlyPlugin({ addUtilities, addVariant, matchUtilities }) {\n // Variant: `ghostly:` targets elements inside a ghostly container\n addVariant('ghostly', '[data-ghostly] &')\n\n // Radius utilities\n addUtilities({\n '.ghostly-radius-none': { '--ghostly-radius': '0px' },\n '.ghostly-radius-xs': { '--ghostly-radius': '2px' },\n '.ghostly-radius-sm': { '--ghostly-radius': '4px' },\n '.ghostly-radius-md': { '--ghostly-radius': '8px' },\n '.ghostly-radius-lg': { '--ghostly-radius': '12px' },\n '.ghostly-radius-full': { '--ghostly-radius': '9999px' },\n })\n\n // Speed utilities\n addUtilities({\n '.ghostly-speed-slow': { '--ghostly-speed': '2s' },\n '.ghostly-speed-normal': { '--ghostly-speed': '1.5s' },\n '.ghostly-speed-fast': { '--ghostly-speed': '0.8s' },\n })\n\n // Color utilities (arbitrary value via matchUtilities)\n matchUtilities(\n { 'ghostly-color': (value: string) => ({ '--ghostly-color': value }) },\n { values: {}, type: ['color'] },\n )\n\n matchUtilities(\n { 'ghostly-shine': (value: string) => ({ '--ghostly-shine': value }) },\n { values: {}, type: ['color'] },\n )\n})\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAAmB;AAsBnB,IAAO,uBAAQ,cAAAA,SAAO,SAAS,cAAc,EAAE,cAAc,YAAY,eAAe,GAAG;AAEzF,aAAW,WAAW,kBAAkB;AAGxC,eAAa;AAAA,IACX,wBAAwB,EAAE,oBAAoB,MAAM;AAAA,IACpD,sBAAsB,EAAE,oBAAoB,MAAM;AAAA,IAClD,sBAAsB,EAAE,oBAAoB,MAAM;AAAA,IAClD,sBAAsB,EAAE,oBAAoB,MAAM;AAAA,IAClD,sBAAsB,EAAE,oBAAoB,OAAO;AAAA,IACnD,wBAAwB,EAAE,oBAAoB,SAAS;AAAA,EACzD,CAAC;AAGD,eAAa;AAAA,IACX,uBAAuB,EAAE,mBAAmB,KAAK;AAAA,IACjD,yBAAyB,EAAE,mBAAmB,OAAO;AAAA,IACrD,uBAAuB,EAAE,mBAAmB,OAAO;AAAA,EACrD,CAAC;AAGD;AAAA,IACE,EAAE,iBAAiB,CAAC,WAAmB,EAAE,mBAAmB,MAAM,GAAG;AAAA,IACrE,EAAE,QAAQ,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE;AAAA,EAChC;AAEA;AAAA,IACE,EAAE,iBAAiB,CAAC,WAAmB,EAAE,mBAAmB,MAAM,GAAG;AAAA,IACrE,EAAE,QAAQ,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE;AAAA,EAChC;AACF,CAAC;","names":["plugin"]}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { N, P } from './resolve-config-QUZ9b-Gn.mjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The source code for one or more nodes in the AST
|
|
5
|
+
*
|
|
6
|
+
* This generally corresponds to a stylesheet
|
|
7
|
+
*/
|
|
8
|
+
interface Source {
|
|
9
|
+
/**
|
|
10
|
+
* The path to the file that contains the referenced source code
|
|
11
|
+
*
|
|
12
|
+
* If this references the *output* source code, this is `null`.
|
|
13
|
+
*/
|
|
14
|
+
file: string | null;
|
|
15
|
+
/**
|
|
16
|
+
* The referenced source code
|
|
17
|
+
*/
|
|
18
|
+
code: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* The file and offsets within it that this node covers
|
|
22
|
+
*
|
|
23
|
+
* This can represent either:
|
|
24
|
+
* - A location in the original CSS which caused this node to be created
|
|
25
|
+
* - A location in the output CSS where this node resides
|
|
26
|
+
*/
|
|
27
|
+
type SourceLocation = [source: Source, start: number, end: number];
|
|
28
|
+
type PluginFn = (api: PluginAPI) => void;
|
|
29
|
+
type PluginWithConfig = {
|
|
30
|
+
handler: PluginFn;
|
|
31
|
+
config?: UserConfig;
|
|
32
|
+
/** @internal */
|
|
33
|
+
reference?: boolean;
|
|
34
|
+
src?: SourceLocation | undefined;
|
|
35
|
+
};
|
|
36
|
+
type PluginWithOptions<T> = {
|
|
37
|
+
(options?: T): PluginWithConfig;
|
|
38
|
+
__isOptionsFunction: true;
|
|
39
|
+
};
|
|
40
|
+
type Plugin = PluginFn | PluginWithConfig | PluginWithOptions<any>;
|
|
41
|
+
type PluginAPI = {
|
|
42
|
+
addBase(base: CssInJs): void;
|
|
43
|
+
addVariant(name: string, variant: string | string[] | CssInJs): void;
|
|
44
|
+
matchVariant<T = string>(name: string, cb: (value: T | string, extra: {
|
|
45
|
+
modifier: string | null;
|
|
46
|
+
}) => string | string[], options?: {
|
|
47
|
+
values?: Record<string, T>;
|
|
48
|
+
sort?(a: {
|
|
49
|
+
value: T | string;
|
|
50
|
+
modifier: string | null;
|
|
51
|
+
}, b: {
|
|
52
|
+
value: T | string;
|
|
53
|
+
modifier: string | null;
|
|
54
|
+
}): number;
|
|
55
|
+
}): void;
|
|
56
|
+
addUtilities(utilities: Record<string, CssInJs | CssInJs[]> | Record<string, CssInJs | CssInJs[]>[], options?: {}): void;
|
|
57
|
+
matchUtilities(utilities: Record<string, (value: string, extra: {
|
|
58
|
+
modifier: string | null;
|
|
59
|
+
}) => CssInJs | CssInJs[]>, options?: Partial<{
|
|
60
|
+
type: string | string[];
|
|
61
|
+
supportsNegativeValues: boolean;
|
|
62
|
+
values: Record<string, string> & {
|
|
63
|
+
__BARE_VALUE__?: (value: N) => string | undefined;
|
|
64
|
+
};
|
|
65
|
+
modifiers: 'any' | Record<string, string>;
|
|
66
|
+
}>): void;
|
|
67
|
+
addComponents(utilities: Record<string, CssInJs> | Record<string, CssInJs>[], options?: {}): void;
|
|
68
|
+
matchComponents(utilities: Record<string, (value: string, extra: {
|
|
69
|
+
modifier: string | null;
|
|
70
|
+
}) => CssInJs>, options?: Partial<{
|
|
71
|
+
type: string | string[];
|
|
72
|
+
supportsNegativeValues: boolean;
|
|
73
|
+
values: Record<string, string> & {
|
|
74
|
+
__BARE_VALUE__?: (value: N) => string | undefined;
|
|
75
|
+
};
|
|
76
|
+
modifiers: 'any' | Record<string, string>;
|
|
77
|
+
}>): void;
|
|
78
|
+
theme(path: string, defaultValue?: any): any;
|
|
79
|
+
config(path?: string, defaultValue?: any): any;
|
|
80
|
+
prefix(className: string): string;
|
|
81
|
+
};
|
|
82
|
+
type CssInJs = {
|
|
83
|
+
[key: string]: string | string[] | CssInJs | CssInJs[];
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
type ResolvableTo<T> = T | ((utils: P) => T);
|
|
87
|
+
type ThemeValue = ResolvableTo<Record<string, unknown>> | null | undefined;
|
|
88
|
+
type ThemeConfig = Record<string, ThemeValue> & {
|
|
89
|
+
extend?: Record<string, ThemeValue>;
|
|
90
|
+
};
|
|
91
|
+
type ContentFile = string | {
|
|
92
|
+
raw: string;
|
|
93
|
+
extension?: string;
|
|
94
|
+
};
|
|
95
|
+
type DarkModeStrategy = false | 'media' | 'class' | ['class', string] | 'selector' | ['selector', string] | ['variant', string | string[]];
|
|
96
|
+
interface UserConfig {
|
|
97
|
+
presets?: UserConfig[];
|
|
98
|
+
theme?: ThemeConfig;
|
|
99
|
+
plugins?: Plugin[];
|
|
100
|
+
}
|
|
101
|
+
interface UserConfig {
|
|
102
|
+
content?: ContentFile[] | {
|
|
103
|
+
relative?: boolean;
|
|
104
|
+
files: ContentFile[];
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
interface UserConfig {
|
|
108
|
+
darkMode?: DarkModeStrategy;
|
|
109
|
+
}
|
|
110
|
+
interface UserConfig {
|
|
111
|
+
prefix?: string;
|
|
112
|
+
}
|
|
113
|
+
interface UserConfig {
|
|
114
|
+
blocklist?: string[];
|
|
115
|
+
}
|
|
116
|
+
interface UserConfig {
|
|
117
|
+
important?: boolean | string;
|
|
118
|
+
}
|
|
119
|
+
interface UserConfig {
|
|
120
|
+
future?: 'all' | Record<string, boolean>;
|
|
121
|
+
}
|
|
122
|
+
interface UserConfig {
|
|
123
|
+
experimental?: 'all' | Record<string, boolean>;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Tailwind CSS plugin for Ghostly skeleton loaders.
|
|
128
|
+
*
|
|
129
|
+
* Adds utilities for configuring ghostly CSS variables
|
|
130
|
+
* and a `ghostly:` variant for conditional skeleton styles.
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* ```js
|
|
134
|
+
* // tailwind.config.js
|
|
135
|
+
* import ghostly from '@ghostly-ui/core/tailwind'
|
|
136
|
+
* export default { plugins: [ghostly] }
|
|
137
|
+
* ```
|
|
138
|
+
*
|
|
139
|
+
* Usage in templates:
|
|
140
|
+
* ```html
|
|
141
|
+
* <div class="ghostly-radius-lg ghostly-speed-fast">
|
|
142
|
+
* ...
|
|
143
|
+
* </div>
|
|
144
|
+
* ```
|
|
145
|
+
*/
|
|
146
|
+
declare const _default: PluginWithConfig;
|
|
147
|
+
|
|
148
|
+
export { _default as default };
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { N, P } from './resolve-config-QUZ9b-Gn.mjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The source code for one or more nodes in the AST
|
|
5
|
+
*
|
|
6
|
+
* This generally corresponds to a stylesheet
|
|
7
|
+
*/
|
|
8
|
+
interface Source {
|
|
9
|
+
/**
|
|
10
|
+
* The path to the file that contains the referenced source code
|
|
11
|
+
*
|
|
12
|
+
* If this references the *output* source code, this is `null`.
|
|
13
|
+
*/
|
|
14
|
+
file: string | null;
|
|
15
|
+
/**
|
|
16
|
+
* The referenced source code
|
|
17
|
+
*/
|
|
18
|
+
code: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* The file and offsets within it that this node covers
|
|
22
|
+
*
|
|
23
|
+
* This can represent either:
|
|
24
|
+
* - A location in the original CSS which caused this node to be created
|
|
25
|
+
* - A location in the output CSS where this node resides
|
|
26
|
+
*/
|
|
27
|
+
type SourceLocation = [source: Source, start: number, end: number];
|
|
28
|
+
type PluginFn = (api: PluginAPI) => void;
|
|
29
|
+
type PluginWithConfig = {
|
|
30
|
+
handler: PluginFn;
|
|
31
|
+
config?: UserConfig;
|
|
32
|
+
/** @internal */
|
|
33
|
+
reference?: boolean;
|
|
34
|
+
src?: SourceLocation | undefined;
|
|
35
|
+
};
|
|
36
|
+
type PluginWithOptions<T> = {
|
|
37
|
+
(options?: T): PluginWithConfig;
|
|
38
|
+
__isOptionsFunction: true;
|
|
39
|
+
};
|
|
40
|
+
type Plugin = PluginFn | PluginWithConfig | PluginWithOptions<any>;
|
|
41
|
+
type PluginAPI = {
|
|
42
|
+
addBase(base: CssInJs): void;
|
|
43
|
+
addVariant(name: string, variant: string | string[] | CssInJs): void;
|
|
44
|
+
matchVariant<T = string>(name: string, cb: (value: T | string, extra: {
|
|
45
|
+
modifier: string | null;
|
|
46
|
+
}) => string | string[], options?: {
|
|
47
|
+
values?: Record<string, T>;
|
|
48
|
+
sort?(a: {
|
|
49
|
+
value: T | string;
|
|
50
|
+
modifier: string | null;
|
|
51
|
+
}, b: {
|
|
52
|
+
value: T | string;
|
|
53
|
+
modifier: string | null;
|
|
54
|
+
}): number;
|
|
55
|
+
}): void;
|
|
56
|
+
addUtilities(utilities: Record<string, CssInJs | CssInJs[]> | Record<string, CssInJs | CssInJs[]>[], options?: {}): void;
|
|
57
|
+
matchUtilities(utilities: Record<string, (value: string, extra: {
|
|
58
|
+
modifier: string | null;
|
|
59
|
+
}) => CssInJs | CssInJs[]>, options?: Partial<{
|
|
60
|
+
type: string | string[];
|
|
61
|
+
supportsNegativeValues: boolean;
|
|
62
|
+
values: Record<string, string> & {
|
|
63
|
+
__BARE_VALUE__?: (value: N) => string | undefined;
|
|
64
|
+
};
|
|
65
|
+
modifiers: 'any' | Record<string, string>;
|
|
66
|
+
}>): void;
|
|
67
|
+
addComponents(utilities: Record<string, CssInJs> | Record<string, CssInJs>[], options?: {}): void;
|
|
68
|
+
matchComponents(utilities: Record<string, (value: string, extra: {
|
|
69
|
+
modifier: string | null;
|
|
70
|
+
}) => CssInJs>, options?: Partial<{
|
|
71
|
+
type: string | string[];
|
|
72
|
+
supportsNegativeValues: boolean;
|
|
73
|
+
values: Record<string, string> & {
|
|
74
|
+
__BARE_VALUE__?: (value: N) => string | undefined;
|
|
75
|
+
};
|
|
76
|
+
modifiers: 'any' | Record<string, string>;
|
|
77
|
+
}>): void;
|
|
78
|
+
theme(path: string, defaultValue?: any): any;
|
|
79
|
+
config(path?: string, defaultValue?: any): any;
|
|
80
|
+
prefix(className: string): string;
|
|
81
|
+
};
|
|
82
|
+
type CssInJs = {
|
|
83
|
+
[key: string]: string | string[] | CssInJs | CssInJs[];
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
type ResolvableTo<T> = T | ((utils: P) => T);
|
|
87
|
+
type ThemeValue = ResolvableTo<Record<string, unknown>> | null | undefined;
|
|
88
|
+
type ThemeConfig = Record<string, ThemeValue> & {
|
|
89
|
+
extend?: Record<string, ThemeValue>;
|
|
90
|
+
};
|
|
91
|
+
type ContentFile = string | {
|
|
92
|
+
raw: string;
|
|
93
|
+
extension?: string;
|
|
94
|
+
};
|
|
95
|
+
type DarkModeStrategy = false | 'media' | 'class' | ['class', string] | 'selector' | ['selector', string] | ['variant', string | string[]];
|
|
96
|
+
interface UserConfig {
|
|
97
|
+
presets?: UserConfig[];
|
|
98
|
+
theme?: ThemeConfig;
|
|
99
|
+
plugins?: Plugin[];
|
|
100
|
+
}
|
|
101
|
+
interface UserConfig {
|
|
102
|
+
content?: ContentFile[] | {
|
|
103
|
+
relative?: boolean;
|
|
104
|
+
files: ContentFile[];
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
interface UserConfig {
|
|
108
|
+
darkMode?: DarkModeStrategy;
|
|
109
|
+
}
|
|
110
|
+
interface UserConfig {
|
|
111
|
+
prefix?: string;
|
|
112
|
+
}
|
|
113
|
+
interface UserConfig {
|
|
114
|
+
blocklist?: string[];
|
|
115
|
+
}
|
|
116
|
+
interface UserConfig {
|
|
117
|
+
important?: boolean | string;
|
|
118
|
+
}
|
|
119
|
+
interface UserConfig {
|
|
120
|
+
future?: 'all' | Record<string, boolean>;
|
|
121
|
+
}
|
|
122
|
+
interface UserConfig {
|
|
123
|
+
experimental?: 'all' | Record<string, boolean>;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Tailwind CSS plugin for Ghostly skeleton loaders.
|
|
128
|
+
*
|
|
129
|
+
* Adds utilities for configuring ghostly CSS variables
|
|
130
|
+
* and a `ghostly:` variant for conditional skeleton styles.
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* ```js
|
|
134
|
+
* // tailwind.config.js
|
|
135
|
+
* import ghostly from '@ghostly-ui/core/tailwind'
|
|
136
|
+
* export default { plugins: [ghostly] }
|
|
137
|
+
* ```
|
|
138
|
+
*
|
|
139
|
+
* Usage in templates:
|
|
140
|
+
* ```html
|
|
141
|
+
* <div class="ghostly-radius-lg ghostly-speed-fast">
|
|
142
|
+
* ...
|
|
143
|
+
* </div>
|
|
144
|
+
* ```
|
|
145
|
+
*/
|
|
146
|
+
declare const _default: PluginWithConfig;
|
|
147
|
+
|
|
148
|
+
export { _default as default };
|
package/dist/tailwind.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// src/tailwind.ts
|
|
2
|
+
import plugin from "tailwindcss/plugin";
|
|
3
|
+
var tailwind_default = plugin(function ghostlyPlugin({ addUtilities, addVariant, matchUtilities }) {
|
|
4
|
+
addVariant("ghostly", "[data-ghostly] &");
|
|
5
|
+
addUtilities({
|
|
6
|
+
".ghostly-radius-none": { "--ghostly-radius": "0px" },
|
|
7
|
+
".ghostly-radius-xs": { "--ghostly-radius": "2px" },
|
|
8
|
+
".ghostly-radius-sm": { "--ghostly-radius": "4px" },
|
|
9
|
+
".ghostly-radius-md": { "--ghostly-radius": "8px" },
|
|
10
|
+
".ghostly-radius-lg": { "--ghostly-radius": "12px" },
|
|
11
|
+
".ghostly-radius-full": { "--ghostly-radius": "9999px" }
|
|
12
|
+
});
|
|
13
|
+
addUtilities({
|
|
14
|
+
".ghostly-speed-slow": { "--ghostly-speed": "2s" },
|
|
15
|
+
".ghostly-speed-normal": { "--ghostly-speed": "1.5s" },
|
|
16
|
+
".ghostly-speed-fast": { "--ghostly-speed": "0.8s" }
|
|
17
|
+
});
|
|
18
|
+
matchUtilities(
|
|
19
|
+
{ "ghostly-color": (value) => ({ "--ghostly-color": value }) },
|
|
20
|
+
{ values: {}, type: ["color"] }
|
|
21
|
+
);
|
|
22
|
+
matchUtilities(
|
|
23
|
+
{ "ghostly-shine": (value) => ({ "--ghostly-shine": value }) },
|
|
24
|
+
{ values: {}, type: ["color"] }
|
|
25
|
+
);
|
|
26
|
+
});
|
|
27
|
+
export {
|
|
28
|
+
tailwind_default as default
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=tailwind.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/tailwind.ts"],"sourcesContent":["import plugin from 'tailwindcss/plugin'\n\n/**\n * Tailwind CSS plugin for Ghostly skeleton loaders.\n *\n * Adds utilities for configuring ghostly CSS variables\n * and a `ghostly:` variant for conditional skeleton styles.\n *\n * @example\n * ```js\n * // tailwind.config.js\n * import ghostly from '@ghostly-ui/core/tailwind'\n * export default { plugins: [ghostly] }\n * ```\n *\n * Usage in templates:\n * ```html\n * <div class=\"ghostly-radius-lg ghostly-speed-fast\">\n * ...\n * </div>\n * ```\n */\nexport default plugin(function ghostlyPlugin({ addUtilities, addVariant, matchUtilities }) {\n // Variant: `ghostly:` targets elements inside a ghostly container\n addVariant('ghostly', '[data-ghostly] &')\n\n // Radius utilities\n addUtilities({\n '.ghostly-radius-none': { '--ghostly-radius': '0px' },\n '.ghostly-radius-xs': { '--ghostly-radius': '2px' },\n '.ghostly-radius-sm': { '--ghostly-radius': '4px' },\n '.ghostly-radius-md': { '--ghostly-radius': '8px' },\n '.ghostly-radius-lg': { '--ghostly-radius': '12px' },\n '.ghostly-radius-full': { '--ghostly-radius': '9999px' },\n })\n\n // Speed utilities\n addUtilities({\n '.ghostly-speed-slow': { '--ghostly-speed': '2s' },\n '.ghostly-speed-normal': { '--ghostly-speed': '1.5s' },\n '.ghostly-speed-fast': { '--ghostly-speed': '0.8s' },\n })\n\n // Color utilities (arbitrary value via matchUtilities)\n matchUtilities(\n { 'ghostly-color': (value: string) => ({ '--ghostly-color': value }) },\n { values: {}, type: ['color'] },\n )\n\n matchUtilities(\n { 'ghostly-shine': (value: string) => ({ '--ghostly-shine': value }) },\n { values: {}, type: ['color'] },\n )\n})\n"],"mappings":";AAAA,OAAO,YAAY;AAsBnB,IAAO,mBAAQ,OAAO,SAAS,cAAc,EAAE,cAAc,YAAY,eAAe,GAAG;AAEzF,aAAW,WAAW,kBAAkB;AAGxC,eAAa;AAAA,IACX,wBAAwB,EAAE,oBAAoB,MAAM;AAAA,IACpD,sBAAsB,EAAE,oBAAoB,MAAM;AAAA,IAClD,sBAAsB,EAAE,oBAAoB,MAAM;AAAA,IAClD,sBAAsB,EAAE,oBAAoB,MAAM;AAAA,IAClD,sBAAsB,EAAE,oBAAoB,OAAO;AAAA,IACnD,wBAAwB,EAAE,oBAAoB,SAAS;AAAA,EACzD,CAAC;AAGD,eAAa;AAAA,IACX,uBAAuB,EAAE,mBAAmB,KAAK;AAAA,IACjD,yBAAyB,EAAE,mBAAmB,OAAO;AAAA,IACrD,uBAAuB,EAAE,mBAAmB,OAAO;AAAA,EACrD,CAAC;AAGD;AAAA,IACE,EAAE,iBAAiB,CAAC,WAAmB,EAAE,mBAAmB,MAAM,GAAG;AAAA,IACrE,EAAE,QAAQ,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE;AAAA,EAChC;AAEA;AAAA,IACE,EAAE,iBAAiB,CAAC,WAAmB,EAAE,mBAAmB,MAAM,GAAG;AAAA,IACrE,EAAE,QAAQ,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE;AAAA,EAChC;AACF,CAAC;","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ghostly-ui/core",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Zero-config skeleton loaders. Wrap your component, done.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.cjs",
|
|
8
|
+
"module": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"import": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"default": "./dist/index.js"
|
|
15
|
+
},
|
|
16
|
+
"require": {
|
|
17
|
+
"types": "./dist/index.d.cts",
|
|
18
|
+
"default": "./dist/index.cjs"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"./css": "./dist/ghostly.css",
|
|
22
|
+
"./tailwind": {
|
|
23
|
+
"import": {
|
|
24
|
+
"types": "./dist/tailwind.d.ts",
|
|
25
|
+
"default": "./dist/tailwind.js"
|
|
26
|
+
},
|
|
27
|
+
"require": {
|
|
28
|
+
"types": "./dist/tailwind.d.cts",
|
|
29
|
+
"default": "./dist/tailwind.cjs"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"files": ["dist", "README.md", "LICENSE"],
|
|
34
|
+
"sideEffects": ["*.css"],
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "tsup",
|
|
37
|
+
"dev": "tsup --watch"
|
|
38
|
+
},
|
|
39
|
+
"peerDependencies": {
|
|
40
|
+
"tailwindcss": ">=3.0.0"
|
|
41
|
+
},
|
|
42
|
+
"peerDependenciesMeta": {
|
|
43
|
+
"tailwindcss": {
|
|
44
|
+
"optional": true
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"tailwindcss": "^4.0.0",
|
|
49
|
+
"tsup": "^8.5.0",
|
|
50
|
+
"typescript": "^5.9.3"
|
|
51
|
+
},
|
|
52
|
+
"keywords": [
|
|
53
|
+
"skeleton",
|
|
54
|
+
"loading",
|
|
55
|
+
"placeholder",
|
|
56
|
+
"shimmer",
|
|
57
|
+
"css",
|
|
58
|
+
"zero-config"
|
|
59
|
+
],
|
|
60
|
+
"repository": {
|
|
61
|
+
"type": "git",
|
|
62
|
+
"url": "https://github.com/AdanSerrano/ghostly",
|
|
63
|
+
"directory": "packages/core"
|
|
64
|
+
},
|
|
65
|
+
"bugs": {
|
|
66
|
+
"url": "https://github.com/AdanSerrano/ghostly/issues"
|
|
67
|
+
},
|
|
68
|
+
"homepage": "https://github.com/AdanSerrano/ghostly#readme"
|
|
69
|
+
}
|