@24vlh/vds 0.1.0 → 0.1.1

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.
@@ -1,385 +1 @@
1
- /************************************************************
2
- * VLAH DESIGN SYSTEM (VDS) - Skeleton Loading System
3
- *
4
- * Responsibilities:
5
- * - Define skeleton primitives (line, avatar, block, card, row, item)
6
- * - Provide a unified shimmer animation shared across VDS
7
- * - Support density variants and multi-component composition
8
- * - Ensure accessibility via reduced-motion compliance
9
- * - Match form, content-block, and layout surfaces for coherent loading
10
- *
11
- * System Notes:
12
- * - 100% token-driven: spacing, radii, surfaces, aspect-ratios
13
- * - Animation is pure CSS; JS only toggles visibility
14
- * - Shimmer uses vds-skeleton-shimmer and respects prefers-reduced-motion
15
- * - Patterns are responsive and safe for all layout containers
16
- ************************************************************/
17
-
18
- /* ---------------------------------------------------------
19
- 1. SKELETON TOKEN DEFINITIONS
20
- --------------------------------------------------------- */
21
-
22
- [data-vds-skeleton],
23
- .vds-skeleton {
24
- --skeleton-line-height: 1rem;
25
- }
26
-
27
- /* ---------------------------------------------------------
28
- 2. SHIMMER ANIMATION (Shared with forms)
29
- --------------------------------------------------------- */
30
-
31
- @keyframes vds-skeleton-shimmer {
32
- 0% {
33
- transform: translateX(-150%);
34
- }
35
- 100% {
36
- transform: translateX(150%);
37
- }
38
- }
39
-
40
- /* ---------------------------------------------------------
41
- 3. BASE SKELETON
42
- --------------------------------------------------------- */
43
-
44
- .skeleton {
45
- position: relative;
46
- display: block;
47
-
48
- width: 100%;
49
- height: var(--skeleton-line-height);
50
-
51
- border-radius: var(--radius-md);
52
- background-color: var(--color-muted-bg);
53
-
54
- overflow: hidden;
55
- }
56
-
57
- .skeleton::after {
58
- content: "";
59
- position: absolute;
60
- top: 0;
61
- right: 0;
62
- bottom: 0;
63
- left: 0;
64
-
65
- transform: translateX(-150%);
66
- background: linear-gradient(
67
- 90deg,
68
- transparent,
69
- var(--color-surface-subtle),
70
- transparent
71
- );
72
-
73
- animation: vds-skeleton-shimmer 1.6s infinite;
74
- }
75
-
76
- .skeleton--sm {
77
- height: calc(var(--skeleton-line-height) * 0.75);
78
- }
79
-
80
- .skeleton--md {
81
- height: var(--skeleton-line-height);
82
- }
83
-
84
- .skeleton--lg {
85
- height: calc(var(--skeleton-line-height) * 1.25);
86
- }
87
-
88
- .skeleton--xl {
89
- height: calc(var(--skeleton-line-height) * 1.75);
90
- }
91
-
92
- .skeleton--subtle {
93
- background-color: var(--color-surface-subtle);
94
- }
95
-
96
- .skeleton--strong {
97
- background-color: var(--color-muted-border);
98
- }
99
-
100
- .skeleton--static::after {
101
- animation: none !important;
102
- display: none !important;
103
- }
104
-
105
- /* ---------------------------------------------------------
106
- 4. SKELETON LINE (Text simulation)
107
- --------------------------------------------------------- */
108
-
109
- .skeleton-line {
110
- display: block;
111
- width: 100%;
112
- height: var(--skeleton-line-height);
113
-
114
- margin-bottom: var(--space-2);
115
- border-radius: var(--radius-md);
116
- background-color: var(--color-muted-bg);
117
-
118
- position: relative;
119
- overflow: hidden;
120
- }
121
-
122
- .skeleton-line::after {
123
- content: "";
124
- position: absolute;
125
- top: 0;
126
- right: 0;
127
- bottom: 0;
128
- left: 0;
129
- transform: translateX(-150%);
130
- background: linear-gradient(
131
- 90deg,
132
- transparent,
133
- var(--color-surface-subtle),
134
- transparent
135
- );
136
- animation: vds-skeleton-shimmer 1.6s infinite;
137
- }
138
-
139
- .skeleton-line--short {
140
- width: 40%;
141
- }
142
-
143
- .skeleton-line--medium {
144
- width: 60%;
145
- }
146
-
147
- .skeleton-line--long {
148
- width: 80%;
149
- }
150
-
151
- .skeleton-line--full {
152
- width: 100%;
153
- }
154
-
155
- .skeleton-line--xs {
156
- height: calc(var(--skeleton-line-height) * 0.6);
157
- }
158
-
159
- .skeleton-line--sm {
160
- height: calc(var(--skeleton-line-height) * 0.8);
161
- }
162
-
163
- .skeleton-line--lg {
164
- height: calc(var(--skeleton-line-height) * 1.3);
165
- }
166
-
167
- /* ---------------------------------------------------------
168
- 5. SKELETON AVATAR
169
- --------------------------------------------------------- */
170
-
171
- .skeleton-avatar {
172
- display: inline-block;
173
-
174
- background-color: var(--color-muted-bg);
175
- border-radius: var(--radius-full);
176
-
177
- position: relative;
178
- overflow: hidden;
179
- }
180
-
181
- .skeleton-avatar--sm {
182
- width: var(--avatar-size-sm);
183
- height: var(--avatar-size-sm);
184
- }
185
-
186
- .skeleton-avatar--md {
187
- width: var(--avatar-size-md);
188
- height: var(--avatar-size-md);
189
- }
190
-
191
- .skeleton-avatar--lg {
192
- width: var(--avatar-size-lg);
193
- height: var(--avatar-size-lg);
194
- }
195
-
196
- .skeleton-avatar--square {
197
- border-radius: var(--radius-md);
198
- }
199
-
200
- .skeleton-avatar::after {
201
- content: "";
202
- position: absolute;
203
- top: 0;
204
- right: 0;
205
- bottom: 0;
206
- left: 0;
207
- transform: translateX(-150%);
208
- background: linear-gradient(
209
- 90deg,
210
- transparent,
211
- var(--color-surface-subtle),
212
- transparent
213
- );
214
- animation: vds-skeleton-shimmer 1.6s infinite;
215
- }
216
-
217
- /* ---------------------------------------------------------
218
- 6. SKELETON BLOCK (Media / Images)
219
- --------------------------------------------------------- */
220
-
221
- .skeleton-block {
222
- width: 100%;
223
- background-color: var(--color-muted-bg);
224
- border-radius: var(--radius-md);
225
- position: relative;
226
- overflow: hidden;
227
- }
228
-
229
- .skeleton-block--1-1 {
230
- aspect-ratio: 1 / 1;
231
- }
232
-
233
- .skeleton-block--4-3 {
234
- aspect-ratio: 4 / 3;
235
- }
236
-
237
- .skeleton-block--16-9 {
238
- aspect-ratio: 16 / 9;
239
- }
240
-
241
- .skeleton-block--21-9 {
242
- aspect-ratio: 21 / 9;
243
- }
244
-
245
- .skeleton-block--sm {
246
- height: 6rem;
247
- }
248
-
249
- .skeleton-block--md {
250
- height: 12rem;
251
- }
252
-
253
- .skeleton-block--lg {
254
- height: 18rem;
255
- }
256
-
257
- .skeleton-block::after {
258
- content: "";
259
- position: absolute;
260
- top: 0;
261
- right: 0;
262
- bottom: 0;
263
- left: 0;
264
- transform: translateX(-150%);
265
- background: linear-gradient(
266
- 90deg,
267
- transparent,
268
- var(--color-surface-subtle),
269
- transparent
270
- );
271
- animation: vds-skeleton-shimmer 1.6s infinite;
272
- }
273
-
274
- /* ---------------------------------------------------------
275
- 7. SKELETON CARD (Composite pattern)
276
- --------------------------------------------------------- */
277
-
278
- .skeleton-card {
279
- display: flex;
280
- flex-direction: column;
281
- gap: var(--space-3);
282
-
283
- background-color: var(--color-surface);
284
- border: 1px solid var(--color-border-subtle);
285
- border-radius: var(--radius-md);
286
-
287
- padding: var(--space-6);
288
- }
289
-
290
- .skeleton-card--dense {
291
- padding: var(--space-4);
292
- }
293
-
294
- .skeleton-card--relaxed {
295
- padding: var(--space-8);
296
- }
297
-
298
- .skeleton-card--list {
299
- flex-direction: row;
300
- align-items: center;
301
- gap: var(--space-4);
302
- }
303
-
304
- .skeleton-card--media .skeleton-block {
305
- margin-bottom: var(--space-4);
306
- }
307
-
308
- .skeleton-card--stat .skeleton-line {
309
- height: calc(var(--skeleton-line-height) * 1.6);
310
- width: 50%;
311
- }
312
-
313
- /* ---------------------------------------------------------
314
- 8. SKELETON ROW (Table loading)
315
- --------------------------------------------------------- */
316
-
317
- .skeleton-row td {
318
- padding: var(--space-3) var(--space-4);
319
- }
320
-
321
- .skeleton-row--a td {
322
- padding: var(--space-4) var(--space-5);
323
- }
324
-
325
- .skeleton-row--c td {
326
- padding: var(--space-2) var(--space-3);
327
- }
328
-
329
- /* ---------------------------------------------------------
330
- 9. SKELETON ITEM (List items)
331
- --------------------------------------------------------- */
332
-
333
- .skeleton-item {
334
- display: flex;
335
- align-items: center;
336
- gap: var(--space-3);
337
- padding: var(--space-3) 0;
338
- }
339
-
340
- .skeleton-item--compact {
341
- gap: var(--space-2);
342
- padding: var(--space-2) 0;
343
- }
344
-
345
- .skeleton-item--spacious {
346
- gap: var(--space-4);
347
- padding: var(--space-4) 0;
348
- }
349
-
350
- /* ---------------------------------------------------------
351
- 10. COMPOSITION HELPERS
352
- --------------------------------------------------------- */
353
-
354
- .skeleton-stack {
355
- display: flex;
356
- flex-direction: column;
357
- gap: var(--space-3);
358
- }
359
-
360
- .skeleton-inline {
361
- display: flex;
362
- align-items: center;
363
- gap: var(--space-3);
364
- }
365
-
366
- .skeleton-gap-sm {
367
- gap: var(--space-2);
368
- }
369
-
370
- .skeleton-gap-lg {
371
- gap: var(--space-6);
372
- }
373
-
374
- /* ---------------------------------------------------------
375
- 11. REDUCED MOTION HANDLING
376
- --------------------------------------------------------- */
377
-
378
- @media (prefers-reduced-motion: reduce) {
379
- .skeleton::after,
380
- .skeleton-line::after,
381
- .skeleton-avatar::after,
382
- .skeleton-block::after {
383
- animation: none !important;
384
- }
385
- }
1
+ .vds-skeleton,[data-vds-skeleton]{--skeleton-line-height:1rem}@keyframes vds-skeleton-shimmer{0%{transform:translateX(-150%)}to{transform:translateX(150%)}}.skeleton{background-color:var(--color-muted-bg);border-radius:var(--radius-md);display:block;height:var(--skeleton-line-height);overflow:hidden;position:relative;width:100%}.skeleton:after{animation:vds-skeleton-shimmer 1.6s infinite;background:linear-gradient(90deg,transparent,var(--color-surface-subtle),transparent);bottom:0;content:"";left:0;position:absolute;right:0;top:0;transform:translateX(-150%)}.skeleton--sm{height:calc(var(--skeleton-line-height)*.75)}.skeleton--md{height:var(--skeleton-line-height)}.skeleton--lg{height:calc(var(--skeleton-line-height)*1.25)}.skeleton--xl{height:calc(var(--skeleton-line-height)*1.75)}.skeleton--subtle{background-color:var(--color-surface-subtle)}.skeleton--strong{background-color:var(--color-muted-border)}.skeleton--static:after{animation:none!important;display:none!important}.skeleton-line{background-color:var(--color-muted-bg);border-radius:var(--radius-md);display:block;height:var(--skeleton-line-height);margin-bottom:var(--space-2);overflow:hidden;position:relative;width:100%}.skeleton-line:after{animation:vds-skeleton-shimmer 1.6s infinite;background:linear-gradient(90deg,transparent,var(--color-surface-subtle),transparent);bottom:0;content:"";left:0;position:absolute;right:0;top:0;transform:translateX(-150%)}.skeleton-line--short{width:40%}.skeleton-line--medium{width:60%}.skeleton-line--long{width:80%}.skeleton-line--full{width:100%}.skeleton-line--xs{height:calc(var(--skeleton-line-height)*.6)}.skeleton-line--sm{height:calc(var(--skeleton-line-height)*.8)}.skeleton-line--lg{height:calc(var(--skeleton-line-height)*1.3)}.skeleton-avatar{background-color:var(--color-muted-bg);border-radius:var(--radius-full);display:inline-block;overflow:hidden;position:relative}.skeleton-avatar--sm{height:var(--avatar-size-sm);width:var(--avatar-size-sm)}.skeleton-avatar--md{height:var(--avatar-size-md);width:var(--avatar-size-md)}.skeleton-avatar--lg{height:var(--avatar-size-lg);width:var(--avatar-size-lg)}.skeleton-avatar--square{border-radius:var(--radius-md)}.skeleton-avatar:after{animation:vds-skeleton-shimmer 1.6s infinite;background:linear-gradient(90deg,transparent,var(--color-surface-subtle),transparent);bottom:0;content:"";left:0;position:absolute;right:0;top:0;transform:translateX(-150%)}.skeleton-block{background-color:var(--color-muted-bg);border-radius:var(--radius-md);overflow:hidden;position:relative;width:100%}.skeleton-block--1-1{aspect-ratio:1/1}.skeleton-block--4-3{aspect-ratio:4/3}.skeleton-block--16-9{aspect-ratio:16/9}.skeleton-block--21-9{aspect-ratio:21/9}.skeleton-block--sm{height:6rem}.skeleton-block--md{height:12rem}.skeleton-block--lg{height:18rem}.skeleton-block:after{animation:vds-skeleton-shimmer 1.6s infinite;background:linear-gradient(90deg,transparent,var(--color-surface-subtle),transparent);bottom:0;content:"";left:0;position:absolute;right:0;top:0;transform:translateX(-150%)}.skeleton-card{background-color:var(--color-surface);border:1px solid var(--color-border-subtle);border-radius:var(--radius-md);display:flex;flex-direction:column;gap:var(--space-3);padding:var(--space-6)}.skeleton-card--dense{padding:var(--space-4)}.skeleton-card--relaxed{padding:var(--space-8)}.skeleton-card--list{align-items:center;flex-direction:row;gap:var(--space-4)}.skeleton-card--media .skeleton-block{margin-bottom:var(--space-4)}.skeleton-card--stat .skeleton-line{height:calc(var(--skeleton-line-height)*1.6);width:50%}.skeleton-row td{padding:var(--space-3) var(--space-4)}.skeleton-row--a td{padding:var(--space-4) var(--space-5)}.skeleton-row--c td{padding:var(--space-2) var(--space-3)}.skeleton-item{align-items:center;display:flex;gap:var(--space-3);padding:var(--space-3) 0}.skeleton-item--compact{gap:var(--space-2);padding:var(--space-2) 0}.skeleton-item--spacious{gap:var(--space-4);padding:var(--space-4) 0}.skeleton-stack{display:flex;flex-direction:column;gap:var(--space-3)}.skeleton-inline{align-items:center;display:flex;gap:var(--space-3)}.skeleton-gap-sm{gap:var(--space-2)}.skeleton-gap-lg{gap:var(--space-6)}@media (prefers-reduced-motion:reduce){.skeleton-avatar:after,.skeleton-block:after,.skeleton-line:after,.skeleton:after{animation:none!important}}