11'use client' ;
22
33import { motion } from 'framer-motion' ;
4+ import type { Variants } from 'framer-motion' ;
45import { PostCard } from '../PostCard' ;
56import { EmptyState } from '@/shared/ui' ;
67import type { FeedData } from '@/domains/post/model/types' ;
8+ import {
9+ useEffectiveMotionMode ,
10+ type EffectiveMotionMode ,
11+ } from '@/shared/motion/model/motion-mode' ;
712
813interface PostListProps {
914 posts : FeedData [ ] ;
1015 layout ?: 'grid' | 'list' ;
1116}
1217
13- const containerVariants = {
14- hidden : { opacity : 0 } ,
15- visible : {
16- opacity : 1 ,
17- transition : {
18- staggerChildren : 0.1 ,
18+ function getContainerVariants (
19+ effectiveMotionMode : EffectiveMotionMode
20+ ) : Variants {
21+ return {
22+ hidden : { opacity : 0 } ,
23+ visible : {
24+ opacity : 1 ,
25+ transition : {
26+ staggerChildren : effectiveMotionMode === 'reduced' ? 0.03 : 0.08 ,
27+ } ,
1928 } ,
20- } ,
21- } ;
29+ } ;
30+ }
31+
32+ function getItemVariants ( effectiveMotionMode : EffectiveMotionMode ) : Variants {
33+ const shouldTranslate = effectiveMotionMode === 'full' ;
2234
23- const itemVariants = {
24- hidden : { opacity : 0 , y : 20 } ,
25- visible : {
26- opacity : 1 ,
27- y : 0 ,
28- transition : {
29- type : 'spring' ,
30- stiffness : 300 ,
31- damping : 30 ,
35+ return {
36+ hidden : {
37+ opacity : 0 ,
38+ y : shouldTranslate ? 20 : 0 ,
3239 } ,
33- } ,
34- } ;
40+ visible : {
41+ opacity : 1 ,
42+ y : 0 ,
43+ transition : {
44+ duration : effectiveMotionMode === 'reduced' ? 0.16 : 0.28 ,
45+ ease : [ 0.22 , 1 , 0.36 , 1 ] ,
46+ } ,
47+ } ,
48+ } ;
49+ }
50+
51+ const layoutClassNames = {
52+ grid : 'grid gap-6 md:grid-cols-2' ,
53+ list : 'space-y-4' ,
54+ } satisfies Record < NonNullable < PostListProps [ 'layout' ] > , string > ;
3555
3656export default function PostList ( { posts, layout = 'grid' } : PostListProps ) {
57+ const effectiveMotionMode = useEffectiveMotionMode ( ) ;
58+
3759 if ( posts . length === 0 ) {
3860 return (
3961 < EmptyState
@@ -44,13 +66,31 @@ export default function PostList({ posts, layout = 'grid' }: PostListProps) {
4466 ) ;
4567 }
4668
69+ if ( effectiveMotionMode === 'off' ) {
70+ return (
71+ < div className = { layoutClassNames [ layout ] } >
72+ { posts . map ( ( post ) => (
73+ < div key = { post . slug } className = { layout === 'grid' ? 'h-full' : '' } >
74+ < PostCard
75+ post = { post }
76+ variant = { layout === 'list' ? 'list' : 'default' }
77+ />
78+ </ div >
79+ ) ) }
80+ </ div >
81+ ) ;
82+ }
83+
84+ const containerVariants = getContainerVariants ( effectiveMotionMode ) ;
85+ const itemVariants = getItemVariants ( effectiveMotionMode ) ;
86+
4787 if ( layout === 'list' ) {
4888 return (
4989 < motion . div
5090 variants = { containerVariants }
5191 initial = "hidden"
5292 animate = "visible"
53- className = "space-y-4"
93+ className = { layoutClassNames . list }
5494 >
5595 { posts . map ( ( post ) => (
5696 < motion . div key = { post . slug } variants = { itemVariants } >
@@ -66,7 +106,7 @@ export default function PostList({ posts, layout = 'grid' }: PostListProps) {
66106 variants = { containerVariants }
67107 initial = "hidden"
68108 animate = "visible"
69- className = " grid gap-6 md:grid-cols-2"
109+ className = { layoutClassNames . grid }
70110 >
71111 { posts . map ( ( post ) => (
72112 < motion . div key = { post . slug } variants = { itemVariants } className = "h-full" >
0 commit comments