Skip to content

Commit 6dc35c8

Browse files
committed
fix: address blog component review comments
1 parent f8c72ae commit 6dc35c8

5 files changed

Lines changed: 64 additions & 31 deletions

File tree

src/blog-back-button/index.module.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.blog-back-button {
1+
.blogBackButton {
22
margin-bottom: 1rem;
33
color: var(--rp-c-text-2);
44
transition: color 0.2s ease-out;

src/blog-back-button/index.tsx

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,20 @@ const getClassName = (...classNames: Array<string | undefined>) => {
1414
};
1515

1616
const getBlogPrefix = (lang: string, blogPrefix = '/blog') => {
17-
return !lang || lang === 'en' ? `${blogPrefix}` : `/${lang}${blogPrefix}`;
17+
if (lang === 'en') {
18+
return blogPrefix;
19+
}
20+
21+
const localizedPrefix = `/${lang}`;
22+
23+
if (
24+
blogPrefix === localizedPrefix ||
25+
blogPrefix.startsWith(`${localizedPrefix}/`)
26+
) {
27+
return blogPrefix;
28+
}
29+
30+
return `${localizedPrefix}${blogPrefix}`;
1831
};
1932

2033
const getLabel = (lang?: string) => {

src/blog-list/index.tsx

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { HTMLAttributes, ReactNode } from 'react';
1+
import type { AnchorHTMLAttributes, HTMLAttributes, ReactNode } from 'react';
22
import { useMemo, useState } from 'react';
33
import { type BlogAvatarAuthor, BlogAvatarGroup } from '../blog-avatar';
44
import { ALink, type LinkComp } from '../shared';
@@ -9,9 +9,33 @@ import styles from './index.module.scss';
99

1010
export type BlogDateValue = Date | string | number;
1111

12+
export type RenderInlineMarkdownResult =
13+
| HTMLAttributes<HTMLParagraphElement>
14+
| {
15+
dangerouslySetInnerHTML: {
16+
__html: string;
17+
};
18+
className?: string;
19+
};
20+
1221
export type RenderInlineMarkdown = (
1322
content: string,
14-
) => HTMLAttributes<HTMLParagraphElement>;
23+
) => RenderInlineMarkdownResult;
24+
25+
const hasDangerousHtml = (
26+
value: RenderInlineMarkdownResult,
27+
): value is Extract<
28+
RenderInlineMarkdownResult,
29+
{ dangerouslySetInnerHTML: object }
30+
> => {
31+
return 'dangerouslySetInnerHTML' in value;
32+
};
33+
34+
type LinkLikeProps = AnchorHTMLAttributes<HTMLAnchorElement> & {
35+
className: string;
36+
href: string;
37+
children: ReactNode;
38+
};
1539

1640
export type BlogListItem = {
1741
id?: string | number;
@@ -34,6 +58,7 @@ export type BlogListProps = {
3458
subtitle?: ReactNode;
3559
featured?: boolean;
3660
interactive?: boolean;
61+
hideDocLayoutChrome?: boolean;
3762
};
3863

3964
const DEFAULT_DATE_FORMAT_OPTIONS: Intl.DateTimeFormatOptions = {
@@ -101,13 +126,23 @@ function MarkdownishText({
101126

102127
if (renderInlineMarkdown) {
103128
const paragraphProps = renderInlineMarkdown(children);
129+
const paragraphChildren = hasDangerousHtml(paragraphProps)
130+
? undefined
131+
: paragraphProps.children;
104132
const paragraphClassName = getClassName(
105133
styles.descriptionParagraph,
106134
paragraphProps.className,
107135
);
108136

109-
const { children: paragraphChildren, ...restParagraphProps } =
110-
paragraphProps;
137+
if (hasDangerousHtml(paragraphProps)) {
138+
return (
139+
<span className={paragraphClassName}>
140+
{paragraphChildren ?? children}
141+
</span>
142+
);
143+
}
144+
145+
const { children: _children, ...restParagraphProps } = paragraphProps;
111146

112147
return (
113148
<p {...restParagraphProps} className={paragraphClassName}>
@@ -122,7 +157,7 @@ function MarkdownishText({
122157
type BlogCardProps = {
123158
post: BlogListItem;
124159
isFeatured: boolean;
125-
Link: LinkComp;
160+
Link: (props: LinkLikeProps) => JSX.Element;
126161
dateFormatter: Intl.DateTimeFormat;
127162
interactive: boolean;
128163
renderInlineMarkdown?: RenderInlineMarkdown;
@@ -215,12 +250,13 @@ export function BlogList({
215250
subtitle,
216251
featured = true,
217252
interactive = true,
253+
hideDocLayoutChrome = false,
218254
}: BlogListProps) {
219255
if (posts.length === 0) {
220256
return emptyState ? <>{emptyState}</> : null;
221257
}
222258

223-
const Link = LinkComp ?? ALink;
259+
const Link = (LinkComp ?? ALink) as (props: LinkLikeProps) => JSX.Element;
224260
const dateFormatter = new Intl.DateTimeFormat(
225261
lang === 'zh' ? 'zh-CN' : 'en-US',
226262
dateFormatOptions,
@@ -283,12 +319,14 @@ export function BlogList({
283319
))}
284320
</section>
285321
) : null}
286-
<style>{`
322+
{hideDocLayoutChrome ? (
323+
<style>{`
287324
.rp-doc-layout__sidebar-placeholder { display: none; }
288325
.rp-doc-layout__outline { display: none; }
289326
.rp-doc-layout__doc { width: 100% !important; max-width: 100% !important; }
290327
.rp-doc-layout__doc-container { margin: 0 auto; }
291328
`}</style>
329+
) : null}
292330
</div>
293331
);
294332
}

stories/BlogBackButton.stories.tsx

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,15 @@ import { BlogBackButton } from '@rstack-dev/doc-ui/blog-back-button';
22
import type { ReactNode } from 'react';
33
import './index.scss';
44

5-
type StoryLinkProps = {
6-
className: string;
7-
href: string;
8-
children: ReactNode;
9-
target?: string;
10-
rel?: string;
11-
onMouseEnter?: () => void;
12-
onMouseLeave?: () => void;
13-
[key: `data-${string}`]: string | undefined;
14-
};
15-
16-
const StoryLink = ({ children, ...props }: StoryLinkProps) => {
17-
return <a {...props}>{children}</a>;
18-
};
19-
205
export const BlogBackButtonStory = () => (
216
<div style={{ margin: '0 auto', maxWidth: 960, padding: 24 }}>
22-
<BlogBackButton
23-
pathname="/blog/rspress-2-0"
24-
blogPrefix="/blog"
25-
LinkComp={StoryLink}
26-
/>
7+
<BlogBackButton pathname="/blog/rspress-2-0" lang="en" blogPrefix="/blog" />
278
<div style={{ marginBottom: 24 }}>English blog detail page</div>
289

2910
<BlogBackButton
3011
pathname="/zh/blog/rspack-roadmap"
3112
lang="zh"
32-
blogPrefix="/zh/blog"
33-
LinkComp={StoryLink}
13+
blogPrefix="/blog"
3414
/>
3515
<div>中文博客详情页</div>
3616
</div>

stories/BlogList.stories.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ export const BlogListStory = () => (
7474
<BlogList
7575
posts={posts}
7676
lang="en"
77+
hideDocLayoutChrome
7778
renderInlineMarkdown={renderInlineMarkdown}
7879
title="Blog"
7980
subtitle={
@@ -100,6 +101,7 @@ export const BlogListWithBackgroundStory = () => (
100101
posts={posts}
101102
lang="en"
102103
LinkComp={StoryLink}
104+
hideDocLayoutChrome
103105
renderInlineMarkdown={renderInlineMarkdown}
104106
title="Blog"
105107
subtitle={

0 commit comments

Comments
 (0)