add scroll
continuous-integration/drone/push Build is passing

This commit is contained in:
2026-04-09 14:12:44 +01:00
parent 3aab9adaea
commit 65a29f343c
3 changed files with 96 additions and 57 deletions
+57 -57
View File
@@ -1,5 +1,8 @@
"use client"; // Necessário para animações no Next.js App Router
import Image from "next/image"; import Image from "next/image";
import Link from "next/link"; import Link from "next/link";
import { motion } from "framer-motion";
const recentes = [ const recentes = [
{ {
@@ -401,79 +404,76 @@ export function TvoneNegocios() {
export function TvoneEscolhaEditor() { export function TvoneEscolhaEditor() {
return ( return (
<section className="mx-auto w-full max-w-[1200px] px-4 pb-20"> <section className="mx-auto w-full max-w-[1200px] px-4 pb-20 overflow-hidden">
{/* HEADER */}
<div className="mb-10 flex items-end justify-between border-b border-neutral-100 pb-6"> <div className="mb-10 flex items-end justify-between border-b border-neutral-100 pb-6">
<div className="max-w-[600px]"> <h2 className="text-3xl font-bold tracking-tight text-neutral-900 md:text-4xl">
<h2 className="text-3xl font-bold tracking-tight text-neutral-900 md:text-4xl"> Escolha do Editor
Escolha do Editor </h2>
</h2> <Link href="/escolhas" className="group flex items-center gap-1 text-sm font-semibold text-[#0066CC]">
<p className="mt-2 text-sm md:text-base text-neutral-500 leading-relaxed">
Curadoria exclusiva das histórias mais impactantes do dia, selecionadas pela nossa redação.
</p>
</div>
<Link
href="/escolhas"
className="group flex items-center gap-1 text-sm font-semibold text-[#0066CC] transition-colors hover:text-[#004499] whitespace-nowrap mb-1"
>
Ver tudo Ver tudo
<svg className="h-4 w-4 transition-transform group-hover:translate-x-0.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2.5}> <svg className="h-4 w-4 transition-transform group-hover:translate-x-0.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2.5}>
<path strokeLinecap="round" strokeLinejoin="round" d="M9 5l7 7-7 7" /> <path d="M9 5l7 7-7 7" />
</svg> </svg>
</Link> </Link>
</div> </div>
{/* CONTAINER DE SCROLL: {/* CONTAINER COM ANIMACÃO "WHILE IN VIEW" */}
- flex e overflow-x-auto no mobile <motion.div
- md:grid no desktop initial={{ x: 80, opacity: 0 }}
- snap-x para efeito de 'imã' ao scrollar whileInView={{ x: 0, opacity: 1 }} // Dispara quando entra na viewport
*/} viewport={{ once: true, margin: "-100px" }} // Executa uma vez, 100px antes de chegar no centro
<div className="no-scrollbar -mx-4 flex snap-x snap-mandatory overflow-x-auto px-4 gap-6 md:mx-0 md:grid md:grid-cols-3 md:overflow-x-visible md:gap-10"> transition={{
{editorChoice.map((item, index) => ( type: "spring",
stiffness: 200, // Aumentado de 50 para 200 (muito mais rápido)
damping: 25, // Mantém o controle para não balançar demais
mass: 0.5 // Reduzimos a massa para o objeto parecer mais leve
}}
className="no-scrollbar flex flex-col gap-10 md:flex-row md:overflow-x-auto md:snap-x md:snap-mandatory md:gap-8 md:pb-6"
>
{editorChoice.slice(0, 6).map((item, index) => (
<article <article
key={index} key={index}
className="min-w-[85vw] snap-start flex flex-col gap-5 sm:min-w-[50vw] md:min-w-full" className={`group flex flex-col gap-5 md:min-w-[31%] md:snap-start
${index >= 3 ? 'hidden md:flex' : 'flex'}`}
> >
<div className="relative aspect-video overflow-hidden rounded-[24px] bg-neutral-100 shadow-sm transition-all duration-500 group-hover:shadow-md"> <Link href="#" className="block">
<Image <div className="relative aspect-video overflow-hidden rounded-[24px] bg-neutral-100 shadow-sm transition-all duration-500 group-hover:shadow-xl">
src={item.img} <Image
alt="" src={item.img}
fill alt={item.title}
className="object-cover transition-transform duration-700 group-hover:scale-105" fill
/> className="object-cover transition-transform duration-700 group-hover:scale-105"
</div> />
<div className="px-1">
<div className="flex items-center gap-3">
<span className="text-[10px] font-bold uppercase tracking-wider text-blue-600">
{item.category}
</span>
<span className="h-1 w-1 rounded-full bg-neutral-300" />
<span className="text-[10px] font-semibold text-neutral-500 uppercase tracking-tight">
{item.publishDate}
</span>
</div> </div>
<h3 className="mt-3 text-xl font-bold leading-snug text-neutral-900 transition-colors group-hover:text-[#0066CC]"> <div className="mt-5 px-1">
{item.title} <div className="flex items-center gap-3">
</h3> <span className="text-[10px] font-bold uppercase tracking-wider text-blue-600">{item.category}</span>
<span className="h-1 w-1 rounded-full bg-neutral-300" />
<span className="text-[10px] font-semibold text-neutral-500 uppercase tracking-tight">{item.publishDate}</span>
</div>
<h3 className="mt-3 text-xl font-bold leading-snug text-neutral-900 group-hover:text-[#0066CC] transition-colors">
{item.title}
</h3>
<p className="mt-3 line-clamp-2 text-sm leading-relaxed text-neutral-500">{item.description}</p>
<div className="mt-5 flex items-center gap-2 border-t border-neutral-50 pt-4">
<svg className="h-3.5 w-3.5 text-neutral-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<span className="text-[10px] font-bold uppercase text-neutral-400">
{item.readTime} min de leitura
</span>
</div>
<p className="mt-3 line-clamp-2 text-sm leading-relaxed text-neutral-500">
{item.description}
</p>
<div className="mt-5 flex items-center gap-2 border-t border-neutral-50 pt-4">
<svg className="h-3.5 w-3.5 text-neutral-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<span className="text-[10px] font-bold uppercase text-neutral-400">
{item.readTime} min de leitura
</span>
</div> </div>
</div> </Link>
</article> </article>
))} ))}
</div> </motion.div>
</section> </section>
); );
} }
+1
View File
@@ -9,6 +9,7 @@
"lint": "eslint" "lint": "eslint"
}, },
"dependencies": { "dependencies": {
"framer-motion": "^12.38.0",
"next": "16.2.1", "next": "16.2.1",
"react": "19.2.4", "react": "19.2.4",
"react-dom": "19.2.4" "react-dom": "19.2.4"
+38
View File
@@ -8,6 +8,9 @@ importers:
.: .:
dependencies: dependencies:
framer-motion:
specifier: ^12.38.0
version: 12.38.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
next: next:
specifier: 16.2.1 specifier: 16.2.1
version: 16.2.1(@babel/core@7.29.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) version: 16.2.1(@babel/core@7.29.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
@@ -1130,6 +1133,20 @@ packages:
resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
framer-motion@12.38.0:
resolution: {integrity: sha512-rFYkY/pigbcswl1XQSb7q424kSTQ8q6eAC+YUsSKooHQYuLdzdHjrt6uxUC+PRAO++q5IS7+TamgIw1AphxR+g==}
peerDependencies:
'@emotion/is-prop-valid': '*'
react: ^18.0.0 || ^19.0.0
react-dom: ^18.0.0 || ^19.0.0
peerDependenciesMeta:
'@emotion/is-prop-valid':
optional: true
react:
optional: true
react-dom:
optional: true
function-bind@1.1.2: function-bind@1.1.2:
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
@@ -1521,6 +1538,12 @@ packages:
minimist@1.2.8: minimist@1.2.8:
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
motion-dom@12.38.0:
resolution: {integrity: sha512-pdkHLD8QYRp8VfiNLb8xIBJis1byQ9gPT3Jnh2jqfFtAsWUA3dEepDlsWe/xMpO8McV+VdpKVcp+E+TGJEtOoA==}
motion-utils@12.36.0:
resolution: {integrity: sha512-eHWisygbiwVvf6PZ1vhaHCLamvkSbPIeAYxWUuL3a2PD/TROgE7FvfHWTIH4vMl798QLfMw15nRqIaRDXTlYRg==}
ms@2.1.3: ms@2.1.3:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
@@ -3140,6 +3163,15 @@ snapshots:
dependencies: dependencies:
is-callable: 1.2.7 is-callable: 1.2.7
framer-motion@12.38.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4):
dependencies:
motion-dom: 12.38.0
motion-utils: 12.36.0
tslib: 2.8.1
optionalDependencies:
react: 19.2.4
react-dom: 19.2.4(react@19.2.4)
function-bind@1.1.2: {} function-bind@1.1.2: {}
function.prototype.name@1.1.8: function.prototype.name@1.1.8:
@@ -3506,6 +3538,12 @@ snapshots:
minimist@1.2.8: {} minimist@1.2.8: {}
motion-dom@12.38.0:
dependencies:
motion-utils: 12.36.0
motion-utils@12.36.0: {}
ms@2.1.3: {} ms@2.1.3: {}
nanoid@3.3.11: {} nanoid@3.3.11: {}