srcdev-nuxt-components 9.1.12 → 9.1.14
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.
|
@@ -116,6 +116,9 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
116
116
|
// ─── Animation gate — prevents indicator from transitioning on first paint ───
|
|
117
117
|
|
|
118
118
|
const isAnimated = ref(false);
|
|
119
|
+
// Stays false until ResizeObserver confirms the nav has been laid out (stronger
|
|
120
|
+
// guarantee than nextTick / RAF which don't ensure layout is complete).
|
|
121
|
+
let hasFirstLayout = false;
|
|
119
122
|
|
|
120
123
|
// ─── Nav decorators (active / hover indicators) ─────────────────────────────
|
|
121
124
|
|
|
@@ -334,6 +337,14 @@ const { navRef, navListRef, isCollapsed, isLoaded, isMenuOpen, activeHref, isAct
|
|
|
334
337
|
onResize: async () => {
|
|
335
338
|
await nextTick(); // wait for Vue to re-render after any isCollapsed change
|
|
336
339
|
initNavDecorators();
|
|
340
|
+
if (!hasFirstLayout) {
|
|
341
|
+
hasFirstLayout = true;
|
|
342
|
+
// RAF here (not nextTick) ensures the browser paints the snapped position
|
|
343
|
+
// before transitions are enabled — avoids animating from x=0 on first layout.
|
|
344
|
+
requestAnimationFrame(() => {
|
|
345
|
+
isAnimated.value = true;
|
|
346
|
+
});
|
|
347
|
+
}
|
|
337
348
|
if (isMenuOpen.value) {
|
|
338
349
|
setFinalPanelActivePositions(true);
|
|
339
350
|
setFinalPanelHoveredPositions(true);
|
|
@@ -341,18 +352,20 @@ const { navRef, navListRef, isCollapsed, isLoaded, isMenuOpen, activeHref, isAct
|
|
|
341
352
|
},
|
|
342
353
|
onRouteChange: () => {
|
|
343
354
|
isAnimated.value = false;
|
|
355
|
+
// Double RAF: RAF1 sets the new position and lets the browser paint it
|
|
356
|
+
// without transitions. RAF2 re-enables transitions only after that frame
|
|
357
|
+
// has committed — so there is no position delta left to animate.
|
|
344
358
|
requestAnimationFrame(() => {
|
|
345
359
|
initNavDecorators();
|
|
346
|
-
|
|
360
|
+
requestAnimationFrame(() => {
|
|
347
361
|
isAnimated.value = true;
|
|
348
362
|
});
|
|
349
363
|
});
|
|
350
364
|
},
|
|
351
365
|
onMounted: () => {
|
|
352
366
|
initNavDecorators();
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
});
|
|
367
|
+
// isAnimated is set in onResize — ResizeObserver guarantees layout is
|
|
368
|
+
// complete before we enable transitions, unlike nextTick / RAF.
|
|
356
369
|
},
|
|
357
370
|
});
|
|
358
371
|
|