Skip to content

Commit 03c85f2

Browse files
committed
Make the question on the roadmap top sticky
1 parent c96886c commit 03c85f2

File tree

3 files changed

+41
-9
lines changed

3 files changed

+41
-9
lines changed

src/components/CustomRoadmap/FlowRoadmapRenderer.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ import { totalRoadmapNodes } from '../../stores/roadmap.ts';
1717

1818
type FlowRoadmapRendererProps = {
1919
isEmbed?: boolean;
20-
roadmap: RoadmapDocument;
20+
roadmap: RoadmapDocument & {
21+
canManage?: boolean
22+
};
2123
};
2224

2325
export function FlowRoadmapRenderer(props: FlowRoadmapRendererProps) {
@@ -159,7 +161,7 @@ export function FlowRoadmapRenderer(props: FlowRoadmapRendererProps) {
159161
{hideRenderer && (
160162
<EmptyRoadmap
161163
roadmapId={roadmapId}
162-
canManage={roadmap.canManage}
164+
canManage={roadmap.canManage || false}
163165
className="grow"
164166
/>
165167
)}

src/components/RoadmapTitleQuestion.tsx

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,43 @@ import {
88
import { useRef, useState } from 'react';
99
import { useOutsideClick } from '../hooks/use-outside-click';
1010
import { markdownToHtml } from '../lib/markdown';
11+
import { cn } from '../lib/classname';
12+
import { useScrollPosition } from '../hooks/use-scroll-position';
1113

1214
type RoadmapTitleQuestionProps = {
1315
question: string;
1416
answer: string;
17+
roadmapId?: string;
1518
};
1619

1720
export function RoadmapTitleQuestion(props: RoadmapTitleQuestionProps) {
18-
const { question, answer } = props;
21+
const { question, answer, roadmapId } = props;
1922

2023
const [isAnswerVisible, setIsAnswerVisible] = useState(false);
2124
const ref = useRef<HTMLDivElement>(null);
25+
const h2Ref = useRef<HTMLHeadingElement>(null);
2226

2327
useOutsideClick(ref, () => {
2428
setIsAnswerVisible(false);
2529
});
2630

31+
const { y: scrollY } = useScrollPosition();
32+
2733
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+
>
2948
{isAnswerVisible && (
3049
<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>
3150
)}
@@ -47,15 +66,25 @@ export function RoadmapTitleQuestion(props: RoadmapTitleQuestionProps) {
4766
</h2>
4867

4968
<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'
5271
}`}
5372
ref={ref}
5473
>
5574
{isAnswerVisible && (
5675
<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}
5988
>
6089
<span className="flex flex-grow items-center">
6190
<Info className="mr-2 inline-block h-4 w-4" strokeWidth={2.5} />
@@ -67,7 +96,7 @@ export function RoadmapTitleQuestion(props: RoadmapTitleQuestionProps) {
6796
</h2>
6897
)}
6998
<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"
71100
dangerouslySetInnerHTML={{ __html: markdownToHtml(answer, false) }}
72101
></div>
73102
</div>

src/pages/[roadmapId]/index.astro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ const projects = await getProjectsByRoadmapId(roadmapId);
123123
question?.title && (
124124
<RoadmapTitleQuestion
125125
client:load
126+
roadmapId={roadmapId}
126127
question={question?.title}
127128
answer={question?.description}
128129
/>

0 commit comments

Comments
 (0)