@joewinke/jatui 0.41.0 → 0.41.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,6 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { untrack } from 'svelte';
|
|
3
|
-
import { Tween } from 'svelte/motion';
|
|
4
3
|
import { cubicOut } from 'svelte/easing';
|
|
5
4
|
import { getMotionContext, motionDuration } from '../motion/level';
|
|
6
5
|
|
|
@@ -21,13 +20,32 @@
|
|
|
21
20
|
|
|
22
21
|
// ── Tween mode ─────────────────────────────────────────────────────────
|
|
23
22
|
let tweenEl: HTMLSpanElement | undefined = $state();
|
|
24
|
-
|
|
23
|
+
// A hand-rolled rAF tween, NOT svelte/motion's Tween: importing svelte/motion
|
|
24
|
+
// creates a prefers-reduced-motion MediaQuery at MODULE load, which throws
|
|
25
|
+
// 'window.matchMedia is not a function' in any jsdom test that merely
|
|
26
|
+
// imports 'jatui' (jatui-oozkb). Reduced motion comes from motionDuration,
|
|
27
|
+
// which is 0 under prefers-reduced-motion.
|
|
28
|
+
let tweenCurrent = $state(untrack(() => value));
|
|
25
29
|
$effect(() => {
|
|
26
30
|
if (mode !== 'tween') return;
|
|
27
31
|
const target = value;
|
|
28
32
|
// Level-aware (data-motion) and instant under prefers-reduced-motion.
|
|
29
33
|
const ms = motionDuration(duration ?? 'move', getMotionContext(tweenEl ?? null));
|
|
30
|
-
|
|
34
|
+
const from = untrack(() => tweenCurrent);
|
|
35
|
+
if (ms <= 0 || from === target || typeof requestAnimationFrame !== 'function') {
|
|
36
|
+
tweenCurrent = target;
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
let frame = 0;
|
|
40
|
+
let start: number | null = null;
|
|
41
|
+
const step = (now: number) => {
|
|
42
|
+
start ??= now;
|
|
43
|
+
const t = Math.min(1, (now - start) / ms);
|
|
44
|
+
tweenCurrent = from + (target - from) * cubicOut(t);
|
|
45
|
+
if (t < 1) frame = requestAnimationFrame(step);
|
|
46
|
+
};
|
|
47
|
+
frame = requestAnimationFrame(step);
|
|
48
|
+
return () => cancelAnimationFrame(frame);
|
|
31
49
|
});
|
|
32
50
|
/** Decimals to show mid-tween: the target's own, unless `format` decides. */
|
|
33
51
|
const tweenDecimals = $derived.by(() => {
|
|
@@ -36,7 +54,7 @@
|
|
|
36
54
|
return s.includes('.') && !s.includes('e') ? s.split('.')[1].length : 0;
|
|
37
55
|
});
|
|
38
56
|
const tweenText = $derived.by(() => {
|
|
39
|
-
const v =
|
|
57
|
+
const v = tweenCurrent;
|
|
40
58
|
const shown = tweenDecimals == null ? v : Number(v.toFixed(tweenDecimals));
|
|
41
59
|
return formatNumber(shown, format);
|
|
42
60
|
});
|