@duskmoon-dev/core 1.19.4 → 1.19.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +1 -1
  2. package/dist/components/alert.css +81 -3
  3. package/dist/components/dialog.css +29 -3
  4. package/dist/components/dropdown.css +91 -0
  5. package/dist/components/fab.css +182 -0
  6. package/dist/components/index.css +1119 -232
  7. package/dist/components/loading.css +105 -0
  8. package/dist/components/modal.css +66 -4
  9. package/dist/components/navigation.css +94 -54
  10. package/dist/components/progress.css +74 -0
  11. package/dist/components/radial-progress.css +47 -0
  12. package/dist/components/skeleton.css +13 -1
  13. package/dist/components/snackbar.css +48 -18
  14. package/dist/components/swap.css +116 -0
  15. package/dist/components/toast.css +188 -34
  16. package/dist/components/tooltip.css +2 -47
  17. package/dist/esm/components/alert.js +81 -3
  18. package/dist/esm/components/dialog.js +29 -3
  19. package/dist/esm/components/dropdown.d.ts +5 -0
  20. package/dist/esm/components/dropdown.js +100 -0
  21. package/dist/esm/components/fab.d.ts +5 -0
  22. package/dist/esm/components/fab.js +191 -0
  23. package/dist/esm/components/loading.d.ts +5 -0
  24. package/dist/esm/components/loading.js +114 -0
  25. package/dist/esm/components/modal.js +66 -4
  26. package/dist/esm/components/navigation.js +94 -54
  27. package/dist/esm/components/progress.js +74 -0
  28. package/dist/esm/components/radial-progress.d.ts +5 -0
  29. package/dist/esm/components/radial-progress.js +56 -0
  30. package/dist/esm/components/skeleton.js +13 -1
  31. package/dist/esm/components/snackbar.js +48 -18
  32. package/dist/esm/components/swap.d.ts +5 -0
  33. package/dist/esm/components/swap.js +125 -0
  34. package/dist/esm/components/toast.js +188 -34
  35. package/dist/esm/components/tooltip.js +2 -47
  36. package/dist/index.css +1119 -232
  37. package/dist/index.min.css +1 -1
  38. package/dist/standalone/duskmoonui-themes.css +1 -1
  39. package/dist/standalone/duskmoonui.css +1120 -233
  40. package/dist/standalone/duskmoonui.js +25 -9
  41. package/dist/standalone/duskmoonui.mjs +25 -9
  42. package/package.json +31 -1
