@griddle/vue 0.1.0 → 0.1.2

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.
@@ -0,0 +1,62 @@
1
+ import {
2
+ resolveAnimationConfig,
3
+ type GridAnimationConfig,
4
+ } from '@griddle/core';
5
+
6
+ const pendingFrames = new WeakMap<HTMLElement, number>();
7
+
8
+ function reducedMotionRequested(config: GridAnimationConfig | undefined): boolean {
9
+ const animation = resolveAnimationConfig(config);
10
+ return animation.respectReducedMotion &&
11
+ typeof window !== 'undefined' &&
12
+ typeof window.matchMedia === 'function' &&
13
+ window.matchMedia('(prefers-reduced-motion: reduce)').matches;
14
+ }
15
+
16
+ function currentTranslation(node: HTMLElement): { x: number; y: number } {
17
+ if (typeof window === 'undefined') return { x: 0, y: 0 };
18
+ const translate = window.getComputedStyle(node).translate;
19
+ if (!translate || translate === 'none') return { x: 0, y: 0 };
20
+ const [x = '0', y = '0'] = translate.split(/\s+/);
21
+ return { x: Number.parseFloat(x) || 0, y: Number.parseFloat(y) || 0 };
22
+ }
23
+
24
+ /** Continue rapid repacks from the tile's current visual position. */
25
+ export function animateReposition(
26
+ node: HTMLElement,
27
+ deltaX: number,
28
+ deltaY: number,
29
+ config?: GridAnimationConfig,
30
+ ): void {
31
+ const pending = pendingFrames.get(node);
32
+ if (pending !== undefined) cancelAnimationFrame(pending);
33
+
34
+ const animation = resolveAnimationConfig(config);
35
+ if (!animation.enabled || animation.repositionDurationMs === 0 || reducedMotionRequested(config)) {
36
+ node.style.transition = 'none';
37
+ node.style.translate = '0px 0px';
38
+ pendingFrames.delete(node);
39
+ return;
40
+ }
41
+
42
+ const current = currentTranslation(node);
43
+ node.style.transition = 'none';
44
+ node.style.translate = `${deltaX + current.x}px ${deltaY + current.y}px`;
45
+ void node.offsetWidth;
46
+
47
+ const frame = requestAnimationFrame(() => {
48
+ pendingFrames.delete(node);
49
+ node.style.transition =
50
+ `translate ${animation.repositionDurationMs}ms ${animation.repositionEasing}`;
51
+ node.style.translate = '0px 0px';
52
+ });
53
+ pendingFrames.set(node, frame);
54
+ }
55
+
56
+ export function liftTransition(config?: GridAnimationConfig): string {
57
+ const animation = resolveAnimationConfig(config);
58
+ const duration = !animation.enabled || reducedMotionRequested(config)
59
+ ? 0
60
+ : animation.liftDurationMs;
61
+ return `filter ${duration}ms ${animation.liftEasing}, opacity ${duration}ms ${animation.liftEasing}`;
62
+ }