@@ -8,24 +8,43 @@ import {
8
8
import { useRef , useState } from 'react' ;
9
9
import { useOutsideClick } from '../hooks/use-outside-click' ;
10
10
import { markdownToHtml } from '../lib/markdown' ;
11
+ import { cn } from '../lib/classname' ;
12
+ import { useScrollPosition } from '../hooks/use-scroll-position' ;
11
13
12
14
type RoadmapTitleQuestionProps = {
13
15
question : string ;
14
16
answer : string ;
17
+ roadmapId ?: string ;
15
18
} ;
16
19
17
20
export function RoadmapTitleQuestion ( props : RoadmapTitleQuestionProps ) {
18
- const { question, answer } = props ;
21
+ const { question, answer, roadmapId } = props ;
19
22
20
23
const [ isAnswerVisible , setIsAnswerVisible ] = useState ( false ) ;
21
24
const ref = useRef < HTMLDivElement > ( null ) ;
25
+ const h2Ref = useRef < HTMLHeadingElement > ( null ) ;
22
26
23
27
useOutsideClick ( ref , ( ) => {
24
28
setIsAnswerVisible ( false ) ;
25
29
} ) ;
26
30
31
+ const { y : scrollY } = useScrollPosition ( ) ;
32
+
27
33
return (
28
- < div className = "relative hidden rounded-b-[5px] border-t bg-white text-sm font-medium hover:bg-gray-50 sm:block" >
34
+ < div
35
+ className = { cn (
36
+ 'relative hidden rounded-b-[5px] border-t bg-white text-sm font-medium hover:bg-gray-50 sm:block' ,
37
+ {
38
+ 'rounded-0 -mx-4 sm:mx-0' : isAnswerVisible ,
39
+ // @FIXME :
40
+ // The line below is to keep the question hidden on mobile devices except for
41
+ // the frontend roadmap. This is because we did not use to have the question
42
+ // on mobile devices before and we don't want to cause any SEO issues. It will
43
+ // be enabled on other roadmaps in the future.
44
+ block : roadmapId === 'frontend' ,
45
+ } ,
46
+ ) }
47
+ >
29
48
{ isAnswerVisible && (
30
49
< div className = "fixed left-0 right-0 top-0 z-[100] h-full items-center justify-center overflow-y-auto overflow-x-hidden overscroll-contain bg-black/50" > </ div >
31
50
) }
@@ -47,15 +66,25 @@ export function RoadmapTitleQuestion(props: RoadmapTitleQuestionProps) {
47
66
</ h2 >
48
67
49
68
< div
50
- className = { `absolute left-0 right-0 top-0 z-[100] mt-0 rounded-md border bg-white ${
51
- isAnswerVisible ? 'block' : 'hidden'
69
+ className = { `absolute left-0 right-0 top-0 z-[100] mt-0 border bg-white ${
70
+ isAnswerVisible ? 'rounded-0 block sm:rounded-md ' : 'hidden'
52
71
} `}
53
72
ref = { ref }
54
73
>
55
74
{ isAnswerVisible && (
56
75
< h2
57
- className = "flex cursor-pointer select-none items-center border-b px-[7px] py-[9px] text-base font-medium"
58
- onClick = { ( ) => setIsAnswerVisible ( false ) }
76
+ className = { cn (
77
+ 'sticky top-0 flex cursor-pointer select-none items-center rounded-t-md border-b bg-white px-[7px] py-[9px] text-base font-medium' ,
78
+ ) }
79
+ onClick = { ( ) => {
80
+ setIsAnswerVisible ( false ) ;
81
+ if (
82
+ scrollY > ( h2Ref ?. current ?. getBoundingClientRect ( ) . top || 0 )
83
+ ) {
84
+ ref . current ?. scrollIntoView ( ) ;
85
+ }
86
+ } }
87
+ ref = { h2Ref }
59
88
>
60
89
< span className = "flex flex-grow items-center" >
61
90
< Info className = "mr-2 inline-block h-4 w-4" strokeWidth = { 2.5 } />
@@ -67,7 +96,7 @@ export function RoadmapTitleQuestion(props: RoadmapTitleQuestionProps) {
67
96
</ h2 >
68
97
) }
69
98
< div
70
- className = "bg-gray-100 p-3 text-base [&>h2]:mb-2 [&>h2]:mt-5 [&>h2]:text-[17px] [&>h2]:font-medium [&>p:last-child]:mb-0 [&>p>a]:font-semibold [&>p>a]:underline [&>p>a]:underline-offset-2 [&>p]:mb-3 [&>p]:font-normal [&>p]:leading-relaxed [&>p]:text-gray-800"
99
+ className = "bg-gray-100 p-3 text-base [&>h2]:mb-2 [&>h2]:mt-5 [&>h2]:text-[17px] [&>h2]:font-medium [&>p:last-child]:mb-0 [&>p>a]:font-semibold [&>p>a]:underline [&>p>a]:underline-offset-2 [&>p]:mb-3 [&>p]:font-normal [&>p]:leading-relaxed [&>p]:text-gray-800 [&>ul>li]:mb-2 [&>ul>li]:font-normal "
71
100
dangerouslySetInnerHTML = { { __html : markdownToHtml ( answer , false ) } }
72
101
> </ div >
73
102
</ div >
0 commit comments