@marianmeres/stuic 2.11.4 → 2.12.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/Input/FieldAssets.svelte +3 -3
- package/dist/components/Input/FieldOptions.svelte +1 -1
- package/dist/components/Spinner/Spinner.svelte +50 -101
- package/dist/components/Spinner/Spinner.svelte.d.ts +4 -5
- package/dist/components/Spinner/SpinnerCircle.svelte +47 -32
- package/dist/components/Spinner/SpinnerCircle.svelte.d.ts +6 -4
- package/dist/components/Spinner/SpinnerCircleOscillate.svelte +47 -0
- package/dist/components/Spinner/SpinnerCircleOscillate.svelte.d.ts +10 -0
- package/dist/components/Spinner/index.d.ts +1 -0
- package/dist/components/Spinner/index.js +1 -0
- package/package.json +1 -1
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
import Circle from "../Circle/Circle.svelte";
|
|
39
39
|
import { Modal } from "../Modal/index.js";
|
|
40
40
|
import { NotificationsStack } from "../Notifications/notifications-stack.svelte.js";
|
|
41
|
-
import
|
|
41
|
+
import SpinnerCircleOscillate from "../Spinner/SpinnerCircleOscillate.svelte";
|
|
42
42
|
import { isTHCNotEmpty, type THC } from "../Thc/Thc.svelte";
|
|
43
43
|
import { X } from "../X/index.js";
|
|
44
44
|
import InputWrap from "./_internal/InputWrap.svelte";
|
|
@@ -377,7 +377,7 @@
|
|
|
377
377
|
{#snippet default_render()}
|
|
378
378
|
{#if isLoading}
|
|
379
379
|
<div class="p-2 pl-8 flex items-center justify-center min-h-24">
|
|
380
|
-
<
|
|
380
|
+
<SpinnerCircleOscillate />
|
|
381
381
|
</div>
|
|
382
382
|
{:else}
|
|
383
383
|
<div class={["p-2 flex items-center gap-0.5 flex-wrap"]}>
|
|
@@ -427,7 +427,7 @@
|
|
|
427
427
|
rotate={-90}
|
|
428
428
|
/>
|
|
429
429
|
{:else}
|
|
430
|
-
<
|
|
430
|
+
<SpinnerCircleOscillate bgStrokeColor="gray" />
|
|
431
431
|
{/if}
|
|
432
432
|
</span>
|
|
433
433
|
{/if}
|
|
@@ -1,136 +1,85 @@
|
|
|
1
1
|
<script lang="ts" module>
|
|
2
2
|
export interface Props {
|
|
3
3
|
class?: string;
|
|
4
|
-
/** One "loop" duration in ms */
|
|
5
|
-
duration?: number;
|
|
6
|
-
/** Number of "hands" (3-12) */
|
|
7
4
|
count?: number;
|
|
8
|
-
thickness?: "
|
|
9
|
-
height?: "
|
|
5
|
+
thickness?: "thin" | "normal" | "thick";
|
|
6
|
+
height?: "short" | "normal" | "tall";
|
|
10
7
|
direction?: "cw" | "ccw";
|
|
8
|
+
rounded?: number;
|
|
9
|
+
duration?: number;
|
|
11
10
|
}
|
|
12
11
|
</script>
|
|
13
12
|
|
|
14
13
|
<script lang="ts">
|
|
15
|
-
import { twMerge } from "../../utils/tw-merge.js";
|
|
16
|
-
|
|
17
|
-
// this is quite verbose, but very straight forward implementation,
|
|
18
|
-
// and always rendered without any issues (opposed to linear-gradient hackish stuff)
|
|
19
|
-
|
|
20
14
|
let {
|
|
21
|
-
class:
|
|
22
|
-
duration = 750,
|
|
15
|
+
class: classProp,
|
|
23
16
|
count = 8,
|
|
24
|
-
thickness = "
|
|
17
|
+
thickness = "normal",
|
|
25
18
|
height = "normal",
|
|
26
19
|
direction = "cw",
|
|
20
|
+
rounded = 2,
|
|
21
|
+
duration = 750,
|
|
27
22
|
}: Props = $props();
|
|
28
23
|
|
|
29
|
-
|
|
24
|
+
const thicknessMap: Record<NonNullable<Props["thickness"]>, number> = {
|
|
25
|
+
thin: 1,
|
|
26
|
+
normal: 2,
|
|
27
|
+
thick: 4,
|
|
28
|
+
};
|
|
29
|
+
const heightMap: Record<NonNullable<Props["height"]>, number> = {
|
|
30
|
+
short: 5,
|
|
31
|
+
normal: 7,
|
|
32
|
+
tall: 10,
|
|
33
|
+
};
|
|
30
34
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
delay:
|
|
37
|
-
(direction === "ccw" ? 1 : -1) * (duration - (duration / _count) * (i + 1)),
|
|
38
|
-
duration,
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
return out;
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
let _thickness = $derived(
|
|
45
|
-
"thickness-" +
|
|
46
|
-
(["normal", "thin", "thick"].includes(thickness) ? thickness : "normal")
|
|
47
|
-
);
|
|
48
|
-
|
|
49
|
-
let _height = $derived(
|
|
50
|
-
"height-" + (["normal", "tall", "short"].includes(height) ? height : "normal")
|
|
51
|
-
);
|
|
35
|
+
const barLength = $derived(heightMap[height]);
|
|
36
|
+
const barWidth = $derived(thicknessMap[thickness]);
|
|
37
|
+
const size = $derived(barLength * 3);
|
|
38
|
+
const center = $derived(size / 2);
|
|
39
|
+
const barHeight = $derived(barLength - 1);
|
|
52
40
|
</script>
|
|
53
41
|
|
|
54
|
-
<div
|
|
55
|
-
{
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
42
|
+
<div
|
|
43
|
+
class="spinner {classProp ?? ''}"
|
|
44
|
+
style:--size="{size}px"
|
|
45
|
+
style:--duration="{duration}ms"
|
|
46
|
+
>
|
|
47
|
+
{#each Array(count) as _, i}
|
|
48
|
+
{@const angle = (360 / count) * i}
|
|
49
|
+
{@const delay = direction === "ccw" ? i / count : (count - i) / count}
|
|
50
|
+
<span
|
|
51
|
+
class="bar"
|
|
52
|
+
style:width="{barWidth}px"
|
|
53
|
+
style:height="{barHeight}px"
|
|
54
|
+
style:border-radius="{rounded}px"
|
|
55
|
+
style:transform-origin="center {center}px"
|
|
56
|
+
style:transform="translateX(-50%) rotate({angle}deg)"
|
|
57
|
+
style:animation-delay="{-delay * duration}ms"
|
|
58
|
+
></span>
|
|
63
59
|
{/each}
|
|
64
60
|
</div>
|
|
65
61
|
|
|
66
62
|
<style>
|
|
67
|
-
.spinner,
|
|
68
|
-
.spinner div,
|
|
69
|
-
.spinner div:after {
|
|
70
|
-
box-sizing: border-box;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
63
|
.spinner {
|
|
74
|
-
/* display: inline-block; */
|
|
75
64
|
position: relative;
|
|
76
|
-
|
|
77
|
-
|
|
65
|
+
width: var(--size);
|
|
66
|
+
height: var(--size);
|
|
78
67
|
}
|
|
79
68
|
|
|
80
|
-
.
|
|
81
|
-
width: 100%;
|
|
82
|
-
height: 100%;
|
|
69
|
+
.bar {
|
|
83
70
|
position: absolute;
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
animation-name: spinner;
|
|
87
|
-
animation-timing-function: linear;
|
|
88
|
-
animation-iteration-count: infinite;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
.spinner div:after {
|
|
92
|
-
content: " ";
|
|
93
|
-
display: block;
|
|
94
|
-
position: absolute;
|
|
95
|
-
|
|
96
|
-
top: 0;
|
|
97
|
-
/* left: 46%;
|
|
98
|
-
width: 8%;
|
|
99
|
-
height: 27%; */
|
|
100
|
-
border-radius: 35%;
|
|
71
|
+
left: 50%;
|
|
72
|
+
top: 0px;
|
|
101
73
|
background: currentColor;
|
|
102
|
-
|
|
103
|
-
/* thickness */
|
|
104
|
-
.spinner.thickness-thin div:after {
|
|
105
|
-
left: 47.5%;
|
|
106
|
-
width: 5%;
|
|
107
|
-
}
|
|
108
|
-
.spinner.thickness-normal div:after {
|
|
109
|
-
left: 46%;
|
|
110
|
-
width: 8%;
|
|
111
|
-
}
|
|
112
|
-
.spinner.thickness-thick div:after {
|
|
113
|
-
left: 44.5%;
|
|
114
|
-
width: 11%;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/* height */
|
|
118
|
-
.spinner.height-short div:after {
|
|
119
|
-
height: 21%;
|
|
120
|
-
}
|
|
121
|
-
.spinner.height-normal div:after {
|
|
122
|
-
height: 27%;
|
|
123
|
-
}
|
|
124
|
-
.spinner.height-tall div:after {
|
|
125
|
-
height: 33%;
|
|
74
|
+
animation: fade var(--duration) linear infinite;
|
|
126
75
|
}
|
|
127
76
|
|
|
128
|
-
@keyframes
|
|
129
|
-
|
|
77
|
+
@keyframes fade {
|
|
78
|
+
from {
|
|
130
79
|
opacity: 1;
|
|
131
80
|
}
|
|
132
|
-
|
|
133
|
-
opacity: 0;
|
|
81
|
+
to {
|
|
82
|
+
opacity: 0.12;
|
|
134
83
|
}
|
|
135
84
|
}
|
|
136
85
|
</style>
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
export interface Props {
|
|
2
2
|
class?: string;
|
|
3
|
-
/** One "loop" duration in ms */
|
|
4
|
-
duration?: number;
|
|
5
|
-
/** Number of "hands" (3-12) */
|
|
6
3
|
count?: number;
|
|
7
|
-
thickness?: "
|
|
8
|
-
height?: "
|
|
4
|
+
thickness?: "thin" | "normal" | "thick";
|
|
5
|
+
height?: "short" | "normal" | "tall";
|
|
9
6
|
direction?: "cw" | "ccw";
|
|
7
|
+
rounded?: number;
|
|
8
|
+
duration?: number;
|
|
10
9
|
}
|
|
11
10
|
declare const Spinner: import("svelte").Component<Props, {}, "">;
|
|
12
11
|
type Spinner = ReturnType<typeof Spinner>;
|
|
@@ -1,47 +1,62 @@
|
|
|
1
1
|
<script lang="ts" module>
|
|
2
2
|
export interface Props {
|
|
3
3
|
class?: string;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
/** One "loop" duration in ms */
|
|
5
|
+
duration?: number;
|
|
6
|
+
/** Border thickness preset */
|
|
7
|
+
thickness?: "normal" | "thin" | "thick";
|
|
8
|
+
/** Rotation direction */
|
|
9
|
+
direction?: "cw" | "ccw";
|
|
8
10
|
}
|
|
9
11
|
</script>
|
|
10
12
|
|
|
11
13
|
<script lang="ts">
|
|
12
|
-
import { createTickerRAF } from "@marianmeres/ticker";
|
|
13
|
-
import { onDestroy } from "svelte";
|
|
14
|
-
import { oscillate } from "../../utils/oscillate.js";
|
|
15
14
|
import { twMerge } from "../../utils/tw-merge.js";
|
|
16
|
-
import Circle from "../Circle/Circle.svelte";
|
|
17
15
|
|
|
18
16
|
let {
|
|
19
|
-
class: classProp
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
rotateDuration = ".75s",
|
|
17
|
+
class: classProp,
|
|
18
|
+
duration = 750,
|
|
19
|
+
thickness = "normal",
|
|
20
|
+
direction = "cw",
|
|
24
21
|
}: Props = $props();
|
|
25
22
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
* 4. the animation-spin duration
|
|
32
|
-
*/
|
|
23
|
+
let _thickness = $derived(
|
|
24
|
+
"thickness-" +
|
|
25
|
+
(["normal", "thin", "thick"].includes(thickness) ? thickness : "normal")
|
|
26
|
+
);
|
|
27
|
+
</script>
|
|
33
28
|
|
|
34
|
-
|
|
35
|
-
|
|
29
|
+
<span
|
|
30
|
+
class={twMerge("stuic-spinner-basic inline-block size-5", _thickness, classProp)}
|
|
31
|
+
style="animation-duration: {duration}ms; animation-direction: {direction === 'ccw'
|
|
32
|
+
? 'reverse'
|
|
33
|
+
: 'normal'};"
|
|
34
|
+
></span>
|
|
36
35
|
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
<style>
|
|
37
|
+
.stuic-spinner-basic {
|
|
38
|
+
box-sizing: border-box;
|
|
39
|
+
border-radius: 50%;
|
|
40
|
+
border-style: solid;
|
|
41
|
+
border-color: currentColor;
|
|
42
|
+
border-top-color: transparent;
|
|
43
|
+
animation: spin linear infinite;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/* Thickness presets */
|
|
47
|
+
.stuic-spinner-basic.thickness-thin {
|
|
48
|
+
border-width: 1px;
|
|
49
|
+
}
|
|
50
|
+
.stuic-spinner-basic.thickness-normal {
|
|
51
|
+
border-width: 2px;
|
|
52
|
+
}
|
|
53
|
+
.stuic-spinner-basic.thickness-thick {
|
|
54
|
+
border-width: 4px;
|
|
55
|
+
}
|
|
39
56
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
style="animation-duration: {rotateDuration}"
|
|
47
|
-
/>
|
|
57
|
+
@keyframes spin {
|
|
58
|
+
to {
|
|
59
|
+
transform: rotate(360deg);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
</style>
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
export interface Props {
|
|
2
2
|
class?: string;
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
/** One "loop" duration in ms */
|
|
4
|
+
duration?: number;
|
|
5
|
+
/** Border thickness preset */
|
|
6
|
+
thickness?: "normal" | "thin" | "thick";
|
|
7
|
+
/** Rotation direction */
|
|
8
|
+
direction?: "cw" | "ccw";
|
|
7
9
|
}
|
|
8
10
|
declare const SpinnerCircle: import("svelte").Component<Props, {}, "">;
|
|
9
11
|
type SpinnerCircle = ReturnType<typeof SpinnerCircle>;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
export interface Props {
|
|
3
|
+
class?: string;
|
|
4
|
+
bgStrokeColor?: string;
|
|
5
|
+
strokeWidth?: number;
|
|
6
|
+
noOscillate?: boolean;
|
|
7
|
+
rotateDuration?: string;
|
|
8
|
+
}
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<script lang="ts">
|
|
12
|
+
import { createTickerRAF } from "@marianmeres/ticker";
|
|
13
|
+
import { onDestroy } from "svelte";
|
|
14
|
+
import { oscillate } from "../../utils/oscillate.js";
|
|
15
|
+
import { twMerge } from "../../utils/tw-merge.js";
|
|
16
|
+
import Circle from "../Circle/Circle.svelte";
|
|
17
|
+
|
|
18
|
+
let {
|
|
19
|
+
class: classProp = "",
|
|
20
|
+
bgStrokeColor = "rgba(0 0 0 / .1)",
|
|
21
|
+
strokeWidth,
|
|
22
|
+
noOscillate,
|
|
23
|
+
rotateDuration = ".75s",
|
|
24
|
+
}: Props = $props();
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* NOTE: we happen to have 4 distinct values here which effect the overall look and feel...
|
|
28
|
+
* 1. the tick frequency
|
|
29
|
+
* 2. the oscillation time input (seconds)
|
|
30
|
+
* 3. the oscillation speed factor (1)
|
|
31
|
+
* 4. the animation-spin duration
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
const ticker = createTickerRAF(50, true);
|
|
35
|
+
let completeness = $derived(noOscillate ? 0.66 : oscillate($ticker / 1000, 0.15, 0.85));
|
|
36
|
+
|
|
37
|
+
onDestroy(ticker.stop);
|
|
38
|
+
</script>
|
|
39
|
+
|
|
40
|
+
<Circle
|
|
41
|
+
animateCompletenessMs={0}
|
|
42
|
+
{completeness}
|
|
43
|
+
class={twMerge("stuic-spinner-circle animate-spin", classProp)}
|
|
44
|
+
{bgStrokeColor}
|
|
45
|
+
{strokeWidth}
|
|
46
|
+
style="animation-duration: {rotateDuration}"
|
|
47
|
+
/>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface Props {
|
|
2
|
+
class?: string;
|
|
3
|
+
bgStrokeColor?: string;
|
|
4
|
+
strokeWidth?: number;
|
|
5
|
+
noOscillate?: boolean;
|
|
6
|
+
rotateDuration?: string;
|
|
7
|
+
}
|
|
8
|
+
declare const SpinnerCircleOscillate: import("svelte").Component<Props, {}, "">;
|
|
9
|
+
type SpinnerCircleOscillate = ReturnType<typeof SpinnerCircleOscillate>;
|
|
10
|
+
export default SpinnerCircleOscillate;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { default as Spinner, type Props as SpinnerProps } from "./Spinner.svelte";
|
|
2
2
|
export { default as SpinnerCircle, type Props as SpinnerCircleProps, } from "./SpinnerCircle.svelte";
|
|
3
|
+
export { default as SpinnerCircleOscillate, type Props as SpinnerCircleOscillateProps, } from "./SpinnerCircleOscillate.svelte";
|
|
3
4
|
export { spinnerCreateBackAndForthCharFrames, default as SpinnerUnicode, type Props as SpinnerUnicodeProps, type SpinnerUnicodeVariant, } from "./SpinnerUnicode.svelte";
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { default as Spinner } from "./Spinner.svelte";
|
|
2
2
|
export { default as SpinnerCircle, } from "./SpinnerCircle.svelte";
|
|
3
|
+
export { default as SpinnerCircleOscillate, } from "./SpinnerCircleOscillate.svelte";
|
|
3
4
|
export { spinnerCreateBackAndForthCharFrames, default as SpinnerUnicode, } from "./SpinnerUnicode.svelte";
|