@@ -0,0 +1,125 @@
1
+ // Auto-generated from swap.css
2
+ export const css = `/**
3
+ * Swap Component Styles
4
+ * Displays one of two non-interactive state indicators.
5
+ */
6
+
7
+ @layer components {
8
+ .swap {
9
+ position: relative;
10
+ display: inline-grid;
11
+ place-items: center;
12
+ vertical-align: middle;
13
+ cursor: pointer;
14
+ user-select: none;
15
+ }
16
+
17
+ .swap-input {
18
+ position: absolute;
19
+ inset: 0;
20
+ z-index: 1;
21
+ width: 100%;
22
+ height: 100%;
23
+ margin: 0;
24
+ opacity: 0;
25
+ cursor: pointer;
26
+ }
27
+
28
+ .swap-on,
29
+ .swap-off {
30
+ grid-area: 1 / 1;
31
+ display: inline-flex;
32
+ align-items: center;
33
+ justify-content: center;
34
+ inline-size: max-content;
35
+ max-inline-size: 100%;
36
+ transition: opacity 150ms ease-out, transform 150ms ease-out;
37
+ }
38
+
39
+ .swap-on {
40
+ opacity: 0;
41
+ visibility: hidden;
42
+ pointer-events: none;
43
+ }
44
+
45
+ .swap-off {
46
+ opacity: 1;
47
+ visibility: visible;
48
+ pointer-events: none;
49
+ }
50
+
51
+ .swap-input:checked ~ .swap-on,
52
+ .swap[aria-pressed="true"] > .swap-on {
53
+ opacity: 1;
54
+ visibility: visible;
55
+ }
56
+
57
+ .swap-input:checked ~ .swap-off,
58
+ .swap[aria-pressed="true"] > .swap-off {
59
+ opacity: 0;
60
+ visibility: hidden;
61
+ }
62
+
63
+ .swap:focus-visible,
64
+ .swap:has(.swap-input:focus-visible) {
65
+ outline: none;
66
+ box-shadow: 0 0 0 3px color-mix(in oklch, currentColor 20%, transparent);
67
+ border-radius: var(--radius-sm);
68
+ }
69
+
70
+ .swap:disabled,
71
+ .swap:has(.swap-input:disabled) {
72
+ cursor: not-allowed;
73
+ opacity: 0.5;
74
+ }
75
+
76
+ .swap-input:disabled {
77
+ cursor: not-allowed;
78
+ }
79
+
80
+ .swap-rotate .swap-on {
81
+ transform: rotate(-90deg) scale(0.8);
82
+ }
83
+
84
+ .swap-rotate .swap-off {
85
+ transform: rotate(0deg) scale(1);
86
+ }
87
+
88
+ .swap-rotate .swap-input:checked ~ .swap-on,
89
+ .swap-rotate[aria-pressed="true"] > .swap-on {
90
+ transform: rotate(0deg) scale(1);
91
+ }
92
+
93
+ .swap-rotate .swap-input:checked ~ .swap-off,
94
+ .swap-rotate[aria-pressed="true"] > .swap-off {
95
+ transform: rotate(90deg) scale(0.8);
96
+ }
97
+
98
+ /* Presentation-only override. It intentionally wins over semantic state. */
99
+ .swap.swap-active > .swap-on {
100
+ opacity: 1;
101
+ visibility: visible;
102
+ transform: rotate(0deg) scale(1);
103
+ }
104
+
105
+ .swap.swap-active > .swap-off {
106
+ opacity: 0;
107
+ visibility: hidden;
108
+ transform: rotate(90deg) scale(0.8);
109
+ }
110
+
111
+ @media (prefers-reduced-motion: reduce) {
112
+ .swap-on,
113
+ .swap-off {
114
+ transition: none;
115
+ }
116
+ }
117
+ }
118
+ `;
119
+
120
+ const sheet = typeof CSSStyleSheet !== 'undefined' ? new CSSStyleSheet() : null;
121
+ if (sheet) {
122
+ sheet.replaceSync(css);
123
+ }
124
+ export const styles = sheet;
125
+ export default sheet;
@@ -16,17 +16,36 @@ export const css = `/**
16
16
  pointer-events: none;
17
17
  }
18
18
 
19
+ /* Native command targets use the container as a manual popover. Reset the
20
+ user-agent popover box while preserving the existing positioning API. */
21
+ :where(.toast-container[popover]) {
22
+ inset: auto;
23
+ width: auto;
24
+ height: auto;
25
+ margin: 0;
26
+ overflow: visible;
27
+ color: inherit;
28
+ background: transparent;
29
+ border: 0;
30
+ }
31
+
32
+ .toast-container[popover]:not(:popover-open) {
33
+ display: none;
34
+ }
35
+
19
36
  /* Position Variants */
20
37
  .toast-container-top-right {
21
38
  top: 0;
22
39
  right: 0;
23
40
  align-items: flex-end;
41
+ padding-top: max(1rem, env(safe-area-inset-top));
24
42
  }
25
43
 
26
44
  .toast-container-top-left {
27
45
  top: 0;
28
46
  left: 0;
29
47
  align-items: flex-start;
48
+ padding-top: max(1rem, env(safe-area-inset-top));
30
49
  }
31
50
 
32
51
  .toast-container-top-center {
@@ -34,18 +53,21 @@ export const css = `/**
34
53
  left: 50%;
35
54
  transform: translateX(-50%);
36
55
  align-items: center;
56
+ padding-top: max(1rem, env(safe-area-inset-top));
37
57
  }
38
58
 
39
59
  .toast-container-bottom-right {
40
60
  bottom: 0;
41
61
  right: 0;
42
62
  align-items: flex-end;
63
+ padding-bottom: max(1rem, env(safe-area-inset-bottom));
43
64
  }
44
65
 
45
66
  .toast-container-bottom-left {
46
67
  bottom: 0;
47
68
  left: 0;
48
69
  align-items: flex-start;
70
+ padding-bottom: max(1rem, env(safe-area-inset-bottom));
49
71
  }
50
72
 
51
73
  .toast-container-bottom-center {
@@ -53,10 +75,20 @@ export const css = `/**
53
75
  left: 50%;
54
76
  transform: translateX(-50%);
55
77
  align-items: center;
78
+ padding-bottom: max(1rem, env(safe-area-inset-bottom));
56
79
  }
57
80
 
81
+ /* Logical aliases add RTL-aware placement without changing left/right. */
82
+ .toast-container-top-start { top: 0; inset-inline-start: 0; align-items: flex-start; }
83
+ .toast-container-top-end { top: 0; inset-inline-end: 0; align-items: flex-end; }
84
+ .toast-container-bottom-start { bottom: 0; inset-inline-start: 0; align-items: flex-start; }
85
+ .toast-container-bottom-end { bottom: 0; inset-inline-end: 0; align-items: flex-end; }
86
+
58
87
  /* Base Toast */
