1- import type { HTMLAttributes , ReactNode } from 'react' ;
1+ import type { AnchorHTMLAttributes , HTMLAttributes , ReactNode } from 'react' ;
22import { useMemo , useState } from 'react' ;
33import { type BlogAvatarAuthor , BlogAvatarGroup } from '../blog-avatar' ;
44import { ALink , type LinkComp } from '../shared' ;
@@ -9,9 +9,33 @@ import styles from './index.module.scss';
99
1010export 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+
1221export 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
1640export 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
3964const 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({
122157type 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}
0 commit comments