1
- import React , { useState , useMemo , useEffect } from 'react' ;
1
+ import React , { useState , useMemo , useEffect } from 'react' ;
2
2
import Layout from '@theme/Layout' ;
3
3
import clsx from 'clsx' ;
4
4
@@ -21,10 +21,10 @@ import {
21
21
import ShowcaseTooltip from './_components/ShowcaseTooltip' ;
22
22
23
23
import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment' ;
24
- import Translate , { translate } from '@docusaurus/Translate' ;
25
- import { useHistory , useLocation } from '@docusaurus/router' ;
26
- import { usePluralForm } from '@docusaurus/theme-common' ;
27
-
24
+ import Translate , { translate } from '@docusaurus/Translate' ;
25
+ import { useHistory , useLocation } from '@docusaurus/router' ;
26
+ import { usePluralForm } from '@docusaurus/theme-common' ;
27
+ import { motion } from "framer-motion" ;
28
28
import styles from './styles.module.css' ;
29
29
30
30
const TITLE =
@@ -40,13 +40,13 @@ type UserState = {
40
40
} ;
41
41
42
42
function restoreUserState ( userState : UserState | null ) {
43
- const { scrollTopPosition, focusedElementId} = userState ?? {
43
+ const { scrollTopPosition, focusedElementId } = userState ?? {
44
44
scrollTopPosition : 0 ,
45
45
focusedElementId : undefined ,
46
46
} ;
47
47
// @ts -expect-error: if focusedElementId is undefined it returns null
48
48
document . getElementById ( focusedElementId ) ?. focus ( ) ;
49
- window . scrollTo ( { top : scrollTopPosition } ) ;
49
+ window . scrollTo ( { top : scrollTopPosition } ) ;
50
50
}
51
51
52
52
export function prepareUserState ( ) : UserState | undefined {
@@ -116,24 +116,57 @@ function useFilteredUsers() {
116
116
function ShowcaseHeader ( ) {
117
117
return (
118
118
< section className = "margin-top--lg margin-bottom--lg text--center" >
119
- < h1 > { TITLE } </ h1 >
120
- < p > { DESCRIPTION } </ p >
121
- < a
122
- className = "button button--primary"
123
- href = { EDIT_URL }
124
- target = "_blank"
125
- rel = "noreferrer"
119
+ < motion . h1
120
+ initial = { { opacity : 0 , x : - 150 } }
121
+ whileInView = { { opacity : 1 , x : 0 } }
122
+ viewport = { { once : true } }
123
+ transition = { {
124
+ duration : 1 ,
125
+ type : "spring" ,
126
+ stiffness : 100 ,
127
+ delay : 0.5 ,
128
+ } }
129
+ > { TITLE } </ motion . h1 >
130
+ < motion . p
131
+ initial = { { opacity : 0 , y : 150 } }
132
+ whileInView = { { opacity : 1 , y : 0 } }
133
+ viewport = { { once : true } }
134
+ transition = { {
135
+ duration : 1 ,
136
+ type : "spring" ,
137
+ stiffness : 100 ,
138
+ delay : 0.8 ,
139
+ } }
140
+ > { DESCRIPTION } </ motion . p >
141
+
142
+ < motion . div
143
+ initial = { { opacity : 0 , y : 150 } }
144
+ whileInView = { { opacity : 1 , y : 0 } }
145
+ viewport = { { once : true } }
146
+ transition = { {
147
+ duration : 1 ,
148
+ type : "spring" ,
149
+ stiffness : 100 ,
150
+ delay : 1.1 ,
151
+ } }
126
152
>
127
- < Translate id = "showcase.header.button" >
128
- 🌟 Join the CodeHarbarHub Community
129
- </ Translate >
130
- </ a >
153
+ < a
154
+ className = "button button--primary"
155
+ href = { EDIT_URL }
156
+ target = "_blank"
157
+ rel = "noreferrer"
158
+ >
159
+ < Translate id = "showcase.header.button" >
160
+ 🌟 Join the CodeHarbarHub Community
161
+ </ Translate >
162
+ </ a >
163
+ </ motion . div >
131
164
</ section >
132
165
) ;
133
166
}
134
167
135
168
function useSiteCountPlural ( ) {
136
- const { selectMessage} = usePluralForm ( ) ;
169
+ const { selectMessage } = usePluralForm ( ) ;
137
170
return ( sitesCount : number ) =>
138
171
selectMessage (
139
172
sitesCount ,
@@ -144,7 +177,7 @@ function useSiteCountPlural() {
144
177
'Pluralized label for the number of sites found on the showcase. Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)' ,
145
178
message : '1 site|{sitesCount} sites' ,
146
179
} ,
147
- { sitesCount} ,
180
+ { sitesCount } ,
148
181
) ,
149
182
) ;
150
183
}
@@ -156,16 +189,49 @@ function ShowcaseFilters() {
156
189
< section className = "container margin-top--l margin-bottom--lg" >
157
190
< div className = { clsx ( 'margin-bottom--sm' , styles . filterCheckbox ) } >
158
191
< div >
159
- < h2 >
192
+ < motion . h2
193
+ initial = { { opacity : 0 , x : - 150 } }
194
+ whileInView = { { opacity : 1 , x : 0 } }
195
+ viewport = { { once : true } }
196
+ transition = { {
197
+ duration : 1 ,
198
+ type : "spring" ,
199
+ stiffness : 100 ,
200
+ delay : 1.4 ,
201
+ } }
202
+ >
160
203
< Translate id = "showcase.filters.title" > Filters</ Translate >
161
- </ h2 >
162
- < span > { siteCountPlural ( filteredUsers . length ) } </ span >
204
+ </ motion . h2 >
205
+ < motion . div
206
+ initial = { { opacity : 0 , x : - 150 } }
207
+ whileInView = { { opacity : 1 , x : 0 } }
208
+ viewport = { { once : true } }
209
+ transition = { {
210
+ duration : 1 ,
211
+ type : "spring" ,
212
+ stiffness : 100 ,
213
+ delay : 1.4 ,
214
+ } }
215
+ >
216
+ < span > { siteCountPlural ( filteredUsers . length ) } </ span >
217
+ </ motion . div >
163
218
</ div >
164
219
< ShowcaseFilterToggle />
165
220
</ div >
166
- < ul className = { clsx ( 'clean-list' , styles . checkboxList ) } >
221
+ < motion . ul
222
+ initial = { { opacity : 0 } }
223
+ whileInView = { { opacity : 1 } }
224
+ viewport = { { once : true } }
225
+ transition = { {
226
+ duration : 4 ,
227
+ type : "spring" ,
228
+ stiffness : 100 ,
229
+ delay : 1.4 ,
230
+ } }
231
+ className = { clsx ( 'clean-list' , styles . checkboxList ) }
232
+ >
167
233
{ TagList . map ( ( tag , i ) => {
168
- const { label, description, color} = Tags [ tag ] ;
234
+ const { label, description, color } = Tags [ tag ] ;
169
235
const id = `showcase_checkbox_id_${ tag } ` ;
170
236
171
237
return (
@@ -199,7 +265,7 @@ function ShowcaseFilters() {
199
265
</ li >
200
266
) ;
201
267
} ) }
202
- </ ul >
268
+ </ motion . ul >
203
269
</ section >
204
270
) ;
205
271
}
@@ -276,32 +342,86 @@ function ShowcaseCards() {
276
342
styles . showcaseFavoriteHeader ,
277
343
) }
278
344
>
279
- < h2 >
345
+ < motion . h2
346
+ initial = { { opacity : 0 , x : - 150 } }
347
+ whileInView = { { opacity : 1 , x : 0 } }
348
+ viewport = { { once : true } }
349
+ transition = { {
350
+ duration : 1 ,
351
+ type : "spring" ,
352
+ stiffness : 100 ,
353
+ delay : 1.4 ,
354
+ } }
355
+ >
280
356
< Translate id = "showcase.favoritesList.title" >
281
357
Our favorites
282
358
</ Translate >
283
- </ h2 >
284
- < FavoriteIcon svgClass = { styles . svgIconFavorite } />
359
+ </ motion . h2 >
360
+ < motion . h2
361
+ initial = { { opacity : 0 , x : - 150 } }
362
+ whileInView = { { opacity : 1 , x : 0 } }
363
+ viewport = { { once : true } }
364
+ transition = { {
365
+ duration : 1 ,
366
+ type : "spring" ,
367
+ stiffness : 100 ,
368
+ delay : 1.4 ,
369
+ } }
370
+ >
371
+ < FavoriteIcon svgClass = { styles . svgIconFavorite } />
372
+ </ motion . h2 >
285
373
< SearchBar />
286
374
</ div >
287
- < ul
375
+ < motion . ul
376
+ initial = { { opacity : 0 } }
377
+ whileInView = { { opacity : 1 } }
378
+ viewport = { { once : true } }
379
+ transition = { {
380
+ duration : 4 ,
381
+ type : "spring" ,
382
+ stiffness : 100 ,
383
+ delay : 1 ,
384
+ } }
288
385
className = { clsx ( 'container' , 'clean-list' , styles . showcaseList ) }
289
386
>
387
+
290
388
{ favoriteUsers . map ( ( user ) => (
291
389
< ShowcaseCard key = { user . title } user = { user } />
292
390
) ) }
293
- </ ul >
391
+ </ motion . ul >
294
392
</ div >
295
393
</ div >
296
394
< div className = "container margin-top--lg" >
297
- < h2 className = { styles . showcaseHeader } >
395
+ < motion . h2
396
+ initial = { { opacity : 0 , x : - 150 } }
397
+ whileInView = { { opacity : 1 , x : 0 } }
398
+ viewport = { { once : true } }
399
+ transition = { {
400
+ duration : 1 ,
401
+ type : "spring" ,
402
+ stiffness : 100 ,
403
+ delay : 0.5 ,
404
+ } }
405
+ className = { styles . showcaseHeader }
406
+ >
298
407
< Translate id = "showcase.usersList.allUsers" > All sites</ Translate >
299
- </ h2 >
300
- < ul className = { clsx ( 'clean-list' , styles . showcaseList ) } >
408
+ </ motion . h2 >
409
+ < motion . ul
410
+ initial = { { opacity : 0 } }
411
+ whileInView = { { opacity : 1 } }
412
+ viewport = { { once : true } }
413
+ transition = { {
414
+ duration : 4 ,
415
+ type : "spring" ,
416
+ stiffness : 100 ,
417
+ delay : 0.8 ,
418
+ } }
419
+ className = { clsx ( 'clean-list' , styles . showcaseList ) }
420
+ >
301
421
{ otherUsers . map ( ( user ) => (
302
422
< ShowcaseCard key = { user . title } user = { user } />
303
423
) ) }
304
- </ ul >
424
+ </ motion . ul >
305
425
</ div >
306
426
</ >
307
427
) : (
0 commit comments