diff --git a/src/components/crapp/BarraSottosezioni.tsx b/src/components/crapp/BarraSottosezioni.tsx index 5ae5a22..9135ef0 100644 --- a/src/components/crapp/BarraSottosezioni.tsx +++ b/src/components/crapp/BarraSottosezioni.tsx @@ -1,7 +1,7 @@ import { useEffect, useRef, useState, type ReactNode } from "react"; -import { AnimatePresence, motion, useReducedMotion } from "motion/react"; +import { motion, useReducedMotion } from "motion/react"; import { cn } from "@/lib/utils"; -import { molla, proietta } from "@/lib/molla"; +import { proietta } from "@/lib/molla"; export type VoceSottosezione = { id: string; @@ -9,10 +9,16 @@ export type VoceSottosezione = { contenuto: ReactNode; }; +/** Tween breve: evita molle + exit che tengono due pannelli in DOM insieme. */ +const transizioneTab = { type: "tween" as const, duration: 0.16, ease: [0.25, 0.1, 0.25, 1] }; + /** * Barra di sottosezioni in un'unica fila scorrevole (swipe orizzontale) e * pannello che mostra una sola sezione alla volta, cambiabile anche con * swipe sul contenuto. + * + * Il pannello precedente si smonta subito (niente AnimatePresence/exit): + * al cambio tab resta un solo albero da animare in ingresso. */ export function BarraSottosezioni({ voci, @@ -32,12 +38,13 @@ export function BarraSottosezioni({ const voce = voci[indice] ?? voci[0]; useEffect(() => { + // `auto`: lo smooth competerebbe col tween del pannello sul main thread. tabRefs.current[attiva]?.scrollIntoView({ - behavior: ridotto ? "auto" : "smooth", + behavior: "auto", inline: "center", block: "nearest", }); - }, [attiva, ridotto]); + }, [attiva]); function vaiA(nuovo: number) { if (nuovo < 0 || nuovo >= voci.length) return; @@ -88,31 +95,27 @@ export function BarraSottosezioni({