Skip to content

Commit 77c46b4

Browse files
committed
feat(website): bookmark floating panel.
1 parent 30b518a commit 77c46b4

File tree

2 files changed

+139
-25
lines changed

2 files changed

+139
-25
lines changed

website/mdx-components-blog.jsx

Lines changed: 51 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,38 +11,64 @@ export function useMDXComponents(components) {
1111

1212
return {
1313
...blogComponents,
14-
wrapper({ children, metadata }) {
14+
wrapper({ children, metadata, toc }) {
1515
const date = formatDate(metadata?.date);
1616
const tags = metadata?.tags ?? [];
17+
const filteredToc = Array.isArray(toc) ? toc.filter((item) => item.depth <= 3) : [];
18+
const hasToc = filteredToc.length > 0;
1719

1820
return (
1921
<>
20-
{metadata?.ogImage ? (
21-
<img
22-
src={metadata.ogImage}
23-
alt={metadata.title ?? "Blog cover image"}
24-
className="typia-blog-hero"
25-
/>
26-
) : null}
27-
<h1>{metadata?.title}</h1>
28-
<div className="typia-blog-meta">
29-
{date ? <time dateTime={date.toISOString()}>{date.toLocaleDateString()}</time> : null}
30-
{metadata?.author ? <span>{metadata.author}</span> : null}
31-
{metadata?.devtoUrl ? (
32-
<a href={metadata.devtoUrl} target="_blank" rel="noreferrer">
33-
Original on DEV
34-
</a>
22+
<div className={hasToc ? "typia-blog-post-layout" : undefined}>
23+
<div className="typia-blog-post-main">
24+
{metadata?.ogImage ? (
25+
<img
26+
src={metadata.ogImage}
27+
alt={metadata.title ?? "Blog cover image"}
28+
className="typia-blog-hero"
29+
/>
30+
) : null}
31+
<h1>{metadata?.title}</h1>
32+
<div className="typia-blog-meta">
33+
{date ? (
34+
<time dateTime={date.toISOString()}>{date.toLocaleDateString()}</time>
35+
) : null}
36+
{metadata?.author ? <span>{metadata.author}</span> : null}
37+
{metadata?.devtoUrl ? (
38+
<a href={metadata.devtoUrl} target="_blank" rel="noreferrer">
39+
Original on DEV
40+
</a>
41+
) : null}
42+
</div>
43+
{tags.length ? (
44+
<div className="typia-blog-tags">
45+
{tags.map((tag) => (
46+
<span key={tag}>#{tag}</span>
47+
))}
48+
</div>
49+
) : null}
50+
{children}
51+
<GiscusComments />
52+
</div>
53+
{hasToc ? (
54+
<aside className="typia-blog-toc" aria-label="Table of contents">
55+
<div className="typia-blog-toc-inner">
56+
<div className="typia-blog-toc-title">On This Page</div>
57+
<nav>
58+
{filteredToc.map((item) => (
59+
<a
60+
key={item.id}
61+
href={`#${item.id}`}
62+
className={`typia-blog-toc-link typia-blog-toc-depth-${item.depth}`}
63+
>
64+
{item.value}
65+
</a>
66+
))}
67+
</nav>
68+
</div>
69+
</aside>
3570
) : null}
3671
</div>
37-
{tags.length ? (
38-
<div className="typia-blog-tags">
39-
{tags.map((tag) => (
40-
<span key={tag}>#{tag}</span>
41-
))}
42-
</div>
43-
) : null}
44-
{children}
45-
<GiscusComments />
4672
</>
4773
);
4874
},

website/src/app/blog/blog.css

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,3 +124,91 @@
124124
padding-top: 2rem;
125125
border-top: 1px solid rgba(127, 127, 127, 0.18);
126126
}
127+
128+
.typia-blog-post-layout {
129+
display: grid;
130+
grid-template-columns: minmax(0, 1fr) 260px;
131+
gap: 2.5rem;
132+
align-items: start;
133+
}
134+
135+
.typia-blog-post-main {
136+
min-width: 0;
137+
}
138+
139+
.typia-blog-toc {
140+
position: sticky;
141+
top: 5.5rem;
142+
align-self: start;
143+
max-height: calc(100vh - 7rem);
144+
overflow: auto;
145+
}
146+
147+
.typia-blog-toc-inner {
148+
display: flex;
149+
flex-direction: column;
150+
gap: 0.6rem;
151+
padding-left: 1rem;
152+
border-left: 1px solid rgba(127, 127, 127, 0.18);
153+
}
154+
155+
.typia-blog-toc-title {
156+
font-size: 0.82rem;
157+
font-weight: 700;
158+
letter-spacing: 0.04em;
159+
text-transform: uppercase;
160+
color: rgb(115 115 115);
161+
}
162+
163+
.dark .typia-blog-toc-title {
164+
color: rgb(165 165 165);
165+
}
166+
167+
.typia-blog-toc-link {
168+
display: block;
169+
color: rgb(90 90 90);
170+
text-decoration: none;
171+
line-height: 1.45;
172+
font-size: 0.95rem;
173+
}
174+
175+
.dark .typia-blog-toc-link {
176+
color: rgb(175 175 175);
177+
}
178+
179+
.typia-blog-toc-link:hover {
180+
color: inherit;
181+
}
182+
183+
.typia-blog-toc-depth-3 {
184+
padding-left: 0.85rem;
185+
font-size: 0.9rem;
186+
}
187+
188+
.typia-blog-toc-depth-4,
189+
.typia-blog-toc-depth-5,
190+
.typia-blog-toc-depth-6 {
191+
padding-left: 1.5rem;
192+
font-size: 0.86rem;
193+
}
194+
195+
@media (max-width: 1024px) {
196+
.typia-blog-post-layout {
197+
grid-template-columns: minmax(0, 1fr);
198+
}
199+
200+
.typia-blog-toc {
201+
position: static;
202+
top: auto;
203+
max-height: none;
204+
overflow: visible;
205+
}
206+
207+
.typia-blog-toc-inner {
208+
position: static;
209+
margin-top: 1rem;
210+
padding: 1rem 0 0;
211+
border-left: 0;
212+
border-top: 1px solid rgba(127, 127, 127, 0.18);
213+
}
214+
}

0 commit comments

Comments
 (0)