@dorsk/tsumikit 0.78.0 → 0.80.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/dist/components/atoms/Artwork.svelte +5 -3
- package/dist/components/atoms/Badge.svelte +2 -5
- package/dist/components/atoms/Button.svelte +327 -17
- package/dist/components/atoms/Button.svelte.d.ts +4 -1
- package/dist/components/atoms/Card.svelte +160 -12
- package/dist/components/atoms/Checkbox.svelte +181 -3
- package/dist/components/atoms/Gauge.svelte +2 -2
- package/dist/components/atoms/Input.svelte +41 -3
- package/dist/components/atoms/Kbd.svelte +1 -1
- package/dist/components/atoms/Link.svelte +61 -0
- package/dist/components/atoms/Progress.svelte +75 -2
- package/dist/components/atoms/Progress.svelte.d.ts +1 -0
- package/dist/components/atoms/SegmentedProgress.svelte +2 -2
- package/dist/components/atoms/Select.svelte +39 -3
- package/dist/components/atoms/Skeleton.svelte +54 -3
- package/dist/components/atoms/Skeleton.svelte.d.ts +1 -0
- package/dist/components/atoms/Slider.svelte +8 -6
- package/dist/components/atoms/Spinner.svelte +152 -3
- package/dist/components/atoms/Spinner.svelte.d.ts +1 -1
- package/dist/components/atoms/Swatch.svelte +1 -1
- package/dist/components/atoms/Switch.svelte +138 -2
- package/dist/components/atoms/Textarea.svelte +42 -3
- package/dist/components/atoms/Thinking.svelte +130 -0
- package/dist/components/atoms/Thinking.svelte.d.ts +15 -0
- package/dist/components/layouts/AppShell.svelte +6 -6
- package/dist/components/layouts/MasterDetail.svelte +3 -3
- package/dist/components/layouts/NavBar.svelte +4 -4
- package/dist/components/layouts/NavSection.svelte +1 -1
- package/dist/components/layouts/ResizablePanel.svelte +7 -7
- package/dist/components/layouts/TabBar.svelte +2 -2
- package/dist/components/molecules/Accordion.svelte +2 -2
- package/dist/components/molecules/AttachmentList.svelte +2 -2
- package/dist/components/molecules/CapBar.svelte +2 -2
- package/dist/components/molecules/CodeBlock.svelte +5 -5
- package/dist/components/molecules/Combobox.svelte +3 -3
- package/dist/components/molecules/CopyButton.svelte +146 -5
- package/dist/components/molecules/Drawer.svelte +8 -8
- package/dist/components/molecules/EmojiPicker.svelte +1 -1
- package/dist/components/molecules/Field.svelte +55 -1
- package/dist/components/molecules/FileButton.svelte +20 -6
- package/dist/components/molecules/FilterInput.svelte +4 -4
- package/dist/components/molecules/GitRef.svelte +2 -2
- package/dist/components/molecules/GlyphStack.svelte +21 -3
- package/dist/components/molecules/InputGroup.svelte +3 -3
- package/dist/components/molecules/LookPicker.svelte +87 -0
- package/dist/components/molecules/LookPicker.svelte.d.ts +17 -0
- package/dist/components/molecules/Modal.svelte +5 -5
- package/dist/components/molecules/MotionSettings.svelte +166 -0
- package/dist/components/molecules/MotionSettings.svelte.d.ts +18 -0
- package/dist/components/molecules/OptionButton.svelte +8 -3
- package/dist/components/molecules/Pagination.svelte +3 -1
- package/dist/components/molecules/Popover.svelte +18 -11
- package/dist/components/molecules/Prose.svelte +6 -6
- package/dist/components/molecules/RadialMenu.svelte +3 -3
- package/dist/components/molecules/RadioGroup.svelte +67 -4
- package/dist/components/molecules/RichSelect.svelte +6 -4
- package/dist/components/molecules/SectionHeader.svelte +1 -1
- package/dist/components/molecules/SeekSlider.svelte +6 -6
- package/dist/components/molecules/SegmentedControl.svelte +7 -7
- package/dist/components/molecules/SortableList.svelte +2 -2
- package/dist/components/molecules/SplitButton.svelte +1 -1
- package/dist/components/molecules/Tabs.svelte +160 -7
- package/dist/components/molecules/ThemePicker.svelte +1 -1
- package/dist/components/molecules/Timestamp.svelte +1 -1
- package/dist/components/molecules/Toggle.svelte +5 -3
- package/dist/components/molecules/Tooltip.svelte +2 -2
- package/dist/components/molecules/VolumeSlider.svelte +3 -3
- package/dist/components/organisms/ConversationFeed.svelte +1 -1
- package/dist/components/organisms/ConversationPanel.svelte +3 -3
- package/dist/components/organisms/DataTable.svelte +18 -16
- package/dist/fx.d.ts +149 -0
- package/dist/fx.js +111 -0
- package/dist/fx.md +58 -0
- package/dist/index.d.ts +8 -2
- package/dist/index.js +8 -2
- package/dist/looks/README.md +101 -0
- package/dist/looks/depth.css +939 -0
- package/dist/looks/editorial.css +545 -0
- package/dist/looks/tactile.css +871 -0
- package/dist/pointer.d.ts +3 -0
- package/dist/pointer.js +40 -0
- package/dist/stores/fx.svelte.d.ts +17 -0
- package/dist/stores/fx.svelte.js +64 -0
- package/dist/stores/theme.svelte.d.ts +8 -2
- package/dist/stores/theme.svelte.js +33 -7
- package/dist/styles/themes.css +249 -249
- package/dist/styles/tokens.css +37 -2
- package/dist/theme-mode.d.ts +31 -0
- package/dist/theme-mode.js +19 -0
- package/package.json +3 -2
|
@@ -10,6 +10,9 @@
|
|
|
10
10
|
// gradient — accent→teal fill (storage meter / library-health bars).
|
|
11
11
|
// striped — diagonal stripes; animated while in-flight (unpacking).
|
|
12
12
|
// indeterminate — explicit "scanning"/"importing" mode without a percentage.
|
|
13
|
+
// variant — `liquid`: two soft pulses flow through the track while
|
|
14
|
+
// indeterminate; `stripes`: a diagonal shimmer drifts over
|
|
15
|
+
// the fill.
|
|
13
16
|
let {
|
|
14
17
|
value,
|
|
15
18
|
max = 100,
|
|
@@ -22,6 +25,7 @@
|
|
|
22
25
|
shrink = true,
|
|
23
26
|
block = false,
|
|
24
27
|
indeterminate: indeterminateProp = false,
|
|
28
|
+
variant = 'default',
|
|
25
29
|
markers = [],
|
|
26
30
|
toneAt,
|
|
27
31
|
color,
|
|
@@ -51,6 +55,7 @@
|
|
|
51
55
|
striped?: boolean;
|
|
52
56
|
// Force indeterminate mode even when a `value` is supplied.
|
|
53
57
|
indeterminate?: boolean;
|
|
58
|
+
variant?: 'default' | 'liquid' | 'stripes';
|
|
54
59
|
/** Thin vertical lines at `at / max` (caps, thresholds). */
|
|
55
60
|
markers?: { at: number; label?: string; tone?: Tone }[];
|
|
56
61
|
/** Percent thresholds that auto-pick warn/danger; an explicit `tone` other
|
|
@@ -80,7 +85,7 @@
|
|
|
80
85
|
{#snippet track()}
|
|
81
86
|
<div
|
|
82
87
|
data-tsu="Progress"
|
|
83
|
-
class="progress tone-{toneClass} size-{size} {klass}"
|
|
88
|
+
class="progress tone-{toneClass} size-{size} v-{variant} {klass}"
|
|
84
89
|
class:grow={grow}
|
|
85
90
|
class:no-shrink={!shrink}
|
|
86
91
|
class:block={block}
|
|
@@ -146,7 +151,7 @@
|
|
|
146
151
|
position: relative;
|
|
147
152
|
width: 100%;
|
|
148
153
|
height: 0.5rem;
|
|
149
|
-
background: var(--
|
|
154
|
+
background: var(--track-fill);
|
|
150
155
|
border-radius: var(--r-pill);
|
|
151
156
|
overflow: hidden;
|
|
152
157
|
}
|
|
@@ -272,4 +277,72 @@
|
|
|
272
277
|
opacity: 0.35;
|
|
273
278
|
}
|
|
274
279
|
}
|
|
280
|
+
.progress.v-liquid.indeterminate .bar {
|
|
281
|
+
animation: none;
|
|
282
|
+
opacity: 0;
|
|
283
|
+
}
|
|
284
|
+
.progress.v-liquid.indeterminate::before,
|
|
285
|
+
.progress.v-liquid.indeterminate::after {
|
|
286
|
+
content: '';
|
|
287
|
+
position: absolute;
|
|
288
|
+
inset: 0;
|
|
289
|
+
width: 55%;
|
|
290
|
+
border-radius: inherit;
|
|
291
|
+
background: linear-gradient(90deg, transparent, var(--fill, var(--accent)) 35% 65%, transparent);
|
|
292
|
+
transform: translateX(-100%);
|
|
293
|
+
animation: tsu-progress-liquid 1.7s var(--ease-drawer) infinite;
|
|
294
|
+
}
|
|
295
|
+
.progress.v-liquid.indeterminate::after {
|
|
296
|
+
width: 35%;
|
|
297
|
+
opacity: 0.55;
|
|
298
|
+
animation: tsu-progress-liquid-2 1.7s var(--ease-in-out) -0.7s infinite;
|
|
299
|
+
}
|
|
300
|
+
@keyframes tsu-progress-liquid {
|
|
301
|
+
to {
|
|
302
|
+
transform: translateX(282%);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
@keyframes tsu-progress-liquid-2 {
|
|
306
|
+
to {
|
|
307
|
+
transform: translateX(386%);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
.progress.v-stripes .bar {
|
|
311
|
+
position: relative;
|
|
312
|
+
overflow: hidden;
|
|
313
|
+
}
|
|
314
|
+
.progress.v-stripes .bar::after {
|
|
315
|
+
content: '';
|
|
316
|
+
position: absolute;
|
|
317
|
+
inset: 0 -1.5rem 0 0;
|
|
318
|
+
background: repeating-linear-gradient(
|
|
319
|
+
135deg,
|
|
320
|
+
transparent 0 0.5rem,
|
|
321
|
+
color-mix(in srgb, var(--text-on-accent) 28%, transparent) 0.5rem 1rem
|
|
322
|
+
);
|
|
323
|
+
animation: tsu-progress-stripes 0.7s linear infinite;
|
|
324
|
+
}
|
|
325
|
+
@keyframes tsu-progress-stripes {
|
|
326
|
+
from {
|
|
327
|
+
transform: translateX(-1.4142rem);
|
|
328
|
+
}
|
|
329
|
+
to {
|
|
330
|
+
transform: translateX(0);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
@media (prefers-reduced-motion: reduce) {
|
|
334
|
+
.progress.v-liquid.indeterminate {
|
|
335
|
+
background: color-mix(in srgb, var(--fill, var(--accent)) 35%, transparent);
|
|
336
|
+
}
|
|
337
|
+
.progress.v-liquid.indeterminate::before,
|
|
338
|
+
.progress.v-liquid.indeterminate::after {
|
|
339
|
+
display: none;
|
|
340
|
+
}
|
|
341
|
+
.progress.v-liquid.indeterminate .bar {
|
|
342
|
+
display: none;
|
|
343
|
+
}
|
|
344
|
+
.progress.v-stripes .bar::after {
|
|
345
|
+
animation: none;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
275
348
|
</style>
|
|
@@ -168,7 +168,7 @@
|
|
|
168
168
|
flex: 0 1 0%;
|
|
169
169
|
min-width: 3px;
|
|
170
170
|
height: 100%;
|
|
171
|
-
background: var(--
|
|
171
|
+
background: var(--track-fill);
|
|
172
172
|
overflow: hidden;
|
|
173
173
|
}
|
|
174
174
|
.segment:first-child {
|
|
@@ -206,7 +206,7 @@
|
|
|
206
206
|
|
|
207
207
|
.stacked {
|
|
208
208
|
overflow: hidden;
|
|
209
|
-
background: var(--
|
|
209
|
+
background: var(--track-fill);
|
|
210
210
|
}
|
|
211
211
|
.stacked .segment {
|
|
212
212
|
min-width: 0;
|
|
@@ -217,9 +217,10 @@
|
|
|
217
217
|
padding: var(--sp-2) var(--control-px-md);
|
|
218
218
|
font-size: var(--control-fs-md);
|
|
219
219
|
line-height: var(--lh-tight);
|
|
220
|
-
background: var(--select-bg, var(--
|
|
221
|
-
border:
|
|
220
|
+
background: var(--select-bg, var(--control-fill));
|
|
221
|
+
border: var(--edge-width) solid var(--select-border, var(--control-edge));
|
|
222
222
|
border-radius: var(--select-radius, var(--r-md));
|
|
223
|
+
box-shadow: var(--control-shadow);
|
|
223
224
|
color: var(--select-fg, var(--text));
|
|
224
225
|
transition: border-color var(--dur-fast) ease;
|
|
225
226
|
}
|
|
@@ -261,11 +262,15 @@
|
|
|
261
262
|
background: var(--select-bg, var(--bg-elevated-2));
|
|
262
263
|
border: none;
|
|
263
264
|
border-radius: var(--select-radius, var(--r-sm));
|
|
265
|
+
box-shadow: none;
|
|
264
266
|
}
|
|
265
267
|
.select:focus {
|
|
266
268
|
outline: none;
|
|
267
269
|
border-color: var(--accent);
|
|
268
270
|
}
|
|
271
|
+
.select:focus-visible:not(.embedded, .ghost) {
|
|
272
|
+
box-shadow: var(--control-shadow), var(--focus-glow);
|
|
273
|
+
}
|
|
269
274
|
.select:focus-visible {
|
|
270
275
|
outline: var(--focus-ring);
|
|
271
276
|
outline-offset: var(--focus-ring-offset);
|
|
@@ -274,6 +279,36 @@
|
|
|
274
279
|
.select[aria-invalid='true']:focus {
|
|
275
280
|
border-color: var(--danger);
|
|
276
281
|
}
|
|
282
|
+
.select {
|
|
283
|
+
--focus-tint: var(--accent);
|
|
284
|
+
}
|
|
285
|
+
.select[aria-invalid='true'] {
|
|
286
|
+
--focus-tint: var(--danger);
|
|
287
|
+
}
|
|
288
|
+
/* Focus bloom: a solid ring whose soft halo swells, then settles to a quieter glow. */
|
|
289
|
+
.select:not(.ghost, .embedded):focus:not(:global([data-fx-focus='none']) *),
|
|
290
|
+
:global(:is([data-fx-focus='bloom'], [data-fx-focus='label'])) .select:not(.ghost, .embedded):focus:not(:global(:is([data-fx-focus='bloom'], [data-fx-focus='label']) [data-fx-focus='none']) *) {
|
|
291
|
+
outline: none;
|
|
292
|
+
box-shadow:
|
|
293
|
+
var(--control-shadow),
|
|
294
|
+
0 0 0 var(--focus-ring-width) var(--focus-tint),
|
|
295
|
+
0 0 16px 2px color-mix(in srgb, var(--focus-tint) 24%, transparent);
|
|
296
|
+
animation: focus-bloom var(--dur-fast) var(--ease-out);
|
|
297
|
+
}
|
|
298
|
+
@keyframes focus-bloom {
|
|
299
|
+
0% {
|
|
300
|
+
box-shadow:
|
|
301
|
+
var(--control-shadow),
|
|
302
|
+
0 0 0 0 transparent,
|
|
303
|
+
0 0 0 0 transparent;
|
|
304
|
+
}
|
|
305
|
+
45% {
|
|
306
|
+
box-shadow:
|
|
307
|
+
var(--control-shadow),
|
|
308
|
+
0 0 0 calc(var(--focus-ring-width) + 1px) var(--focus-tint),
|
|
309
|
+
0 0 20px 4px color-mix(in srgb, var(--focus-tint) 32%, transparent);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
277
312
|
.select:disabled {
|
|
278
313
|
cursor: not-allowed;
|
|
279
314
|
}
|
|
@@ -367,7 +402,7 @@
|
|
|
367
402
|
}
|
|
368
403
|
@media (hover: hover) and (pointer: fine) {
|
|
369
404
|
.select:hover:not(:disabled, :focus, [aria-invalid='true'], .ghost, .embedded) {
|
|
370
|
-
border-color: var(--
|
|
405
|
+
border-color: var(--control-edge-hover);
|
|
371
406
|
}
|
|
372
407
|
}
|
|
373
408
|
/* Transparent overlay: fills the positioned parent, the trigger shows through. */
|
|
@@ -380,6 +415,7 @@
|
|
|
380
415
|
opacity: 0;
|
|
381
416
|
border: none;
|
|
382
417
|
background: none;
|
|
418
|
+
box-shadow: none;
|
|
383
419
|
cursor: pointer;
|
|
384
420
|
}
|
|
385
421
|
</style>
|
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
3
|
// Shimmering placeholder bar(s) standing in for content that is still
|
|
4
4
|
// loading. Decorative only — the surrounding region should carry aria-busy.
|
|
5
|
-
// Bars are tinted from --text so they read on any surface
|
|
6
|
-
// viewport-anchored so every bar on screen shimmers in sync
|
|
5
|
+
// Bars are tinted from --text so they read on any surface. `shimmer` is a
|
|
6
|
+
// viewport-anchored sweep so every bar on screen shimmers in sync; `sheen`
|
|
7
|
+
// runs one light across each bar; `pulse` breathes in opacity, each bar a
|
|
8
|
+
// beat behind the previous one (`--skeleton-phase` offsets the whole set).
|
|
7
9
|
type Own = {
|
|
8
10
|
width?: string;
|
|
9
11
|
height?: string;
|
|
@@ -12,6 +14,7 @@
|
|
|
12
14
|
/** Round avatar placeholder — width follows height. */
|
|
13
15
|
circle?: boolean;
|
|
14
16
|
radius?: string;
|
|
17
|
+
variant?: 'shimmer' | 'sheen' | 'pulse';
|
|
15
18
|
class?: string;
|
|
16
19
|
};
|
|
17
20
|
let {
|
|
@@ -20,6 +23,7 @@
|
|
|
20
23
|
lines = 1,
|
|
21
24
|
circle = false,
|
|
22
25
|
radius = 'var(--r-sm)',
|
|
26
|
+
variant = 'shimmer',
|
|
23
27
|
class: klass = '',
|
|
24
28
|
...rest
|
|
25
29
|
}: Omit<HTMLAttributes<HTMLElement>, keyof Own> & Own = $props();
|
|
@@ -29,13 +33,14 @@
|
|
|
29
33
|
const count = $derived(Math.max(1, Math.floor(lines)));
|
|
30
34
|
</script>
|
|
31
35
|
|
|
32
|
-
<span class="skeleton {klass}" data-tsu="Skeleton" aria-hidden="true" style:width={w} {...rest}>
|
|
36
|
+
<span class="skeleton v-{variant} {klass}" data-tsu="Skeleton" aria-hidden="true" style:width={w} {...rest}>
|
|
33
37
|
{#each { length: count } as _, i (i)}
|
|
34
38
|
<span
|
|
35
39
|
class="skeleton-bar"
|
|
36
40
|
style:height
|
|
37
41
|
style:border-radius={r}
|
|
38
42
|
style:width={count > 1 && i === count - 1 ? '60%' : undefined}
|
|
43
|
+
style:--i={i}
|
|
39
44
|
></span>
|
|
40
45
|
{/each}
|
|
41
46
|
</span>
|
|
@@ -72,4 +77,50 @@
|
|
|
72
77
|
background: var(--sk-base);
|
|
73
78
|
}
|
|
74
79
|
}
|
|
80
|
+
.v-sheen .skeleton-bar,
|
|
81
|
+
.v-pulse .skeleton-bar {
|
|
82
|
+
background: var(--sk-base);
|
|
83
|
+
}
|
|
84
|
+
.v-sheen .skeleton-bar {
|
|
85
|
+
position: relative;
|
|
86
|
+
overflow: hidden;
|
|
87
|
+
animation: none;
|
|
88
|
+
}
|
|
89
|
+
.v-sheen .skeleton-bar::after {
|
|
90
|
+
content: '';
|
|
91
|
+
position: absolute;
|
|
92
|
+
inset: 0;
|
|
93
|
+
width: 45%;
|
|
94
|
+
background: linear-gradient(100deg, transparent 20%, var(--sk-hi) 50%, transparent 80%);
|
|
95
|
+
transform: translateX(-100%);
|
|
96
|
+
animation: tsu-skeleton-sheen 2s var(--ease-in-out) infinite;
|
|
97
|
+
}
|
|
98
|
+
@keyframes tsu-skeleton-sheen {
|
|
99
|
+
70%,
|
|
100
|
+
100% {
|
|
101
|
+
transform: translateX(260%);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
.v-pulse .skeleton-bar {
|
|
105
|
+
animation: tsu-skeleton-pulse 1.6s var(--ease-in-out) infinite;
|
|
106
|
+
animation-delay: calc(0.13s * (var(--i, 0) + var(--skeleton-phase, 0)));
|
|
107
|
+
}
|
|
108
|
+
@keyframes tsu-skeleton-pulse {
|
|
109
|
+
0%,
|
|
110
|
+
100% {
|
|
111
|
+
opacity: 1;
|
|
112
|
+
}
|
|
113
|
+
50% {
|
|
114
|
+
opacity: 0.45;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
@media (prefers-reduced-motion: reduce) {
|
|
118
|
+
.v-pulse .skeleton-bar {
|
|
119
|
+
animation: none;
|
|
120
|
+
}
|
|
121
|
+
.v-sheen .skeleton-bar::after {
|
|
122
|
+
animation: none;
|
|
123
|
+
transform: translateX(60%);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
75
126
|
</style>
|
|
@@ -210,13 +210,13 @@
|
|
|
210
210
|
background: linear-gradient(
|
|
211
211
|
to right,
|
|
212
212
|
var(--slider-accent, var(--accent)) var(--pct),
|
|
213
|
-
var(--
|
|
213
|
+
var(--track-fill) var(--pct)
|
|
214
214
|
);
|
|
215
215
|
}
|
|
216
216
|
input[type='range']::-moz-range-track {
|
|
217
217
|
height: var(--track);
|
|
218
218
|
border-radius: var(--r-pill);
|
|
219
|
-
background: var(--
|
|
219
|
+
background: var(--track-fill);
|
|
220
220
|
}
|
|
221
221
|
input[type='range']::-moz-range-progress {
|
|
222
222
|
height: var(--track);
|
|
@@ -233,7 +233,7 @@
|
|
|
233
233
|
border-radius: var(--r-pill);
|
|
234
234
|
background: var(--slider-accent, var(--accent));
|
|
235
235
|
border: 2px solid var(--bg);
|
|
236
|
-
box-shadow: var(--shadow
|
|
236
|
+
box-shadow: var(--thumb-shadow);
|
|
237
237
|
transition:
|
|
238
238
|
scale var(--dur-press) var(--ease-out),
|
|
239
239
|
box-shadow var(--dur-fast) var(--ease);
|
|
@@ -244,17 +244,17 @@
|
|
|
244
244
|
border-radius: var(--r-pill);
|
|
245
245
|
background: var(--slider-accent, var(--accent));
|
|
246
246
|
border: 2px solid var(--bg);
|
|
247
|
-
box-shadow: var(--shadow
|
|
247
|
+
box-shadow: var(--thumb-shadow);
|
|
248
248
|
transition:
|
|
249
249
|
scale var(--dur-press) var(--ease-out),
|
|
250
250
|
box-shadow var(--dur-fast) var(--ease);
|
|
251
251
|
}
|
|
252
252
|
@media (hover: hover) and (pointer: fine) {
|
|
253
253
|
input[type='range']:not(:disabled):hover::-webkit-slider-thumb {
|
|
254
|
-
box-shadow: var(--shadow
|
|
254
|
+
box-shadow: var(--thumb-shadow), var(--halo);
|
|
255
255
|
}
|
|
256
256
|
input[type='range']:not(:disabled):hover::-moz-range-thumb {
|
|
257
|
-
box-shadow: var(--shadow
|
|
257
|
+
box-shadow: var(--thumb-shadow), var(--halo);
|
|
258
258
|
}
|
|
259
259
|
}
|
|
260
260
|
input[type='range']:not(:disabled):active::-webkit-slider-thumb {
|
|
@@ -269,10 +269,12 @@
|
|
|
269
269
|
input[type='range']:focus-visible::-webkit-slider-thumb {
|
|
270
270
|
outline: var(--focus-ring);
|
|
271
271
|
outline-offset: var(--focus-ring-offset);
|
|
272
|
+
box-shadow: var(--thumb-shadow), var(--focus-glow);
|
|
272
273
|
}
|
|
273
274
|
input[type='range']:focus-visible::-moz-range-thumb {
|
|
274
275
|
outline: var(--focus-ring);
|
|
275
276
|
outline-offset: var(--focus-ring-offset);
|
|
277
|
+
box-shadow: var(--thumb-shadow), var(--focus-glow);
|
|
276
278
|
}
|
|
277
279
|
@media (pointer: coarse) {
|
|
278
280
|
input[type='range'] {
|
|
@@ -8,7 +8,11 @@
|
|
|
8
8
|
| 'bars'
|
|
9
9
|
| 'grid'
|
|
10
10
|
| 'clock'
|
|
11
|
-
| 'bounce'
|
|
11
|
+
| 'bounce'
|
|
12
|
+
| 'comet'
|
|
13
|
+
| 'breath'
|
|
14
|
+
| 'morph'
|
|
15
|
+
| 'sweep';
|
|
12
16
|
|
|
13
17
|
// Inner spans per variant; `.in` wraps the flex/grid ones in an absolute
|
|
14
18
|
// layer so the root keeps the same inline baseline as the others.
|
|
@@ -20,7 +24,11 @@
|
|
|
20
24
|
bars: { count: 4, wrap: true },
|
|
21
25
|
grid: { count: 9, wrap: true },
|
|
22
26
|
clock: { count: 0, wrap: false },
|
|
23
|
-
bounce: { count: 2, wrap: false }
|
|
27
|
+
bounce: { count: 2, wrap: false },
|
|
28
|
+
comet: { count: 1, wrap: false },
|
|
29
|
+
breath: { count: 5, wrap: true },
|
|
30
|
+
morph: { count: 0, wrap: false },
|
|
31
|
+
sweep: { count: 0, wrap: false }
|
|
24
32
|
};
|
|
25
33
|
</script>
|
|
26
34
|
|
|
@@ -29,7 +37,7 @@
|
|
|
29
37
|
// other variants are pure-CSS pictograms drawn in currentColor inside a 1em
|
|
30
38
|
// box. Every variant's base style is a meaningful static pose, which is what
|
|
31
39
|
// shows under prefers-reduced-motion. `--spinner-speed` scales the tempo.
|
|
32
|
-
// `clock` and `bounce` read best at 20px and up.
|
|
40
|
+
// `clock` and `bounce` read best at 20px and up; `breath` is 2.5em wide.
|
|
33
41
|
import Icon from './Icon.svelte';
|
|
34
42
|
|
|
35
43
|
let {
|
|
@@ -82,6 +90,11 @@
|
|
|
82
90
|
inherits: false;
|
|
83
91
|
initial-value: 100deg;
|
|
84
92
|
}
|
|
93
|
+
@property --tsu-spin-sweep {
|
|
94
|
+
syntax: '<angle>';
|
|
95
|
+
inherits: false;
|
|
96
|
+
initial-value: 0deg;
|
|
97
|
+
}
|
|
85
98
|
|
|
86
99
|
.spinner {
|
|
87
100
|
--sw: max(1.5px, 0.11em);
|
|
@@ -472,6 +485,142 @@
|
|
|
472
485
|
}
|
|
473
486
|
}
|
|
474
487
|
|
|
488
|
+
.v-comet::before,
|
|
489
|
+
.v-comet > span,
|
|
490
|
+
.v-sweep::before {
|
|
491
|
+
content: '';
|
|
492
|
+
position: absolute;
|
|
493
|
+
inset: 0;
|
|
494
|
+
border-radius: 50%;
|
|
495
|
+
-webkit-mask: radial-gradient(
|
|
496
|
+
farthest-side,
|
|
497
|
+
transparent calc(100% - var(--sw)),
|
|
498
|
+
#000 calc(100% - var(--sw) + 0.5px)
|
|
499
|
+
);
|
|
500
|
+
mask: radial-gradient(
|
|
501
|
+
farthest-side,
|
|
502
|
+
transparent calc(100% - var(--sw)),
|
|
503
|
+
#000 calc(100% - var(--sw) + 0.5px)
|
|
504
|
+
);
|
|
505
|
+
}
|
|
506
|
+
.v-comet::before {
|
|
507
|
+
background: currentColor;
|
|
508
|
+
opacity: 0.1;
|
|
509
|
+
}
|
|
510
|
+
.v-comet > span {
|
|
511
|
+
background: conic-gradient(from 0deg, transparent 0 35%, currentColor 100%);
|
|
512
|
+
animation: tsu-spin-comet calc(var(--t) * 1.1) linear infinite;
|
|
513
|
+
}
|
|
514
|
+
.v-comet > span::after {
|
|
515
|
+
content: '';
|
|
516
|
+
position: absolute;
|
|
517
|
+
top: 0;
|
|
518
|
+
left: 50%;
|
|
519
|
+
width: var(--sw);
|
|
520
|
+
height: var(--sw);
|
|
521
|
+
border-radius: 50%;
|
|
522
|
+
background: currentColor;
|
|
523
|
+
box-shadow: 0 0 0.25em 0.04em currentColor;
|
|
524
|
+
transform: translateX(-50%);
|
|
525
|
+
}
|
|
526
|
+
@keyframes tsu-spin-comet {
|
|
527
|
+
to {
|
|
528
|
+
transform: rotate(360deg);
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
.v-sweep::before {
|
|
533
|
+
background: conic-gradient(
|
|
534
|
+
from var(--tsu-spin-sweep),
|
|
535
|
+
color-mix(in srgb, currentColor 18%, transparent),
|
|
536
|
+
currentColor 50%,
|
|
537
|
+
color-mix(in srgb, currentColor 18%, transparent)
|
|
538
|
+
);
|
|
539
|
+
animation: tsu-spin-sweep calc(var(--t) * 1.4) linear infinite;
|
|
540
|
+
}
|
|
541
|
+
@keyframes tsu-spin-sweep {
|
|
542
|
+
to {
|
|
543
|
+
--tsu-spin-sweep: 360deg;
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
.v-morph::before {
|
|
548
|
+
content: '';
|
|
549
|
+
position: absolute;
|
|
550
|
+
inset: 0.08em;
|
|
551
|
+
border-radius: 50%;
|
|
552
|
+
background: currentColor;
|
|
553
|
+
animation: tsu-spin-morph calc(var(--t) * 2.4) cubic-bezier(0.77, 0, 0.175, 1) infinite;
|
|
554
|
+
}
|
|
555
|
+
@keyframes tsu-spin-morph {
|
|
556
|
+
0% {
|
|
557
|
+
border-radius: 50%;
|
|
558
|
+
transform: rotate(0deg) scale(1);
|
|
559
|
+
}
|
|
560
|
+
25% {
|
|
561
|
+
border-radius: 24%;
|
|
562
|
+
transform: rotate(90deg) scale(0.92);
|
|
563
|
+
}
|
|
564
|
+
50% {
|
|
565
|
+
border-radius: 50%;
|
|
566
|
+
transform: rotate(180deg) scale(1);
|
|
567
|
+
}
|
|
568
|
+
75% {
|
|
569
|
+
border-radius: 24%;
|
|
570
|
+
transform: rotate(270deg) scale(0.92);
|
|
571
|
+
}
|
|
572
|
+
100% {
|
|
573
|
+
border-radius: 50%;
|
|
574
|
+
transform: rotate(360deg) scale(1);
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
.v-breath {
|
|
579
|
+
width: 2.5em;
|
|
580
|
+
}
|
|
581
|
+
.v-breath .in {
|
|
582
|
+
display: flex;
|
|
583
|
+
align-items: center;
|
|
584
|
+
justify-content: space-between;
|
|
585
|
+
}
|
|
586
|
+
.v-breath .in span {
|
|
587
|
+
width: 0.34em;
|
|
588
|
+
height: 0.34em;
|
|
589
|
+
border-radius: 50%;
|
|
590
|
+
background: currentColor;
|
|
591
|
+
animation: tsu-spin-breath calc(var(--t) * 1.3) cubic-bezier(0.77, 0, 0.175, 1) infinite;
|
|
592
|
+
}
|
|
593
|
+
.v-breath .in span:nth-child(1) {
|
|
594
|
+
opacity: 1;
|
|
595
|
+
animation-delay: calc(var(--t) * -0.52);
|
|
596
|
+
}
|
|
597
|
+
.v-breath .in span:nth-child(2) {
|
|
598
|
+
opacity: 0.75;
|
|
599
|
+
animation-delay: calc(var(--t) * -0.39);
|
|
600
|
+
}
|
|
601
|
+
.v-breath .in span:nth-child(3) {
|
|
602
|
+
opacity: 0.55;
|
|
603
|
+
animation-delay: calc(var(--t) * -0.26);
|
|
604
|
+
}
|
|
605
|
+
.v-breath .in span:nth-child(4) {
|
|
606
|
+
opacity: 0.4;
|
|
607
|
+
animation-delay: calc(var(--t) * -0.13);
|
|
608
|
+
}
|
|
609
|
+
.v-breath .in span:nth-child(5) {
|
|
610
|
+
opacity: 0.28;
|
|
611
|
+
}
|
|
612
|
+
@keyframes tsu-spin-breath {
|
|
613
|
+
0%,
|
|
614
|
+
100% {
|
|
615
|
+
opacity: 0.3;
|
|
616
|
+
transform: scale(0.6);
|
|
617
|
+
}
|
|
618
|
+
40% {
|
|
619
|
+
opacity: 1;
|
|
620
|
+
transform: scale(1);
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
|
|
475
624
|
@media (prefers-reduced-motion: reduce) {
|
|
476
625
|
.spinner.spinner,
|
|
477
626
|
.spinner.spinner span,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type SpinnerVariant = 'icon' | 'arc' | 'dots' | 'orbit' | 'pulse' | 'bars' | 'grid' | 'clock' | 'bounce';
|
|
1
|
+
export type SpinnerVariant = 'icon' | 'arc' | 'dots' | 'orbit' | 'pulse' | 'bars' | 'grid' | 'clock' | 'bounce' | 'comet' | 'breath' | 'morph' | 'sweep';
|
|
2
2
|
type $$ComponentProps = {
|
|
3
3
|
variant?: SpinnerVariant;
|
|
4
4
|
/** Explicit pixel size. Omit to track the surrounding text (1em). */
|