59
88
  .toast {
89
+ --_toast-accent-color: var(--color-primary);
90
+
91
+ position: relative;
60
92
  display: flex;
61
93
  align-items: flex-start;
62
94
  gap: 0.75rem;
@@ -87,9 +119,28 @@ export const css = `/**
87
119
  /* Toast Open State */
88
120
  .toast.toast-open,
89
121
  .toast.show,
90
- .toast-show {
122
+ .toast.toast-show {
123
+ opacity: 1;
124
+ transform: translateX(0) translateY(0);
125
+ visibility: visible;
126
+ pointer-events: auto;
127
+ }
128
+
129
+ /* A closed item cannot intercept input. Consumers should also use hidden,
130
+ inert, or unmounting when removing it from the accessibility tree. */
131
+ .toast:not(.toast-open):not(.show):not(.toast-show),
132
+ .toast[hidden],
133
+ .toast[inert],
134
+ .toast[aria-hidden="true"] {
135
+ pointer-events: none;
136
+ visibility: hidden;
137
+ }
138
+
139
+ .toast-container[popover]:popover-open .toast {
91
140
  opacity: 1;
92
141
  transform: translateX(0) translateY(0);
142
+ visibility: visible;
143
+ pointer-events: auto;
93
144
  }
94
145
 
95
146
  /* Toast Icon */
@@ -140,7 +191,7 @@ export const css = `/**
140
191
  cursor: pointer;
141
192
  transition: background-color 150ms ease-in-out, color 150ms ease-in-out;
142
193
  flex-shrink: 0;
143
- margin-left: auto;
194
+ margin-inline-start: auto;
144
195
  }
145
196
 
146
197
  .toast-close:hover {
@@ -158,10 +209,46 @@ export const css = `/**
158
209
  display: flex;
159
210
  gap: 0.5rem;
160
211
  margin-top: 0.5rem;
212
+ flex-wrap: wrap;
213
+ }
214
+
215
+ .toast-action {
216
+ display: inline-flex;
217
+ align-items: center;
218
+ justify-content: center;
219
+ width: fit-content;
220
+ min-height: 2rem;
221
+ padding: 0.375rem 0.75rem;
222
+ color: var(--color-primary);
223
+ font-size: 0.875rem;
224
+ font-weight: 500;
225
+ background-color: transparent;
226
+ border: 1px solid currentColor;
227
+ border-radius: var(--radius-sm);
228
+ cursor: pointer;
229
+ }
230
+
231
+ .toast-action:hover {
232
+ background-color: color-mix(in oklch, currentColor 10%, transparent);
233
+ }
234
+
235
+ .toast-action:focus-visible {
236
+ outline: none;
237
+ box-shadow: 0 0 0 3px color-mix(in oklch, currentColor 20%, transparent);
161
238
  }
162
239
 
163
240
  /* Type Variants */
241
+ .toast-accent {
242
+ --_toast-accent-color: var(--color-accent);
243
+ border-color: var(--color-accent);
244
+ }
245
+
246
+ .toast-accent .toast-icon {
247
+ color: var(--color-accent);
248
+ }
249
+
164
250
  .toast-info {
251
+ --_toast-accent-color: var(--color-info);
165
252
  border-color: var(--color-info);
166
253
  }
167
254
 
@@ -170,6 +257,7 @@ export const css = `/**
170
257
  }
171
258
 
172
259
  .toast-success {
260
+ --_toast-accent-color: var(--color-success);
173
261
  border-color: var(--color-success);
174
262
  }
175
263
 
@@ -178,6 +266,7 @@ export const css = `/**
178
266
  }
179
267
 
180
268
  .toast-warning {
269
+ --_toast-accent-color: var(--color-warning);
181
270
  border-color: var(--color-warning);
182
271
  }
183
272
 
@@ -186,6 +275,7 @@ export const css = `/**
186
275
  }
187
276
 
188
277
  .toast-error {
278
+ --_toast-accent-color: var(--color-error);
189
279
  border-color: var(--color-error);
190
280
  }
191
281
 
@@ -194,6 +284,7 @@ export const css = `/**
194
284
  }
195
285
 
196
286
  .toast-primary {
287
+ --_toast-accent-color: var(--color-primary);
197
288
  border-color: var(--color-primary);
198
289
  }
199
290
 
@@ -202,6 +293,7 @@ export const css = `/**
202
293
  }
203
294
 
204
295
  .toast-secondary {
296
+ --_toast-accent-color: var(--color-secondary);
205
297
  border-color: var(--color-secondary);
206
298
  }
207
299
 
@@ -210,6 +302,7 @@ export const css = `/**
210
302
  }
211
303
 
212
304
  .toast-tertiary {
305
+ --_toast-accent-color: var(--color-tertiary);
213
306
  border-color: var(--color-tertiary);
214
307
  }
215
308
 
@@ -217,15 +310,8 @@ export const css = `/**
217
310
  color: var(--color-tertiary);
218
311
  }
219
312
 
220
- .toast-accent {
221
- border-color: var(--color-accent);
222
- }
223
-
224
- .toast-accent .toast-icon {
225
- color: var(--color-accent);
226
- }
227
-
228
313
  .toast-neutral {
314
+ --_toast-accent-color: var(--color-neutral);
229
315
  border-color: var(--color-neutral);
230
316
  }
231
317
 
@@ -234,6 +320,7 @@ export const css = `/**
234
320
  }
235
321
 
236
322
  .toast-base {
323
+ --_toast-accent-color: var(--color-base-content);
237
324
  border-color: var(--color-base-content);
238
325
  }
239
326
 
@@ -242,58 +329,58 @@ export const css = `/**
242
329
  }
243
330
 
244
331
  /* Filled Variants */
332
+ .toast-filled.toast-accent {
333
+ background-color: var(--color-accent);
334
+ border-color: transparent;
335
+ color: var(--color-accent-content);
336
+ }
337
+
245
338
  .toast-filled.toast-info {
246
- background-color: var(--color-info-container);
339
+ background-color: var(--color-info);
247
340
  border-color: transparent;
248
- color: var(--color-on-info-container);
341
+ color: var(--color-info-content);
249
342
  }
250
343
 
251
344
  .toast-filled.toast-success {
252
- background-color: var(--color-success-container);
345
+ background-color: var(--color-success);
253
346
  border-color: transparent;
254
- color: var(--color-on-success-container);
347
+ color: var(--color-success-content);
255
348
  }
256
349
 
257
350
  .toast-filled.toast-warning {
258
- background-color: var(--color-warning-container);
351
+ background-color: var(--color-warning);
259
352
  border-color: transparent;
260
- color: var(--color-on-warning-container);
353
+ color: var(--color-warning-content);
261
354
  }
262
355
 
263
356
  .toast-filled.toast-error {
264
- background-color: var(--color-error-container);
357
+ background-color: var(--color-error);
265
358
  border-color: transparent;
266
- color: var(--color-on-error-container);
359
+ color: var(--color-error-content);
267
360
  }
268
361
 
269
362
  .toast-filled.toast-primary {
270
- background-color: var(--color-primary-container);
363
+ background-color: var(--color-primary);
271
364
  border-color: transparent;
272
- color: var(--color-on-primary-container);
365
+ color: var(--color-primary-content);
273
366
  }
274
367
 
275
368
  .toast-filled.toast-secondary {
276
- background-color: var(--color-secondary-container);
369
+ background-color: var(--color-secondary);
277
370
  border-color: transparent;
278
- color: var(--color-on-secondary-container);
371
+ color: var(--color-secondary-content);
279
372
  }
280
373
 
281
374
  .toast-filled.toast-tertiary {
282
- background-color: var(--color-tertiary-container);
375
+ background-color: var(--color-tertiary);
283
376
  border-color: transparent;
284
- color: var(--color-on-tertiary-container);
285
- }
286
-
287
- .toast-filled.toast-accent {
288
- background-color: color-mix(in oklch, var(--color-accent) 15%, var(--color-surface));
289
- border-color: transparent;
290
- color: var(--color-on-surface);
377
+ color: var(--color-tertiary-content);
291
378
  }
292
379
 
293
380
  .toast-filled.toast-neutral {
294
- background-color: color-mix(in oklch, var(--color-neutral) 15%, var(--color-surface));
381
+ background-color: var(--color-neutral);
295
382
  border-color: transparent;
296
- color: var(--color-on-surface);
383
+ color: var(--color-neutral-content);
297
384
  }
298
385
 
299
386
  .toast-filled.toast-base {
@@ -306,8 +393,16 @@ export const css = `/**
306
393
  .toast-title and .toast-message have explicit color rules that would otherwise
307
394
  override the filled variant's inherited on-container color. */
308
395
  .toast-filled .toast-title,
309
- .toast-filled .toast-message {
396
+ .toast-filled .toast-message,
397
+ .toast-filled .toast-icon,
398
+ .toast-filled .toast-close,
399
+ .toast-filled .toast-action {
400
+ color: inherit;
401
+ }
402
+
403
+ .toast-filled .toast-close:hover {
310
404
  color: inherit;
405
+ background-color: color-mix(in oklch, currentColor 12%, transparent);
311
406
  }
312
407
 
313
408
  /* Ghost Variant */
@@ -316,6 +411,7 @@ export const css = `/**
316
411
  border-color: transparent;
317
412
  }
318
413
 
414
+ .toast-ghost.toast-accent { color: var(--color-accent); }
319
415
  .toast-ghost.toast-primary { color: var(--color-primary); }
320
416
  .toast-ghost.toast-secondary { color: var(--color-secondary); }
321
417
  .toast-ghost.toast-tertiary { color: var(--color-tertiary); }
@@ -323,7 +419,6 @@ export const css = `/**
323
419
  .toast-ghost.toast-success { color: var(--color-success); }
324
420
  .toast-ghost.toast-warning { color: var(--color-warning); }
325
421
  .toast-ghost.toast-error { color: var(--color-error); }
326
- .toast-ghost.toast-accent { color: var(--color-accent); }
327
422
  .toast-ghost.toast-neutral { color: var(--color-neutral); }
328
423
  .toast-ghost.toast-base { color: var(--color-base-content); }
329
424
 
@@ -332,6 +427,49 @@ export const css = `/**
332
427
  color: inherit;
333
428
  }
334
429
 
430
+ /* Size and density variants retained by the public API. */
431
+ .toast-sm {
432
+ width: 18rem;
433
+ padding: 0.75rem;
434
+ }
435
+
436
+ .toast-lg {
437
+ width: 26rem;
438
+ padding: 1.25rem;
439
+ }
440
+
441
+ .toast-compact {
442
+ padding: 0.75rem;
443
+ gap: 0.5rem;
444
+ }
445
+
446
+ .toast-compact .toast-icon {
447
+ width: 1.25rem;
448
+ height: 1.25rem;
449
+ font-size: 1rem;
450
+ }
451
+
452
+ .toast-compact .toast-title { font-size: 0.8125rem; }
453
+ .toast-compact .toast-message { font-size: 0.8125rem; }
454
+
455
+ /* Accent edge and stacked presentation. */
456
+ .toast-accent::before {
457
+ content: "";
458
+ position: absolute;
459
+ inset-block: 0;
460
+ inset-inline-start: 0;
461
+ width: 0.25rem;
462
+ background-color: var(--_toast-accent-color);
463
+ border-start-start-radius: var(--radius-md);
464
+ border-end-start-radius: var(--radius-md);
465
+ }
466
+
467
+ .toast-container-stacked .toast:not(:first-child) {
468
+ margin-top: -0.75rem;
469
+ transform: scale(0.97);
470
+ opacity: 0.9;
471
+ }
472
+
335
473
  /* Progress Bar (for auto-dismiss) */
336
474
  .toast-progress {
337
475
  position: absolute;
@@ -362,6 +500,22 @@ export const css = `/**
362
500
  .toast-progress {
363
501
  animation: none;
364
502
  }
503
+
504
+ .toast-container { scroll-behavior: auto; }
505
+ }
506
+
507
+ @media (max-width: 40rem) {
508
+ .toast-container[popover] {
509
+ inset-inline: 0;
510
+ width: 100%;
511
+ transform: none;
512
+ align-items: stretch;
513
+ }
514
+
515
+ .toast {
516
+ width: 100%;
517
+ max-width: 100%;
518
+ }
365
519
  }
366
520
  }
367
521
  `;
@@ -77,53 +77,8 @@ export const css = `/**
77
77
  position-area: right;
78
78
  }
79
79
 
80
- /* ========================================
81
- * Arrow (preferred position only; may be wrong after flip)
82
- * ======================================== */
83
-
84
- .tooltip[popover]::before {
85
- content: '';
86
- position: absolute;
87
- width: 0;
88
- height: 0;
89
- border: 0.375rem solid transparent;
90
- }
91
-
92
- .tooltip-top[popover]::before,
93
- .tooltip[popover]:not(.tooltip-bottom):not(.tooltip-left):not(.tooltip-right)::before {
94
- top: 100%;
95
- left: 50%;
96
- transform: translateX(-50%);
97
- border-top-color: var(--tooltip-bg);
98
- }
99
-
100
- .tooltip-bottom[popover]::before {
101
- bottom: 100%;
102
- top: auto;
103
- left: 50%;
104
- transform: translateX(-50%);
105
- border-bottom-color: var(--tooltip-bg);
106
- border-top-color: transparent;
107
- }
108
-
109
- .tooltip-left[popover]::before {
110
- left: 100%;
111
- top: 50%;
112
- bottom: auto;
113
- transform: translateY(-50%);
114
- border-left-color: var(--tooltip-bg);
115
- border-top-color: transparent;
116
- }
117
-
118
- .tooltip-right[popover]::before {
119
- right: 100%;
120
- left: auto;
121
- top: 50%;
122
- bottom: auto;
123
- transform: translateY(-50%);
124
- border-right-color: var(--tooltip-bg);
125
- border-top-color: transparent;
126
- }
80
+ /* Automatic placement can flip independently of the preferred side. The
81
+ core stays arrowless instead of showing a misleading arrow. */
127
82
 
128
83
  /* ========================================
129
84
  * Color variants