Files
btrc-hub/frontend/src/components/PostList.tsx
T
みてるぞ e72ec608f4 利用規約(#95) (#311)
#95

#95

#95

#95

#95

Merge remote-tracking branch 'origin/main' into feature/095

#95

#95

#95

Co-authored-by: miteruzo <miteruzo@naver.com>
Reviewed-on: #311
2026-04-14 12:31:48 +09:00

71 lines
2.0 KiB
TypeScript

import { motion } from 'framer-motion'
import { useRef } from 'react'
import { useLocation } from 'react-router-dom'
import PrefetchLink from '@/components/PrefetchLink'
import { useSharedTransitionStore } from '@/stores/sharedTransitionStore'
import type { FC, MouseEvent } from 'react'
import type { Post } from '@/types'
type Props = { posts: Post[]
onClick?: (event: MouseEvent<HTMLElement>) => void }
export default (({ posts, onClick }: Props) => {
const location = useLocation ()
const setForLocationKey = useSharedTransitionStore (s => s.setForLocationKey)
const cardRef = useRef<HTMLDivElement> (null)
return (
<div className="flex flex-wrap gap-6 p-4">
{posts.map ((post, i) => {
const sharedId = `page-${ post.id }`
const layoutId = sharedId
return (
<PrefetchLink
to={`/posts/${ post.id }`}
key={post.id}
className="w-40 h-40"
state={{ sharedId }}
onClick={e => {
setForLocationKey (location.key, sharedId)
onClick?.(e)
}}>
<motion.div
ref={cardRef}
layoutId={layoutId}
className="w-full h-full overflow-hidden rounded-xl shadow
transform-gpu will-change-transform"
whileHover={{ scale: 1.02 }}
onLayoutAnimationStart={() => {
if (!(cardRef.current))
return
cardRef.current.style.position = 'relative'
cardRef.current.style.zIndex = '9999'
}}
onLayoutAnimationComplete={() => {
if (!(cardRef.current))
return
cardRef.current.style.zIndex = ''
cardRef.current.style.position = ''
}}
transition={{ layout: { duration: .2, ease: 'easeOut' } }}>
<img src={post.thumbnail || post.thumbnailBase || undefined}
alt={post.title || post.url}
title={post.title || post.url || undefined}
loading={i < 12 ? 'eager' : 'lazy'}
decoding="async"
className="object-cover w-full h-full"/>
</motion.div>
</PrefetchLink>)
})}
</div>)
}) satisfies FC<Props>