1
- import React , { useState } from 'react' ;
1
+ import React , { useState , useEffect } from 'react' ;
2
+ import { useRouter } from 'next/router' ;
2
3
3
4
interface AccordionItem {
4
5
question : string ;
5
6
answer : string ;
6
- id ? : number ;
7
+ id : number ;
7
8
}
8
9
9
10
interface AccordionProps {
@@ -12,37 +13,74 @@ interface AccordionProps {
12
13
13
14
const Accordion : React . FC < AccordionProps > = ( { items } ) => {
14
15
const [ activeIndex , setActiveIndex ] = useState < number | null > ( null ) ;
16
+ const router = useRouter ( ) ;
15
17
16
18
const handleToggle = ( index : number ) => {
17
19
setActiveIndex ( ( prevIndex ) => ( prevIndex === index ? null : index ) ) ;
18
20
} ;
19
21
22
+ useEffect ( ( ) => {
23
+ const hash = router . asPath . split ( '#' ) [ 1 ] ;
24
+ if ( hash ) {
25
+ const id = parseInt ( hash , 10 ) ;
26
+ const index = items . findIndex ( ( item ) => item . id === id ) ;
27
+ if ( index !== - 1 ) {
28
+ setActiveIndex ( index ) ;
29
+
30
+ setTimeout ( ( ) => {
31
+ const element = document . getElementById ( hash ) ;
32
+ if ( element ) {
33
+ const navbarHeight = 150 ;
34
+ const offset = element . offsetTop - navbarHeight ;
35
+ window . scrollTo ( { top : offset , behavior : 'smooth' } ) ;
36
+ }
37
+ } , 0 ) ;
38
+ }
39
+ }
40
+ } , [ items , router . asPath ] ) ;
41
+
42
+ const handleLinkClick = ( id : number ) => {
43
+ const index = items . findIndex ( ( item ) => item . id === id ) ;
44
+ setActiveIndex ( index ) ;
45
+
46
+ const newUrl = `#${ id } ` ;
47
+ router . push ( newUrl , undefined , { shallow : true } ) ;
48
+ } ;
49
+
20
50
return (
21
51
< div >
22
52
{ items . map ( ( item , index ) => (
23
53
< div
24
- key = { index }
54
+ key = { item . id || index }
25
55
className = { `overflow-hidden transition-max-height border-t-2 ${
26
56
activeIndex === index ? 'max-h-96' : 'max-h-20'
27
- } ${ index === items . length - 1 ? 'border-b-2' : '' } `}
57
+ } ${ index === items . length - 1 ? 'border-b-2' : '' } `}
28
58
>
29
- < div
30
- className = 'flex justify-between items-center p-4 cursor-pointer'
31
- onClick = { ( ) => handleToggle ( index ) }
32
- >
59
+ < div className = 'flex justify-between items-center p-4 cursor-pointer' >
33
60
< div className = 'text-[20px]' >
34
- < a href = { `#${ item . id } ` } > { item . question } </ a >
61
+ < a
62
+ href = { `#${ item . id } ` }
63
+ onClick = { ( e ) => {
64
+ e . preventDefault ( ) ;
65
+ handleLinkClick ( item . id ) ;
66
+ } }
67
+ >
68
+ { item . question }
69
+ </ a >
35
70
</ div >
36
71
< div
37
72
className = { `transform transition-transform text-[20px] ${
38
73
activeIndex === index ? 'rotate-45' : ''
39
74
} `}
75
+ onClick = { ( ) => handleToggle ( index ) }
40
76
>
41
77
+
42
78
</ div >
43
79
</ div >
44
80
{ activeIndex === index && (
45
- < div className = 'p-2 text-gray-500' > { item . answer } </ div >
81
+ < div id = { `${ item . id } ` } className = 'p-2 text-gray-500' >
82
+ { item . answer }
83
+ </ div >
46
84
) }
47
85
</ div >
48
86
) ) }
0 commit comments