ttrpg-tools/src/components/Article.tsx

56 lines
1.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Component, createSignal, createEffect, onCleanup, Show, createResource } from 'solid-js';
import { parseMarkdown } from '../markdown';
import { fetchData, extractSection } from '../data-loader';
export interface ArticleProps {
src: string;
section?: string; // 指定要显示的标题(不含 #
onLoaded?: () => void;
onError?: (error: Error) => void;
class?: string; // 额外的 class 用于样式控制
}
async function fetchArticleContent(params: { src: string; section?: string }): Promise<string> {
const text = await fetchData(params.src);
// 如果指定了 section提取对应内容
return params.section ? extractSection(text, params.section) : text;
}
/**
* Article 组件
* 用于将特定 src 位置的 md 文件显示为 markdown 文章
*/
export const Article: Component<ArticleProps> = (props) => {
const [content, { refetch }] = createResource(
() => ({ src: props.src, section: props.section }),
fetchArticleContent
);
createEffect(() => {
const data = content();
if (data) {
props.onLoaded?.();
}
});
onCleanup(() => {
// 清理时清空内容,触发内部组件的销毁
});
return (
<article class={`prose ${props.class || ''}`} data-src={props.src}>
<Show when={content.loading}>
<div class="text-gray-500">...</div>
</Show>
<Show when={content.error}>
<div class="text-red-500">{content.error?.message}</div>
</Show>
<Show when={!content.loading && !content.error && content()}>
<div class="relative" innerHTML={parseMarkdown(content()!)} />
</Show>
</article>
);
};
export default Article;